Icons in Angular
glyphfox-angular stellt eine Standalone-Komponente gf-icon und einen Provider bereit, der Icons nach Namen registriert. Das Paket unterstützt Angular 17 und neuer, serverseitiges Rendering, OnPush und Zoneless Change Detection.
Installation
npm install glyphfox glyphfox-angular
glyphfox-angular wird im Angular Package Format veröffentlicht, mit ng-packagr gebaut und nutzt glyphfox für die Icon-Daten und die Rendering-Engine. Die Peer-Dependency ist @angular/core 17 oder neuer, weil die Inputs auf Input-Transforms wie booleanAttribute angewiesen sind.
Icons mit provideGlyphFox registrieren
gf-icon sucht Icons nach Namen, registrieren Sie also die Icons, die Ihre Templates verwenden. Jedes Icon ist ein benannter Datenexport von glyphfox: home ist iconHome, arrow-right ist iconArrowRight.
import { ApplicationConfig } from '@angular/core'; import { provideRouter } from '@angular/router'; import { iconCheck, iconFile, iconHome, iconMenu, iconSave, iconSearch, iconX } from 'glyphfox'; import { provideGlyphFox } from 'glyphfox-angular'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideGlyphFox({ icons: [iconHome, iconSearch, iconFile, iconMenu, iconX, iconSave, iconCheck], defaults: { weight: 1.75 }, }), ], };
defaults gilt für jedes gf-icon unterhalb dieses Injectors, und ein Input am Element hat Vorrang vor dem Standardwert. Mehrere provideGlyphFox-Aufrufe im selben Injector ergänzen sich: Alle ihre Icons werden registriert, und ihre Standardwerte werden der Reihe nach zusammengeführt. provideGlyphFoxIcons(icons) ist die Kurzform, wenn Sie nur Icons registrieren.
Um jedes Icon per Name verfügbar zu machen, übergeben Sie den vollständigen Record: import { icons } from 'glyphfox' und provideGlyphFox({ icons }). Damit landen die Daten aller 419 Icons in dem Bundle, das den Provider lädt, etwa 105 KB minifiziert und 25 KB mit gzip. Setzen Sie das daher nur für Prototypen und interne Tools ein. Zwei benannte Datenexporte kosten deutlich unter 1 KB.
gf-icon verwenden
import { Component, signal } from '@angular/core'; import { GlyphFoxIcon } from 'glyphfox-angular'; @Component({ selector: 'app-toolbar', standalone: true, // the default from Angular 19 imports: [GlyphFoxIcon], template: ` <a href="/" aria-label="Home"><gf-icon name="home" /></a> <gf-icon name="search" size="20" /> <gf-icon name="file+check@tr" variant="duotone" secondaryColor="#ff7a1a" /> <button type="button" aria-label="Menu" [attr.aria-expanded]="open()" (click)="open.set(!open())"> <gf-icon name="menu" morphTo="x" trigger="state" [active]="open()" /> </button> `, }) export class Toolbar { readonly open = signal(false); }
Die Inputs verwenden die Prop-Namen in camelCase: secondaryColor, modifierCorner, flipX. Statische Strings funktionieren für jeden Input, auch für numerische (size="20" wird zur Zahl 20), und boolesche Inputs akzeptieren ein Attribut ohne Wert, sodass <gf-icon name="arrow-right" mirrorRtl /> den Pfeil in Layouts von rechts nach links spiegelt.
class und style landen auf dem Host gf-icon, einer Inline-Flexbox um das SVG-Element. Striche verwenden currentColor, daher färbt die CSS-Eigenschaft color des Hosts oder eines beliebigen Elternelements das Icon ein, und der Input color setzt die Farbe direkt.
Modifier, Stile und Fusion
name versteht die vollständige Namenssyntax. file+check fügt ein Badge hinzu, @tl, @tr, @bl oder @br wählt dessen Ecke, und heart/solid wählt einen Stil. Badges zeichnet die Engine selbst, daher muss nur das Basis-Icon registriert werden. Für eine Fusion übergeben Sie die Teile an [icons] und wählen ein layout.
<gf-icon name="cloud+sync@tr" /> <gf-icon name="heart/solid" color="#e5484d" /> <gf-icon [icons]="['cloud', 'lock']" layout="overlap" [gap]="1" /> <gf-icon [icons]="['user', 'shield']" layout="badge" /> <gf-icon [icons]="['file', 'image', 'music', 'video']" layout="grid" />
Eine Fusion wird wie jedes andere Icon über den Namen aufgelöst, daher muss jeder Teil registriert sein. Das Ergebnis folgt weight, variant und den anderen Inputs, und wo sich Teile überlappen, wird der hintere Teil rund um den vorderen ausgespart. Die Layouts sind overlap, side, stack, grid, orbit, badge und inside.
Icon-Daten statt Namen
Der Input icon nimmt Icon-Daten direkt entgegen und umgeht die Registry. Das eignet sich für Icons, die im Code aus einer festen Map ausgewählt werden.
import { Component, computed, input } from '@angular/core'; import { iconFile, iconFileCode, iconFileImage, iconFileText } from 'glyphfox'; import { GlyphFoxIcon } from 'glyphfox-angular'; const byType = { code: iconFileCode, image: iconFileImage, text: iconFileText }; type FileType = keyof typeof byType; @Component({ selector: 'app-file-row', standalone: true, imports: [GlyphFoxIcon], template: `<gf-icon [icon]="icon()" size="18" /> {{ name() }}`, }) export class FileRow { readonly name = input.required<string>(); readonly type = input<FileType | null>(null); readonly icon = computed(() => { const type = this.type(); return type ? byType[type] : iconFile; }); }
Icons für lazy geladene Routen
provideGlyphFox gibt Environment Providers zurück und funktioniert daher auch in den providers einer Route. In einer lazy geladenen Routendatei deklariert, werden Feature-Icons mit dem Lazy-Chunk ausgeliefert statt mit dem Haupt-Bundle.
import { iconHome, iconMenu, iconSearch, iconX } from 'glyphfox'; import type { GlyphFoxConfig } from 'glyphfox-angular'; export const sharedIcons = { icons: [iconHome, iconSearch, iconMenu, iconX], defaults: { weight: 1.75 }, } satisfies GlyphFoxConfig;
import { Routes } from '@angular/router'; export const routes: Routes = [ { path: 'billing', loadChildren: () => import('./billing/billing.routes').then((m) => m.BILLING_ROUTES) }, ];
import { Routes } from '@angular/router'; import { iconCreditCard, iconReceipt, iconWallet } from 'glyphfox'; import { provideGlyphFox } from 'glyphfox-angular'; import { sharedIcons } from '../icons'; import { BillingPage } from './billing.page'; export const BILLING_ROUTES: Routes = [ { path: '', providers: [ provideGlyphFox({ ...sharedIcons, icons: [...sharedIcons.icons, iconCreditCard, iconReceipt, iconWallet] }), ], component: BillingPage, }, ];
Eine Route, die provideGlyphFox aufruft, erhält eine eigene Konfiguration. Angular führt Multi-Provider nicht über Injector-Grenzen hinweg zusammen, daher lesen Komponenten unterhalb dieser Route nur den Aufruf der Route, einschließlich seiner Standardwerte. Wenn Sie wie oben ein gemeinsames Objekt per Spread-Syntax einfügen, bleiben die Icons und Standardwerte der Root-Ebene erhalten.
Serverseitiges Rendering und Hydration
gf-icon schreibt sein SVG über Renderer2, daher steht das Icon bei Angular SSR oder Prerendering bereits im HTML, und der Browser zeichnet beim Initialisieren der Komponente dasselbe Markup erneut. Der Server kennt kein requestAnimationFrame: Ein Morph springt dort direkt auf seinen Endwert, und ein Morph mit dem Standard-Auslöser (mount) läuft erst ab, wenn die App im Browser startet.
Registrieren Sie jedes Icon, das der Server rendert. Ein nicht registrierter Name wird über einen dynamischen Import nachgeladen, und diese Anfrage kann noch ausstehen, wenn der Server die Seite serialisiert. Dann bleibt das Icon im HTML leer, bis die Hydration es füllt.
Derselbe Loader erklärt ein Detail von Produktionsbuilds: Die Ausgabe listet einen kleinen Chunk pro Icon auf, weil der Builder jedes mögliche Ziel dieses dynamischen Imports bündelt. Diese Chunks werden nur für Namen heruntergeladen, die Sie nicht registriert haben.
OnPush, Signals und Zoneless-Apps
gf-icon nutzt OnPush und zeichnet sein SVG selbst, sobald sich ein Input ändert, bei Hover- und Klick-Auslösern sowie in jedem Frame eines Morphs. Die Komponente hängt nicht von zone.js ab, funktioniert also in Zoneless-Apps, und Signals werden wie jeder andere Wert gebunden: [active]="saved()".
import { Component, signal } from '@angular/core'; import { GlyphFoxIcon } from 'glyphfox-angular'; @Component({ selector: 'app-save-button', standalone: true, imports: [GlyphFoxIcon], template: ` <button type="button" (click)="save()"> <gf-icon name="save" morphTo="check" trigger="state" [active]="saved()" [duration]="300" /> {{ saved() ? 'Saved' : 'Save' }} </button> `, }) export class SaveButton { readonly saved = signal(false); save() { this.saved.set(true); setTimeout(() => this.saved.set(false), 1500); } }
Presets für lebendige Zustände funktionieren genauso: <gf-icon name="bell" animate="shake" trigger="state" [active]="hasNews()" /> lässt die Glocke schwingen, solange das Signal true ist, und animate="spin" auf loader-circle ergibt einen Spinner. Die Animationen sind CSS innerhalb des SVG und stoppen bei reduzierter Bewegung; der Leitfaden zu animierten Icons listet alle Presets und Auslöser auf.
Inputs
Jede gemeinsame Prop ist ein Input mit demselben Namen und derselben Bedeutung wie in den anderen glyphfox-Paketen.
| Input | Typ | Standard | Beschreibung |
|---|---|---|---|
size | number, string | 24 | Breite und Höhe; Zahlen sind Pixel. |
color | string | currentColor | Hauptfarbe. |
secondaryColor | string | color | Farbe der Duotone-Ebene und der Solid-Füllung. |
secondaryOpacity | number | 0.3 / 1 | Deckkraft der Duotone-Ebene oder der Solid-Füllung. |
weight | number | 2 | Strichstärke von 1 bis 3 im 24er-Raster, unter 24 px optisch ausgeglichen. |
absoluteWeight | boolean | false | Hält den Strich bei jeder Größe auf weight Pixeln. |
corners | round, sharp | round | Abgerundete oder spitze Verbindungen und Enden. |
variant | outline, duotone, solid | outline | Stilachse; solid entsteht aus den geschlossenen Formen. |
rotate | number | 0 | Drehung in Grad. |
flipX | boolean | false | Horizontal spiegeln. |
flipY | boolean | false | Vertikal spiegeln. |
mirrorRtl | boolean | false | In Layouts von rechts nach links spiegeln. |
animate | draw, pop, wiggle, spin, pulse, bounce, shake | keiner | Voreinstellung für den lebendigen Zustand. |
trigger | mount, hover, click, state | mount | Wann die Animation oder der Morph abläuft. |
active | boolean | false | Der Zustand für den Auslöser state. |
duration | number (ms) | je nach Voreinstellung | Dauer der Animation oder des Morphs. |
delay | number (ms) | 0 | Verzögerung der Animation oder des Morphs. |
loop | boolean, number | false | Endlos oder eine bestimmte Anzahl von Malen wiederholen (spin und pulse laufen standardmäßig in Schleife). |
modifier | plus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dot | keiner | Badge mit automatischer Aussparung. |
modifierCorner | top-left, top-right, bottom-left, bottom-right | bottom-right | Ecke des Badges. |
morphTo | name, data | keiner | Ziel des Morphs; der Auslöser bestimmt, wann es erscheint. |
title | string | keiner | Zugänglicher Name: title, role img und aria-label. |
decorative | boolean | true ohne title | Verbirgt das Icon vor assistiven Technologien. |
Neben den gemeinsamen Props nimmt gf-icon folgende Inputs entgegen: name (beliebige Angabe), icon (Icon-Daten), icons (2 bis 10 Teile einer Fusion), layout und gap.
Stolperfallen
- provideGlyphFox in einer Komponente
- Die Funktion gibt Environment Providers zurück, die in die Anwendungskonfiguration, ein NgModule oder eine Route gehören. In den
providerseiner Komponente weist Angular sie zurück. - Eine lazy geladene Route verliert die Root-Standardwerte
- Route-Provider ersetzen die Konfiguration für alles unterhalb der Route, weil Multi-Provider nicht über Injector-Grenzen hinweg zusammengeführt werden. Übernehmen Sie ein gemeinsames Konfigurationsobjekt per Spread-Syntax in jeden Aufruf.
- aria-label auf dem Host
- Ein
aria-labelaufgf-iconmacht das innere SVG nicht dekorativ (role="img"), aber das Label bleibt auf dem Host-Element, das keine Rolle hat, sodass Screenreader womöglich nichts ansagen. Verwenden Sie für ein bedeutungstragendes Icon den Inputtitle, oder beschriften Sie den übergeordneten Button und lassen Sie das Icon dekorativ. - Eine Fusion, die nie erscheint
- Ist ein Teil von
[icons]nicht registriert, wartet die gesamte Fusion darauf und bleibt in der Zwischenzeit leer, auch auf dem Server. Registrieren Sie jeden Teil. - Versehentlich das gesamte Set registrieren
provideGlyphFox({ icons })mit dem vollständigen Record ausglyphfoxhält jedes Icon im Bundle. Importieren Sie stattdessen die benannten Datenexporte, die Sie brauchen.
Häufige Fragen
Kann ich glyphfox-angular in einer NgModule-basierten App verwenden?
Ja. GlyphFoxIcon ist eine Standalone-Komponente. Fügen Sie sie daher zu den imports des NgModule hinzu, das Ihre Komponenten deklariert, und tragen Sie provideGlyphFox(...) in die providers Ihres Root-Moduls ein.
Welche Angular-Versionen werden unterstützt?
Angular 17 und neuer, also der Peer-Dependency-Bereich des Pakets. Behalten Sie unter 17 und 18 standalone: true bei den Komponenten bei, die GlyphFoxIcon importieren; ab 19 ist das der Standard. Selbstschließende Tags wie <gf-icon name="home" /> funktionieren in jeder unterstützten Version.