Skip to content

Commit

Permalink
feat(icons): add cdn functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Dafnik committed Nov 28, 2023
1 parent 6a22fd4 commit 33821a3
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 53 deletions.
6 changes: 5 additions & 1 deletion apps/dfx-bootstrap-icons-demo/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
"assets": [
"apps/dfx-bootstrap-icons-demo/src/favicon.ico",
"apps/dfx-bootstrap-icons-demo/src/assets",
"apps/dfx-bootstrap-icons-demo/src/404.html"
{
"glob": "**/*",
"input": "./node_modules/bootstrap-icons/icons/",
"output": "./icons/"
}
],
"styles": ["apps/dfx-bootstrap-icons-demo/src/styles.scss", "node_modules/bootstrap/dist/css/bootstrap.min.css"],
"scripts": []
Expand Down
23 changes: 0 additions & 23 deletions apps/dfx-bootstrap-icons-demo/src/404.html

This file was deleted.

50 changes: 28 additions & 22 deletions libs/dfx-bootstrap-icons/src/lib/icon.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ import {
} from '@angular/core';

import { BiName, BiNamesEnum } from './generated';
import { DEFAULT_COLOR, DEFAULT_ICON_SIZE, ICON_COLOR, ICON_HEIGHT, ICON_WIDTH, ICONS_PICKED } from './icons.config';
import { ColorValueHex, IconsType } from './types';
import {
DEFAULT_COLOR,
DEFAULT_ICON_SIZE,
ICON_COLOR,
ICON_HEIGHT,
ICON_WIDTH,
ICONS_LOADER,
} from "./icons.config";
import { ColorValueHex } from './types';
import { toEscapedName } from './internal/toEscapedName';

