Frameworks

Icônes React

Chaque icône glyphfox est un composant React qui génère du SVG inline. Les mêmes props fonctionnent sur toutes les icônes, aucun provider n'est nécessaire, et les composants que vous n'importez pas ne se retrouvent jamais dans votre bundle.

Installation

Les composants React se trouvent dans le package principal glyphfox, sous le point d'entrée glyphfox/react. React est une dépendance peer optionnelle : le package fonctionne avec React 16.8 et les versions ultérieures, car il n'a besoin que des hooks et de forwardRef, et sa suite de tests s'exécute sur React 19.

terminal
npm install glyphfox

Il n'y a aucune feuille de style à importer ni aucun plugin de build à ajouter. Le package fournit des builds ESM et CommonJS accompagnés de déclarations de types : Vite, webpack, Rspack, esbuild et Parcel le prennent donc en charge tel quel.

Afficher vos premières icônes

Chaque icône est exportée sous son nom en PascalCase, suivi du suffixe Icon : home devient HomeIcon, arrow-right devient ArrowRightIcon et message-circle devient MessageCircleIcon. Cherchez un nom dans l'explorateur d'icônes ; la page de chaque icône, comme arrow right, affiche aussi la ligne d'import.

Toolbar.jsx
import { HomeIcon, SearchIcon, BellIcon } from 'glyphfox/react';

export function Toolbar() {
  return (
    <nav className="toolbar">
      <a href="/"><HomeIcon /> Home</a>
      <button type="button" aria-label="Search">
        <SearchIcon />
      </button>
      <BellIcon size={20} />
    </nav>
  );
}

Sans props, une icône mesure 24 pixels sur 24, se dessine avec stroke="currentColor" pour reprendre la couleur du texte de son parent, et porte aria-hidden="true", car la plupart des icônes accompagnent un libellé visible. Donnez-lui un title quand l'icône est seule à porter le sens ; le guide d'accessibilité présente les modèles à suivre.

Taille, couleur, épaisseur et style

Chaque icône se décline selon trois axes : l'épaisseur, les coins et le style. Ce sont de simples props : elles peuvent donc suivre l'état, les thèmes ou les points de rupture comme n'importe quelle autre valeur.

Axes.jsx
import { FolderIcon, SearchIcon, ArrowRightIcon } from 'glyphfox/react';

export function Axes() {
  return (
    <>
      <SearchIcon size={32} color="#ff7a1a" />
      <SearchIcon weight={1} />
      <SearchIcon weight={3} corners="sharp" />
      <SearchIcon size={16} weight={1.5} absoluteWeight />
      <FolderIcon variant="duotone" secondaryColor="#ff7a1a" />
      <FolderIcon variant="solid" />
      <ArrowRightIcon rotate={90} />
      <ArrowRightIcon mirrorRtl />
    </>
  );
}
  • size accepte un nombre de pixels ou toute longueur CSS sous forme de chaîne, comme "1.25em".
  • weight va de 1 à 3 sur la grille de 24. Sous 24 pixels, le trait bénéficie d'une compensation optique et devient jusqu'à 30 % plus épais aux plus petites tailles, si bien qu'une icône de 16 pixels garde la même présence qu'une icône de 24 pixels. absoluteWeight désactive cette compensation et maintient le trait à exactement weight pixels.
  • variant="duotone" utilise la seconde couche dessinée à la main quand l'icône en possède une, ou, à défaut, un remplissage translucide de ses formes fermées. variant="solid" remplit les formes fermées et évide les lignes intérieures, qui deviennent de l'espace négatif.
  • mirrorRtl retourne horizontalement les icônes directionnelles lorsqu'elles s'affichent dans un contexte dir="rtl" : le même balisage fonctionne ainsi dans les deux sens.

Icônes par nom

Quand l'icône provient de données, d'un champ de CMS, d'une table de routes ou d'un réglage utilisateur, affichez-la avec Icon et un nom. La prop name accepte la syntaxe de nom complète, commune à tous les packages glyphfox : modificateurs, fusions et styles tiennent donc dans une seule chaîne.

