Icônes Vue 3
Chaque icône glyphfox est un composant Vue 3 doté des mêmes props que dans tous les autres packages glyphfox. Ce guide couvre l'installation, les props dans les templates, les icônes par nom, le morph, l'enregistrement global, TypeScript et les erreurs qui laissent une icône vide.
Installation
npm install glyphfox
glyphfox n'a aucune dépendance. Vue 3.2 ou plus récent est une dépendance peer optionnelle, nécessaire uniquement si vous importez glyphfox/vue. Le même package contient aussi les builds React, Svelte et web component : il n'y a donc rien d'autre à installer.
Chaque icône est un composant qui porte le nom de l'icône en PascalCase, suivi du suffixe Icon : arrow-right devient ArrowRightIcon, x devient XIcon. L'explorateur d'icônes affiche le nom de chaque icône et copie pour vous l'extrait de code Vue.
Utiliser les composants
<script setup> import { HomeIcon, SearchIcon, BellIcon } from 'glyphfox/vue'; defineProps({ unread: { type: Number, default: 0 } }); </script> <template> <nav class="toolbar"> <a href="/" aria-label="Home"><HomeIcon /></a> <SearchIcon :size="20" :weight="1.5" class="muted" /> <BellIcon variant="duotone" secondary-color="#ff7a1a" :modifier="unread ? 'dot' : undefined" /> </nav> </template>
Les props sont déclarées en camelCase, et Vue accepte les deux graphies dans les templates : secondary-color et secondaryColor désignent la même prop. Liez les nombres avec :size="20" ; un simple size="20" fonctionne aussi, car size, weight, rotate, duration et les autres props numériques acceptent des chaînes.
Les composants ne déclarent ni class, ni style, ni écouteurs d'événements : Vue les transmet donc à l'élément racine <svg>. Vos classes sont combinées avec les classes intégrées glyphfox glyphfox-NAME, et @click, aria-*, data-* et id arrivent directement sur le svg.
Les traits utilisent currentColor : une icône reprend donc la propriété CSS color de son parent et suit sans effort les états de survol et les thèmes. La prop color définit la couleur sur le svg quand il vous faut une couleur fixe. Le svg reçoit ses attributs width et height de size (24 par défaut) ; une largeur et une hauteur CSS définies sur une classe les remplacent.
Épaisseur, coins et style
Trois props modifient le dessin lui-même plutôt que la boîte qui l'entoure : 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 ne paraissent pas effacées ; absolute-weight conserve exactement le trait demandé.
<script setup> import { FolderIcon } from 'glyphfox/vue'; </script> <template> <FolderIcon :weight="1" /> <FolderIcon :weight="3" corners="sharp" /> <FolderIcon variant="duotone" secondary-color="#ff7a1a" /> <FolderIcon variant="solid" /> <FolderIcon :size="16" :weight="1.5" absolute-weight /> </template>
Le style solid est généré au moment du build à partir des formes fermées de chaque icône, les lignes intérieures étant évidées en espace négatif. Les icônes sans formes fermées conservent leur contour quand vous demandez solid.
Icônes par nom, modificateurs et fusion
Icon affiche n'importe quelle spécification de la syntaxe de nom : un nom simple, 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. Les deux sont utiles quand l'icône provient de données, comme une définition de menu, un champ de statut ou un CMS.
Les composants comme FileIcon apportent leurs propres données. Un nom placé dans une chaîne ne s'appuie sur aucun import : enregistrez donc ses données une fois avec registerIcons. Le registre est partagé par Icon, Fusion, MorphIcon et chaque prop morph-to : un seul module suffit pour toute l'application. Les badges de modificateur sont dessinés par le moteur et ne nécessitent aucun enregistrement.
import { registerIcons } from 'glyphfox/vue'; 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 pause from 'glyphfox/icons/pause'; // Every name used in a string: Icon, Fusion, MorphIcon and morph-to. registerIcons([file, cloud, lock, menu, x, pause]);
import { createApp } from 'vue'; import App from './App.vue'; import './icons.js'; createApp(App).mount('#app');
<script setup> import { Icon, Fusion } from 'glyphfox/vue'; defineProps({ saved: Boolean }); </script> <template> <Icon :name="saved ? 'file+check' : 'file'" /> <Icon name="file+alert@tr" variant="duotone" /> <Fusion :icons="['cloud', 'lock']" layout="overlap" :gap="1" /> </template>
Une fusion est une véritable icône : elle suit weight, variant et toutes les autres props, et là où les parties se chevauchent, celle de derrière est découpée autour de celle de devant. Les dispositions sont overlap, side, stack, grid, orbit, badge et inside ; scale et offsets ajustent finement les parties.
Morph entre icônes
Il existe trois façons d'obtenir un morph. MorphIcon s'anime chaque fois que sa prop name change. Tout composant d'icône accepte morph-to avec un déclencheur (mount, hover, click ou state). Enfin, le composable useMorph renvoie les images de l'animation pour votre propre rendu.
<script setup> import { ref } from 'vue'; import { MorphIcon } from 'glyphfox/vue'; const open = ref(false); </script> <template> <button type="button" aria-label="Menu" :aria-expanded="open" @click="open = !open"> <MorphIcon :name="open ? 'x' : 'menu'" :duration="300" /> </button> </template>
<script setup> import { HeartIcon, PlayIcon } from 'glyphfox/vue'; defineProps({ playing: Boolean }); </script> <template> <!-- toggles on every click --> <HeartIcon morph-to="heart/solid" trigger="click" /> <!-- shows pause while playing is true --> <PlayIcon morph-to="pause" trigger="state" :active="playing" /> </template>
useMorph accepte une ref, un getter ou une valeur simple, et renvoie une image d'animation { icon, variant } calculée (computed) qui s'anime chaque fois que la spécification change. Passez cette image à Icon via sa prop icon, ou confiez-la à votre propre moteur de rendu.
<script setup> import { ref } from 'vue'; import { Icon, useMorph } from 'glyphfox/vue'; const playing = ref(false); const frame = useMorph(() => (playing.value ? 'pause' : 'play'), { duration: 250 }); </script> <template> <button type="button" aria-label="Play" :aria-pressed="playing" @click="playing = !playing"> <Icon v-if="frame" :icon="frame.icon" :variant="frame.variant" /> </button> </template>
Des paires ajustées à la main donnent aux transitions courantes un rendu soigné : 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. Toute autre paire se transforme quand même grâce à une correspondance automatique. Le guide des icônes animées couvre les durées, les délais et le mouvement réduit.
États vivants
La prop animate ajoute un préréglage qui comprend 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 font ce que leur nom indique. L'animation est une petite feuille de style intégrée au svg : elle ne nécessite aucun import CSS et s'arrête pour les visiteurs qui préfèrent un mouvement réduit.
<script setup> import { BellIcon, LoaderCircleIcon, SparklesIcon } from 'glyphfox/vue'; defineProps({ hasNews: Boolean, loading: Boolean }); </script> <template> <BellIcon animate="shake" trigger="state" :active="hasNews" /> <LoaderCircleIcon v-if="loading" animate="spin" /> <SparklesIcon animate="draw" trigger="hover" /> </template>
Enregistrement global
Importer les icônes là où vous les utilisez permet de garder chaque bundle léger. Quand un design system a besoin d'un ensemble fixe dans tous les templates, enregistrez ces composants une fois avec app.component. Donnez à Icon un nom distinctif comme GfIcon, pour éviter toute collision avec un autre composant global.
import { createApp } from 'vue'; import { HomeIcon, SearchIcon, SettingsIcon, Icon } from 'glyphfox/vue'; import App from './App.vue'; import './icons.js'; const app = createApp(App); app.component('HomeIcon', HomeIcon); app.component('SearchIcon', SearchIcon); app.component('SettingsIcon', SettingsIcon); app.component('GfIcon', Icon); app.mount('#app');
Avec TypeScript, déclarez les composants globaux pour que les templates soient vérifiés :
import type { HomeIcon, SearchIcon, SettingsIcon, Icon } from 'glyphfox/vue'; declare module 'vue' { interface GlobalComponents { HomeIcon: typeof HomeIcon; SearchIcon: typeof SearchIcon; SettingsIcon: typeof SettingsIcon; GfIcon: typeof Icon; } } export {};
TypeScript
Chaque composant est typé comme GlyphComponent avec les props communes : les éditeurs complètent donc variant, modifier, animate et les autres. Dans les types Vue, les spécifications d'icônes sont de simples chaînes, car l'inférence des props de Vue ne peut pas développer l'union complète des noms d'icônes. Si vous conservez des noms dans votre propre code, typez-les avec IconName de glyphfox pour repérer les fautes de frappe à la compilation.
import type { IconName } from 'glyphfox'; export const nav: { label: string; to: string; icon: IconName }[] = [ { label: 'Home', to: '/', icon: 'home' }, { label: 'Search', to: '/search', icon: 'search' }, { label: 'Settings', to: '/settings', icon: 'settings' }, ];
Imports profonds et taille du bundle
Les imports nommés depuis glyphfox/vue profitent du tree shaking : les modules d'icônes sont marqués sans effets de bord et chaque composant est créé par un appel pur. Dans un build de production Vite 8 (hors Vue lui-même), un composant d'icône et le runtime partagé pèsent environ 53 Ko minifiés et 20 Ko après gzip, et neuf icônes de plus ajoutent moins de 1 Ko après gzip. Le runtime embarque le moteur de rendu et les moteurs de morph, de fusion et de modificateurs, et ne se paie qu'une seule fois.
<script setup> // One module, for tools that do not tree shake. import { FoxIcon } from 'glyphfox/vue/icons/fox'; </script> <template> <FoxIcon :size="32" variant="duotone" title="glyphfox" /> </template>
Le guide du tree shaking explique ce qui maintient le jeu d'icônes hors de votre bundle et ce qui l'y fait revenir.
Props
Tous les composants d'icônes, ainsi que Icon, Fusion et MorphIcon, acceptent les props communes. Dans les templates, vous pouvez écrire l'attribut en kebab-case indiqué dans la deuxième colonne.
| Prop | Dans les templates | Type | Par défaut | Description |
|---|---|---|---|---|
size | size | number, string | 24 | Largeur et hauteur ; les nombres sont en pixels. |
color | color | string | currentColor | Couleur principale. |
secondaryColor | secondary-color | string | color | Couleur du calque duotone et du remplissage plein. |
secondaryOpacity | secondary-opacity | number | 0.3 / 1 | Opacité du calque duotone ou du remplissage plein. |
weight | weight | number | 2 | Trait de 1 à 3 sur la grille de 24, avec compensation optique en dessous de 24 px. |
absoluteWeight | absolute-weight | boolean | false | Garde le trait à weight pixels quelle que soit la taille. |
corners | corners | round, sharp | round | Jointures et extrémités arrondies ou vives. |
variant | variant | outline, duotone, solid | outline | Axe de style ; solid vient des formes fermées. |
rotate | rotate | number | 0 | Rotation en degrés. |
flipX | flip-x | boolean | false | Miroir horizontal. |
flipY | flip-y | boolean | false | Miroir vertical. |
mirrorRtl | mirror-rtl | boolean | false | Miroir dans les mises en page de droite à gauche. |
animate | animate | draw, pop, wiggle, spin, pulse, bounce, shake | aucun | Préréglage d'état vivant. |
trigger | trigger | mount, hover, click, state | mount | Moment où l'animation ou le morph se joue. |
active | active | boolean | false | L'état pour le déclencheur state. |
duration | duration | number (ms) | selon le préréglage | Durée de l'animation ou du morph. |
delay | delay | number (ms) | 0 | Délai de l'animation ou du morph. |
loop | loop | boolean, number | false | Répète à l'infini ou un certain nombre de fois (spin et pulse bouclent par défaut). |
modifier | modifier | plus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dot | aucun | Badge avec espace de découpe automatique. |
modifierCorner | modifier-corner | top-left, top-right, bottom-left, bottom-right | bottom-right | Coin du badge. |
morphTo | morph-to | name, data | aucun | Cible du morph ; le déclencheur décide quand elle s'affiche. |
title | title | string | aucun | Nom accessible : title, role img et aria-label. |
decorative | decorative | boolean | true sans title | Masque 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. Un slot par défaut s'affiche à l'intérieur du svg.
Pièges courants
- Une icône utilisée par son nom est vide en production
- Le serveur de développement effectue un pré-bundling de tout le package : chaque nom est donc résolu pendant le développement. 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,MorphIconoumorph-todonnent un svg vide. Enregistrez-les avecregisterIcons, comme danssrc/icons.jsci-dessus. - Boutons à icône seule sans nom accessible
- Les icônes sont décoratives par défaut et reçoivent
aria-hidden="true". Un bouton qui ne contient qu'une icône n'a donc pas de nom accessible. Placezaria-labelsur le bouton, ou donnez untitleà l'icône. Vous trouverez d'autres modèles dans le guide d'accessibilité. - morph-to se lance dès le chargement de la page
- Le déclencheur par défaut est mount : l'icône se transforme en sa cible juste après le montage. Si la cible est l'état que vous voulez afficher immédiatement, utilisez
trigger="state"avec:active, qui affiche d'emblée le bon état, sans animation. - Props booléennes écrites comme des chaînes
active="false"passe la chaîne "false". glyphfox l'interprète bien comme false, mais Vue émet un avertissement sur le type de la prop. Écrivez les props booléennes sans valeur (flip-x) ou liez-les (:active="playing").- Imports avec astérisque
import * as icons from 'glyphfox/vue'suivi deicons[name]conserve toutes les icônes dans le bundle, car le bundler ne peut pas savoir quels noms vous lisez. Construisez plutôt une petite table de correspondance avec les composants dont vous avez besoin.
Questions fréquentes
glyphfox fonctionne-t-il avec Vue 2 ?
Les composants nécessitent Vue 3.2 ou plus récent. Dans une application Vue 2, utilisez le web component <glyph-fox>, qui accepte les mêmes props sous forme d'attributs ; ajoutez glyph-fox à Vue.config.ignoredElements pour que Vue ne touche pas à la balise. Consultez le guide des web components.
Puis-je utiliser les composants avec l'Options API ?
Oui. Ce sont des composants classiques : déclarez-les dans components: { HomeIcon } et utilisez-les dans le template. useMorph est un composable : sa place est donc dans setup().
Mes propres icônes SVG peuvent-elles avoir les mêmes props ?
Oui. createIcon({ name, body, tags, categories }), exportée par glyphfox/vue, transforme des données d'icône en composant, body étant le balisage interne d'une icône au trait de 24 sur 24. Passez d'abord votre SVG dans Fox-ify, dans le Studio, pour qu'il respecte les règles de grille, de trait et de padding sur lesquelles reposent l'épaisseur et les autres axes.