Fundamentos
Cada pieza del sistema toma una de dos formas: un custom element con su propia etiqueta, vadavo-<nombre>, o una clase que se aplica sobre marcado que escribe quien la usa.
Un custom element aporta marcado propio, comportamiento, aislamiento y una API de JavaScript. Una clase aporta el aspecto del sistema sobre el marcado del consumidor.
Por defecto, se prefieren las clases. Una pieza es un custom element si cumple al menos uno de estos cuatro criterios:
| Criterio | Descripción | Ejemplo |
|---|---|---|
| Comportamiento | Necesita JavaScript: estado, eventos o teclado que ningún elemento nativo ofrece. | <vadavo-select> recorre y filtra su lista. |
| Marcado generado | Produce estructura a partir de datos, no del marcado que escribe el consumidor. | <vadavo-logo> inyecta su propio SVG. |
| Aislamiento | Su interior tiene que ser inalcanzable desde la página. | <vadavo-shell> encierra el marco de la página. |
| Coste de estructura | Como clase, obligaría al consumidor a repetir estructura que el sistema debe garantizar: un icono, un envoltorio, un control que no es contenido. | <vadavo-textfield> envuelve su control con su etiqueta y su línea de error. |
Si no cumple ninguno, es una clase.
<h2>Un <span class="highlight primary">highlight</span> es una clase</h2>
<vadavo-tag>Un tag es un elemento</vadavo-tag>
Una variante dice qué es la pieza, nunca su aspecto: una alerta que informa de que algo ha terminado bien lleva la variante success, nunca green.
En un custom element la variante es un atributo, reflejado también como propiedad de JavaScript: cambiarlo desde código (alert.tone = 'warning') actualiza la pieza igual que cambiar el atributo en el HTML. En una clase la variante es otra clase junto a la principal.
<span class="badge success">Pagada</span>
<span class="badge warning">Pendiente</span>
<span class="badge error">Vencida</span>
Cada custom element encapsula su propio marcado y su propio CSS en un shadow root: sus estilos nunca se filtran a la página, y ninguna regla de la página alcanza su interior salvo por lo que él mismo decide exponer. El CSS vive junto al elemento, fuera de la hoja de estilos general, y cada tipo lo adopta una sola vez.
El contenido que un elemento recibe entre sus etiquetas de apertura y cierre, o en un hueco con nombre (slot="..."), es HTML del documento, escrito por el autor de la página. Un hueco con nombre reserva un lugar concreto de la plantilla interna para ese contenido.
Pulsa sobre el botón para hacer efectiva la modificación de los DNS.
<vadavo-card heading="Modificar DNS">
<p>Pulsa sobre el botón para hacer efectiva la modificación de los DNS.</p>
<div slot="footer">
<button class="button primary">Modificar DNS</button>
</div>
</vadavo-card>
Un elemento nunca alcanza el interior de otro, ni desde su CSS ni desde su JavaScript: expone métodos públicos, atributos reflejados o eventos (CustomEvent) en su lugar, nunca su marcado interno. Rige la misma separación de capas que en los tokens: ninguna pieza sabe nada de quién la usa.
Una superficie de marca —spotlight, standout, callout (ver Superficies de marca)— cambia el aspecto de un elemento que vive dentro redefiniendo las propiedades personalizadas que ese elemento expone, que fuera de ella conservan su valor por defecto. Las propiedades personalizadas atraviesan el límite del shadow DOM; los selectores, no.
El color de la sombra desplazada es el que trae la tarjeta.
La superficie redefine --card--color--shadow.
<div style="display: grid; gap: 1.5rem">
<vadavo-card raised heading="Fuera de spotlight">
<p>El color de la sombra desplazada es el que trae la tarjeta.</p>
</vadavo-card>
<div class="spotlight" style="padding: 20px; border-radius: var(--surface--radius--container)">
<vadavo-card raised heading="Dentro de spotlight">
<p>La superficie redefine <code>--card--color--shadow</code>.</p>
</vadavo-card>
</div>
</div>