Button
CVA variants 4 variantes · 3 tamaños · estado loading · forward refVariantes
Tamaños
Estado: loading / disabled
📄 Button.tsx
tsx
const buttonVariants = cva( "inline-flex items-center rounded-md font-medium transition-colors focus-visible:ring-2 disabled:opacity-50", { variants: { variant: { primary: "bg-green-500 text-white hover:bg-green-600", secondary: "bg-white/8 text-slate-200 border border-white/10 hover:bg-white/12", ghost: "text-slate-300 hover:bg-white/6 hover:text-white", danger: "bg-red-500 text-white hover:bg-red-600", }, size: { sm: "h-8 px-3 text-sm", md: "h-[38px] px-4 text-sm", lg: "h-[46px] px-6 text-base", }, }, defaultVariants: { variant: "primary", size: "md" }, } ) export const Button = forwardRef<HTMLButtonElement, ButtonProps>( ({ variant, size, isLoading, children, ...props }, ref) => ( <button ref={ref} disabled={isLoading} className={cn(buttonVariants({ variant, size }))}> {isLoading && <Spinner />} {children} </button> ) )
Badge
status labels 6 variantes de estado · indicador animado
Activo
Pausado
Completado
Pendiente
Error
Pro
📄 Badge.tsx
tsx
type BadgeVariant = "active" | "paused" | "completed" | "pending" | "error" | "pro" const variantClasses: Record<BadgeVariant, string> = { active: "bg-green-500/15 text-green-400 border-green-500/30", paused: "bg-yellow-500/15 text-yellow-400 border-yellow-500/30", completed: "bg-blue-500/15 text-blue-400 border-blue-500/30", pending: "bg-white/5 text-slate-400 border-white/8", error: "bg-red-500/15 text-red-400 border-red-500/30", pro: "bg-gradient-to-r from-purple-500/20 to-blue-500/20 text-purple-400", } export function Badge({ variant, label }: BadgeProps) { return ( <span className={cn("badge", variantClasses[variant])}> <span className="badge-dot" />{label} </span> ) }
Card
compound component header / body / footer · variantes métricas y proyectoProyectos activos
Este mes
24
proyectos en curso
↑ +3 esta semana
Campañas IA
Marketing automatizado
8.4k
impresiones generadas
↑ +22% vs. semana pasada
Agentes desplegados
Automatización activa
12
agentes en producción
⚠ 1 requiere revisión
📄 Card.tsx — Compound component pattern
tsx
// Compound component: Card.Header / Card.Body / Card.Footer function Card({ children, className }: CardProps) { return <div className={cn("rounded-2xl border bg-slate-800 border-white/7 hover:border-green-500/20", className)}>{children}</div> } Card.Header = function CardHeader({ title, subtitle, icon }: CardHeaderProps) { return ( <div className="flex items-start justify-between p-6 pb-0"> <div> <h3 className="font-bold text-white">{title}</h3> <p className="text-xs text-slate-500">{subtitle}</p> </div> {icon && <CardIcon>{icon}</CardIcon>} </div> ) } // Usage: <Card> <Card.Header title="Proyectos activos" subtitle="Este mes" icon="📋" /> <Card.Body><MetricDisplay value=24 /></Card.Body> <Card.Footer><Badge variant="active" /></Card.Footer> </Card>
Select
compound component accessible dropdown · keyboard nav · controlled/uncontrolledServicio
Agentes IA✓
Marketing
Desarrollo Web
Analítica de Datos
Contenido
Estado del proyecto
⚠ URL no válida
📄 Select.tsx — Compound Component
tsx
// Compound pattern: Select > Select.Trigger + Select.Options > Select.Option <Select value={servicio} onChange={setServicio}> <Select.Trigger> {options.find(o => o.value === servicio)?.label ?? "Selecciona un servicio"} </Select.Trigger> <Select.Options> {options.map(opt => ( <Select.Option key={opt.value} value={opt.value}> {opt.icon} {opt.label} </Select.Option> ))} </Select.Options> </Select> // Context interno gestiona isOpen, selectedValue, focus trap const SelectContext = createContext<SelectCtx>(null!)
DataTable
render props ordenación · filtro · paginación · filas personalizables| Proyecto ↑ | Cliente ↕ | Servicio | Estado ↕ | Facturación ↕ | Acciones |
|---|---|---|---|---|---|
SEO Automatizado techstartup.io |
TechStartup SL |
Agentes IA | Activo | €2.800/mo |
|
Campañas Meta IA moda-urbana.com |
Moda Urbana SLU |
Marketing | Activo | €1.500/mo |
|
Web Corporativa React inmodata.es |
InmoData Group |
Desarrollo Web | Pausado | €5.200 (único) |
|
Dashboard Analytics fintech-hub.io |
FintechHub |
Analítica | Completado | €3.400 (único) |
|
Agente Soporte 24h ecommerce-pets.es |
PetStore Online SL |
Agentes IA | Error | €900/mo |
Mostrando 1–5 de 24 proyectos
📄 DataTable.tsx — Render Props pattern
tsx
// Render props: columnas configurables con renderCell personalizado const columns: Column<Proyecto>[] = [ { key: "nombre", header: "Proyecto", sortable: true, renderCell: (row) => ( <div> <p className="font-semibold text-white">{row.nombre}</p> <p className="text-xs text-slate-400">{row.url}</p> </div> ), }, { key: "estado", renderCell: (row) => <Badge variant={row.estado} /> }, ] <DataTable data={proyectos} columns={columns} pageSize={5} searchable />
Alert
feedback 4 niveles de severidad · título + descripciónCampaña publicada correctamente
La campaña "Black Friday 2026" se ha activado en Meta Ads y Google. El agente IA comenzará a optimizar pujas en 15 minutos.
Límite de API próximo
Has usado el 87% de tus llamadas a la API este mes. Considera actualizar tu plan o esperar al próximo ciclo (3 días).
Agente de soporte desconectado
El agente "Soporte 24h — PetStore" ha perdido conexión con el webhook. Revisa las credenciales de integración.
Nueva versión disponible
CULTIVA IA Platform v1.3.0 ya está disponible con mejoras en el editor de prompts y nuevos modelos Claude Sonnet.
Design Tokens
foundations paleta de colores · tipografíaPaleta de marca
green-500
#22C55E
green-600
#16A34A
slate-900
#0F172A
slate-800
#1E293B
red-500
#EF4444
yellow-500
#F59E0B
Escala tipográfica
Display Heading
Section Title
Card Title / Label
Body text — descripción de proyecto o servicio con información relevante.
Caption / metadata — última actualización, contadores, hints
Patrones utilizados
Compound Components
Render Props
CVA Variants
forwardRef
Context API
Composables Vue 3
Svelte Runes
CSS Modules
Tailwind CVA