Ein Icon-Set für jedes Framework
Jedes Paket nimmt dieselben Props an (size, color, weight, corners, variant, animate, modifier, morphTo und alle weiteren) und rendert dasselbe SVG. Wähle dein Framework oder folge einem Rezept für dein Meta-Framework.
Pakete
Alles steckt im Paket glyphfox (für Angular gibt es zusätzlich glyphfox-angular). Jedes Framework ist eine optionale Peer-Dependency und wird nur genutzt, wenn du seinen Einstiegspunkt importierst. Die Icon-Komponenten sind Tree-Shaking-fähig und jeder Einstiegspunkt ist typisiert.
| Framework | Import | Rendert |
|---|---|---|
| React | glyphfox/react | Client-Komponenten (mit 'use client' markiert), forwardRef |
| React Server Components | glyphfox/react/server | Icon und Fusion ohne Hooks, kein JavaScript |
| Vue 3 | glyphfox/vue | Komponenten und useMorph |
| Svelte 5 | glyphfox/svelte | .svelte-Quelldateien und morphStore |
| Angular | glyphfox-angular | Standalone-Komponente und Registry-Provider |
| Solid | glyphfox/solid | Komponenten und useMorph, auf Server und Client |
| Preact | glyphfox/preact | Komponenten und Hooks, ohne compat-Schicht |
| Qwik | glyphfox/qwik | Leichtgewichtige Komponenten, die ohne JavaScript fortgesetzt werden |
| Lit | glyphfox/lit | Lit-Elemente (<gf-file>, <gf-glyph>) |
| Astro | glyphfox/astro | .astro-Komponenten, statisches SVG |
| React Native | glyphfox/native | react-native-svg-Komponenten |
| Ember | glyphfox/ember | Helper für .gjs, .gts und klassische Templates |
| Webkomponente | glyphfox/web | <glyph-fox>, auch über das CDN |
| Tailwind CSS | glyphfox/tailwind | CSS-Maskenklassen |
Solid
import { createSignal } from 'solid-js';
import { HomeIcon, HeartIcon, Fusion, MorphIcon } from 'glyphfox/solid';
export function Toolbar() {
const [open, setOpen] = createSignal(false);
return (
<nav>
<HomeIcon size={20} class="nav-icon" />
<HeartIcon animate="pop" trigger="click" variant="duotone" />
<Fusion icons={['cloud', 'lock']} layout="overlap" />
<button onClick={() => setOpen(!open())}>
<MorphIcon name={open() ? 'x' : 'menu'} />
</button>
</nav>
);
}Keine JSX-Compiler-Konfiguration und keine spezielle Export-Bedingung: Dasselbe Modul rendert in SolidStart auf dem Server und im Browser. class, style, ref und Events werden an das svg-Element durchgereicht. useMorph(accessor) liefert einen Accessor mit Icon-Daten, die sich bei jeder Namensänderung verwandeln.
Preact
import { useState } from 'preact/hooks';
import { FileIcon, HeartIcon, MorphIcon } from 'glyphfox/preact';
export function App() {
const [copied, setCopied] = useState(false);
return (
<>
<FileIcon size={20} weight={1.5} modifier="check" class="doc" />
<HeartIcon animate="pop" trigger="click" />
<MorphIcon name={copied ? 'check' : 'copy'} onClick={() => setCopied(true)} />
</>
);
}Dieselbe API wie React (Icon, Fusion, MorphIcon, useMorph), gebaut auf preact und preact/hooks, sodass preact/compat nicht mitgeladen wird. Unter Preact 11 erreicht eine ref das svg-Element. Sowohl class als auch className funktionieren.
Qwik
import { component$, useSignal } from '@qwik.dev/core';
import { iconX } from 'glyphfox';
import { BellIcon, HomeIcon, MenuIcon, registerIcons } from 'glyphfox/qwik';
registerIcons([iconX]); // names used only by morphTo, Icon or Fusion
export default component$(() => {
const open = useSignal(false);
return (
<header>
<HomeIcon size={20} class="logo" />
<BellIcon animate="shake" trigger="hover" />
<button onClick$={() => (open.value = !open.value)}>
<MenuIcon morphTo="x" trigger="state" active={open.value} />
</button>
</header>
);
});Für Qwik 2 gebaut (@qwik.dev/core). Die Icons sind leichtgewichtige Komponenten: Sie rendern auf dem Server und werden fortgesetzt, ohne etwas herunterzuladen. Lebendige Zustände und morphTo laufen über CSS, active schaltet trigger="state" um, und trigger="click" nutzt einen winzigen Inline-Handler. Namen, die Icon, morphTo und Fusion verwenden, müssen registriert werden: Icon-Komponenten registrieren ihr Icon, und registerIcons([iconX]) (oder registerIcons(icons) mit icons aus glyphfox für das ganze Set) deckt Namen ab, die du nur als Strings schreibst.
Lit
import { LitElement, html } from 'lit';
import { defineIcons, FileIcon, HeartIcon, Icon, Fusion, MorphIcon } from 'glyphfox/lit';
// <gf-file>, <gf-heart>, <gf-glyph>, <gf-fusion> and <gf-morph>
defineIcons([FileIcon, HeartIcon, Icon, Fusion, MorphIcon]);
class AppBar extends LitElement {
static properties = { open: { type: Boolean } };
render() {
return html`
<gf-file size="20" weight="1.5" modifier="check"></gf-file>
<gf-heart animate="pop" trigger="click" secondary-color="#ff7a1a"></gf-heart>
<gf-glyph name="cloud&lock:overlap"></gf-glyph>
<gf-morph .name=${this.open ? 'x' : 'menu'} @click=${() => (this.open = !this.open)}></gf-morph>
`;
}
}
customElements.define('app-bar', AppBar);Beim Import wird nichts registriert: defineIcons(list, { prefix }) definiert die Elemente, die du verwendest ({ prefix: 'my' } ergibt <my-file>). Attribute sind in kebab-case (secondary-color, flip-x, morph-to), Properties in camelCase; das Attribut animate ist die Property animatePreset, weil animate() eine Methode jedes Elements ist, und animation spielt wie in jedem Paket die gestaltete Animation ab. class und style gestalten das Host-Element. Die Elemente rendern im Shadow DOM und funktionieren mit @lit-labs/ssr.
Astro
---
import { HomeIcon, BellIcon, Icon, Fusion } from 'glyphfox/astro';
import SearchIcon from 'glyphfox/astro/icons/search';
---
<nav>
<HomeIcon size={20} class:list={['nav-icon', { active: true }]} />
<SearchIcon weight={1.5} />
<BellIcon animate="shake" trigger="hover" />
<Icon name="file+check@tr" variant="duotone" />
<Fusion icons={['cloud', 'lock']} layout="overlap" />
</nav>Die Komponenten rendern statisches SVG auf dem Server und liefern kein JavaScript aus. Jedes Icon des Sets steht für Icon-Namen, morphTo und Fusion bereit. class (und class:list), style als String oder Objekt sowie jedes andere Attribut werden an das svg-Element durchgereicht. Die Auslöser hover, mount und state laufen über CSS; trigger="click" nutzt einen winzigen Inline-Handler.
React Native
npm install glyphfox react-native-svg
import { HomeIcon, BellIcon, HeartIcon, MorphIcon } from 'glyphfox/native';
export function Tabs({ open, unread }) {
return (
<View style={{ flexDirection: 'row', gap: 16 }}>
<HomeIcon size={28} color="#ff7a1a" />
<BellIcon animate="shake" trigger="state" active={unread > 0} />
<HeartIcon animate="pop" trigger="click" variant="duotone" />
<MorphIcon name={open ? 'x' : 'menu'} style={{ marginLeft: 'auto' }} />
</View>
);
}Die Komponenten rendern react-native-svg-Elemente mit denselben Props. Nativ gibt es kein CSS, daher werden lebendige Zustände Frame für Frame aus denselben Animationen abgetastet und Morphs interpoliert; beides folgt der Einstellung für reduzierte Bewegung. trigger="click" spielt beim Antippen ab und trigger="hover", solange gedrückt wird. title setzt das Accessibility-Label, style und weitere Props erreichen das Svg, und Refs werden weitergereicht. Metro löst den Export glyphfox/native über Package Exports auf, die seit React Native 0.79 standardmäßig aktiv sind.
Ember
import { FileIcon, BellIcon, Glyph, Fusion } from 'glyphfox/ember';
<template>
{{FileIcon size=20 weight=1.5 class="toolbar-icon"}}
{{BellIcon animate="shake" trigger="hover"}}
{{Glyph "file+check@tr" variant="duotone"}}
{{Fusion "cloud" "lock" layout="overlap"}}
</template>Einfache Funktions-Helper (Ember 4.5 und neuer), daher brauchen sie keine Addon-Konfiguration und funktionieren in .gjs, .gts und klassischen Templates. Sie geben vertrauenswürdiges Markup zurück: Die gemeinsamen Props, class, style und weitere Attribute sind benannte Argumente. Namen, die Glyph, morphTo und Fusion verwenden, müssen registriert werden: Icon-Helper registrieren ihr Icon, und registerIcons([iconCloud]) (oder registerIcons(icons)) deckt den Rest ab. Die Auslöser hover, mount und state laufen über CSS; trigger="click" nutzt einen winzigen Inline-Handler.