Communitygithub.com

Sistema de UI Personal

Construye componentes y diseños de UI responsivos y accesibles con Chakra UI v3, instala o configura Chakra UI en proyectos nuevos y existentes, y diseña temas escalables usando tokens, tokens semánticos, recetas y slot recetas.

¿Qué es Sistema de UI Personal?

Este skill permite a un agente de IA construir, configurar y tematizar interfaces de usuario completas usando Chakra UI versión 3. Está diseñado para desarrolladores que trabajan con React, Next.js, Vite o Remix, y que necesitan crear desde componentes simples (botones, tarjetas, formularios) hasta layouts complejos (tablas, paneles laterales, gráficos). El agente sigue un proceso estructurado: primero lee el contexto del proyecto (framework, gestor de paquetes, versión de Chakra), luego instala y configura Chakra UI si es necesario usando la CLI oficial, y finalmente construye el componente solicitado siguiendo buenas prácticas de accesibilidad, diseño responsive y uso de tokens semánticos. El skill también maneja temas avanzados como la creación de recetas y slot recetas, la integración con `next-themes` para modo oscuro, y la generación de código TypeScript con componentes servidor y cliente en Next.js App Router. Todo el código generado es completo, ejecutable y listo para producción.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/0xAlchemist-cs/personal-ui-system/tree/HEAD/.agents/skills/chakra-ui-builder

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Constructor de Chakra UI

Estás construyendo UI con Chakra UI v3 y ayudando a los desarrolladores a configurar Chakra UI en sus proyectos. Tu trabajo es producir código limpio, accesible y responsivo que se ajuste al proyecto, no código genérico. Lee primero el contexto del proyecto, luego construye o configura.


Paso 1 — Leer el contexto del proyecto

Revisa package.json si está disponible. Busca:

  • Versión de Chakra UI (usa patrones v3 por defecto; solo usa v2 si está explícitamente en v2)
  • Framework: Next.js App Router, Pages Router, Vite, plain React
  • TypeScript o JavaScript
  • Gestor de paquetes (por archivo de bloqueo: pnpm-lock.yaml, yarn.lock, bun.lock, package-lock.json)

También echa un vistazo a los componentes existentes si el usuario los menciona, para que tu código coincida con las convenciones ya en uso (nombres, estructura de archivos, estilo de importación).

Si los requisitos son vagos o el componente es lo suficientemente complejo como para que las decisiones importen (dirección del layout, forma de los datos, paleta de colores, número de variantes), pregunta antes de construir en lugar de generar algo que pueda ser descartado.


Configuración del proyecto

Si Chakra UI aún no está instalado, completa la configuración antes de construir.

Instalación

# npm
npm install @chakra-ui/react @emotion/react

# pnpm
pnpm add @chakra-ui/react @emotion/react

# yarn
yarn add @chakra-ui/react @emotion/react

# bun
bun add @chakra-ui/react @emotion/react

Generar fragmentos con la CLI

npx @chakra-ui/cli snippet add

Sin argumentos, esto agrega el conjunto recomendado — provider, toaster, y tooltip — e instala automáticamente las dependencias necesarias (incluyendo next-themes). Usa --all para agregar todos los fragmentos, o snippet list para explorar primero.

La CLI detecta tu framework y escribe los archivos en el lugar correcto:

FrameworkRuta de salida
Next.js (con src/)src/components/ui/
Next.js (sin src/)components/ui/
Vite / plain Reactsrc/components/ui/
Remixapp/components/ui/

Conectar el Provider

Next.js App Router (app/layout.tsx):

import { Provider } from "@/components/ui/provider"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <Provider>{children}</Provider>
      </body>
    </html>
  )
}

suppressHydrationWarning evita una discrepancia causada por next-themes al inyectar la clase de modo de color. No agregues "use client" a layout.tsx — el archivo provider generado ya lo tiene.

Next.js Pages Router (pages/_app.tsx):

import { Provider } from "@/components/ui/provider"

export default function App({ Component, pageProps }) {
  return (
    <Provider>
      <Component {...pageProps} />
    </Provider>
  )
}

Vite (src/main.tsx):

import { Provider } from "./components/ui/provider"

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <Provider>
      <App />
    </Provider>
  </StrictMode>,
)

Provider manual (si la CLI no está disponible)

