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/date-range-picker.md

20 KiB

date-range-picker — 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-20 · Alcance: 42% — 22 de 52 knobs por token público
  • Knobs de apariencia: 55 — público 22 · privado 9 · global 19 · literal 2 · sistema 3 (fuera del ratio)
  • Contrato hoy (lib/recipes/base.ts): 24 pública(s) — accent-border, accent-track, accent-text, overview-gap, overview-width, overview-header-gap, overview-heading-fg, overview-heading-font-weight, overview-nav-size, overview-nav-radius, overview-nav-fg, overview-nav-font-size, hover-overview-nav-bg, overview-grid-gap, overview-cell-height, overview-cell-radius, overview-cell-fg, overview-cell-font-size, hover-overview-cell-bg, in-range-overview-cell-bg, in-range-overview-cell-fg, endpoint-overview-cell-bg, endpoint-overview-cell-fg, endpoint-overview-cell-border
  • Eje size: sí · ficheros: date-range-picker-time.css, date-range-picker.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (19)

# fichero:línea selector propiedad valor
1 date-range-picker-time.css:11 .range-time gap calc(var(--space-8) + var(--space-1))
2 date-range-picker-time.css:12 .range-time padding-block-start var(--space-2)
3 date-range-picker-time.css:13 .range-time border-block-start var(--border-width, 1px) solid var(--color-neutral-border)
4 date-range-picker.css:166 [data-date-range-picker][data-invalid] [data-field-control] border-color var(--field-invalid-control-border) ⤴ prestado de field
5 date-range-picker.css:189 [data-date-range-picker-trigger] border var(--field-control-border-width) solid var(--field-control-border) ⤴ prestado de field
6 date-range-picker.css:190 [data-date-range-picker-trigger] border-radius var(--field-control-radius) ⤴ prestado de field
7 date-range-picker.css:191 [data-date-range-picker-trigger] background var(--field-control-bg) ⤴ prestado de field
8 date-range-picker.css:217 [data-date-range-picker-trigger][data-disabled], [data-date-range-picker-trigger]:disabled opacity var(--field-disabled-opacity) ⤴ prestado de field
9 date-range-picker.css:232 [data-date-range-field-input] [data-date-range-picker-trigger] inline-size var(--field-segment-height) ⤴ prestado de field
10 date-range-picker.css:233 [data-date-range-field-input] [data-date-range-picker-trigger] block-size var(--field-segment-height) ⤴ prestado de field
11 date-range-picker.css:237 [data-date-range-field-input] [data-date-range-picker-trigger] border-radius var(--radius-sm)
12 date-range-picker.css:248 [data-date-range-field-input] [data-date-range-picker-trigger]:hover, [data-date-range-field-input] [data-date-range-picker-trigger]:focus-visible background var(--field-segment-active-bg) ⤴ prestado de field
13 date-range-picker.css:249 [data-date-range-field-input] [data-date-range-picker-trigger]:hover, [data-date-range-field-input] [data-date-range-picker-trigger]:focus-visible color var(--field-segment-active-text) ⤴ prestado de field
14 date-range-picker.css:271 [data-date-range-picker-calendar][data-range-calendar] gap var(--calendar-gap) ⤴ prestado de calendar
15 date-range-picker.css:279 [data-date-range-picker-calendar][data-range-calendar] color var(--calendar-fg) ⤴ prestado de calendar
16 date-range-picker.css:280 [data-date-range-picker-calendar][data-range-calendar] font-family var(--calendar-font-family) ⤴ prestado de calendar
17 date-range-picker.css:282 [data-date-range-picker-calendar][data-range-calendar] line-height var(--calendar-line-height) ⤴ prestado de calendar
18 date-range-picker.css:407 [data-date-range-picker-year-view-prev], [data-date-range-picker-year-view-next], [data-date-range-picker-month-view-prev], [data-date-range-picker-month-view-next] border var(--border-width) solid transparent
19 date-range-picker.css:433 [data-date-range-picker-year-view-cell], [data-date-range-picker-month-view-cell] border var(--border-width) solid transparent

1.2 A través de un privado (9)

