Documentación

Estilos y tematización

El DS resuelve cada color, espacio y radio a través de una propiedad CSS personalizada --yl-*. Eso es lo que permite que las primitivas se rendericen en el servidor y que cambiar de tema sea una sola escritura de atributo. Esta guía cubre cómo se distribuyen las hojas de estilo en 0.2.0 y la regla que más confunde: la raíz de 10px.

#Dos hojas obligatorias, el resto opcional

En 0.2.0 los estilos de componente salieron de themeCss() y pasaron a archivos. Importa siempre los tokens y la capa base; añade la hoja de un componente cuando lo renderices:

ts
import "@yoltra/ds/styles/tokens.css"; // variables --yl-*, claro + oscuro
import "@yoltra/ds/styles/base.css";   // raíz html 62.5%, .yl-root, .yl-container, .yl-visually-hidden
import "@yoltra/ds/styles/button.css";
import "@yoltra/ds/styles/modal.css";  // Dialog + Drawer

Es deliberado. El JavaScript se puede tree-shakear, pero una única hoja con las reglas de todos los componentes no —se convierte en un coste que paga toda app sin importar lo que renderice—. Para un sitio de documentación o un prototipo, @yoltra/ds/styles/all.css lo trae todo en un import.

¿Migrando desde 0.1.0? Antes themeCss() emitía las variables y las reglas de cada componente. Ahora emite solo variables. Importa las hojas de componente (o all.css) o tus componentes se renderizarán sin estilo.

#themeCss() — para un render de servidor

themeCss() se sigue exportando y emite las mismas propiedades personalizadas, para cuando las necesitas insertadas antes del primer pintado en lugar de enlazadas:

tsx
<style dangerouslySetInnerHTML={{ __html: themeCss() }} />

Te da solo las variables —combínalo con las hojas de componente (o enlaza tokens.css en su lugar)—. Una app basada en archivos no lo necesita en absoluto.

#1rem es 10px

base.css fija html { font-size: 62.5% }, dejando la raíz en 10px para que cada longitud se lea como su valor en píxeles entre diez —1.6rem es 16px, 0.4rem es 4px—. Los tokens se escriben en píxeles (porque spacing[4] siendo 16 es más claro que 1.6) y solo el valor emitido lleva la unidad. Se usa rem en vez de px para que la preferencia de tamaño de fuente del lector siga escalando la interfaz.

De esto se derivan tres cosas fáciles de olvidar:

  • Fija el font-size del body. .yl-root no lleva font-size, así que el texto heredado se resuelve contra la raíz de 10px. Fija una base (p. ej. body { font-size: 1.6rem }).
  • La declaración de la raíz es global. Afecta a todo el documento. Una app que no pueda aceptarlo importa @yoltra/ds/styles/base-no-root.css y fija su propia raíz —momento en que cada longitud --yl-* es relativa a lo que elija—.
  • Breakpoints y hairlines siguen en píxeles. Un breakpoint en rem se resuelve contra la raíz inicial, no la de 62.5%, así que sería 1.6× su valor en silencio; un borde de 1px debe ser 1px.

#Tematización

La tematización es data-theme en la raíz del documento —"light" u "dark"—:

tsx
import { ThemeProvider, useTheme, applyTheme } from "@yoltra/ds/client";

ThemeProvider guarda el tema y lo refleja en la raíz; useTheme() lo lee y lo cambia; applyTheme("dark") escribe el atributo directamente (útil en un script previo a la hidratación para evitar un parpadeo del tema equivocado). Los consumidores que controlan su estado —como este sitio, que gestiona el tema con un store de Yoltra— se saltan el proveedor y fijan data-theme ellos mismos. El contrato del DOM es idéntico.

Consulta la referencia de la API para foundationTokens, lightTheme / darkTheme y cada nombre --yl-*.