@codenhub/styles 0.5.0 → 0.7.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 +61 -0
- package/README.md +27 -22
- package/README.pt-BR.md +61 -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/components.css +2 -2
- package/dist/index.css +2 -2
- package/dist/native.css +2 -2
- package/dist/palette.css +1 -1
- package/dist/theme.css +2 -2
- package/dist/tw/aesthetics/chunky-tile.css +120 -62
- package/dist/tw/aesthetics/cyber.css +102 -40
- package/dist/tw/aesthetics/glass.css +371 -19
- package/dist/tw/aesthetics/index.css +2 -1
- package/dist/tw/aesthetics/neobrutalism.css +121 -33
- package/dist/tw/aesthetics/pixel.css +111 -16
- package/dist/tw/aesthetics/sketch.css +100 -28
- package/dist/tw/box.css +69 -28
- package/dist/tw/components/button.css +35 -14
- package/dist/tw/components/feedback.css +61 -58
- package/dist/tw/components/form.css +255 -142
- package/dist/tw/components/index.css +4 -9
- package/dist/tw/components/surface.css +80 -68
- package/dist/tw/components/tooltip.css +75 -41
- package/dist/tw/elevation.css +14 -22
- package/dist/tw/index.css +15 -19
- package/dist/tw/intent.css +35 -27
- package/dist/tw/native.css +22 -12
- package/dist/tw/palette.css +14 -11
- package/dist/tw/presentation.css +16 -30
- package/dist/tw/reset.css +36 -43
- package/dist/tw/surface.css +11 -12
- package/dist/tw/theme.css +87 -103
- package/dist/tw/utilities/content.css +311 -200
- package/dist/tw/utilities/layout.css +41 -37
- package/docs/accessibility.md +104 -58
- 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 +53 -0
- package/docs/changelog/0.7.0.md +50 -0
- package/docs/changelog/index.md +2 -0
- package/docs/concepts.md +188 -46
- package/docs/es/accessibility.md +150 -0
- package/docs/es/concepts.md +212 -0
- package/docs/es/index.md +104 -0
- package/docs/es/integrating/astro.md +35 -0
- package/docs/es/integrating/index.md +47 -0
- package/docs/es/integrating/nextjs.md +67 -0
- package/docs/es/integrating/svelte.md +45 -0
- package/docs/es/integrating/tailwind.md +78 -0
- package/docs/es/integrating/vue.md +31 -0
- package/docs/es/integrating/without-a-bundler.md +115 -0
- package/docs/es/setup.md +180 -0
- package/docs/es/usage/aesthetics.md +276 -0
- package/docs/es/usage/buttons.md +131 -0
- package/docs/es/usage/composing.md +164 -0
- package/docs/es/usage/content-and-layout.md +215 -0
- package/docs/es/usage/customizing.md +298 -0
- package/docs/es/usage/feedback.md +153 -0
- package/docs/es/usage/forms.md +231 -0
- package/docs/es/usage/index.md +29 -0
- package/docs/es/usage/solo.md +84 -0
- package/docs/es/usage/theming.md +296 -0
- package/docs/es/usage/tooltips.md +127 -0
- package/docs/index.md +89 -21
- package/docs/integrating/astro.md +3 -4
- package/docs/integrating/index.md +18 -13
- package/docs/integrating/nextjs.md +4 -5
- package/docs/integrating/svelte.md +5 -4
- package/docs/integrating/tailwind.md +29 -8
- package/docs/integrating/vue.md +3 -4
- package/docs/integrating/without-a-bundler.md +114 -0
- package/docs/pt-BR/accessibility.md +150 -0
- package/docs/pt-BR/concepts.md +212 -0
- package/docs/pt-BR/index.md +104 -0
- package/docs/pt-BR/integrating/astro.md +35 -0
- package/docs/pt-BR/integrating/index.md +47 -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 +78 -0
- package/docs/pt-BR/integrating/vue.md +31 -0
- package/docs/pt-BR/integrating/without-a-bundler.md +115 -0
- package/docs/pt-BR/setup.md +180 -0
- package/docs/pt-BR/usage/aesthetics.md +276 -0
- package/docs/pt-BR/usage/buttons.md +131 -0
- package/docs/pt-BR/usage/composing.md +164 -0
- package/docs/pt-BR/usage/content-and-layout.md +215 -0
- package/docs/pt-BR/usage/customizing.md +298 -0
- package/docs/pt-BR/usage/feedback.md +153 -0
- package/docs/pt-BR/usage/forms.md +231 -0
- package/docs/pt-BR/usage/index.md +29 -0
- package/docs/pt-BR/usage/solo.md +84 -0
- package/docs/pt-BR/usage/theming.md +296 -0
- package/docs/pt-BR/usage/tooltips.md +127 -0
- package/docs/setup.md +134 -91
- package/docs/usage/aesthetics.md +102 -65
- package/docs/usage/buttons.md +108 -40
- package/docs/usage/composing.md +105 -92
- package/docs/usage/content-and-layout.md +159 -127
- package/docs/usage/customizing.md +112 -43
- package/docs/usage/feedback.md +135 -70
- package/docs/usage/forms.md +184 -99
- package/docs/usage/index.md +18 -14
- package/docs/usage/solo.md +83 -0
- package/docs/usage/theming.md +260 -119
- package/docs/usage/tooltips.md +103 -42
- package/llms-full.txt +2465 -1272
- package/llms.txt +25 -17
- package/package.json +28 -35
- package/dist/tw/components/loader.css +0 -117
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Construir una pantalla
|
|
3
|
+
description: Maqueta la página de ajustes, define su tipografía y añade tarjetas y botones mientras aprendes qué son la intención, el relleno, el borde y la estética.
|
|
4
|
+
order: 3
|
|
5
|
+
source: 8fa5ed2f6fb9a2786f61301f94bbe806649d7e1d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Construir una pantalla
|
|
9
|
+
|
|
10
|
+
Esta página convierte la estructura vacía de [Configuración inicial](./setup.md) en la primera parte real de la pantalla de ajustes: un encabezado de página, una tarjeta de perfil con los botones Guardar y Cancelar, y un resumen del plan junto a una tarjeta de uso. Por el camino presenta las tres decisiones que toma cada componente, intención, presentación y estética, justo cuando la pantalla necesita cada una. Todo lo demás en esta documentación se apoya en este modelo.
|
|
11
|
+
|
|
12
|
+
## La pantalla más pequeña
|
|
13
|
+
|
|
14
|
+
Un encabezado de página y una tarjeta con un botón:
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<main class="section">
|
|
18
|
+
<div class="section-content narrow stack">
|
|
19
|
+
<h1 class="text-title">Account settings</h1>
|
|
20
|
+
<section class="card stack">
|
|
21
|
+
<h2 class="text-title-sm">Profile</h2>
|
|
22
|
+
<p>Your name appears on invoices and shared projects.</p>
|
|
23
|
+
<button class="btn primary" type="button">Save changes</button>
|
|
24
|
+
</section>
|
|
25
|
+
</div>
|
|
26
|
+
</main>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Cada clase hace una sola cosa:
|
|
30
|
+
|
|
31
|
+
- `.section` da espacio a la página: un margen lateral adaptable (de 1 a 2rem) y un espacio generoso arriba y abajo (de 4 a 7rem).
|
|
32
|
+
- `.section-content` centra una columna con un ancho máximo; `.narrow` lo deja en 48rem en lugar de 80rem, un ancho cómodo para un formulario.
|
|
33
|
+
- `.stack` coloca sus hijos en vertical con una separación de 1rem.
|
|
34
|
+
- `.text-title` y `.text-title-sm` definen el tamaño de los encabezados: 1.875rem en negrita y 1.25rem en seminegrita.
|
|
35
|
+
- `.card` es un contenedor con borde, esquinas redondeadas y 1.25rem de relleno interior.
|
|
36
|
+
- `.btn` crea un botón, y `.primary` le da el color principal.
|
|
37
|
+
|
|
38
|
+
Los encabezados no toman su tamaño de la etiqueta: el reset le da a un `<h1>` sin clase de tipografía el mismo tamaño y peso que el texto que lo rodea. Así la estructura del documento, qué nivel de encabezado es un elemento, queda separada del tamaño con el que quieres que se vea. Si quieres que los encabezados reciban estilo automáticamente, consulta [Configuración inicial → HTML sin clases](./setup.md#html-sin-clases).
|
|
39
|
+
|
|
40
|
+
## Maquetar la página
|
|
41
|
+
|
|
42
|
+
Tres helpers de layout cubren la mayoría de las pantallas, y los tres usan la misma separación, `--layout-gap` (1rem):
|
|
43
|
+
|
|
44
|
+
- `.stack` para listas verticales de bloques.
|
|
45
|
+
- `.cluster` para una fila que salta de línea cuando se queda sin espacio, como un grupo de botones. Añade `.between` para llevar el primer y el último elemento a extremos opuestos.
|
|
46
|
+
- `.auto-grid` para una cuadrícula de tarjetas iguales que añade o quita columnas según cambia el espacio. Una columna nunca es más estrecha que `--layout-grid-min` (16rem), salvo que lo sea el propio contenedor.
|
|
47
|
+
|
|
48
|
+
`.tight` (0.5rem) y `.loose` (1.5rem) cambian la separación del layout en el que están. Un layout anidado dentro conserva su propia separación.
|
|
49
|
+
|
|
50
|
+
Añade un encabezado y pon los botones en una fila:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<main class="section">
|
|
54
|
+
<div class="section-content narrow stack loose">
|
|
55
|
+
<header class="stack tight">
|
|
56
|
+
<h1 class="text-title">Account settings</h1>
|
|
57
|
+
<p>Manage your profile, plan, and security.</p>
|
|
58
|
+
</header>
|
|
59
|
+
|
|
60
|
+
<section class="card stack" aria-labelledby="profile-title">
|
|
61
|
+
<h2 class="text-title-sm" id="profile-title">Profile</h2>
|
|
62
|
+
<p>Your name appears on invoices and shared projects.</p>
|
|
63
|
+
<div class="cluster">
|
|
64
|
+
<button class="btn primary" type="button">Save changes</button>
|
|
65
|
+
<button class="btn ghost" type="button">Cancel</button>
|
|
66
|
+
</div>
|
|
67
|
+
</section>
|
|
68
|
+
</div>
|
|
69
|
+
</main>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
[Contenido y layout](./usage/content-and-layout.md) enumera todos los helpers de layout, incluidos `.view`, `.divider` y `.visually-hidden`, y la escala tipográfica completa.
|
|
73
|
+
|
|
74
|
+
## Intención: qué color
|
|
75
|
+
|
|
76
|
+
El botón Guardar es `.primary` y el botón Cancelar no tiene intención, lo que lo hace neutro. Una clase de intención elige un rol de color:
|
|
77
|
+
|
|
78
|
+
| Clase | Úsala para | Color por defecto |
|
|
79
|
+
| -------------- | ---------------------------------------- | ------------------------------------------- |
|
|
80
|
+
| _ninguna_ | Cualquier cosa sin un significado propio | Los grises de texto y de borde de la página |
|
|
81
|
+
| `.primary` | La acción principal de una pantalla | Casi negro en claro, casi blanco en oscuro |
|
|
82
|
+
| `.secondary` | Una segunda acción, más discreta | Gris medio |
|
|
83
|
+
| `.success` | Confirmaciones y estados completados | Verde esmeralda |
|
|
84
|
+
| `.warning` | Algo que pronto necesita atención | Ámbar, con texto oscuro |
|
|
85
|
+
| `.destructive` | Eliminar, revocar y errores | Rojo rosado |
|
|
86
|
+
| `.info` | Avisos neutros y ayuda | Índigo |
|
|
87
|
+
|
|
88
|
+
La intención se queda en el elemento que la lleva. Poner `.destructive` en una `<section>` no vuelve rojos todos los botones de dentro; la escribes en cada botón. Es deliberado: un contenedor que cambiara en silencio el color de todo lo que contiene también volvería rojo el botón Cancelar de una zona de peligro roja.
|
|
89
|
+
|
|
90
|
+
`.neutral` nombra explícitamente el valor por defecto. Rara vez lo necesitas, porque no poner ninguna clase de intención ya significa neutro; importa donde el color vendría de otra parte, como en una fila de tabla, que hereda la intención de su tabla.
|
|
91
|
+
|
|
92
|
+
## Presentación: cuánto color
|
|
93
|
+
|
|
94
|
+
El botón Cancelar es `.ghost`: sin relleno, solo texto de color, así que se percibe como menos importante que Guardar. Ese es el eje de presentación, dos decisiones independientes:
|
|
95
|
+
|
|
96
|
+
- **Relleno:** `.solid` rellena el componente con el color de su intención y cambia el texto al color de contraste. `.soft` mezcla un tinte claro del 12% y mantiene el texto en el color de la intención. `.ghost` no tiene relleno en reposo.
|
|
97
|
+
- **Borde:** `.edged` dibuja un borde en el color de la intención; `.edgeless` no dibuja ninguno.
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<button class="btn primary">Save changes</button>
|
|
101
|
+
<button class="btn primary soft">Preview</button>
|
|
102
|
+
<button class="btn primary ghost edged">Export data</button>
|
|
103
|
+
<button class="btn ghost">Cancel</button>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Cada componente tiene su propio valor por defecto cuando no se aplica ninguna clase de presentación. Un botón es sólido y sin borde. Una tarjeta no tiene relleno y tiene borde. Un campo de formulario no tiene relleno y tiene borde. [Composición](./usage/composing.md#valores-por-defecto-de-los-componentes) enumera el valor por defecto de cada componente.
|
|
107
|
+
|
|
108
|
+
A diferencia de la intención, la presentación se hereda. Un `.soft` en un contenedor vuelve soft todo lo que hay dentro salvo que un elemento diga otra cosa, y una clase en el propio elemento siempre gana a una heredada de un contenedor:
|
|
109
|
+
|
|
110
|
+
```html
|
|
111
|
+
<div class="cluster soft">
|
|
112
|
+
<button class="btn primary">Soft primary</button>
|
|
113
|
+
<button class="btn success">Soft success</button>
|
|
114
|
+
<button class="btn primary solid">Solid: its own class wins</button>
|
|
115
|
+
</div>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Algunos componentes limitan lo que puede hacer la presentación, para proteger algo que necesitan. Un campo de formulario que hereda un contenedor `.solid` se rellena solo hasta el 6%, para que el texto escrito siga siendo legible. Un checkbox siempre conserva su borde, porque el borde es lo único que muestra una casilla sin marcar. Estos límites aparecen con cada componente y están reunidos en [Composición](./usage/composing.md).
|
|
119
|
+
|
|
120
|
+
## Terminar la primera pantalla
|
|
121
|
+
|
|
122
|
+
Añade un resumen del plan junto a una tarjeta de uso en una cuadrícula, y dale al resumen un tinte primario soft para que destaque como el estado actual de la cuenta:
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<main class="section">
|
|
126
|
+
<div class="section-content narrow stack loose">
|
|
127
|
+
<header class="stack tight">
|
|
128
|
+
<h1 class="text-title">Account settings</h1>
|
|
129
|
+
<p>Manage your profile, plan, and security.</p>
|
|
130
|
+
</header>
|
|
131
|
+
|
|
132
|
+
<section class="card stack" aria-labelledby="profile-title">
|
|
133
|
+
<h2 class="text-title-sm" id="profile-title">Profile</h2>
|
|
134
|
+
<p>Your name appears on invoices and shared projects.</p>
|
|
135
|
+
<div class="cluster">
|
|
136
|
+
<button class="btn primary" type="button">Save changes</button>
|
|
137
|
+
<button class="btn ghost" type="button">Cancel</button>
|
|
138
|
+
</div>
|
|
139
|
+
</section>
|
|
140
|
+
|
|
141
|
+
<div class="auto-grid">
|
|
142
|
+
<section class="card soft primary stack tight" aria-labelledby="plan-title">
|
|
143
|
+
<h2 class="text-label" id="plan-title">Current plan</h2>
|
|
144
|
+
<p class="text-title-sm">Team, billed yearly</p>
|
|
145
|
+
<p class="text-body">Renews on 12 March 2027.</p>
|
|
146
|
+
</section>
|
|
147
|
+
<section class="card stack tight" aria-labelledby="usage-title">
|
|
148
|
+
<h2 class="text-label" id="usage-title">Storage</h2>
|
|
149
|
+
<p class="text-title-sm">48 GB of 100 GB</p>
|
|
150
|
+
<p class="text-body">Shared by 6 members.</p>
|
|
151
|
+
</section>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</main>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
En una ventana ancha las dos tarjetas quedan una al lado de la otra; cuando la columna es demasiado estrecha para dos columnas de 16rem más la separación entre ellas, se apilan. La página de [Feedback](./usage/feedback.md) convierte el número de la tarjeta de almacenamiento en una barra de uso.
|
|
158
|
+
|
|
159
|
+
Una `.card` reposa a una unidad de profundidad, pero en el aspecto base esa profundidad no tiene sombra visible; aparece cuando una estética la dibuja o cuando añades `.raised` o `.floating`. [Composición → Elevación](./usage/composing.md#elevación) explica la profundidad.
|
|
160
|
+
|
|
161
|
+
## Estética: de qué está hecho
|
|
162
|
+
|
|
163
|
+
El tercer eje cambia el material de todo lo que contiene: esquinas, grosor del borde, sombras y a veces la fuente. Necesita su propio import (consulta [Configuración inicial → Añadir una estética](./setup.md#añadir-una-estética-opcional)):
|
|
164
|
+
|
|
165
|
+
```html
|
|
166
|
+
<main class="section neobrutalism">
|
|
167
|
+
<!-- La misma pantalla de ajustes: esquinas rectas, líneas gruesas y oscuras, sombras duras desplazadas -->
|
|
168
|
+
</main>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Como la presentación, una estética se hereda, y un componente dentro de ella puede llevar otra distinta. No la necesitas para construir la pantalla; [Estéticas](./usage/aesthetics.md) compara las seis.
|
|
172
|
+
|
|
173
|
+
## Vocabulario de esta documentación
|
|
174
|
+
|
|
175
|
+
Algunas páginas describen cómo se pinta un componente. Estas palabras tienen un único significado cada una:
|
|
176
|
+
|
|
177
|
+
| Palabra | Significado |
|
|
178
|
+
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
179
|
+
| Relleno | Cuánto del color de la intención cubre el componente, del 0% (`.ghost`) al 100% (`.solid`). |
|
|
180
|
+
| Tope | El relleno máximo que permite un componente. Por ejemplo, un campo de formulario limita un relleno heredado al 6%. |
|
|
181
|
+
| Placa | La superficie pintada del componente: el relleno, mezclado sobre el fondo. |
|
|
182
|
+
| Fondo | El color sobre el que se mezcla el relleno. Normalmente se ve la propia página a través; unos pocos componentes definen la suya, como el tinte claro de la intención bajo `.kbd` y `.code`. |
|
|
183
|
+
| Borde | El contorno del componente. Es distinto de las líneas divisorias, las líneas dentro de una tabla. |
|
|
184
|
+
| Tinta | Un color que se usa para dibujar líneas: el borde, las líneas divisorias de una tabla, la marca de un checkbox. "Tinta de texto" es el color del texto impreso sobre una placa. |
|
|
185
|
+
| Material | Lo que cambia una estética: radio y forma de las esquinas, grosor y estilo del borde, sombra y transparencia. |
|
|
186
|
+
| Losa | Una sombra dura, sin desenfoque, desplazada hacia abajo y hacia un lado, como la que dibujan `.neobrutalism` y `.chunky-tile`. |
|
|
187
|
+
| Elevación | Cuánta de la sombra disponible toma un elemento: ninguna (`.flat`), una unidad (`.raised`) o dos (`.floating`). |
|
|
188
|
+
|
|
189
|
+
## Los tokens detrás de las clases
|
|
190
|
+
|
|
191
|
+
Cada clase lee custom properties de CSS, llamadas tokens, así que puedes cambiar el resultado sin reescribir una clase:
|
|
192
|
+
|
|
193
|
+
| Tipo | Controla | Dónde se enumeran |
|
|
194
|
+
| ------------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
195
|
+
| Color | La paleta: colores de intención, texto, bordes y fondos, para claro y oscuro. | [Temas → Tokens de color](./usage/theming.md#tokens-de-color) |
|
|
196
|
+
| Base | Anchos y separaciones del layout, radios de esquina, altura de los controles, foco, movimiento. | [Temas → Tokens base](./usage/theming.md#tokens-base) |
|
|
197
|
+
| Intención | Los huecos de color que lee un componente después de que una clase de intención elige un rol. | [Temas → Tokens de intención](./usage/theming.md#tokens-de-intención) |
|
|
198
|
+
| Presentación | Los porcentajes de relleno y de borde que definen las clases de presentación. | [Personalización → Tokens de presentación](./usage/customizing.md#tokens-de-presentación) |
|
|
199
|
+
| Material | Radio, grosor del borde, geometría de la sombra y transparencia. | [Personalización → Tokens de material](./usage/customizing.md#tokens-de-material) |
|
|
200
|
+
| Estética | Un control por estética, como `--pixel-unit` o `--tile-lift`. | [Personalización → Tokens de estética](./usage/customizing.md#tokens-de-estética) |
|
|
201
|
+
|
|
202
|
+
Los tokens de color y los tokens base son lo que la mayoría de las aplicaciones cambia primero, para ajustarse a una marca. El resto es de más bajo nivel: los componentes los leen, y las clases de presentación y de estética los definen por ti.
|
|
203
|
+
|
|
204
|
+
## Límites que conviene conocer ya
|
|
205
|
+
|
|
206
|
+
- **La intención no se hereda.** Escríbela en cada elemento que la muestre. La única excepción son las filas de tabla.
|
|
207
|
+
- **Las clases solo dan estilo.** `<div class="btn">` parece un botón, pero no puede recibir el foco ni pulsarse con el teclado. Usa `<button>` o `<a href>`, y consulta [Accesibilidad](./accessibility.md).
|
|
208
|
+
- **Una combinación que la documentación no describe no está soportada.** Puede que se renderice, pero puede cambiar en cualquier versión; consulta [Introducción → Qué se considera soportado](./index.md#qué-se-considera-soportado).
|
|
209
|
+
|
|
210
|
+
## Siguiente paso
|
|
211
|
+
|
|
212
|
+
La pantalla tiene una acción principal y una discreta. [Botones](./usage/buttons.md) añade el resto: una acción destructiva para la zona de peligro, botones de icono, tamaños y estados deshabilitados.
|
package/docs/es/index.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Introducción
|
|
3
|
+
description: Para qué sirve @codenhub/styles, qué cuesta y en qué orden leer esta documentación.
|
|
4
|
+
source: 238cac2f0ca6132818c99d938219a6c537bc837a
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# @codenhub/styles
|
|
8
|
+
|
|
9
|
+
`@codenhub/styles` te permite construir una interfaz coherente y con temas escribiendo nombres de clase sobre HTML normal. Importas una hoja de estilos y obtienes tokens, un reset, helpers de layout y de tipografía, y clases para botones, campos de formulario, alertas, tarjetas, tablas y tooltips. No hay JavaScript que cargar ni una librería de componentes que envolver: un `<button class="btn primary">` es toda la integración.
|
|
10
|
+
|
|
11
|
+
Esta documentación construye una pequeña pantalla de principio a fin: una página de ajustes de cuenta con un formulario de perfil, un resumen del plan y una zona de peligro. Cada página le añade algo, así que al final habrás visto todas las partes del paquete trabajando juntas en lugar de por separado.
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<main class="section">
|
|
15
|
+
<div class="section-content narrow stack">
|
|
16
|
+
<h1 class="text-title">Account settings</h1>
|
|
17
|
+
<form class="card stack">
|
|
18
|
+
<h2 class="text-title-sm">Profile</h2>
|
|
19
|
+
<div class="field">
|
|
20
|
+
<label class="label" for="display-name">Display name</label>
|
|
21
|
+
<input class="ipt" id="display-name" name="display-name" value="Ada Lovelace" />
|
|
22
|
+
</div>
|
|
23
|
+
<div class="cluster">
|
|
24
|
+
<button class="btn primary" type="submit">Save changes</button>
|
|
25
|
+
<button class="btn ghost" type="reset">Cancel</button>
|
|
26
|
+
</div>
|
|
27
|
+
</form>
|
|
28
|
+
</div>
|
|
29
|
+
</main>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tres decisiones por componente
|
|
33
|
+
|
|
34
|
+
Cada componente responde con clases a tres preguntas independientes, así que un aspecto nuevo nunca necesita una nueva variante del componente:
|
|
35
|
+
|
|
36
|
+
- **Intención: ¿qué color?** `.primary`, `.secondary`, `.success`, `.warning`, `.destructive` o `.info`. Si no pones ninguna, es neutro.
|
|
37
|
+
- **Presentación: ¿cuánto de ese color?** `.solid`, `.soft` o `.ghost` definen el relleno; `.edged` o `.edgeless` definen el borde.
|
|
38
|
+
- **Estética: ¿de qué está hecho?** Una clase opcional, como `.neobrutalism` o `.glass`, cambia las esquinas, el grosor del borde, las sombras y la tipografía de todo lo que contiene.
|
|
39
|
+
|
|
40
|
+
`<button class="btn destructive ghost edged">Delete account</button>` es un botón rojo con contorno, y envolver la página en `.pixel` lo convierte en uno de pixel art sin tocar el botón. [Construir una pantalla](./concepts.md) presenta cada eje a medida que la página de ajustes lo necesita.
|
|
41
|
+
|
|
42
|
+
## CSS compilado o código fuente de Tailwind
|
|
43
|
+
|
|
44
|
+
El paquete ofrece las mismas clases de dos formas:
|
|
45
|
+
|
|
46
|
+
- **CSS compilado**, listo para usar. Impórtalo desde cualquier bundler o enlaza el archivo desde un CDN. No necesitas Tailwind.
|
|
47
|
+
- **Código fuente de Tailwind CSS v4**, en `@codenhub/styles/tw`. Úsalo cuando tu proyecto ya usa Tailwind v4, para que tu build compile el paquete junto con tus propias utilidades y tu tema.
|
|
48
|
+
|
|
49
|
+
[Configuración inicial](./setup.md) te ayuda a elegir.
|
|
50
|
+
|
|
51
|
+
## Lo que no hace
|
|
52
|
+
|
|
53
|
+
- **Sin JavaScript.** No hay runtime, ni bindings para frameworks, ni código generado. Todo lo que necesite un script, como abrir un diálogo, cambiar de tema o cerrar un tooltip, es código tuyo.
|
|
54
|
+
- **Sin semántica ni comportamiento.** Las clases pintan elementos; no añaden semántica HTML, ARIA, manejo del teclado, gestión del foco, validación ni anuncios. [Accesibilidad](./accessibility.md) marca el límite exacto.
|
|
55
|
+
- **Sin cambio de tema.** Elegir claro u oscuro es una clase o un atributo que pones tú. El paquete independiente `@codenhub/theme` puede recordar y aplicar esa elección por ti.
|
|
56
|
+
- **Sin fuentes ni iconos.** No se descarga ningún archivo de fuente. Las estéticas que quieren una fuente especial usan una fuente del sistema hasta que tú aportes una. Los iconos, incluidos los spinners de carga, vienen de tu propio conjunto de iconos, como `@codenhub/icons`.
|
|
57
|
+
- **Sin alias de compatibilidad.** Una clase o un token eliminado aparece en el changelog, no se conserva con su nombre antiguo.
|
|
58
|
+
|
|
59
|
+
## Contrapartidas
|
|
60
|
+
|
|
61
|
+
Conoce estos costes antes de adoptarlo:
|
|
62
|
+
|
|
63
|
+
- **Los nombres de clase son cortos y no llevan prefijo.** `.primary`, `.success`, `.dark`, `.label`, `.field`, `.section`, `.stack`, `.flat` y `.ghost` son nombres globales. Otra hoja de estilos en la misma página que los use choca con esta. El paquete está en [capas de cascada](./setup.md#capas-de-cascada), así que tu propio CSS sin capa gana en caso de choque, pero las reglas de una librería de terceros para el mismo nombre se siguen aplicando junto a las del paquete.
|
|
64
|
+
- **Las hojas de estilos completas son grandes antes de comprimir.** En el momento de escribir esto, minificada, la hoja de estilos completa ocupa unos 410 KB, `/native` unos 575 KB y `/components` unos 320 KB. Servidas con gzip ocupan unos 19 KB, 25 KB y 15 KB. Los archivos específicos son mucho más pequeños: `/theme` ocupa unos 10 KB (2 KB con gzip) y una estética, de 4 a 21 KB (de 1 a 2 KB con gzip). La mayor parte del tamaño es composición que cada componente repite, y por eso la compresión elimina tanto. Importa el punto de entrada más reducido que cubra una página; consulta [Configuración inicial → Todos los puntos de entrada](./setup.md#todos-los-puntos-de-entrada).
|
|
65
|
+
- **`--color-foreground` es un fondo, no un color de texto.** Es el tono un paso por encima de la página sobre el que se apoya una tarjeta o un panel discreto. El color de texto es `--color-text`.
|
|
66
|
+
- **Cuatro colores de hover son valores fijos.** `--color-success-hover`, `--color-warning-hover`, `--color-destructive-hover` y `--color-info-hover` están precalculados, porque mezclarlos en vivo hacía fallar WebKit. Si sobrescribes solo `--color-success`, su hover conserva el tono anterior, así que reemplaza la familia completa; consulta [Temas → Tokens de color](./usage/theming.md#tokens-de-color).
|
|
67
|
+
- **Solo navegadores modernos.** Chrome 123, Safari 17.5 o Firefox 128 y posteriores. No hay una capa de respaldo para navegadores antiguos.
|
|
68
|
+
|
|
69
|
+
## Qué se considera soportado
|
|
70
|
+
|
|
71
|
+
Una combinación de clases está soportada cuando esta documentación la describe y la demo pública en [demo.codenhub.dev/styles](https://demo.codenhub.dev/styles/) la muestra. La demo renderiza los fixtures de prueba del paquete, incluidas las matrices completas de intención, presentación y estética, con el CSS compilado. Una combinación que ni está documentada ni aparece en la demo puede seguir produciendo CSS, pero no se mantiene y puede cambiar en cualquier versión.
|
|
72
|
+
|
|
73
|
+
La demo se reconstruye desde la rama principal, no desde cada versión. Puede mostrar trabajo que todavía no se ha publicado, así que, cuando la demo y esta documentación no coinciden sobre una versión publicada, mandan la documentación y el [changelog](../changelog/index.md) de esa versión.
|
|
74
|
+
|
|
75
|
+
## Versionado
|
|
76
|
+
|
|
77
|
+
El paquete está por debajo de 1.0 y sigue la [regla del versionado semántico para las versiones 0.x](https://semver.org/#spec-item-4): la superficie pública todavía puede cambiar entre versiones menores.
|
|
78
|
+
|
|
79
|
+
- Una versión menor, como de 0.7.0 a 0.8.0, puede romper la compatibilidad. Puede renombrar o eliminar una clase o un token, o cambiar un valor por defecto. Cada cambio incompatible aparece en **Changed** o **Removed** en la página del [changelog](../changelog/index.md) de esa versión, con lo que debes usar en su lugar.
|
|
80
|
+
- Una versión de parche, como de 0.7.0 a 0.7.1, nunca rompe la compatibilidad.
|
|
81
|
+
|
|
82
|
+
El rango por defecto de npm para una nueva dependencia, `^0.7.0`, ya acepta solo parches, porque por debajo de 1.0 un rango con caret no pasa a la siguiente versión menor. Lee el changelog antes de subirlo. Cuando enlaces un archivo desde un CDN, pon la versión exacta en la URL; consulta [Sin bundler](./integrating/without-a-bundler.md).
|
|
83
|
+
|
|
84
|
+
Los cambios incompatibles no se suavizan con alias porque el modelo todavía se está asentando, y mantener cada nombre antiguo junto a su reemplazo haría crecer la superficie en cada versión. Un cambio de nombre o una eliminación suele costar un buscar y reemplazar al actualizar; un valor por defecto que cambia puede requerir que reajustes tu propio CSS.
|
|
85
|
+
|
|
86
|
+
## Orden de lectura
|
|
87
|
+
|
|
88
|
+
La primera vez, léelas en orden. Cada página añade algo a la pantalla de ajustes y termina indicando la siguiente.
|
|
89
|
+
|
|
90
|
+
1. [Configuración inicial](./setup.md): instala el paquete, elige entre CSS compilado o código fuente de Tailwind y renderiza la estructura vacía de la página.
|
|
91
|
+
2. [Integración](./integrating/index.md): solo si usas Next.js, Vue, Svelte, Astro, Tailwind v4 o ningún bundler. Cada guía te devuelve al camino principal.
|
|
92
|
+
3. [Construir una pantalla](./concepts.md): maqueta la página, define su tipografía y añade una tarjeta y un botón Guardar, aprendiendo por el camino la intención, el relleno y el borde.
|
|
93
|
+
4. [Uso](./usage/index.md): el resto de la pantalla, en orden:
|
|
94
|
+
- [Botones](./usage/buttons.md): acciones secundarias y destructivas, tamaños, botones de icono y estados deshabilitados.
|
|
95
|
+
- [Formularios](./usage/forms.md): campos con etiqueta, pistas, errores, iconos, selects, checkboxes, radios y switches.
|
|
96
|
+
- [Feedback](./usage/feedback.md): un estado de guardado, una alerta de éxito, un badge del plan, un placeholder de carga y una barra de uso.
|
|
97
|
+
- [Tooltips](./usage/tooltips.md): ayuda de campo que funciona con ratón, con teclado y con lector de pantalla.
|
|
98
|
+
- [Temas](./usage/theming.md): modo claro y oscuro, colores de marca y tus propias intenciones.
|
|
99
|
+
- [Estéticas](./usage/aesthetics.md): cambia el estilo de toda la pantalla con una sola clase.
|
|
100
|
+
- [Clases solo](./usage/solo.md): pinta una estética sobre un componente al que este paquete no da estilo.
|
|
101
|
+
- [Composición](./usage/composing.md), [Personalización](./usage/customizing.md) y [Contenido y layout](./usage/content-and-layout.md): páginas de consulta con cada regla de eje, token, valor por defecto y clase helper.
|
|
102
|
+
5. [Accesibilidad](./accessibility.md): lo que el CSS resuelve por ti y lo que tu aplicación todavía debe hacer.
|
|
103
|
+
|
|
104
|
+
El [changelog](../changelog/index.md) enumera cada versión y lo que cambió en ella.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Astro
|
|
3
|
+
description: Cargar la hoja de estilos en una aplicación Astro.
|
|
4
|
+
order: 5
|
|
5
|
+
source: 4f93b3a6e0d1cd24a0b7d0eb6050cc98690cd598
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Astro
|
|
9
|
+
|
|
10
|
+
Astro renderiza los componentes de forma estática por defecto, pero el import de una hoja de estilos global sigue necesitando hacerse una sola vez: desde un layout compartido, no desde páginas o islas individuales.
|
|
11
|
+
|
|
12
|
+
## Importar la hoja de estilos
|
|
13
|
+
|
|
14
|
+
```astro
|
|
15
|
+
---
|
|
16
|
+
// src/layouts/Layout.astro
|
|
17
|
+
import "@codenhub/styles";
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
<html lang="en">
|
|
21
|
+
<body>
|
|
22
|
+
<slot />
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Cada página que usa este layout carga la hoja de estilos una vez. ¿Usas Tailwind CSS v4? Importa en su lugar `@codenhub/styles/tw` a través de la integración de Tailwind para Astro; consulta [Tailwind CSS v4](./tailwind.md), incluido cuándo hace falta realmente un `@source` explícito.
|
|
28
|
+
|
|
29
|
+
## Forzar un tema
|
|
30
|
+
|
|
31
|
+
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).
|
|
32
|
+
|
|
33
|
+
## Siguiente paso
|
|
34
|
+
|
|
35
|
+
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,47 @@
|
|
|
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: f2ccb27bbdbe15278726278864c01a586505eb16
|
|
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, Django o cualquier aplicación sin paso de build de CSS | [Sin bundler](./without-a-bundler.md) |
|
|
32
|
+
|
|
33
|
+
Un proyecto sin framework, un build simple con Vite, webpack o Parcel, no necesita nada más allá de [Configuración inicial → Importar la hoja de estilos](../setup.md#importar-la-hoja-de-estilos): importa la hoja de estilos compilada desde la entrada CSS global que el proyecto ya tiene.
|
|
34
|
+
|
|
35
|
+
## Comprobar que funciona
|
|
36
|
+
|
|
37
|
+
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:
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<button class="btn primary">Save changes</button>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
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.
|
|
44
|
+
|
|
45
|
+
## Siguiente paso
|
|
46
|
+
|
|
47
|
+
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,78 @@
|
|
|
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: 7988dc023c91950991a720ea7da7edfe3378d4d7
|
|
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 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 `dist/tw`; 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: `/tw` ya incluye todas las definiciones de clase que publica, así que escanearlo también solo ralentiza el build sin añadir clases.
|
|
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
|
+
## Solución de problemas
|
|
51
|
+
|
|
52
|
+
**Las clases no producen ningún estilo**
|
|
53
|
+
|
|
54
|
+
- **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.
|
|
55
|
+
- **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.
|
|
56
|
+
- **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).
|
|
57
|
+
|
|
58
|
+
**Reglas de tokens y de reset duplicadas**
|
|
59
|
+
|
|
60
|
+
- **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.
|
|
61
|
+
- **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.
|
|
62
|
+
- **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`.
|
|
63
|
+
|
|
64
|
+
**Una clase construida en tiempo de ejecución no tiene estilo**
|
|
65
|
+
|
|
66
|
+
- **Qué ha pasado:** `<button class="btn primary">` tiene estilo, pero un botón cuya intención viene de una variable, como `` `btn ${tone}` ``, no.
|
|
67
|
+
- **Por qué:** Tailwind genera una clase solo cuando encuentra el nombre completo en tus archivos fuente. Las clases de componente y de eje del propio paquete se generan siempre, pero tus propias utilidades no, y un nombre armado a partir de strings es invisible para el escaneo.
|
|
68
|
+
- **Solución:** escribe nombres de clase completos en tu código, por ejemplo en un objeto de consulta (`{ save: "btn primary", remove: "btn destructive" }`), o enumera los nombres que tu código puede producir con `@source inline("...")` en tu hoja de estilos.
|
|
69
|
+
|
|
70
|
+
Todos los puntos de entrada `/tw` requieren Tailwind CSS 4.3.2 o posterior, por debajo de 5: el código fuente usa `@source not` y `@source inline()`, que llegaron en la 4.1, y se prueba con la 4.3.2.
|
|
71
|
+
|
|
72
|
+
## La variante `dark:`
|
|
73
|
+
|
|
74
|
+
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).
|
|
75
|
+
|
|
76
|
+
## Siguiente paso
|
|
77
|
+
|
|
78
|
+
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.
|