# fichero:línea selector propiedad valor
1 date-range-picker.css:26 [data-date-range-picker] gap var(--space-1-5) var(--_date-range-picker-field-gap)
2 date-range-picker.css:29 [data-date-range-picker] font-size var(--_date-range-picker-field-font-size)
3 date-range-picker.css:186 [data-date-range-picker-trigger] inline-size var(--_date-range-picker-field-height)
4 date-range-picker.css:187 [data-date-range-picker-trigger] block-size var(--_date-range-picker-field-height)
5 date-range-picker.css:202 [data-date-range-picker-trigger]:hover border-color var(--_date-range-picker-field-accent-border)
6 date-range-picker.css:203 [data-date-range-picker-trigger]:hover background var(--_date-range-picker-field-accent-track)
7 date-range-picker.css:204 [data-date-range-picker-trigger]:hover color var(--_date-range-picker-field-accent-text)
8 date-range-picker.css:208 [data-date-range-picker-trigger]:focus-visible border-color var(--_date-range-picker-field-accent-border)
9 date-range-picker.css:281 [data-date-range-picker-calendar][data-range-calendar] font-size var(--_date-range-picker-calendar-font-size)

1.3 Literales (2)

# fichero:línea selector propiedad valor
1 date-range-picker.css:27 [data-date-range-picker] inline-size 100%
2 date-range-picker.css:272 [data-date-range-picker-calendar][data-range-calendar] inline-size max-content

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 date-range-picker.css:170 [data-date-range-picker][data-disabled] opacity var(--opacity-disabled)
2 date-range-picker.css:210 [data-date-range-picker-trigger]:focus-visible outline var(--focus-ring-width) solid var(--focus-ring-color)
3 date-range-picker.css:490 [data-date-range-picker-year-view-cell]:focus-visible, [data-date-range-picker-month-view-cell]:focus-visible outline var(--focus-ring-width) solid var(--color-primary-border)

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

privado declaraciones valor(es) origen ¿deriva de un público?
--_date-range-picker-field-height 4 var(--field-control-height-md), var(--field-control-height-xs), var(--field-control-height-sm), var(--field-control-height-lg) global no
--_date-range-picker-field-gap 4 var(--space-1), var(--space-0-5), var(--space-1-5) global no
--_date-range-picker-field-font-size 4 var(--field-control-font-size-md), var(--field-control-font-size-xs), var(--field-control-font-size-sm), var(--field-control-font-size-lg) global no
--_date-range-picker-field-accent-border 8 var(--date-range-picker-accent-border), var(--color-secondary-border), var(--color-neutral-border), var(--color-affirm-border), var(--color-fulfill-border), var(--color-risk-border) …(+2) global, public no
--_date-range-picker-field-accent-track 8 var(--date-range-picker-accent-track), var(--color-secondary-track), var(--color-neutral-track), var(--color-affirm-track), var(--color-fulfill-track), var(--color-risk-track) …(+2) global, public no
--_date-range-picker-field-accent-text 8 var(--date-range-picker-accent-text), var(--color-secondary-text), var(--color-neutral-text), var(--color-affirm-text), var(--color-fulfill-text), var(--color-risk-text) …(+2) global, public no
--_date-range-picker-calendar-font-size 8 var(--calendar-font-size-md), var(--calendar-font-size-xs), var(--calendar-font-size-sm), var(--calendar-font-size-lg) global no

