Uso
Buscar en el proyecto
<p><UIIcon name="lucide:search" /> Buscar en el proyecto</p>
<UIButton variant="outline">
<UIIcon name="lucide:trash-2" label="Eliminar" />
</UIButton>
UIIcon
escribe un
<svg>
en línea. Cada nombre literal se resuelve durante el build con el paquete de la colección instalado en el proyecto: no hay peticiones en tiempo de ejecución ni CDN, y el bundle sólo lleva los iconos que usas.
Instalación y colecciones
Necesitas
@meekojs/meeko
>=1.8 <2, con el registro de módulos por su nombre. Instala el módulo y cada colección de Iconify que quieras usar como
@iconify-json/<colección>. El módulo se registra por su nombre y sus opciones van en la clave
icon, tipada en
meeko.config.ts.
// pnpm add @meekojs/icon && pnpm add -D @iconify-json/lucide
// meeko.config.ts
export default defineMeekoConfig({
modules: ['@meekojs/icon'],
icon: {
collections: ['lucide'], // @iconify-json/lucide del proyecto
local: 'app/icons', // SVG propios: 'local:<nombre>'
size: '1em',
include: ['lucide:sun', 'lucide:moon'], // para bind:name
},
})
Los nombres disponibles forman una unión de TypeScript que Meeko genera en
.meeko/types: el editor completa
name="lucide:…", y un nombre que no existe es un error de
meeko check
con la sugerencia más parecida. Si
icon.collections
nombra una colección que no está instalada,
meeko check,
meeko dev
y
meeko build
fallan con el comando para instalarla.
Nombres dinámicos
Con
bind:name, los literales de la expresión se resuelven al compilar igual que un nombre fijo. Un valor que no aparece en el código, como el que llega de datos, sólo funciona si está en
icon.include
(o con
'colección:*', que incluye la colección entera). Si no, se pinta un
<svg>
vacío y
meeko dev
avisa en la consola.
<!-- Literales de la expresión: se resuelven al compilar -->
<UIIcon
bind:name="open.value ? 'lucide:x' : 'lucide:menu'"
bind:label="open.value ? 'Cerrar menú' : 'Abrir menú'" />
<!-- Un valor que llega de datos: el icono debe estar en icon.include -->
<UIIcon bind:name="mode.value" />Cómo se resuelve
- Nombres literales.
Durante el build, un plugin de Vite resuelve cada
name="…"de<UIIcon>con@iconify/utilsy lo incrusta en el componente que lo usa, antes de que Meeko lo compile. El bundle de cada página sólo lleva sus iconos; el SSR y el navegador ven el mismo SVG, así que la hidratación y la navegación no parpadean. - Nombre inexistente.
Es un error de tipos (
TS2820, con la sugerencia más parecida) enmeeko check,meeko buildy el editor; el build también lo rechaza con el archivo y la posición.
Tipos
El módulo genera la unión de los nombres disponibles en
.meeko/types/modules/%40meekojs%2Ficon/, una declaración por colección más la de los SVG locales.
name
de
<UIIcon>
y
icon.include
de
meeko.config.ts
usan esa unión. Con Lucide (2.302 nombres), Tabler y Material Design Icons a la vez (22.802), la comprobación de TypeScript 7 sube unos 35 ms.
import type { IconName } from '@meekojs/icon'
const close: IconName = 'lucide:x'SVG propios
Cada archivo de
app/icons
(o de la carpeta de
icon.local) es
local:<nombre>, en kebab-case. Al compilar se sanea con una lista de elementos y atributos permitidos: se quitan
<foreignObject>,
<image>, enlaces, animaciones,
class
y
<script>,
<style>, manejadores
on*,
style
y toda referencia fuera del icono (href
y
url(…)
sólo a
#id). Los
id
internos se prefijan por icono para que dos iconos no choquen, y un icono de un solo color pasa a
currentColor.
<!-- app/icons/paw.svg -->
<UIIcon name="local:paw" label="Meeko" size="1.5em" />Accesibilidad, tamaño y color
Sin
label, el icono es decorativo:
aria-hidden="true"
y
focusable="false". Con
label, el
<svg>
lleva
role="img"
y
aria-label; úsalo cuando el icono sea el único contenido de un botón o un enlace.
Mide
1em
de alto por defecto, así que sigue al texto que lo rodea, y toma el color con
currentColor. Ancho, alto,
viewBox
y relleno son atributos, nunca estilos en línea: funciona con una Content Security Policy estricta. La hoja del módulo sólo alinea el icono con la línea base (.meeko-icon).
API
| Nombre | Tipo / valor inicial | Descripción |
|---|---|---|
name
|
IconName
| Icono: colección:icono o local:nombre. Un literal se resuelve al compilar. |
label
|
string
| Texto accesible. Sin él, el icono es decorativo. |
size
|
string
icon.size (1em)
| Alto, una longitud CSS. El ancho sigue la proporción del icono. |
class
|
string
| Clases del svg, que siempre lleva meeko-icon. |
Opciones del módulo
| Nombre | Tipo / valor inicial | Descripción |
|---|---|---|
collections
|
string[]
[]
| Colecciones de Iconify (lucide, mdi…); cada una, el paquete @iconify-json/<colección> del proyecto. El editor completa las instaladas. |
include
|
IconInclude[]
[]
| Iconos para nombres dinámicos, o colección:* para una entera. |
local
|
string | false
app/icons si existe
| Carpeta de SVG propios. |
size
|
string
1em
| Alto por defecto de los iconos. |