Frameworks

Icônes Svelte 5

glyphfox/svelte fournit un composant Svelte 5 par icône, ainsi que Icon, Fusion et MorphIcon, avec les mêmes props que tous les autres packages glyphfox.

Installation

terminal
npm install glyphfox

Les composants sont des fichiers source .svelte que votre application compile : le build a donc besoin de Svelte 5 et de son compilateur, généralement via vite-plugin-svelte, déjà présent dans tout projet SvelteKit. Ils sont écrits avec des runes comme $props et $state, si bien que Svelte 4 ne peut pas les compiler.

svelte 5 est une dépendance peer optionnelle de glyphfox : vous n'en avez besoin que si vous importez glyphfox/svelte. Le package expose cette entrée sous la condition d'export svelte, que vite-plugin-svelte utilise pour reconnaître une bibliothèque Svelte et compiler ses composants pour le navigateur et pour le serveur.

Utiliser les composants

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>

Chaque icône est un composant qui porte le nom de l'icône en PascalCase, suivi du suffixe Icon : arrow-right devient ArrowRightIcon, loader-circle devient LoaderCircleIcon. Les props utilisent les noms en camelCase, exactement comme en JavaScript, car Svelte transmet les props aux composants telles qu'elles sont écrites.

class et style s'appliquent au svg, et tout autre attribut, comme aria-*, data-* ou id, y est propagé. En Svelte 5, les gestionnaires d'événements sont des props : onclick, onmouseenter et onmouseleave sont transmis, et ils s'exécutent toujours quand un déclencheur click ou hover est défini sur l'icône.

Les traits utilisent currentColor : l'icône suit donc la propriété CSS color de son parent. La prop color définit une couleur fixe sur le svg.

Épaisseur, coins et style

weight règle le trait de 1 à 3, corners bascule entre jointures arrondies et jointures vives, et variant choisit outline, duotone ou solid. Sous 24 px, le trait est légèrement épaissi pour que les petites icônes gardent leur présence ; absoluteWeight conserve la valeur exacte.

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, modificateurs et fusion

Icon affiche n'importe quelle spécification de la syntaxe de nom : un nom, un badge de modificateur (file+check, avec @tl, @tr, @bl ou @br pour le coin), une fusion (cloud&lock:overlap) ou un style (heart/solid). Fusion prend une liste de noms et une disposition : overlap, side, stack, grid, orbit, badge ou inside.

Les composants d'icônes embarquent leurs propres données : chacun enregistre son icône dans un bloc <script module>. Un nom placé dans une chaîne ne s'appuie sur aucun import : enregistrez donc ces noms une fois avec registerIcons. Les badges de modificateur sont dessinés par le moteur et ne nécessitent aucun enregistrement.

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} />

Importez le module d'enregistrement depuis votre fichier d'entrée ou votre composant racine. Un composant peut aussi enregistrer des icônes dans son propre bloc <script module>, qui s'exécute une seule fois au chargement du module plutôt qu'une fois par instance.

MorphIcon, morphTo et morphStore

MorphIcon s'anime chaque fois que sa prop name change, ce qui se marie naturellement avec $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>

Tout composant d'icône accepte aussi morphTo avec un déclencheur : click bascule à chaque clic, hover suit le pointeur, state suit active, et mount, la valeur par défaut, effectue le morph une fois après le montage.

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) est un store destiné au rendu personnalisé. Appelez set(name) pour lancer un morph et lisez $store, une image d'animation contenant icon et variant, que vous pouvez passer à Icon.

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>

Des paires ajustées à la main couvrent menu vers x, play vers pause, plus vers check, sun vers moon, eye vers eye-off, bell vers bell-ring, heart vers heart/solid, copy vers check, lock vers unlock et wifi vers wifi-off. Les autres paires se transforment grâce à une correspondance automatique.

Animations pilotées par l'état

Les états vivants sont des préréglages qui comprennent l'icône : draw trace les traits dans l'ordre du dessin, shake la fait osciller depuis le haut, et pop, wiggle, spin, pulse et bounce complètent l'ensemble. Avec trigger="state", une animation se joue tant que active est vrai : elle suit donc directement vos 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" />

Chaque préréglage est une petite feuille de style intégrée au svg : il ne nécessite aucun import CSS et s'arrête pour les visiteurs qui préfèrent un mouvement réduit. Le guide des icônes animées couvre les durées, les délais et les boucles.

Imports profonds et types

glyphfox/svelte réexporte tous les composants, et les builds de production écartent ceux que vous n'importez pas. Un import profond se résout en un seul fichier .svelte, ce qui limite le code que voient votre compilateur et votre serveur de développement à ce que vous utilisez :

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

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

Les types sont fournis avec le package. Chaque composant est un Component<GlyphProps>, où GlyphProps regroupe les props communes et n'importe quel attribut SVG, si bien qu'un wrapper typé peut tout transmettre :

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} />

Les noms typés avec IconName sont vérifiés à la compilation, mais ils doivent tout de même être enregistrés pour s'afficher : consultez les pièges ci-dessous et le guide du tree shaking.

Props

Tous les composants d'icônes, ainsi que Icon, Fusion et MorphIcon, acceptent les props communes, en camelCase.

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 ajoute name, icon (données d'icône) et gap. Fusion ajoute icons, layout, gap, scale et offsets. MorphIcon ajoute name et icon. Les enfants (children) sont rendus à l'intérieur du svg.

Pièges courants

Les props en kebab-case n'ont aucun effet
En Svelte, secondary-color="#ff7a1a" n'est pas la prop secondaryColor : il est propagé sur le svg comme simple attribut, et l'icône garde sa valeur par défaut. Utilisez partout les noms en camelCase.
Des noms qui fonctionnent en développement et disparaissent en production
En développement, Vite effectue un pré-bundling du package et chaque nom est résolu. Un build de production ne garde que ce que vous importez, et Vite n'intègre pas au bundle le chargeur à la demande situé dans node_modules : les noms non enregistrés dans Icon, Fusion, MorphIcon, morphTo et morphStore donnent donc un svg vide. Enregistrez-les.
morphStore créé avant l'enregistrement
morphStore résout un nom au moment où vous appelez set. Si le nom n'est pas encore enregistré à ce moment-là, le store attend le chargeur à la place. Importez le module d'enregistrement avant de créer le store, comme dans l'exemple ci-dessus.
Imports avec astérisque et accès dynamiques
import * as icons from 'glyphfox/svelte' avec icons[name] conserve tous les composants dans le bundle. Créez une table des composants dont vous avez besoin, ou utilisez Icon avec des noms enregistrés.

Questions fréquentes

Puis-je utiliser glyphfox dans un projet Svelte 4 ?

Pas avec glyphfox/svelte, qui nécessite le compilateur de Svelte 5. Dans une application Svelte 4, le web component <glyph-fox> fonctionne avec les mêmes props sous forme d'attributs ; consultez le guide des web components.

Les composants nécessitent-ils SvelteKit ?

Non. Toute configuration Svelte 5 qui compile les fichiers .svelte convient, par exemple Vite seul avec vite-plugin-svelte. SvelteKit ajoute le rendu côté serveur et le prérendu, traités dans le guide SvelteKit.

Icônes de ce guide