4. Propuesta de corrección

  • Consume la capa compartida field-segment-state. Un eje que la capa posee se consume como var(--_x, var(--x)); el consumidor no acuña --date-range-picker-{eje} para él — sería un vocabulario paralelo (README de eidos/components, «Capas compartidas» regla 2).
  • Consume la capa compartida picker-shell. Un eje que la capa posee se consume como var(--_x, var(--x)); el consumidor no acuña --date-range-picker-{eje} para él — sería un vocabulario paralelo (README de eidos/components, «Capas compartidas» regla 2).
  • Consume tokens públicos de calendar, field. Un token prestado importa la semántica de su dueño: la corrección no es duplicarlo con prefijo propio, sino la decisión de familia que la auditoría de fase 1 dejó registrada (theming-audit.md §B, familia calendar).
  • 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 (37)

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 (--date-range-picker-…) scope TSC valor propuesto usos
hover-trigger-bg root ⚠ var(--date-range-picker-accent-track) / var(--color-secondary-track) / var(--color-neutral-track) / var(--color-affirm-track) / var(--color-fulfill-track) / var(--color-risk-track) / var(--color-threat-track) / var(--color-loss-track) / var(--field-segment-active-bg) 9
hover-trigger-fg root ⚠ var(--date-range-picker-accent-text) / var(--color-secondary-text) / var(--color-neutral-text) / var(--color-affirm-text) / var(--color-fulfill-text) / var(--color-risk-text) / var(--color-threat-text) / var(--color-loss-text) / var(--field-segment-active-text) 9
hover-trigger-border root ⚠ var(--date-range-picker-accent-border) / var(--color-secondary-border) / var(--color-neutral-border) / var(--color-affirm-border) / var(--color-fulfill-border) / var(--color-risk-border) / var(--color-threat-border) / var(--color-loss-border) 8
trigger-border root ⚠ var(--date-range-picker-accent-border) / var(--color-secondary-border) / var(--color-neutral-border) / var(--color-affirm-border) / var(--color-fulfill-border) / var(--color-risk-border) / var(--color-threat-border) / var(--color-loss-border) 8
trigger-radius root ⚠ var(--field-control-radius) / var(--radius-sm) 2
calendar-font-size-md size:md var(--calendar-font-size-md) 2
calendar-font-size-xs size:xs var(--calendar-font-size-xs) 2
calendar-font-size-sm size:sm var(--calendar-font-size-sm) 2
calendar-font-size-lg size:lg var(--calendar-font-size-lg) 2
gap root calc(var(--space-8) + var(--space-1)) 1
padding-block root var(--space-2) 1
gap-md size:md var(--space-1) 1
gap-xs size:xs var(--space-0-5) 1
gap-sm size:sm var(--space-0-5) 1
gap-lg size:lg var(--space-1-5) 1
font-size-md size:md var(--field-control-font-size-md) 1
font-size-xs size:xs var(--field-control-font-size-xs) 1
font-size-sm size:sm var(--field-control-font-size-sm) 1
font-size-lg size:lg var(--field-control-font-size-lg) 1
invalid-border root var(--field-invalid-control-border) 1
trigger-width-md size:md var(--field-control-height-md) 1
trigger-width-xs size:xs var(--field-control-height-xs) 1
trigger-width-sm size:sm var(--field-control-height-sm) 1
trigger-width-lg size:lg var(--field-control-height-lg) 1
trigger-height-md size:md var(--field-control-height-md) 1
trigger-height-xs size:xs var(--field-control-height-xs) 1
trigger-height-sm size:sm var(--field-control-height-sm) 1
trigger-height-lg size:lg var(--field-control-height-lg) 1
trigger-bg root var(--field-control-bg) 1
disabled-trigger-opacity root var(--field-disabled-opacity) 1
trigger-width root var(--field-segment-height) 1
trigger-height root var(--field-segment-height) 1
calendar-gap root var(--calendar-gap) 1
calendar-width root max-content 1
calendar-fg root var(--calendar-fg) 1
calendar-font-family root var(--calendar-font-family) 1
calendar-line-height root var(--calendar-line-height) 1

4.2 Sin nombre mecánico (5)

  • ⚠ decisión: border-block-start es shorthand o eje físico — hay que partirlo en ejes lógicos antes de nombrarlo (recipe-contract §1, R-4.4) — 1: border-block-start.
  • ⚠ 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 — 1: inline-size.
  • ⚠ decisión: border es shorthand o eje físico — hay que partirlo en ejes lógicos antes de nombrarlo (recipe-contract §1, R-4.4) — 3: border.

4.3 Avisos sobre los tokens propuestos (8)

  • ⚠ decisión: el valor es una expresión — el token puede llevar la expresión entera o sólo su término variable — --date-range-picker-gap
  • el privado --_date-range-picker-field-gap debe pasar a leer este público (o desaparecer) — --date-range-picker-gap-md, --date-range-picker-gap-xs, --date-range-picker-gap-sm, --date-range-picker-gap-lg
  • el privado --_date-range-picker-field-font-size debe pasar a leer este público (o desaparecer) — --date-range-picker-font-size-md, --date-range-picker-font-size-xs, --date-range-picker-font-size-sm, --date-range-picker-font-size-lg
  • el privado --_date-range-picker-field-height debe pasar a leer este público (o desaparecer) — --date-range-picker-trigger-width-md, --date-range-picker-trigger-width-xs, --date-range-picker-trigger-width-sm, --date-range-picker-trigger-width-lg, --date-range-picker-trigger-height-md, --date-range-picker-trigger-height-xs, --date-range-picker-trigger-height-sm, --date-range-picker-trigger-height-lg
  • el privado --_date-range-picker-field-accent-border debe pasar a leer este público (o desaparecer) — --date-range-picker-hover-trigger-border, --date-range-picker-trigger-border
  • el privado --_date-range-picker-field-accent-track debe pasar a leer este público (o desaparecer) — --date-range-picker-hover-trigger-bg
  • el privado --_date-range-picker-field-accent-text debe pasar a leer este público (o desaparecer) — --date-range-picker-hover-trigger-fg
  • el privado --_date-range-picker-calendar-font-size debe pasar a leer este público (o desaparecer) — --date-range-picker-calendar-font-size-md, --date-range-picker-calendar-font-size-xs, --date-range-picker-calendar-font-size-sm, --date-range-picker-calendar-font-size-lg

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

