Empezando
Iconos de Lucide animados sobre Web Animations API nativa. Cero dependencias de animación en runtime — ni @angular/animations, ni Motion, ni GSAP.
Instalar
npm i glyphflowAngular 20, 21 o 22 (peerDependencies: >=20.0.0 <23.0.0). La única dependencia real es tslib. Licencia MIT.
Tu primer icono
El componente es standalone: se importa donde se usa, sin módulo intermedio. El icono se pasa como valor, con un import nombrado.
import { Component } from '@angular/core';
import { GfIconComponent, bellIcon } from 'glyphflow';
@Component({
selector: 'app-alert',
imports: [GfIconComponent],
template: '<gf-icon [iconDef]="bell" [size]="24" label="Notifications" />',
})
export class Alert {
protected readonly bell = bellIcon;
}Por qué [iconDef] y no name=
Porque es la ruta que de verdad hace tree-shaking. Los números salen del presupuesto que corre en CI en cada commit, no de una promesa:
| Qué importas | Bundle (gzip) |
|---|---|
| Solo el componente, sin ningún icono | 5.5 KB |
| Componente + 1 icono por import nombrado recomendado | 5.87 KB |
name= con el registro completo | 174.74 KB |
Un icono cuesta ese icono. Buscar por nombre en tiempo de ejecución obliga al bundler a conservar los 1767, porque no puede saber cuál vas a pedir.
Si aun así quieres name=
Existe, y es opt-in a propósito: sin registrar el catálogo, name="bell" no pinta nada y no truena — mismo contrato que un nombre desconocido.
import { provideIconCatalog, ANIMATED_ICONS } from 'glyphflow';
bootstrapApplication(App, {
providers: [provideIconCatalog(ANIMATED_ICONS)],
});Cuándo se anima
trigger | Qué hace |
|---|---|
group | Dibuja al montarse y se anima con el hover del contenedor .group más cercano — el mismo que gobierna group-hover: de Tailwind. Si no hay ninguno, escucha al propio icono. |
hover | Al entrar el puntero. |
tap | Al hacer click. |
view | Al entrar al viewport. Con viewOnce decides si una vez o cada reentrada. |
auto | En cuanto monta. |
manual | Nunca solo: lo disparas tú llamando play() sobre la instancia. |
Velocidad global
Un solo multiplicador para todas las duraciones calculadas — coreografías y transiciones de morph por igual. 1 es sin cambio; sin proveer nada, el comportamiento queda intacto.
import { provideGfIcons } from 'glyphflow';
providers: [provideGfIcons({ durationScale: 0.8 })]Los chips de velocidad de la barra superior de este sitio son exactamente eso, movidos en vivo. Aplican desde la siguiente reproducción: lo que ya está corriendo conserva la duración que el navegador ya recibió.
Morph entre dos iconos
Vive en un entry point aparte, glyphflow/morph, para que quien solo quiera iconos animados no pague la matemática de interpolación de formas.
import { GfIconMorphComponent } from 'glyphflow/morph';
// The binding IS the state: changing [icon] triggers the transition from the previous value.
// <gf-icon-morph [icon]="current()" [size]="32" label="Status" />El primer valor se pinta estático — morphear "desde nada" no existe. Ahí cae también el SSR y cualquier navegador sin WAAPI: se ve el icono, no se anima.
Con qué se siente la transición lo decide [spring]: smooth (default, sin rebote), snappy (rápido, sobrepaso sutil) o bouncy (se pasa del destino y regresa). El resorte no toca la geometría — solo la duración y cómo se reparten los keyframes en el tiempo. También acepta un { k, c } propio si quieres afinarlo tú.