Frameworks

Icons in Svelte 5

glyphfox/svelte liefert eine Svelte-5-Komponente pro Icon sowie Icon, Fusion und MorphIcon, alle mit denselben Props wie jedes andere glyphfox-Paket.

Installation

terminal
npm install glyphfox

Die Komponenten sind .svelte-Quelldateien, die Ihre App kompiliert. Der Build braucht daher Svelte 5 und dessen Compiler, meist über vite-plugin-svelte, das in jedem SvelteKit-Projekt bereits vorhanden ist. Sie sind mit Runes wie $props und $state geschrieben, daher kann Svelte 4 sie nicht kompilieren.

svelte 5 ist eine optionale Peer-Dependency von glyphfox: Sie brauchen es nur, wenn Sie glyphfox/svelte importieren. Das Paket stellt diesen Einstiegspunkt unter der Export-Bedingung svelte bereit, an der vite-plugin-svelte eine Svelte-Bibliothek erkennt, um deren Komponenten für Browser und Server zu kompilieren.

Die Komponenten verwenden

Toolbar.svelte
<script>
  import { HomeIcon, SearchIcon, BellIcon } from 'glyphfox/svelte';

  let { unread = 0 } = $props();
</script>

<nav class="toolbar">
  <a href="/" aria-label="Home"><HomeIcon /></a>
  <SearchIcon size={20} weight={1.5} class="muted" />
  <BellIcon variant="duotone" secondaryColor="#ff7a1a" modifier={unread ? 'dot' : undefined} />
</nav>

Jedes Icon ist eine Komponente, die nach dem Icon in PascalCase mit dem Suffix Icon benannt ist: Aus arrow-right wird ArrowRightIcon, aus loader-circle wird LoaderCircleIcon. Props verwenden die Namen in camelCase, genau wie in JavaScript, weil Svelte Props so an Komponenten übergibt, wie sie geschrieben sind.

class und style werden auf das SVG-Element angewendet, und jedes andere Attribut, etwa aria-*, data-* oder id, wird per Spread an das Element weitergereicht. Event-Handler sind in Svelte 5 Props: onclick, onmouseenter und onmouseleave werden weitergeleitet und laufen auch dann, wenn am Icon ein Klick- oder Hover-Auslöser gesetzt ist.

Striche verwenden currentColor, daher folgt das Icon der CSS-Eigenschaft color seines Elternelements. Die Prop color setzt eine feste Farbe auf dem SVG-Element.

Strichstärke, Ecken und Stil

weight legt den Strich von 1 bis 3 fest, corners wechselt zwischen abgerundeten und spitzen Linienverbindungen, und variant wählt outline, duotone oder solid. Unter 24 px wird der Strich leicht verstärkt, damit kleine Icons ihre Präsenz behalten; absoluteWeight behält den exakten Wert bei.

Axes.svelte
<script>
  import { FolderIcon } from 'glyphfox/svelte';
</script>

<FolderIcon weight={1} />
<FolderIcon weight={3} corners="sharp" />
<FolderIcon variant="duotone" secondaryColor="#ff7a1a" />
<FolderIcon variant="solid" />
<FolderIcon size={16} weight={1.5} absoluteWeight />

Icon, Modifier und Fusion

Icon rendert jede Angabe in der Namenssyntax: einen Namen, ein Modifier-Badge (file+check, mit @tl, @tr, @bl oder @br für die Ecke), eine Fusion (cloud&lock:overlap) oder einen Stil (heart/solid). Fusion nimmt eine Liste von Namen und ein Layout entgegen: overlap, side, stack, grid, orbit, badge oder inside.

Icon-Komponenten bringen ihre eigenen Daten mit: Jede registriert ihr Icon in einem <script module>-Block. Hinter einem Namen in einem String steht kein Import, registrieren Sie solche Namen deshalb einmal mit registerIcons. Modifier-Badges zeichnet die Engine selbst, sie müssen nicht registriert werden.

src/lib/icons.js
import { registerIcons } from 'glyphfox/svelte';
import file from 'glyphfox/icons/file';
import cloud from 'glyphfox/icons/cloud';
import lock from 'glyphfox/icons/lock';
import menu from 'glyphfox/icons/menu';
import x from 'glyphfox/icons/x';
import play from 'glyphfox/icons/play';
import pause from 'glyphfox/icons/pause';

// Every name used in a string: Icon, Fusion, MorphIcon, morphStore and morphTo.
registerIcons([file, cloud, lock, menu, x, play, pause]);
FileStatus.svelte
<script>
  import './lib/icons.js';
  import { Icon, Fusion } from 'glyphfox/svelte';

  let { saved = false } = $props();
</script>

