@codercito/grid-system
v0.1.0
Published
Sistema de grid responsivo para React + Tailwind CSS
Maintainers
Readme
@codercito/grid-system
Sistema de grid responsivo para React + Tailwind CSS. Dos componentes simples (GridWrapper y GridColumn) que abstraen las clases de grid de Tailwind detrás de una API tipada y consistente.
Instalación
npm install @codercito/grid-systemLa librería instala automáticamente clsx y tailwind-merge como dependencias internas.
Setup de Tailwind (importante)
Esta librería usa clases de Tailwind CSS. Tu proyecto debe tener Tailwind configurado y debe escanear los archivos compilados de la librería para detectar las clases que usa.
El setup depende de qué versión de Tailwind tengas. Verifica en tu package.json:
cat package.json | grep tailwindcssTailwind v4 (proyectos nuevos de Next.js, Vite, etc.)
En v4 toda la configuración va en CSS — no hay tailwind.config.js. Abre tu archivo CSS principal (típicamente app/globals.css o src/index.css) y agrega una directiva @source:
@import "tailwindcss";
@source "../node_modules/@codercito/grid-system/dist";La ruta relativa depende de dónde está tu CSS. Si está en
app/globals.css, usa../node_modules/.... Si está ensrc/app/globals.css, usa../../node_modules/.... Cuenta cuántos niveles hay que subir hasta la raíz del proyecto.
Tailwind v3
Agrega esta línea al content de tu tailwind.config.js (o .ts):
module.exports = {
content: [
'./src/**/*.{js,ts,jsx,tsx}',
'./node_modules/@codercito/grid-system/dist/**/*.{js,mjs}',
],
// ...
};⚠️ Sin esta configuración, los componentes no tendrán estilos aplicados — Tailwind no incluirá las clases
grid-cols-*,col-span-*ygap-*en el CSS final.
Alternativa: safelist (v3 únicamente)
Si por alguna razón no quieres escanear node_modules en v3, puedes usar safelist:
module.exports = {
content: ['./src/**/*.{js,ts,jsx,tsx}'],
safelist: [
'md:grid-cols-6', 'md:grid-cols-8', 'md:grid-cols-10', 'md:grid-cols-12',
'col-span-full',
{ pattern: /sm:col-span-(1|2|3|4|5|6|7|8|9|10|11|12)/ },
{ pattern: /gap(-x|-y)?-(0|1|2|3|4|5|6|8|10|12)/ },
],
};Uso básico
import { GridWrapper, GridColumn } from '@codercito/grid-system';
export default function Page() {
return (
<GridWrapper columns={12}>
<GridColumn column={8}>
<article>Contenido principal</article>
</GridColumn>
<GridColumn column={4}>
<aside>Sidebar</aside>
</GridColumn>
</GridWrapper>
);
}Comportamiento responsivo
El grid se adapta automáticamente a tres breakpoints:
| Breakpoint | Ancho | Columnas del wrapper |
|------------|-------|---------------------|
| Móvil | < 640px | 1 (todo apilado) |
| sm | 640px+ | 4 |
| md | 768px+ | el valor de columns |
Los GridColumn con column definido se aplican desde sm.
API
<GridWrapper>
| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| children | ReactNode | — | Contenido del grid (debe ser GridColumns). |
| className | string | — | Clases extra para el contenedor. |
| columns | 6 \| 8 \| 10 \| 12 | 8 | Total de columnas en md y arriba. |
| gap | 0-6, 8, 10, 12 | 4 | Espacio entre hijos (ambos ejes). |
| gapX | 0-6, 8, 10, 12 | — | Espacio horizontal. Sobreescribe gap en eje X. |
| gapY | 0-6, 8, 10, 12 | — | Espacio vertical. Sobreescribe gap en eje Y. |
<GridColumn>
| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| children | ReactNode | — | Contenido de la columna. |
| className | string | — | Clases extra. |
| column | 1-12 | — | Cuántas columnas ocupa. Si no se pasa, ocupa todo el ancho. |
Ejemplos
Header de ancho completo + contenido en dos columnas
<GridWrapper columns={12}>
<GridColumn>
<h1 className="text-3xl font-bold">Título</h1>
</GridColumn>
<GridColumn column={8}>
<article>Artículo</article>
</GridColumn>
<GridColumn column={4}>
<aside>Información lateral</aside>
</GridColumn>
</GridWrapper>Tres tarjetas en fila
<GridWrapper columns={12} gap={6}>
<GridColumn column={4}><Card /></GridColumn>
<GridColumn column={4}><Card /></GridColumn>
<GridColumn column={4}><Card /></GridColumn>
</GridWrapper>Formulario con espacio horizontal pequeño y vertical grande
Caso típico donde gapX y gapY separados ayudan: campos del mismo "grupo" cerca, filas distintas separadas.
<GridWrapper columns={12} gapX={4} gapY={8}>
<GridColumn column={6}><Input label="Nombre" /></GridColumn>
<GridColumn column={6}><Input label="Apellido" /></GridColumn>
<GridColumn column={6}><Input label="Email" /></GridColumn>
<GridColumn column={6}><Input label="Teléfono" /></GridColumn>
</GridWrapper>Combinando gap + override de un eje
{/* gap-6 horizontal, gap-12 vertical */}
<GridWrapper columns={12} gap={6} gapY={12}>
{/* ... */}
</GridWrapper>Centrar el grid en la página
La librería intencionalmente NO incluye un componente "container" — el centrado y padding de página son responsabilidad del layout, no del sistema de grid. Hazlo a nivel de tu página:
<main className="mx-auto max-w-7xl px-4 py-8">
<GridWrapper columns={12}>
{/* ... */}
</GridWrapper>
</main>Sobreescribir clases con className
Gracias a tailwind-merge, las clases que pases en className sobreescriben de forma predecible las clases por defecto cuando hay conflictos:
{/* gap-2 gana sobre el gap-4 por defecto */}
<GridWrapper className="gap-2">...</GridWrapper>
{/* sm:col-span-12 gana sobre sm:col-span-6 */}
<GridColumn column={6} className="sm:col-span-12">...</GridColumn>Esto es útil cuando necesitas un caso específico que no encaja en la API tipada (por ejemplo, un breakpoint adicional).
Licencia
MIT
