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/progress.md

11 KiB

progress — 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-25 · Alcance: 93% — 26 de 28 knobs por token público
  • Knobs de apariencia: 30 — público 26 · privado 0 · global 2 · literal 0 · sistema 0 · excepción 6 · estructural 0 · puente 0 · canal 2 (los cinco últimos, fuera del ratio)
  • Contrato hoy (lib/recipes/base.ts): 43 pública(s) — height-xs, height-sm, height-md, height-lg, height-xl, vertical-height, row-gap, column-gap, radius-xs, radius-sm, radius-md, radius-lg, radius-xl, ring-size-xs, ring-size-sm, ring-size-md, ring-size-lg, ring-size-xl, ring-thickness-xs, ring-thickness-sm, ring-thickness-md, ring-thickness-lg, ring-thickness-xl, label-font-family, label-font-size, label-font-weight, label-line-height, label-fg, value-text-font-family, value-text-font-size, value-text-font-weight, value-text-line-height, value-text-fg, track-bg, ring-track-bg, ring-center-bg, indicator-bg, indicator-bg-loaded, transition-duration, transition-ease, indeterminate-width, indeterminate-duration, indeterminate-ease
  • Eje size: sí · ficheros: progress.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (2)

# fichero:línea selector propiedad valor
1 progress.css:127 [data-progress][data-shape='circular'] [data-progress-indicator] border-radius var(--radius-full)
2 progress.css:139 [data-progress][data-shape='circular'] [data-progress-indicator]::before border-radius var(--radius-full)

1.2 A través de un privado (0)

Sólo el residuo: el puente de paleta (§2-ter) y el canal de valor (§2-quater) salen aparte, porque no son deuda ni tienen nombre que acuñar.

Ninguno.

1.3 Literales (0)

Ninguno.

1.4 Excepciones firmadas (6) — fuera del ratio

Literales que llevan su anotación /* literal: <razón> */ en la propia declaración: la válvula de recipe-contract §3, la misma que honra component-audit. Una desviación firmada no es deuda — se listan para que la razón se lea, no para acuñarlas.

# fichero:línea selector propiedad valor
1 progress.css:13 [data-progress] inline-size 100%
2 progress.css:45 [data-progress][data-orientation='vertical'] inline-size max-content
3 progress.css:55 [data-progress-indicator] inline-size 100%
4 progress.css:82 [data-progress][data-orientation='vertical'] [data-progress-indicator]::before inline-size 100%
5 progress.css:103 [data-progress][data-orientation='vertical'][data-state='indeterminate'] [data-progress-indicator]::before inline-size 100%
6 progress.css:108 [data-progress][data-shape='circular'] inline-size max-content

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

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

Ninguno.

2-quater. Canal de valor (2) — fuera del ratio

La receta lee un privado que nadie declara — ni su CSS ni el generador: lo escribe soma o el envoltorio por instancia (un %, un rect medido, la talla que pide una prop). Un tema no debe alcanzarlo: fijarlo rompe el comportamiento, y por eso tabs rechazó por escrito esa misma propuesta.

# fichero:línea selector propiedad valor
1 progress.css:67 [data-progress-indicator]::before inline-size calc(var(--_progress-value-pct, 0) * 1%)
2 progress.css:83 [data-progress][data-orientation='vertical'] [data-progress-indicator]::before block-size calc(var(--_progress-value-pct, 0) * 1%)

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

privado declaraciones valor(es) origen ¿deriva de un público?
--_progress-height 5 var(--progress-height-md), var(--progress-height-xs), var(--progress-height-sm), var(--progress-height-lg), var(--progress-height-xl) public sí
--_progress-radius 5 var(--progress-radius-md), var(--progress-radius-xs), var(--progress-radius-sm), var(--progress-radius-lg), var(--progress-radius-xl) public sí
--_progress-ring-size 5 var(--progress-ring-size-md), var(--progress-ring-size-xs), var(--progress-ring-size-sm), var(--progress-ring-size-lg), var(--progress-ring-size-xl) public sí
--_progress-ring-thickness 5 var(--progress-ring-thickness-md), var(--progress-ring-thickness-xs), var(--progress-ring-thickness-sm), var(--progress-ring-thickness-lg), var(--progress-ring-thickness-xl) public sí
--_progress-indicator-bg 2 var(--progress-indicator-bg), var(--progress-indicator-bg-loaded) public sí

Consumidos y no declarados en el CSS (vienen de base.ts o de un estilo inline del wrapper): --_progress-value-pct.

4. Propuesta de corrección

  • 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 (2)

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 (--progress-…) scope TSC valor propuesto usos
width root max-content 2
indicator-radius root var(--radius-full) 2

