@codenhub/styles 0.7.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/README.es.md +8 -7
- package/README.md +7 -6
- package/README.pt-BR.md +8 -7
- 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/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 +46 -27
- package/docs/changelog/0.8.0.md +70 -0
- package/docs/changelog/index.md +1 -0
- package/docs/es/accessibility.md +47 -28
- package/docs/es/index.md +3 -2
- package/docs/es/integrating/index.md +38 -10
- package/docs/es/integrating/tailwind.md +78 -8
- package/docs/es/integrating/without-a-bundler.md +128 -5
- package/docs/es/setup.md +42 -34
- package/docs/es/usage/aesthetics.md +19 -13
- package/docs/es/usage/buttons.md +6 -2
- package/docs/es/usage/composing.md +6 -2
- package/docs/es/usage/content-and-layout.md +8 -4
- package/docs/es/usage/customizing.md +19 -13
- package/docs/es/usage/feedback.md +5 -1
- package/docs/es/usage/forms.md +29 -4
- package/docs/es/usage/index.md +6 -2
- package/docs/es/usage/presets.md +92 -0
- package/docs/es/usage/solo.md +4 -2
- package/docs/es/usage/theming.md +28 -15
- package/docs/index.md +2 -1
- package/docs/integrating/index.md +38 -10
- package/docs/integrating/tailwind.md +77 -7
- package/docs/integrating/without-a-bundler.md +127 -4
- package/docs/pt-BR/accessibility.md +47 -28
- package/docs/pt-BR/index.md +3 -2
- package/docs/pt-BR/integrating/index.md +38 -10
- package/docs/pt-BR/integrating/tailwind.md +78 -8
- package/docs/pt-BR/integrating/without-a-bundler.md +128 -5
- package/docs/pt-BR/setup.md +42 -34
- package/docs/pt-BR/usage/aesthetics.md +19 -13
- package/docs/pt-BR/usage/buttons.md +6 -2
- package/docs/pt-BR/usage/composing.md +6 -2
- package/docs/pt-BR/usage/content-and-layout.md +8 -4
- package/docs/pt-BR/usage/customizing.md +19 -13
- package/docs/pt-BR/usage/feedback.md +5 -1
- package/docs/pt-BR/usage/forms.md +29 -4
- package/docs/pt-BR/usage/index.md +6 -2
- package/docs/pt-BR/usage/presets.md +92 -0
- package/docs/pt-BR/usage/solo.md +4 -2
- package/docs/pt-BR/usage/theming.md +21 -8
- package/docs/setup.md +30 -22
- package/docs/usage/aesthetics.md +18 -12
- package/docs/usage/buttons.md +5 -1
- package/docs/usage/composing.md +5 -1
- package/docs/usage/content-and-layout.md +7 -3
- package/docs/usage/customizing.md +18 -12
- package/docs/usage/feedback.md +4 -0
- package/docs/usage/forms.md +28 -3
- package/docs/usage/index.md +5 -1
- package/docs/usage/presets.md +91 -0
- package/docs/usage/solo.md +3 -1
- package/docs/usage/theming.md +20 -7
- package/llms-full.txt +592 -115
- package/package.json +113 -63
- package/{dist/tw → tw}/aesthetics/chunky-tile.css +39 -19
- package/{dist/tw → tw}/aesthetics/cyber.css +15 -24
- package/{dist/tw → tw}/aesthetics/glass.css +105 -36
- package/{dist/tw → tw}/aesthetics/neobrutalism.css +37 -20
- package/{dist/tw → tw}/aesthetics/sketch.css +152 -133
- package/{dist/tw → tw}/box.css +89 -12
- 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} +134 -30
- package/tw/components/form.css +11 -0
- package/{dist/tw/components/form.css → tw/components/form.rules.css} +524 -111
- 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 +11 -9
- 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} +7 -8
- 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 +92 -28
- package/tw/typography.css +8 -0
- package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
- package/{dist/tw → tw}/utilities/content.css +183 -63
- package/tw/utilities/index.css +11 -0
- package/tw/utilities/layout.css +208 -0
- package/tw/utilities/rules.css +8 -0
- package/dist/tw/components/button.css +0 -139
- package/dist/tw/components/index.css +0 -35
- package/dist/tw/components/surface.css +0 -184
- package/dist/tw/intent.css +0 -229
- 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 -144
- /package/{dist/tw → tw}/aesthetics/index.css +0 -0
- /package/{dist/tw → tw}/aesthetics/pixel.css +0 -0
package/docs/es/usage/forms.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: Formularios
|
|
3
3
|
description: Campos con etiqueta, pistas y errores, iconos y prefijos fijos, selects y toggles de checkbox, radio y switch.
|
|
4
4
|
order: 2
|
|
5
|
-
source:
|
|
5
|
+
source: 00e6a57cfd62f524fde5a550af721786edd7a5dd
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Formularios
|
|
@@ -28,6 +28,25 @@ Un campo es una etiqueta, un control y una pista opcional, apilados:
|
|
|
28
28
|
|
|
29
29
|
Un control de texto mide al menos 2.5rem de alto (`--control-height`), la misma altura que un botón por defecto, así que un campo y un botón quedan alineados en una fila. Su aspecto por defecto es sin relleno y con borde. Un `.textarea` mide al menos 7rem de alto y se puede redimensionar en vertical.
|
|
30
30
|
|
|
31
|
+
### Tamaños
|
|
32
|
+
|
|
33
|
+
`.ipt`, `.select`, `.textarea` e `.input-group` aceptan las clases de tamaño del botón, así que un campo pequeño y un botón pequeño quedan alineados en una fila:
|
|
34
|
+
|
|
35
|
+
| Clase | Altura | Relleno lateral | Texto |
|
|
36
|
+
| ----------- | ------ | --------------- | --------- |
|
|
37
|
+
| `.sm` | 2rem | 0.625rem | 0.875rem |
|
|
38
|
+
| por defecto | 2.5rem | 0.75rem | heredado |
|
|
39
|
+
| `.lg` | 3rem | 1rem | 1.0625rem |
|
|
40
|
+
|
|
41
|
+
Las esquinas escalan con el tamaño, como las de un botón. Un `.textarea` conserva su altura mínima de 7rem en todos los tamaños; la clase cambia su texto, su relleno y sus esquinas. Define el tamaño de un `.input-group` en el grupo, no en el control de dentro: el control y sus adornos toman el tamaño de texto del grupo.
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<div class="cluster tight">
|
|
45
|
+
<input class="ipt sm" aria-label="Coupon code" />
|
|
46
|
+
<button class="btn sm" type="button">Apply</button>
|
|
47
|
+
</div>
|
|
48
|
+
```
|
|
49
|
+
|
|
31
50
|
## Mostrar un error de validación
|
|
32
51
|
|
|
33
52
|
Marca el control como inválido con `aria-invalid="true"` y dale al mensaje de error `.hint.destructive`:
|
|
@@ -40,7 +59,13 @@ Marca el control como inválido con `aria-invalid="true"` y dale al mensaje de e
|
|
|
40
59
|
</div>
|
|
41
60
|
```
|
|
42
61
|
|
|
43
|
-
Un control inválido dibuja su borde, su anillo de foco y el texto escrito en el color destructivo, tenga la clase de intención que tenga. El texto usa el tono legible de ese color, `--intent-strong`, para que siga siendo legible sobre la página. El paquete solo pinta el estado: decidir que el valor es inválido, poner y quitar `aria-invalid` y escribir el mensaje es cosa de tu código. Quita `aria-invalid` en cuanto el valor vuelva a ser válido; si lo dejas puesto, el campo sigue en rojo.
|
|
62
|
+
Un control inválido dibuja su borde, su anillo de foco y el texto escrito en el color destructivo, tenga la clase de intención que tenga. El texto usa el tono legible de ese color, `--intent-strong`, para que siga siendo legible sobre la página. El paquete solo pinta el estado: decidir que el valor es inválido, poner y quitar `aria-invalid` y escribir el mensaje es cosa de tu código. Quita `aria-invalid` en cuanto el valor vuelva a ser válido; si lo dejas puesto, el campo sigue en rojo. En un checkbox, un radio o un switch, `aria-invalid="true"` dibuja el toggle exactamente igual que `.destructive`, marca de activado incluida.
|
|
63
|
+
|
|
64
|
+
Un `.hint` acepta cualquiera de las seis intenciones incorporadas, no solo `.destructive`: `.hint.success` confirma que se aceptó un valor, y `.hint.warning` señala uno que está permitido pero es inusual. Cada uno se muestra en el tono legible de su intención, `--intent-strong`, que mantiene 4.5:1 frente a la página en los dos temas. Un `.hint` sin intención, con `.neutral` o con una [intención que definiste tú](./theming.md#tu-propia-intención), se queda en el color secundario. Solo lo colorea una clase en el propio `.hint`; una intención en el campo o en un contenedor que lo rodee no lo hace.
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<input class="ipt success" id="username" value="ada" aria-describedby="username-hint" /> <span class="hint success" id="username-hint">That username is available.</span>
|
|
68
|
+
```
|
|
44
69
|
|
|
45
70
|
## Montar el formulario de perfil
|
|
46
71
|
|
|
@@ -84,7 +109,7 @@ Un `.select` dibuja su propia flecha. Con `multiple` o con un `size` mayor que 1
|
|
|
84
109
|
|
|
85
110
|
## Añadir un icono o un prefijo fijo
|
|
86
111
|
|
|
87
|
-
`.input-group` pone un icono o un fragmento de texto dentro del borde de un campo. El grupo dibuja el borde, el fondo, el anillo de foco y los estados inválido y deshabilitado; el control de dentro renuncia a los suyos, así que el borde se dibuja una sola vez. Coloca el adorno antes del control para ponerlo al principio, o después para ponerlo al final.
|
|
112
|
+
`.input-group` pone un icono o un fragmento de texto dentro del borde de un campo. El grupo dibuja el borde, el fondo, el anillo de foco y los estados inválido y deshabilitado; el control de dentro renuncia a los suyos, así que el borde se dibuja una sola vez. Coloca el adorno antes del control para ponerlo al principio, o después para ponerlo al final. Un grupo mide lo mismo que un campo solo, así que queda alineado con los campos y los botones que tiene al lado.
|
|
88
113
|
|
|
89
114
|
La dirección del perfil siempre empieza con el mismo host, así que es un prefijo fijo:
|
|
90
115
|
|
|
@@ -116,7 +141,7 @@ Un `.select` también funciona en un grupo. El grupo quita el relleno lateral de
|
|
|
116
141
|
|
|
117
142
|
Cualquier elemento sirve como adorno: una clase de icono, un `<svg>` en línea, un `<img>` o texto. El paquete no incluye iconos para los campos, porque una imagen incorporada no podría seguir tu color de texto, tu tema ni tu estética.
|
|
118
143
|
|
|
119
|
-
El grupo lee la intención y la presentación igual que un `.ipt` solo: `.input-group.primary` colorea el borde, y `.input-group.soft.edgeless` es un campo hundido en la página. `aria-invalid="true"` o `disabled` en el control de dentro se aplica a todo el grupo, y lo mismo si cualquiera de los dos está en el propio grupo. El anillo de foco aparece cuando
|
|
144
|
+
El grupo lee la intención y la presentación igual que un `.ipt` solo: `.input-group.primary` colorea el borde y el texto escrito, y `.input-group.soft.edgeless` es un campo hundido en la página. Pon la intención en el grupo, no en el control de dentro: el grupo dibuja el campo, así que el texto del control toma la intención del grupo y una clase de intención en el control no tiene efecto. `aria-invalid="true"` o `disabled` en el control de dentro se aplica a todo el grupo, y lo mismo si cualquiera de los dos está en el propio grupo. El anillo de foco del grupo aparece cuando su campo tiene el foco, así que, a diferencia de un campo solo, también se muestra después de un clic con el ratón. Un botón dentro del grupo, como un botón para borrar, dibuja su propio anillo cuando tiene el foco, y el grupo no dibuja ninguno: un solo anillo marca siempre el único control que tiene el foco.
|
|
120
145
|
|
|
121
146
|
## Decoraciones del navegador
|
|
122
147
|
|
package/docs/es/usage/index.md
CHANGED
|
@@ -3,12 +3,12 @@ title: Visión general
|
|
|
3
3
|
description: Las guías que terminan la pantalla de ajustes y, después, las páginas de consulta con cada clase, token y valor por defecto.
|
|
4
4
|
group: Uso
|
|
5
5
|
order: 4
|
|
6
|
-
source:
|
|
6
|
+
source: ccdf1949cd4f7688574d6f4fae9ad2cf34465fb3
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Uso
|
|
10
10
|
|
|
11
|
-
Estas guías terminan la pantalla de ajustes que empezó en [Construir una pantalla](../concepts.md). Lee las siete primeras en orden: cada una añade una parte de la pantalla y da por hechas las anteriores. Las tres
|
|
11
|
+
Estas guías terminan la pantalla de ajustes que empezó en [Construir una pantalla](../concepts.md). Lee las siete primeras en orden: cada una añade una parte de la pantalla y da por hechas las anteriores. Las tres siguientes son páginas de consulta; las guías te enviarán a ellas cuando necesiten la tabla completa, y puedes volver siempre que necesites un valor por defecto o una regla. La última, Preajustes, es para cuando la pantalla ya funciona y te has cansado de escribir las mismas clases.
|
|
12
12
|
|
|
13
13
|
Guías, en orden:
|
|
14
14
|
|
|
@@ -26,4 +26,8 @@ Páginas de consulta:
|
|
|
26
26
|
- [Personalización](./customizing.md): tokens de presentación y de material, controles de las estéticas, las seis variables públicas de componente, la paleta generada y los helpers de composición para construir tus propios componentes.
|
|
27
27
|
- [Contenido y layout](./content-and-layout.md): todos los helpers de layout, la escala tipográfica, tarjetas y paneles, tablas, citas, código y teclas.
|
|
28
28
|
|
|
29
|
+
Cuando la pantalla funcione:
|
|
30
|
+
|
|
31
|
+
- [Preajustes](./presets.md): define un aspecto una sola vez, con clases de eje en un contenedor, tokens de tema y de material, o tus propias clases de componente hechas con `@apply`.
|
|
32
|
+
|
|
29
33
|
Cuando termines, [Accesibilidad](../accessibility.md) reúne lo que el CSS hace por ti y lo que tu aplicación todavía les debe a sus usuarios.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Preajustes
|
|
3
|
+
description: Tres formas de definir un aspecto una sola vez en lugar de en cada elemento, y cuándo recurrir a cada una.
|
|
4
|
+
order: 11
|
|
5
|
+
source: 308b21076223635a3323bcfecb70abe3a9e6d1c7
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Preajustes
|
|
9
|
+
|
|
10
|
+
A estas alturas, la pantalla de ajustes dice `btn primary soft sm` en una docena de sitios, y cambiar de opinión significa cambiar una docena de sitios. Esta página cubre las tres formas de definir un aspecto una sola vez: clases de eje en un contenedor, tokens de tema y de material, y tus propias clases de componente hechas con `@apply`. Cada una encaja con un tipo distinto de "una sola vez".
|
|
11
|
+
|
|
12
|
+
## Cuál usar
|
|
13
|
+
|
|
14
|
+
| Quieres | Recurre a |
|
|
15
|
+
| ------------------------------------------------------------------------------------ | --------------------------------------------------------------------- |
|
|
16
|
+
| Que todos los componentes de una región compartan un relleno, un borde o un material | [Clases de eje en un contenedor](#clases-de-eje-en-un-contenedor) |
|
|
17
|
+
| Otros colores, esquinas, bordes o profundidad para una página o una región | [Tokens de tema y de material](#tokens-de-tema-y-de-material) |
|
|
18
|
+
| Un nombre para una receta que repites, como "el botón de guardar" | [Tus propias clases de componente](#tus-propias-clases-de-componente) |
|
|
19
|
+
|
|
20
|
+
Se combinan. Una región puede definir un token de material, estar bajo una estética y contener tu propia clase de botón, y cada elemento puede seguir sobrescribiendo lo que hereda.
|
|
21
|
+
|
|
22
|
+
## Clases de eje en un contenedor
|
|
23
|
+
|
|
24
|
+
Algunas clases funcionan en un contenedor además de en un componente, y todo lo que hay dentro las toma:
|
|
25
|
+
|
|
26
|
+
- Las clases de presentación: `.solid`, `.soft`, `.ghost`, `.edged` y `.edgeless`.
|
|
27
|
+
- Los patrones de esquina: `.cut-diagonal` y `.cut-diagonal-reverse`.
|
|
28
|
+
- Las [estéticas](./aesthetics.md), como `.glass` o `.pixel`.
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<div class="cluster soft edged">
|
|
32
|
+
<button class="btn primary" type="button">Negrita</button>
|
|
33
|
+
<button class="btn" type="button">Cursiva</button>
|
|
34
|
+
<button class="btn destructive solid" type="button">Quitar formato</button>
|
|
35
|
+
</div>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Los botones de la barra son soft y con borde, y el último pide su propio relleno. Una clase en el elemento siempre gana a la de un contenedor.
|
|
39
|
+
|
|
40
|
+
Los demás ejes no se heredan. La intención, la elevación (`.flat`, `.raised`, `.floating`) y el tamaño (`.sm`, `.lg`) cambian solo el elemento en el que están, así que una barra `.sm` no encoge sus botones; [Composición → Combinar clases](./composing.md#combinar-clases) explica por qué. Una clase de estética también define su propio patrón de esquina en su región, así que un `.cut-diagonal` por encima de una región `.pixel` no llega a su interior.
|
|
41
|
+
|
|
42
|
+
Usa una clase de contenedor cuando el aspecto pertenece a la región, como una barra lateral discreta, y no a los componentes que contiene.
|
|
43
|
+
|
|
44
|
+
## Tokens de tema y de material
|
|
45
|
+
|
|
46
|
+
Los tokens son propiedades personalizadas de CSS. Defínelo en `:root` y toda la página lo sigue; defínelo en un elemento y solo lo sigue lo que hay dentro. Llegan más lejos que las clases, porque los componentes los leen al dibujarse:
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
.admin {
|
|
50
|
+
--radius-control: 0.25rem;
|
|
51
|
+
--radius-surface: 0.5rem;
|
|
52
|
+
--border-width: 2px;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Cada botón, campo, burbuja de tooltip y superficie dentro de `.admin` toma las esquinas más cerradas y el borde más grueso, sin una clase en ninguno de ellos. Las casillas de verificación, `.kbd` y `.code` mantienen su propia esquina más pequeña, `--radius-small`.
|
|
57
|
+
|
|
58
|
+
Las tablas están donde se explican los tokens, así que esta página no las repite:
|
|
59
|
+
|
|
60
|
+
- [Temas → Tokens de color](./theming.md#tokens-de-color): colores de marca y de estado, en los dos temas.
|
|
61
|
+
- [Temas → Tokens base](./theming.md#tokens-base): esquinas, grosor del borde, altura de los controles, anillo de foco, profundidad y movimiento.
|
|
62
|
+
- [Personalización → Tokens de presentación](./customizing.md#tokens-de-presentación): cuánto aportan un relleno, un borde o un hover.
|
|
63
|
+
- [Personalización → Tokens de material](./customizing.md#tokens-de-material): lo que define una estética, y que puedes definir tú, como `--ui-radius`.
|
|
64
|
+
- [Personalización → Tokens de estética](./customizing.md#tokens-de-estética): los controles de cada estética, como `--neo-offset`.
|
|
65
|
+
|
|
66
|
+
Usa tokens cuando el cambio es un valor, como un color o una esquina, y no una elección entre clases.
|
|
67
|
+
|
|
68
|
+
## Tus propias clases de componente
|
|
69
|
+
|
|
70
|
+
Con los puntos de entrada de código fuente de Tailwind, cada componente, helper y clase de eje es una utilidad de Tailwind, así que una clase tuya puede llevar la receta completa:
|
|
71
|
+
|
|
72
|
+
```css
|
|
73
|
+
@import "@codenhub/styles/tw";
|
|
74
|
+
|
|
75
|
+
@utility btn-save {
|
|
76
|
+
@apply btn primary soft sm;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<button class="btn-save" type="submit">Guardar cambios</button>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`btn-save` se comporta como `btn primary soft sm` escrito completo, con estéticas y hover incluidos, y cambiar la receta cambia todos los botones de guardar. Los modificadores que pertenecen a un componente, como `.tight` en `.stack` o `.icon` en `.btn`, también son utilidades, así que `@apply btn icon` te da un botón de icono propio. [Tailwind CSS v4 → Construir tus propios componentes con `@apply`](../integrating/tailwind.md#construir-tus-propios-componentes-con-apply) tiene las reglas, incluido por qué `@utility` es mejor que una regla simple.
|
|
85
|
+
|
|
86
|
+
Con el CSS compilado no hay `@apply`. Guarda la receta en un solo lugar del otro lado: un parcial de plantilla, un componente de tu framework o una constante como `const saveButton = "btn primary soft sm"`.
|
|
87
|
+
|
|
88
|
+
Usa tu propia clase cuando la misma combinación nombra una sola cosa de tu diseño, como el botón de guardar o la tarjeta de plan.
|
|
89
|
+
|
|
90
|
+
## Siguiente paso
|
|
91
|
+
|
|
92
|
+
[Accesibilidad](../accessibility.md) enumera lo que el CSS hace por tus usuarios y lo que tu aplicación todavía les debe.
|
package/docs/es/usage/solo.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: Clases solo
|
|
3
3
|
description: Cómo pintar una estética sobre un elemento de otra librería, como un toast o un diálogo, y qué lee e ignora una clase solo.
|
|
4
4
|
order: 7
|
|
5
|
-
source:
|
|
5
|
+
source: c44308a8768737292529d4f93b703b3fa200255a
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Clases solo
|
|
@@ -77,7 +77,9 @@ Sin ninguna de esas clases, una clase solo pinta solo el material (borde, esquin
|
|
|
77
77
|
## Cómo gana y cuándo se mueve
|
|
78
78
|
|
|
79
79
|
- **Gana a los estilos de la otra librería.** Las reglas no tienen capa y tienen un solo nivel de clase, así que ganan a las reglas con capa de un componente, y a las de especificidad cero, se carguen donde se carguen. Una regla ajena sin capa que sea más específica, o igual de específica y posterior en la página, sigue ganando. La otra cara es que una utilidad de Tailwind en el mismo elemento, como `rounded-none`, pierde frente a la clase solo: ajústalo mediante sus controles.
|
|
80
|
-
- **Solo pulsa una acción.** Neobrutalism, chunky tile y cyber pulsan un `button`, un `a[href]`, un `[role="button"]`, un `summary` o un `input` de tipo botón que no esté deshabilitado. Todo lo demás se queda quieto, así que un toast no se hunde al hacer clic.
|
|
80
|
+
- **Solo pulsa una acción.** Neobrutalism, chunky tile y cyber pulsan un `button`, un `a[href]`, un `[role="button"]`, un `summary` o un `input` de tipo botón que no esté deshabilitado. Todo lo demás se queda quieto, así que un toast no se hunde al hacer clic. La etiqueta más gruesa de chunky tile sigue la misma regla.
|
|
81
|
+
- **No toca el movimiento de un contenedor.** Solo una acción toma la `transition` de la pulsación, y la pulsación mueve el elemento mediante las propiedades `translate` y `scale`, no `transform`. Un toast conserva sus propias transiciones y su propio `transform`. En una acción, la `transition` de la pulsación reemplaza la que tuviera el elemento.
|
|
82
|
+
- **El movimiento reducido conserva la pulsación y quita su movimiento.** Con `prefers-reduced-motion: reduce`, neobrutalism, chunky tile y cyber siguen pulsando, pero al instante: el elemento cae en su sombra o su barra, o se encoge, sin recorrer la distancia.
|
|
81
83
|
|
|
82
84
|
## Siguiente paso
|
|
83
85
|
|
package/docs/es/usage/theming.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: Temas
|
|
3
3
|
description: Modo claro y oscuro, reemplazar la paleta con los colores de marca, definir una intención propia, y cada token de color, intención, base y fuente con su valor por defecto.
|
|
4
4
|
order: 5
|
|
5
|
-
source:
|
|
5
|
+
source: faefe01e9a435bd2630c846cc365f3c8783107df
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Temas
|
|
@@ -30,17 +30,26 @@ Una pantalla de ajustes con la opción "Sistema / Claro / Oscuro" quita el atrib
|
|
|
30
30
|
|
|
31
31
|
Cómo se resuelve:
|
|
32
32
|
|
|
33
|
-
- Un selector de tema define la propiedad CSS `color-scheme
|
|
34
|
-
- `color-scheme` se hereda, así que un selector aplica el tema a todo lo que contiene. Un selector en cualquier elemento aplica el tema a esa parte de la página: una barra lateral oscura en una página clara es `<aside class="dark"
|
|
33
|
+
- Un selector de tema define la propiedad CSS `color-scheme`, y el color del texto del elemento en `--color-text`. Cada token de color contiene a la vez su valor claro y su valor oscuro, mediante `light-dark()`, y el `color-scheme` del elemento elige uno.
|
|
34
|
+
- `color-scheme` se hereda, así que un selector aplica el tema a todo lo que contiene. Un selector en cualquier elemento aplica el tema a esa parte de la página: una barra lateral oscura en una página clara es `<aside class="dark">`, y el texto que contiene toma el color de texto del tema oscuro.
|
|
35
|
+
- Un selector no define ningún fondo. Dale tú el fondo a la zona, por ejemplo con `background: var(--color-background)`. Cualquier utilidad o clase de componente en el mismo elemento sobrescribe el color de texto del selector.
|
|
35
36
|
- Gana el selector más cercano, a cualquier profundidad. Una tarjeta `.light` dentro de una página `.dark` es clara.
|
|
36
37
|
- Sin selector, la raíz tiene `color-scheme: light dark`, que sigue al sistema.
|
|
37
38
|
- Pon un solo tema en cada elemento. Si un elemento lleva a la vez un selector claro y uno oscuro, gana el oscuro, pero no confíes en ello.
|
|
38
|
-
- Definir tú mismo `color-scheme` en un elemento
|
|
39
|
+
- Definir tú mismo `color-scheme` en un elemento aplica el tema a los tokens de la misma forma, porque es lo único que lee la paleta. También aplica el tema a partes nativas como las barras de desplazamiento y el interior de los controles de formulario. El texto simple de dentro conserva el color que heredó hasta que también defines `color: var(--color-text)`.
|
|
39
40
|
|
|
40
41
|
Cada color de componente viene de un token o de `currentColor`, así que los componentes siguen el tema sin reglas propias de modo oscuro. Las marcas que dibuja el paquete, como el tick del checkbox y la flecha del select, también usan `currentColor`. Los iconos y las imágenes que añadas son tuyos para adaptarlos al tema.
|
|
41
42
|
|
|
42
43
|
`light-dark()` funciona desde Chrome 123, Safari 17.5 y Firefox 120. El paquete en su conjunto necesita Firefox 128; consulta [Configuración inicial → Requisitos](../setup.md#requisitos).
|
|
43
44
|
|
|
45
|
+
### Impresión
|
|
46
|
+
|
|
47
|
+
Una página se imprime con el tema claro, sea cual sea el tema que muestra en pantalla. Dentro de `@media print`, la raíz y cada selector oscuro definen `color-scheme: light`, así que cada token se resuelve a su valor claro, también el de una barra lateral forzada a oscuro. El papel es claro, y un texto oscuro sobre él gasta menos tinta que una página oscura impresa.
|
|
48
|
+
|
|
49
|
+
Los componentes con relleno imprimen su fondo. Por defecto, un navegador quita los fondos de una página impresa, lo que deja el texto de contraste de un botón sólido sobre nada, así que cada componente define `print-color-adjust: exact`. La propiedad se hereda, de modo que el contenido de un componente también conserva sus colores.
|
|
50
|
+
|
|
51
|
+
Un límite: una utilidad `dark:` se sigue aplicando al imprimir. Se compara por selector, no por `color-scheme`, así que con `<html class="dark">` y `dark:bg-black` en un elemento, ese fondo se imprime negro. Escribe una utilidad `print:` a su lado si la página impresa importa.
|
|
52
|
+
|
|
44
53
|
### La variante `dark:`
|
|
45
54
|
|
|
46
55
|
Con los puntos de entrada de código fuente de Tailwind (`/tw`), el paquete reemplaza la variante `dark:` de Tailwind para que tus propias utilidades sigan el mismo tema que los tokens. Una utilidad `dark:` se aplica bajo un selector oscuro explícito en el elemento o en un ancestro, o bajo una preferencia oscura del sistema cuando ningún ancestro define un tema:
|
|
@@ -92,6 +101,8 @@ El mismo patrón funciona con cada familia de [Tokens de color](#tokens-de-color
|
|
|
92
101
|
|
|
93
102
|
Los valores tienen que ser colores completos: hex, `rgb()`, `oklch()` o una variable que hayas declarado tú. Las variables de la paleta de Tailwind, como `--color-teal-700`, existen en un build `/tw`, a partir de tu tema de Tailwind, pero el CSS compilado solo declara los colores de la paleta que usa el propio paquete. Con CSS compilado, una referencia a cualquier otra variable de la paleta está vacía, y el color que alimenta se pierde.
|
|
94
103
|
|
|
104
|
+
Con `/tw` puedes prescindir de los tonos de Tailwind que tu diseño no usa, para que `bg-red-500` y sus hermanas dejen de ser clases. Conserva los que lee el tema, `neutral`, `emerald`, `amber`, `rose`, `indigo` y `white`: si los borras, los colores que se construyen con ellos se pierden sin ningún error. [Tailwind CSS v4 → Prescindir de la paleta de Tailwind](../integrating/tailwind.md#prescindir-de-la-paleta-de-tailwind) tiene el bloque para copiar.
|
|
105
|
+
|
|
95
106
|
## Tu propia intención
|
|
96
107
|
|
|
97
108
|
El paquete incluye seis intenciones: `.primary`, `.secondary`, `.success`, `.warning`, `.destructive` e `.info`, y la de por defecto, `.neutral`. Para añadir una, como un color "Beta" para funciones en vista previa, escribe una clase que defina los siete huecos de intención. Usa colores completos, con `light-dark()` para todo lo que cambia entre temas:
|
|
@@ -121,6 +132,8 @@ La clase funciona en todo lo que acepta una intención: botones, badges, campos
|
|
|
121
132
|
- **Un reposo discreto, sin tinte.** Una `.card.soft`, un `.panel` y una `.alert` neutros reposan sobre el tono de fondo discreto, y solo reconocen una intención por las seis clases incorporadas. `.card.soft.beta`, `.panel.beta` y `.alert.beta` se dibujan como el neutro: el tono de fondo discreto en lugar de un tinte violeta. Tu intención sigue coloreando su texto y su borde.
|
|
122
133
|
- **El tinte de los chips.** Una tecla o un bloque de código `.beta` muestra tu tinte `--intent-subtle`, pero no el 12% adicional de `--intent-color` que una intención incorporada añade encima.
|
|
123
134
|
- **Clases solo.** Una [clase solo](./solo.md) como `.neobrutalism-solo` solo toma una intención de las seis clases incorporadas, así que `.neobrutalism-solo.beta` se dibuja neutro.
|
|
135
|
+
- **El texto del hint.** Un [`.hint`](./forms.md#mostrar-un-error-de-validación) solo se muestra en el tono legible de una intención con las seis clases incorporadas, así que `.hint.beta` se queda en el color secundario.
|
|
136
|
+
- **Filas de tabla.** Una fila del cuerpo cambia el color de su texto, su línea y su hover solo con las clases de intención incorporadas. `<tr class="beta">` se ve como el resto de su tabla.
|
|
124
137
|
|
|
125
138
|
Si los necesitas, hay dos caminos:
|
|
126
139
|
|
|
@@ -233,7 +246,7 @@ Las cuatro sombras `--elevation-*` son para elementos a los que das estilo tú.
|
|
|
233
246
|
| `--elevation-sm` | `0 1px 2px`, `0 1px 3px` | Una sombra ligera para tus propias superficies, como una tarjeta. |
|
|
234
247
|
| `--elevation-md` | `0 4px 6px -1px`, `0 2px 4px -2px` | Una sombra para tus propios elementos elevados, como un menú desplegable. |
|
|
235
248
|
| `--elevation-lg` | `0 20px 25px -5px`, `0 8px 10px -6px` | Una sombra para tus propias capas superpuestas, como un diálogo modal. |
|
|
236
|
-
| `--focus-ring` | `--color-primary` con un 64% de opacidad
|
|
249
|
+
| `--focus-ring` | Sin definir | Color del anillo de foco del teclado. Sin definir, `--color-primary` con un 64% de opacidad, en el elemento con foco. |
|
|
237
250
|
| `--focus-ring-offset` | Sin definir | Distancia del anillo al elemento. Sin definir, el anillo queda sobre el borde del elemento con cualquier estética. |
|
|
238
251
|
| `--focus-ring-width` | `3px` | Grosor del anillo de foco del teclado. |
|
|
239
252
|
| `--motion-duration-fast` | `120ms` | El hover de una fila de tabla. |
|
|
@@ -243,22 +256,22 @@ Las cuatro sombras `--elevation-*` son para elementos a los que das estilo tú.
|
|
|
243
256
|
| `--z-popover` | `40` | Orden de apilamiento de las burbujas de tooltip. Úsalo para tus propios popovers, para que se apilen igual. |
|
|
244
257
|
| `--breakpoint-xs` | `30rem` | El breakpoint adaptable `xs:`. Solo en un build `/tw`; los puntos de entrada compilados no lo declaran. |
|
|
245
258
|
|
|
246
|
-
Cada sombra `--elevation-*` está formada por las partes indicadas, cada una en `--elevation-color`. El paso de hover que intensifica un relleno bajo el puntero es un token de presentación, `--hover-step`; consulta [Personalización](./customizing.md#tokens-de-presentación).
|
|
259
|
+
Cada sombra `--elevation-*` está formada por las partes indicadas, cada una en `--elevation-color`. Las cuatro sombras se componen una sola vez, en la raíz, así que un `--elevation-color` que definas en un contenedor no les llega: defínelo en `:root`, o define el propio token `--elevation-*` en el contenedor. Las clases de elevación, como `.card.raised`, leen `--elevation-color` en el elemento y siguen el valor de un contenedor, con una excepción: cada clase de estética define su propio `--elevation-color` en su región. Un valor definido por encima de una región `.glass` o `.pixel` no llega a su interior. Defínelo en el propio elemento de la estética, donde tu utilidad o tu CSS sin capa supera a la clase, o en un elemento dentro de la región. Con glass, la sombra de una superficie se construye en el elemento `.glass`, así que solo la cambia un valor definido ahí. Con `.neobrutalism` la sombra se dibuja en la intención o en la tinta, y `.cyber` no dibuja profundidad, así que ninguna de las dos lee el token. El paso de hover que intensifica un relleno bajo el puntero es un token de presentación, `--hover-step`; consulta [Personalización](./customizing.md#tokens-de-presentación).
|
|
247
260
|
|
|
248
261
|
## Fuentes
|
|
249
262
|
|
|
250
263
|
El paquete no incluye archivos de fuente ni hace peticiones de red. Cada token de fuente nombra fuentes ya instaladas en el dispositivo del lector hasta que aportes las tuyas.
|
|
251
264
|
|
|
252
|
-
| Token | Lo lee
|
|
253
|
-
| ---------------- |
|
|
254
|
-
| `--font-default` | El reset, en `html` y `body
|
|
255
|
-
| `--font-mono` | Los helpers de contenido `kbd`, `code` y `pre`, y `<kbd>`, `<code>` y `<pre>` con `/native`
|
|
256
|
-
| `--font-pixel` | [`.pixel`](./aesthetics.md#pixel) y `.pixel-solo`
|
|
257
|
-
| `--font-rounded` | [`.chunky-tile`](./aesthetics.md#chunky-tile) y `.chunky-tile-solo`
|
|
258
|
-
| `--font-cyber` | [`.cyber`](./aesthetics.md#cyber) y `.cyber-solo`
|
|
259
|
-
| `--font-sketch` | [`.sketch`](./aesthetics.md#sketch) y `.sketch-solo`
|
|
265
|
+
| Token | Lo lee | Sin tu valor |
|
|
266
|
+
| ---------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
267
|
+
| `--font-default` | El reset, en `html` y `body`, y las regiones `.glass` y `.neobrutalism`. Los controles lo heredan. | `"Segoe UI", system-ui, sans-serif` |
|
|
268
|
+
| `--font-mono` | Los helpers de contenido `kbd`, `code` y `pre`, y `<kbd>`, `<code>` y `<pre>` con `/native` | `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`. Con `/tw`, el valor de tu tema de Tailwind. |
|
|
269
|
+
| `--font-pixel` | [`.pixel`](./aesthetics.md#pixel) y `.pixel-solo` | No declarado. Recurre a una pila monoespaciada. |
|
|
270
|
+
| `--font-rounded` | [`.chunky-tile`](./aesthetics.md#chunky-tile) y `.chunky-tile-solo` | No declarado. Recurre a `--font-default` y después a una pila sans-serif. |
|
|
271
|
+
| `--font-cyber` | [`.cyber`](./aesthetics.md#cyber) y `.cyber-solo` | No declarado. Recurre a una pila monoespaciada. |
|
|
272
|
+
| `--font-sketch` | [`.sketch`](./aesthetics.md#sketch) y `.sketch-solo` | No declarado. Recurre a la familia `cursive` de la plataforma. |
|
|
260
273
|
|
|
261
|
-
`--font-default` solo llega a la página a través del reset, que incluyen `@codenhub/styles`, `/native`, `/tw`, `/tw/native` y `/tw/reset`. Con `/theme` o `/components` solos, define tú mismo `font-family` en `body`. Los tokens de las estéticas los lee la propia clase de la estética, así que funcionan con cualquier punto de entrada.
|
|
274
|
+
`--font-default` solo llega a la página a través del reset, que incluyen `@codenhub/styles`, `/native`, `/tw`, `/tw/native` y `/tw/reset`. Con `/theme` o `/components` solos, define tú mismo `font-family` en `body` y define `--font-default` con la misma fuente: las regiones `.glass` y `.neobrutalism` definen su propio `font-family` a partir del token, así que una fuente definida solo en `body` no llega dentro de ellas. O define solo el token y escribe `font-family: var(--font-default)` en `body`. Los tokens de las estéticas los lee la propia clase de la estética, así que funcionan con cualquier punto de entrada.
|
|
262
275
|
|
|
263
276
|
Para usar una fuente web, cárgala como cargas cualquier fuente y después nómbrala en el token. Define el token en `:root` para toda la página, o en cualquier elemento para esa parte:
|
|
264
277
|
|
package/docs/index.md
CHANGED
|
@@ -60,7 +60,7 @@ The package ships the same classes two ways:
|
|
|
60
60
|
Know these costs before you adopt it:
|
|
61
61
|
|
|
62
62
|
- **Class names are short and unprefixed.** `.primary`, `.success`, `.dark`, `.label`, `.field`, `.section`, `.stack`, `.flat`, and `.ghost` are global names. Another stylesheet on the same page that uses them collides with this one. The package sits in [cascade layers](./setup.md#cascade-layers), so your own unlayered CSS wins a collision, but a third-party library's rules for the same name still apply alongside the package's.
|
|
63
|
-
- **The complete stylesheets are large before compression.** At the time of writing, minified, the complete stylesheet is about
|
|
63
|
+
- **The complete stylesheets are large before compression.** At the time of writing, minified, the complete stylesheet is about 198 KB, `/native` about 295 KB, and `/components` about 159 KB. Served with gzip they are about 17 KB, 22 KB, and 13 KB. Focused files are much smaller: `/theme` is about 12 KB (3 KB with gzip) and one aesthetic is 4 to 14 KB (1 to 2 KB with gzip). Most of the size is composition that every component repeats, which is why compression removes so much of it. A compiled file ships every class, whether a page uses it or not. To ship only the classes your pages use, compile the package in your own build: through [Tailwind CSS v4](./integrating/tailwind.md) when the project runs it, or with the package's [`build` command](./integrating/without-a-bundler.md#build-only-the-classes-you-use) in any other project. A page with one button gets 26 to 28 KB minified that way, and about 6 KB with gzip. Otherwise import the narrowest entrypoint that covers a page; see [Setup → All entrypoints](./setup.md#all-entrypoints).
|
|
64
64
|
- **`--color-foreground` is a background, not a text color.** It is the tone one step off the page that a quiet card or panel sits on. The text color is `--color-text`.
|
|
65
65
|
- **Four hover colors are fixed values.** `--color-success-hover`, `--color-warning-hover`, `--color-destructive-hover`, and `--color-info-hover` are precomputed, because mixing them live crashed WebKit. If you override `--color-success` alone, its hover keeps the old hue, so replace the whole family; see [Theming → Color tokens](./usage/theming.md#color-tokens).
|
|
66
66
|
- **Modern browsers only.** Chrome 123, Safari 17.5, or Firefox 128 and newer. There is no fallback layer for older browsers.
|
|
@@ -98,6 +98,7 @@ Read these in order the first time. Each page adds to the settings screen and en
|
|
|
98
98
|
- [Aesthetics](./usage/aesthetics.md): restyle the whole screen with one class.
|
|
99
99
|
- [Solo classes](./usage/solo.md): paint an aesthetic onto a component this package does not style.
|
|
100
100
|
- [Composing](./usage/composing.md), [Customizing](./usage/customizing.md), and [Content and layout](./usage/content-and-layout.md): lookup pages with every axis rule, token, default, and helper class.
|
|
101
|
+
- [Presets](./usage/presets.md): set a look once, for a region, a theme, or your own component class, instead of repeating it on every element.
|
|
101
102
|
5. [Accessibility](./accessibility.md): what the CSS handles for you and what your application must still do.
|
|
102
103
|
|
|
103
104
|
The [changelog](./changelog/index.md) lists every release and what changed in it.
|
|
@@ -20,16 +20,44 @@ Importing from one place matters for two reasons. Some frameworks only _allow_ g
|
|
|
20
20
|
|
|
21
21
|
## Which guide to follow
|
|
22
22
|
|
|
23
|
-
| Stack
|
|
24
|
-
|
|
|
25
|
-
| A Tailwind CSS v4 project on any bundler
|
|
26
|
-
| Next.js / React
|
|
27
|
-
| Vue
|
|
28
|
-
| Svelte / SvelteKit
|
|
29
|
-
| Astro
|
|
30
|
-
| Plain HTML, Rails, Django, or any app with no CSS build step | [Without a bundler](./without-a-bundler.md) |
|
|
31
|
-
|
|
32
|
-
A project with no framework — a plain Vite, webpack, or Parcel build —
|
|
23
|
+
| Stack | Guide |
|
|
24
|
+
| ----------------------------------------------------------------------------- | ------------------------------------------- |
|
|
25
|
+
| A Tailwind CSS v4 project on any bundler | [Tailwind CSS v4](./tailwind.md) |
|
|
26
|
+
| Next.js / React | [Next.js](./nextjs.md) |
|
|
27
|
+
| Vue | [Vue](./vue.md) |
|
|
28
|
+
| Svelte / SvelteKit | [Svelte](./svelte.md) |
|
|
29
|
+
| Astro | [Astro](./astro.md) |
|
|
30
|
+
| Plain HTML, Rails, Laravel, Django, or any app with no Node.js CSS build step | [Without a bundler](./without-a-bundler.md) |
|
|
31
|
+
|
|
32
|
+
A project with no framework — a plain Vite, webpack, or Parcel build — imports the compiled stylesheet from the project's existing global CSS entry, as [Setup → Import the stylesheet](../setup.md#import-the-stylesheet) shows. Vite and webpack resolve the package name as it is; Parcel and PostCSS with `postcss-import` need the change below. The compiled stylesheet holds every class; to ship only the ones your pages use without adopting Tailwind, write a trimmed stylesheet with the package's [`build` command](./without-a-bundler.md#build-only-the-classes-you-use) and import that instead.
|
|
33
|
+
|
|
34
|
+
### Bundlers that need a nudge
|
|
35
|
+
|
|
36
|
+
Both tools find the stylesheet once they are told how; neither needs a different entrypoint.
|
|
37
|
+
|
|
38
|
+
**Parcel.** Turn on its support for a package's `exports` map in your `package.json`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"@parcel/resolver-default": {
|
|
43
|
+
"packageExports": true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Then import the package with Parcel's `npm:` prefix, which tells it the name is a package and not a file next to the stylesheet:
|
|
49
|
+
|
|
50
|
+
```css
|
|
51
|
+
@import "npm:@codenhub/styles";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**PostCSS with `postcss-import`.** The plugin does not read a package's `exports` map, so the package name alone does not resolve. Import the compiled file by its path on disk instead, relative to your own stylesheet, the same file a `<link>` would name:
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
@import "../node_modules/@codenhub/styles/dist/index.css";
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The other compiled entrypoints work the same way, such as `@codenhub/styles/dist/aesthetics/neobrutalism.css`.
|
|
33
61
|
|
|
34
62
|
## Verifying it worked
|
|
35
63
|
|
|
@@ -6,11 +6,11 @@ order: 1
|
|
|
6
6
|
|
|
7
7
|
# Tailwind CSS v4
|
|
8
8
|
|
|
9
|
-
A project that already runs Tailwind CSS v4 can compile this package's source instead of loading its compiled output. Your app's utilities and the package's classes then come out of one build, share one theme, and use one `dark:` variant. This page covers the import, aesthetics, the focused entrypoints, and the build problems you are likely to meet.
|
|
9
|
+
A project that already runs Tailwind CSS v4 can compile this package's source instead of loading its compiled output. Your app's utilities and the package's classes then come out of one build, share one theme, and use one `dark:` variant. This page covers the import, aesthetics, the focused entrypoints, building your own components with `@apply`, dropping Tailwind's palette, and the build problems you are likely to meet.
|
|
10
10
|
|
|
11
11
|
## Why source instead of compiled
|
|
12
12
|
|
|
13
|
-
`/tw` entrypoints publish copied, uncompiled source from `
|
|
13
|
+
`/tw` entrypoints publish copied, uncompiled source from the package's `tw/` folder; your own Tailwind build compiles it alongside your app, so its `@theme`, `@utility`, and `@apply` directives resolve together with yours. The compiled entrypoints (`@codenhub/styles`) still work in a Tailwind project, but then two separate CSS pipelines run side by side instead of one — use `/tw` unless a specific reason rules it out.
|
|
14
14
|
|
|
15
15
|
## Import the source entrypoint
|
|
16
16
|
|
|
@@ -22,7 +22,7 @@ A project that already runs Tailwind CSS v4 can compile this package's source in
|
|
|
22
22
|
|
|
23
23
|
`/tw` imports Tailwind itself, so it replaces your own `@import "tailwindcss"` rather than joining it: with both, Tailwind's Preflight is emitted twice. Every other `/tw/*` entrypoint expects your import to come first; see [Using a focused entrypoint](#using-a-focused-entrypoint).
|
|
24
24
|
|
|
25
|
-
Tailwind CSS v4 scans your project automatically — most projects need nothing beyond the import above. `@source` paths resolve relative to the CSS file that declares them, not your project root, so `./src` here means "the `src/` next to this stylesheet"; adjust it to match where your own global stylesheet actually lives. Add `@source` only for markup Tailwind's automatic scan won't reach on its own: a path excluded by default (`.gitignore`d, or inside `node_modules` — an external component library, for instance) or, in a monorepo, one outside this file's own directory tree. Point it at your app's markup, not at this package
|
|
25
|
+
Tailwind CSS v4 scans your project automatically — most projects need nothing beyond the import above. `@source` paths resolve relative to the CSS file that declares them, not your project root, so `./src` here means "the `src/` next to this stylesheet"; adjust it to match where your own global stylesheet actually lives. Add `@source` only for markup Tailwind's automatic scan won't reach on its own: a path excluded by default (`.gitignore`d, or inside `node_modules` — an external component library, for instance) or, in a monorepo, one outside this file's own directory tree. Point it at your app's markup, not at this package: the package's source names every class it defines, so scanning it emits all of them whether your pages use them or not.
|
|
26
26
|
|
|
27
27
|
## Add aesthetics
|
|
28
28
|
|
|
@@ -46,6 +46,70 @@ Unlike `/tw`, the focused entrypoints and `/tw/native` do not import Tailwind, s
|
|
|
46
46
|
@import "@codenhub/styles/tw/button";
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
## Build your own components with `@apply`
|
|
50
|
+
|
|
51
|
+
On `/tw`, every component, helper, and axis class is a Tailwind utility. That includes the intents (`neutral`, `primary`, `secondary`, `success`, `warning`, `destructive`, `info`), the presentation (`solid`, `soft`, `ghost`, `edged`, `edgeless`), the elevation (`flat`, `raised`, `floating`), the corner patterns (`cut-diagonal`, `cut-diagonal-reverse`), and the sizes (`sm`, `lg`). So one class of yours can carry a whole recipe:
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
@import "@codenhub/styles/tw";
|
|
55
|
+
|
|
56
|
+
@utility btn-save {
|
|
57
|
+
@apply btn primary soft sm;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@utility btn-danger {
|
|
61
|
+
@apply btn destructive md:lg dark:solid;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<button class="btn-save" type="submit">Save</button>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- **An applied component behaves like the class.** `btn-save` hovers, presses, takes focus, and follows an aesthetic the way `class="btn primary soft sm"` does.
|
|
70
|
+
- **Variants work.** `hover:primary`, `md:lg`, and `dark:solid` apply an axis class under that condition, in your markup or inside `@apply`.
|
|
71
|
+
- **Write your class as `@utility`.** It then stays in the `utilities` layer, so your other utilities on the same element still beat it. A plain `.btn-save { @apply … }` rule works too, but it is unlayered, so what it applies beats every utility on the element; [Customizing → Composition helpers](../usage/customizing.md#composition-helpers) has the details.
|
|
72
|
+
- **Modifiers apply too.** A component's modifiers, such as `.tight` on `.stack`, `.icon` on `.btn`, or `.interactive` on `.card`, are utilities as well, so `@apply stack tight`, `@apply btn icon pill`, and `md:tight` work. The disabled state is the exception: it stays an attribute or the `.disabled` class in markup.
|
|
73
|
+
- **Your utility beats a component's inner defaults.** `p-0 text-center` on a `.data-table` cell, `text-sm` on a `.label`, and `px-8` on a `.btn.sm` all apply.
|
|
74
|
+
|
|
75
|
+
[Presets](../usage/presets.md) compares this with the other ways to set a look once.
|
|
76
|
+
|
|
77
|
+
## Drop Tailwind's palette
|
|
78
|
+
|
|
79
|
+
`/tw` builds on Tailwind's default theme, so Tailwind's palette utilities, such as `bg-red-500`, stay available. If your design uses only the package's tokens, clear the hues you do not use:
|
|
80
|
+
|
|
81
|
+
```css
|
|
82
|
+
@import "@codenhub/styles/tw";
|
|
83
|
+
|
|
84
|
+
@theme {
|
|
85
|
+
--color-red-*: initial;
|
|
86
|
+
--color-orange-*: initial;
|
|
87
|
+
--color-yellow-*: initial;
|
|
88
|
+
--color-lime-*: initial;
|
|
89
|
+
--color-green-*: initial;
|
|
90
|
+
--color-teal-*: initial;
|
|
91
|
+
--color-cyan-*: initial;
|
|
92
|
+
--color-sky-*: initial;
|
|
93
|
+
--color-blue-*: initial;
|
|
94
|
+
--color-violet-*: initial;
|
|
95
|
+
--color-purple-*: initial;
|
|
96
|
+
--color-fuchsia-*: initial;
|
|
97
|
+
--color-pink-*: initial;
|
|
98
|
+
--color-slate-*: initial;
|
|
99
|
+
--color-gray-*: initial;
|
|
100
|
+
--color-zinc-*: initial;
|
|
101
|
+
--color-stone-*: initial;
|
|
102
|
+
--color-black: initial;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The package's own colors do not change, and you can still add colors of your own in the same block.
|
|
107
|
+
|
|
108
|
+
The block leaves out `neutral`, `emerald`, `amber`, `rose`, `indigo`, and `white` on purpose: the theme builds its colors from them.
|
|
109
|
+
|
|
110
|
+
- **Do not clear the whole namespace.** `--color-*: initial` also removes the package's semantic colors, and the build stops with an error such as `Cannot apply unknown utility class`.
|
|
111
|
+
- **Do not clear a ramp the theme reads.** Clearing `--color-emerald-*` builds without an error, but the success colors made from it are lost.
|
|
112
|
+
|
|
49
113
|
## Troubleshooting
|
|
50
114
|
|
|
51
115
|
**Classes resolve to no styling**
|
|
@@ -62,11 +126,17 @@ Unlike `/tw`, the focused entrypoints and `/tw/native` do not import Tailwind, s
|
|
|
62
126
|
|
|
63
127
|
**A class built at runtime has no styling**
|
|
64
128
|
|
|
65
|
-
- **What happened:** `<button class="btn primary">` is styled, but a button whose
|
|
66
|
-
- **Why:** Tailwind
|
|
67
|
-
- **Fix:** write complete class
|
|
129
|
+
- **What happened:** `<button class="btn primary">` is styled, but a button whose class comes from a variable, such as `"btn " + variant`, or from CMS content, is not.
|
|
130
|
+
- **Why:** Tailwind emits only the classes it finds written out in the files it scans. That holds for the package's component classes too: a `/tw` build emits `.alert` only if `alert` appears somewhere it scans, which keeps the stylesheet to what your pages use. The intent, presentation, elevation, corner, and size classes, such as `.primary`, `.soft`, and `.sm`, are utilities too, so the same holds for them. The aesthetic classes, such as `.glass`, are plain CSS and always emitted. A name assembled at runtime never appears whole in a file, so the scan misses it.
|
|
131
|
+
- **Fix:** write each complete class name somewhere Tailwind scans, for example in a lookup object (`{ save: "btn primary", remove: "btn destructive" }`), or list the names your code or content can produce in your stylesheet:
|
|
132
|
+
|
|
133
|
+
```css
|
|
134
|
+
@import "@codenhub/styles/tw";
|
|
135
|
+
|
|
136
|
+
@source inline("btn alert badge primary destructive soft");
|
|
137
|
+
```
|
|
68
138
|
|
|
69
|
-
Every `/tw` entrypoint requires Tailwind CSS 4.3.2 or newer, below 5
|
|
139
|
+
Every `/tw` entrypoint requires Tailwind CSS 4.3.2 or newer, below 5 (`>=4.3.2 <5`).
|
|
70
140
|
|
|
71
141
|
## The `dark:` variant
|
|
72
142
|
|