@weibook/icons-angular
v0.3.4
Published
Weibook icon components for Angular 14+ applications.
Maintainers
Readme
@weibook/icons-angular
Librería de iconos para Angular 14.3+ que replica la ergonomía de mat-icon añadiendo soporte de primera clase para variantes SVG, temas y animaciones.
✨ Características
- Componente
<wb-icon>con la misma experiencia de desarrollo que<mat-icon> - Registro tree-shakeable de iconos mediante
provideWeibookIcons - Soporte de variantes (
download,download:filled,download:outlined, etc.) - Renderizado inline de SVG con caché, peticiones HTTP memoizadas y compatibilidad con SSR
- Temas y tokens de color (
primary,success, variables CSS personalizadas) - Catálogo de animaciones reutilizables (
spin,pulse,bounce,shake) con hooks de extensibilidad - Pipeline de SVG automatizado (optimización SVGO + generación de manifest)
- Compatibilidad con SSR (Angular Universal)
- Accesibilidad integrada (ARIA, soporte para lectores de pantalla)
📦 Instalación
npm install @weibook/icons-angular
# o
yarn add @weibook/icons-angular
# o
pnpm add @weibook/icons-angularRequisitos de Peer Dependencies
- Angular
>=14.3.0 @angular/platform-browsery@angular/common/http
🚀 Inicio Rápido
Configuración con Módulos (Angular 14.3+)
Registra los iconos y valores por defecto una vez en el bootstrap de tu aplicación:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import {
WeibookIconModule,
provideWeibookIconDefaults,
provideWeibookIconManifest,
} from '@weibook/icons-angular';
@NgModule({
imports: [
BrowserModule,
HttpClientModule, // ⚠️ Requerido para cargar SVGs
WeibookIconModule,
],
providers: [
// Animaciones y temas por defecto
...provideWeibookIconDefaults(),
// Registra el manifest generado desde el directorio icons/
...provideWeibookIconManifest(),
],
bootstrap: [AppComponent],
})
export class AppModule {}Configuración Standalone (Angular 15+)
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import {
provideWeibookIconDefaults,
provideWeibookIconManifest,
} from '@weibook/icons-angular';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(), // ⚠️ Requerido para cargar SVGs
...provideWeibookIconDefaults(),
...provideWeibookIconManifest(),
],
});Uso del Componente
Usa el componente de icono en cualquier parte de tus plantillas:
<!-- Por nombre y variante -->
<wb-icon name="download" variant="filled" ariaLabel="Descargar archivo"></wb-icon>
<!-- Con contenido inline (estilo mat-icon) -->
<wb-icon>download</wb-icon>
<wb-icon>download:filled</wb-icon>
<!-- Con animación -->
<wb-icon name="download" animation="spin" ariaLabel="Descargando"></wb-icon>
<!-- Con tema de color -->
<wb-icon name="download" color="primary" ariaLabel="Descargar"></wb-icon>
<!-- Con tamaño personalizado -->
<wb-icon name="download" size="2rem" ariaLabel="Descargar"></wb-icon>
<!-- Con múltiples propiedades -->
<wb-icon
name="download"
variant="outlined"
animation="pulse"
color="success"
size="3rem"
ariaLabel="Descarga completada">
</wb-icon>🛠️ Ayudantes CLI
Agregar la librería
ng add @weibook/icons-angularEste comando imprime instrucciones de configuración y te recuerda registrar los providers.
Generar un nuevo icono
ng g @weibook/icons-angular:generate-icon download --variant=outlinedEsto crea un scaffold en icons/outlined/download.svg con un placeholder y te recuerda ejecutar nuevamente el generador de manifest.
📋 Inputs y Outputs
Inputs
| Input | Tipo | Descripción |
| ------------ | ---------- | --------------------------------------------------------------------------------------------------------- |
| name | string | Nombre del icono registrado en el registro (download) |
| variant | string | Clave de variante (filled, outlined, round, etc.) |
| svgIcon | string | Búsqueda estilo namespace (system:alert) para conjuntos de iconos |
| animation | string | Animación nombrada (spin, pulse, bounce, shake) o clase personalizada |
| color | string | Token de tema (primary) o cualquier color/variable CSS |
| size | string | Tamaño del icono usando font-size (ej: "2rem", "24px") |
| fontSet | string | Lista de clases opcional para fallbacks basados en fuente |
| ariaLabel | string | Etiqueta accesible. Cuando se omite, el icono se oculta de tecnologías de asistencia |
| tabIndex | number | Enfoque de teclado opcional. Por defecto es null |
Outputs
| Output | Tipo | Se emite cuando |
| ------------ | -------- | ---------------------------------------------------------------------------------------------------------- |
| iconError | Event | El icono no puede ser resuelto (error de red, registro faltante, SVG inválido) |
📝 Registro de Iconos
1. Manifest Generado (Recomendado)
Agrega archivos SVG bajo
icons/<variante>/<nombre>.svg(ej:icons/filled/download.svg)Ejecuta el pipeline para optimizar SVGs y regenerar el manifest:
npm run icons:manifestProporciona el manifest en tu app:
...provideWeibookIconManifest()
2. Registro Manual
import { provideWeibookIcons } from '@weibook/icons-angular';
providers: [
...provideWeibookIcons({
defaultVariant: 'filled',
icons: [
{
name: 'download',
variant: 'filled',
source: { url: '/assets/icons/download-filled.svg' },
},
{
name: 'download',
variant: 'outlined',
source: { svgText: '<svg ...></svg>' },
},
],
themes: {
primary: { cssVariable: '--brand-primary' },
},
animations: {
wiggle: {
className: 'animate-wiggle',
inlineStyles: { animationDuration: '700ms' },
},
},
}),
];🎨 Temas y Estrategia de Color
Temas Integrados
La librería incluye los siguientes temas predefinidos:
primary: Color primario de la marca (#246BFE)secondary: Color secundario (#030c1a)success: Color para acciones exitosas (#0B9850) con variante clara (#2DCE89)warning: Color para advertencias (#FF8C42)danger: Color para acciones peligrosas (#FB6340)gray,gray2,gray3: Tonos de gris (#828286, #8898aa, #5f6368)blue2: Azul oscuro (#32325d)purple: Púrpura (#525f7f)muted: Color atenuado para elementos secundarios
Los temas integrados exponen variables CSS que puedes personalizar:
:root {
--wb-icon-primary: #246BFE;
--wb-icon-secondary: #030c1a;
--wb-icon-success: #0B9850;
--wb-icon-success-light: #2DCE89;
--wb-icon-warning: #FF8C42;
--wb-icon-danger: #FB6340;
--wb-icon-gray: #828286;
--wb-icon-gray-2: #8898aa;
--wb-icon-gray-3: #5f6368;
--wb-icon-blue-2: #32325d;
--wb-icon-purple: #525f7f;
--wb-icon-muted: #6B7280;
}Personalización de Temas
Puedes sobrescribir o agregar temas mediante provideWeibookIconThemes:
import { provideWeibookIconThemes } from '@weibook/icons-angular';
providers: [
...provideWeibookIconThemes({
primary: { cssVariable: '--brand-primary' },
custom: { color: '#ff9800' },
}),
];Uso de Colores Directos
El input color también acepta valores directos:
<wb-icon name="download" color="#ff9800"></wb-icon>
<wb-icon name="download" color="rgb(255, 152, 0)"></wb-icon>
<wb-icon name="download" color="var(--mi-variable-css)"></wb-icon>🎬 Animaciones
Animaciones Predefinidas
La librería incluye las siguientes animaciones:
spin: Rotación continua (1.2s)pulse: Pulso de escala y opacidad (1.1s)bounce: Rebote vertical (1.2s)shake: Sacudida horizontal (0.6s)
Uso de Animaciones
<!-- Animación simple -->
<wb-icon name="download" animation="spin"></wb-icon>
<!-- Múltiples animaciones (usando clases CSS personalizadas) -->
<wb-icon name="download" animation="custom-animation"></wb-icon>Registro de Animaciones Personalizadas
import { provideWeibookIconAnimations } from '@weibook/icons-angular';
providers: [
...provideWeibookIconAnimations({
wiggle: {
className: 'wb-icon--wiggle',
inlineStyles: {
animation: 'wiggle 0.7s ease-in-out infinite',
},
keyframes: `
@keyframes wiggle {
0%, 100% { transform: rotate(0deg); }
25% { transform: rotate(-5deg); }
75% { transform: rotate(5deg); }
}
`,
},
}),
];Cada animación puede incluir estilos inline y @keyframes opcionales. El componente inyecta los keyframes en tiempo de ejecución una vez por animación y funciona con DOCUMENT seguro para SSR.
🖼️ Componente de Vista Previa Visual
La librería incluye una galería ligera para inspeccionar rápidamente los iconos registrados:
import { IconGalleryModule, provideWeibookIconManifest } from '@weibook/icons-angular';
@Component({
standalone: true,
selector: 'app-icon-preview',
imports: [IconGalleryModule],
template: `
<wb-icon-gallery title="Iconos Filled" variant="filled"></wb-icon-gallery>
<wb-icon-gallery title="Todos los Iconos" [search]="searchQuery"></wb-icon-gallery>
`,
providers: [...provideWeibookIconManifest()],
})
export class IconPreviewComponent {
searchQuery = '';
}Coloca <wb-icon-gallery> en cualquier ruta solo para desarrollo o página de documentación para obtener una cuadrícula responsive que muestre el manifest actual (filtrable por variant y con búsqueda).
Inputs del Componente de Galería
title: Título de la sección de iconosvariant: Filtrar por variante específica (filled,outlined, etc.)search: Cadena de búsqueda para filtrar iconos por nombre
♿ Accesibilidad y Seguridad
Seguridad
- Sanitización de SVG: El contenido SVG se sanitiza con
DomSanitizerde Angular enIconRegistryService - Validación de viewBox: El pipeline SVGO exige la presencia de
viewBoxpara escalado responsive - Validación de URLs: Se rechazan URLs no seguras
Accesibilidad
- ARIA por defecto: Los iconos usan
aria-hidden="true"por defecto hasta que se proporcionaariaLabel - Enfoque de teclado: El enfoque de teclado es opcional mediante
tabIndex - Manejo de errores:
iconErrorpermite registrar o mostrar UI alternativa cuando los assets faltan - Lectores de pantalla: Los iconos decorativos se ocultan automáticamente; los iconos con significado requieren
ariaLabel
Buenas Prácticas
<!-- Icono decorativo (oculto de lectores de pantalla) -->
<wb-icon name="star"></wb-icon>
<!-- Icono con significado (visible para lectores de pantalla) -->
<wb-icon name="download" ariaLabel="Descargar archivo"></wb-icon>
<!-- Icono interactivo (con enfoque de teclado) -->
<wb-icon
name="settings"
ariaLabel="Configuración"
[tabIndex]="0"
(click)="openSettings()">
</wb-icon>🛠️ Scripts de Desarrollo
| Script | Propósito |
| ----------------------- | ------------------------------------------------------------- |
| npm run icons:manifest| Optimiza SVGs y regenera el manifest de TypeScript |
| npm run build | Genera el manifest y construye el paquete Angular |
| npm run lint | ESLint sobre fuentes de la librería y scripts de herramientas |
| npm test | Suite de pruebas (Karma/Jest) |
El output del build se emite a dist/weibook-icons-angular. Publica desde esa carpeta mediante npm publish.
➕ Agregar Nuevos Iconos
- Coloca SVGs sin procesar en
icons/<variante>/ - Asegúrate de que los trazos usen
currentColore incluyan unviewBox - Ejecuta
npm run icons:manifest - Confirma tanto el SVG actualizado como los archivos generados bajo
projects/icons-angular/src/lib/generated/
Ejemplo de SVG Válido
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7v10l10 5 10-5V7l-10-5z" stroke="currentColor" stroke-width="2" fill="none"/>
</svg>Requisitos:
- ✅ Debe tener
viewBox - ✅ Usar
currentColorpara colores (permite theming) - ✅ Sin IDs duplicados
- ✅ Optimizado (el pipeline SVGO lo optimizará automáticamente)
📚 Ejemplos de Uso
Ejemplo Básico
<wb-icon name="download" variant="filled" ariaLabel="Descargar"></wb-icon>Ejemplo con Contenido Inline
<wb-icon ariaLabel="Descargar">download</wb-icon>
<wb-icon ariaLabel="Descargar versión filled">download:filled</wb-icon>Ejemplo con Animación
<wb-icon name="loading" animation="spin" ariaLabel="Cargando"></wb-icon>
<wb-icon name="notification" animation="pulse" ariaLabel="Nueva notificación"></wb-icon>
<wb-icon name="error" animation="shake" ariaLabel="Error"></wb-icon>Ejemplo con Tema
<wb-icon name="check" color="success" ariaLabel="Completado"></wb-icon>
<wb-icon name="alert" color="warning" ariaLabel="Advertencia"></wb-icon>
<wb-icon name="delete" color="danger" ariaLabel="Eliminar"></wb-icon>
<wb-icon name="info" color="primary" ariaLabel="Información"></wb-icon>
<wb-icon name="settings" color="secondary" ariaLabel="Configuración"></wb-icon>Ejemplo con Tamaño Personalizado
<wb-icon name="star" size="1rem" ariaLabel="Favorito"></wb-icon>
<wb-icon name="star" size="2rem" ariaLabel="Favorito"></wb-icon>
<wb-icon name="star" size="3rem" ariaLabel="Favorito"></wb-icon>Ejemplo Completo
<wb-icon
name="download"
variant="outlined"
animation="pulse"
color="primary"
size="2.5rem"
ariaLabel="Descargar archivo"
[tabIndex]="0"
(click)="downloadFile()"
(iconError)="handleIconError($event)">
</wb-icon>🔗 Enlaces Útiles
- Demo Interactiva: https://sergeist24.github.io/WeibookIcons/
- Repositorio: https://github.com/sergeist24/WeibookIcons
- Reportar Issues: https://github.com/sergeist24/WeibookIcons/issues
- NPM Package: https://www.npmjs.com/package/@weibook/icons-angular
🗺️ Roadmap
- [ ] Pruebas headless basadas en Jest para comportamiento de registro/componente
- [ ] Storybook con controles interactivos y CI de accesibilidad con axe
- [ ] Paquete compartido
@weibook/icon-corepara futuros bindings de React - [ ] Soporte para más variantes de iconos
- [ ] Más animaciones predefinidas
🤝 Contribuciones
¡Las contribuciones son bienvenidas! Abre un issue o PR con propuestas y podemos iterar juntos.
📄 Licencia
MIT License - Copyright (c) 2025 Weibook
