You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/docs/audit/theming/select.md

13 KiB

select — alcance de tema: análisis y propuesta

Generado por node --import tsx/esm scripts/theming-census.ts --report. Lo medido y la propuesta se regeneran; el Veredicto (§5) se conserva. Vista de conjunto: README · método y protocolo: PLAN-theming.md §1, §2, §7.

  • Medido: 2026-08-19 · Alcance: 69% — 45 de 65 knobs por token público
  • Knobs de apariencia: 72 — público 45 · privado 14 · global 3 · literal 3 · sistema 7 (fuera del ratio)
  • Contrato hoy (lib/recipes/base.ts): 101 pública(s) — stack-gap, font-family, font-size-xs, font-size-sm, font-size-md, font-size-lg, font-size-xl, line-height, color, primary-text, secondary-text, neutral-text, affirm-text, fulfill-track, fulfill-border, fulfill-text, risk-text, threat-text, loss-track, loss-border, loss-text, trigger-height-xs, trigger-height-sm, trigger-height-md, trigger-height-lg, trigger-height-xl, trigger-padding-inline-xs, trigger-padding-inline-sm, trigger-padding-inline-md, trigger-padding-inline-lg, trigger-padding-inline-xl, trigger-gap-xs, trigger-gap-sm, trigger-gap-md, trigger-gap-lg, trigger-gap-xl, trigger-border-width, trigger-border, trigger-border-hover, trigger-radius, trigger-bg, trigger-shadow, trigger-color, trigger-indicator-color, trigger-indicator-size, placeholder-color, disabled-border, disabled-bg, disabled-color, content-z, content-padding-block-xs, content-padding-block-sm, content-padding-block-md, content-padding-block-lg, content-padding-block-xl, content-padding-inline-xs, content-padding-inline-sm, content-padding-inline-md, content-padding-inline-lg, content-padding-inline-xl, content-min-width, content-max-width, content-max-height, content-radius, content-color, open-duration, close-duration, viewport-gap, viewport-padding, group-padding-block, group-heading-padding-block, group-heading-padding-inline, group-heading-font-family, group-heading-font-size, group-heading-font-weight, group-heading-letter-spacing, group-heading-color, separator-size, separator-margin-block, separator-bg, item-gap, item-padding-inline, item-color, item-indicator-size, item-description-mt, item-description-color, item-description-font-size, transition-duration, transition-ease, primary-track, primary-border, secondary-track, secondary-border, neutral-track, neutral-border, affirm-track, affirm-border, risk-track, risk-border, threat-track, threat-border · 3 privada(s) forward — _palette-track, _palette-border, _palette-text
  • Eje size: sí · ficheros: select.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (3)

# fichero:línea selector propiedad valor
1 select.css:131 [data-select-trigger][data-invalid] border-color var(--color-risk-border)
2 select.css:136 [data-select-trigger][data-invalid]:focus-visible, [data-select-trigger][data-invalid][data-state='open'] border-color var(--color-risk-border)
3 select.css:277 [data-select-group] gap var(--space-1)

1.2 A través de un privado (14)

# fichero:línea selector propiedad valor
1 select.css:34 [data-select-trigger] gap var(--_select-trigger-gap)
2 select.css:37 [data-select-trigger] block-size var(--_select-trigger-height)
3 select.css:38 [data-select-trigger] padding-inline var(--_select-trigger-padding-inline)
4 select.css:45 [data-select-trigger] font-size var(--_select-font-size)
5 select.css:101 [data-select-trigger][data-state='open'] border-color var(--_select-palette-border)
6 select.css:107 [data-select-trigger]:focus-visible border-color var(--_select-palette-border)
7 select.css:169 [data-select-trigger][data-state='open'] [data-select-indicator] color var(--_select-palette-text)
8 select.css:187 [data-select-content] inline-size min(var(--_select-content-width), calc(100vw - var(--space-4)))
9 select.css:191 [data-select-content] padding-block var(--_select-content-padding-block)
10 select.css:192 [data-select-content] padding-inline var(--_select-content-padding-inline)
11 select.css:200 [data-select-content] font-size var(--_select-font-size)
12 select.css:270 [data-select-content] [data-scroll-area]:has(> [data-scroll-area-scrollbar][data-orientation='vertical']) > [data-scroll-area-viewport] padding-inline-end calc(var(--_select-content-padding-inline) + var(--space-3-5))
13 select.css:319 [data-select-item][data-state='checked'] background var(--_select-palette-track)
14 select.css:320 [data-select-item][data-state='checked'] color var(--_select-palette-text)

