Un seul jeu d'icônes pour tous les frameworks
Chaque paquet accepte les mêmes props (size, color, weight, corners, variant, animate, modifier, morphTo et les autres) et produit le même SVG. Choisissez votre framework, ou suivez une recette pour votre méta-framework.
Paquets
Tout est livré dans le paquet glyphfox (Angular a aussi glyphfox-angular). Chaque framework est une peer dependency facultative, utilisée uniquement quand vous importez son point d'entrée. Les composants d'icône sont compatibles tree shaking et chaque point d'entrée est typé.
| Framework | Import | Rendu |
|---|---|---|
| React | glyphfox/react | Composants client (marqués 'use client'), forwardRef |
| React Server Components | glyphfox/react/server | Icon et Fusion sans hooks, zéro JavaScript |
| Vue 3 | glyphfox/vue | Composants et useMorph |
| Svelte 5 | glyphfox/svelte | Sources .svelte et morphStore |
| Angular | glyphfox-angular | Composant standalone et provider de registre |
| Solid | glyphfox/solid | Composants et useMorph, côté serveur et client |
| Preact | glyphfox/preact | Composants et hooks, sans couche compat |
| Qwik | glyphfox/qwik | Composants légers qui reprennent leur exécution sans JavaScript |
| Lit | glyphfox/lit | Éléments Lit (<gf-file>, <gf-glyph>) |
| Astro | glyphfox/astro | Composants .astro, SVG statique |
| React Native | glyphfox/native | Composants react-native-svg |
| Ember | glyphfox/ember | Helpers pour .gjs, .gts et les templates classiques |
| Composant web | glyphfox/web | <glyph-fox>, aussi via le CDN |
| Tailwind CSS | glyphfox/tailwind | Classes de masque CSS |
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>
);
}Aucune configuration du compilateur JSX ni condition d'export particulière : le même module effectue le rendu dans SolidStart, côté serveur comme dans le navigateur. class, style, ref et les événements sont transmis au svg. useMorph(accessor) renvoie un accessor de données d'icône qui se transforment à chaque changement de nom.
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)} />
</>
);
}La même API que React (Icon, Fusion, MorphIcon, useMorph), construite sur preact et preact/hooks : elle n'embarque donc pas preact/compat. Avec Preact 11, une ref atteint l'élément svg. class et className fonctionnent tous les deux.
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>
);
});Conçu pour Qwik 2 (@qwik.dev/core). Les icônes sont des composants légers : elles sont rendues sur le serveur et reprennent leur exécution sans rien télécharger. Les états animés et morphTo reposent sur CSS, active bascule trigger="state" et trigger="click" utilise un minuscule gestionnaire inline. Les noms utilisés par Icon, morphTo et Fusion doivent être enregistrés : les composants d'icône enregistrent leur icône, et registerIcons([iconX]) (ou registerIcons(icons) avec icons de glyphfox pour tout le jeu) couvre les noms que vous n'écrivez que sous forme de chaînes.
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);Rien n'est enregistré à l'import : defineIcons(list, { prefix }) définit les éléments que vous utilisez ({ prefix: 'my' } donne <my-file>). Les attributs sont en kebab-case (secondary-color, flip-x, morph-to), les propriétés en camelCase ; l'attribut animate correspond à la propriété animatePreset, car animate() est une méthode de tout élément, et animation joue l'animation conçue pour l'icône, comme dans tous les paquets. class et style stylisent l'élément hôte. Les éléments sont rendus dans le shadow DOM et fonctionnent avec @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>Les composants produisent du SVG statique sur le serveur et n'envoient aucun JavaScript. Toutes les icônes du jeu sont disponibles pour les noms de Icon, morphTo et Fusion. class (et class:list), style sous forme de chaîne ou d'objet, et tout autre attribut sont transmis au svg. Les déclencheurs hover, mount et state reposent sur CSS ; trigger="click" utilise un minuscule gestionnaire inline.
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>
);
}Les composants produisent des éléments react-native-svg avec les mêmes props. Il n'y a pas de CSS en natif : les états animés sont donc échantillonnés image par image à partir des mêmes préréglages, et les morphings sont interpolés ; les deux respectent le réglage de réduction des animations. trigger="click" se joue à l'appui et trigger="hover" pendant l'appui. title définit le libellé d'accessibilité, style et les autres props atteignent le Svg, et les refs sont transmises. Metro résout l'export glyphfox/native grâce aux package exports, activés par défaut depuis React Native 0.79.
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>De simples helpers de fonction (Ember 4.5 et versions ultérieures) : ils ne demandent aucune configuration d'addon et fonctionnent dans les fichiers .gjs, .gts et les templates classiques. Ils renvoient du markup de confiance : les props communes, class, style et les autres attributs sont des arguments nommés. Les noms utilisés par Glyph, morphTo et Fusion doivent être enregistrés : les helpers d'icône enregistrent leur icône, et registerIcons([iconCloud]) (ou registerIcons(icons)) couvre le reste. Les déclencheurs hover, mount et state reposent sur CSS ; trigger="click" utilise un minuscule gestionnaire inline.