4.2 Sin nombre mecánico (4)

  • ⚠ 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 — 4: inline-size.

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

Ejecutado 2026-08-23 — 69 % → 87 %. Dos claves acuñadas, seis literales firmados, cuatro knobs adjudicados. Diff de computed 0 sobre 60 configuraciones (2 formas × 2 orientaciones × 3 estados × 5 tallas) y capturas 2× idénticas byte a byte. Guard R-5.4: 40 de 43 tokens mueven un computed; los tres callados, medidos y escritos en el ledger.

Lo que entra (2 claves, el ÚNICO knob que iba a un primitivo a pelo):

  • row-gap (--space-2) y column-gap (--space-3). Eran un gap en atajo de DOS valores distintos, y por eso se parte: el hueco de fila separa la línea de texto de la barra, el de columna separa el rótulo del valor. Un gap único habría nombrado un knob para dos. El catálogo tiene las dos palabras (row-gap ×10, column-gap ×4) y el molde exacto es chart.legend-row-gap / -column-gap.

Lo que se FIRMA en vez de acuñarse (6 literales, fuera del ratio): los cuatro 100% y los dos max-content son la geometría de la barra, no una decisión de tema — llena la fila que le dan (100%) o se encoge a su propio grosor / diámetro (max-content). Llevan su /* literal: <razón> */ en la declaración; válvula de recipe-contract §3.

Lo que se RECHAZA de la propuesta §4 (dos de las tres filas):

  1. indicator-radius — el --radius-full del anillo. Su gemelo meter ya dejó el veredicto escrito EN EL CSS: es lo que hace circular a shape='circular', y un token dejaría que un tema des-redondease una forma que el consumidor pidió POR SU NOMBRE. Identidad, no knob. Se copia el comentario del gemelo. Son los dos únicos global que quedan, y el censo no puede sacarlos del ratio: la válvula /* literal: */ sólo reclasifica la clase literal, nunca un global (mismo techo que meter).
  2. width: max-content — la §4 fundía en UN nombre dos nodos distintos (la raíz vertical y la raíz circular) y además lo llamaba por el primer selector, no por lo que pinta. Es el literal de identidad de arriba.

Los dos knobs private que quedan son el CANAL DE VALOR, no deuda. --_progress-value-pct lo escribe soma en el estilo inline del provider en cada render (progress-provider.svelte.ts, 0–100 saturado); la receta lo lee para el ancho del relleno lineal y el alto del vertical. Un público encima mentiría: un tema no puede fijar el progreso de una tarea. Es la misma clase que el z-index inline de drag-drop y el gap de carousel. Con ellos y con los dos --radius-full de identidad, el techo honesto de este componente es 87 %, no el 100 %.

Lo que el guard da por callado (3 de 43, todos medidos sobre el nodo real):

  • indicator-bg-loaded — sólo pinta bajo [data-state='loaded'], y la corrida mantiene indeterminate encendido para alcanzar los tokens del barrido: forzado → oklch(0.6406 0.1329 157.68) → rgb(1,2,3).
  • transition-duration / transition-ease — los congela el propio guard por diseño; pasada SIN congelar → 0.18s → 11.5s y cubic-bezier(0.4, 0, 0.2, 1) → steps(7). Mismo par que en meter.

Lo que enseñó el instrumento. La sonda estándar mide 4 nodos — que son TODAS las partes del morfo — pero una sola configuración: lineal, horizontal, loading, md. Medio contrato (el anillo, el eje vertical, el barrido indeterminado, la tinta de completado) no entra en ese diff, y el gate habría pasado en verde sin haberlo mirado. El guard lo dijo antes: 22 de 41 en la página por defecto. Con sweepAttr: data-shape (el interruptor que su gemelo meter ya tenía) sube a 34; encendiendo el interruptor indeterminate de la demo, a 37; y el chip vertical, a 38 — cada control comprobado por separado, antes y después, porque montar más puede medir menos. Aquí no tapó ninguno.

Y una trampa nueva del instrumento, medida aquí: una sonda que CACHEA los nodos y luego mide en bucle da 8.352 falsos diffs si el HMR reemplaza el subárbol a mitad de corrida — getComputedStyle sobre un nodo DESACOPLADO devuelve la cadena VACÍA en todas las propiedades, y el diff lee cada vacío como un cambio. Se arregla re-consultando los nodos en cada instantánea, y se detecta haciendo fallar la sonda ante un computed vacío. Es pariente de hmr-stale-tab-phantom-findings, con otra cara.

Powered by TurnKey Linux.