Skip to content

Icons es

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

Ecosistema de iconos

🌐 Esta página en: English · Português · Español · Français · Deutsch

eQuantic.UI provee un ecosistema de iconos completo y extensible. Soporta de fábrica varios conjuntos de iconos populares, todos integrados a través de un modelo de componentes unificado.

🚀 Inicio rápido

Para usar iconos en tu proyecto, instala el paquete del conjunto de iconos que quieras y el paquete de componentes base.

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

Uso

Nada que registrar. Un paquete es un catálogo de IconGlyph: nombras el glifo que quieres y el compilador incorpora ese y solo ese:

using eQuantic.UI.Lucide;

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

Los tamaños son la lista blanca §07 (16 / 20 / 24 / 32). Para un tamaño fuera de esa lista, Vector(glyph, size) dibuja los mismos trazados sin el contrato de icono, y Vector(glyph, size, height: h) le da su propia proporción a una figura no cuadrada (desde 0.2.0-preview.28; el conector de un diagrama fue el caso). Icon(...) es la fábrica del enum Icons curado del propio framework. Ver DeclarativeSurface para saber por qué los dos tienen nombres distintos.

Como nombras el glifo, nada se resuelve en tiempo de ejecución y dos paquetes nunca pueden discrepar sobre un nombre: no hay búsqueda que perder.

Paquete Descripción
eQuantic.UI.Lucide Iconos bellos y consistentes (conjunto por defecto).
eQuantic.UI.Heroicons Bellos iconos SVG hechos a mano por los creadores de Tailwind CSS.
eQuantic.UI.RadixIcons Un conjunto nítido de iconos de 15×15 diseñado por el equipo de Radix UI.
eQuantic.UI.TablerIcons Más de 4200 iconos perfectos al píxel para diseño web.
eQuantic.UI.FontAwesome6.Solid El conjunto de iconos más popular del mundo (variante Solid).
eQuantic.UI.FontAwesome6.Regular Iconos Font Awesome 6 Regular.
eQuantic.UI.FontAwesome6.Brands Iconos de marcas de Font Awesome 6.
eQuantic.UI.Phosphor Una familia de iconos flexible para interfaces, diagramas y más.
eQuantic.UI.SimpleIcons Más de 3000 iconos SVG de marcas populares.
eQuantic.UI.BootstrapIcons Biblioteca de iconos libre, de alta calidad y de código abierto, con más de 2000 iconos.
eQuantic.UI.Iconoir Un conjunto de alta calidad de más de 1500 iconos de código abierto.
eQuantic.UI.MaterialSymbols Material Symbols de Google: 16 284 glifos, el paquete más grande de aquí.

Glifos de paquete, escritura única

Un paquete de iconos es un catálogo de IconGlyph: datos de trazado neutrales al destino, así que la misma entrada sirve al realizador web como SVG en línea y al atlas nativo como geometría de glifo. Dibuja uno con Glyph:

using eQuantic.UI.MaterialSymbols;

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

Glyph, no Icon: Icon es la fábrica del enum Icons curado del propio framework, y la superficie declarativa no tiene sobrecargas. Ver DeclarativeSurface. Los tamaños son la lista blanca §07 (16 / 20 / 24 / 32); para cualquier cosa fuera de ella, Vector(glyph, size) dibuja los mismos trazados sin el contrato de icono, y un argumento height: libera la caja del cuadrado.

Pagas por lo que nombras. eqc incorpora solo los glifos que una página referencia de verdad: una página que usa dos glifos de Material Symbols emite un módulo de 627 bytes, de un catálogo cuya fuente son ~8 MB. El tamaño del paquete es un costo de compilación, no de descarga.

Desde 0.2.0-preview.7

Una nota sobre Material Symbols

Google entrega Material Symbols como una fuente variable con ejes FILL, wght, GRAD y opsz, y los tres cortes (outlined, rounded, sharp) son a lo que esos ejes resuelven. Una lista de display de GPU no puede dibujar una fuente, así que este paquete lleva en su lugar los trazados ya resueltos: el corte vive en el nombre del icono (Home, HomeRounded, HomeSharp) y no hay eje FILL, así que X y XOutline son dos entradas. Los nombres son los de Iconify en PascalCase, así que material-symbols:play-arrow-rounded es PlayArrowRounded.

Es además el paquete más pesado que el framework publica (~13 MB de ensamblado contra los 8 de Phosphor), lo cual antes era un consejo sobre qué paquete elegir, y ya no lo es. Ver abajo.

Un paquete entrega los glifos que tu app nombra

Una app publicada lleva los iconos que USA, no el paquete que referenció. Medido sobre el más grande: el ensamblado del paquete pasa de 14 558 720 bytes a 7680, y una publicación que lo llevaba, de 35 256 KB a 20 952 KB, un 41 % menos, para una app que dibuja un puñado de glifos de 16 284.

Nada que configurar y nada que nombrar. Lo que cambió es la FORMA en la que se generan los paquetes: un inicializador de campo compila en un constructor estático para toda la clase, y un constructor estático no se puede eliminar, así que un paquete de campos se entregaba entero, todo él, para dibujar cinco glifos. Una propiedad con cuerpo de expresión es un cuerpo de método aparte, y el recortador de IL descarta los que nada llama:

// antes: un constructor estático, 16 284 glifos, imposible de eliminar
public static readonly IconGlyph Camera = new("camera", "M14.5 4h-5L7 7", …);

// ahora: un cuerpo de método por glifo, y el recortador guarda los que nombras
public static IconGlyph Camera => new("camera", "M14.5 4h-5L7 7", …);

Necesita PublishTrimmed, que es lo que hace que el recortador corra en absoluto. Sin él el paquete tiene el mismo tamaño que siempre tuvo, así que «elige un paquete más pequeño» sigue siendo el consejo para una publicación sin recorte. Con él, el tamaño del paquete deja de ser una razón para elegir un conjunto sobre otro: elige los iconos que se vean bien.

Desde 0.2.0-preview.47

Arte de un archivo .svg

Desde 0.2.0-preview.29

Un icono es un trazado en un tinte. Un LOGO son varias formas, cada una en el color que eligió su diseñador, eso es Drawing, y es el nodo que apuntas a un archivo.

Pon el archivo en la carpeta Assets de la app y se convierte en un miembro tipado:

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

La lectura ocurre en tiempo de compilación: nada lee un archivo en tiempo de ejecución en ninguno de los dos destinos, porque un navegador no puede y una app nativa estaría llevando su arte dos veces. Un miembro tipado y no una cadena de ruta, por la misma razón por la que el resto de este SDK genera superficies: Vectors.Mark es un error de compilación cuando está mal, y Drawing("mark.svg") es un espacio en blanco en tiempo de ejecución.

Un número conserva la proporción propia del arte (un icono es cuadrado por defecto porque eso es lo que un icono es; un logo achatado es un logo equivocado). Da los dos para enmarcar o estirar a propósito.

Al ancho de su columna. El ancho es un SizeValue, así que SizeValue.Fill toma el ancho que ofrece el padre y la proporción del arte decide la altura: un mapa en una columna adaptable, que ningún número dice para toda ventana. La web escribe width: 100% y aspect-ratio; Photon resuelve el ancho como resuelve el de un lienzo y pinta en la caja que maquetó. Una altura que des sigue ganando. Un fill sobre un ancho que el padre dimensiona desde su propio contenido no tiene nada que llenar y es de ancho cero, como lo es un lienzo, y un dibujo rechaza SizeValue.Hug, ya que no tiene contenido al que ajustarse.

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

Desde 0.2.0-preview.61

Tinte. Una forma que el archivo dejó como currentColor es el arte pidiendo que se le dé tinte, así que pasa tint: y lo sigue, mientras que toda forma que eligió su propio color lo ignora. En la web la palabra currentColor llega al marcado y el tinte se fija como color de CSS, así que la cascada puede responderlo; en Photon cada forma se rasteriza y se pinta en su propio color.

new Drawing(Vectors.Mark, 240, tint: theme.TextPrimary)   // la mitad monocroma sigue al tema

El subconjunto, nombrado como lo está el de Markdown. Se entienden: viewBox, path, rect (con rx/ry), circle, ellipse, line, polyline, polygon, g anidado, transform (translate / scale / rotate / skew / matrix, cocido dentro de los datos del trazado en vez de llevado aparte), fill, stroke, stroke-width, fill-rule, las tres opacidades, las mismas propiedades escritas en un atributo style, y los colores como #rgb / #rrggbb / #rrggbbaa / rgb() / rgba() / none / currentColor / los nombres básicos. Descartados, a propósito: patrones, clipPath, mask, filter, use, image y text: cada uno necesita un servidor de pintura para el que este modelo no tiene espacio, o una fuente. Esas formas llegan AUSENTES en vez de rellenas con un color que nadie eligió, y la compilación dice qué archivo omitió.

Una serie de colores

Desde 0.2.0-preview.31

linearGradient y radialGradient se entienden, con sus paradas, en cualquiera de las dos unidades (objectBoundingBox, la de por defecto, es una FRACCIÓN de la caja propia de la forma; userSpaceOnUse mide sobre la rejilla del viewBox), y se sigue href para una paleta que dos degradados comparten. Las defs se leen en una pasada propia, así que un relleno puede nombrar un degradado que el archivo declara después de él, que es lo que escribe la mitad de los exportadores del mundo.

Cada destino pinta la serie como nativamente puede. En la web el arte lleva sus propios defs y cada forma nombra uno con url(#…), así que el navegador interpola al tamaño en el que la caja termine; el id es un hash del degradado mismo, así que una serie usada por dos formas se declara una vez y el servidor y el gemelo del cliente aterrizan en la misma cadena. En Photon la misma máscara alfa que el rasterizador ya hizo se rellena con la pintura de degradado propia del motor, que es el degradado de trazado que el TEXTO ya usaba: ningún comando de dibujo nuevo y ningún punto de entrada de shader nuevo.

Dos cercas: una serie cruza con dos paradas en Photon (la primera y la última, porque la pintura del motor interpola entre un par; el multiparada es su propia tajada), y gradientTransform, spreadMethod y el punto focal de un radial se descartan. Un servidor de pintura que el lector no entiende sigue pintando NADA, que es lo que todo servidor de pintura hacía antes de esto.

Cómo llega un icono a la pantalla

Un icono es un VALOR, no un servicio. Icons.Heart es un IconGlyph, un nombre, un trazado, y si está trazado o rellenado, y el nodo Icon lo dibuja. El realizador web escribe un <svg> en línea; el realizador de Photon rasteriza el trazado una vez y lo cachea. No hay registro que consultar ni nada que registrar.

Fue una interfaz de proveedor una vez (IIconProvider en eQuantic.UI.Core, resolviendo nombres a componentes por DI), y eso se fue con el modelo de componentes previo a la escritura única en 0.2.0-preview.48. Un proveedor solo puede responder en el destino para el que fue escrito, y un icono tiene que ser el mismo icono en tres.

Tus propios iconos

Dos maneras, ambas sin proveedor:

  • Un archivo .svg en Assets/ se convierte en un Vectors.Mark en tiempo de compilación, ver Arte de un archivo .svg arriba.
  • Un IconGlyph que construyas, cuando ya tienes los datos del trazado:
public static class MyIcons
{
    // Una propiedad y no un campo, a propósito: un paquete de campos compila en un
    // constructor estático y se entrega entero, que es de lo que habla la nota de recorte de arriba.
    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