Si la CLI falla, crea components/ui/provider.tsx manualmente e instala next-themes por separado:

"use client"
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
import { ThemeProvider } from "next-themes"

export function Provider({ children }: { children: React.ReactNode }) {
  return (
    <ChakraProvider value={defaultSystem}>
      <ThemeProvider attribute="class" disableTransitionOnChange>
        {children}
      </ThemeProvider>
    </ChakraProvider>
  )
}

Problemas comunes de configuración

  • Componentes sin estilo — la aplicación no está envuelta en <Provider>. Verifica la ruta de importación y que Provider envuelva el árbol de componentes.
  • Discrepancia de hidratación — agrega suppressHydrationWarning a <html> en App Router.
  • next-themes no encontrado — instálalo: npm install next-themes (solo es necesario para el fallback manual; la CLI lo maneja automáticamente).
  • extendTheme no exportado — este es un patrón de v2. Usa createSystem en v3.

Paso 2 — Elegir los primitivos de layout correctos

Usa el primitivo de Chakra adecuado en lugar de envolver todo en Box:

NecesidadUsa
Pila vertical de elementosStack (por defecto) o VStack
Fila horizontalHStack o Flex
CSS GridGrid + GridItem
Cuadrícula de columnas igualesSimpleGrid columns={N}
Contenido centrado en páginaContainer maxW="container.lg"
Control completo de flexboxFlex con props explícitas
Sección/artículo semánticoBox as="section" / Box as="article"

Evita el anidamiento profundo. Si estás a tres niveles de Box sin razón semántica, aplana. Prefiere gap en lugar de margen entre hermanos.


Paso 3 — Usa tokens, no valores crudos

Chakra v3 incluye tokens semánticos que se adaptan automáticamente al modo claro/oscuro. Prefiérelos sobre valores de paleta hardcodeados — hacen que el componente sea consciente del tema sin trabajo adicional.

// Prefiere tokens semánticos
<Box bg="bg.subtle" color="fg.default" borderColor="border.subtle" />
<Text color="fg.muted" />
<Box shadow="md" rounded="lg" />

// Usa colorPalette para componentes interactivos (no colorScheme)
<Button colorPalette="blue">Enviar</Button>
<Badge colorPalette="green">Activo</Badge>

Usa valores de paleta crudos (blue.500, gray.100) solo cuando un color específico es intencional y no debe cambiar con el modo de color.


Paso 4 — Estilos responsivos

Chakra usa breakpoints mobile-first. Usa la sintaxis de array u objeto de manera consistente:

// Array: [base, sm, md, lg, xl]
<Box px={[4, 6, 8]} fontSize={["sm", "md", "lg"]} />

// Objeto: breakpoints explícitos
<SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} gap={6} />
<Stack direction={{ base: "column", md: "row" }} gap={4} />

Cada componente de layout debería manejar al menos los breakpoints base (móvil) y md (escritorio) a menos que la solicitud sea explícitamente solo para escritorio.


Paso 5 — Formularios

Usa Field.Root para todos los campos de formulario — conecta correctamente la etiqueta, el input, el error y el texto de ayuda:

<Field.Root invalid={!!error} required>
  <Field.Label>Dirección de correo electrónico</Field.Label>
  <Input type="email" placeholder="[email protected]" />
  <Field.ErrorText>{error}</Field.ErrorText>
  <Field.HelpText>Nunca compartiremos tu correo.</Field.HelpText>
</Field.Root>

Para el estado de envío del formulario, usa disabled (no isDisabled) en inputs y botones. Agrupa campos relacionados en un Stack gap={4}.


Paso 6 — Accesibilidad

Los componentes integrados de Chakra manejan la mayoría de la accesibilidad automáticamente — no la sobrescribas. Las cosas que sí necesitas proporcionar:

  • Botones solo icono: siempre agrega aria-label
    <IconButton aria-label="Cerrar diálogo" icon={<CloseIcon />} />
    
  • Imágenes: siempre pasa texto alt significativo (o alt="" para decorativas)
  • Etiquetas de formulario: usa Field.Label o asegura que htmlFor coincida con el id del input
  • Elementos personalizados interactivos: si construyes algo con onClick en un Box, usa as="button" o un <button> real para que la navegación por teclado funcione
  • Encabezados semánticos: usa la jerarquía h1–h6; no saltes niveles
  • Contraste de color: no uses texto gris claro sobre fondos blancos; confía en los tokens semánticos que tienen contraste probado

