Frameworks

Un solo conjunto de iconos para todos los frameworks

Todos los paquetes aceptan las mismas props (size, color, weight, corners, variant, animate, modifier, morphTo y el resto) y renderizan el mismo SVG. Elige tu framework o sigue una receta para tu meta framework.

Paquetes

Todo viene en el paquete glyphfox (Angular también tiene glyphfox-angular). Cada framework es una peer dependency opcional que solo se usa cuando importas su punto de entrada. Los componentes de icono son compatibles con tree shaking y todos los puntos de entrada tienen tipos.

FrameworkImportaciónRenderiza
Reactglyphfox/reactComponentes de cliente (marcados con 'use client'), forwardRef
React Server Componentsglyphfox/react/serverIcon y Fusion sin hooks, cero JavaScript
Vue 3glyphfox/vueComponentes y useMorph
Svelte 5glyphfox/svelteArchivos fuente .svelte y morphStore
Angularglyphfox-angularComponente standalone y provider de registro
Solidglyphfox/solidComponentes y useMorph, en servidor y cliente
Preactglyphfox/preactComponentes y hooks, sin capa compat
Qwikglyphfox/qwikComponentes ligeros que se reanudan sin JavaScript
Litglyphfox/litElementos Lit (<gf-file>, <gf-glyph>)
Astroglyphfox/astroComponentes .astro, SVG estático
React Nativeglyphfox/nativeComponentes de react-native-svg
Emberglyphfox/emberHelpers para .gjs, .gts y plantillas clásicas
Componente webglyphfox/web<glyph-fox>, también desde la CDN
Tailwind CSSglyphfox/tailwindClases de máscara CSS

Solid

Toolbar.jsx
import { createSignal } from 'solid-js';
import { HomeIcon, HeartIcon, Fusion, MorphIcon } from 'glyphfox/solid';

export function Toolbar() {
  const [open, setOpen] = createSignal(false);
  return (
    <nav>
      <HomeIcon size={20} class="nav-icon" />
      <HeartIcon animate="pop" trigger="click" variant="duotone" />
      <Fusion icons={['cloud', 'lock']} layout="overlap" />
      <button onClick={() => setOpen(!open())}>
        <MorphIcon name={open() ? 'x' : 'menu'} />
      </button>
    </nav>
  );
}

Sin configurar el compilador de JSX y sin condiciones de exportación especiales: el mismo módulo se renderiza en SolidStart, en el servidor y en el navegador. class, style, ref y los eventos pasan directamente al svg. useMorph(accessor) devuelve un accessor de datos de icono que se transforman cada vez que cambia el nombre.

Preact

App.jsx
import { useState } from 'preact/hooks';
import { FileIcon, HeartIcon, MorphIcon } from 'glyphfox/preact';

export function App() {
  const [copied, setCopied] = useState(false);
  return (
    <>
      <FileIcon size={20} weight={1.5} modifier="check" class="doc" />
      <HeartIcon animate="pop" trigger="click" />
      <MorphIcon name={copied ? 'check' : 'copy'} onClick={() => setCopied(true)} />
    </>
  );
}

La misma API que React (Icon, Fusion, MorphIcon, useMorph), construida sobre preact y preact/hooks, así que no arrastra preact/compat. En Preact 11, un ref llega al elemento svg. Funcionan tanto class como className.

Qwik

header.tsx
import { component$, useSignal } from '@qwik.dev/core';
import { iconX } from 'glyphfox';
import { BellIcon, HomeIcon, MenuIcon, registerIcons } from 'glyphfox/qwik';

registerIcons([iconX]); // names used only by morphTo, Icon or Fusion

export default component$(() => {
  const open = useSignal(false);
  return (
    <header>
      <HomeIcon size={20} class="logo" />
      <BellIcon animate="shake" trigger="hover" />
      <button onClick$={() => (open.value = !open.value)}>
        <MenuIcon morphTo="x" trigger="state" active={open.value} />
      </button>
    </header>
  );
});

Pensado para Qwik 2 (@qwik.dev/core). Los iconos son componentes ligeros: se renderizan en el servidor y se reanudan sin descargar nada. Los estados vivos y morphTo funcionan con CSS, active alterna trigger="state" y trigger="click" usa un pequeño handler inline. Los nombres que usan Icon, morphTo y Fusion deben registrarse: los componentes de icono registran su icono, y registerIcons([iconX]) (o registerIcons(icons) con icons de glyphfox para todo el conjunto) cubre los nombres que solo escribes como strings.

