1- import { HttpErrorResponse } from '@angular/common/http'
2- import { ChangeDetectionStrategy , Component , effect , ElementRef , inject , input , Renderer2 } from '@angular/core'
1+ import { ChangeDetectionStrategy , Component , computed , inject , input } from '@angular/core'
32import { Logger } from '@shiftcode/logger'
43import { LoggerService } from '@shiftcode/ngx-core'
54
6- import { SvgRegistry } from './svg-registry.service '
5+ import { SvgBaseDirective } from './svg-base.directive '
76
87/**
98 * Standalone SvgComponent to display svg inline.
10- * (Initially copied from material MdIcon Directive but got rid of unused functionality and refactored to Promises)
119 *
1210 * - Specify the url input to load an SVG icon from a URL.
1311 * The SVG content is directly inlined as a child of the <sc-svg> component,
1412 * so that CSS styles can easily be applied to it.
15- * The URL is loaded via an XMLHttpRequest, so it must be on the same domain as the page or its
13+ * The URL is loaded via Angular's { @link HttpClient}, it must be on the same domain as the page or its
1614 * server must be configured to allow cross-domain requests.
1715 * @example
18- * <sc-svg url="assets/arrow.svg"></sc-svg >
16+ * <sc-svg url="assets/arrow.svg" / >
1917 */
2018@Component ( {
2119 selector : 'sc-svg' ,
@@ -24,52 +22,14 @@ import { SvgRegistry } from './svg-registry.service'
2422 styleUrls : [ './svg.component.scss' ] ,
2523 changeDetection : ChangeDetectionStrategy . OnPush ,
2624} )
27- export class SvgComponent {
25+ export class SvgComponent extends SvgBaseDirective {
2826 readonly url = input . required < string > ( )
2927
3028 readonly attrs = input < Record < string , string > > ( { } )
3129
32- protected readonly elRef : ElementRef < HTMLElement > = inject ( ElementRef )
33- protected readonly renderer = inject ( Renderer2 )
34- protected readonly svgRegistry = inject ( SvgRegistry )
35-
36- private readonly logger : Logger = inject ( LoggerService ) . getInstance ( 'SvgComponent' )
37-
38- constructor ( ) {
39- effect ( ( ) => {
40- this . loadAndSetSvg ( this . url ( ) , this . attrs ( ) )
41- } )
42- }
43-
44- private loadAndSetSvg ( url : string , attrs : Record < string , string > ) {
45- if ( ! url . endsWith ( '.svg' ) ) {
46- this . logger . warn ( 'svg url does not end with *.svg' )
47- }
48- this . svgRegistry
49- . getFromUrl ( url )
50- . then ( this . modifySvgElement ( attrs ) )
51- . then ( this . setSvgElement )
52- . catch ( ( err : any ) => {
53- if ( err instanceof HttpErrorResponse && err . status === 0 ) {
54- // in case of no internet or a timeout log a warning, we can not do anything about that
55- this . logger . warn ( `Error retrieving icon for path ${ this . url ( ) } , due to no network` , err )
56- } else {
57- this . logger . error ( `Error retrieving icon for path ${ this . url ( ) } ` , err )
58- }
59- } )
60- }
61-
62- private modifySvgElement ( attrs : Record < string , string > ) {
63- return ( svg : SVGElement ) : SVGElement => {
64- Object . keys ( attrs ) . forEach ( ( key ) => svg . setAttribute ( key , attrs [ key ] ) )
65- return svg
66- }
67- }
68-
69- private setSvgElement = ( svg : SVGElement | null ) => {
70- const layoutElement = this . elRef . nativeElement
71- // Remove existing child nodes and add the new SVG element.
72- layoutElement . innerHTML = ''
73- this . renderer . appendChild ( layoutElement , svg )
74- }
30+ protected readonly logger : Logger = inject ( LoggerService ) . getInstance ( 'SvgComponent' )
31+ protected readonly data = computed ( ( ) => ( {
32+ url : this . url ( ) ,
33+ attrs : this . attrs ( ) ,
34+ } ) )
7535}
0 commit comments