¿Qué hace shadcn-svelte?
Un framework para construir UI, componentes y sistemas de diseño para Svelte. Los componentes se agregan como código fuente al proyecto del usuario a través de la CLI.
IMPORTANTE: Ejecute todos los comandos de la CLI usando el ejecutor de paquetes del proyecto:
npx shadcn-svelte@latest,pnpm dlx shadcn-svelte@latest, obunx --bun shadcn-svelte@latest— según el gestor de paquetes del proyecto. Los ejemplos siguientes usannpx shadcn-svelte@latestpero sustituya con el ejecutor correcto para el proyecto.
Contexto Actual del Proyecto
Lea components.json en la raíz del proyecto y, cuando necesite la estructura de archivos en vivo, liste el directorio dado por la ruta aliases.ui (resuelta con las mismas reglas que la CLI).
Importaciones (Svelte)
Cada componente vive en su propia carpeta con un archivo index.ts de barril. Siga la documentación de instalación:
- Componentes de múltiples partes (dialog, select, card, field, tabs, …):
import * as Dialog from "$lib/components/ui/dialog"y luegoDialog.Content,Dialog.Title,Card.Root,Card.Header, etc. — lo que exporte el barril (nombres cortos y/o aliasRoot as …). - Barriles de un solo componente (solo un componente significativo en la carpeta): importaciones nombradas —
import { Button } from "$lib/components/ui/button"y<Button>, noimport * as Button+Button.Root. Mismo patrón para{ Input },{ Badge },{ Spinner },{ Checkbox },{ Separator },{ Skeleton }, etc.
import * as Dialog from "$lib/components/ui/dialog";
import { Button } from "$lib/components/ui/button";
import { Separator } from "$lib/components/ui/separator";
Use los alias reales de components.json (a menudo $lib/components/ui/...), no rutas hardcodeadas.
Principios
- Use los componentes existentes primero. Ejecute
npx shadcn-svelte@latest addsin argumentos para explorar los componentes disponibles, o revise Componentes antes de escribir UI personalizada. - Componga, no reinvente. Página de configuración = Tabs + Card + controles de formulario. Dashboard = Sidebar + Card + Chart + Table.
- Use variantes incorporadas antes que estilos personalizados.
variant="outline",size="sm", etc. - Use colores semánticos.
bg-primary,text-muted-foreground— nunca valores planos comobg-blue-500.
Reglas Críticas
Estas reglas se aplican siempre. Cada una enlaza a un archivo con pares Incorrecto/Correcto.
Estilización y Tailwind → styling.md
classpara diseño, no para estilización. Nunca sobrescriba colores o tipografía de componentes.- Sin
space-x-*nispace-y-*. Useflexcongap-*. Para pilas verticales,flex flex-col gap-*. - Use
size-*cuando ancho y alto sean iguales.size-10now-10 h-10. - Use la abreviatura
truncate. Nooverflow-hidden text-ellipsis whitespace-nowrap. - Sin sobrescrituras manuales de color
dark:. Use tokens semánticos (bg-background,text-muted-foreground). - Use
cn()para clases condicionales. No escriba ternarios manuales con literales de plantilla. - Sin
z-indexmanual en componentes de superposición. Dialog, Sheet, Popover, etc. manejan su propio apilamiento.
Formularios e Inputs → forms.md
- Los formularios usan
Field.FieldGroup+Field.Field. Nunca usedivplano conspace-y-*ogrid gap-*para el diseño del formulario. InputGroupusaInputGroup.Input/InputGroup.Textarea. NuncaInput/Textareaplanos dentro deInputGroup.Root.- Botones dentro de inputs usan
InputGroup.Root+InputGroup.Addon. - Conjuntos de opciones (2–7 opciones) usan
ToggleGroup. No recorraButtoncon estado activo manual. Field.FieldSet+Field.FieldLegendpara agrupar checkboxes/radios relacionados. No use undivcon un encabezado.- La validación de campos usa
data-invalid+aria-invalid.data-invalidenField,aria-invaliden el control. Para deshabilitado:data-disabledenField,disableden el control.
Estructura de Componentes → composition.md
- Los elementos siempre dentro de su Grupo.
Select.Item→Select.Group.DropdownMenu.Item→DropdownMenu.Group.Command.Item→Command.Group. - Triggers personalizados. Envuelva los controles en
Dialog.Trigger/AlertDialog.Trigger, o controle el estado abierto conbind:openen la raíz — consulte la documentación del componente. - Dialog, Sheet y Drawer siempre necesitan un Title.
Dialog.Title,Sheet.Title,Drawer.Titlerequeridos para accesibilidad. Useclass="sr-only"si está oculto visualmente. - Use la composición completa de Card.
Card.Header/Card.Title/Card.Description/Card.Content/Card.Footer. No ponga todo enCard.Content. - Button no tiene
isPending/isLoading. Componga conSpinnerdentro deButton+disabled; usedata-icon="inline-start"/inline-endenSpinnerpara el espaciado correcto (import { Button },import { Spinner }). Tabs.Triggerdebe estar dentro deTabs.List. Nunca renderice triggers directamente enTabs.Avatarsiempre necesitaAvatar.Fallback. Para cuando la imagen no carga.
Use Componentes, No Marcado Personalizado → composition.md
- Use componentes existentes antes que marcado personalizado. Verifique si existe un componente antes de escribir un
divestilizado. - Las llamadas de atención usan
Alert. No construya divs personalizados estilizados. - Los estados vacíos usan
Empty. No construya marcado de estado vacío personalizado. - Toast vía
svelte-sonner. Usetoast()desvelte-sonnercon el componente Sonner desde su carpeta de UI. - Use
Separatoren lugar de<hr>o undivcon solo clases de borde. - Use
Skeletonpara marcadores de posición de carga. Sin divsanimate-pulsepersonalizados. - Use
Badgeen lugar de spans estilizados personalizados.
Iconos → icons.md
- Los iconos en
<Button>usandata-icon.data-icon="inline-start"odata-icon="inline-end"en el icono. - Sin clases de tamaño en iconos dentro de componentes. Los componentes manejan el tamaño de iconos vía CSS. Sin
size-4niw-4 h-4. - Pase los iconos como componentes. Importe desde la
iconLibraryconfigurada (ej.@lucide/svelte), no claves de cadena.
CLI
- Presets — copie la cadena codificada del constructor de sistemas de diseño en shadcn-svelte.com y pase a
npx shadcn-svelte@latest init --preset <code>.
Patrones Clave
Estos son los patrones más comunes que diferencian el código shadcn-svelte correcto. Para casos extremos, consulte los archivos de reglas enlazados arriba.
<script lang="ts">
import * as Field from "$lib/components/ui/field";
import { Input } from "$lib/components/ui/input";
import { Button } from "$lib/components/ui/button";
import SearchIcon from "@lucide/svelte/icons/search";
import { Badge } from "$lib/components/ui/badge";
import * as Avatar from "$lib/components/ui/avatar";
</script>
<!-- Diseño de formulario: Field.FieldGroup + Field.Field, no div + Label. -->
<Field.FieldGroup>
<Field.Field>
<Field.FieldLabel for="email">Correo electrónico</Field.FieldLabel>
<Input id="email" />
</Field.Field>
</Field.FieldGroup>
<!-- Validación: data-invalid en Field, aria-invalid en el control. -->
<Field.Field data-invalid>
<Field.FieldLabel for="email">Correo electrónico</Field.FieldLabel>
<Input id="email" aria-invalid />
<Field.FieldDescription>Correo electrónico inválido.</Field.FieldDescription>
</Field.Field>
<!-- Iconos en botones: data-icon, sin clases de tamaño. -->
<Button>
<SearchIcon data-icon="inline-start" />
Buscar
</Button>
<!-- Espaciado: gap-*, no space-y-*. -->
<div class="flex flex-col gap-4"></div>
<!-- Dimensiones iguales: size-*, no w-* h-*. -->
<Avatar.Root class="size-10">
<Avatar.Image src="/u.png" alt="Usuario" />
<Avatar.Fallback>U</Avatar.Fallback>
</Avatar.Root>
<!-- Colores de estado: variantes de Badge o tokens semánticos, no colores planos. -->
<Badge variant="secondary">+20.1%</Badge>
Selección de Componentes
| Necesidad | Use |
|---|---|
| Botón/acción | Button con variante apropiada (import { Button }) |
| Inputs de formulario | Input, Select, Combobox, Switch, Checkbox, RadioGroup, Textarea, InputOTP, Slider |
| Alternar entre 2–5 opciones | ToggleGroup.Root + ToggleGroup.Item |
| Visualización de datos | Table, Card, Badge, Avatar |
| Navegación | Sidebar, NavigationMenu, Breadcrumb, Tabs, Pagination |
| Superposiciones | Dialog (modal), Sheet (panel lateral), Drawer (hoja inferior), AlertDialog (confirmación) |
| Retroalimentación | svelte-sonner (toast), Alert, Progress, Skeleton, Spinner |
| Paleta de comandos | Command dentro de Dialog |
| Gráficos | Chart (LayerChart) |
| Diseño | Card, Separator, Resizable, ScrollArea, Accordion, Collapsible |
| Estados vacíos | Empty |
| Menús | DropdownMenu, ContextMenu, Menubar |
| Tooltips/info | Tooltip, HoverCard, Popover |
Campos Clave
Use components.json y el sistema de archivos — no un comando info separado:
aliases→ use el prefijo de alias real de la configuración (ej.$lib/), nunca hardcodee proyectos no relacionados.tailwind.css→ el archivo CSS global donde viven las variables de tema. Edite este archivo para ajustes de tema; no agregue un segundo archivo de globales a menos que el usuario ya use uno.style→ tratamiento visual (ej.nova,vega, …) y ruta de estilo del registro.iconLibrary→ determina los paquetes de iconos (@lucide/svelte,@tabler/icons-svelte, etc.). Nunca asuma@lucide/svelte.registry→ de dónde la CLI obtiene los componentes; registro oficial predeterminado enshadcn-svelte.com.resolvedPaths(conceptual) → la CLI resuelvealiasesa rutas absolutas; listealiases.uien disco para ver los componentes instalados.
Consulte cli.md para comandos y banderas.
Documentación, Ejemplos y Uso de Componentes
Abra https://shadcn-svelte.com/docs/components/<name>.md para documentación y ejemplos. Al crear, arreglar, depurar o usar un componente, lea primero la página oficial para seguir las APIs documentadas.
Flujo de Trabajo
- Obtenga el contexto del proyecto — lea
components.jsony liste el directorio de componentes de UI cuando sea necesario. - Verifique los componentes instalados primero — antes de ejecutar
add, liste los archivos bajo la rutauiresuelta. No importe componentes que no se hayan agregado, y no vuelva a agregar los ya presentes a menos que se actualicen. - Descubra componentes —
npx shadcn-svelte@latest addsin argumentos (lista interactiva), o el sitio de documentación. - Instale o actualice —
npx shadcn-svelte@latest add <name>o una URL de registro. Para actualizar archivos existentes desde el registro, usenpx shadcn-svelte@latest update(consulte cli.md). - Arregle importaciones en elementos de terceros / agregados por URL — Después de agregar desde una URL de registro personalizada, verifique rutas hardcodeadas que no coincidan con los
aliasesdel proyecto. Reescriba las importaciones para usar los aliasui/libdel proyecto desdecomponents.json. - Revise los componentes agregados — Después de agregar, lea los archivos agregados y verifique la composición (grupos, títulos, atributos de validación). Alinee las importaciones de iconos con
iconLibrary. - Elementos de registro remoto — Agregar por URL es explícito; si el usuario quiere un componente de una fuente desconocida, confirme la URL del registro o el elemento antes de ejecutar
add.
Sistemas de Diseño desde DESIGN.md
Cuando el usuario solicite un sistema de diseño desde un DESIGN.md (o una especificación de marca), con o sin un preset, siga design-system.md de principio a fin:
- Para una nueva aplicación, genere SvelteKit con
npx sv create <app>(o Svelte + Vite cuando se solicite), luego inicialice connpx shadcn-svelte@latest init --preset <code>. Sin un código, elija un estilo que se ajuste al DESIGN.md y pase su nombre, ej.init --preset luma; los códigos de preset de React y las banderas de generación no aplican. En una aplicación existente, conserve las personalizaciones locales. - Instale cada componente con
add --all --yesen una nueva aplicación; agregue solo los componentes faltantes en una existente. - Lea el frontmatter del DESIGN.md, los Hacer y No Hacer, y las Brechas Conocidas antes de editar.
- Mapee sus tokens en las variables de
components.json'stailwind.css. Fije la escala de radio, sombras, fuentes y utilidadestype-*. - Reestilice las variantes instaladas de
tailwind-variantsy el CSS de estilo asociado. Cambie las alturas de los controles juntos. - Construya la página según design-system-page.md: roles de color verificados por contraste, especímenes de tipo, matrices de estado fijadas, casos extremos, pares hacer/no hacer, recetas. Verifique importaciones con
scripts/showcase-coverage.mjs, luego verifique que cada componente se renderice. - Verifique en un navegador:
svelte-check, compilación de producción incluyendo SSR, sin errores de consola, cargue en la parte superior, sin desbordamiento horizontal, modo oscuro.
Actualización de Componentes
Use el comando update para obtener las últimas versiones del registro de componentes ya en el proyecto. Revise los cambios con git diff después de update.
- Guarde o stash el trabajo local.
- Ejecute
npx shadcn-svelte@latest update [component]o--all. - Resuelva conflictos de fusión si había personalizado archivos.
- Nunca use
--overwriteenaddsin la aprobación explícita del usuario cuando destruiría ediciones intencionales.
Referencia Rápida
# Inicializar shadcn-svelte en el proyecto
npx shadcn-svelte@latest init
# Inicializar con un preset (código del constructor de la web)
npx shadcn-svelte@latest init --preset <code>
# Agregar un componente específico
npx shadcn-svelte@latest add button
# Agregar todos los componentes (nuevo proyecto)
npx shadcn-svelte@latest add --all --yes
# Agregar desde una URL de registro personalizada
npx shadcn-svelte@latest add <url>
# Actualizar componentes instalados
npx shadcn-svelte@latest update [componente] o --all
# Explorar componentes disponibles (modo interactivo)
npx shadcn-svelte@latest add
# Obtener ayuda
npx shadcn-svelte@latest help
Reglas de Importación Por Componente (Referencia Rápida)
| Tipo de componente | Patrón de importación |
|---|---|
| Button, Input, Badge, Spinner | import { Button } from "$lib/components/ui/button" |
| Dialog, Select, Card, Tabs | import * as Dialog from "$lib/components/ui/dialog" |
| Multiple partes (Field, etc.) | import * as Field from "$lib/components/ui/field" |
Nota: Consulte siempre el archivo
index.tsdel componente para confirmar qué exporta; los patrones anteriores son la convención estándar pero pueden variar para componentes personalizados o de terceros.