Skip to content

Icons fr

Edgar Mesquita edited this page Oct 14, 2026 · 1 revision

Écosystème d'icônes

🌐 Cette page en : English · Português · Español · Français · Deutsch

eQuantic.UI fournit un écosystème d'icônes complet et extensible. Il prend en charge d'emblée plusieurs jeux d'icônes populaires, tous intégrés par un modèle de composants unifié.

🚀 Démarrage rapide

Pour utiliser des icônes dans votre projet, installez le paquet du jeu d'icônes voulu et le paquet des composants de base.

dotnet add package eQuantic.UI.Components
dotnet add package eQuantic.UI.Lucide

Utilisation

Rien à enregistrer. Un pack est un catalogue d'IconGlyph : vous nommez le glyphe que vous voulez et le compilateur intègre celui-là seulement :

using eQuantic.UI.Lucide;

Glyph(LucideIcons.Search)
Glyph(LucideIcons.Check, size: 20)

Les tailles sont la liste blanche §07 (16 / 20 / 24 / 32). Pour une taille hors de cette liste, Vector(glyph, size) dessine les mêmes tracés sans le contrat d'icône, et Vector(glyph, size, height: h) donne à une figure non carrée sa propre proportion (depuis 0.2.0-preview.28 ; le connecteur d'un diagramme en fut le cas). Icon(...) est la fabrique de l'enum Icons curaté du framework lui-même. Voir DeclarativeSurface pour savoir pourquoi les deux portent des noms différents.

Comme vous nommez le glyphe, rien ne se résout à l'exécution et deux packs ne peuvent jamais être en désaccord sur un nom : il n'y a aucune recherche à perdre.

Paquet Description
eQuantic.UI.Lucide Des icônes belles et cohérentes (jeu par défaut).
eQuantic.UI.Heroicons De belles icônes SVG faites main par les créateurs de Tailwind CSS.
eQuantic.UI.RadixIcons Un jeu net d'icônes 15×15 conçu par l'équipe de Radix UI.
eQuantic.UI.TablerIcons Plus de 4200 icônes parfaites au pixel pour le design web.
eQuantic.UI.FontAwesome6.Solid Le jeu d'icônes le plus populaire au monde (variante Solid).
eQuantic.UI.FontAwesome6.Regular Les icônes Font Awesome 6 Regular.
eQuantic.UI.FontAwesome6.Brands Les icônes de marques de Font Awesome 6.
eQuantic.UI.Phosphor Une famille d'icônes souple pour les interfaces, les diagrammes et plus.
eQuantic.UI.SimpleIcons Plus de 3000 icônes SVG de marques populaires.
eQuantic.UI.BootstrapIcons Bibliothèque d'icônes libre, de haute qualité et open source, avec plus de 2000 icônes.
eQuantic.UI.Iconoir Un jeu de haute qualité de plus de 1500 icônes open source.
eQuantic.UI.MaterialSymbols Les Material Symbols de Google : 16 284 glyphes, le plus gros pack d'ici.

Des glyphes de pack, à écriture unique

Un paquet d'icônes est un catalogue d'IconGlyph : des données de tracé neutres vis-à-vis de la cible, donc la même entrée sert au réalisateur web comme SVG en ligne et à l'atlas natif comme géométrie de glyphe. Dessinez-en un avec Glyph :

using eQuantic.UI.MaterialSymbols;

Glyph(MaterialSymbolsIcons.PlayArrowRounded)
Glyph(MaterialSymbolsIcons.ExpandMore, size: 20)

Glyph, pas Icon : Icon est la fabrique de l'enum Icons curaté du framework lui-même, et la surface déclarative n'a pas de surcharges. Voir DeclarativeSurface. Les tailles sont la liste blanche §07 (16 / 20 / 24 / 32) ; pour tout ce qui en sort, Vector(glyph, size) dessine les mêmes tracés sans le contrat d'icône, et un argument height: libère la boîte du carré.

Vous payez ce que vous nommez. eqc n'intègre que les glyphes qu'une page référence vraiment : une page qui utilise deux glyphes de Material Symbols émet un module de 627 octets, dans un catalogue dont la source fait ~8 Mo. La taille du pack est un coût de compilation, pas de téléchargement.

Depuis 0.2.0-preview.7

Une note sur Material Symbols

