Icônes Preact
Preact exécute les composants React de glyphfox via preact/compat, sans aucune modification de code. Si votre application ne charge pas compat, le web component glyph-fox fonctionne avec Preact seul.
Installation
Installez glyphfox à côté de Preact. preact/compat fait partie du package preact : il n'y a donc aucune seconde dépendance à ajouter.
npm install glyphfox
Vous disposez de deux façons d'afficher les icônes, qui partagent le même moteur de rendu et les mêmes props :
- Les composants de
glyphfox/react, exécutés par Preact via compat. Idéal si votre application définit déjà un alias pour React ou utilise d'autres packages React. - Le web component
<glyph-fox>, qui se passe entièrement de compat. Idéal si vous gardez Preact léger et n'avez besoin que des icônes.
Comment les composants fonctionnent sous Preact
Le point d'entrée React importe exactement six éléments depuis react : createElement, forwardRef, useState, useEffect, useMemo et useRef. compat les implémente tous : dès que le bundler résout react vers preact/compat, les composants sont rendus par le moteur de rendu de Preact lui-même, dans le même arbre et avec les mêmes hooks que le reste de votre application.
Les attributs SVG sont créés avec les noms React, comme strokeWidth et strokeLinecap, et compat les reconvertit en stroke-width et stroke-linecap sur l'élément. Les animations des états vivants sont un élément <style> placé dans le SVG et défini via dangerouslySetInnerHTML, que Preact prend également en charge.
Vite
Le preset officiel de Preact pour Vite définit déjà des alias qui redirigent react, react-dom et le runtime JSX vers compat. Rien d'autre n'est nécessaire :
import { defineConfig } from 'vite'; import preact from '@preact/preset-vite'; export default defineConfig({ plugins: [preact()], });
webpack et esbuild
Avec webpack, ajoutez les alias dans resolve.alias. glyphfox n'a besoin que de react, mais définir des alias pour l'ensemble garantit que tout autre package React de votre application utilise la même instance de Preact :
module.exports = {
resolve: {
alias: {
react: 'preact/compat',
'react-dom/test-utils': 'preact/test-utils',
'react-dom': 'preact/compat',
'react/jsx-runtime': 'preact/jsx-runtime',
},
},
};esbuild propose la même option. Activez en même temps le découpage du code (code splitting), sinon esbuild intègre directement chaque module d'icône que le chargeur à la demande peut atteindre (le guide du tree shaking explique pourquoi) :
import * as esbuild from 'esbuild'; await esbuild.build({ entryPoints: ['src/main.jsx'], bundle: true, splitting: true, format: 'esm', outdir: 'dist', jsx: 'automatic', jsxImportSource: 'preact', alias: { react: 'preact/compat', 'react-dom': 'preact/compat' }, });
TypeScript
Les déclarations de glyphfox/react sont écrites pour les types React (ForwardRefExoticComponent, SVGProps). Faites pointer react vers compat dans paths pour qu'elles se résolvent vers les types de Preact. Si le vérificateur de types signale encore des problèmes dans les fichiers de déclaration des dépendances, laissez skipLibCheck activé, comme le font la plupart des templates Preact :
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact",
"skipLibCheck": true,
"paths": {
"react": ["./node_modules/preact/compat/"],
"react-dom": ["./node_modules/preact/compat/"]
}
}
}Utiliser les composants
Importez les icônes par leur nom et utilisez les hooks de Preact autour d'elles comme d'habitude. Tout le contenu du guide React s'applique : Icon avec la syntaxe de nom, Fusion, MorphIcon, useMorph, les modificateurs et les refs.
import { useState } from 'preact/hooks'; import { HeartIcon, MorphIcon, Fusion } from 'glyphfox/react'; export function Card() { const [liked, setLiked] = useState(false); return ( <article className="card"> <button type="button" onClick={() => setLiked(!liked)} aria-pressed={liked}> <HeartIcon animate="pop" trigger="state" active={liked} variant={liked ? 'solid' : 'outline'} /> Like </button> <MorphIcon name={liked ? 'check' : 'plus'} duration={250} /> <Fusion icons={['user', 'shield']} layout="badge" /> </article> ); }
Les refs passent par le forwardRef de compat : ref sur une icône pointe donc vers l'élément <svg> rendu, prêt pour getBoundingClientRect() ou l'API Web Animations. Les gestionnaires d'événements comme onClick et les attributs comme data-* sont transmis directement à l'élément, exactement comme dans React.
Avec les signaux, passez la valeur plutôt que le signal. Preact déballe les signaux liés aux attributs du DOM, mais un composant d'icône reçoit l'objet signal lui-même et lit ses props comme des valeurs simples, si bien qu'il ne lirait pas la bonne valeur et ne se mettrait pas à jour quand le signal change :
import { signal } from '@preact/signals'; import { CloudIcon } from 'glyphfox/react'; const syncing = signal(false); export function Status() { return <CloudIcon modifier={syncing.value ? 'sync' : undefined} />; }
Sans compat : le web component
L'élément personnalisé (custom element) <glyph-fox> affiche les mêmes icônes avec les mêmes props, sous forme d'attributs en kebab-case. Importez glyphfox/web une fois pour le définir avec toutes les icônes, ou définissez-le vous-même et enregistrez uniquement les icônes que vous utilisez :
import { defineGlyphFox } from 'glyphfox/web/element'; import { registerIcons } from 'glyphfox/core'; import { iconHome, iconSearch, iconMenu, iconX } from 'glyphfox'; registerIcons([iconHome, iconSearch, iconMenu, iconX]); defineGlyphFox();
import { useState } from 'preact/hooks'; import './icons.js'; export function Header() { const [open, setOpen] = useState(false); return ( <header> <glyph-fox name="home" size="20"></glyph-fox> <glyph-fox name="search" weight="1.5" title="Search"></glyph-fox> <button type="button" onClick={() => setOpen(!open)} aria-expanded={open} aria-label="Menu"> <glyph-fox name={open ? 'x' : 'menu'} morph></glyph-fox> </button> </header> ); }
Preact applique les props inconnues des éléments personnalisés sous forme d'attributs, ce qu'écoute justement l'élément : les valeurs dynamiques comme name={open ? 'x' : 'menu'} fonctionnent donc, et l'attribut morph anime chaque changement. En TypeScript, ajoutez glyph-fox aux JSX.IntrinsicElements de Preact dans un fichier de déclaration, comme la documentation de Preact le décrit pour tout élément personnalisé.
Les attributs, le dimensionnement dans le shadow DOM et le rendu côté serveur de l'élément sont traités dans le guide des web components.
Quelle approche est la plus légère ?
Les deux approches embarquent le même moteur (rendu, axes, modificateurs, fusion et morph) : les icônes coûtent donc à peu près la même chose dans les deux cas. La vraie différence, c'est compat : si votre application le charge déjà pour d'autres packages, les composants n'ajoutent rien de nouveau ; sinon, le web component vous en dispense. Dans les deux cas, importez uniquement les icônes que vous utilisez, comme montré ci-dessus.
Props
Les composants acceptent ces props. Sur <glyph-fox>, les mêmes props sont des attributs en kebab-case (secondary-color, flip-x, morph-to), auxquels s'ajoutent name, layout, gap et morph.
| Prop | Type | Par défaut | Description |
|---|---|---|---|
size | number, string | 24 | Largeur et hauteur ; les nombres sont en pixels. |
color | string | currentColor | Couleur principale. |
secondaryColor | string | color | Couleur du calque duotone et du remplissage plein. |
secondaryOpacity | number | 0.3 / 1 | Opacité du calque duotone ou du remplissage plein. |
weight | number | 2 | Trait de 1 à 3 sur la grille de 24, avec compensation optique en dessous de 24 px. |
absoluteWeight | boolean | false | Garde le trait à weight pixels quelle que soit la taille. |
corners | round, sharp | round | Jointures et extrémités arrondies ou vives. |
variant | outline, duotone, solid | outline | Axe de style ; solid vient des formes fermées. |
rotate | number | 0 | Rotation en degrés. |
flipX | boolean | false | Miroir horizontal. |
flipY | boolean | false | Miroir vertical. |
mirrorRtl | boolean | false | Miroir dans les mises en page de droite à gauche. |
animate | draw, pop, wiggle, spin, pulse, bounce, shake | aucun | Préréglage d'état vivant. |
trigger | mount, hover, click, state | mount | Moment où l'animation ou le morph se joue. |
active | boolean | false | L'état pour le déclencheur state. |
duration | number (ms) | selon le préréglage | Durée de l'animation ou du morph. |
delay | number (ms) | 0 | Délai de l'animation ou du morph. |
loop | boolean, number | false | Répète à l'infini ou un certain nombre de fois (spin et pulse bouclent par défaut). |
modifier | plus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dot | aucun | Badge avec espace de découpe automatique. |
modifierCorner | top-left, top-right, bottom-left, bottom-right | bottom-right | Coin du badge. |
morphTo | name, data | aucun | Cible du morph ; le déclencheur décide quand elle s'affiche. |
title | string | aucun | Nom accessible : title, role img et aria-label. |
decorative | boolean | true sans title | Masque l'icône aux technologies d'assistance. |
Pièges courants
- Un alias manquant
- Sans l'alias, le bundler résout
reactvers le vrai package React (ou ne le trouve pas). Les icônes appellent alors les hooks d'un autre moteur de rendu, ce qui se traduit par des erreurs « invalid hook call » ou des icônes qui ne se mettent jamais à jour. Vérifiez quereactse résout bien verspreact/compat. classau lieu declassName- Les composants combinent
classNameavec leurs propres classesglyphfox glyphfox-NAME. Une propclassn'est pas combinée et peut être remplacée par ces classes : utilisez doncclassNamesur les composants d'icônes. - Deux copies de Preact
- compat doit se résoudre vers le même
preactque votre application. Une copie en double dansnode_modulescasse les hooks de la même manière qu'un alias manquant ; dédupliquez-la avec votre gestionnaire de paquets. - Signaux passés en props
- Passez
signal.valueaux composants d'icônes. L'objet signal lui-même n'est pas déballé pour les composants. - Éléments vides avant la définition
<glyph-fox>ne dessine qu'une fois quedefineGlyphFox()s'est exécuté dans le navigateur. Avec du HTML prérendu, donnez une taille à l'élément en CSS pour que la mise en page ne se décale pas pendant le chargement du script.
Questions fréquentes
Ai-je besoin de preact/compat pour utiliser glyphfox ?
Uniquement pour les composants de glyphfox/react. L'élément <glyph-fox> et toSvg de glyphfox fonctionnent sans lui, avec Preact seul.
Peut-on rendre les composants avec preact-render-to-string ?
Oui. Via compat, ils sont rendus côté serveur comme n'importe quel composant React, et le SVG figure dans le HTML. Les icônes affichées par nom avec Icon doivent d'abord avoir leurs données enregistrées, comme l'explique le guide du rendu côté serveur.