@Component({
Expand All @@ -38,8 +45,7 @@ export class BiComponent implements OnInit, OnChanges {

private renderer = inject(Renderer2);

// icons are provided as an array of objects because of "multi: true"
readonly pickedIcons: IconsType = Object.assign({}, ...(inject(ICONS_PICKED) as unknown as object[])) as IconsType;
private iconsLoader = inject(ICONS_LOADER);

ngOnInit(): void {
this.renderIcon();
Expand All @@ -52,28 +58,28 @@ export class BiComponent implements OnInit, OnChanges {
renderIcon(): void {
const escapedName = toEscapedName(this.name);

let svg = this.pickedIcons[escapedName] || undefined;

if (!svg) {
console.warn(`BiComponent: Icon ${this.name} not found, path: ${escapedName}`);
return;
}
this.iconsLoader(escapedName).subscribe((svg) => {
if (!svg) {
console.warn(`BiComponent: Icon ${this.name} not found, path: ${escapedName}`);
return;
}

if (!this.clearDimensions) {
svg = setSize(svg, 'width', this.width);
svg = setSize(svg, 'height', this.height);
}
if (!this.clearDimensions) {
svg = setSize(svg, 'width', this.width);
svg = setSize(svg, 'height', this.height);
}

if (this.color) {
svg = setFillColor(svg, this.color);
}
if (this.color) {
svg = setFillColor(svg, this.color);
}

this.renderer.setAttribute(this.elementRef.nativeElement, 'aria-label', this.ariaLabel ?? '');
if (this.ariaLabel) {
this.renderer.setAttribute(this.elementRef.nativeElement, 'role', 'img');
}
this.renderer.setAttribute(this.elementRef.nativeElement, 'aria-label', this.ariaLabel ?? '');
if (this.ariaLabel) {
this.renderer.setAttribute(this.elementRef.nativeElement, 'role', 'img');
}

this.renderer.setProperty(this.elementRef.nativeElement, 'innerHTML', svg);
this.renderer.setProperty(this.elementRef.nativeElement, 'innerHTML', svg);
})
}
}

Expand Down
5 changes: 4 additions & 1 deletion libs/dfx-bootstrap-icons/src/lib/icons.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { InjectionToken } from '@angular/core';
import { InjectionToken } from "@angular/core";

import { ColorValueHex, IconsType } from './types';
import { Observable } from "rxjs";

export const ICONS_PICKED = new InjectionToken<IconsType>('DFX_ICONS_PICKED', {
factory: () => ({}),
});

export const ICONS_LOADER = new InjectionToken<(name: string) => Observable<string|undefined>>('DFX_ICONS_LOADER')

export const DEFAULT_ICON_SIZE = '16';
export const DEFAULT_COLOR = 'currentColor';

Expand Down
4 changes: 3 additions & 1 deletion libs/dfx-bootstrap-icons/src/lib/icons.feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Provider } from '@angular/core';

export enum IconFeatureKind {
ICON_PICK,
ICON_CDN,
WIDTH,
HEIGHT,
COLOR,
Expand All @@ -13,8 +14,9 @@ declare interface IconFeature<KindT extends IconFeatureKind> {
}

export declare type IconPickFeature = IconFeature<IconFeatureKind.ICON_PICK>;
export declare type IconCDNFeature = IconFeature<IconFeatureKind.ICON_CDN>;
export declare type IconWidthFeature = IconFeature<IconFeatureKind.WIDTH>;
export declare type IconHeightFeature = IconFeature<IconFeatureKind.HEIGHT>;
export declare type IconColorFeature = IconFeature<IconFeatureKind.COLOR>;

export declare type IconFeatures = IconPickFeature | IconWidthFeature | IconHeightFeature | IconColorFeature;
export declare type IconFeatures = IconPickFeature | IconCDNFeature | IconWidthFeature | IconHeightFeature | IconColorFeature;
47 changes: 42 additions & 5 deletions libs/dfx-bootstrap-icons/src/lib/icons.provider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { EnvironmentProviders, makeEnvironmentProviders, Provider } from '@angular/core';
import { IconColorFeature, IconFeatureKind, IconFeatures, IconHeightFeature, IconPickFeature, IconWidthFeature } from './icons.feature';
import { ICON_COLOR, ICON_HEIGHT, ICON_WIDTH, ICONS_PICKED } from './icons.config';
import { ColorValueHex, IconsType } from './types';
import { EnvironmentProviders, inject, makeEnvironmentProviders, Provider } from "@angular/core";
import {
IconCDNFeature,
IconColorFeature,
IconFeatureKind,
IconFeatures,
IconHeightFeature,
IconPickFeature,
IconWidthFeature
} from "./icons.feature";
import { ICON_COLOR, ICON_HEIGHT, ICON_WIDTH, ICONS_LOADER, ICONS_PICKED } from "./icons.config";
import { ColorValueHex, IconsType } from "./types";
import { catchError, Observable, of } from "rxjs";
import { HttpClient } from "@angular/common/http";

export function provideBi(...features: IconFeatures[]): EnvironmentProviders {
return makeEnvironmentProviders([features.map((it) => it.providers)]);
Expand All @@ -11,10 +21,37 @@ export function provideIcons(icons: IconsType): Provider {
return { provide: ICONS_PICKED, multi: true, useValue: icons };
}

export function provideLocalIconsLoader(): Provider {
return {
provide: ICONS_LOADER,
useFactory: (): (name: string) => Observable<string|undefined> => {
const pickedIcons: IconsType = Object.assign({}, ...(inject(ICONS_PICKED) as unknown as object[])) as IconsType;
return (name: string) => of(pickedIcons[name] || undefined)
}
};
}

export function withCDN(...cdnUrls: string[]): IconCDNFeature {
return {
kind: IconFeatureKind.ICON_CDN,
providers: [{
provide: ICONS_LOADER,
useFactory: (): (name: string) => Observable<string|undefined> => {
const httpClient = inject(HttpClient);

return (name: string): Observable<string|undefined> =>
httpClient.get<string>(`${cdnUrls[Math.floor(Math.random() * cdnUrls.length)]}/${name}.svg`).pipe(
catchError(() => of(undefined))
)
}
}]
};
}

export function withIcons(icons: IconsType): IconPickFeature {
return {
kind: IconFeatureKind.ICON_PICK,
providers: [provideIcons(icons)],
providers: [provideIcons(icons), provideLocalIconsLoader()],
};
}

Expand Down

0 comments on commit 33821a3

Please sign in to comment.