@presencelearning/icons
A typed <pl-icon> component that renders both Material Symbols Outlined and the custom Presence SVG set. The Material Symbols font is self-hosted by this package, so there is no Google Fonts CDN dependency.
Current version: 1.1.0.
Install
Section titled “Install”npm install @presencelearning/iconsPeer dependencies
Section titled “Peer dependencies”@angular/core>=18.0.0 <22.0.0@angular/common>=18.0.0 <22.0.0@angular/material>=18.0.0 <22.0.0@angular/platform-browser>=18.0.0 <22.0.0
material-symbols ships as a regular dependency, so the font comes with the package.
Add providePlIcons() to your application’s root providers:
import { ApplicationConfig } from '@angular/core';import { providePlIcons } from '@presencelearning/icons';
export const appConfig: ApplicationConfig = { providers: [ providePlIcons(), // ...other providers ],};On app init this registers every custom PL SVG under the pl: namespace with MatIconRegistry, and sets material-symbols-outlined as the default <mat-icon> font set. SVGs are inlined into the bundle as literals, so there is no HTTP request per icon.
Then pull in the font stylesheet:
@use '@presencelearning/icons/material-symbols';PlIconComponent is standalone, so add it to the imports of each component that uses <pl-icon>:
import { Component } from '@angular/core';import { PlIconComponent } from '@presencelearning/icons';
@Component({ selector: 'app-toolbar', imports: [PlIconComponent], template: `<pl-icon name="chat" />`,})export class ToolbarComponent {}<!-- Custom PL SVG icon --><pl-icon name="chat" />
<!-- Material Symbol (font ligature) --><pl-icon name="search" />
<!-- Inline sizing (inherits font-size / line-height) --><pl-icon name="chat" [inline]="true" />
<!-- Meaningful (non-decorative) icon: disable aria-hidden and add a label --><pl-icon name="close" aria-hidden="false" aria-label="Close dialog" />The name input is typed, so a bound expression narrows correctly:
<pl-icon [name]="isOpen() ? 'chevron-left' : 'chevron-right'" />Inputs
Section titled “Inputs”| Input | Type | Default | Description |
| ------------- | ------------- | -------- | ------------------------------------------------------------ |
| name | PlIconInput | required | Custom PL icon name or Material Symbol name |
| inline | boolean | false | Render inline instead of a fixed box |
| aria-hidden | string | 'true' | Decorative by default; set to 'false' for meaningful icons |
In dev mode the component warns when name is neither a known PL icon nor a plausible Material Symbol token.
Custom-first precedence
Section titled “Custom-first precedence”When name matches a registered custom PL icon, the custom SVG always wins — even if a Material Symbol of the same name exists. Names that currently collide include home, chat, close, check, info, and menu.
Sizing
Section titled “Sizing”There is no size input by design. Material ligatures scale with font-size; custom SVGs scale with width/height, or with font-size when inline is set.
pl-icon { font-size: 24px;}Typing
Section titled “Typing”type PlIconInput = PlIconName | MaterialSymbol;PlIconName is a union of the 140 custom icon names, generated from the SVG files. isPlIconName(name) is an exported type guard. Note that the underlying PL_ICON_NAMES tuple is not a public export — use the PlIconName type for compile-time checks.
Adding or regenerating icons
Section titled “Adding or regenerating icons”- Drop a kebab-case
.svgfile intopackages/icons/src/icons/. - Run
npm run generate:icons --workspace=@presencelearning/icons.
The generator optimizes each SVG through SVGO and rewrites src/build/pl-icons.generated.ts. Never hand-edit that file. It also runs automatically as prebuild, so npm run build always regenerates first. Non-kebab-case names and duplicates fail the codegen.
API reference
Section titled “API reference”| Export | Kind | Description |
| ------------------------------------------ | --------- | ------------------------------------------------------------------------------ |
| PlIconComponent | component | pl-icon — renders a custom PL SVG or a Material Symbol |
| providePlIcons | function | () => EnvironmentProviders — registers custom icons and the default font set |
| PL_ICON_NAMESPACE | const | 'pl' — namespace custom SVGs are registered under |
| isPlIconName | function | (name: string) => name is PlIconName |
| PlIconName | type | Union of the custom PL icon names |
| PlIconInput | type | PlIconName \| MaterialSymbol |
| @presencelearning/icons/material-symbols | style | Self-hosted Material Symbols Outlined font stylesheet |
Storybook
Section titled “Storybook”The CustomGallery story renders every custom icon with its name — the quickest way to browse the set.
npm run storybook --workspace=@presencelearning/iconsSource: packages/icons