MenuItem.jsx
import { Icon } from 'glyphfox/react';

export function MenuItem({ item }) {
  // item.icon could be "settings", "file+check@tr", "cloud&lock:overlap" or "heart/solid"
  return (
    <li>
      <Icon name={item.icon} size={18} />
      {item.label}
    </li>
  );
}

Les noms qui ne sont importés nulle part sont chargés à la demande via un import dynamique. webpack et esbuild découpent cet import en un petit chunk par icône, et tant que ce chunk n'est pas arrivé, Icon affiche un SVG vide aux bonnes dimensions, pour que la mise en page ne saute pas. Un build de production Vite laisse cet import tel quel dans node_modules : l'icône y reste donc vide (le guide du tree shaking donne les détails). Quel que soit le bundler, la solution est la même : enregistrez une fois au démarrage les données des noms que vous affichez à partir de chaînes, et leur rendu devient synchrone, dès le premier affichage comme côté serveur :

icons.js
import { registerIcons } from 'glyphfox/react';
import { iconSettings, iconFile, iconCloud, iconLock } from 'glyphfox';

registerIcons([iconSettings, iconFile, iconCloud, iconLock]);

Les exports de données (iconSettings, iconArrowRight...) proviennent du point d'entrée principal glyphfox et profitent du tree shaking comme les composants : en importer un ne coûte que quelques centaines d'octets. Importer un composant comme SettingsIcon enregistre également ses données.

Modificateurs et fusions

Un modificateur est un petit badge placé dans un coin de n'importe quelle icône : plus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down ou dot. L'icône sous-jacente est évidée autour du badge grâce à un espace de découpe, si bien que les lignes ne se touchent jamais, quelle que soit l'épaisseur.

Status.jsx
import { FileIcon, CloudIcon, Fusion } from 'glyphfox/react';

export function Status({ saved, syncing }) {
  return (
    <>
      <FileIcon modifier={saved ? 'check' : undefined} />
      <CloudIcon modifier={syncing ? 'sync' : undefined} modifierCorner="top-right" />
      <Fusion icons={['cloud', 'lock']} layout="overlap" gap={1} />
      <Fusion icons={['shield', 'heart']} layout="inside" />
    </>
  );
}

Fusion combine de 2 à 10 icônes en une nouvelle icône qui respecte toujours les règles communes à toutes les icônes : une seule épaisseur, la grille de 24 et la zone de padding. Les dispositions sont overlap, side, stack, grid, orbit, badge et inside ; gap définit l'espace de découpe en unités de grille, tandis que scale et offsets ajustent finement chaque partie. Fusion accepte toutes les props communes : une icône fusionnée peut donc être duotone, animée ou dotée d'un libellé, comme n'importe quelle autre.

Morph et états vivants

Trois outils prennent en charge l'animation. MorphIcon se transforme chaque fois que sa prop name change. Sur n'importe quelle icône, morphTo la fait se transformer vers une cible quand son trigger se déclenche. animate joue un préréglage (draw, pop, wiggle, spin, pulse, bounce ou shake) au montage, au survol, au clic ou tant que active est vrai.

Motion.jsx
import { MorphIcon, MenuIcon, BellIcon, HeartIcon } from 'glyphfox/react';

export function Motion({ open, copied, hasNews, liked }) {
  return (
    <>
      <MorphIcon name={copied ? 'check' : 'copy'} duration={300} />
      <MenuIcon morphTo={open ? 'x' : undefined} />
      <BellIcon animate="shake" trigger="state" active={hasNews} />
      <HeartIcon animate="pop" trigger="click" variant={liked ? 'solid' : 'outline'} />
    </>
  );
}

Pour un rendu personnalisé, useMorph(name, { duration }) renvoie les données d'icône de l'image d'animation en cours, que vous pouvez passer à Icon via sa prop icon ou à votre propre code de dessin. Toutes les animations respectent prefers-reduced-motion. Le guide des icônes animées détaille les préréglages, les déclencheurs et les paires de morph ajustées à la main.

CustomMorph.jsx
import { Icon, useMorph } from 'glyphfox/react';