Lit

app.js
import { LitElement, html } from 'lit';
import { defineIcons, FileIcon, HeartIcon, Icon, Fusion, MorphIcon } from 'glyphfox/lit';

// <gf-file>, <gf-heart>, <gf-glyph>, <gf-fusion> and <gf-morph>
defineIcons([FileIcon, HeartIcon, Icon, Fusion, MorphIcon]);

class AppBar extends LitElement {
  static properties = { open: { type: Boolean } };
  render() {
    return html`
      <gf-file size="20" weight="1.5" modifier="check"></gf-file>
      <gf-heart animate="pop" trigger="click" secondary-color="#ff7a1a"></gf-heart>
      <gf-glyph name="cloud&lock:overlap"></gf-glyph>
      <gf-morph .name=${this.open ? 'x' : 'menu'} @click=${() => (this.open = !this.open)}></gf-morph>
    `;
  }
}
customElements.define('app-bar', AppBar);

Nada se registra al importar: defineIcons(list, { prefix }) define los elementos que usas ({ prefix: 'my' } da <my-file>). Los atributos van en kebab-case (secondary-color, flip-x, morph-to) y las propiedades en camelCase; el atributo animate es la propiedad animatePreset, porque animate() es un método de todo elemento, y animation reproduce la animación diseñada, como en todos los paquetes. class y style dan estilo al elemento host. Los elementos se renderizan en shadow DOM y funcionan con @lit-labs/ssr.

Astro

src/pages/index.astro
---
import { HomeIcon, BellIcon, Icon, Fusion } from 'glyphfox/astro';
import SearchIcon from 'glyphfox/astro/icons/search';
---

<nav>
  <HomeIcon size={20} class:list={['nav-icon', { active: true }]} />
  <SearchIcon weight={1.5} />
  <BellIcon animate="shake" trigger="hover" />
  <Icon name="file+check@tr" variant="duotone" />
  <Fusion icons={['cloud', 'lock']} layout="overlap" />
</nav>

Los componentes renderizan SVG estático en el servidor y no envían JavaScript. Todos los iconos del conjunto están disponibles para los nombres de Icon, morphTo y Fusion. class (y class:list), style como string u objeto y cualquier otro atributo pasan directamente al svg. Los disparadores hover, mount y state funcionan con CSS; trigger="click" usa un pequeño handler inline.

React Native

terminal
npm install glyphfox react-native-svg
Tabs.tsx
import { HomeIcon, BellIcon, HeartIcon, MorphIcon } from 'glyphfox/native';

export function Tabs({ open, unread }) {
  return (
    <View style={{ flexDirection: 'row', gap: 16 }}>
      <HomeIcon size={28} color="#ff7a1a" />
      <BellIcon animate="shake" trigger="state" active={unread > 0} />
      <HeartIcon animate="pop" trigger="click" variant="duotone" />
      <MorphIcon name={open ? 'x' : 'menu'} style={{ marginLeft: 'auto' }} />
    </View>
  );
}

Los componentes renderizan elementos de react-native-svg con las mismas props. En nativo no hay CSS, así que los estados vivos se muestrean fotograma a fotograma a partir de las mismas animaciones y los morphs se interpolan; ambos respetan el ajuste de movimiento reducido. trigger="click" se reproduce al pulsar y trigger="hover" mientras se mantiene pulsado. title define la etiqueta de accesibilidad, style y las demás props llegan al Svg, y los refs se reenvían. Metro resuelve el export glyphfox/native con package exports, activados por defecto desde React Native 0.79.

Ember

app/components/toolbar.gjs
import { FileIcon, BellIcon, Glyph, Fusion } from 'glyphfox/ember';

<template>
  {{FileIcon size=20 weight=1.5 class="toolbar-icon"}}
  {{BellIcon animate="shake" trigger="hover"}}
  {{Glyph "file+check@tr" variant="duotone"}}
  {{Fusion "cloud" "lock" layout="overlap"}}
</template>

Helpers de función simples (Ember 4.5 o posterior), así que no necesitan configurar ningún addon y funcionan en .gjs, .gts y plantillas clásicas. Devuelven markup de confianza: las props compartidas, class, style y los demás atributos son argumentos con nombre. Los nombres que usan Glyph, morphTo y Fusion deben registrarse: los helpers de icono registran su icono, y registerIcons([iconCloud]) (o registerIcons(icons)) cubre el resto. Los disparadores hover, mount y state funcionan con CSS; trigger="click" usa un pequeño handler inline.

Recetas