9.8 KiB
Continue tomorrow
Fecha de corte: 2026-05-27. Rama: active-uix. Working tree con cambios
sin commitear listos para push.
TL;DR de la sesión
Sesión maratón del Token Scope Contract — del bug del toggle (ya conocido) hasta cobertura universal sin excepciones arquitectónicas:
- Diagnóstico inicial: usuario reporta "el toggle no funciona, el color del intent no cambia". Eager-resolution de CSS custom properties en el cascade del toggle.
- TSC v1 → v2 → v2.1 → v2.2: 4 iteraciones del Token Scope Contract. Cada una cerrando un gap (scope explícito, álgebra de cobertura, private tokens, multi-part + composition).
- Universal migration: 18 componentes con
data-colormigrados a TSC (15 con TSC v2.1, + 3 con extensiones v2.2 de hoy). - Bug crítico post-composition: la toggle-group composition
correctamente override
--toggle-palette-*pero el cascade colapsaba downstream porque los derived tokens (--toggle-solid-on-bgetc.) viven en scope[data-toggle](sibling, no ancestor, de[data-toggle-group-item]). Fix: inlined derivations en toggle-group.css con palette-direct refs. - Bundle JIT purge (
scripts/eidos-purge.ts): tool standalone que tree-shakes elgenerated/base.csspor componente, var() ref, data-attr y component import. Reduce ~50% el bundle final. - Docs: THEMING.md (~1700 líneas) como referencia canónica del theming. CLAUDE.md con 5 hand-offs del 2026-05-27. Eidos README actualizado.
Tareas completadas hoy (resumen)
Total: 87 tareas TaskList. Sprint TSC ocupa #50–#87. Highlights:
- TSC v1 (#50–#56): primera versión —
scope/dependsexplícitos, generator agrupando por scope. - TSC v2 (#57–#62): álgebra de scope (ScopeSet covers), cross-axis collision detection, var() auto-inferred deps, color:* rename.
- P0–P2 housekeeping (#63–#68): rename
--{c}-color-{role}-{slot}→--{c}-{role}-{slot}, JIT purge script. - CONSOL + GAP (#69–#73): consolidación de docs, universal anti-eager- resolution guard test.
- UNIV (#75–#79): private tokens (
_prefix) + migración universal de 13 componentes. - EXT (#80–#86): TSC v2.2 — multi-part
parts+ cross-recipecomposition+ 3 componentes restantes migrados (select,toggle-group,avatar) + docs. - EXT-FIX (#87): bug del toggle-group color cascade tras la composition migration.
Patrones canon nuevos en esta sesión
Token Scope Contract (TSC) — la fuente de verdad
Cada recipe token tiene un scope explícito que materializa el selector
CSS donde se emite. El generator infiere deps de los var() y valida
álgebra de cobertura. Imposible introducir el bug eager-resolution si
declaras tokens en TSC — el validator lo rechaza antes de generar CSS.
Formas:
recipes.toggle = {
'height-md': '32px', // shorthand → root
'solid-on-bg': { // single decl
value: 'var(--toggle-palette-solid)', scope: 'host'
},
'palette-solid': { // multi-decl
declarations: [
{ value: 'var(--toggle-neutral-solid)', scope: 'host' },
{ value: 'var(--toggle-affirm-solid)', scope: 'color:affirm' }
]
}
}
TSC v2.2 — parts: [...] para multi-part scope
'_accent-track': {
parts: ['trigger', 'content'],
declarations: [
{ value: 'var(--select-primary-track)', scope: 'host' },
{ value: 'var(--select-affirm-track)', scope: 'color:affirm' }
]
}
// → emits:
// [data-select-trigger], [data-select-content] { --_select-accent-track: ... }
// [data-select-trigger][data-color='affirm'], [data-select-content][data-color='affirm'] { ... }
Único consumer hoy: select (Trigger + Content). Cualquier componente
que tenga atributos cascadeados per-part (no en root) usa este patrón.
TSC v2.2 — composition: { ... } para cross-recipe override
'toggle-group': {
gap: 'var(--space-1)',
composition: {
toggle: { // foreign recipe
targetSelector: '[data-toggle-group-item]',
tokens: {
'palette-solid': {
declarations: [
{ value: 'var(--toggle-affirm-solid)', scope: 'color:affirm' },
{ value: 'var(--toggle-risk-solid)', scope: 'color:risk' }
]
}
}
}
}
}
// → emits:
// [data-toggle-group][data-color='affirm'] [data-toggle-group-item] {
// --toggle-palette-solid: var(--toggle-affirm-solid);
// }
Único consumer hoy: toggle-group. Pattern reutilizable para futuros
wrappers compositivos (button-group, nav-menu, etc.).
Private tokens (_ prefix)
Recipe key _palette-solid → CSS var --_toggle-palette-solid (con
underscore prefix). NO aparece en el public CSS contract. Solo accesible
desde la propia CSS recipe del componente. Convención: usar para slots
intermedios de derivation que no quieres exponer como theming knobs.
Inline derivation cuando el ancestor scope no aplica
Anti-pattern: leer var(--{foreign-component}-derived-token) desde
un elemento que NO es descendant del scope donde se declaró ese token.
Resultado: undefined → cascade colapsa.
Pattern correcto: inline la derivation expression localmente. Ejemplo
en toggle-group.css para [data-toggle-group-item] — replica las
expressions de recipes/base.ts > toggle.{solid,outline,ghost}-*
directamente. Duplicación documentada y aceptada como trade-off.
Trabajo acumulado SIN commitear
Modificados (eidos + soma touched durante TSC sprint):
M src/uix/eidos/components/avatar/avatar.css
M src/uix/eidos/components/badge/badge.css
M src/uix/eidos/components/button/button.css
M src/uix/eidos/components/card/card.css
M src/uix/eidos/components/checkbox/checkbox.css
M src/uix/eidos/components/editable/editable.css
M src/uix/eidos/components/file-upload/file-upload.css
M src/uix/eidos/components/radio-group/radio-group.css
M src/uix/eidos/components/select/select.css
M src/uix/eidos/components/stepper/stepper.css
M src/uix/eidos/components/switch/switch.css
M src/uix/eidos/components/tag-group/tag-group.css
M src/uix/eidos/components/tags-input/tags-input.css
M src/uix/eidos/components/toggle-group/toggle-group.css
M src/uix/eidos/components/toggle/toggle.css
M src/uix/eidos/README.md
M CLAUDE.md
M package.json (npm script para eidos:purge añadido)
Modificados (words component sprint en paralelo — no este chat):
M src/uix/eidos/components/words/*
M src/uix/soma/components/words/*
M src/uix/words/README.md
M web/routes/uix/components/words/*
Eliminado:
D src/docs/libro_semantica_completo.txt (reemplazado por .docx)
Untracked (TSC v2.2 + auxiliares):
?? scripts/eidos-purge.ts
?? scripts/probe-*.ts (5 probe scripts del debug session)
?? src/docs/Disenando_lo_que_ocurre_manuscrito_completo_revisado_v2.docx
?? src/uix/eidos/THEMING.md
?? src/uix/eidos/THEMING_AUDIT_2026-05-27.md
?? src/uix/eidos/components/words/* (slash menu, family menu, code lang picker)
?? src/uix/soma/components/words/components/words-slash-menu.svelte
?? src/uix/soma/components/words/engine/code-highlight.ts
?? src/uix/words/references/* (4 audit docs + 1 screenshot)
Variants son canon — NO theme-extensibles
Decisión arquitectónica documentada hoy en THEMING.md §19. Los
variants (solid, outline, ghost, soft, surface, etc.) son
fijos a nivel del framework — paralelos a las 8 sema families. El
theme solo cambia palette/shadows. La fuente de verdad es la const
EIDOS_VARIANTS en lib/types.ts con 5 archetypes
(control / selection / chip / marker / tabs); los unions
TS se derivan de ella via [number] indexed access.
Variants component-specific (Banner inline/overlay/persistent,
Spinner bars/dots/ring, Button 'plain') viven en cada
components/{c}/types.ts. El lint
recipe-css-contract.test.ts > variant CSS selectors per component match the declared type union valida bidireccionalmente que CSS
selectors y type unions coincidan.
Cómo retomar mañana
-
Probar toggle-group en navegador:
- El bug del cascade fue corregido inlining derivations en
toggle-group.css. Pero el fix no se probó en navegador. Si el cascade sigue roto en algún caso, revisar las inlined expressions contrarecipes/base.ts > toggle.{solid,outline,ghost}-*.
- El bug del cascade fue corregido inlining derivations en
-
Avatar regenerado: la migración TSC v2.2 produce un orden de selector ligeramente distinto al original (
[data-color][data-variant]en lugar de[data-variant][data-color]). Mismo CSS efectivo — misma especificidad. Si algún test snapshot rompe, regenerar. -
Próximo trabajo natural en TSC (NO urgent):
- Si más componentes necesitan multi-part scope o composition, ya está todo soportado — solo añadir las recipes.
- Considerar
radius:/ring-color:como AtomicScope adicionales si el avatarring-colorcascade emerge como pattern recurrente.
Comandos útiles
cd G:/dev/svelte/vicen
npm run check # svelte-check
npm run test # full vitest run
npx vitest run src/uix/eidos # eidos-only (100 tests)
npm run generate:eidos-css # regen src/uix/eidos/generated/base.css
npx tsx scripts/eidos-purge.ts <route> # JIT purge para una ruta
Referencias canónicas tras la sesión
- Theming completo:
src/uix/eidos/THEMING.md(1700+ líneas, §18 reescrito hoy como "Cobertura universal de TSC", §7 ampliado con multi-part + composition). - Hand-offs:
CLAUDE.md§"Session hand-off — 2026-05-27 #5" (TSC v2.2 + cobertura universal de theming). - Recipe authoring guide:
THEMING.md§7 (TSC) + §8 (añadir componente nuevo). - Anti-eager-resolution guard:
src/uix/eidos/recipe-css-contract.test.tstest "forbids palette-derived tokens at :root scope".