export function PlayButton({ playing }) {
  const frame = useMorph(playing ? 'pause' : 'play', { duration: 250 });
  return frame ? <Icon icon={frame.icon} variant={frame.variant} size={28} /> : null;
}

Refs, className, style et événements

Les composants sont des composants forwardRef : une ref pointe donc vers l'élément <svg> rendu. className s'ajoute après les classes intégrées glyphfox glyphfox-NAME, style est transmis tel quel, et tous les autres attributs SVG ou gestionnaires d'événements (onClick, data-*, aria-*, id) vont directement sur l'élément.

Like.jsx
import { useRef } from 'react';
import { HeartIcon } from 'glyphfox/react';

export function Like({ onLike }) {
  const ref = useRef(null);
  const like = () => {
    ref.current?.animate([{ transform: 'scale(1)' }, { transform: 'scale(1.25)' }, { transform: 'scale(1)' }], 240);
    onLike();
  };
  return (
    <button type="button" onClick={like}>
      <HeartIcon ref={ref} className="like-icon" style={{ color: 'var(--accent)' }} />
      Like
    </button>
  );
}

Un aria-label transmis de cette façon signale aussi l'icône comme porteuse de sens : le composant remplace automatiquement aria-hidden par role="img".

TypeScript

Les types sont fournis avec le package. GlyphIconComponent est le type de chaque composant d'icône, GlyphProps décrit ses props (les props communes plus tous les attributs SVG), et IconName, exporté par le point d'entrée principal, est l'union de tous les noms d'icônes, ce qui vous offre l'autocomplétion sur Icon et dans vos propres données.

nav.tsx
import type { IconName } from 'glyphfox';
import { Icon, HomeIcon, SettingsIcon, type GlyphIconComponent } from 'glyphfox/react';

type NavItem = { label: string; href: string; icon: GlyphIconComponent };
const items: NavItem[] = [
  { label: 'Home', href: '/', icon: HomeIcon },
  { label: 'Settings', href: '/settings', icon: SettingsIcon },
];

export function Nav() {
  return (
    <nav>
      {items.map(({ label, href, icon: ItemIcon }) => (
        <a key={href} href={href}>
          <ItemIcon size={18} /> {label}
        </a>
      ))}
    </nav>
  );
}

export function Badge({ name }: { name: IconName }) {
  return <Icon name={name} variant="duotone" />;
}

Imports et taille du bundle

Les imports nommés depuis glyphfox/react profitent du tree shaking : chaque icône est un module distinct, créé avec une annotation pure, et le package déclare quels fichiers ont des effets de bord. Les imports profonds comme glyphfox/react/icons/home chargent directement un seul module d'icône, ce qui aide les outils dépourvus de tree shaking et évite aux serveurs de développement de traiter l'index complet.

deep-imports.js
import { HomeIcon } from 'glyphfox/react/icons/home';
import FileIcon from 'glyphfox/react/icons/file'; // default export works too

Ce qui casse le tree shaking, ce que coûte le runtime partagé et pourquoi le build contient un minuscule chunk par icône : tout cela est mesuré dans le guide du tree shaking.

Props

Tous les composants d'icônes, ainsi que Icon, Fusion et MorphIcon, acceptent les mêmes props. Elles portent le même nom et ont le même sens dans Vue, Svelte, Angular, le web component et toSvg : une valeur copiée depuis le Studio fonctionne donc partout.

