Para los desarrolladores web, la búsqueda del conjunto de herramientas de interfaz de usuario (UI) perfecto es un esfuerzo constante. Durante años, los desarrolladores de React han dependido de bibliotecas de componentes tradicionales como Material-UI (MUI), Ant Design y Chakra UI. Estas bibliotecas ofrecen una gran cantidad de componentes preconstruidos, prometiendo acelerar el desarrollo. Sin embargo, a menudo vienen con una contrapartida: falta de control, anulaciones de estilo que se sienten como una batalla y tamaños de paquete inflados.
Presentamos Shadcn UI, un enfoque que cambia el paradigma y que ha arrasado en la comunidad de React. No es una biblioteca de componentes como las que estás acostumbrado; es algo mejor. Es una colección de componentes bellamente diseñados, accesibles y infinitamente reutilizables que no instalas desde npm como una dependencia, sino que los copias directamente en tu proyecto.
Este tutorial completo de 4000 palabras servirá como tu guía definitiva, llevándote de ser un principiante total a un practicante seguro de Shadcn UI. Exploraremos su filosofía fundamental, recorreremos una configuración detallada, construiremos interfaces de usuario complejas, dominaremos el theming avanzado y el manejo de formularios, y discutiremos las mejores prácticas para aplicaciones a gran escala. Prepárate para replantearte lo que esperas de un conjunto de herramientas de UI.
¿Quieres una plataforma integrada y todo en uno para que tu equipo de desarrolladores trabaje junto con la máxima productividad?
¡Apidog cumple todas tus demandas y reemplaza a Postman a un precio mucho más asequible!
La Filosofía de Shadcn UI - Una Nueva Forma de Construir
Antes de escribir una sola línea de código, es fundamental comprender por qué existe Shadcn UI y qué problemas resuelve. Comprender esta filosofía central es la clave para desbloquear todo su potencial.
Lo Que Shadcn UI No Es
- No es un paquete npm tradicional. No encontrarás
shadcn-ui
en la lista de dependencias de tupackage.json
. Esta es la distinción más crucial. - No es una biblioteca monolítica. No te obliga a instalar cientos de componentes cuando solo necesitas un botón y un campo de entrada.
- No es restrictivo. Nunca estás limitado a una estética de diseño específica ni restringido por las capacidades de theming proporcionadas por los mantenedores de una biblioteca.
Lo Que Shadcn UI Es
- Una Colección de Código Reutilizable: Piensa en ello como un conjunto de recetas expertamente seleccionadas. Eliges la receta que deseas (por ejemplo, un componente
Card
), y se te dan las instrucciones (el código) para cocinar en tu propia cocina (tu proyecto). - Un Compromiso con la Propiedad del Código: Una vez que añades un componente Shadcn, su código fuente —un archivo
.tsx
— se coloca directamente en tu base de código, típicamente bajocomponents/ui/
. Ahora es tu componente. Puedes cambiar su estructura, sus estilos, su lógica, lo que sea. Esto elimina la frustrante experiencia de luchar con anulaciones CSS!important
o APIs de props complejas para lograr un simple ajuste visual. - Construido sobre una Base Moderna y Sólida: Shadcn UI no reinventa la rueda. Se apoya en los hombros de gigantes:
- Tailwind CSS: Un framework CSS "utility-first" que proporciona bloques de construcción de bajo nivel para crear cualquier diseño directamente en tu marcado. Los componentes de Shadcn están estilizados exclusivamente con Tailwind, lo que los hace increíblemente fáciles de personalizar si estás familiarizado con el framework.
- Radix UI: Una biblioteca de primitivas de UI sin estilo, accesibles y de bajo nivel. Radix maneja todos los aspectos complejos y a menudo pasados por alto de los componentes de UI, como la navegación con teclado, la gestión del enfoque y los atributos ARIA para la accesibilidad (a11y). Shadcn toma estas potentes primitivas "headless" y les añade un estilo hermoso con Tailwind CSS.
La principal ventaja de este modelo es la fusión de velocidad y control. Obtienes la velocidad inicial de usar componentes preconstruidos sin sacrificar la flexibilidad y mantenibilidad a largo plazo que proviene de ser dueño de tu propio código.
Preparando el Escenario - Configuración e Instalación del Proyecto
Pasemos de la teoría a la práctica. Configuraremos un nuevo proyecto desde cero. Para esta guía, utilizaremos principalmente Next.js, ya que sus componentes de servidor y su enrutamiento basado en archivos se alinean perfectamente con el espíritu de Shadcn UI. También cubriremos brevemente la configuración para Vite.
Paso 1: Prerrequisitos del Entorno
Asegúrate de que tu entorno de desarrollo esté listo. Necesitarás:
- Node.js: Se recomienda la última versión de Soporte a Largo Plazo (LTS). Puedes descargarla desde el sitio web oficial de Node.js.
- Un Gestor de Paquetes: Este tutorial utilizará
npm
, que viene incluido con Node.js. También puedes usaryarn
opnpm
.
Paso 2: Creando una Nueva Aplicación Next.js
Abre tu terminal y ejecuta el siguiente comando para iniciar un nuevo proyecto Next.js.Bash
npx create-next-app@latest my-pro-shadcn-app --typescript --tailwind --eslint
Este comando crea una nueva aplicación en un directorio llamado my-pro-shadcn-app
. Hemos incluido algunas flags importantes:
--typescript
: Shadcn UI está escrito en TypeScript y funciona mejor en un entorno TypeScript.--tailwind
: Tailwind CSS es una dependencia obligatoria para el estilo de Shadcn UI.--eslint
: Siempre es una buena práctica para mantener la calidad del código.
El instalador te hará algunas preguntas. Estas son las opciones recomendadas para una configuración moderna de Next.js 14+:
✔ Would you like to use `src/` directory? … No / **Yes**
✔ Would you like to use App Router? (recommended) … No / **Yes**
✔ Would you like to customize the default import alias? … **No** / Yes
Usar el App Router es una práctica estándar, y el directorio src/
ayuda a organizar el código. Una vez hecho, navega a tu nuevo proyecto:Bash
cd my-pro-shadcn-app
Paso 3: El Comando init
- Dando Vida a Shadcn UI
Este es el paso más importante. Shadcn UI proporciona una herramienta CLI para configurar tu proyecto. Ejecuta el siguiente comando desde el directorio raíz de tu proyecto:Bash
npx shadcn-ui@latest init
Esto activará un cuestionario interactivo para configurar tu proyecto. Analicemos cada pregunta y su significado:
- ¿Te gustaría usar TypeScript (recomendado)?
Yes
. Estamos en un proyecto TypeScript. - ¿Qué estilo te gustaría usar?
Default
vs.New York
. Estos son dos estilos visuales predefinidos.Default
es un poco más espacioso, mientras queNew York
es más compacto. Puedes ver ejemplos en el sitio web de Shadcn UI. ElegiremosDefault
. - ¿Qué color te gustaría usar como color base? Esto configura la paleta de colores principal para tu UI. El predeterminado es
Slate
. MantengamosSlate
por ahora; aprenderemos cómo cambiarlo más adelante. - ¿Dónde está tu archivo
global.css
? La CLI lo detecta correctamente ensrc/app/globals.css
. Este archivo es donde se inyectarán las variables CSS principales para el theming. - ¿Quieres usar variables CSS para el theming?
Yes
. Esta es la piedra angular del sistema de theming de Shadcn, permitiendo cambios dinámicos (como modo oscuro/claro) y una fácil personalización. - ¿Dónde se encuentra tu
tailwind.config.ts
? La CLI detectasrc/tailwind.config.ts
. Este archivo se modificará para integrar los presets de tema de Shadcn. - Configurar alias de importación para componentes:
@/components
. Esta es una buena práctica. Significa que no importa cuán anidado esté un archivo, siempre puedes importar un componente con una ruta limpia comoimport { Button } from "@/components/ui/button";
. - Configurar alias de importación para utilidades:
@/lib/utils
. Igual que lo anterior, para funciones de utilidad. - ¿Estás usando React Server Components?
Yes
. Elegimos el App Router, que usa Server Components por defecto. - ¿Escribir configuración en
components.json
?Yes
. Esto crea un archivo crucial que recuerda todas tus elecciones, para que no tengas que responder estas preguntas cada vez que ejecutesnpx shadcn-ui@latest add ...
.
Después de confirmar, la CLI hace su magia:
- Instala Dependencias: Añade paquetes necesarios como
tailwindcss-animate
yclass-variance-authority
. - Crea
components.json
: Almacena tus opciones de configuración. - Actualiza
tailwind.config.ts
: Inyecta el plugin de Shadcn UI y la configuración de theming. - Actualiza
globals.css
: Añade un gran bloque de variables CSS que definen toda tu paleta de colores, radios de borde y más. - Crea
lib/utils.ts
: Este archivo exporta una función de ayudacn
, que es una utilidad inteligente para fusionar condicionalmente clases de Tailwind CSS.
Tu proyecto ahora está completamente configurado.
(Alternativa: Configuración con Vite)
Si estás usando Vite con React, el proceso es muy similar. Después de configurar un proyecto Vite + React + TS, instalarías manualmente Tailwind CSS y luego ejecutarías npx shadcn-ui@latest init. La CLI es lo suficientemente inteligente como para detectar una configuración de Vite y hará preguntas ligeramente diferentes sobre las ubicaciones de los archivos (por ejemplo, index.css en lugar de globals.css).
Construyendo una UI - De Componentes Simples a Diseños Complejos
Con la configuración completa, comencemos a construir. El flujo de trabajo principal es: identificar una necesidad, añadir el componente, usarlo.
Paso 4: Añadiendo y Usando Tus Primeros Componentes
Limpiemos el código boilerplate predeterminado de Next.js y construyamos una interfaz simple.
1. Añadir un Botón:Bash
npx shadcn-ui@latest add button
Observa lo que sucede: se crea un nuevo archivo, src/components/ui/button.tsx
. Este es tu botón. Tú eres el dueño.
2. Añadir una Tarjeta (Card):Bash
npx shadcn-ui@latest add card
Este comando es más interesante. Crea src/components/ui/card.tsx
. Si inspeccionas este archivo, verás que exporta múltiples componentes: Card
, CardHeader
, CardTitle
, CardDescription
, CardContent
y CardFooter
. Este es un patrón común para componentes compuestos.
3. Construir la UI:
Ahora, abre src/app/page.tsx
y reemplaza su contenido con lo siguiente:TypeScript
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input"; // Añadiremos esto después
import { Label } from "@/components/ui/label"; // Y esto
export default function Home() {
return (
<main className="flex min-h-screen items-center justify-center bg-background p-8">
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle className="text-2xl">Crear Proyecto</CardTitle>
<CardDescription>
Despliega tu nuevo proyecto en un clic.
</CardDescription>
</CardHeader>
<CardContent className="grid gap-4">
<div className="grid gap-2">
<Label htmlFor="name">Nombre</Label>
<Input id="name" placeholder="Nombre de tu proyecto" />
</div>
<div className="grid gap-2">
<Label htmlFor="framework">Framework</Label>
{/* Reemplazaremos esto con un componente Select más tarde */}
<Input id="framework" placeholder="ej. Next.js" />
</div>
</CardContent>
<CardFooter>
<Button className="w-full">Desplegar</Button>
</CardFooter>
</Card>
</main>
);
}
Nuestro código aún no se ejecutará porque nos faltan los componentes Input
y Label
. Añadámoslos:Bash
npx shadcn-ui@latest add input
npx shadcn-ui@latest add label
Ahora, ejecuta tu servidor de desarrollo:Bash
npm run dev
Navega a http://localhost:3000
. Verás un formulario limpio y de aspecto profesional dentro de una tarjeta. Observa cómo usamos clases de utilidad como w-full
, max-w-md
y grid
directamente en nuestro JSX para controlar el diseño. Este es el poder de combinar Shadcn y Tailwind CSS.
Paso 5: Introduciendo Componentes Más Sofisticados
Las entradas estáticas son buenas, pero las aplicaciones reales necesitan elementos interactivos. Mejoremos nuestro formulario.
1. Añadir un Componente Select
: La entrada "Framework" debería ser un desplegable. Añadamos el componente Select
. Este es más complejo y tiene dependencias de otros componentes.Bash
npx shadcn-ui@latest add select
La CLI es inteligente. Verá que Select
requiere un componente Popover
para funcionar y te pedirá permiso para instalarlo a él y a sus dependencias también. Esta es una característica fantástica que te evita tener que rastrear dependencias manualmente.
2. Integrar el Select
Componente: Reemplaza la entrada Input
para "Framework" en src/app/page.tsx
con el nuevo componente Select
.TypeScript
// Añade estas importaciones al principio
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
// ... dentro de CardContent
<div className="grid gap-2">
<Label htmlFor="framework">Framework</Label>
<Select>
<SelectTrigger id="framework">
<SelectValue placeholder="Selecciona un framework" />
</SelectTrigger>
<SelectContent>
<SelectItem value="nextjs">Next.js</SelectItem>
<SelectItem value="sveltekit">SvelteKit</SelectItem>
<SelectItem value="astro">Astro</SelectItem>
<SelectItem value="nuxt">Nuxt.js</SelectItem>
</SelectContent>
</Select>
</div>
Actualiza tu navegador. Ahora tienes un desplegable de selección completamente funcional y accesible, completo con animaciones y navegación de teclado adecuada, todo gracias a Radix UI trabajando en segundo plano.
3. Añadiendo Feedback al Usuario con Toast
: ¿Qué sucede cuando un usuario hace clic en "Deploy"? Deberíamos darle algo de feedback. El componente Toast
es perfecto para esto.
Primero, añádelo:Bash
npx shadcn-ui@latest add toast
A continuación, para usar toasts, necesitas añadir un componente <Toaster />
a tu layout raíz para que pueda mostrarse en cualquier parte de la aplicación. Abre src/app/layout.tsx
y modifícalo:TypeScript
import { Toaster } from "@/components/ui/toaster" // Importa el Toaster
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Toaster /> {/* Añádelo aquí, justo antes de cerrar body */}
</body>
</html>
)
}
Ahora, necesitamos una forma de activar el toast. Usaremos el hook useToast
. Actualicemos src/app/page.tsx
para convertirlo en un componente de cliente y manejar el clic del botón.TypeScript
'use client'; // <-- Añade esto al principio del archivo
// ... otras importaciones
import { useToast } from "@/components/ui/use-toast";
export default function Home() {
const { toast } = useToast(); // Obtén la función toast del hook
function handleDeploy() {
toast({
title: "Despliegue Programado!",
description: "Tu proyecto 'Nombre de tu proyecto' se está desplegando.",
duration: 5000,
});
}
return (
<main className="flex min-h-screen items-center justify-center bg-background p-8">
<Card className="w-full max-w-md">
{/* ... CardHeader y CardContent ... */}
<CardFooter>
<Button className="w-full" onClick={handleDeploy}> {/* Añade el manejador onClick */}
Desplegar
</Button>
</CardFooter>
</Card>
</main>
);
}
Ahora, cuando hagas clic en el botón "Desplegar", aparecerá una elegante notificación en la esquina de tu pantalla.
Construyendo un Formulario Profesional con Validación
La mayoría de las aplicaciones del mundo real requieren un manejo robusto de formularios, incluida la validación del lado del cliente. La forma oficial de manejar esto con Shadcn UI es combinándolo con react-hook-form
para la gestión del estado y zod
para la validación del esquema. Construyámoslo.
Paso 6: Instalando Dependencias del Formulario
Primero, instalemos las bibliotecas necesarias:Bash
npm install react-hook-form zod @hookform/resolvers
react-hook-form
: Una biblioteca de formularios de alto rendimiento, flexible y extensible.zod
: Una biblioteca de declaración y validación de esquemas "TypeScript-first".@hookform/resolvers
: Una biblioteca puente para permitir quereact-hook-form
usezod
para la validación.
Paso 7: Añadiendo el Componente Form
de Shadcn
Shadcn UI proporciona un componente Form
especial que actúa como un wrapper para conectar sin problemas react-hook-form
con tus componentes de UI.Bash
npx shadcn-ui@latest add form
Esto añadirá src/components/ui/form.tsx
. Este archivo proporciona un conjunto de componentes conscientes del contexto (Form
, FormField
, FormItem
, FormLabel
, FormControl
, FormDescription
, FormMessage
) que reducen drásticamente el código boilerplate.
Paso 8: Creando el Esquema de Validación
En tu src/app/page.tsx
, definamos la forma y las reglas de los datos de nuestro formulario usando zod
.TypeScript
// Añade estas importaciones al principio
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
Ahora, creemos el esquema justo encima de nuestro componente Home
:TypeScript
const formSchema = z.object({
projectName: z.string().min(2, {
message: "El nombre del proyecto debe tener al menos 2 caracteres.",
}).max(50, {
message: "El nombre del proyecto no debe exceder los 50 caracteres.",
}),
framework: z.string({
required_error: "Por favor, selecciona un framework para mostrar.",
}),
});
Este esquema define dos campos: projectName
debe ser una cadena de texto entre 2 y 50 caracteres, y framework
es una cadena de texto obligatoria.
Paso 9: Conectando el Formulario
Ahora, refactoricemos nuestro componente Home
para usar todas estas nuevas herramientas.TypeScript
export default function Home() {
const { toast } = useToast();
// 1. Define tu formulario.
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
projectName: "",
},
});
// 2. Define un manejador de envío.
function onSubmit(values: z.infer<typeof formSchema>) {
// Haz algo con los valores del formulario.
// ✅ Esto será type-safe y validado.
console.log(values);
toast({
title: "Has enviado los siguientes valores:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(values, null, 2)}</code>
</pre>
),
});
}
// 3. Construye el JSX con los componentes Form de Shadcn
return (
<main className="flex min-h-screen items-center justify-center bg-background p-8">
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle className="text-2xl">Crear Proyecto</CardTitle>
<CardDescription>
Despliega tu nuevo proyecto en un clic.
</CardDescription>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="projectName"
render={({ field }) => (
<FormItem>
<FormLabel>Nombre</FormLabel>
<FormControl>
<Input placeholder="Nombre de tu proyecto" {...field} />
</FormControl>
<FormDescription>
Este es tu nombre público de visualización.
</FormDescription>
<FormMessage /> {/* Muestra errores de validación */}
</FormItem>
)}
/>
<FormField
control={form.control}
name="framework"
render={({ field }) => (
<FormItem>
<FormLabel>Framework</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Selecciona un framework" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="nextjs">Next.js</SelectItem>
<SelectItem value="sveltekit">SvelteKit</SelectItem>
<SelectItem value="astro">Astro</SelectItem>
<SelectItem value="nuxt">Nuxt.js</SelectItem>
</SelectContent>
</Select>
<FormDescription>
El framework que quieres desplegar.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" className="w-full">Desplegar</Button>
</form>
</Form>
</CardContent>
</Card>
</main>
);
}
Este es un fragmento de código considerable, pero es un patrón increíblemente potente y escalable. El componente FormField
maneja todas las conexiones de estado, y FormMessage
muestra automáticamente el error de validación correcto de tu esquema zod
cuando un usuario interactúa con el campo. Intenta enviar el formulario con un nombre de proyecto vacío para ver la validación en acción.
Dominando el Theming y la Personalización
El verdadero poder de Shadcn UI se desata cuando empiezas a hacerlo tuyo.
Paso 10: Theming Avanzado con Variables CSS
Todo tu tema está definido por variables CSS en src/app/globals.css
. Abre este archivo y busca los bloques :root
y .dark
.CSS
/* Ejemplo de globals.css */
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
/* ... y muchos más */
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
/* ... */
}
- Cambiando Colores: Los valores se representan como valores HSL (Hue, Saturation, Lightness) sin el wrapper
hsl()
. Esta es una elección deliberada para una manipulación más sencilla. Para cambiar el color principal de tu marca, solo necesitas encontrar los valores HSL de tu color y actualizar las variables--primary
y--primary-foreground
. La página de Temas de Shadcn UI tiene un generador fantástico que te permite elegir un color y copiar-pegar todo el bloque del tema. - Cambiando el Radio del Borde: ¿Quieres esquinas más afiladas? Cambia
--radius: 0.5rem;
a--radius: 0.2rem;
o incluso0rem
. Cada componente que tiene esquinas redondeadas usa esta variable, por lo que tu cambio se propagará globalmente.
Implementando el Modo Oscuro:
Shadcn está preconfigurado para el modo oscuro gracias al bloque de clase .dark y la estrategia darkMode: "class" de Tailwind en tailwind.config.ts. Todo lo que necesitas es una forma de alternar la clase dark en el elemento <html>. Una biblioteca popular para esto es next-themes.
- Instálala:
npm install next-themes
- Crea un componente
ThemeProvider
(src/components/theme-provider.tsx
): TypeScript
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
- Envuelve tu
RootLayout
en este proveedor (src/app/layout.tsx
): TypeScript
import { ThemeProvider } from "@/components/theme-provider"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
<Toaster />
</ThemeProvider>
</body>
</html>
)
}
- Finalmente, crea un botón de alternancia (por ejemplo,
src/components/mode-toggle.tsx
): TypeScript
"use client"
import * as React from "react"
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
export function ModeToggle() {
const { theme, setTheme } = useTheme()
return (
<Button
variant="outline"
size="icon"
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Alternar tema</span>
</Button>
)
}
Ahora puedes colocar este <ModeToggle />
en cualquier parte de tu aplicación para obtener un alternador de modo oscuro consciente del sistema y anulable por el usuario.
Paso 11: Personalizando el Código Fuente del Componente
Este es el superpoder definitivo. Supongamos que quieres una nueva variante de éxito para tu botón que tenga un fondo verde.
Abre src/components/ui/button.tsx. Encuentra la definición de buttonVariants. Usa cva (Class Variance Authority). Simplemente añade una nueva variante:TypeScript
const buttonVariants = cva(
// ... estilos base
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
success: "bg-green-600 text-white hover:bg-green-600/90", // Nuestra nueva variante
},
// ... variantes de tamaño
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
Eso es todo. Ahora puedes usarlo en tu código: <Button variant="success">Success</Button>
. No necesitaste escribir anulaciones CSS complejas. Simplemente editaste el propio código fuente del componente. Este flujo de trabajo es simple, predecible e increíblemente potente.
Parte 6: Mejores Prácticas y el Camino a Seguir
A medida que tu aplicación crece, aquí tienes algunas mejores prácticas a tener en cuenta.
- Organización de Archivos: Si bien la CLI coloca todo en
components/ui
, esta carpeta debe considerarse tu kit de UI "base". Para componentes más complejos que compones tú mismo (por ejemplo, unaUserProfileCard
que usaCard
,Avatar
yButton
de Shadcn), créalos en un directorio diferente, comocomponents/shared
ocomponents/features
. Esto mantiene una clara separación entre la UI fundamental y los componentes específicos de la aplicación. - Actualizaciones de Componentes: ¿Cómo obtienes actualizaciones si el componente original de Shadcn UI mejora? La CLI te cubre. Puedes ejecutar
npx shadcn-ui@latest add button
de nuevo. La CLI detectará que ya tienes un archivobutton.tsx
y te mostrará una comparacióndiff
, permitiéndote sobrescribir tu archivo o aceptar los cambios manualmente. Es como un mini control de versiones para tus componentes. - Aprovechar la Accesibilidad: Recuerda que los componentes de Shadcn son accesibles de fábrica porque están construidos sobre primitivas de Radix. Cuando los personalices, ten cuidado de no romper esta accesibilidad. Por ejemplo, si cambias los colores de un botón, asegúrate de que el texto aún tenga suficiente contraste. Cuando construyas nuevos componentes, intenta seguir los patrones establecidos por Shadcn/Radix para mantener la navegabilidad con teclado y el soporte para lectores de pantalla.