<Icon name={saved ? 'file+check' : 'file'} />
<Icon name="file+alert@tr" variant="duotone" />
<Fusion icons={['cloud', 'lock']} layout="overlap" gap={1} />

Importieren Sie das Registrierungsmodul in Ihrer Einstiegsdatei oder Ihrer Root-Komponente. Eine Komponente kann auch in ihrem eigenen <script module>-Block registrieren, der einmal beim Laden des Moduls ausgeführt wird statt einmal pro Instanz.

MorphIcon, morphTo und morphStore

MorphIcon animiert, sobald sich sein name ändert, und passt damit ganz natürlich zu $state:

MenuButton.svelte
<script>
  import { MorphIcon } from 'glyphfox/svelte';

  let open = $state(false);
</script>

<button type="button" aria-label="Menu" aria-expanded={open} onclick={() => (open = !open)}>
  <MorphIcon name={open ? 'x' : 'menu'} duration={300} />
</button>

Jede Icon-Komponente akzeptiert außerdem morphTo mit einem Auslöser: click wechselt bei jedem Klick hin und her, hover folgt dem Zeiger, state folgt active, und der Standardwert mount morpht einmal nach dem Mounten.

Triggers.svelte
<script>
  import { HeartIcon, PlayIcon } from 'glyphfox/svelte';

  let { playing = false } = $props();
</script>

<HeartIcon morphTo="heart/solid" trigger="click" />
<PlayIcon morphTo="pause" trigger="state" active={playing} />

morphStore(initial, options) ist ein Store für eigenes Rendering. Rufen Sie set(name) auf, um einen Morph zu starten, und lesen Sie $store, einen Frame mit icon und variant, den Sie an Icon übergeben können.

PlayToggle.svelte
<script>
  import './lib/icons.js';
  import { Icon, morphStore } from 'glyphfox/svelte';

  const frame = morphStore('play', { duration: 250 });
  let playing = $state(false);

  function toggle() {
    playing = !playing;
    frame.set(playing ? 'pause' : 'play');
  }
</script>

