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

9.7 KiB

textarea — 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: 87% — 20 de 23 knobs por token público
  • Knobs de apariencia: 26 — público 20 · privado 0 · global 0 · literal 3 · sistema 3 · excepción 2 · estructural 0 · puente 0 · canal 0 (los cinco últimos, fuera del ratio)
  • Contrato hoy (lib/recipes/base.ts): 37 pública(s) — input-font-size-xs, input-font-size-sm, input-font-size-md, input-font-size-lg, input-font-size-xl, input-padding-inline-xs, input-padding-inline-sm, input-padding-inline-md, input-padding-inline-lg, input-padding-inline-xl, input-padding-block-xs, input-padding-block-sm, input-padding-block-md, input-padding-block-lg, input-padding-block-xl, input-font-size, input-padding-inline, input-padding-block, gap, input-radius, input-border-width, input-border, hover-input-border, focus-input-border, invalid-input-border, input-bg, input-fg, input-placeholder-fg, input-font-family, input-font-weight, input-line-height, count-font-size, count-gap, count-fg, count-font-family, overflow-count-fg, overflow-count-font-weight · 1 privada(s) forward — _palette-solid
  • Eje size: no · ficheros: textarea.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (0)

Ninguno.

1.2 A través de un privado (0)

Ninguno.

1.3 Literales (3)

# fichero:línea selector propiedad valor
1 textarea.css:23 [data-textarea] inline-size 100%
2 textarea.css:51 [data-textarea-input] inline-size 100%
3 textarea.css:117 [data-textarea-count] line-height 1

1.4 Excepciones firmadas (2) — 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 textarea.css:75 [data-textarea][data-focused] [data-textarea-input] border-color var(--_textarea-border-focus)
2 textarea.css:95 [data-textarea][data-variant='ghost'][data-focused] [data-textarea-input] border-color var(--_textarea-border-focus)

2. Sistema transversal (3) — 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 textarea.css:78 [data-textarea][data-focused] [data-textarea-input] outline var(--focus-ring-width) solid var(--focus-ring-color)
2 textarea.css:100 [data-textarea-input][data-disabled] opacity var(--opacity-disabled)
3 textarea.css:126 [data-textarea-count-sep] opacity var(--opacity-muted)

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

privado declaraciones valor(es) origen ¿deriva de un público?
--_textarea-border-focus 2 var(--textarea-focus-input-border), var(--_textarea-palette-solid) private, public no
--_textarea-resize 4 vertical, none, horizontal, both literal no

Consumidos y no declarados en el CSS (vienen de base.ts o de un estilo inline del wrapper): --_textarea-palette-solid.

4. Propuesta de corrección

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 (--textarea-…) scope TSC valor propuesto usos
input-border (ya existe) root var(--_textarea-border-focus) 1
ghost-input-border root var(--_textarea-border-focus) 1

4.2 Sin nombre mecánico (3)

  • ⚠ 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.
  • ⚠ 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: line-height.

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

Medido 2026-08-21 (sonda ×2 sobre el mismo código = 0 diffs en 1.247 valores · 8 estados). La §4 propone 35 tokens y cuatro de ellos son colisiones que hay que partir o retirar, más un error que cambiaría el default. Corregido queda en 37 claves.

  1. count-font-size-{k} × 5 BORRARÍA el factor 0.85 — es el error grave de la propuesta. El CSS calcula calc(var(--_textarea-font-size) * 0.85) (con su anotación /* literal: */), y la §4 propone cinco tokens con el font-size del INPUT crudo: el contador crecería un 18 % en las cinco tallas. D-TH.5 lo prohíbe. La corrección: UN token count-font-size que conserva el calc sobre el público del input, así sigue la talla sin repetir la escala. Mismo reparto que tree-grid.guide-fg — el knob es el valor, la construcción se queda en la receta.
  2. input-fg ⚠ son DOS knobs: la tinta del texto (--color-content-primary) y la del placeholder (--color-content-muted). El clasificador las fundió por caer ambas sobre la parte input. → input-fg + input-placeholder-fg (precedente exacto: command.input-fg / command.input-placeholder-fg).
  3. count-fg ⚠ son DOS knobs: reposo (content-muted) y rebasado (threat-text). → count-fg + overflow-count-fg; overflow es valor de data-overflow, declarado en el morfo (textarea.ts:163), así que entra como modificador delante.
  4. input-border ⚠ NO son dos knobs, y su nombre está mal. Los dos valores son UNA variable (--_textarea-border-focus) con su swap de paleta: --focus-ring-color de base y --_textarea-palette-solid cuando hay data-color. El swap es el forward THM-2 y se queda privado. Y el knob es el borde de FOCO, no el de reposo → focus-input-border. El de reposo (--color-neutral-border) es otro token, que la §4 ni listó porque viaja dentro del atajo border:.
  5. ghost-input-border ⚠ se RETIRA de la propuesta: la regla ghost lee exactamente la misma --_textarea-border-focus que la regla base. Un token propio sería un duplicado con dos nombres para un valor.
  6. border shorthand se parte en input-border-width + input-border (color) — molde command.input-border / input-border-width.
  7. Qué casa con el bundle, medido (generated/base.css:409-450):
    • font-size casa 1:1 en las cinco (font-size-{k} ES --size-{k}-font-size) → van al bundle.
    • padding-inline casa en sm/md/lg/xl pero NO en xs: el textarea pone --space-2 (8px) donde el bundle dice --space-1-5 (6px).
    • padding-block no casa en ninguna salvo xs: sm 6px vs 4px, md 8px vs 6px, lg 12px vs 8px. El campo multi-línea respira más que un control de una línea, y es correcto. Los dos ejes de spacing van verbatim en --space-*, con la desviación escrita: el guard del bundle gobierna control-height / font-size / icon-size, no el spacing (precedente table.cell-padding-* y tree-grid.row-padding-*). Los resueltos sin parts — data-size se estampa en [data-textarea] y el input hereda; molde command.
  8. Fuera del contrato, a propósito: los dos inline-size: 100% y el line-height: 1 del count (identidad, D-TH.2); --_textarea-resize, que no es apariencia sino el enum de comportamiento que el morfo conduce; y el forward de paleta.
  9. Alcance final 80 % (20 de 25) — mi propia predicción de «≈100 %» era errónea y la medición la corrigió. Cero globales y cero privados de valor: los 16 de la propuesta leen ya su público. Lo que queda son las DOS declaraciones que consumen --_textarea-border-focus (base y ghost), que el censo cuenta como private porque el privado sobrevive a propósito — es el conmutador de una variable con dos fuentes (el token público y el forward de paleta), y aplanarlo exigiría duplicar la regla por color. Es el mismo techo de listbox (68 % por consumir bien su capa) y el mismo que §13 registra para los forwards THM-2: la métrica penaliza hacer lo correcto. Más los tres literales de identidad (dos 100% y el line-height: 1 del contador), fuera del perímetro por D-TH.2.

Powered by TurnKey Linux.