Skip to content

Commit

Permalink
feat: modernise fast svg library by using inject, standalone and prov…
Browse files Browse the repository at this point in the history
…ide function
  • Loading branch information
BioPhoton authored Apr 29, 2023
2 parents 0fcd1b4 + f949780 commit 97cfc17
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 58 deletions.
11 changes: 6 additions & 5 deletions packages/ngx-fast-icon-demo/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DescriptionComponent } from './routes/description/description.component
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { TransferHttpCacheModule } from '@nguniversal/common';
import { FastSvgModule } from '@push-based/ngx-fast-svg';
import { provideFastSVG } from '@push-based/ngx-fast-svg';

@NgModule({
declarations: [AppComponent],
Expand All @@ -16,9 +16,6 @@ import { FastSvgModule } from '@push-based/ngx-fast-svg';
BrowserModule.withServerTransition({ appId: 'ngx-fast-icon-demo' }),
HttpClientModule,
TransferHttpCacheModule,
FastSvgModule.forRoot({
url: (name: string) => `assets/svg-icons/${name}.svg`,
}),
IonicModule.forRoot(),
RouterModule.forRoot(
[
Expand Down Expand Up @@ -93,7 +90,11 @@ import { FastSvgModule } from '@push-based/ngx-fast-svg';
{ initialNavigation: 'enabledBlocking' }
),
],
providers: [],
providers: [
provideFastSVG({
url: (name: string) => `assets/svg-icons/${name}.svg`,
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}
8 changes: 5 additions & 3 deletions packages/ngx-fast-icon-demo/src/app/app.server.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import {
} from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { FastSvgModule } from '@push-based/ngx-fast-svg';
import { provideFastSVG } from '@push-based/ngx-fast-svg';
import { SvgLoadStrategySsr } from './ngx-fast-icon-ssr/icon-load.ssr.strategy';

@NgModule({
declarations: [],
imports: [
Expand All @@ -18,12 +19,13 @@ import { SvgLoadStrategySsr } from './ngx-fast-icon-ssr/icon-load.ssr.strategy';
*/
ServerModule,
ServerTransferStateModule,
FastSvgModule.forRoot({
],
providers: [
provideFastSVG({
svgLoadStrategy: SvgLoadStrategySsr,
url: (name: string) => `assets/svg-icons/${name}.svg`,
}),
],
providers: [],
bootstrap: [AppComponent],
})
export class AppServerModule {}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { FastSvgModule } from '@push-based/ngx-fast-svg';
import { FastSvgComponent } from '@push-based/ngx-fast-svg';
import { FastIconRouteComponent } from './fast-icon.component';

@NgModule({
Expand All @@ -14,7 +14,7 @@ import { FastIconRouteComponent } from './fast-icon.component';
},
]),
CommonModule,
FastSvgModule,
FastSvgComponent,
],
})
export class FastIconRouteModule {}
66 changes: 63 additions & 3 deletions packages/ngx-fast-lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,45 @@ yarn add @push-based/ngx-fast-svg

### Setup

#### Setup the library in your standalone application:

**main.ts**

```typescript
import { provideFastSVG } from '@push-based/ngx-fast-svg';

bootstrapApplication(AppComponent, {
providers: [
// ... other providers
provideFastSVG({
url: (name: string) => `path/to/svg-assets/${name}.svg`,
})
]
});
```

#### Setup the library in your Angular application using NgModules:

**app.module.ts**

```typescript
// ...
import { provideFastSVG } from '@push-based/ngx-fast-svg';

@NgModule({
declarations: [AppComponent],
providers: [
provideFastSVG({
url: (name: string) => `path/to/svg-assets/${name}.svg`,
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
```

or if you're using an older version of the library, you can still do:

```typescript
// ...
import { FastSvgModule } from '@push-based/ngx-fast-svg';
Expand All @@ -38,7 +75,7 @@ import { FastSvgModule } from '@push-based/ngx-fast-svg';
FastSvgModule.forRoot({
url: (name: string) => `path/to/svg-assets/${name}.svg`,
})
]
],
providers: [],
bootstrap: [AppComponent]
})
Expand Down Expand Up @@ -98,6 +135,28 @@ import { HttpClientFetchStrategy } from './fetch-strategy';
export class AppModule {}
```

or in a standalone application:

**main.ts**

```typescript
import { provideFastSVG } from '@push-based/ngx-fast-svg';
import { loaderSvg } from './assets';
import { HttpClientFetchStrategy } from './fetch-strategy';

bootstrapApplication(AppComponent, {
providers: [
// ... other providers
provideFastSVG({
url: (name: string) => `path/to/svg-assets/${name}.svg`,
defaultSize: '32',
suspenseSvgString: loaderSvg,
svgLoadStrategy: HttpClientFetchStrategy
})
]
});
```

#### SSR Usage

You can provide your own SSR loading strategy that can look like this:
Expand All @@ -124,12 +183,13 @@ And then just provide it in you server module.
AppModule,
ServerModule,
ServerTransferStateModule,
FastSvgModule.forRoot({
],
providers: [
provideFastSVG({
svgLoadStrategy: SvgLoadStrategySsr,
url: (name: string) => `assets/svg-icons/${name}.svg`,
}),
],
providers: [],
bootstrap: [AppComponent],
})
export class AppServerModule {}
Expand Down
2 changes: 2 additions & 0 deletions packages/ngx-fast-lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ export * from './lib/svg-registry.service';
export * from './lib/fast-svg.component';
// module
export * from './lib/fast-svg.module';
// provider
export * from './lib/fast-svg.provider';
32 changes: 14 additions & 18 deletions packages/ngx-fast-lib/src/lib/fast-svg.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import {
ChangeDetectionStrategy,
Component,
ElementRef,
Inject,
Input,
OnDestroy,
PLATFORM_ID,
Renderer2
Renderer2,
inject,
} from '@angular/core';
import { Subscription } from 'rxjs';
import { getZoneUnPatchedApi } from './internal/get-zone-unpatched-api';
Expand Down Expand Up @@ -91,38 +91,34 @@ function createGetImgFn(renderer: Renderer2): (src: string) => HTMLElement {
}
`,
],
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FastSvgComponent implements AfterViewInit, OnDestroy {
private readonly platform = inject(PLATFORM_ID);
private readonly renderer = inject(Renderer2);
private readonly registry = inject(SvgRegistry);
private readonly element = inject<ElementRef<HTMLElement>>(ElementRef);

private readonly sub = new Subscription();
private readonly getImg = createGetImgFn(this.renderer);

@Input()
name = '';
@Input()
size: string = this.registry.defaultSize;
@Input()
width = '';
@Input()
height = '';
@Input() name = '';
@Input() size: string = this.registry.defaultSize;
@Input() width = '';
@Input() height = '';

// When the browser loaded the svg resource we trigger the caching mechanism
// re-fetch -> cache-hit -> get SVG -> cache in DOM
loadedListener = () => {
this.registry.fetchSvg(this.name);
};

constructor(
@Inject(PLATFORM_ID)
private platform: Record<string, unknown>,
private renderer: Renderer2,
private registry: SvgRegistry,
private element: ElementRef<HTMLElement>
) {}

ngAfterViewInit() {
if (!this.name) {
throw new Error('svg component needs a name to operate');
}

// Setup view refs and init them
const elem = this.element.nativeElement;

Expand Down
31 changes: 4 additions & 27 deletions packages/ngx-fast-lib/src/lib/fast-svg.module.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,19 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
import { FastSvgComponent } from './fast-svg.component';
import { SvgRegistry } from './svg-registry.service';
import { CommonModule } from '@angular/common';
import { FastSvgProviderOptions } from './provider-config.interface';
import { SvgLoadStrategyImpl } from './token/svg-load.strategy';
import { SvgLoadStrategy } from './token/svg-load.strategy.model';
import { SvgOptionsToken } from './token/svg-options.token';
import { SvgOptions } from './token/svg-options.model';
import { provideFastSVG } from './fast-svg.provider';

@NgModule({
imports: [CommonModule],
declarations: [FastSvgComponent],
imports: [FastSvgComponent],
exports: [FastSvgComponent],
})
export class FastSvgModule {
static forRoot(
providers: FastSvgProviderOptions
options: FastSvgProviderOptions
): ModuleWithProviders<FastSvgModule> {
const svgOptions: SvgOptions = {
url: providers.url,
};
providers?.suspenseSvgString &&
(svgOptions.suspenseSvgString = providers.suspenseSvgString);
providers?.defaultSize && (svgOptions.defaultSize = providers.defaultSize);

return {
ngModule: FastSvgModule,
providers: [
{
provide: SvgLoadStrategy,
useClass: providers.svgLoadStrategy || SvgLoadStrategyImpl,
},
{
provide: SvgOptionsToken,
useValue: svgOptions,
},
SvgRegistry,
],
providers: [provideFastSVG(options)],
};
}

Expand Down
46 changes: 46 additions & 0 deletions packages/ngx-fast-lib/src/lib/fast-svg.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Provider, makeEnvironmentProviders } from '@angular/core';
import {
SvgLoadStrategy,
SvgLoadStrategyImpl,
SvgOptions,
SvgOptionsToken,
SvgRegistry,
} from '..';
import { FastSvgProviderOptions } from './provider-config.interface';

/**
* @description
* Use this function to register the FastSvg providers in your application.
*
* @param options {FastSvgProviderOptions} - The options for the FastSvg providers.
* @return {EnvironmentProviders} - The providers for the FastSvg module.
*
* @example
*
* ```ts
* bootstrapApplication(AppComponent, {
* providers: [
* provideFastSVG({
* url: (name: string) => `path/to/svg-assets/${name}.svg`,
* })
* ]});
* ```
*/
export const provideFastSVG = (options: FastSvgProviderOptions) => {
const svgOptions: SvgOptions = {
url: options.url,
suspenseSvgString: options.suspenseSvgString || undefined,
defaultSize: options.defaultSize || undefined,
};

const providers: Provider[] = [
SvgRegistry,
{
provide: SvgLoadStrategy,
useClass: options.svgLoadStrategy || SvgLoadStrategyImpl,
},
{ provide: SvgOptionsToken, useValue: svgOptions },
];

return makeEnvironmentProviders(providers);
};

0 comments on commit 97cfc17

Please sign in to comment.