@codenhub/styles 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +18 -16
- package/README.es.md +62 -0
- package/README.md +28 -22
- package/README.pt-BR.md +62 -0
- package/dist/aesthetics/chunky-tile.css +1 -1
- package/dist/aesthetics/cyber.css +1 -1
- package/dist/aesthetics/glass.css +1 -1
- package/dist/aesthetics/index.css +2 -2
- package/dist/aesthetics/neobrutalism.css +1 -1
- package/dist/aesthetics/pixel.css +1 -1
- package/dist/aesthetics/sketch.css +1 -1
- package/dist/cli.js +189 -0
- package/dist/components.css +2 -2
- package/dist/index.css +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/native.css +2 -2
- package/dist/palette.css +1 -1
- package/dist/theme.css +2 -2
- package/docs/accessibility.md +108 -60
- package/docs/changelog/0.1.1.md +1 -0
- package/docs/changelog/0.2.0.md +1 -0
- package/docs/changelog/0.3.0.md +1 -0
- package/docs/changelog/0.4.0.md +1 -0
- package/docs/changelog/0.5.0.md +8 -3
- package/docs/changelog/0.6.0.md +2 -1
- package/docs/changelog/0.7.0.md +50 -0
- package/docs/changelog/0.8.0.md +70 -0
- package/docs/changelog/index.md +2 -0
- package/docs/concepts.md +188 -46
- package/docs/es/accessibility.md +169 -0
- package/docs/es/concepts.md +212 -0
- package/docs/es/index.md +105 -0
- package/docs/es/integrating/astro.md +35 -0
- package/docs/es/integrating/index.md +75 -0
- package/docs/es/integrating/nextjs.md +67 -0
- package/docs/es/integrating/svelte.md +45 -0
- package/docs/es/integrating/tailwind.md +148 -0
- package/docs/es/integrating/vue.md +31 -0
- package/docs/es/integrating/without-a-bundler.md +238 -0
- package/docs/es/setup.md +188 -0
- package/docs/es/usage/aesthetics.md +282 -0
- package/docs/es/usage/buttons.md +135 -0
- package/docs/es/usage/composing.md +168 -0
- package/docs/es/usage/content-and-layout.md +219 -0
- package/docs/es/usage/customizing.md +304 -0
- package/docs/es/usage/feedback.md +157 -0
- package/docs/es/usage/forms.md +256 -0
- package/docs/es/usage/index.md +33 -0
- package/docs/es/usage/presets.md +92 -0
- package/docs/es/usage/solo.md +86 -0
- package/docs/es/usage/theming.md +309 -0
- package/docs/es/usage/tooltips.md +127 -0
- package/docs/index.md +86 -26
- package/docs/integrating/astro.md +3 -4
- package/docs/integrating/index.md +46 -13
- package/docs/integrating/nextjs.md +3 -4
- package/docs/integrating/svelte.md +5 -4
- package/docs/integrating/tailwind.md +89 -6
- package/docs/integrating/vue.md +3 -4
- package/docs/integrating/without-a-bundler.md +237 -0
- package/docs/pt-BR/accessibility.md +169 -0
- package/docs/pt-BR/concepts.md +212 -0
- package/docs/pt-BR/index.md +105 -0
- package/docs/pt-BR/integrating/astro.md +35 -0
- package/docs/pt-BR/integrating/index.md +75 -0
- package/docs/pt-BR/integrating/nextjs.md +67 -0
- package/docs/pt-BR/integrating/svelte.md +45 -0
- package/docs/pt-BR/integrating/tailwind.md +148 -0
- package/docs/pt-BR/integrating/vue.md +31 -0
- package/docs/pt-BR/integrating/without-a-bundler.md +238 -0
- package/docs/pt-BR/setup.md +188 -0
- package/docs/pt-BR/usage/aesthetics.md +282 -0
- package/docs/pt-BR/usage/buttons.md +135 -0
- package/docs/pt-BR/usage/composing.md +168 -0
- package/docs/pt-BR/usage/content-and-layout.md +219 -0
- package/docs/pt-BR/usage/customizing.md +304 -0
- package/docs/pt-BR/usage/feedback.md +157 -0
- package/docs/pt-BR/usage/forms.md +256 -0
- package/docs/pt-BR/usage/index.md +33 -0
- package/docs/pt-BR/usage/presets.md +92 -0
- package/docs/pt-BR/usage/solo.md +86 -0
- package/docs/pt-BR/usage/theming.md +309 -0
- package/docs/pt-BR/usage/tooltips.md +127 -0
- package/docs/setup.md +142 -91
- package/docs/usage/aesthetics.md +89 -73
- package/docs/usage/buttons.md +112 -40
- package/docs/usage/composing.md +109 -92
- package/docs/usage/content-and-layout.md +160 -125
- package/docs/usage/customizing.md +117 -41
- package/docs/usage/feedback.md +138 -71
- package/docs/usage/forms.md +201 -107
- package/docs/usage/index.md +22 -14
- package/docs/usage/presets.md +91 -0
- package/docs/usage/solo.md +85 -0
- package/docs/usage/theming.md +273 -118
- package/docs/usage/tooltips.md +90 -49
- package/llms-full.txt +2820 -1298
- package/llms.txt +24 -22
- package/package.json +134 -91
- package/{dist/tw → tw}/aesthetics/chunky-tile.css +107 -29
- package/{dist/tw → tw}/aesthetics/cyber.css +88 -40
- package/{dist/tw → tw}/aesthetics/glass.css +257 -61
- package/{dist/tw → tw}/aesthetics/neobrutalism.css +113 -20
- package/{dist/tw → tw}/aesthetics/pixel.css +93 -8
- package/tw/aesthetics/sketch.css +417 -0
- package/{dist/tw → tw}/box.css +105 -9
- package/tw/components/button.css +11 -0
- package/tw/components/button.rules.css +187 -0
- package/tw/components/feedback.css +11 -0
- package/{dist/tw/components/feedback.css → tw/components/feedback.rules.css} +136 -32
- package/tw/components/form.css +11 -0
- package/{dist/tw/components/form.css → tw/components/form.rules.css} +577 -125
- package/tw/components/index.css +16 -0
- package/tw/components/rules.css +41 -0
- package/tw/components/surface.css +11 -0
- package/tw/components/surface.rules.css +222 -0
- package/tw/components/tooltip.css +11 -0
- package/{dist/tw/components/tooltip.css → tw/components/tooltip.rules.css} +43 -27
- package/{dist/tw → tw}/corner.css +18 -12
- package/{dist/tw → tw}/elevation.css +23 -17
- package/{dist/tw → tw}/index.css +12 -10
- package/tw/index.d.ts +1 -0
- package/tw/intent.css +312 -0
- package/tw/modifiers.css +127 -0
- package/tw/native.css +320 -0
- package/tw/presentation.css +139 -0
- package/tw/reset.css +10 -0
- package/{dist/tw/reset.css → tw/reset.rules.css} +21 -22
- package/tw/size.css +34 -0
- package/tw/surface.css +9 -0
- package/tw/surface.rules.css +212 -0
- package/{dist/tw → tw}/theme.css +121 -45
- package/tw/typography.css +8 -0
- package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
- package/{dist/tw → tw}/utilities/content.css +212 -50
- package/tw/utilities/index.css +11 -0
- package/tw/utilities/layout.css +208 -0
- package/tw/utilities/rules.css +8 -0
- package/dist/tw/aesthetics/sketch.css +0 -333
- package/dist/tw/components/button.css +0 -139
- package/dist/tw/components/index.css +0 -36
- package/dist/tw/components/loader.css +0 -116
- package/dist/tw/components/surface.css +0 -175
- package/dist/tw/intent.css +0 -228
- package/dist/tw/native.css +0 -203
- package/dist/tw/palette.css +0 -460
- package/dist/tw/presentation.css +0 -68
- package/dist/tw/surface.css +0 -61
- package/dist/tw/utilities/index.css +0 -6
- package/dist/tw/utilities/layout.css +0 -130
- /package/{dist/tw → tw}/aesthetics/index.css +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Visión general
|
|
3
|
+
description: Cómo se carga la hoja de estilos en el build de un framework, y qué guía seguir.
|
|
4
|
+
group: Integración
|
|
5
|
+
order: 2
|
|
6
|
+
source: 2028acef66a8ab3659cef35e08ecc0db1de7bdeb
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Integración
|
|
10
|
+
|
|
11
|
+
Esta sección es un desvío del orden de lectura principal, para proyectos cuyo framework decide dónde puede ir el CSS global. El paquete no tiene JavaScript ni bindings para frameworks (consulta [Introducción](../index.md#lo-que-no-hace)), así que integrarlo se reduce a dos cosas: dónde te deja tu framework cargar una hoja de estilos global, y si el proyecto usa Tailwind CSS v4. Sigue la guía que corresponde a tu stack y después vuelve a [Construir una pantalla](../concepts.md).
|
|
12
|
+
|
|
13
|
+
## El modelo común
|
|
14
|
+
|
|
15
|
+
Todos los stacks hacen los mismos dos imports, desde el mismo tipo de lugar: un layout raíz, un archivo de entrada de la aplicación o un archivo CSS global, nunca una página o un componente más abajo en el árbol:
|
|
16
|
+
|
|
17
|
+
1. Un [punto de entrada](../setup.md#todos-los-puntos-de-entrada): el compilado `@codenhub/styles` para cualquier build, o `@codenhub/styles/tw` cuando el proyecto ya usa Tailwind CSS v4.
|
|
18
|
+
2. `@codenhub/styles/aesthetics` (o `/tw/aesthetics`) después, solo si el proyecto usa una [estética](../usage/aesthetics.md).
|
|
19
|
+
|
|
20
|
+
Importar desde un solo lugar importa por dos motivos. Algunos frameworks solo _permiten_ CSS global desde un archivo raíz designado y, si no, el build falla; el Pages Router de Next.js es uno de ellos, consulta [Next.js → Solución de problemas](./nextjs.md#solución-de-problemas). Donde un framework lo permite de forma más amplia, como hace el App Router de Next.js, importar desde la raíz sigue siendo la opción recomendada para que el orden del CSS sea predecible; además, importar en cada componente cargaría las mismas reglas de reset y de tokens una vez por componente en lugar de una vez por aplicación.
|
|
21
|
+
|
|
22
|
+
## Qué guía seguir
|
|
23
|
+
|
|
24
|
+
| Stack | Guía |
|
|
25
|
+
| ----------------------------------------------------------------------------------------------- | ------------------------------------- |
|
|
26
|
+
| Un proyecto con Tailwind CSS v4 en cualquier bundler | [Tailwind CSS v4](./tailwind.md) |
|
|
27
|
+
| Next.js / React | [Next.js](./nextjs.md) |
|
|
28
|
+
| Vue | [Vue](./vue.md) |
|
|
29
|
+
| Svelte / SvelteKit | [Svelte](./svelte.md) |
|
|
30
|
+
| Astro | [Astro](./astro.md) |
|
|
31
|
+
| HTML simple, Rails, Laravel, Django o cualquier aplicación sin paso de build de CSS con Node.js | [Sin bundler](./without-a-bundler.md) |
|
|
32
|
+
|
|
33
|
+
Un proyecto sin framework, un build simple con Vite, webpack o Parcel, importa la hoja de estilos compilada desde la entrada CSS global que el proyecto ya tiene, como muestra [Configuración inicial → Importar la hoja de estilos](../setup.md#importar-la-hoja-de-estilos). Vite y webpack resuelven el nombre del paquete tal cual; Parcel y PostCSS con `postcss-import` necesitan el cambio de abajo. La hoja de estilos compilada contiene todas las clases; para incluir solo las que usan tus páginas sin adoptar Tailwind, escribe una hoja de estilos reducida con el [comando `build`](./without-a-bundler.md#generar-solo-las-clases-que-usas) del paquete e impórtala en su lugar.
|
|
34
|
+
|
|
35
|
+
### Bundlers que necesitan un empujón
|
|
36
|
+
|
|
37
|
+
Ambas herramientas encuentran la hoja de estilos en cuanto se les dice cómo; ninguna necesita otro punto de entrada.
|
|
38
|
+
|
|
39
|
+
**Parcel.** Activa su soporte del mapa `exports` de un paquete en tu `package.json`:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"@parcel/resolver-default": {
|
|
44
|
+
"packageExports": true
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Luego importa el paquete con el prefijo `npm:` de Parcel, que le indica que el nombre es un paquete y no un archivo junto a la hoja de estilos:
|
|
50
|
+
|
|
51
|
+
```css
|
|
52
|
+
@import "npm:@codenhub/styles";
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**PostCSS con `postcss-import`.** El plugin no lee el mapa `exports` de un paquete, así que el nombre del paquete por sí solo no se resuelve. Importa en su lugar el archivo compilado por su ruta en disco, relativa a tu propia hoja de estilos, el mismo archivo que nombraría un `<link>`:
|
|
56
|
+
|
|
57
|
+
```css
|
|
58
|
+
@import "../node_modules/@codenhub/styles/dist/index.css";
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Los demás puntos de entrada compilados funcionan igual, como `@codenhub/styles/dist/aesthetics/neobrutalism.css`.
|
|
62
|
+
|
|
63
|
+
## Comprobar que funciona
|
|
64
|
+
|
|
65
|
+
Después del import, renderiza un elemento con estilo y confirma que ha tomado los tokens del paquete y no los valores por defecto del navegador:
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<button class="btn primary">Save changes</button>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Un botón redondeado relleno con el color principal (casi negro en una página clara, casi blanco en una oscura) significa que la hoja de estilos se ha cargado. Un texto sin estilo, con los valores por defecto del navegador, casi siempre significa que el especificador del import no se ha resuelto: consulta en la [tabla de puntos de entrada](../setup.md#todos-los-puntos-de-entrada) el especificador exacto que debes importar, y confirma que tus herramientas de build resuelven imports de CSS de paquetes; consulta [Configuración inicial → Requisitos](../setup.md#requisitos). Sin herramienta de build, enlaza el archivo por su ruta; consulta [Sin bundler](./without-a-bundler.md). [Configuración inicial → Cuando nada tiene estilo](../setup.md#cuando-nada-tiene-estilo) enumera las otras causas habituales.
|
|
72
|
+
|
|
73
|
+
## Siguiente paso
|
|
74
|
+
|
|
75
|
+
Cuando el botón se renderice, vuelve al camino principal: [Construir una pantalla](../concepts.md) añade la primera tarjeta y el primer formulario a la página de ajustes.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Next.js
|
|
3
|
+
description: Cargar la hoja de estilos en una aplicación Next.js / React.
|
|
4
|
+
order: 2
|
|
5
|
+
source: fd8dc12652c64995638c5b902a1ca35787f9a37c
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next.js
|
|
9
|
+
|
|
10
|
+
Next.js tiene dos arquitecturas de router, y tratan el CSS global de forma distinta:
|
|
11
|
+
|
|
12
|
+
- **App Router** (un directorio `app/`): el CSS global, incluida la hoja de estilos de un paquete externo como este, se puede importar desde cualquier layout, página o componente dentro de `app/`. Importarlo desde el layout raíz es solo una recomendación, para que el orden del CSS sea predecible entre rutas; Next.js no lo impone y no se produce ningún error si lo importas en otro sitio.
|
|
13
|
+
- **Pages Router** (un directorio `pages/`, sin `app/`): el CSS global está restringido a `pages/_app.tsx`. Importarlo desde cualquier otro sitio hace fallar el build; lo impone el propio Next.js, no este paquete; consulta [Solución de problemas](#solución-de-problemas).
|
|
14
|
+
- **Ambos directorios presentes** (a mitad de una migración): importa la hoja de estilos en los dos archivos raíz. Los dos routers sirven sus propias rutas de forma independiente, así que una ruta dentro de `pages/` nunca ve una hoja de estilos importada solo en `app/layout.tsx`, y viceversa.
|
|
15
|
+
|
|
16
|
+
## Importar la hoja de estilos
|
|
17
|
+
|
|
18
|
+
Añade el import al archivo raíz de tu router:
|
|
19
|
+
|
|
20
|
+
**App Router**
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
// app/layout.tsx
|
|
24
|
+
import "@codenhub/styles";
|
|
25
|
+
|
|
26
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
27
|
+
return (
|
|
28
|
+
<html lang="en">
|
|
29
|
+
<body>{children}</body>
|
|
30
|
+
</html>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Pages Router**
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
// pages/_app.tsx
|
|
39
|
+
import "@codenhub/styles";
|
|
40
|
+
import type { AppProps } from "next/app";
|
|
41
|
+
|
|
42
|
+
export default function App({ Component, pageProps }: AppProps) {
|
|
43
|
+
return <Component {...pageProps} />;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
¿Usas Tailwind CSS v4? `@import "@codenhub/styles/tw"` es una directiva de CSS, así que va en un archivo CSS, no como import suelto en `layout.tsx`/`_app.tsx`: añádelo (con `@source` si hace falta; `/tw` ya importa Tailwind, así que no pongas tu propio `@import "tailwindcss"`) a tu archivo CSS global, e importa ese archivo desde el mismo archivo raíz de arriba. Consulta [Tailwind CSS v4](./tailwind.md).
|
|
48
|
+
|
|
49
|
+
## Forzar un tema
|
|
50
|
+
|
|
51
|
+
Aplica `.dark` o `.light` en `<html>` para forzar un tema en lugar de seguir la preferencia del sistema; consulta [Temas → Claro y oscuro](../usage/theming.md#claro-y-oscuro).
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<html lang="en" className="dark">
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Solución de problemas
|
|
58
|
+
|
|
59
|
+
**El build con Pages Router falla con "Global CSS cannot be imported from files other than your Custom `<App>`"**
|
|
60
|
+
|
|
61
|
+
- **Qué ha pasado:** Next.js ha rechazado una sentencia `import` de CSS global fuera de `pages/_app.tsx`. Esta restricción es propia del Pages Router: la impone el propio Next.js, no este paquete, y se aplica a cualquier import de CSS global, no solo a `@codenhub/styles`. No se aplica al App Router, donde el mismo import funciona desde cualquier layout, página o componente.
|
|
62
|
+
- **Por qué:** el Pages Router no tiene un límite de CSS por ruta como el App Router, así que Next.js exige un único archivo predecible para las hojas de estilos globales y así evitar conflictos de orden entre páginas.
|
|
63
|
+
- **Solución:** mueve la línea `import "@codenhub/styles"` a `pages/_app.tsx` y quítala de donde esté ahora.
|
|
64
|
+
|
|
65
|
+
## Siguiente paso
|
|
66
|
+
|
|
67
|
+
Vuelve al camino principal: [Construir una pantalla](../concepts.md) añade la primera tarjeta y el primer formulario a la página de ajustes. [Configuración inicial → Todos los puntos de entrada](../setup.md#todos-los-puntos-de-entrada) enumera todas las demás hojas de estilos que puedes importar.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Svelte
|
|
3
|
+
description: Cargar la hoja de estilos en una aplicación Svelte / SvelteKit.
|
|
4
|
+
order: 4
|
|
5
|
+
source: 9c8bc0fee69e4b2bf1edd85c784b7df8ff1e883d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Svelte
|
|
9
|
+
|
|
10
|
+
Svelte y SvelteKit te permiten importar CSS desde cualquier componente, pero el reset y los tokens del paquete deberían cargarse una vez, antes de que se renderice cualquier componente. Esta página muestra dónde va ese único import en SvelteKit y en una aplicación Svelte simple.
|
|
11
|
+
|
|
12
|
+
## Importar la hoja de estilos
|
|
13
|
+
|
|
14
|
+
**SvelteKit**: importa desde el layout raíz para que se cargue una vez para todas las rutas:
|
|
15
|
+
|
|
16
|
+
```svelte
|
|
17
|
+
<!-- src/routes/+layout.svelte -->
|
|
18
|
+
<script>
|
|
19
|
+
import "@codenhub/styles";
|
|
20
|
+
let { children } = $props();
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
{@render children()}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Svelte simple + Vite**: importa en su lugar desde el archivo de entrada:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
// main.ts
|
|
30
|
+
import "@codenhub/styles";
|
|
31
|
+
import { mount } from "svelte";
|
|
32
|
+
import App from "./App.svelte";
|
|
33
|
+
|
|
34
|
+
mount(App, { target: document.getElementById("app")! });
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
¿Usas Tailwind CSS v4? Importa en su lugar `@codenhub/styles/tw` desde la entrada CSS de la aplicación; consulta [Tailwind CSS v4](./tailwind.md).
|
|
38
|
+
|
|
39
|
+
## Forzar un tema
|
|
40
|
+
|
|
41
|
+
Aplica `.dark` o `.light` en `<html>` (edita `src/app.html` en SvelteKit) para forzar un tema en lugar de seguir la preferencia del sistema; consulta [Temas → Claro y oscuro](../usage/theming.md#claro-y-oscuro).
|
|
42
|
+
|
|
43
|
+
## Siguiente paso
|
|
44
|
+
|
|
45
|
+
Vuelve al camino principal: [Construir una pantalla](../concepts.md) añade la primera tarjeta y el primer formulario a la página de ajustes. [Configuración inicial → Todos los puntos de entrada](../setup.md#todos-los-puntos-de-entrada) enumera todas las demás hojas de estilos que puedes importar.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tailwind CSS v4
|
|
3
|
+
description: Usar los puntos de entrada de código fuente /tw en un proyecto con Tailwind CSS v4.
|
|
4
|
+
order: 1
|
|
5
|
+
source: a86fe5fa121db14ab917b10fb69e839111ddbc47
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Tailwind CSS v4
|
|
9
|
+
|
|
10
|
+
Un proyecto que ya usa Tailwind CSS v4 puede compilar el código fuente de este paquete en lugar de cargar su salida compilada. Así, las utilidades de tu aplicación y las clases del paquete salen de un solo build, comparten un tema y usan una sola variante `dark:`. Esta página cubre el import, las estéticas, los puntos de entrada específicos, cómo construir tus propios componentes con `@apply`, cómo prescindir de la paleta de Tailwind y los problemas de build con los que probablemente te encuentres.
|
|
11
|
+
|
|
12
|
+
## Por qué código fuente en lugar de compilado
|
|
13
|
+
|
|
14
|
+
Los puntos de entrada `/tw` publican código fuente copiado y sin compilar desde la carpeta `tw/` del paquete; tu propio build de Tailwind lo compila junto con tu aplicación, así que sus directivas `@theme`, `@utility` y `@apply` se resuelven junto con las tuyas. Los puntos de entrada compilados (`@codenhub/styles`) siguen funcionando en un proyecto con Tailwind, pero entonces se ejecutan dos pipelines de CSS separados en paralelo en lugar de uno: usa `/tw` salvo que un motivo concreto lo descarte.
|
|
15
|
+
|
|
16
|
+
## Importar el punto de entrada de código fuente
|
|
17
|
+
|
|
18
|
+
```css
|
|
19
|
+
@import "@codenhub/styles/tw";
|
|
20
|
+
|
|
21
|
+
@source "./src";
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`/tw` importa el propio Tailwind, así que sustituye a tu `@import "tailwindcss"` en lugar de sumarse a él: con los dos, el Preflight de Tailwind se emite dos veces. Todos los demás puntos de entrada `/tw/*` esperan que tu import vaya primero; consulta [Usar un punto de entrada específico](#usar-un-punto-de-entrada-específico).
|
|
25
|
+
|
|
26
|
+
Tailwind CSS v4 escanea tu proyecto automáticamente: la mayoría de los proyectos no necesita nada más que el import anterior. Las rutas de `@source` se resuelven respecto al archivo CSS que las declara, no respecto a la raíz de tu proyecto, así que aquí `./src` significa "el `src/` que está junto a esta hoja de estilos"; ajústalo según dónde esté realmente tu hoja de estilos global. Añade `@source` solo para el markup al que el escaneo automático de Tailwind no llega por sí solo: una ruta excluida por defecto (incluida en `.gitignore`, o dentro de `node_modules`, por ejemplo una librería de componentes externa) o, en un monorepo, una que está fuera del árbol de directorios de este archivo. Apúntalo al markup de tu aplicación, no a este paquete: el código fuente del paquete nombra cada clase que define, así que escanearlo las emite todas, las usen tus páginas o no.
|
|
27
|
+
|
|
28
|
+
## Añadir estéticas
|
|
29
|
+
|
|
30
|
+
Añade una estética desde el punto de entrada de código fuente igual que con el compilado, después del import base:
|
|
31
|
+
|
|
32
|
+
```css
|
|
33
|
+
@import "@codenhub/styles/tw";
|
|
34
|
+
@import "@codenhub/styles/tw/aesthetics";
|
|
35
|
+
|
|
36
|
+
@source "./src";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usar un punto de entrada específico
|
|
40
|
+
|
|
41
|
+
Importa un punto de entrada `/tw/*` específico en lugar del combinado, como `/tw/button` o `/tw/form`, cuando un build solo necesita una familia de componentes; consulta la [tabla de puntos de entrada](../setup.md#todos-los-puntos-de-entrada) completa para ver qué compone cada uno.
|
|
42
|
+
|
|
43
|
+
A diferencia de `/tw`, los puntos de entrada específicos y `/tw/native` no importan Tailwind, así que mantén tu propio import primero:
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
@import "tailwindcss";
|
|
47
|
+
@import "@codenhub/styles/tw/button";
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Construir tus propios componentes con `@apply`
|
|
51
|
+
|
|
52
|
+
En `/tw`, cada componente, helper y clase de eje es una utilidad de Tailwind. Eso incluye las intenciones (`neutral`, `primary`, `secondary`, `success`, `warning`, `destructive`, `info`), la presentación (`solid`, `soft`, `ghost`, `edged`, `edgeless`), la elevación (`flat`, `raised`, `floating`), los patrones de esquina (`cut-diagonal`, `cut-diagonal-reverse`) y los tamaños (`sm`, `lg`). Así, una clase tuya puede llevar una receta completa:
|
|
53
|
+
|
|
54
|
+
```css
|
|
55
|
+
@import "@codenhub/styles/tw";
|
|
56
|
+
|
|
57
|
+
@utility btn-save {
|
|
58
|
+
@apply btn primary soft sm;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@utility btn-danger {
|
|
62
|
+
@apply btn destructive md:lg dark:solid;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<button class="btn-save" type="submit">Guardar</button>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- **Un componente aplicado se comporta como la clase.** `btn-save` reacciona al hover, se presiona, recibe el foco y sigue a una estética igual que `class="btn primary soft sm"`.
|
|
71
|
+
- **Las variantes funcionan.** `hover:primary`, `md:lg` y `dark:solid` aplican una clase de eje bajo esa condición, en tu marcado o dentro de `@apply`.
|
|
72
|
+
- **Escribe tu clase como `@utility`.** Así se queda en la capa `utilities`, y tus demás utilidades en el mismo elemento le siguen ganando. Una regla simple `.btn-save { @apply … }` también funciona, pero queda sin capa, así que lo que aplica gana a todas las utilidades del elemento; [Personalización → Helpers de composición](../usage/customizing.md#helpers-de-composición) tiene los detalles.
|
|
73
|
+
- **Los modificadores también se aplican.** Los modificadores de un componente, como `.tight` en `.stack`, `.icon` en `.btn` o `.interactive` en `.card`, también son utilidades, así que `@apply stack tight`, `@apply btn icon pill` y `md:tight` funcionan. El estado deshabilitado es la excepción: sigue siendo un atributo o la clase `.disabled` en el marcado.
|
|
74
|
+
- **Tu utilidad gana a los valores internos de un componente.** `p-0 text-center` en una celda de `.data-table`, `text-sm` en un `.label` y `px-8` en un `.btn.sm` se aplican todos.
|
|
75
|
+
|
|
76
|
+
[Preajustes](../usage/presets.md) compara esto con las demás formas de definir un aspecto una sola vez.
|
|
77
|
+
|
|
78
|
+
## Prescindir de la paleta de Tailwind
|
|
79
|
+
|
|
80
|
+
`/tw` se construye sobre el tema por defecto de Tailwind, así que las utilidades de su paleta, como `bg-red-500`, siguen disponibles. Si tu diseño usa solo los tokens del paquete, borra los tonos que no usas:
|
|
81
|
+
|
|
82
|
+
```css
|
|
83
|
+
@import "@codenhub/styles/tw";
|
|
84
|
+
|
|
85
|
+
@theme {
|
|
86
|
+
--color-red-*: initial;
|
|
87
|
+
--color-orange-*: initial;
|
|
88
|
+
--color-yellow-*: initial;
|
|
89
|
+
--color-lime-*: initial;
|
|
90
|
+
--color-green-*: initial;
|
|
91
|
+
--color-teal-*: initial;
|
|
92
|
+
--color-cyan-*: initial;
|
|
93
|
+
--color-sky-*: initial;
|
|
94
|
+
--color-blue-*: initial;
|
|
95
|
+
--color-violet-*: initial;
|
|
96
|
+
--color-purple-*: initial;
|
|
97
|
+
--color-fuchsia-*: initial;
|
|
98
|
+
--color-pink-*: initial;
|
|
99
|
+
--color-slate-*: initial;
|
|
100
|
+
--color-gray-*: initial;
|
|
101
|
+
--color-zinc-*: initial;
|
|
102
|
+
--color-stone-*: initial;
|
|
103
|
+
--color-black: initial;
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Los colores propios del paquete no cambian, y puedes seguir añadiendo colores tuyos en el mismo bloque.
|
|
108
|
+
|
|
109
|
+
El bloque deja fuera `neutral`, `emerald`, `amber`, `rose`, `indigo` y `white` a propósito: el tema construye sus colores a partir de ellos.
|
|
110
|
+
|
|
111
|
+
- **No borres todo el espacio de nombres.** `--color-*: initial` quita también los colores semánticos del paquete, y el build se detiene con un error como `Cannot apply unknown utility class`.
|
|
112
|
+
- **No borres una escala que lee el tema.** Borrar `--color-emerald-*` compila sin error, pero los colores de éxito construidos con ella se pierden.
|
|
113
|
+
|
|
114
|
+
## Solución de problemas
|
|
115
|
+
|
|
116
|
+
**Las clases no producen ningún estilo**
|
|
117
|
+
|
|
118
|
+
- **Qué ha pasado:** los componentes usan clases documentadas como `.btn.primary`, pero no aparece ningún estilo aunque `@import "@codenhub/styles/tw"` está en la hoja de estilos.
|
|
119
|
+
- **Por qué:** rara vez es por el propio `@source`, porque Tailwind ya escanea tu proyecto automáticamente. La causa más habitual es un markup que vive en un lugar que el escaneo automático excluye por defecto: una ruta incluida en `.gitignore`, o un componente que viene de `node_modules`. Puede que Tailwind no vea una clase usada solo ahí y no genere una regla para ella.
|
|
120
|
+
- **Solución:** añade un `@source` explícito que apunte a ese directorio, resuelto respecto a esta hoja de estilos, como en el [ejemplo de arriba](#importar-el-punto-de-entrada-de-código-fuente).
|
|
121
|
+
|
|
122
|
+
**Reglas de tokens y de reset duplicadas**
|
|
123
|
+
|
|
124
|
+
- **Qué ha pasado:** la hoja de estilos generada es más grande de lo esperado, y las herramientas de desarrollo del navegador muestran las mismas custom properties o reglas de reset definidas dos veces.
|
|
125
|
+
- **Por qué:** una de dos cosas. Importar en el mismo build un punto de entrada compilado (`@codenhub/styles`) y un punto de entrada `/tw` (`@codenhub/styles/tw`) compila los mismos tokens y el mismo reset desde dos fuentes independientes; el build de Tailwind no tiene forma de saber que describen el mismo paquete. O bien tu hoja de estilos importa `tailwindcss` junto a `/tw`, que ya lo importa, así que el Preflight se emite dos veces.
|
|
126
|
+
- **Solución:** elige un camino por proyecto, los puntos de entrada `/tw` para un proyecto con Tailwind CSS v4 y los compilados en todos los demás casos, y quita tu propio `@import "tailwindcss"` cuando importes `/tw`.
|
|
127
|
+
|
|
128
|
+
**Una clase construida en tiempo de ejecución no tiene estilo**
|
|
129
|
+
|
|
130
|
+
- **Qué ha pasado:** `<button class="btn primary">` tiene estilo, pero un botón cuya clase viene de una variable, como `"btn " + variant`, o de contenido de un CMS, no.
|
|
131
|
+
- **Por qué:** Tailwind emite solo las clases que encuentra escritas completas en los archivos que escanea. Eso vale también para las clases de componente del paquete: un build con `/tw` emite `.alert` solo si `alert` aparece en algún lugar que escanea, lo que limita la hoja de estilos a lo que usan tus páginas. Las clases de intención, de presentación, de elevación, de esquina y de tamaño, como `.primary`, `.soft` y `.sm`, también son utilidades, así que les pasa lo mismo. Las clases de estética, como `.glass`, son CSS plano y se emiten siempre. Un nombre armado en tiempo de ejecución nunca aparece completo en un archivo, así que el escaneo no lo ve.
|
|
132
|
+
- **Solución:** escribe cada nombre de clase completo en algún lugar que Tailwind escanee, por ejemplo en un objeto de consulta (`{ save: "btn primary", remove: "btn destructive" }`), o enumera en tu hoja de estilos los nombres que tu código o tu contenido pueden producir:
|
|
133
|
+
|
|
134
|
+
```css
|
|
135
|
+
@import "@codenhub/styles/tw";
|
|
136
|
+
|
|
137
|
+
@source inline("btn alert badge primary destructive soft");
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Todos los puntos de entrada `/tw` requieren Tailwind CSS 4.3.2 o posterior, por debajo de 5 (`>=4.3.2 <5`).
|
|
141
|
+
|
|
142
|
+
## La variante `dark:`
|
|
143
|
+
|
|
144
|
+
Los puntos de entrada `/tw` definen su propia variante `dark:`, así que tus utilidades cambian con los mismos selectores claro y oscuro que usan los tokens del paquete. Tiene una diferencia conocida respecto a los tokens cuando los temas están anidados; consulta [Temas → La variante dark:](../usage/theming.md#la-variante-dark).
|
|
145
|
+
|
|
146
|
+
## Siguiente paso
|
|
147
|
+
|
|
148
|
+
Vuelve al camino principal: [Construir una pantalla](../concepts.md) añade la primera tarjeta y el primer formulario a la página de ajustes. Todo lo que muestra funciona igual con `/tw`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Vue
|
|
3
|
+
description: Cargar la hoja de estilos en una aplicación Vue / Vite.
|
|
4
|
+
order: 3
|
|
5
|
+
source: 9cc23f66518b0aa3ce886602f39d05820b2b8bcf
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Vue
|
|
9
|
+
|
|
10
|
+
Vue no pone ninguna restricción sobre desde dónde se importa el CSS, pero importarlo una vez, desde el archivo de entrada de la aplicación, evita que el reset y los tokens se carguen más de una vez y garantiza que estén listos antes de que se renderice cualquier componente.
|
|
11
|
+
|
|
12
|
+
## Importar la hoja de estilos
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
// main.ts
|
|
16
|
+
import "@codenhub/styles";
|
|
17
|
+
import { createApp } from "vue";
|
|
18
|
+
import App from "./App.vue";
|
|
19
|
+
|
|
20
|
+
createApp(App).mount("#app");
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
¿Usas Tailwind CSS v4? Importa `@codenhub/styles/tw` desde un archivo CSS de entrada en lugar de `main.ts`, con el plugin `@tailwindcss/vite`; consulta [Tailwind CSS v4](./tailwind.md).
|
|
24
|
+
|
|
25
|
+
## Forzar un tema
|
|
26
|
+
|
|
27
|
+
Aplica `.dark` o `.light` en el elemento raíz para forzar un tema en lugar de seguir la preferencia del sistema; consulta [Temas → Claro y oscuro](../usage/theming.md#claro-y-oscuro).
|
|
28
|
+
|
|
29
|
+
## Siguiente paso
|
|
30
|
+
|
|
31
|
+
Vuelve al camino principal: [Construir una pantalla](../concepts.md) añade la primera tarjeta y el primer formulario a la página de ajustes. [Configuración inicial → Todos los puntos de entrada](../setup.md#todos-los-puntos-de-entrada) enumera todas las demás hojas de estilos que puedes importar.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Sin bundler
|
|
3
|
+
description: Enlazar las hojas de estilos compiladas desde HTML simple, Rails, Laravel, Django o cualquier aplicación renderizada en el servidor, y el build por línea de comandos.
|
|
4
|
+
order: 6
|
|
5
|
+
source: 6289ea781c99dcda5c027a72fede9e2f1cab8414
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Sin bundler
|
|
9
|
+
|
|
10
|
+
Las hojas de estilos compiladas son CSS terminado: cada una es un único archivo sin `@import` ni referencias a otro archivo, y cada imagen que dibuja va incrustada como URL `data:`: las máscaras del tick y del guion del checkbox, y los filtros de lente SVG que usa `.glass-liquid`. Una página puede cargar una con una simple etiqueta `<link>`, desde cualquier servidor, sin paso de build, y la hoja de estilos no hace más peticiones.
|
|
11
|
+
|
|
12
|
+
Lo que necesita una herramienta de build es el _nombre_ del import. `@import "@codenhub/styles"` nombra un paquete, y encontrar el archivo que hay detrás de ese nombre, `node_modules/@codenhub/styles/dist/index.css`, lo hacen herramientas que conocen Node, como Vite, webpack o la CLI de Tailwind, que leen el mapa `exports` del paquete. Un navegador no: resuelve la URL de un `@import` respecto a la hoja de estilos que lo contiene y un `<link href>` respecto a la página, así que un nombre de paquete sin más se convierte en una petición a una ruta que no existe. Sin bundler, enlaza el archivo por su ruta.
|
|
13
|
+
|
|
14
|
+
Los puntos de entrada `/tw` son código fuente de Tailwind y necesitan un build de Tailwind. `/tw/aesthetics` es la excepción, CSS simple sin nada que Tailwind tenga que procesar, pero sin bundler enlaza en su lugar los archivos compilados de `dist/aesthetics/`, como se muestra abajo. Esta página es para una página que no tiene un build de CSS con Node.js: HTML simple, Rails, Laravel, Django o cualquier aplicación renderizada en el servidor. Hay dos caminos:
|
|
15
|
+
|
|
16
|
+
1. **Enlazar la hoja de estilos compilada.** Funciona hoy, solo con archivos estáticos. Envías todas las clases, las usen tus páginas o no.
|
|
17
|
+
2. **Generar una hoja de estilos con el comando `build` del paquete.** Escanea tus plantillas y escribe una hoja de estilos con solo las clases que usan. Consulta [Generar solo las clases que usas](#generar-solo-las-clases-que-usas).
|
|
18
|
+
|
|
19
|
+
## Qué archivo enlazar
|
|
20
|
+
|
|
21
|
+
Cada ruta de import compilada es un archivo en la carpeta `dist/` del paquete:
|
|
22
|
+
|
|
23
|
+
| Ruta de import | Archivo |
|
|
24
|
+
| ------------------------------- | -------------------------------------------------------------- |
|
|
25
|
+
| `@codenhub/styles` | `dist/index.css` |
|
|
26
|
+
| `@codenhub/styles/theme` | `dist/theme.css` |
|
|
27
|
+
| `@codenhub/styles/components` | `dist/components.css` |
|
|
28
|
+
| `@codenhub/styles/native` | `dist/native.css` |
|
|
29
|
+
| `@codenhub/styles/palette` | `dist/palette.css` |
|
|
30
|
+
| `@codenhub/styles/aesthetics` | `dist/aesthetics/index.css` |
|
|
31
|
+
| `@codenhub/styles/aesthetics/*` | `dist/aesthetics/<name>.css`, como `dist/aesthetics/pixel.css` |
|
|
32
|
+
|
|
33
|
+
Enlaza un solo archivo base, no varios, porque se solapan, y las estéticas que uses. Su orden no importa, porque cada archivo declara las [capas de cascada](../setup.md#capas-de-cascada) antes de usar alguna. [Configuración inicial → Todos los puntos de entrada](../setup.md#todos-los-puntos-de-entrada) explica qué contiene cada uno.
|
|
34
|
+
|
|
35
|
+
## Desde un CDN
|
|
36
|
+
|
|
37
|
+
jsDelivr y unpkg sirven todos los archivos de cada versión publicada en npm, así que una página puede enlazar uno sin instalar nada:
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<head>
|
|
41
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.8.0/dist/index.css" />
|
|
42
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.8.0/dist/aesthetics/pixel.css" />
|
|
43
|
+
</head>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Pon la versión exacta en la URL. Sin ella, el CDN sirve la última versión, y por debajo de 1.0 una versión menor puede renombrar o eliminar una clase; consulta [Versionado](../index.md#versionado).
|
|
47
|
+
|
|
48
|
+
## Desde tu propio servidor
|
|
49
|
+
|
|
50
|
+
Instala el paquete y después sirve su carpeta `dist/` como archivos estáticos:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
npm install @codenhub/styles
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Cada framework sirve de forma distinta una carpeta de `node_modules`, así que abajo está cada uno. Donde el framework lee la carpeta en su sitio, como hacen Rails y Django, actualizar el paquete y volver a desplegar es todo lo que hace falta para una actualización.
|
|
57
|
+
|
|
58
|
+
### HTML simple
|
|
59
|
+
|
|
60
|
+
Copia `node_modules/@codenhub/styles/dist` en la carpeta que publica tu servidor y después enlázala:
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<link rel="stylesheet" href="/vendor/codenhub-styles/index.css" />
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Repite la copia después de cada actualización, por ejemplo desde un script `postinstall` de npm.
|
|
67
|
+
|
|
68
|
+
### Ruby on Rails
|
|
69
|
+
|
|
70
|
+
Una aplicación Rails construida con `cssbundling-rails` ya usa un bundler: importa el paquete desde `app/assets/stylesheets/application.css` como en [Configuración inicial → Importar la hoja de estilos](../setup.md#importar-la-hoja-de-estilos).
|
|
71
|
+
|
|
72
|
+
Con Propshaft y sin bundler de CSS, añade la carpeta del paquete a las rutas de assets:
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
# config/initializers/assets.rb
|
|
76
|
+
Rails.application.config.assets.paths << Rails.root.join("node_modules/@codenhub")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Después enlázala desde el layout, por su ruta dentro de esa carpeta:
|
|
80
|
+
|
|
81
|
+
```erb
|
|
82
|
+
<%# app/views/layouts/application.html.erb %>
|
|
83
|
+
<%= stylesheet_link_tag "styles/dist/index" %>
|
|
84
|
+
<%= stylesheet_link_tag "styles/dist/aesthetics/pixel" %>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Apunta la ruta a `node_modules/@codenhub` y no directamente a `dist/`. Propshaft sirve los archivos por su ruta dentro de cada carpeta de assets, así que añadir `dist/` directamente publicaría un `index.css` suelto que choca con cualquier `index.css` tuyo.
|
|
88
|
+
|
|
89
|
+
Los archivos que enlazas están en `dist/`, que contiene solo CSS terminado, más un `index.d.ts` vacío para TypeScript. El código fuente de Tailwind vive en `tw/`, fuera de `dist/`, así que un pipeline estático que sirve `dist/` o le añade huellas no encuentra ningún `@import` que no pueda resolver.
|
|
90
|
+
|
|
91
|
+
### Django
|
|
92
|
+
|
|
93
|
+
Añade la carpeta a `STATICFILES_DIRS` con un prefijo, que mantiene sus nombres de archivo separados de tus propios archivos estáticos:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
# settings.py
|
|
97
|
+
STATICFILES_DIRS = [
|
|
98
|
+
("codenhub-styles", BASE_DIR / "node_modules/@codenhub/styles/dist"),
|
|
99
|
+
]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```django
|
|
103
|
+
{% load static %}
|
|
104
|
+
<link rel="stylesheet" href="{% static 'codenhub-styles/index.css' %}" />
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Apunta el prefijo a `dist`, no a la carpeta del paquete. `dist/` contiene solo CSS terminado, más un `index.d.ts` vacío para TypeScript que el almacenamiento copia tal cual, así que `collectstatic` también funciona con `ManifestStaticFilesStorage`, que añade una huella a cada archivo y reescribe las referencias que contiene. La carpeta del paquete también contiene el código fuente de Tailwind en `tw/`, cuyas líneas `@import "tailwindcss/..."` ese almacenamiento no puede resolver.
|
|
108
|
+
|
|
109
|
+
### Laravel
|
|
110
|
+
|
|
111
|
+
Una aplicación Laravel usa Vite por defecto, así que tiene un bundler: importa el paquete desde `resources/css/app.css` como en [Configuración inicial → Importar la hoja de estilos](../setup.md#importar-la-hoja-de-estilos), y carga ese archivo con la directiva `@vite` como de costumbre.
|
|
112
|
+
|
|
113
|
+
## Generar solo las clases que usas
|
|
114
|
+
|
|
115
|
+
El paquete trae un comando, `codenhub-styles`, que lo compila por ti. Lee tus plantillas en busca de nombres de clase y escribe una sola hoja de estilos minificada con solo las clases de StyleKit y las utilidades de Tailwind que usan. Una página que usa un botón recibe una pequeña fracción de la hoja de estilos completa; el tamaño exacto depende de las clases que uses, porque cada componente trae las reglas compartidas de las que depende.
|
|
116
|
+
|
|
117
|
+
El comando también sirve con un bundler. Un proyecto cuyo bundler no ejecuta Tailwind, como un build simple con Vite o webpack, puede escribir la hoja de estilos entre sus fuentes, `--output src/stylekit.css`, e importar ese archivo donde importaría `@codenhub/styles`. Un proyecto que usa Tailwind CSS v4 obtiene la misma reducción con el [punto de entrada de código fuente](./tailwind.md) y no necesita el comando.
|
|
118
|
+
|
|
119
|
+
Necesita Node.js 24 o posterior en la máquina que genera el CSS, sea tu portátil, un job de CI o un paso del despliegue. Compila con Tailwind CSS, que el paquete no instala por ti, así que un proyecto que solo enlaza la hoja de estilos compilada nunca lo descarga. Instala los tres paquetes como dependencias de desarrollo desde la raíz de tu proyecto; npm crea un `package.json` si no tienes uno, y no necesitas configuración de Tailwind:
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
npm install --save-dev @codenhub/styles @tailwindcss/cli tailwindcss
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
La hoja de estilos que escribe el comando es CSS simple, así que los servidores que sirven tu sitio no necesitan ni Node.js ni ninguno de estos paquetes. Ejecútalo desde la raíz de tu proyecto:
|
|
126
|
+
|
|
127
|
+
```sh
|
|
128
|
+
npx codenhub-styles build --content "app/views/**/*.erb" --output public/stylekit.css
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Si todo va bien, el comando imprime una línea: la ruta absoluta que escribió y el tamaño del archivo en bytes:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
/home/you/shop/public/stylekit.css 25782 bytes
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Enlaza ese archivo desde tu layout como cualquier hoja de estilos estática.
|
|
138
|
+
|
|
139
|
+
### Vistas de Rails
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
npx codenhub-styles build --content "app/views/**/*.erb" --content "app/helpers/**/*.rb" --output public/stylekit.css
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```erb
|
|
146
|
+
<%# app/views/layouts/application.html.erb %>
|
|
147
|
+
<link rel="stylesheet" href="/stylekit.css" />
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Vistas Blade de Laravel
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
npx codenhub-styles build --content "resources/views/**/*.blade.php" --output public/css/stylekit.css
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```blade
|
|
157
|
+
{{-- resources/views/layouts/app.blade.php --}}
|
|
158
|
+
<link rel="stylesheet" href="{{ asset('css/stylekit.css') }}" />
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Plantillas de Django
|
|
162
|
+
|
|
163
|
+
Un proyecto Django guarda las plantillas en una carpeta `templates/` del proyecto, en la carpeta `templates/` de cada app, o en ambas. Pasa un `--content` por cada lugar donde estén las tuyas, y deja fuera los que no uses, porque un glob que no coincide con nada hace fallar el build:
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
npx codenhub-styles build --content "templates/**/*.html" --content "shop/templates/**/*.html" --output static/stylekit.css
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```django
|
|
170
|
+
{% load static %}
|
|
171
|
+
<link rel="stylesheet" href="{% static 'stylekit.css' %}" />
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Escribe la salida en una carpeta incluida en `STATICFILES_DIRS`, aquí `static/`, para que `collectstatic` la recoja. La configuración de arriba solo incluye la carpeta del paquete, así que añade `BASE_DIR / "static"` a esa lista si tu proyecto aún no la tiene.
|
|
175
|
+
|
|
176
|
+
### Opciones
|
|
177
|
+
|
|
178
|
+
- `--content <glob>`, o `-c <glob>`, indica los archivos en los que buscar nombres de clase. Es obligatorio y se puede repetir: pásalo una vez por glob, y el build lee todos los archivos que coincidan con alguno. Un glob relativo se resuelve respecto a la carpeta desde la que ejecutas el comando, así que ejecútalo desde la raíz de tu proyecto; un glob absoluto se usa tal cual. `**` coincide con cualquier número de carpetas, y `{rb,erb}` con cualquiera de las dos extensiones. Sirve cualquier archivo de texto, tenga la extensión que tenga. Cada glob tiene que coincidir con al menos un archivo, o el build falla y lo nombra, así que una errata no puede publicar una hoja de estilos vacía. Los archivos que excluye tu `.gitignore` se leen igualmente cuando un glob coincide con ellos, y no se lee nada fuera de tus globs.
|
|
179
|
+
- Pon cada glob entre comillas. Sin comillas, tu shell puede expandir el glob a una lista de archivos antes de que el comando lo vea, y solo el primer archivo cuenta como valor de `--content`. Cuando eso deja nombres de archivo sobrantes, el build los rechaza en lugar de leer en silencio menos de lo que querías; cuando el glob coincidió con un solo archivo, el build lee solo ese archivo y nada de lo que tus plantillas añadan más adelante.
|
|
180
|
+
- `--output <file>`, o `-o <file>`, es la hoja de estilos que se escribe. Es obligatorio. Una ruta relativa se resuelve respecto a la carpeta desde la que ejecutas el comando, las carpetas padre que falten se crean, y un archivo existente se reemplaza.
|
|
181
|
+
- `--aesthetic <name>` añade una de las [estéticas](../usage/aesthetics.md): `neobrutalism`, `glass`, `pixel`, `chunky-tile`, `cyber` o `sketch`. Repítelo para más de una; nombrar una dos veces la incluye una sola vez. Las estéticas se piden explícitamente porque el build no puede saber por tus plantillas cuál quieres, así que cada una se escribe completa cuando la pides, y no se incluye ninguna cuando no lo haces.
|
|
182
|
+
- `--no-minify` escribe en su lugar CSS legible e indentado. Sirve para leer lo que generó el build; en producción sirve el archivo minificado.
|
|
183
|
+
- `--help` imprime el uso, con las estéticas que trae esta versión. `--version` imprime la versión del paquete. Ninguno de los dos genera nada, y ambos terminan con estado 0.
|
|
184
|
+
|
|
185
|
+
La salida siempre contiene el tema, sus design tokens como propiedades personalizadas de CSS, el reset y las reglas base de las que dependen todos los componentes. Encima van cada clase de StyleKit que usan tus plantillas, con las variantes con las que la combinas, como `primary` o `soft`, y cada utilidad de Tailwind que usan, como `flex` o `mt-4`. La salida se construye a partir de la hoja de estilos completa, no de `/native`, así que no incluye los mapeos sin clases.
|
|
186
|
+
|
|
187
|
+
### Cómo se encuentran las clases
|
|
188
|
+
|
|
189
|
+
El build no ejecuta tus plantillas. Lee como texto simple cada archivo que coincide con tus globs de `--content`, recoge cada palabra que podría ser un nombre de clase y escribe las reglas de las palabras que son clases de StyleKit o utilidades de Tailwind. Tailwind CSS también lee el contenido así.
|
|
190
|
+
|
|
191
|
+
Una clase tiene que aparecer en un archivo como una palabra completa. `class="btn primary"`, `class: "btn primary"` y `classes = ["btn", "primary"]` funcionan. Una palabra que solo parece una clase también cuenta: un comentario que dice "card" añade todas las reglas de la tarjeta a la hoja de estilos, lo que agranda el archivo y no cambia nada en la página.
|
|
192
|
+
|
|
193
|
+
Un nombre de clase que tu código arma al renderizar nunca aparece completo en ningún archivo, así que el build no puede encontrarlo. En `class="btn <%= @order.priority %>"`, `btn` se encuentra, pero la intención es lo que contenga `priority` al renderizar; si es `destructive`, el botón se renderiza sin su rojo. Hay dos salidas:
|
|
194
|
+
|
|
195
|
+
- **Escribe los nombres de clase completos.** Asigna cada valor a un nombre de clase completo en un archivo que el build lea, como `{ "urgent" => "destructive", "normal" => "neutral" }.fetch(@order.priority)` en un helper.
|
|
196
|
+
- **Enuméralos en un archivo de safelist.** Un archivo de texto simple con un nombre de clase por línea, añadido con su propio `--content`, como `--content config/stylekit-classes.txt`. Guárdalo junto al código que arma los nombres de clase, para que quien cambie uno vea el otro.
|
|
197
|
+
|
|
198
|
+
### Lo que no hace
|
|
199
|
+
|
|
200
|
+
- **No tiene modo watch.** Genera una vez y termina. Vuelve a ejecutarlo después de cambiar una plantilla, desde un script o desde un observador de archivos que ya tengan tu framework o tu editor. Una clase que la hoja de estilos todavía no tiene deja su elemento sin estilo hasta el siguiente build.
|
|
201
|
+
- **No tiene archivo de configuración ni CSS propio.** No puedes añadir tus propios valores de `@theme`, definiciones de `@utility` ni plugins. Para cambiar el aspecto, sobrescribe las propiedades personalizadas en una hoja de estilos tuya cargada después de esta, como describe [Personalización](../usage/customizing.md). Cuando necesites la configuración propia de Tailwind, instala Tailwind CSS e importa el punto de entrada de código fuente desde tu propia entrada de Tailwind, como muestra [Tailwind CSS v4](./tailwind.md).
|
|
202
|
+
- **No tiene otros comandos.** `build` es el único; `--help` y `--version` son los únicos flags que funcionan sin él.
|
|
203
|
+
- **No trae una versión de Tailwind propia.** Cada build usa los `@tailwindcss/cli` y `tailwindcss` instalados en tu proyecto, dentro del rango `>=4.3.2 <5` que StyleKit admite, así que tu lockfile los fija.
|
|
204
|
+
|
|
205
|
+
### En un despliegue
|
|
206
|
+
|
|
207
|
+
Genera la hoja de estilos antes del paso que recoge o añade huella a tus assets, como `rails assets:precompile`, `php artisan optimize` o `python manage.py collectstatic`. Puedes hacer commit de la salida, de modo que los servidores no necesitan Node.js en absoluto, a cambio de un archivo generado que alguien tiene que acordarse de regenerar; o generarla en el despliegue, de modo que la máquina de build necesita Node.js 24 o posterior.
|
|
208
|
+
|
|
209
|
+
Fija la versión. Por debajo de 1.0 una versión menor puede renombrar o eliminar una clase, así que el mismo comando puede escribir otra hoja de estilos con una versión más nueva. Haz commit de `package.json` y del lockfile que escribe npm, e instala con `npm ci` en la máquina de build, para que cada build use las versiones que probaste.
|
|
210
|
+
|
|
211
|
+
### Cuando el build falla
|
|
212
|
+
|
|
213
|
+
Cada fallo imprime una línea que empieza por `codenhub-styles:` en la salida de error estándar y termina con estado 1, sin escribir el archivo de salida, así que un script de despliegue se detiene en lugar de publicar una hoja de estilos desactualizada o vacía. La línea dice qué salió mal y qué hacer:
|
|
214
|
+
|
|
215
|
+
- **`missing --content` o `missing --output`.** Añade la que nombra. Un `--output` vacío o con solo espacios cuenta como ausente.
|
|
216
|
+
- **`--content "<glob>" matches no file in <folder>`.** Suele ser una errata en la ruta, un comando ejecutado desde una carpeta distinta de la raíz de tu proyecto, o un glob de un lugar que tu proyecto no usa. Generar a partir de nada escribiría una hoja de estilos sin clases de componente, y el sitio perdería sus estilos sin avisar.
|
|
217
|
+
- **`unexpected argument "<file>"`.** Casi siempre es un glob de `--content` sin comillas, que tu shell expandió a una lista de archivos. Pon el glob entre comillas.
|
|
218
|
+
- **`unknown option "<flag>"`.** Una errata, o una opción de otra herramienta, como `--watch` o `--config`. `--help` enumera las opciones.
|
|
219
|
+
- **`option "<flag>" is missing its value or does not take one`.** Un flag que lleva valor fue lo último de la línea, o se le dio un valor a `--no-minify`, como en `--no-minify=true`.
|
|
220
|
+
- **`unknown aesthetic "<name>"; choose from ...`.** Elige uno de los nombres de la lista. Van en minúsculas y con guion, como `chunky-tile`.
|
|
221
|
+
- **`missing command` o `unknown command "<name>"`.** La primera palabra después de `codenhub-styles` tiene que ser `build`.
|
|
222
|
+
- **`this command needs @tailwindcss/cli and tailwindcss, which are not installed`.** La línea nombra el que falte de los dos y termina con el comando que lo instala. Ejecútalo desde la raíz de tu proyecto.
|
|
223
|
+
- **`this command needs Node.js 24 or newer`.** Actualiza Node.js en la máquina que genera el CSS.
|
|
224
|
+
- **`Tailwind failed to build the stylesheet: <reason>`.** `<reason>` es el propio mensaje de Tailwind. `EISDIR` significa que `--output` nombra una carpeta existente, así que nombra un archivo dentro de ella; `EACCES` o `EPERM` significa que no puedes escribir ahí. Ante cualquier otro motivo, ejecuta el mismo comando con `--no-minify` para descartar el minificador, e informa del mensaje junto con la versión que imprime `--version`.
|
|
225
|
+
|
|
226
|
+
## Comprobar que funciona
|
|
227
|
+
|
|
228
|
+
Renderiza un elemento con estilo, como en [Integración → Comprobar que funciona](./index.md#comprobar-que-funciona):
|
|
229
|
+
|
|
230
|
+
```html
|
|
231
|
+
<button class="btn primary">Save changes</button>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Un botón redondeado relleno con el color principal significa que la hoja de estilos se ha cargado. Si el botón se ve como el predeterminado del navegador, abre el panel de red del navegador: un `404` en la hoja de estilos significa que la ruta o la configuración de archivos estáticos es incorrecta.
|
|
235
|
+
|
|
236
|
+
## Siguiente paso
|
|
237
|
+
|
|
238
|
+
Vuelve al camino principal: [Construir una pantalla](../concepts.md) añade la primera tarjeta y el primer formulario a la página de ajustes. [Configuración inicial → Todos los puntos de entrada](../setup.md#todos-los-puntos-de-entrada) enumera todas las demás hojas de estilos que puedes importar.
|