Revisión 2026-08-20 — verificación previa a implementación (Opus).

Análisis (§1–§3): CORRECTO en cifras (55 · 0 · 0 · 49 · 3 · 3), y el «privado 0» vuelve a ser falso de nombre: la receta declara localmente --_date-field-* (date-range-picker.css:7-12,33-34) y hasta --_calendar-font-size (:16,:39) — privados con prefijo de OTROS componentes, redeclarados por talla. Si un date-field o un calendar reales conviven cerca, los nombres se cruzan. Paso previo: renombrar ambos grupos a --_date-range-picker-* (mecánico, git ls-files antes).

Propuesta (§4.1): NO APTA tal cual — es el híbrido de sus dos familias y hereda los defectos de ambas:

  1. Lado calendar (filas calendar-*): alias de públicos de calendar → NO acuñar (nota de §4; purga de alias §39). Va con la decisión de familia calendar (theming-audit.md §B, préstamo medido: 38 tokens), bloque B7.
  2. Lado field (filas trigger-*, font-size, invalid-border, disabled-trigger-opacity): leen públicos de field y los privados renombrados del punto previo → mandato «Field composition» de theming-audit.md §5.3-3; se teman en la ficha del dueño, no aquí. Los hover-trigger-* con --_date-field-accent-*: promover el acento a público propio (accent-border/track/text) como en time-picker.
  3. Lo genuinamente propio y acuñable: la vista de década (year-view-*) — partes limpias, valores verbatim válidos. Corrección de nombres: las colisiones ⚠ de year-view-cell-fg/bg son estados sin parsear (seleccionado/en-rango/hoy) → separar por estado (selected-year-view-cell-*, etc.) leyendo el selector real. El year-view-prev-width/height = var(--control-height-sm) — comprobar contra el bundle (--size-sm-control-height computa idéntico) y usar la coordenada del bundle.
  4. Talla: el root estampa data-size ✓, pero el popup del calendario viaja por portal → cualquier token consumido dentro del content necesita parts o resolverse en el nodo portalado (verificar en la sonda §7.2 con el popup ABIERTO).

Bloqueos de firma: decisión de familia calendar · mandato field-composition · D-TH.4 (B7). Sin esas dos firmas, aquí sólo procede el renombrado de privados + year-view-*.


EJECUTADO 2026-08-20 (exactamente lo que no dependía de otra firma). Alcance 0 % → 42 % · contrato 0 → 22 claves públicas.

Hecho, los dos puntos que la revisión marcó como accionables:

  1. Renombrado de privados con prefijo ajeno: 44 --_date-field-* y 9 --_calendar-font-size que este CSS declaraba con el nombre de OTRO componente — se habrían cruzado con un DateField o un Calendar anidados. Ahora --_date-range-picker-*.
  2. La vista de década / mes a contrato: overview-* (separación, ancho, cabecera, navegación, rejilla, celdas) con los estados del rango separados por nombre (in-range-overview-cell-*, endpoint-overview-cell-*), que es justo la colisión que la propuesta automática tenía en year-view-cell-fg. Y el acento a público.

No hecho, con dueño: la mitad de calendario espera la decisión de familia calendar (§B) y la de campo el mandato de composición de Field (§5.3-3).

Verificación: diff de computed = 0 sobre 493 valores en 8 estados · component:audit PASS · suite eidos sin rojos nuevos · rtl:check 0 · docs:check 0.

Powered by TurnKey Linux.