|
|
1 month ago | |
|---|---|---|
| .. | ||
| README.md | 2 months ago | |
| index.ts | 3 months ago | |
| surface.css | 1 month ago | |
| surface.svelte | 3 months ago | |
| types.ts | 2 months ago | |
README.md
Surface
El lienzo temable: Box + tratamiento. Box es layout-only por doctrina
(estructura ≠ tratamiento) y rechaza background/color; Surface es la
primitiva que posee el lado del tratamiento — un lienzo pintable de primera
clase para el caso hero / banda decorativa / bgGradient, en vez de un
escape-hatch style=.
<Surface color="primary" variant="solid" gradient padding={8} rounded>
<h2>Crea sin límites</h2>
<p>…</p>
<Button>Empezar</Button>
</Surface>
<Surface color="teal" paddingY={6}>…banda soft…</Surface>
<Surface color="plum" variant="solid" gradient="spread" rounded>…</Surface>
Qué es (y qué no)
- Es la superficie neutra del catálogo: el mecanismo palette-tint de Card SIN su chrome (sin slots de cabecera, sin borde por defecto, sin interactividad, sin promoción a botón).
- No es un contenedor de layout nuevo — compone
<Box>(patrón Section) y hereda TODA su API de caja (padding/margin/size/flex/grid/inset…). - No es el sistema COMPLETO de inversión de contenido:
on="light|dark"(D12) re-vincula los roles globales de contenido para el texto plano del subárbol, pero los componentes anidados conservan sus identidades y el contenido portaleado escapa — límites por construcción; la inversión total es iniciativa aparte.
Props
- Todo
BoxProps(layout, passthrough a Box). color?: ComponentColor— identidad (rol o escala donante; THM-2). Default host =neutral, como Card.variant?: 'soft' | 'solid'— tinte discreto (track) o lienzo saturado (solid + tinta contrast heredada). Defaultsoft.gradient?: boolean | 'ramp' | 'spread' | (string & {})— el acabado §39 (rampa anclada a la sombra de la tinta / rotación de matiz a L constante / un named finish D11 como'aurora': gradiente del open cage con tinta autorada sobre el solid de la identidad). Solo pinta envariant="solid"; inerte en soft. Guard:gradient-finish-guard.test.ts.on?: 'light' | 'dark'— el contexto mínimo de tinta del subárbol (D12): re-vincula--color-content-*/--color-border-defaultpara el contenido plano; anidados y portales excluidos por construcción; forced-colors →CanvasText.rounded?: boolean— esquinas--surface-radius(recorta el contenido).
Tokens públicos del recipe (--surface-*)
radius + las paletas de 5 slots por color
(--surface-{color}-{track,border,solid,text,contrast}) que la cascada
privada --_surface-palette-* resuelve según data-color (THM-2: las 33
escalas entran por el forward compartido).
Baseline
No existe air/surface que recuperar (verificado en el censo del ciclo
gradient-finish 2026-07-15: el catálogo no tenía primitiva de lienzo — Card y
Banner eran los únicos palette-tint, y Box/Section/Container no pintan fondo
por doctrina). El baseline real es doble: el mecanismo palette-tint de
Card (recipe _palette-* 5 slots × 8 colores, espejado exacto) y el
patrón de composición de Section (wrapper sobre <Box> + estampado
propio). El specimen sheet del árbol alpha TERMINADO se descartó como
evidencia (veredicto de usuario sobre ese árbol).
Passive justification
Como Box, Surface es un lienzo pasivo: no comete, no emerge, no reacciona a
nada — traduce props visuales a attrs que el recipe pinta. Cero eventos sema;
añadirlos fabricaría semántica que la primitiva no porta. El morfo
(morfo/components/surface.ts, scope: ['eidos']) declara la parte única y
esta justificación; data-color/data-variant/data-gradient/
data-rounded son attrs eidos-only de wrapper (doctrina D8 del gradient
finish — declararlos en morfo haría que el runtime los resolviera desde el
espacio de props de soma y clobbeara el estampado).
Decisiones
- Nombre
Surface(noSheet): fijado en el plan y el capítulo committeados del ciclo gradient-finish; la evidenciasheetdel árbol alpha terminado se descartó. - Composición sobre Box, no fork: Surface = Box + tratamiento (patrón Section); Box conserva su doctrina layout-only intacta (D1 de la taxonomía: identidad × porte × material).
- Attrs de wrapper eidos-only, morfo declarativo (D8): el morfo existe (morfo-first) pero no lleva los attrs visuales — el runtime los resolvería desde soma y clobbearía el estampado.
- Variantes solo
soft/solid: outline/ghost son territorio de Card (un lienzo sin fill no es un lienzo). - Registro completo:
docs/theming/gradient-finish.md(D1–D10).
Gaps
- Demo propia (
web/routes/uix/components/surface) — implementar: hoy los especímenes canónicos viven en el labweb/routes/temas/gradientes(CASO 07); la demo con profundidad DEMO_AUTHORING_GUIDE es la siguiente pieza del rollout. - Inversión COMPLETA de subárbol (re-entintado de componentes anidados + portales) — diferir (iniciativa independiente): D12 cubre el contenido plano; el resto queda excluido por construcción y documentado.
- Scrim de autoría para vívidos — CERRADO 2026-08-18 por
Background.Scrim: el caso repetido apareció (el layoutbackgrounddel hero lo escribía inline), así que el velo es ya un componente con pesos semánticos, variante graduada y opción de escarcha. Se compone como capa de la pila, no como prop de Surface — la pila es hija del anfitrión y Surface sigue sin saber nada de ella. - Validación de modelo para tintas named — diferir (D11): solo
posible para gradientes
buildGradient(stops conocidos); la tinta named es autorada y el guard clava la sanidad del config. - depth/frost — descartar (a propósito): un gradiente opaco mata el
backdrop-filter; Surface no adopta
data-depth, como Card. - Custom color (
data-color-custom) — diferir: la vía existe en Card si surge el caso real.
Talla y tema
25 clave(s) pública(s) en lib/recipes/base.ts (bloque surface).
Es el contrato vivo: la pestaña Tokens de su demo lista estas mismas
claves y las resuelve sobre el escenario.
Token (--surface-…) |
Valor por defecto |
|---|---|
radius |
var(--radius-lg) |
neutral-track |
var(--color-neutral-track) |
neutral-solid |
var(--color-neutral-solid) |
neutral-contrast |
var(--color-neutral-contrast) |
primary-track |
var(--color-primary-track) |
primary-solid |
var(--color-primary-solid) |
primary-contrast |
var(--color-primary-contrast) |
secondary-track |
var(--color-secondary-track) |
secondary-solid |
var(--color-secondary-solid) |
secondary-contrast |
var(--color-secondary-contrast) |
affirm-track |
var(--color-affirm-track) |
affirm-solid |
var(--color-affirm-solid) |
affirm-contrast |
var(--color-affirm-contrast) |
fulfill-track |
var(--color-fulfill-track) |
fulfill-solid |
var(--color-fulfill-solid) |
fulfill-contrast |
var(--color-fulfill-contrast) |
risk-track |
var(--color-risk-track) |
risk-solid |
var(--color-risk-solid) |
risk-contrast |
var(--color-risk-contrast) |
threat-track |
var(--color-threat-track) |
threat-solid |
var(--color-threat-solid) |
threat-contrast |
var(--color-threat-contrast) |
loss-track |
var(--color-loss-track) |
loss-solid |
var(--color-loss-solid) |
loss-contrast |
var(--color-loss-contrast) |
Lo que el guard R-5.4 da por silencioso, con su razón medida
(scripts/theming-sentinel-exceptions.ts):
- Por patrón
/^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|solid|contrast)$/— la cascada de paleta: el bloque genérico[data-surface][data-color]se emite el ÚLTIMO y gana por orden, así que la pintura sale del--palette-*global (§13, pendiente de firma).
Comparativa
| UIX Surface | Chakra Box bg= |
Radix Themes | MD3 | |
|---|---|---|---|---|
| Primitiva de lienzo temable | ✓ (identidad + variante + acabado) | prop suelto sin identidad | ✗ (Card o nada) | roles surface (sin componente) |
| Gradiente con garantía de tinta | ✓ (§39, guard ejecutable) | ✗ (autor) | ✗ | ✗ |
| Hereda un sistema de layout | ✓ (Box entero) | ✓ | ✗ | — |
Doctrina completa: docs/theming/gradient-finish.md (D1–D10) + THEMING §39.