Google livre Material Symbols comme une police variable avec les axes FILL, wght, GRAD et opsz, et les trois coupes (outlined, rounded, sharp) sont ce à quoi ces axes se résolvent. Une liste d'affichage GPU ne peut pas dessiner une police, donc ce paquet porte à la place les tracés déjà résolus : la coupe vit dans le nom de l'icône (Home, HomeRounded, HomeSharp) et il n'y a pas d'axe FILL, donc X et XOutline sont deux entrées. Les noms sont ceux d'Iconify en PascalCase, donc material-symbols:play-arrow-rounded est PlayArrowRounded.

C'est aussi le pack le plus lourd que le framework publie (~13 Mo d'assemblage contre les 8 de Phosphor), ce qui était autrefois un conseil sur le pack à choisir, et ne l'est plus. Voir plus bas.

Un pack livre les glyphes que votre app nomme

Une app publiée porte les icônes qu'elle UTILISE, pas le pack qu'elle a référencé. Mesuré sur le plus gros : l'assemblage du pack passe de 14 558 720 octets à 7680, et une publication qui le portait, de 35 256 Ko à 20 952 Ko, soit 41 % de moins, pour une app qui dessine une poignée de glyphes sur 16 284.

Rien à configurer et rien à nommer. Ce qui a changé, c'est la FORME dans laquelle les packs sont générés : un initialiseur de champ compile en un constructeur statique pour toute la classe, et un constructeur statique n'est pas supprimable, donc un pack de champs se livrait entier, tout entier, pour dessiner cinq glyphes. Une propriété à corps d'expression est un corps de méthode à part, et le découpeur d'IL jette ceux que rien n'appelle :

// avant : un constructeur statique, 16 284 glyphes, non supprimable
public static readonly IconGlyph Camera = new("camera", "M14.5 4h-5L7 7", …);

// maintenant : un corps de méthode par glyphe, et le découpeur garde ceux que vous nommez
public static IconGlyph Camera => new("camera", "M14.5 4h-5L7 7", …);

Cela a besoin de PublishTrimmed, qui est ce qui fait tourner le découpeur du tout. Sans lui le pack a la taille qu'il a toujours eue, donc « choisissez un pack plus petit » reste le conseil pour une publication sans découpe. Avec lui, la taille d'un pack cesse d'être une raison de choisir un jeu plutôt qu'un autre : prenez les icônes qui vont bien.

Depuis 0.2.0-preview.47

Un dessin depuis un fichier .svg

Depuis 0.2.0-preview.29

Une icône est un tracé dans une teinte. Un LOGO, c'est plusieurs formes, chacune dans la couleur que son créateur a choisie, c'est Drawing, et c'est le nœud que vous pointez vers un fichier.

Mettez le fichier dans le dossier Assets de l'app et il devient un membre typé :

// Assets/mark.svg  →  Vectors.Mark
column.Add(new Drawing(Vectors.Mark, width: 240, label: "eQuantic"));

La lecture se fait à la compilation : rien ne lit un fichier à l'exécution sur l'une ou l'autre cible, parce qu'un navigateur ne peut pas et qu'une app native porterait son dessin deux fois. Un membre typé plutôt qu'une chaîne de chemin, pour la même raison que le reste de ce SDK génère des surfaces : Vectors.Mark est une erreur de compilation quand il est faux, et Drawing("mark.svg") est un espace blanc à l'exécution.

Un seul nombre garde la proportion propre du dessin (une icône est carrée par défaut parce que c'est ce qu'une icône est ; un logo écrasé est un logo faux). Donnez les deux pour encadrer ou étirer délibérément.

À la largeur de sa colonne. La largeur est un SizeValue, donc SizeValue.Fill prend la largeur que le parent offre et la proportion du dessin décide la hauteur : une carte dans une colonne adaptative, ce qu'aucun nombre ne dit pour chaque fenêtre. Le web écrit width: 100% et aspect-ratio ; Photon résout la largeur comme il résout celle d'un canevas et peint dans la boîte qu'il a mise en page. Une hauteur que vous donnez gagne toujours. Un fill sur une largeur que le parent dimensionne depuis son propre contenu n'a rien à remplir et est de largeur zéro, comme l'est un canevas, et un dessin refuse SizeValue.Hug, puisqu'il n'a pas de contenu à épouser.

column.Add(new Drawing(Vectors.Mark, SizeValue.Fill, label: "eQuantic"));

Depuis 0.2.0-preview.61