<button type="button" aria-label="Play" aria-pressed={playing} onclick={toggle}>
  {#if $frame}<Icon icon={$frame.icon} variant={$frame.variant} />{/if}
</button>

Von Hand abgestimmte Paare decken menu zu x, play zu pause, plus zu check, sun zu moon, eye zu eye-off, bell zu bell-ring, heart zu heart/solid, copy zu check, lock zu unlock und wifi zu wifi-off ab. Andere Paare morphen über eine automatische Zuordnung.

Zustandsgesteuerte Animationen

Lebendige Zustände sind Presets, die das Icon verstehen: draw zeichnet die Striche in Zeichenreihenfolge nach, shake schwingt von oben, und pop, wiggle, spin, pulse und bounce vervollständigen das Set. Mit trigger="state" läuft eine Animation, solange active true ist, und folgt so direkt Ihren Runes.

Inbox.svelte
<script>
  import { BellIcon, LoaderCircleIcon, SparklesIcon } from 'glyphfox/svelte';

  let { hasNews = false, loading = false } = $props();
</script>

<BellIcon animate="shake" trigger="state" active={hasNews} />
{#if loading}<LoaderCircleIcon animate="spin" />{/if}
<SparklesIcon animate="draw" trigger="hover" />

Jedes Preset ist ein kleines Stylesheet im SVG-Element, braucht also keinen CSS-Import und stoppt für Besucher, die reduzierte Bewegung bevorzugen. Der Leitfaden zu animierten Icons behandelt Dauer, Verzögerungen und Schleifen.

Deep Imports und Typen

glyphfox/svelte re-exportiert jede Komponente, und Produktionsbuilds verwerfen die, die Sie nicht importieren. Ein Deep Import wird zu einer einzelnen .svelte-Datei aufgelöst, sodass Ihr Compiler und Ihr Dev-Server nur den Code sehen, den Sie tatsächlich verwenden:

Logo.svelte
<script>
  import FoxIcon from 'glyphfox/svelte/icons/fox';
</script>

<FoxIcon size={32} variant="duotone" title="glyphfox" />

Die Typen werden mit dem Paket ausgeliefert. Jede Komponente ist eine Component<GlyphProps>, wobei GlyphProps die gemeinsamen Props plus beliebige SVG-Attribute umfasst, sodass ein typisierter Wrapper alles weiterreichen kann:

AppIcon.svelte
<script lang="ts">
  import { Icon, type GlyphProps } from 'glyphfox/svelte';
  import type { IconName } from 'glyphfox';

  let { name, ...rest }: GlyphProps & { name: IconName } = $props();
</script>

<Icon {name} weight={1.75} {...rest} />

Als IconName typisierte Namen werden beim Kompilieren geprüft, müssen aber trotzdem registriert sein, damit sie gerendert werden: siehe die Stolperfallen unten und den Leitfaden zum Tree-Shaking.

Props

Alle Icon-Komponenten sowie Icon, Fusion und MorphIcon akzeptieren die gemeinsamen Props in camelCase.

PropTypStandardBeschreibung
sizenumber, string24Breite und Höhe; Zahlen sind Pixel.
colorstringcurrentColorHauptfarbe.
secondaryColorstringcolorFarbe der Duotone-Ebene und der Solid-Füllung.
secondaryOpacitynumber0.3 / 1Deckkraft der Duotone-Ebene oder der Solid-Füllung.
weightnumber2Strichstärke von 1 bis 3 im 24er-Raster, unter 24 px optisch ausgeglichen.
absoluteWeightbooleanfalseHält den Strich bei jeder Größe auf weight Pixeln.
cornersround, sharproundAbgerundete oder spitze Verbindungen und Enden.
variantoutline, duotone, solidoutlineStilachse; solid entsteht aus den geschlossenen Formen.
rotatenumber0Drehung in Grad.
flipXbooleanfalseHorizontal spiegeln.
flipYbooleanfalseVertikal spiegeln.
mirrorRtlbooleanfalseIn Layouts von rechts nach links spiegeln.
animatedraw, pop, wiggle, spin, pulse, bounce, shakekeinerVoreinstellung für den lebendigen Zustand.
triggermount, hover, click, statemountWann die Animation oder der Morph abläuft.
activebooleanfalseDer Zustand für den Auslöser state.
durationnumber (ms)je nach VoreinstellungDauer der Animation oder des Morphs.
delaynumber (ms)0Verzögerung der Animation oder des Morphs.
loopboolean, numberfalseEndlos oder eine bestimmte Anzahl von Malen wiederholen (spin und pulse laufen standardmäßig in Schleife).
modifierplus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dotkeinerBadge mit automatischer Aussparung.
modifierCornertop-left, top-right, bottom-left, bottom-rightbottom-rightEcke des Badges.
morphToname, datakeinerZiel des Morphs; der Auslöser bestimmt, wann es erscheint.
titlestringkeinerZugänglicher Name: title, role img und aria-label.
decorativebooleantrue ohne titleVerbirgt das Icon vor assistiven Technologien.

Icon ergänzt name, icon (Icon-Daten) und gap. Fusion ergänzt icons, layout, gap, scale und offsets. MorphIcon ergänzt name und icon. Kindinhalte (children) werden innerhalb des SVG-Elements gerendert.

Stolperfallen

Props in kebab-case bewirken nichts
secondary-color="#ff7a1a" ist in Svelte nicht die Prop secondaryColor: Es wird per Spread als einfaches Attribut an das SVG-Element weitergereicht, und das Icon behält seinen Standardwert. Verwenden Sie überall die Namen in camelCase.
Namen, die in der Entwicklung funktionieren und im Produktionsbuild verschwinden
Während der Entwicklung bündelt Vite das Paket vorab, und jeder Name wird aufgelöst. Ein Produktionsbuild behält nur, was Sie importieren, und Vite bündelt den On-Demand-Loader in node_modules nicht mit, daher rendern nicht registrierte Namen in Icon, Fusion, MorphIcon, morphTo und morphStore ein leeres SVG. Registrieren Sie sie.
morphStore vor der Registrierung erstellt
morphStore löst einen Namen auf, wenn Sie set aufrufen. Ist der Name in diesem Moment nicht registriert, wartet der Store stattdessen auf den Loader. Importieren Sie das Registrierungsmodul, bevor Sie den Store erstellen, wie im Beispiel oben.
Wildcard-Importe und dynamische Zugriffe
import * as icons from 'glyphfox/svelte' mit icons[name] hält jede Komponente im Bundle. Legen Sie eine Map der Komponenten an, die Sie brauchen, oder verwenden Sie Icon mit registrierten Namen.

Häufige Fragen

Kann ich glyphfox in einem Svelte-4-Projekt verwenden?

Nicht mit glyphfox/svelte, das den Compiler von Svelte 5 benötigt. In einer Svelte-4-App funktioniert die Web Component <glyph-fox> mit denselben Props als Attributen; mehr dazu im Leitfaden zu Web Components.

Benötigen die Komponenten SvelteKit?

Nein. Jedes Svelte-5-Setup, das .svelte-Dateien kompiliert, funktioniert, etwa reines Vite mit vite-plugin-svelte. SvelteKit ergänzt serverseitiges Rendering und Prerendering, beschrieben im SvelteKit-Leitfaden.

Icons in diesem Leitfaden