@ng-icons/core 25.4.0 → 25.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/esm2022/index.mjs +2 -1
- package/esm2022/lib/icon.component.mjs +51 -12
- package/esm2022/lib/providers/icon-loader.provider.mjs +17 -0
- package/esm2022/lib/providers/icon.provider.mjs +2 -2
- package/esm2022/lib/utils/async.mjs +15 -0
- package/fesm2022/ng-icons-core.mjs +81 -13
- package/fesm2022/ng-icons-core.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/icon.component.d.ts +17 -0
- package/lib/providers/icon-loader.provider.d.ts +17 -0
- package/lib/utils/async.d.ts +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -157,7 +157,7 @@ import { featherAirplay } from '@ng-icons/feather-icons';
|
|
|
157
157
|
providers: [
|
|
158
158
|
provideNgIconsConfig({
|
|
159
159
|
size: '1.5em',
|
|
160
|
-
color: 'red'
|
|
160
|
+
color: 'red',
|
|
161
161
|
}),
|
|
162
162
|
],
|
|
163
163
|
})
|
|
@@ -181,3 +181,20 @@ bootstrapApplication(AppComponent, {
|
|
|
181
181
|
],
|
|
182
182
|
});
|
|
183
183
|
```
|
|
184
|
+
|
|
185
|
+
### Dynamically Loading Icons
|
|
186
|
+
|
|
187
|
+
The most common way to load icons is simply by registering them individually, however you may want to load icons lazily from a URL, or generate an SVG programatically on the fly. This can be achived using an icon loader. Icon loaders are a function that receives the name of the requested icon, and can return an `Observable<string>`, `Promise<string>` or a `string` containing the SVG to render. Within this function you can do whatever you need to retrieve an icon.
|
|
188
|
+
|
|
189
|
+
The function is also run within the injection context, this allows you to inject dependencies as you need such as the `HttpClient`.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
bootstrapApplication(AppComponent, {
|
|
193
|
+
providers: [
|
|
194
|
+
provideNgIconLoader(name => {
|
|
195
|
+
const http = inject(HttpClient);
|
|
196
|
+
return http.get(`/assets/icons/${name}.svg`);
|
|
197
|
+
}),
|
|
198
|
+
],
|
|
199
|
+
});
|
|
200
|
+
```
|
package/esm2022/index.mjs
CHANGED
|
@@ -2,7 +2,8 @@ export * from './lib/icon-name';
|
|
|
2
2
|
export * from './lib/icon.component';
|
|
3
3
|
export * from './lib/icon.module';
|
|
4
4
|
export * from './lib/providers/icon-config.provider';
|
|
5
|
+
export * from './lib/providers/icon-loader.provider';
|
|
5
6
|
export * from './lib/providers/icon.provider';
|
|
6
7
|
// re-export the component as NgIconComponent to prevent breaking changes
|
|
7
8
|
export { NgIcon as NgIconComponent } from './lib/icon.component';
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLHNDQUFzQyxDQUFDO0FBQ3JELGNBQWMsc0NBQXNDLENBQUM7QUFDckQsY0FBYywrQkFBK0IsQ0FBQztBQUU5Qyx5RUFBeUU7QUFDekUsT0FBTyxFQUFFLE1BQU0sSUFBSSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbGliL2ljb24tbmFtZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9pY29uLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9pY29uLm1vZHVsZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9wcm92aWRlcnMvaWNvbi1jb25maWcucHJvdmlkZXInO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvcHJvdmlkZXJzL2ljb24tbG9hZGVyLnByb3ZpZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3Byb3ZpZGVycy9pY29uLnByb3ZpZGVyJztcblxuLy8gcmUtZXhwb3J0IHRoZSBjb21wb25lbnQgYXMgTmdJY29uQ29tcG9uZW50IHRvIHByZXZlbnQgYnJlYWtpbmcgY2hhbmdlc1xuZXhwb3J0IHsgTmdJY29uIGFzIE5nSWNvbkNvbXBvbmVudCB9IGZyb20gJy4vbGliL2ljb24uY29tcG9uZW50JztcbiJdfQ==
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, HostBinding,
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Injector, Input, inject, runInInjectionContext, } from '@angular/core';
|
|
2
2
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
3
3
|
import { injectNgIconConfig } from './providers/icon-config.provider';
|
|
4
|
+
import { injectNgIconLoader } from './providers/icon-loader.provider';
|
|
4
5
|
import { injectNgIcons } from './providers/icon.provider';
|
|
6
|
+
import { coerceLoaderResult } from './utils/async';
|
|
5
7
|
import { toPropertyName } from './utils/format';
|
|
6
8
|
import * as i0 from "@angular/core";
|
|
7
9
|
export class NgIcon {
|
|
@@ -12,22 +14,19 @@ export class NgIcon {
|
|
|
12
14
|
this.sanitizer = inject(DomSanitizer);
|
|
13
15
|
/** Access the icons */
|
|
14
16
|
this.icons = injectNgIcons();
|
|
17
|
+
/** Access the icon loader if defined */
|
|
18
|
+
this.loader = injectNgIconLoader();
|
|
19
|
+
/** Access the injector */
|
|
20
|
+
this.injector = inject(Injector);
|
|
21
|
+
/** Access the change detector */
|
|
22
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
15
23
|
this._size = this.config.size;
|
|
16
24
|
/** Define the color of the icon */
|
|
17
25
|
this.color = this.config.color;
|
|
18
26
|
}
|
|
19
27
|
/** Define the name of the icon to display */
|
|
20
28
|
set name(name) {
|
|
21
|
-
|
|
22
|
-
for (const icons of [...this.icons].reverse()) {
|
|
23
|
-
if (icons[name]) {
|
|
24
|
-
// insert the SVG into the template
|
|
25
|
-
this.template = this.sanitizer.bypassSecurityTrustHtml(icons[name]);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// if there is no icon with this name warn the user as they probably forgot to import it
|
|
30
|
-
console.warn(`No icon named ${name} was found. You may need to import it using the withIcons function.`);
|
|
29
|
+
this.setIcon(name);
|
|
31
30
|
}
|
|
32
31
|
/** Define the size of the icon */
|
|
33
32
|
set size(size) {
|
|
@@ -37,6 +36,46 @@ export class NgIcon {
|
|
|
37
36
|
get size() {
|
|
38
37
|
return this._size;
|
|
39
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Load the icon with the given name and insert it into the template.
|
|
41
|
+
* @param name The name of the icon to load.
|
|
42
|
+
*/
|
|
43
|
+
async setIcon(name) {
|
|
44
|
+
const propertyName = toPropertyName(name);
|
|
45
|
+
for (const icons of [...this.icons].reverse()) {
|
|
46
|
+
if (icons[propertyName]) {
|
|
47
|
+
// insert the SVG into the template
|
|
48
|
+
this.template = this.sanitizer.bypassSecurityTrustHtml(icons[propertyName]);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// if there is a loader defined, use it to load the icon
|
|
53
|
+
if (this.loader) {
|
|
54
|
+
const result = await this.requestIconFromLoader(name);
|
|
55
|
+
// if the result is a string, insert the SVG into the template
|
|
56
|
+
if (result !== null) {
|
|
57
|
+
this.template = this.sanitizer.bypassSecurityTrustHtml(result);
|
|
58
|
+
// run change detection as this operation is asynchronous
|
|
59
|
+
this.changeDetector.detectChanges();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// if there is no icon with this name warn the user as they probably forgot to import it
|
|
64
|
+
console.warn(`No icon named ${name} was found. You may need to import it using the withIcons function.`);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Request the icon from the loader.
|
|
68
|
+
* @param name The name of the icon to load.
|
|
69
|
+
* @returns The SVG content for a given icon name.
|
|
70
|
+
*/
|
|
71
|
+
requestIconFromLoader(name) {
|
|
72
|
+
return new Promise(resolve => {
|
|
73
|
+
runInInjectionContext(this.injector, async () => {
|
|
74
|
+
const result = await coerceLoaderResult(this.loader(name));
|
|
75
|
+
resolve(result);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
40
79
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.5", ngImport: i0, type: NgIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
41
80
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.5", type: NgIcon, isStandalone: true, selector: "ng-icon", inputs: { name: "name", size: "size", strokeWidth: "strokeWidth", color: "color" }, host: { properties: { "innerHTML": "this.template", "style.--ng-icon__size": "this.size", "style.--ng-icon__stroke-width": "this.strokeWidth", "style.color": "this.color" } }, ngImport: i0, template: '', isInline: true, styles: [":host{display:inline-block;width:var(--ng-icon__size);height:var(--ng-icon__size)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
42
81
|
}
|
|
@@ -67,4 +106,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.5", ngImpor
|
|
|
67
106
|
function coerceCssPixelValue(value) {
|
|
68
107
|
return value == null ? '' : /^\d+$/.test(value) ? `${value}px` : value;
|
|
69
108
|
}
|
|
70
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
109
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9saWIvaWNvbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFdBQVcsRUFDWCxRQUFRLEVBQ1IsS0FBSyxFQUNMLE1BQU0sRUFDTixxQkFBcUIsR0FDdEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLDJCQUEyQixDQUFDO0FBRW5FLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQWFoRCxNQUFNLE9BQU8sTUFBTTtJQVBuQjtRQVFFLG9DQUFvQztRQUNuQixXQUFNLEdBQUcsa0JBQWtCLEVBQUUsQ0FBQztRQUUvQywyQkFBMkI7UUFDVixjQUFTLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWxELHVCQUF1QjtRQUNOLFVBQUssR0FBRyxhQUFhLEVBQUUsQ0FBQztRQUV6Qyx3Q0FBd0M7UUFDdkIsV0FBTSxHQUFHLGtCQUFrQixFQUFFLENBQUM7UUFFL0MsMEJBQTBCO1FBQ1QsYUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUU3QyxpQ0FBaUM7UUFDaEIsbUJBQWMsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQXNCcEQsVUFBSyxHQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFD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Q0FBQyxLQUFLLENBQUM7QUFDekUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBIb3N0QmluZGluZyxcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBpbmplY3QsXG4gIHJ1bkluSW5qZWN0aW9uQ29udGV4dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIsIFNhZmVIdG1sIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgdHlwZSB7IEljb25OYW1lIH0gZnJvbSAnLi9pY29uLW5hbWUnO1xuaW1wb3J0IHsgaW5qZWN0TmdJY29uQ29uZmlnIH0gZnJvbSAnLi9wcm92aWRlcnMvaWNvbi1jb25maWcucHJvdmlkZXInO1xuaW1wb3J0IHsgaW5qZWN0TmdJY29uTG9hZGVyIH0gZnJvbSAnLi9wcm92aWRlcnMvaWNvbi1sb2FkZXIucHJvdmlkZXInO1xuaW1wb3J0IHsgaW5qZWN0TmdJY29ucyB9IGZyb20gJy4vcHJvdmlkZXJzL2ljb24ucHJvdmlkZXInO1xuaW1wb3J0IHsgY29lcmNlTG9hZGVyUmVzdWx0IH0gZnJvbSAnLi91dGlscy9hc3luYyc7XG5pbXBvcnQgeyB0b1Byb3BlcnR5TmFtZSB9IGZyb20gJy4vdXRpbHMvZm9ybWF0JztcblxuLy8gVGhpcyBpcyBhIHR5cGVzY3JpcHQgdHlwZSB0byBwcmV2ZW50IGluZmVyZW5jZSBmcm9tIGNvbGxhcHNpbmcgdGhlIHVuaW9uIHR5cGUgdG8gYSBzdHJpbmcgdG8gaW1wcm92ZSB0eXBlIHNhZmV0eVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbmV4cG9ydCB0eXBlIEljb25UeXBlID0gSWNvbk5hbWUgfCAoc3RyaW5nICYge30pO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZy1pY29uJyxcbiAgdGVtcGxhdGU6ICcnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzdHlsZVVybHM6IFsnLi9pY29uLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBOZ0ljb24ge1xuICAvKiogQWNjZXNzIHRoZSBnbG9iYWwgaWNvbiBjb25maWcgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWcgPSBpbmplY3ROZ0ljb25Db25maWcoKTtcblxuICAvKiogQWNjZXNzIHRoZSBzYW5pdGl6ZXIgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBzYW5pdGl6ZXIgPSBpbmplY3QoRG9tU2FuaXRpemVyKTtcblxuICAvKiogQWNjZXNzIHRoZSBpY29ucyAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGljb25zID0gaW5qZWN0TmdJY29ucygpO1xuXG4gIC8qKiBBY2Nlc3MgdGhlIGljb24gbG9hZGVyIGlmIGRlZmluZWQgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkZXIgPSBpbmplY3ROZ0ljb25Mb2FkZXIoKTtcblxuICAvKiogQWNjZXNzIHRoZSBpbmplY3RvciAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcblxuICAvKiogQWNjZXNzIHRoZSBjaGFuZ2UgZGV0ZWN0b3IgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjaGFuZ2VEZXRlY3RvciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgLyoqIERlZmluZSB0aGUgbmFtZSBvZiB0aGUgaWNvbiB0byBkaXNwbGF5ICovXG4gIEBJbnB1dCgpIHNldCBuYW1lKG5hbWU6IEljb25UeXBlKSB7XG4gICAgdGhpcy5zZXRJY29uKG5hbWUpO1xuICB9XG5cbiAgLyoqIFN0b3JlIHRoZSBmb3JtYXR0ZWQgaWNvbiBuYW1lICovXG4gIEBIb3N0QmluZGluZygnaW5uZXJIVE1MJykgdGVtcGxhdGU/OiBTYWZlSHRtbDtcblxuICAvKiogRGVmaW5lIHRoZSBzaXplIG9mIHRoZSBpY29uICovXG4gIEBIb3N0QmluZGluZygnc3R5bGUuLS1uZy1pY29uX19zaXplJylcbiAgQElucHV0KClcbiAgc2V0IHNpemUoc2l6ZTogc3RyaW5nKSB7XG4gICAgLy8gaWYgdGhlIHNpemUgb25seSBjb250YWlucyBudW1iZXJzLCBhc3N1bWUgaXQgaXMgaW4gcGl4ZWxzXG4gICAgdGhpcy5fc2l6ZSA9IGNvZXJjZUNzc1BpeGVsVmFsdWUoc2l6ZSk7XG4gIH1cblxuICBnZXQgc2l6ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zaXplO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2l6ZTogc3RyaW5nID0gdGhpcy5jb25maWcuc2l6ZTtcblxuICAvKiogRGVmaW5lIHRoZSBzdHJva2Utd2lkdGggb2YgdGhlIGljb24gKi9cbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS4tLW5nLWljb25fX3N0cm9rZS13aWR0aCcpXG4gIEBJbnB1dCgpXG4gIHN0cm9rZVdpZHRoPzogc3RyaW5nIHwgbnVtYmVyO1xuXG4gIC8qKiBEZWZpbmUgdGhlIGNvbG9yIG9mIHRoZSBpY29uICovXG4gIEBIb3N0QmluZGluZygnc3R5bGUuY29sb3InKVxuICBASW5wdXQoKVxuICBjb2xvcj86IHN0cmluZyA9IHRoaXMuY29uZmlnLmNvbG9yO1xuXG4gIC8qKlxuICAgKiBMb2FkIHRoZSBpY29uIHdpdGggdGhlIGdpdmVuIG5hbWUgYW5kIGluc2VydCBpdCBpbnRvIHRoZSB0ZW1wbGF0ZS5cbiAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGljb24gdG8gbG9hZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2V0SWNvbihuYW1lOiBJY29uVHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHByb3BlcnR5TmFtZSA9IHRvUHJvcGVydHlOYW1lKG5hbWUpO1xuICAgIGZvciAoY29uc3QgaWNvbnMgb2YgWy4uLnRoaXMuaWNvbnNdLnJldmVyc2UoKSkge1xuICAgICAgaWYgKGljb25zW3Byb3BlcnR5TmFtZV0pIHtcbiAgICAgICAgLy8gaW5zZXJ0IHRoZSBTVkcgaW50byB0aGUgdGVtcGxhdGVcbiAgICAgICAgdGhpcy50ZW1wbGF0ZSA9IHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKFxuICAgICAgICAgIGljb25zW3Byb3BlcnR5TmFtZV0sXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpZiB0aGVyZSBpcyBhIGxvYWRlciBkZWZpbmVkLCB1c2UgaXQgdG8gbG9hZCB0aGUgaWNvblxuICAgIGlmICh0aGlzLmxvYWRlcikge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5yZXF1ZXN0SWNvbkZyb21Mb2FkZXIobmFtZSk7XG5cbiAgICAgIC8vIGlmIHRoZSByZXN1bHQgaXMgYSBzdHJpbmcsIGluc2VydCB0aGUgU1ZHIGludG8gdGhlIHRlbXBsYXRlXG4gICAgICBpZiAocmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMudGVtcGxhdGUgPSB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChyZXN1bHQpO1xuXG4gICAgICAgIC8vIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uIGFzIHRoaXMgb3BlcmF0aW9uIGlzIGFzeW5jaHJvbm91c1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGlmIHRoZXJlIGlzIG5vIGljb24gd2l0aCB0aGlzIG5hbWUgd2FybiB0aGUgdXNlciBhcyB0aGV5IHByb2JhYmx5IGZvcmdvdCB0byBpbXBvcnQgaXRcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgTm8gaWNvbiBuYW1lZCAke25hbWV9IHdhcyBmb3VuZC4gWW91IG1heSBuZWVkIHRvIGltcG9ydCBpdCB1c2luZyB0aGUgd2l0aEljb25zIGZ1bmN0aW9uLmAsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1ZXN0IHRoZSBpY29uIGZyb20gdGhlIGxvYWRlci5cbiAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGljb24gdG8gbG9hZC5cbiAgICogQHJldHVybnMgVGhlIFNWRyBjb250ZW50IGZvciBhIGdpdmVuIGljb24gbmFtZS5cbiAgICovXG4gIHByaXZhdGUgcmVxdWVzdEljb25Gcm9tTG9hZGVyKG5hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgcnVuSW5JbmplY3Rpb25Db250ZXh0KHRoaXMuaW5qZWN0b3IsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29lcmNlTG9hZGVyUmVzdWx0KHRoaXMubG9hZGVyIShuYW1lKSk7XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvZXJjZUNzc1BpeGVsVmFsdWUodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiAvXlxcZCskLy50ZXN0KHZhbHVlKSA/IGAke3ZhbHVlfXB4YCA6IHZhbHVlO1xufVxuIl19
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { InjectionToken, inject } from '@angular/core';
|
|
2
|
+
export const NgIconLoaderToken = new InjectionToken('Ng Icon Loader Token');
|
|
3
|
+
/**
|
|
4
|
+
* Provide a function that will return the SVG content for a given icon name.
|
|
5
|
+
* @param loader The function that will return the SVG content for a given icon name.
|
|
6
|
+
* @returns The SVG content for a given icon name.
|
|
7
|
+
*/
|
|
8
|
+
export function provideNgIconLoader(loader) {
|
|
9
|
+
return { provide: NgIconLoaderToken, useValue: loader };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Inject the function that will return the SVG content for a given icon name.
|
|
13
|
+
*/
|
|
14
|
+
export function injectNgIconLoader() {
|
|
15
|
+
return inject(NgIconLoaderToken, { optional: true });
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi1sb2FkZXIucHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9saWIvcHJvdmlkZXJzL2ljb24tbG9hZGVyLnByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBT3ZELE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLElBQUksY0FBYyxDQUNqRCxzQkFBc0IsQ0FDdkIsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsTUFBb0I7SUFDdEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDMUQsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQjtJQUNoQyxPQUFPLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3Rpb25Ub2tlbiwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgdHlwZSB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuZXhwb3J0IHR5cGUgTmdJY29uTG9hZGVyID0gKFxuICBuYW1lOiBzdHJpbmcsXG4pID0+IFByb21pc2U8c3RyaW5nPiB8IE9ic2VydmFibGU8c3RyaW5nPiB8IHN0cmluZztcblxuZXhwb3J0IGNvbnN0IE5nSWNvbkxvYWRlclRva2VuID0gbmV3IEluamVjdGlvblRva2VuPE5nSWNvbkxvYWRlcj4oXG4gICdOZyBJY29uIExvYWRlciBUb2tlbicsXG4pO1xuXG4vKipcbiAqIFByb3ZpZGUgYSBmdW5jdGlvbiB0aGF0IHdpbGwgcmV0dXJuIHRoZSBTVkcgY29udGVudCBmb3IgYSBnaXZlbiBpY29uIG5hbWUuXG4gKiBAcGFyYW0gbG9hZGVyIFRoZSBmdW5jdGlvbiB0aGF0IHdpbGwgcmV0dXJuIHRoZSBTVkcgY29udGVudCBmb3IgYSBnaXZlbiBpY29uIG5hbWUuXG4gKiBAcmV0dXJucyBUaGUgU1ZHIGNvbnRlbnQgZm9yIGEgZ2l2ZW4gaWNvbiBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZU5nSWNvbkxvYWRlcihsb2FkZXI6IE5nSWNvbkxvYWRlcikge1xuICByZXR1cm4geyBwcm92aWRlOiBOZ0ljb25Mb2FkZXJUb2tlbiwgdXNlVmFsdWU6IGxvYWRlciB9O1xufVxuXG4vKipcbiAqIEluamVjdCB0aGUgZnVuY3Rpb24gdGhhdCB3aWxsIHJldHVybiB0aGUgU1ZHIGNvbnRlbnQgZm9yIGEgZ2l2ZW4gaWNvbiBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0TmdJY29uTG9hZGVyKCk6IE5nSWNvbkxvYWRlciB8IG51bGwge1xuICByZXR1cm4gaW5qZWN0KE5nSWNvbkxvYWRlclRva2VuLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xufVxuIl19
|
|
@@ -23,6 +23,6 @@ export const NgIconsToken = new InjectionToken('Icons Token');
|
|
|
23
23
|
* @internal
|
|
24
24
|
*/
|
|
25
25
|
export function injectNgIcons() {
|
|
26
|
-
return inject(NgIconsToken);
|
|
26
|
+
return inject(NgIconsToken, { optional: true }) ?? [];
|
|
27
27
|
}
|
|
28
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi5wcm92aWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL2xpYi9wcm92aWRlcnMvaWNvbi5wcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsY0FBYyxFQUNkLFFBQVEsRUFFUixRQUFRLEVBQ1IsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBRXZCOzs7R0FHRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsS0FBNkI7SUFDeEQsT0FBTztRQUNMO1lBQ0UsT0FBTyxFQUFFLFlBQVk7WUFDckIsVUFBVSxFQUFFLENBQUMsV0FBc0MsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDdkQsR0FBRyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsR0FBRyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ2xFLEdBQUcsS0FBSzthQUNULENBQUM7WUFDRixJQUFJLEVBQUUsQ0FBQyxDQUFDLFlBQVksRUFBRSxJQUFJLFFBQVEsRUFBRSxFQUFFLElBQUksUUFBUSxFQUFFLENBQUMsQ0FBQztZQUN0RCxLQUFLLEVBQUUsSUFBSTtTQUNaO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxjQUFjLENBQzVDLGFBQWEsQ0FDZCxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxhQUFhO0lBQzNCLE9BQU8sTUFBTSxDQUFDLFlBQVksRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUN4RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIE9wdGlvbmFsLFxuICBQcm92aWRlcixcbiAgU2tpcFNlbGYsXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogRGVmaW5lIHRoZSBpY29ucyB0byB1c2VcbiAqIEBwYXJhbSBpY29ucyBUaGUgaWNvbnMgdG8gcHJvdmlkZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZUljb25zKGljb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogUHJvdmlkZXJbXSB7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTmdJY29uc1Rva2VuLFxuICAgICAgdXNlRmFjdG9yeTogKHBhcmVudEljb25zPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPltdKSA9PiAoe1xuICAgICAgICAuLi5wYXJlbnRJY29ucz8ucmVkdWNlKChhY2MsIGljb25zKSA9PiAoeyAuLi5hY2MsIC4uLmljb25zIH0pLCB7fSksXG4gICAgICAgIC4uLmljb25zLFxuICAgICAgfSksXG4gICAgICBkZXBzOiBbW05nSWNvbnNUb2tlbiwgbmV3IE9wdGlvbmFsKCksIG5ldyBTa2lwU2VsZigpXV0sXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICB9LFxuICBdO1xufVxuXG5leHBvcnQgY29uc3QgTmdJY29uc1Rva2VuID0gbmV3IEluamVjdGlvblRva2VuPFJlY29yZDxzdHJpbmcsIHN0cmluZz5bXT4oXG4gICdJY29ucyBUb2tlbicsXG4pO1xuXG4vKipcbiAqIEluamVjdCB0aGUgaWNvbnMgdG8gdXNlXG4gKiBAcmV0dXJucyBUaGUgaWNvbnMgdG8gdXNlXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluamVjdE5nSWNvbnMoKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPltdIHtcbiAgcmV0dXJuIGluamVjdChOZ0ljb25zVG9rZW4sIHsgb3B0aW9uYWw6IHRydWUgfSkgPz8gW107XG59XG4iXX0=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { firstValueFrom, isObservable } from 'rxjs';
|
|
2
|
+
/**
|
|
3
|
+
* A loader may return a promise, an observable or a string. This function will coerce the result into a promise.
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export function coerceLoaderResult(result) {
|
|
7
|
+
if (typeof result === 'string') {
|
|
8
|
+
return Promise.resolve(result);
|
|
9
|
+
}
|
|
10
|
+
if (isObservable(result)) {
|
|
11
|
+
return firstValueFrom(result);
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9saWIvdXRpbHMvYXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFjLGNBQWMsRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFaEU7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxNQUFxRDtJQUVyRCxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtRQUM5QixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7S0FDaEM7SUFFRCxJQUFJLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUN4QixPQUFPLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUMvQjtJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlLCBmaXJzdFZhbHVlRnJvbSwgaXNPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbi8qKlxuICogQSBsb2FkZXIgbWF5IHJldHVybiBhIHByb21pc2UsIGFuIG9ic2VydmFibGUgb3IgYSBzdHJpbmcuIFRoaXMgZnVuY3Rpb24gd2lsbCBjb2VyY2UgdGhlIHJlc3VsdCBpbnRvIGEgcHJvbWlzZS5cbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2VyY2VMb2FkZXJSZXN1bHQoXG4gIHJlc3VsdDogUHJvbWlzZTxzdHJpbmc+IHwgT2JzZXJ2YWJsZTxzdHJpbmc+IHwgc3RyaW5nLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpO1xuICB9XG5cbiAgaWYgKGlzT2JzZXJ2YWJsZShyZXN1bHQpKSB7XG4gICAgcmV0dXJuIGZpcnN0VmFsdWVGcm9tKHJlc3VsdCk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuIl19
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, Optional, SkipSelf, Component, ChangeDetectionStrategy, Input, HostBinding, NgModule, Inject } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, Optional, SkipSelf, Injector, ChangeDetectorRef, runInInjectionContext, Component, ChangeDetectionStrategy, Input, HostBinding, NgModule, Inject } from '@angular/core';
|
|
3
3
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
4
|
+
import { isObservable, firstValueFrom } from 'rxjs';
|
|
4
5
|
|
|
5
6
|
const NgIconConfigToken = new InjectionToken('Ng Icon Config');
|
|
6
7
|
const defaultConfig = {
|
|
@@ -25,6 +26,22 @@ function injectNgIconConfig() {
|
|
|
25
26
|
return inject(NgIconConfigToken, { optional: true }) ?? defaultConfig;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
const NgIconLoaderToken = new InjectionToken('Ng Icon Loader Token');
|
|
30
|
+
/**
|
|
31
|
+
* Provide a function that will return the SVG content for a given icon name.
|
|
32
|
+
* @param loader The function that will return the SVG content for a given icon name.
|
|
33
|
+
* @returns The SVG content for a given icon name.
|
|
34
|
+
*/
|
|
35
|
+
function provideNgIconLoader(loader) {
|
|
36
|
+
return { provide: NgIconLoaderToken, useValue: loader };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Inject the function that will return the SVG content for a given icon name.
|
|
40
|
+
*/
|
|
41
|
+
function injectNgIconLoader() {
|
|
42
|
+
return inject(NgIconLoaderToken, { optional: true });
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
/**
|
|
29
46
|
* Define the icons to use
|
|
30
47
|
* @param icons The icons to provide
|
|
@@ -49,7 +66,21 @@ const NgIconsToken = new InjectionToken('Icons Token');
|
|
|
49
66
|
* @internal
|
|
50
67
|
*/
|
|
51
68
|
function injectNgIcons() {
|
|
52
|
-
return inject(NgIconsToken);
|
|
69
|
+
return inject(NgIconsToken, { optional: true }) ?? [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A loader may return a promise, an observable or a string. This function will coerce the result into a promise.
|
|
74
|
+
* @returns
|
|
75
|
+
*/
|
|
76
|
+
function coerceLoaderResult(result) {
|
|
77
|
+
if (typeof result === 'string') {
|
|
78
|
+
return Promise.resolve(result);
|
|
79
|
+
}
|
|
80
|
+
if (isObservable(result)) {
|
|
81
|
+
return firstValueFrom(result);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
53
84
|
}
|
|
54
85
|
|
|
55
86
|
/**
|
|
@@ -70,22 +101,19 @@ class NgIcon {
|
|
|
70
101
|
this.sanitizer = inject(DomSanitizer);
|
|
71
102
|
/** Access the icons */
|
|
72
103
|
this.icons = injectNgIcons();
|
|
104
|
+
/** Access the icon loader if defined */
|
|
105
|
+
this.loader = injectNgIconLoader();
|
|
106
|
+
/** Access the injector */
|
|
107
|
+
this.injector = inject(Injector);
|
|
108
|
+
/** Access the change detector */
|
|
109
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
73
110
|
this._size = this.config.size;
|
|
74
111
|
/** Define the color of the icon */
|
|
75
112
|
this.color = this.config.color;
|
|
76
113
|
}
|
|
77
114
|
/** Define the name of the icon to display */
|
|
78
115
|
set name(name) {
|
|
79
|
-
|
|
80
|
-
for (const icons of [...this.icons].reverse()) {
|
|
81
|
-
if (icons[name]) {
|
|
82
|
-
// insert the SVG into the template
|
|
83
|
-
this.template = this.sanitizer.bypassSecurityTrustHtml(icons[name]);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// if there is no icon with this name warn the user as they probably forgot to import it
|
|
88
|
-
console.warn(`No icon named ${name} was found. You may need to import it using the withIcons function.`);
|
|
116
|
+
this.setIcon(name);
|
|
89
117
|
}
|
|
90
118
|
/** Define the size of the icon */
|
|
91
119
|
set size(size) {
|
|
@@ -95,6 +123,46 @@ class NgIcon {
|
|
|
95
123
|
get size() {
|
|
96
124
|
return this._size;
|
|
97
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Load the icon with the given name and insert it into the template.
|
|
128
|
+
* @param name The name of the icon to load.
|
|
129
|
+
*/
|
|
130
|
+
async setIcon(name) {
|
|
131
|
+
const propertyName = toPropertyName(name);
|
|
132
|
+
for (const icons of [...this.icons].reverse()) {
|
|
133
|
+
if (icons[propertyName]) {
|
|
134
|
+
// insert the SVG into the template
|
|
135
|
+
this.template = this.sanitizer.bypassSecurityTrustHtml(icons[propertyName]);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// if there is a loader defined, use it to load the icon
|
|
140
|
+
if (this.loader) {
|
|
141
|
+
const result = await this.requestIconFromLoader(name);
|
|
142
|
+
// if the result is a string, insert the SVG into the template
|
|
143
|
+
if (result !== null) {
|
|
144
|
+
this.template = this.sanitizer.bypassSecurityTrustHtml(result);
|
|
145
|
+
// run change detection as this operation is asynchronous
|
|
146
|
+
this.changeDetector.detectChanges();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// if there is no icon with this name warn the user as they probably forgot to import it
|
|
151
|
+
console.warn(`No icon named ${name} was found. You may need to import it using the withIcons function.`);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Request the icon from the loader.
|
|
155
|
+
* @param name The name of the icon to load.
|
|
156
|
+
* @returns The SVG content for a given icon name.
|
|
157
|
+
*/
|
|
158
|
+
requestIconFromLoader(name) {
|
|
159
|
+
return new Promise(resolve => {
|
|
160
|
+
runInInjectionContext(this.injector, async () => {
|
|
161
|
+
const result = await coerceLoaderResult(this.loader(name));
|
|
162
|
+
resolve(result);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
98
166
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.5", ngImport: i0, type: NgIcon, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
99
167
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.5", type: NgIcon, isStandalone: true, selector: "ng-icon", inputs: { name: "name", size: "size", strokeWidth: "strokeWidth", color: "color" }, host: { properties: { "innerHTML": "this.template", "style.--ng-icon__size": "this.size", "style.--ng-icon__stroke-width": "this.strokeWidth", "style.color": "this.color" } }, ngImport: i0, template: '', isInline: true, styles: [":host{display:inline-block;width:var(--ng-icon__size);height:var(--ng-icon__size)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
100
168
|
}
|
|
@@ -160,5 +228,5 @@ const NG_ICON_DIRECTIVES = [NgIcon];
|
|
|
160
228
|
* Generated bundle index. Do not edit.
|
|
161
229
|
*/
|
|
162
230
|
|
|
163
|
-
export { NG_ICON_DIRECTIVES, NgIcon, NgIcon as NgIconComponent, NgIconConfigToken, NgIconsModule, NgIconsToken, injectNgIconConfig, injectNgIcons, provideIcons, provideNgIconsConfig };
|
|
231
|
+
export { NG_ICON_DIRECTIVES, NgIcon, NgIcon as NgIconComponent, NgIconConfigToken, NgIconLoaderToken, NgIconsModule, NgIconsToken, injectNgIconConfig, injectNgIconLoader, injectNgIcons, provideIcons, provideNgIconLoader, provideNgIconsConfig };
|
|
164
232
|
//# sourceMappingURL=ng-icons-core.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-icons-core.mjs","sources":["../../../../packages/core/src/lib/providers/icon-config.provider.ts","../../../../packages/core/src/lib/providers/icon.provider.ts","../../../../packages/core/src/lib/utils/format.ts","../../../../packages/core/src/lib/icon.component.ts","../../../../packages/core/src/lib/icon.module.ts","../../../../packages/core/src/ng-icons-core.ts"],"sourcesContent":["import { InjectionToken, Provider, inject } from '@angular/core';\n\nexport interface NgIconConfig {\n /** Define the default size of icons */\n size: string;\n /** Define the default color of icons */\n color?: string;\n}\n\nexport const NgIconConfigToken = new InjectionToken<NgIconConfig>(\n 'Ng Icon Config',\n);\n\nconst defaultConfig: NgIconConfig = {\n size: '1em',\n};\n\n/**\n * Provide the configuration for the icons\n * @param config The configuration to use\n */\nexport function provideNgIconsConfig(config: Partial<NgIconConfig>): Provider {\n return {\n provide: NgIconConfigToken,\n useValue: { ...defaultConfig, ...config },\n };\n}\n\n/**\n * Inject the configuration for the icons\n * @returns The configuration to use\n * @internal\n */\nexport function injectNgIconConfig(): NgIconConfig {\n return inject(NgIconConfigToken, { optional: true }) ?? defaultConfig;\n}\n","import {\n InjectionToken,\n Optional,\n Provider,\n SkipSelf,\n inject,\n} from '@angular/core';\n\n/**\n * Define the icons to use\n * @param icons The icons to provide\n */\nexport function provideIcons(icons: Record<string, string>): Provider[] {\n return [\n {\n provide: NgIconsToken,\n useFactory: (parentIcons?: Record<string, string>[]) => ({\n ...parentIcons?.reduce((acc, icons) => ({ ...acc, ...icons }), {}),\n ...icons,\n }),\n deps: [[NgIconsToken, new Optional(), new SkipSelf()]],\n multi: true,\n },\n ];\n}\n\nexport const NgIconsToken = new InjectionToken<Record<string, string>[]>(\n 'Icons Token',\n);\n\n/**\n * Inject the icons to use\n * @returns The icons to use\n * @internal\n */\nexport function injectNgIcons(): Record<string, string>[] {\n return inject(NgIconsToken);\n}\n","/**\n * Hyphenated to lowerCamelCase\n */\nexport function toPropertyName(str: string): string {\n return str\n .replace(/([^a-zA-Z0-9])+(.)?/g, (_, __, chr) =>\n chr ? chr.toUpperCase() : '',\n )\n .replace(/[^a-zA-Z\\d]/g, '')\n .replace(/^([A-Z])/, m => m.toLowerCase());\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n HostBinding,\n inject,\n Input,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport type { IconName } from './icon-name';\nimport { injectNgIconConfig } from './providers/icon-config.provider';\nimport { injectNgIcons } from './providers/icon.provider';\nimport { toPropertyName } from './utils/format';\n\n// This is a typescript type to prevent inference from collapsing the union type to a string to improve type safety\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type IconType = IconName | (string & {});\n\n@Component({\n selector: 'ng-icon',\n template: '',\n standalone: true,\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgIcon {\n /** Access the global icon config */\n private readonly config = injectNgIconConfig();\n\n /** Access the sanitizer */\n private readonly sanitizer = inject(DomSanitizer);\n\n /** Access the icons */\n private readonly icons = injectNgIcons();\n\n /** Define the name of the icon to display */\n @Input() set name(name: IconType) {\n name = toPropertyName(name);\n\n for (const icons of [...this.icons].reverse()) {\n if (icons[name]) {\n // insert the SVG into the template\n this.template = this.sanitizer.bypassSecurityTrustHtml(icons[name]);\n return;\n }\n }\n\n // if there is no icon with this name warn the user as they probably forgot to import it\n console.warn(\n `No icon named ${name} was found. You may need to import it using the withIcons function.`,\n );\n }\n\n /** Store the formatted icon name */\n @HostBinding('innerHTML') template?: SafeHtml;\n\n /** Define the size of the icon */\n @HostBinding('style.--ng-icon__size')\n @Input()\n set size(size: string) {\n // if the size only contains numbers, assume it is in pixels\n this._size = coerceCssPixelValue(size);\n }\n\n get size(): string {\n return this._size;\n }\n\n private _size: string = this.config.size;\n\n /** Define the stroke-width of the icon */\n @HostBinding('style.--ng-icon__stroke-width')\n @Input()\n strokeWidth?: string | number;\n\n /** Define the color of the icon */\n @HostBinding('style.color')\n @Input()\n color?: string = this.config.color;\n}\n\nfunction coerceCssPixelValue(value: string): string {\n return value == null ? '' : /^\\d+$/.test(value) ? `${value}px` : value;\n}\n","import { Inject, ModuleWithProviders, NgModule } from '@angular/core';\nimport { NgIcon } from './icon.component';\nimport { NgIconsToken, provideIcons } from './providers/icon.provider';\n\n@NgModule({\n imports: [NgIcon],\n exports: [NgIcon],\n})\nexport class NgIconsModule {\n constructor(@Inject(NgIconsToken) icons: Record<string, string>) {\n if (Object.keys(icons).length === 0) {\n throw new Error(\n 'No icons have been provided. Ensure to include some icons by importing them using NgIconsModule.withIcons({ ... }).',\n );\n }\n }\n\n /**\n * Define the icons that will be included in the application. This allows unused icons to\n * be tree-shaken away to reduce bundle size\n * @param icons The object containing the required icons\n */\n static withIcons(\n icons: Record<string, string>,\n ): ModuleWithProviders<NgIconsModule> {\n return { ngModule: NgIconsModule, providers: provideIcons(icons) };\n }\n}\n\nexport const NG_ICON_DIRECTIVES = [NgIcon] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-icons-core.mjs","sources":["../../../../packages/core/src/lib/providers/icon-config.provider.ts","../../../../packages/core/src/lib/providers/icon-loader.provider.ts","../../../../packages/core/src/lib/providers/icon.provider.ts","../../../../packages/core/src/lib/utils/async.ts","../../../../packages/core/src/lib/utils/format.ts","../../../../packages/core/src/lib/icon.component.ts","../../../../packages/core/src/lib/icon.module.ts","../../../../packages/core/src/ng-icons-core.ts"],"sourcesContent":["import { InjectionToken, Provider, inject } from '@angular/core';\n\nexport interface NgIconConfig {\n /** Define the default size of icons */\n size: string;\n /** Define the default color of icons */\n color?: string;\n}\n\nexport const NgIconConfigToken = new InjectionToken<NgIconConfig>(\n 'Ng Icon Config',\n);\n\nconst defaultConfig: NgIconConfig = {\n size: '1em',\n};\n\n/**\n * Provide the configuration for the icons\n * @param config The configuration to use\n */\nexport function provideNgIconsConfig(config: Partial<NgIconConfig>): Provider {\n return {\n provide: NgIconConfigToken,\n useValue: { ...defaultConfig, ...config },\n };\n}\n\n/**\n * Inject the configuration for the icons\n * @returns The configuration to use\n * @internal\n */\nexport function injectNgIconConfig(): NgIconConfig {\n return inject(NgIconConfigToken, { optional: true }) ?? defaultConfig;\n}\n","import { InjectionToken, inject } from '@angular/core';\nimport type { Observable } from 'rxjs';\n\nexport type NgIconLoader = (\n name: string,\n) => Promise<string> | Observable<string> | string;\n\nexport const NgIconLoaderToken = new InjectionToken<NgIconLoader>(\n 'Ng Icon Loader Token',\n);\n\n/**\n * Provide a function that will return the SVG content for a given icon name.\n * @param loader The function that will return the SVG content for a given icon name.\n * @returns The SVG content for a given icon name.\n */\nexport function provideNgIconLoader(loader: NgIconLoader) {\n return { provide: NgIconLoaderToken, useValue: loader };\n}\n\n/**\n * Inject the function that will return the SVG content for a given icon name.\n */\nexport function injectNgIconLoader(): NgIconLoader | null {\n return inject(NgIconLoaderToken, { optional: true });\n}\n","import {\n InjectionToken,\n Optional,\n Provider,\n SkipSelf,\n inject,\n} from '@angular/core';\n\n/**\n * Define the icons to use\n * @param icons The icons to provide\n */\nexport function provideIcons(icons: Record<string, string>): Provider[] {\n return [\n {\n provide: NgIconsToken,\n useFactory: (parentIcons?: Record<string, string>[]) => ({\n ...parentIcons?.reduce((acc, icons) => ({ ...acc, ...icons }), {}),\n ...icons,\n }),\n deps: [[NgIconsToken, new Optional(), new SkipSelf()]],\n multi: true,\n },\n ];\n}\n\nexport const NgIconsToken = new InjectionToken<Record<string, string>[]>(\n 'Icons Token',\n);\n\n/**\n * Inject the icons to use\n * @returns The icons to use\n * @internal\n */\nexport function injectNgIcons(): Record<string, string>[] {\n return inject(NgIconsToken, { optional: true }) ?? [];\n}\n","import { Observable, firstValueFrom, isObservable } from 'rxjs';\n\n/**\n * A loader may return a promise, an observable or a string. This function will coerce the result into a promise.\n * @returns\n */\nexport function coerceLoaderResult(\n result: Promise<string> | Observable<string> | string,\n): Promise<string> {\n if (typeof result === 'string') {\n return Promise.resolve(result);\n }\n\n if (isObservable(result)) {\n return firstValueFrom(result);\n }\n\n return result;\n}\n","/**\n * Hyphenated to lowerCamelCase\n */\nexport function toPropertyName(str: string): string {\n return str\n .replace(/([^a-zA-Z0-9])+(.)?/g, (_, __, chr) =>\n chr ? chr.toUpperCase() : '',\n )\n .replace(/[^a-zA-Z\\d]/g, '')\n .replace(/^([A-Z])/, m => m.toLowerCase());\n}\n","import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n HostBinding,\n Injector,\n Input,\n inject,\n runInInjectionContext,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport type { IconName } from './icon-name';\nimport { injectNgIconConfig } from './providers/icon-config.provider';\nimport { injectNgIconLoader } from './providers/icon-loader.provider';\nimport { injectNgIcons } from './providers/icon.provider';\nimport { coerceLoaderResult } from './utils/async';\nimport { toPropertyName } from './utils/format';\n\n// This is a typescript type to prevent inference from collapsing the union type to a string to improve type safety\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport type IconType = IconName | (string & {});\n\n@Component({\n selector: 'ng-icon',\n template: '',\n standalone: true,\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgIcon {\n /** Access the global icon config */\n private readonly config = injectNgIconConfig();\n\n /** Access the sanitizer */\n private readonly sanitizer = inject(DomSanitizer);\n\n /** Access the icons */\n private readonly icons = injectNgIcons();\n\n /** Access the icon loader if defined */\n private readonly loader = injectNgIconLoader();\n\n /** Access the injector */\n private readonly injector = inject(Injector);\n\n /** Access the change detector */\n private readonly changeDetector = inject(ChangeDetectorRef);\n\n /** Define the name of the icon to display */\n @Input() set name(name: IconType) {\n this.setIcon(name);\n }\n\n /** Store the formatted icon name */\n @HostBinding('innerHTML') template?: SafeHtml;\n\n /** Define the size of the icon */\n @HostBinding('style.--ng-icon__size')\n @Input()\n set size(size: string) {\n // if the size only contains numbers, assume it is in pixels\n this._size = coerceCssPixelValue(size);\n }\n\n get size(): string {\n return this._size;\n }\n\n private _size: string = this.config.size;\n\n /** Define the stroke-width of the icon */\n @HostBinding('style.--ng-icon__stroke-width')\n @Input()\n strokeWidth?: string | number;\n\n /** Define the color of the icon */\n @HostBinding('style.color')\n @Input()\n color?: string = this.config.color;\n\n /**\n * Load the icon with the given name and insert it into the template.\n * @param name The name of the icon to load.\n */\n private async setIcon(name: IconType): Promise<void> {\n const propertyName = toPropertyName(name);\n for (const icons of [...this.icons].reverse()) {\n if (icons[propertyName]) {\n // insert the SVG into the template\n this.template = this.sanitizer.bypassSecurityTrustHtml(\n icons[propertyName],\n );\n return;\n }\n }\n\n // if there is a loader defined, use it to load the icon\n if (this.loader) {\n const result = await this.requestIconFromLoader(name);\n\n // if the result is a string, insert the SVG into the template\n if (result !== null) {\n this.template = this.sanitizer.bypassSecurityTrustHtml(result);\n\n // run change detection as this operation is asynchronous\n this.changeDetector.detectChanges();\n return;\n }\n }\n\n // if there is no icon with this name warn the user as they probably forgot to import it\n console.warn(\n `No icon named ${name} was found. You may need to import it using the withIcons function.`,\n );\n }\n\n /**\n * Request the icon from the loader.\n * @param name The name of the icon to load.\n * @returns The SVG content for a given icon name.\n */\n private requestIconFromLoader(name: string): Promise<string> {\n return new Promise(resolve => {\n runInInjectionContext(this.injector, async () => {\n const result = await coerceLoaderResult(this.loader!(name));\n resolve(result);\n });\n });\n }\n}\n\nfunction coerceCssPixelValue(value: string): string {\n return value == null ? '' : /^\\d+$/.test(value) ? `${value}px` : value;\n}\n","import { Inject, ModuleWithProviders, NgModule } from '@angular/core';\nimport { NgIcon } from './icon.component';\nimport { NgIconsToken, provideIcons } from './providers/icon.provider';\n\n@NgModule({\n imports: [NgIcon],\n exports: [NgIcon],\n})\nexport class NgIconsModule {\n constructor(@Inject(NgIconsToken) icons: Record<string, string>) {\n if (Object.keys(icons).length === 0) {\n throw new Error(\n 'No icons have been provided. Ensure to include some icons by importing them using NgIconsModule.withIcons({ ... }).',\n );\n }\n }\n\n /**\n * Define the icons that will be included in the application. This allows unused icons to\n * be tree-shaken away to reduce bundle size\n * @param icons The object containing the required icons\n */\n static withIcons(\n icons: Record<string, string>,\n ): ModuleWithProviders<NgIconsModule> {\n return { ngModule: NgIconsModule, providers: provideIcons(icons) };\n }\n}\n\nexport const NG_ICON_DIRECTIVES = [NgIcon] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export * from './lib/icon-name';
|
|
|
2
2
|
export * from './lib/icon.component';
|
|
3
3
|
export * from './lib/icon.module';
|
|
4
4
|
export * from './lib/providers/icon-config.provider';
|
|
5
|
+
export * from './lib/providers/icon-loader.provider';
|
|
5
6
|
export * from './lib/providers/icon.provider';
|
|
6
7
|
export { NgIcon as NgIconComponent } from './lib/icon.component';
|
package/lib/icon.component.d.ts
CHANGED
|
@@ -9,6 +9,12 @@ export declare class NgIcon {
|
|
|
9
9
|
private readonly sanitizer;
|
|
10
10
|
/** Access the icons */
|
|
11
11
|
private readonly icons;
|
|
12
|
+
/** Access the icon loader if defined */
|
|
13
|
+
private readonly loader;
|
|
14
|
+
/** Access the injector */
|
|
15
|
+
private readonly injector;
|
|
16
|
+
/** Access the change detector */
|
|
17
|
+
private readonly changeDetector;
|
|
12
18
|
/** Define the name of the icon to display */
|
|
13
19
|
set name(name: IconType);
|
|
14
20
|
/** Store the formatted icon name */
|
|
@@ -21,6 +27,17 @@ export declare class NgIcon {
|
|
|
21
27
|
strokeWidth?: string | number;
|
|
22
28
|
/** Define the color of the icon */
|
|
23
29
|
color?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Load the icon with the given name and insert it into the template.
|
|
32
|
+
* @param name The name of the icon to load.
|
|
33
|
+
*/
|
|
34
|
+
private setIcon;
|
|
35
|
+
/**
|
|
36
|
+
* Request the icon from the loader.
|
|
37
|
+
* @param name The name of the icon to load.
|
|
38
|
+
* @returns The SVG content for a given icon name.
|
|
39
|
+
*/
|
|
40
|
+
private requestIconFromLoader;
|
|
24
41
|
static ɵfac: i0.ɵɵFactoryDeclaration<NgIcon, never>;
|
|
25
42
|
static ɵcmp: i0.ɵɵComponentDeclaration<NgIcon, "ng-icon", never, { "name": { "alias": "name"; "required": false; }; "size": { "alias": "size"; "required": false; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; }; "color": { "alias": "color"; "required": false; }; }, {}, never, never, true, never>;
|
|
26
43
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import type { Observable } from 'rxjs';
|
|
3
|
+
export type NgIconLoader = (name: string) => Promise<string> | Observable<string> | string;
|
|
4
|
+
export declare const NgIconLoaderToken: InjectionToken<NgIconLoader>;
|
|
5
|
+
/**
|
|
6
|
+
* Provide a function that will return the SVG content for a given icon name.
|
|
7
|
+
* @param loader The function that will return the SVG content for a given icon name.
|
|
8
|
+
* @returns The SVG content for a given icon name.
|
|
9
|
+
*/
|
|
10
|
+
export declare function provideNgIconLoader(loader: NgIconLoader): {
|
|
11
|
+
provide: InjectionToken<NgIconLoader>;
|
|
12
|
+
useValue: NgIconLoader;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Inject the function that will return the SVG content for a given icon name.
|
|
16
|
+
*/
|
|
17
|
+
export declare function injectNgIconLoader(): NgIconLoader | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
/**
|
|
3
|
+
* A loader may return a promise, an observable or a string. This function will coerce the result into a promise.
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export declare function coerceLoaderResult(result: Promise<string> | Observable<string> | string): Promise<string>;
|