La teinte. Une forme que le fichier a laissée en currentColor est le dessin qui demande à être teinté, donc passez tint: et elle suit, tandis que chaque forme qui a choisi sa propre couleur l'ignore. Sur le web le mot currentColor atteint le balisage et la teinte est posée comme color CSS, donc la cascade peut y répondre ; sur Photon chaque forme est rastérisée et peinte dans sa propre couleur.

new Drawing(Vectors.Mark, 240, tint: theme.TextPrimary)   // la moitié monochrome suit le thème

Le sous-ensemble, nommé comme celui du Markdown l'est. Compris : viewBox, path, rect (avec rx/ry), circle, ellipse, line, polyline, polygon, g imbriqué, transform (translate / scale / rotate / skew / matrix, cuit dans les données du tracé plutôt que porté à côté), fill, stroke, stroke-width, fill-rule, les trois opacités, les mêmes propriétés écrites dans un attribut style, et les couleurs en #rgb / #rrggbb / #rrggbbaa / rgb() / rgba() / none / currentColor / les noms de base. Écartés, délibérément : les motifs, clipPath, mask, filter, use, image et text : chacun a besoin d'un serveur de peinture pour lequel ce modèle n'a pas de place, ou d'une police. Ces formes arrivent MANQUANTES plutôt que remplies d'une couleur que personne n'a choisie, et la compilation dit quel fichier elle a sauté.

Une suite de couleurs

Depuis 0.2.0-preview.31

linearGradient et radialGradient sont compris, avec leurs arrêts, dans l'une ou l'autre unité (objectBoundingBox, celle par défaut, est une FRACTION de la boîte propre de la forme ; userSpaceOnUse mesure sur la grille du viewBox), et href est suivi pour une palette que deux dégradés partagent. Les defs sont lues dans une passe à elles, donc un remplissage peut nommer un dégradé que le fichier déclare après lui, ce qu'écrit la moitié des exportateurs du monde.

Chaque cible peint la suite comme elle le peut nativement. Sur le web le dessin porte ses propres defs et chaque forme en nomme un avec url(#…), donc le navigateur interpole à la taille où la boîte finit ; l'id est un hachage du dégradé lui-même, donc une suite utilisée par deux formes est déclarée une fois et le serveur et le jumeau du client atterrissent sur la même chaîne. Sur Photon le même masque alpha que le rastériseur a déjà fait est rempli avec la peinture de dégradé propre au moteur, qui est le dégradé de tracé que le TEXTE utilisait déjà : aucune nouvelle commande de dessin et aucun nouveau point d'entrée de shader.

Deux barrières : une suite traverse avec deux arrêts sur Photon (le premier et le dernier, parce que la peinture du moteur interpole entre une paire ; le multi-arrêt est sa propre tranche), et gradientTransform, spreadMethod et le point focal d'un radial sont écartés. Un serveur de peinture que le lecteur ne comprend pas peint toujours RIEN, ce que faisait chaque serveur de peinture avant cela.

Comment une icône atteint l'écran

Une icône est une VALEUR, pas un service. Icons.Heart est un IconGlyph, un nom, un tracé, et le fait qu'elle soit au trait ou pleine, et le nœud Icon la dessine. Le réalisateur web écrit un <svg> en ligne ; le réalisateur Photon rastérise le tracé une fois et le met en cache. Il n'y a aucun registre à consulter et rien à enregistrer.

Ce fut une interface de fournisseur autrefois (IIconProvider dans eQuantic.UI.Core, résolvant des noms en composants par l'injection de dépendances), et cela est parti avec le modèle de composants d'avant l'écriture unique en 0.2.0-preview.48. Un fournisseur ne peut répondre que sur la cible pour laquelle il a été écrit, et une icône doit être la même icône sur trois.

Vos propres icônes

Deux façons, toutes les deux sans fournisseur :

  • Un fichier .svg dans Assets/ devient un Vectors.Mark à la compilation, voir Un dessin depuis un fichier .svg plus haut.
  • Un IconGlyph que vous construisez, quand vous avez déjà les données du tracé :
public static class MyIcons
{
    // Une propriété et non un champ, délibérément : un pack de champs compile en un
    // constructeur statique et se livre entier, ce dont parle la note sur la découpe plus haut.
    public static IconGlyph Logo => new("logo", "M12 2L2 7l10 5 10-5-10-5z", IconGlyphStyle.Fill);
}

Icon(MyIcons.Logo, size: IconSize.Lg)

Clone this wiki locally