A lightweight library that makes it easier to use SVG icons in your Angular Application
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.
ng add @ngneat/svg-icon
- Add the icons to
src/assets/svg
- Add an alias to the
tsconfig
file:
{
...
"paths": {
"@app/svg/*": ["src/app/svg/*"]
}
}
- Use
@ngneat/svg-generator
to clean and extract the icons content:
{
"scripts": {
"generate-icons": "svgGenerator"
},
"svgGenerator": {
"outputPath": "./src/app/svg",
"prefix": "app",
"srcPath": "./src/assets/svg",
"svgoConfig": {
"plugins": [
"removeDimensions"
]
}
}
}
- Run
npm run generate-icons
Import the SvgIconsModule
in your AppModule
, and register the icons:
import { SvgIconsModule } from '@ngneat/svg-icon';
import { settingsIcon } from '@app/svg/settings';
@NgModule({
imports: [
SvgIconsModule.forRoot({
icons: [settingsIcon],
}),
],
})
export class AppModule {}
Now we can use the svg-icon
component:
<svg-icon key="settings"></svg-icon>
<svg-icon key="settings" color="hotpink" fontSize="40px"></svg-icon>
In lazy load modules or in reusable component modules, we can use the forChild
method, for register icons accessible locally in these modules:
import { dashboardIcon } from '@app/svg/dashboard';
import { userIcon } from '@app/svg/user';
import { SvgIconsModule } from '@ngneat/svg-icon';
@NgModule({
declarations: [DashboardComponent],
imports: [DashboardRoutingModule, SvgIconsModule.forChild([userIcon])],
})
export class DashboardModule {}
Note that we're NOT using a barrel file (i.e index.ts
). This will make sure we only load the SVG files we use in the current module.
To make the process more seamless, the library provides a Webpack plugin you can use to automate the extracting process:
const { SvgGeneratorWebpackPlugin } = require('@ngneat/svg-generator/webpack-plugin');
{
plugins: [
new SvgGeneratorWebpackPlugin({
watch: !isProd,
srcPath: './src/assets/svg',
outputPath: './src/app/svg',
svgoConfig: {
plugins: [
"removeDimensions"
],
},
}),
];
}
There are cases where we want to group multiple SVG icons. For example, we might have a notifications
feature, and we need to load SVG icons such as Slack, Email, etc.
In such cases, create a unique directory, and put the related icons inside it. For example:
home.svg
user.svg
/notifications
- slack.svg
- email.svg
This will create a notifications
folder with a barrel
file that export the SVG icons inside the folder under a const named ${folderName}Icons
:
import { notificationsIcons } from '@app/svg/notifications';
@NgModule({
imports: [SvgIconsModule.forChild(notificationsIcons)],
})
export class NotificationsModule {}
To control the SVG size, we use the font-size
property as described in this article.
You also have the option to pass fixed sizes and use them across the application:
@NgModule({
imports: [
SvgIconsModule.forRoot({
sizes: {
xs: '10px',
sm: '12px',
md: '16px',
lg: '20px',
xl: '25px',
xxl: '30px'
},
defaultSize: 'md',
icons
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
They are used in the size
input:
<svg-icon key="settings" size="lg"></svg-icon>
@Input() key: string;
@Input() size: string;
@Input() fontSize: string;
@Input() color: string;
@Input() width: string | number;
@Input() height: string | number;
@Input() noShrink: boolean;
You can inject the SvgIconRegistry
, and get existing SVG icons or register new ones:
import { SvgIconRegistry } from '@ngneat/svg-icon';
interface Icon {
name: string;
data: string;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(private registry: SvgIconRegistry) {
registry.register([Icon, Icon, Icon]);
registry.register(Icon);
registry.get(name);
registry.getAll();
}
}
You can define missingIconFallback which will be used if icon is not found in registry:
import { unknownIcon } from '@app/svg/unknown';
@NgModule({
imports: [
SvgIconsModule.forRoot({
missingIconFallback: unknownIcon,
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}
Thanks goes to these wonderful people (emoji key):
Netanel Basal π» π π€ |
Inbal Sinai π |
Shahar Kazaz π» π€ |
Artur Androsovych π» |
Vlad Tansky π» |
Zura Gabievi π» |
This project follows the all-contributors specification. Contributions of any kind welcome!
Logo icon was made by Freepik from www.flaticon.com