PropTypePar défautDescription
sizenumber, string24Largeur et hauteur ; les nombres sont en pixels.
colorstringcurrentColorCouleur principale.
secondaryColorstringcolorCouleur du calque duotone et du remplissage plein.
secondaryOpacitynumber0.3 / 1Opacité du calque duotone ou du remplissage plein.
weightnumber2Trait de 1 à 3 sur la grille de 24, avec compensation optique en dessous de 24 px.
absoluteWeightbooleanfalseGarde le trait à weight pixels quelle que soit la taille.
cornersround, sharproundJointures et extrémités arrondies ou vives.
variantoutline, duotone, solidoutlineAxe de style ; solid vient des formes fermées.
rotatenumber0Rotation en degrés.
flipXbooleanfalseMiroir horizontal.
flipYbooleanfalseMiroir vertical.
mirrorRtlbooleanfalseMiroir dans les mises en page de droite à gauche.
animatedraw, pop, wiggle, spin, pulse, bounce, shakeaucunPréréglage d'état vivant.
triggermount, hover, click, statemountMoment où l'animation ou le morph se joue.
activebooleanfalseL'état pour le déclencheur state.
durationnumber (ms)selon le préréglageDurée de l'animation ou du morph.
delaynumber (ms)0Délai de l'animation ou du morph.
loopboolean, numberfalseRépète à l'infini ou un certain nombre de fois (spin et pulse bouclent par défaut).
modifierplus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dotaucunBadge avec espace de découpe automatique.
modifierCornertop-left, top-right, bottom-left, bottom-rightbottom-rightCoin du badge.
morphToname, dataaucunCible du morph ; le déclencheur décide quand elle s'affiche.
titlestringaucunNom accessible : title, role img et aria-label.
decorativebooleantrue sans titleMasque l'icône aux technologies d'assistance.

Icon et MorphIcon acceptent aussi name (toute syntaxe de nom) ou icon (données d'icône). Fusion accepte icons, layout, gap, scale et offsets.

Pièges courants

Icon s'affiche d'abord vide
Un nom qui n'est pas encore enregistré est récupéré via un import dynamique : le premier rendu (et le rendu côté serveur) produit donc un SVG vide. Importez le composant, ou appelez registerIcons avec les données de chaque nom que vous affichez à partir d'une chaîne.
Server Components de Next.js
Les composants utilisent des hooks et le package ne comporte pas de directive "use client" : un Server Component ne peut donc pas les afficher directement. Le guide Next.js présente la correction en un seul fichier ainsi qu'une option sans aucun JavaScript.
Colorer avec fill
Les icônes sont des traits sur fill="none". Passer fill remplit toutes les formes, ce qui est rarement l'effet voulu. Utilisez color (ou la propriété CSS color sur un parent) pour le trait et variant="solid" pour des formes pleines.
Du CSS global écrase l'épaisseur
Une règle de feuille de style comme svg { stroke-width: 1.5 } l'emporte sur l'attribut SVG qui porte l'axe d'épaisseur, compensation optique comprise. Limitez la portée de ces règles ou utilisez la prop weight.
Pas de compensation optique avec les tailles relatives
La compensation doit connaître la taille en pixels. Avec size="1em", le trait reste à l'épaisseur nominale, ce qui peut paraître trop fin avec de petites tailles de texte ; passez un nombre de pixels là où c'est important, ou une valeur de weight légèrement plus élevée.
Appeler createIcon pendant le rendu
createIcon(data) transforme vos propres données d'icône en un composant doté de toutes les props. Appelez-la une seule fois au niveau du module : l'appeler dans un composant crée un nouveau type de composant à chaque rendu et remonte le SVG.
import * avec une clé dynamique
Icons[name] sur un import d'espace de noms conserve toutes les icônes dans le bundle. Utilisez plutôt Icon avec un nom, qui ne charge que ce qui est affiché.

Questions fréquentes

Puis-je utiliser mes propres icônes avec les mêmes props ?

Oui. createIcon(data), exportée par glyphfox/react, prend des données d'icône (name, body, tags, categories) et renvoie un composant doté de toutes les props communes, y compris l'épaisseur, les styles duotone et solid, les modificateurs et le morph. Dessinez l'icône dans l'éditeur du Studio ou convertissez un SVG existant avec Fox-ify, pour que l'icône respecte les mêmes règles de grille et de trait.

Comment définir une taille ou une épaisseur par défaut pour toutes les icônes ?

Le package React n'a pas de provider : la méthode habituelle consiste donc à écrire un petit wrapper comme const NavIcon = (props) => <Icon size={20} weight={1.75} {...props} />. La couleur ne demande rien : les icônes suivent la propriété CSS color de leur parent.

Icônes de ce guide