1.3 Literales (3)

# fichero:línea selector propiedad valor
1 select.css:18 [data-select] inline-size 100%
2 select.css:35 [data-select-trigger] inline-size 100%
3 select.css:359 [data-select-item][data-state='checked'] [data-select-item-indicator] opacity 1

2. Sistema transversal (7) — informativo, fuera del ratio

Un tema los alcanza a nivel de sistema, por diseño (recipe-contract §2).

# fichero:línea selector propiedad valor
1 select.css:97 [data-select-trigger]:hover:not(:disabled):not([data-disabled]) background-image linear-gradient(var(--state-hover), var(--state-hover))
2 select.css:102 [data-select-trigger][data-state='open'] outline var(--focus-ring-width) solid var(--focus-ring-color)
3 select.css:108 [data-select-trigger]:focus-visible outline var(--focus-ring-width) solid var(--focus-ring-color)
4 select.css:335 [data-select-item-description] opacity var(--opacity-subtle)
5 select.css:340 [data-select-item][data-state='checked'] [data-select-item-description] opacity var(--opacity-subtle)
6 select.css:369 [data-select-arrow] polygon fill var(--depth-overlay-surface)
7 select.css:374 [data-select-arrow] path stroke var(--depth-overlay-border)

3. Privados de la receta — ¿de dónde sale su valor?

privado declaraciones valor(es) origen ¿deriva de un público?
--_select-trigger-height 5 var(--select-trigger-height-md), var(--select-trigger-height-xs), var(--select-trigger-height-sm), var(--select-trigger-height-lg), var(--select-trigger-height-xl) public sí
--_select-trigger-padding-inline 5 var(--select-trigger-padding-inline-md), var(--select-trigger-padding-inline-xs), var(--select-trigger-padding-inline-sm), var(--select-trigger-padding-inline-lg), var(--select-trigger-padding-inline-xl) public sí
--_select-trigger-gap 5 var(--select-trigger-gap-md), var(--select-trigger-gap-xs), var(--select-trigger-gap-sm), var(--select-trigger-gap-lg), var(--select-trigger-gap-xl) public sí
--_select-font-size 10 var(--select-font-size-md), var(--select-font-size-xs), var(--select-font-size-sm), var(--select-font-size-lg), var(--select-font-size-xl) public sí
--_select-content-padding-block 5 var(--select-content-padding-block-md), var(--select-content-padding-block-xs), var(--select-content-padding-block-sm), var(--select-content-padding-block-lg), var(--select-content-padding-block-xl) public sí
--_select-content-padding-inline 5 var(--select-content-padding-inline-md), var(--select-content-padding-inline-xs), var(--select-content-padding-inline-sm), var(--select-content-padding-inline-lg), var(--select-content-padding-inline-xl) public sí
--_select-content-width 1 var(--_select-match-anchor-width, var(--select-content-min-width)) public sí

Consumidos y no declarados en el CSS (vienen de base.ts o de un estilo inline del wrapper): --_select-match-anchor-width, --_select-palette-border, --_select-palette-text, --_select-palette-track.

