Skip to content

Commit

Permalink
feat: 🎸 lazy load focus
Browse files Browse the repository at this point in the history
The library encourages the use of lazy load svg

BREAKING CHANGE: An icon is now an object with a name and data keys
  • Loading branch information
NetanelBasal committed Nov 12, 2020
1 parent 52027d6 commit 718819f
Show file tree
Hide file tree
Showing 31 changed files with 385 additions and 212 deletions.
134 changes: 76 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
[![ngneat](https://img.shields.io/badge/@-ngneat-383636?style=flat-square&labelColor=8f68d4)](https://github.com/ngneat/)
[![spectator](https://img.shields.io/badge/tested%20with-spectator-2196F3.svg?style=flat-square)]()

The `svg-icon` library enables using the `<svg-icon>` tag to directly display SVG icons in the DOM.
This approach offers an advantage over using an `<img>` tag or via the CSS `background-image` property, because it allows styling and animating the SVG with CSS.
The `svg-icon` library enables using the `<svg-icon>` tag to directly display SVG icons in the DOM.
This approach offers an advantage over using an `<img>` tag or via the CSS `background-image` property, because it allows styling and animating the SVG with CSS.

For example, if the fill or stroke properties of elements in the svg are set to `currentColor`, they will have the color defined for the containing DOM element,. So the color can easily be changed by changing the color style on the `svg-icon` element.

Expand All @@ -28,64 +28,83 @@ This command will automatically preform the recommended flow (steps 2-4).
## Recommended Flow

### Icons Preparation

1. Add the icons to `src/assets/svg`
2. Use [svg-to-ts](https://github.com/kreuzerk/svg-to-ts) to clean and extract the icons content:

```json
{
"scripts": {
"generate-icons": "svg-to-ts"
},
"svg-to-ts": {
"conversionType": "object",
"srcFiles": [
"./src/assets/svg/*.svg"
],
"outputDirectory": "./src/assets/svg",
"fileName": "svg-icons",
"svgoConfig": {
"plugins": [
{
"removeDimensions": true,
"cleanupAttrs": true
}
]
}
}
}
```
```json
{
"scripts": {
"generate-icons": "svg-to-ts"
},
"svg-to-ts": {
"generateType": "false",
"delimiter": "KEBAB",
"conversionType": "files",
"iconsFolderName": "svg",
"prefix": "app",
"srcFiles": ["./src/assets/svg/*.svg"],
"outputDirectory": "./src/app",
"svgoConfig": {
"plugins": [
{
"removeDimensions": true,
"cleanupAttrs": true
}
]
}
}
}
```

3. Run `npm run generate-icons`

### Icons Rendering
### Icons Rendering

4. Import the `SvgIconsModule` in your `AppModule`, and register the icons:

```ts
import { SvgIconsModule } from '@ngneat/svg-icon';
import icons from '../assets/svg/svg-icons';
@NgModule({
imports: [
SvgIconsModule.forRoot({
icons
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
```
```ts
import { SvgIconsModule } from '@ngneat/svg-icon';

import { appSettings } from '../svg/app-settings.icon';

@NgModule({
imports: [
SvgIconsModule.forRoot({
icons: [appSettings]
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
```

5. Now you can use the `svg-icon` component:

```html
<svg-icon key="settings"></svg-icon>
<svg-icon key="settings" color="hotpink" fontSize="40px"></svg-icon>
```
```html
// prettier-ignore
<svg-icon key="settings"></svg-icon>
<svg-icon key="settings" color="hotpink" fontSize="40px"></svg-icon>
```

In lazy load modules, you can use the `forChild` method:

```ts
import { DashboardRoutingModule } from './dashboard-routing.module';
import { DashboardComponent } from './dashboard.component';
import { appSettings } from '../svg/app-settings.icon';
import { SvgIconsModule } from '@ngneat/svg-icon';

@NgModule({
declarations: [DashboardComponent],
imports: [CommonModule, DashboardRoutingModule, SvgIconsModule.forChild([appSettings])]
})
export class DashboardModule {}
```

### Icon Sizing

To control the SVG size, we use the `font-size` property as described in this [article](https://css-tricks.com/control-icons-with-font-size/).
To control the SVG size, we use the `font-size` property as described in this [article](https://css-tricks.com/control-icons-with-font-size/).
You also have the option to pass fixed sizes and use them across the application:

```ts
Expand All @@ -98,6 +117,7 @@ You also have the option to pass fixed sizes and use them across the application
md: '16px',
lg: '20px'
},
defaultSize: 'md'
icons
})
],
Expand All @@ -118,11 +138,10 @@ You can inject the `SvgIconRegistry`, and get existing SVG icons or register new

```ts
import { SvgIconRegistry } from '@ngneat/svg-icon';
import { mySvg } from 'my-icons.ts';


interface Icon {
name: string;
data: string;
name: string;
data: string;
}

@Component({
Expand All @@ -131,14 +150,12 @@ interface Icon {
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(private registry: SvgIconRegistry) {
registry.register({ settings: `<svg>...</svg>`});
// You can pass a Icon structure map or array as well
registry.register({ mySvg });
registry.register([mySvg]);
registry.get(key);
registry.getAll();
}
constructor(private registry: SvgIconRegistry) {
registry.register([Icon, Icon, Icon]);
registry.register(Icon);
registry.get(name);
registry.getAll();
}
}
```

Expand All @@ -161,6 +178,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
Expand Down
39 changes: 22 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"protractor": "~7.0.0",
"schematics-utilities": "1.1.1",
"standard-version": "^6.0.1",
"svg-to-ts": "^5.0.0",
"svg-to-ts": "5.7.1",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.8.3"
Expand All @@ -87,11 +87,15 @@
}
},
"svg-to-ts": {
"conversionType": "object",
"generateType": "false",
"delimiter": "KEBAB",
"conversionType": "files",
"iconsFolderName": "svg",
"prefix": "app",
"srcFiles": [
"./src/assets/svg/*.svg"
],
"outputDirectory": "./src/assets/svg",
"outputDirectory": "./src/app",
"fileName": "svg-icons",
"svgoConfig": {
"plugins": [
Expand Down
36 changes: 7 additions & 29 deletions projects/ngneat/svg-icon/src/lib/registry.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { Inject, Injectable } from '@angular/core';
import { SVG_CONFIG, SVG_ICONS_CONFIG } from './types';

interface SvgToTSIcon {
name: string;
data: string;
}
import { SVG_CONFIG, SVG_ICONS_CONFIG, SvgIconType } from './types';

class SvgIcon {
appliedAttributes = false;
Expand Down Expand Up @@ -49,11 +44,12 @@ export class SvgIconRegistry {
return svg.content;
}

register(svg: Record<string, string | SvgToTSIcon> | SvgToTSIcon[], options: { override?: boolean } = {}) {
const { override = true } = options;
for (const [key, content] of this.normalizeSvgs(svg)) {
if (override || !this.svgMap.has(key)) {
this.addIcon(key, content);
register(icons: SvgIconType | SvgIconType[]) {
const toArray = Array.isArray(icons) ? icons : [icons];

for (const { name, data } of toArray) {
if (!this.hasSvg(name)) {
this.addIcon(name, data);
}
}
}
Expand Down Expand Up @@ -128,22 +124,4 @@ export class SvgIconRegistry {
const config = new SvgIcon(data);
this.svgMap.set(name, config);
}

private svgTsToEntry({ name, data }: SvgToTSIcon) {
return [name, data];
}

private isString(value): value is string {
return typeof value === 'string';
}

private normalizeSvgs(svg: Parameters<this['register']>[0]) {
return Array.isArray(svg)
? svg.map(this.svgTsToEntry)
: Object.entries(svg).map(entry => {
const [, content] = entry;

return this.isString(content) ? (entry as [string, string]) : this.svgTsToEntry(content);
});
}
}
Loading

0 comments on commit 718819f

Please sign in to comment.