Last active
December 7, 2020 23:06
-
-
Save pjlamb12/b265ce3cf741d0237c084a27ea553dda to your computer and use it in GitHub Desktop.
SVG Icon Manager Module for Angular using the angular-svg-icon library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@NgModule({ | |
imports: [ | |
IconManagerModule.forRoot({ configUrl: './assets/icons/heroicons.json' }), | |
] | |
}) | |
export class AppModule {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { SvgIconManagerService } from './svg-icon-manager/svg-icon-manager.service'; | |
import { SvgIconManagerConfig } from './svg-icon-manager/svg-icon-config.class'; | |
export function initConfig(svgSvc: SvgIconManagerService) { | |
return () => svgSvc.loadConfig(); | |
} | |
@NgModule({ | |
imports: [CommonModule], | |
providers: [ | |
SvgIconManagerService, | |
{ | |
provide: APP_INITIALIZER, | |
useFactory: initConfig, | |
deps: [SvgIconManagerService], | |
multi: true, | |
}, | |
], | |
}) | |
export class IconManagerModule { | |
static forRoot(config: SvgIconManagerConfig): ModuleWithProviders<IconManagerModule> { | |
return { | |
ngModule: IconManagerModule, | |
providers: [ | |
{ | |
provide: SvgIconManagerConfig, | |
useValue: config, | |
}, | |
SvgIconManagerService, | |
], | |
}; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface IconImageFile { | |
iconName: string; | |
iconPath: string; | |
} | |
export interface CustomIconData { | |
iconName: string; | |
iconData: string; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class SvgIconManagerConfig { | |
configUrl: string; | |
constructor() {} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { waitForAsync } from '@angular/core/testing'; | |
import { of } from 'rxjs'; | |
import { SvgIconManagerService } from './svg-icon-manager.service'; | |
const DEMO_ICONS_JSON = { | |
iconImageFiles: [ | |
{ | |
iconName: 'badge-check', | |
iconPath: '/assets/icons/badge-check.svg', | |
}, | |
], | |
customIcons: [ | |
{ | |
iconName: 'academic-cap', | |
iconData: | |
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> <path d="M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4-1.714a1 1 0 11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7-3a1 1 0 000-1.838l-7-3zM3.31 9.397L5 10.12v4.102a8.969 8.969 0 00-1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25-3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-3.957l1.818.78a3 3 0 002.364 0l5.508-2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00-5.35 2.524 1 1 0 01-1.4 0zM6 18a1 1 0 001-1v-2.065a8.935 8.935 0 00-2-.712V17a1 1 0 001 1z" /> </svg>', | |
}, | |
], | |
}; | |
describe('SvgIconManagerService', () => { | |
let service: SvgIconManagerService; | |
let mockHttpClient; | |
let mockConfig; | |
let mockSvgIconRegistryService; | |
beforeEach(() => { | |
mockHttpClient = { | |
get: null, | |
}; | |
mockSvgIconRegistryService = { | |
loadSvg: jest.fn().mockReturnValue(of(null)), | |
addSvg: jest.fn(), | |
}; | |
service = new AngularSvgIconPreloaderService( | |
mockHttpClient, | |
mockConfig, | |
mockSvgIconRegistryService | |
); | |
}); | |
it('should be created', () => { | |
expect(service).toBeTruthy(); | |
}); | |
it( | |
'should call the load icons method', | |
waitForAsync(() => { | |
mockHttpClient.get = jest.fn().mockReturnValue(of(DEMO_ICONS_JSON)); | |
service.loadConfig(); | |
expect(mockSvgIconRegistryService.loadSvg).toHaveBeenCalled(); // fails | |
}) | |
); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Injectable, Optional } from '@angular/core'; | |
import { HttpClient } from '@angular/common/http'; | |
import { Subject } from 'rxjs'; | |
import { SvgIconManagerConfig } from './svg-icon-config.class'; | |
import { SvgIconRegistryService } from 'angular-svg-icon'; | |
import { CustomIconData, IconImageFile } from './icon.interface'; | |
import { take } from 'rxjs/operators'; | |
@Injectable({ | |
providedIn: 'root', | |
}) | |
export class SvgIconManagerService { | |
private configUrl: string = './assets/icons.json'; | |
private iconsFileDate: { iconImageFiles: IconImageFile[]; customIcons: CustomIconData[] }; | |
public configSubject: Subject<any> = new Subject<any>(); | |
constructor( | |
private _http: HttpClient, | |
@Optional() config: SvgIconManagerConfig, | |
private _iconRegistry: SvgIconRegistryService, | |
) { | |
if (config) { | |
this.configUrl = config.configUrl; | |
} | |
} | |
loadConfig(): Promise<any> { | |
return this._http | |
.get(this.configUrl) | |
.toPromise() | |
.then((configData: { iconImageFiles: IconImageFile[]; customIcons: CustomIconData[] }) => { | |
this.iconsFileDate = configData; | |
this.loadIcons(); | |
}) | |
.catch((err: any) => { | |
this.iconsFileDate = { customIcons: [], iconImageFiles: [] }; | |
this.loadIcons(); | |
}); | |
} | |
loadIcons() { | |
this.iconsFileDate.iconImageFiles.forEach((i: IconImageFile) => { | |
this._iconRegistry.loadSvg(i.iconPath, i.iconName).pipe(take(1)).subscribe(); | |
}); | |
this.iconsFileDate.customIcons.forEach((i: CustomIconData) => { | |
this._iconRegistry.addSvg(i.iconName, i.iconData); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment