Frameworks

Iconos para React

Cada icono de glyphfox es un componente de React que renderiza SVG en línea. Las mismas props sirven para todos los iconos, no hace falta ningún proveedor y los componentes que no importas nunca llegan a tu bundle.

Instalación

Los componentes de React están en el paquete principal glyphfox, bajo el punto de entrada glyphfox/react. React es una peer dependency opcional: el paquete funciona con React 16.8 y versiones posteriores porque solo necesita hooks y forwardRef, y su conjunto de pruebas se ejecuta con React 19.

terminal
npm install glyphfox

No hay que importar ninguna hoja de estilos ni agregar ningún plugin de compilación. El paquete incluye compilaciones ESM y CommonJS con declaraciones de tipos, así que Vite, webpack, Rspack, esbuild y Parcel lo usan tal cual.

Renderiza tus primeros iconos

Cada icono se exporta con su nombre en PascalCase y el sufijo Icon: home se convierte en HomeIcon, arrow-right en ArrowRightIcon y message-circle en MessageCircleIcon. Busca un nombre en el explorador de iconos; la página de cada icono, como la de arrow right, también muestra la línea de importación.

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>
  );
}

Sin props, un icono mide 24 por 24 píxeles, se dibuja con stroke="currentColor" (así toma el color del texto de su elemento padre) y se marca con aria-hidden="true", porque la mayoría de los iconos aparecen junto a una etiqueta visible. Dale un title cuando el icono sea lo único que transmite el significado; la guía de accesibilidad explica los patrones.

Tamaño, color, peso y estilo

Cada icono se renderiza según tres ejes: peso, esquinas y estilo. Son props normales, así que pueden variar según el estado, los temas o los breakpoints, como cualquier otro valor.

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 acepta un número de píxeles o cualquier longitud CSS en forma de cadena, como "1.25em".
  • weight va de 1 a 3 en la cuadrícula de 24. Por debajo de 24 píxeles, el trazo se compensa ópticamente, hasta un 30 por ciento más grueso en los tamaños más pequeños, para que un icono de 16 píxeles conserve la misma presencia que uno de 24. absoluteWeight desactiva esa compensación y mantiene el trazo exactamente en weight píxeles.
  • variant="duotone" usa la segunda capa dibujada a mano si el icono la tiene o, si no, un relleno translúcido de sus formas cerradas. variant="solid" rellena las formas cerradas y recorta las líneas interiores como espacio negativo.
  • mirrorRtl refleja los iconos direccionales cuando se renderizan dentro de dir="rtl", así que el mismo marcado funciona en ambas direcciones.

Iconos por nombre

Cuando el icono viene de los datos, como un campo de un CMS, una tabla de rutas o una preferencia del usuario, renderízalo con Icon y un nombre. La prop name acepta la sintaxis de nombres completa que comparten todos los paquetes de glyphfox, así que los modificadores, las fusiones y los estilos funcionan a partir de una sola cadena.

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>
  );
}

Los nombres que no se han importado en ninguna parte se cargan bajo demanda con una importación dinámica. webpack y esbuild la dividen en un pequeño chunk por icono y, hasta que llega ese chunk, Icon renderiza un SVG vacío del tamaño correcto, para que el diseño no dé saltos. Una compilación de producción de Vite deja esa importación intacta dentro de node_modules, por lo que, en ese caso, el nombre se queda vacío (la guía de tree shaking da los detalles). En todos los bundlers la solución es la misma: registra una vez, al arrancar, los datos de los nombres que renderizas a partir de cadenas, y se dibujan de forma síncrona, desde el primer renderizado y también en el servidor:

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

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

Las exportaciones de datos (iconSettings, iconArrowRight...) vienen del punto de entrada principal glyphfox y, como los componentes, son compatibles con tree shaking: importar una ocupa unos pocos cientos de bytes. Importar un componente como SettingsIcon también registra sus datos.

Modificadores y fusiones

Un modificador es una pequeña insignia en una esquina de cualquier icono: plus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down o dot. El icono de debajo se recorta alrededor de la insignia dejando un hueco de recorte, así que las líneas nunca se tocan, sea cual sea el peso.

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 combina de 2 a 10 iconos en un icono nuevo que sigue cumpliendo las reglas de los iconos: un único peso, la cuadrícula de 24 y el margen interior. Las disposiciones son overlap, side, stack, grid, orbit, badge e inside; gap define el hueco de recorte en unidades de la cuadrícula, y scale y offsets ajustan con precisión cada parte. Fusion acepta todas las props compartidas, así que un icono fusionado puede ser duotone, estar animado o llevar una etiqueta, como cualquier otro.

Morph y estados vivos

Tres herramientas se encargan del movimiento. MorphIcon se transforma cada vez que cambia su name. morphTo, en cualquier icono, lo transforma hacia un destino cuando se activa su trigger. animate reproduce un preset (draw, pop, wiggle, spin, pulse, bounce o shake) al montarse, al pasar el puntero por encima, al hacer clic o mientras active sea true.

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'} />
    </>
  );
}

Para un renderizador propio, useMorph(name, { duration }) devuelve los datos del icono en el fotograma actual, que puedes pasar a Icon mediante su prop icon o a tu propio código de dibujo. Todas las animaciones respetan prefers-reduced-motion. La guía de iconos animados repasa los presets, los disparadores y los pares de morph ajustados a mano.

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 y eventos

Los componentes se crean con forwardRef, así que una ref apunta al elemento <svg> renderizado. className se agrega después de las clases integradas glyphfox glyphfox-NAME, style se pasa tal cual, y cualquier otro atributo SVG o controlador de eventos (onClick, data-*, aria-*, id) va directamente al elemento.

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 pasado de esta forma también marca el icono como significativo: el componente cambia automáticamente de aria-hidden a role="img".

TypeScript

Los tipos vienen incluidos en el paquete. GlyphIconComponent es el tipo de todos los componentes de icono, GlyphProps son sus props (las props compartidas más todos los atributos SVG) y IconName, del punto de entrada principal, es la unión de todos los nombres de iconos, lo que te da autocompletado en Icon y en tus propios datos.

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

Importaciones y tamaño del bundle

Las importaciones con nombre de glyphfox/react son compatibles con tree shaking: cada icono es un módulo propio, creado con una llamada anotada como pura, y el paquete declara qué archivos tienen efectos secundarios. Las importaciones profundas como glyphfox/react/icons/home cargan directamente un único módulo de icono, lo que ayuda a las herramientas que no hacen tree shaking y evita que los servidores de desarrollo procesen el índice completo.

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

La guía de tree shaking analiza, con mediciones, qué rompe el tree shaking, cuánto cuesta el runtime compartido y por qué la salida de la compilación contiene un chunk diminuto por icono.

Props

Todos los componentes de icono, Icon, Fusion y MorphIcon aceptan las mismas props. Tienen el mismo nombre y significado en Vue, Svelte, Angular, el web component y toSvg, así que un valor copiado del Estudio funciona en todas partes.

PropTipoPor defectoDescripción
sizenumber, string24Ancho y alto; los números son píxeles.
colorstringcurrentColorColor principal.
secondaryColorstringcolorColor de la capa duotone y del relleno sólido.
secondaryOpacitynumber0.3 / 1Opacidad de la capa duotone o del relleno sólido.
weightnumber2Trazo de 1 a 3 en la cuadrícula de 24, con compensación óptica por debajo de 24 px.
absoluteWeightbooleanfalseMantiene el trazo en weight píxeles a cualquier tamaño.
cornersround, sharproundUniones y extremos redondeados o rectos.
variantoutline, duotone, solidoutlineEje de estilo; solid se obtiene de las formas cerradas.
rotatenumber0Rotación en grados.
flipXbooleanfalseRefleja en horizontal.
flipYbooleanfalseRefleja en vertical.
mirrorRtlbooleanfalseRefleja en layouts de derecha a izquierda.
animatedraw, pop, wiggle, spin, pulse, bounce, shakeningunoPreset de estado vivo.
triggermount, hover, click, statemountCuándo se reproduce la animación o el morph.
activebooleanfalseEl estado para el disparador state.
durationnumber (ms)según el presetDuración de la animación o del morph.
delaynumber (ms)0Retraso de la animación o del morph.
loopboolean, numberfalseRepite sin fin o un número de veces (spin y pulse se repiten por defecto).
modifierplus, minus, check, x, alert, lock, clock, sync, arrow-up, arrow-down, dotningunoInsignia con hueco de recorte automático.
modifierCornertop-left, top-right, bottom-left, bottom-rightbottom-rightEsquina de la insignia.
morphToname, dataningunoDestino del morph; el disparador decide cuándo se muestra.
titlestringningunoNombre accesible: title, role img y aria-label.
decorativebooleantrue sin titleOculta el icono a las tecnologías de apoyo.

Icon y MorphIcon también aceptan name (cualquier forma de la sintaxis de nombres) o icon (datos de icono). Fusion acepta icons, layout, gap, scale y offsets.

Errores comunes

Icon se renderiza vacío al principio
Un nombre que todavía no está registrado se carga con una importación dinámica, así que el primer renderizado (y el renderizado en el servidor) es un SVG vacío. Importa el componente o llama a registerIcons con los datos de cada nombre que renderices mediante una cadena.
Server Components de Next.js
Los componentes usan hooks y el paquete no tiene la directiva "use client", así que un Server Component no puede renderizarlos directamente. La guía de Next.js muestra la solución de un solo archivo y una opción sin JavaScript.
Colorear con fill
Los iconos son trazos sobre fill="none". Si pasas fill, se rellenan todas las formas, y eso rara vez es lo que quieres. Usa color (o la propiedad CSS color en un elemento padre) para el trazo y variant="solid" para las formas rellenas.
El CSS global anula el peso
Una regla de una hoja de estilos como svg { stroke-width: 1.5 } tiene prioridad sobre el atributo SVG que lleva el eje de peso, incluida su compensación óptica. Limita el alcance de esas reglas o usa la prop weight.
Los tamaños relativos se saltan la compensación óptica
La compensación necesita conocer el tamaño en píxeles. Con size="1em", el trazo se queda en el peso sin compensar, lo que puede verse fino con tamaños de texto pequeños; pasa un número de píxeles donde importe o un weight un poco más alto.
Llamar a createIcon durante el renderizado
createIcon(data) convierte tus propios datos de icono en un componente con todas las props. Llámalo una sola vez a nivel de módulo: si lo llamas dentro de un componente, crea un tipo de componente nuevo en cada renderizado y vuelve a montar el SVG.
import * con una clave dinámica
Icons[name] sobre una importación de espacio de nombres mantiene todos los iconos en el bundle. Usa en su lugar Icon con un nombre, que solo carga lo que se renderiza.

Preguntas frecuentes

¿Puedo usar mis propios iconos con las mismas props?

Sí. createIcon(data) de glyphfox/react recibe datos de icono (name, body, tags, categories) y devuelve un componente con todas las props compartidas, incluidos el peso, los estilos duotone y solid, los modificadores y el morph. Dibuja el icono en el editor del Estudio o convierte un SVG existente con Fox-ify para que siga las mismas reglas de cuadrícula y trazo.

¿Cómo defino un tamaño o un peso predeterminado para todos los iconos?

El paquete de React no tiene proveedor, así que lo habitual es un pequeño componente envoltorio como const NavIcon = (props) => <Icon size={20} weight={1.75} {...props} />. El color no necesita nada: los iconos siguen el color CSS de su elemento padre.

Iconos de esta guía