4. Propuesta de corrección

  • Consume la capa compartida list-surface. Un eje que la capa posee se consume como var(--_x, var(--x)); el consumidor no acuña --select-{eje} para él — sería un vocabulario paralelo (README de eidos/components, «Capas compartidas» regla 2).
  • Tiene eje size: los tokens dimensionales van por talla ({part}-{eje}-{k}) apuntando al bundle --size-{k}-*, nunca al primitivo crudo (theming §5; el guard recipe-css-contract prohíbe el primitivo).

4.1 Tokens a declarar en lib/recipes/base.ts (3)

Valor verbatim del CSS de hoy: el default no se mueve, sólo cambia quién puede moverlo. Nombres derivados de recipe-contract §1 (ejes lógicos, talla al final) y theming §6.7 (slots de color, modificador delante). Un token con DOS valores distintos es una colisión de nombre: son dos knobs, o el nombre no distingue lo que debería — se marca ⚠.

token (--select-…) scope TSC valor propuesto usos
invalid-trigger-border root var(--color-risk-border) 1
open-invalid-trigger-border root var(--color-risk-border) 1
group-gap root var(--space-1) 1

4.2 Sin nombre mecánico (17)

  • ⚠ decisión: 100% es un valor identidad o geometría de layout, no un knob de tema — el perímetro de «knob» es D-TH.2, sin firmar — 2: inline-size.
  • ya alcanzable: el privado --_select-trigger-gap deriva de un público (var(--select-trigger-gap-md), var(--select-trigger-gap-xs), var(--select-trigger-gap-sm), var(--select-trigger-gap-lg)) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 1: gap.
  • ya alcanzable: el privado --_select-trigger-height deriva de un público (var(--select-trigger-height-md), var(--select-trigger-height-xs), var(--select-trigger-height-sm), var(--select-trigger-height-lg)) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 1: block-size.
  • ya alcanzable: el privado --_select-trigger-padding-inline deriva de un público (var(--select-trigger-padding-inline-md), var(--select-trigger-padding-inline-xs), var(--select-trigger-padding-inline-sm), var(--select-trigger-padding-inline-lg)) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 1: padding-inline.
  • ya alcanzable: el privado --_select-font-size deriva de un público (var(--select-font-size-md), var(--select-font-size-xs), var(--select-font-size-sm), var(--select-font-size-lg)) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 2: font-size.
  • ⚠ decisión: el privado que alimenta este knob no se declara en el CSS (viene de base.ts o de un estilo inline) — hay que resolverlo antes de nombrarlo — 5: border-color, color, background.
  • ya alcanzable: el privado --_select-content-width deriva de un público (var(--_select-match-anchor-width, var(--select-content-min-width))) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 1: inline-size.
  • ya alcanzable: el privado --_select-content-padding-block deriva de un público (var(--select-content-padding-block-md), var(--select-content-padding-block-xs), var(--select-content-padding-block-sm), var(--select-content-padding-block-lg)) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 1: padding-block.
  • ya alcanzable: el privado --_select-content-padding-inline deriva de un público (var(--select-content-padding-inline-md), var(--select-content-padding-inline-xs), var(--select-content-padding-inline-sm), var(--select-content-padding-inline-lg)) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 2: padding-inline, padding-inline-end.
  • ⚠ decisión: 1 es un valor identidad o geometría de layout, no un knob de tema — el perímetro de «knob» es D-TH.2, sin firmar — 1: opacity.

4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)

  • Privado que no deriva de un público — §3 lo marca; el privado debe leer el público o desaparecer.
  • Velo o acento en el nodo equivocado (archetype: 'item' en un envoltorio, un background en shorthand que mata la capa de estado) — se mide desde el píxel hacia arriba.
  • Doble animación al mover un sello a una superficie con animación propia — registro de animationstart/animationend.
  • Diff de computed = 0 en reposo · hover · abierto · disabled · foco, por talla, antes y después.
  • Centinela por token nuevo: valor imposible en el root → el nodo lo sigue. Si no, el token miente.

5. Veredicto

(pendiente — lo escribe el autor; se conserva al regenerar)

Powered by TurnKey Linux.