Paso 7 — Next.js: dónde agregar "use client"

En Next.js App Router, los Componentes Servidor son el valor predeterminado. Agrega "use client" solo a los archivos que lo necesiten — no a layouts o páginas completas.

Un componente necesita "use client" cuando:

  • Usa hooks de React (useState, useEffect, useContext, etc.)
  • Maneja eventos del navegador (onClick con estado, envío de formularios, etc.)
  • Usa APIs del navegador
// Componente servidor — no necesita directiva
export default function TarjetaProducto({ nombre, precio }: Props) {
  return (
    <Box p={4} borderWidth={1} rounded="md">
      <Text fontWeight="bold">{nombre}</Text>
      <Text color="fg.muted">{precio}</Text>
    </Box>
  )
}

// Componente cliente — necesita la directiva
;("use client")
export function BotonAgregarAlCarrito({ productoId }: { productoId: string }) {
  const [agregado, setAgregado] = useState(false)
  return (
    <Button onClick={() => setAgregado(true)} colorPalette="blue">
      {agregado ? "¡Agregado!" : "Agregar al carrito"}
    </Button>
  )
}

El objetivo es empujar la interactividad a las hojas — mantener la mayor parte del árbol como Componentes Servidor.


Paso 8 — Cuándo extraer componentes, usar recetas y personalizar el tema

Extrae un componente cuando la misma estructura aparece más de dos veces, o cuando una pieza es lo suficientemente compleja como para que nombrarla haga el padre más claro.

Sugiere una receta cuando un componente tiene variantes de estilo significativas que un desarrollador querría personalizar. Sugiere una slot receta para componentes con múltiples partes coordinadas (tarjeta con encabezado/cuerpo/pie, estadística con etiqueta/valor/icono, etc.).

Para trabajo de tematización más profundo — definir tokens de color de marca, tokens semánticos con valores de modo oscuro, creación completa de recetas/slot recetas, typegen, o extraer el tema predeterminado — lee references/theming.md antes de responder. Cubre la API completa de defineConfig / createSystem con ejemplos completos.

Para cualquier solicitud de gráficos — gráficos de barras, gráficos de área, gráficos de líneas, gráficos circulares/de dona, BarList, BarSegment, o cualquier cosa que involucre @chakra-ui/charts — lee references/charts.md antes de responder. Cubre el hook useChart, los tres tipos de gráficos, la integración con Recharts, los tokens de color y ejemplos ejecutables completos.

Cuando no estés seguro de qué componente usar, o el usuario no haya especificado uno, lee references/component-decision-tree.md. Cubre cada componente de Chakra con orientación sobre cuándo elegir uno sobre una alternativa similar.


Formato de salida

Produce:

  1. Código completo y ejecutable — imports correctos, sin marcadores de posición como TODO o ...resto del componente
  2. Declaraciones de importación adecuadas — agrupa imports de Chakra, luego imports locales
  3. Separación de componentes — divide en múltiples componentes/archivos si el componente es complejo o contiene partes claramente separables
  4. Estilos responsivos — al menos breakpoints base y md para el layout
  5. Breve explicación después del código — 2–4 oraciones sobre las decisiones clave tomadas (enfoque de layout, elecciones de accesibilidad, estrategia responsiva). Omite la explicación si la solicitud fue trivial.
// Buen estilo de importación
import { Box, Button, Field, Stack, Text } from "@chakra-ui/react"
// Luego local
import { SomeLocalComponent } from "./SomeLocalComponent"

Cuándo preguntar primero

Construye inmediatamente si la solicitud es lo suficientemente clara como para producir algo útil. Pregunta primero cuando:

  • La forma de los datos es desconocida y cambia toda la estructura (ej., "construye una tabla" — ¿cuántas columnas? ¿qué datos?)
  • Hay decisiones de diseño significativas que podrían importarle al usuario (dirección del layout, número de columnas, paleta de colores)
  • El usuario menciona archivos o componentes existentes que no has visto

En caso de duda, indica tus suposiciones al inicio de la respuesta y construye — es más rápido para el usuario redirigir desde algo concreto que desde nada.

Skills relacionados