astra
alpha-0.1-background
alpha-0.1-dir-prefs
alpha-0.1-sec-dom
menubar-v4-safe
active-uix
morfo-runtime
morfo-driven-soma
semantuix
glm-5
main
sium-v1.0
${ noResults }
28 Commits (6f42eebfe80bc9ac5656be2bbf621c6d62e768fb)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
6f42eebfe8 |
feat(morfo,sema,eidos): todo evento dice de que familia es, y el cruce por fin se ve
El framework llamaba a la misma cosa de dos maneras: `open` pelado en ocho
componentes y `emerge-open` en tres. No era estetica — un preset de movimiento
engancha el nombre con `^=`, asi que el dialecto pelado no casaba con ninguna
firma y simplemente no animaba, sin romper una sola prueba.
Los 40 nombres sin prefijo pasan a `{familia}-{verbo}[-{matiz}]`: 256 eventos,
256 con prefijo, 0 ambiguos. El plan decia 36 y decia `handle-drag-start`; eran
40, y el canon (c25) dice que esos verbos son `pick` y `drop` — `handle-pick` y
`handle-drop` ya existian en 10 y 4 componentes.
`validateMorfo` cierra la puerta: un `events[].name` que no empiece por su
familia ahora lanza. Visto fallar antes con un nombre pelado inyectado.
Lo que el renombrado destapo, y va aqui tambien:
- La receta del splitter enganchaba `commit-resize`, muerto desde
`bd2e40366`. No casaba desde mayo y nadie chillo. Reescrita por FAMILIA, como
slider y knob, y `eidos-lint` valida ahora el VALOR de `data-event*` contra el
catalogo de morfos — el guard que lo habria cazado en su dia.
- La familia `shift` era muda en el canal visual, contra su propia doctrina
(c27: el cruce debe percibirse; c34 tipifica el «shift invisible»). Su mapa ya
describia la firma que le faltaba y su sonido por defecto es `slide`. Ahora
tiene firma direccional: sexto atributo del sello (`data-event-direction`,
`forward`|`backward`, por emision) y deslizamiento de 320ms RTL-safe por
`:dir()`. Medido: LTR -30px/+30px, RTL los invierte.
- El sello de `shift-navigate` pasa del BOTON al `grid` en los cuatro
calendarios. Medido: el boton recibia `contact-activate` y 8,5 ms despues
—media trama— el `shift-navigate` pisaba la misma ranura y el `press-squeeze`
moria sin pintar un fotograma. Una superficie, una ranura (A-36).
- 101 contradicciones docs<->morfo adjudicadas con evidencia (git log, docs de
decision, el componente vivo). Las docs desfasadas, corregidas; los nueve
DEFECTOS de codigo obsoleto quedan abiertos y sin tocar.
- `SoundDirection` -> `SoundContour`: era un contorno de tono, no un sentido, y
habia tres cosas distintas deletreadas «direction».
check en su linea base con 0 errores nuevos por diferencia de conjuntos ·
docs:check 0/0 · eidos-lint invalid 0 · el censo y las escenas de navegador
medidas con raton real y rAF vivo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
3097cfcb69 |
revert: deshacer la auditoría entera — se hizo sin leer la doctrina
Revert de los 7 commits de la sesión del 2026-07-29/30: |
2 months ago |
|
|
c39170abbf |
fix(uix): la auditoría del sistema — lo que los guards no veían
Auditoría clean-room de todo ActiveUIX (excluido `web/`), componente a
componente. Lo que sale de aquí no es una lista de bugs: es un patrón.
El framework validaba que lo escrito fuese VÁLIDO, no que lo declarado
se CUMPLIESE — y sus guards fallaban ABIERTOS.
## El colapso de las uniones de props (95 → 0)
Un `Props` de eidos es `{ …props propias… } & <atributos nativos>`.
Cuando el elemento declara un atributo homónimo, la intersección funde
ambos y una unión estrecha contra el `string` nativo COLAPSA a `string`.
Causa: `Without<T, U> = Omit<T, keyof U>` invocado como `Without<T, {}>`
— `Omit<T, never>`, un no-op — 433 veces en soma; sólo 3 con argumento
real. Invisible para `svelte-check`: ensanchar un tipo no es un error,
es una garantía perdida.
Medido: 95 props en 72 componentes. `<Avatar color="nonsense">`
compilaba. `ComboboxInput.size` chocaba con el `<input size>` numérico
y era inusable. Migrado con codemod sobre AST (nunca regex) a
`Own & Omit<Nativos, keyof Own>`: 92 tipos en 73 ficheros + carousel a
mano. `check` no se movió.
Garantía nueva: `eidos/prop-surface.test.ts` (PROP-1) compara los
literales de la anotación del autor contra los de la propiedad pública.
Verificado que falla reintroduciendo el defecto.
## Los cuatro guards que fallaban abiertos
- `translations:check` crasheaba en CADA ejecución de su historia — un
stripper de comentarios borraba `//` dentro de strings. Sustituido por
import dinámico. Al arrancar destapó 8 slots `texts` sin traducción.
- `soma-attr-audit` agotaba el timeout de 5 s: sin veredicto, verde por
omisión.
- `component-audit` D-7.4 hacía `continue` mudo cuando el tipo no
resolvía. Ahora resuelve con el checker de TypeScript
(`scripts/prop-unions.ts`): puntos ciegos de 124 → 3.
- `component-audit` R-1.1: el regex casaba `[data-motion='reduce']` y
daba PASS por el motivo equivocado.
Regla adoptada: un guard que no puede evaluar TIENE que decirlo. El
informe lleva ahora bloque «Not verified» y recuento en el resumen.
## D-1 · tooltip y D-2 · card, cableados
`tooltip` declaraba 3 eventos `emerge` que nadie emitía. Ahora emiten;
`present` pasa a `sequence: 'post'` — con `'pre'` el hold de ~240 ms
gateaba el montaje del propio overlay.
`card` declaraba `commit-select` sin emisor posible (scope sin soma).
Puente headless en `soma/components/card/` con la forma ya establecida
por `menu-dial` / `onion-menu`: eidos posee estado y render, soma posee
sólo el `SomaRuntime` que emite.
## Documentación: 22 mentiras corregidas
`docs/` afirmaba guards inexistentes (`NO_MISSING_PROVIDER_TESTS`),
APIs con firma equivocada y un modelo de Motion que el código no
implementa. Corregido en CANON, arquitectura, glosario, theming/motion,
checklist y los README de `motion` / `callout` / `arts/motion`.
## Además
- CardGroup: la descripción se metía en la primera celda del grid.
- Motion: `data-state` siempre estampado, salida real en `leave()`,
token fantasma `--motion-stagger-each-default` eliminado.
- `engine-motion`: `handoffState` Map → WeakMap (fuga por nodo).
- `mockup`: primitivo crudo → token de rol (R-4.6).
- 5 catálogos de traducción que faltaban.
Handoff: `docs/process/CONTINUE-audit-2026-07-29.md`.
Batería: check 0 errores en src · vitest server 3701/3701 ·
docs:check 0/0 · component:audit 161 PASS / 2 NEEDS-WORK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2 months ago |
|
|
528ddaa7f9 |
uix(color): abre `color` en listbox · timeline · combobox
Migra los 3 al forward de paleta compartido, cada uno con su matiz: - listbox: 2 slots (solid = indicador activo, element = fila seleccionada), raíz bare `[data-listbox]`. El `accent-text` era código muerto (sin consumidor) → eliminado. Recipe nuevo. - timeline: 5 slots (solid/track/border/contrast/text) que alimentan `--_timeline-hue-*` del item; data-intent por item sigue mandando sobre el acento del root. Tipo ProgressiveColorRole → ComponentColorProp. Recipe existente ampliado. - combobox: la cascada vivía en CUATRO partes (control/input/trigger/content), así que el forward las cubre vía `parts: [...]` (forma declarations[]). 3 slots (track/border/text). Los 5 wrappers (root + 4 partes) pasan por `resolveComponentColor` para que el custom hex no se estampe crudo. Recipe existente (content-z) ampliado. Verificado en navegador: combobox data-color=risk → palette-border del control = token risk compartido; custom #00b894 → color-mix. table (lote previo) idem. check: 76 ajenos, 0 propios. Contract 26/28 (2 = proof-of-human pre-existente). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
53b6f629f2 |
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the checkpoint verdicts in docs/audit/components/) and the executed fix packages. - P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 + API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d, component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts (role=application removed ×4, aria-selected off the Day, drp translationRef, field data-state prune, pin-input commit-set, media-player renames), 13 new sema packs + 12 morfos family-default → pack. - P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar); onValueCommit terminal-callback norm (pin-input/search/password/textarea + date/time/color-field add); typed validation reason + onInvalid (tags-input, css-field); index/onIndexChange (carousel); deselectable; openDelay/ groupSkipDelay; allowCustomValue; defaultValue prune. - P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel); touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual, 44 AAA). S6 (Field composition) + S8 (calendar-surface) pending. Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline); morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched components; per-component vitest suites green. Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md Excluded (broken by the N1 rename, left broken per user decision, not staged): words/**, palabras/**, chronos, web/routes/alpha/**. Reconciliation pending: the touch-rows ::before for checkbox/switch reverses changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed markers to a labeled-row/Field task — flagged for the user in the handoff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
3b08711d77 |
fix(uix): C3 — literal typography swept across 16 recipes (R-2.7 clean)
Two classes. Real fixes: 8 numeric font-weights tokenized to var(--font-weight-medium/semibold/regular) in command, date-range-picker, link-preview, listbox, menubar, textarea, time-range-picker x2 — same rendered weight, but the foundation now propagates (verified in a live browser: the token resolves to 500). Honest annotations: the proportional/identity literals get their /* literal: <reason> */ valve instead of a fake token — avatar initials/badge scale with the avatar diameter (physically proportional), the calc(1em - (md - sm)) family is the Field label-one-step-down doctrine with a token-derived delta, 1em is context identity (fab glyph, password toggle), the x0.85 captions are proportional to their field token, and combobox's -1px is an optical adjustment on a token-derived size. component:audit R-2.7: 16/16 clean; npm run check at the 61-error baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
3095065f0c |
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions
Fable audit follow-through (fable_audit.md + fable-eidos-audit.md): - RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must consume, enforced by component-audit R-4.1-4.6 (all at error; escape valves /* literal */ + /* functional */; WIP tracks excluded). Stale audit rules fixed against the current architecture (E-2.2 wrapper imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant mirror) - verdicts went 0/117/15 -> 75/50/5. - Motion migration 15/15: recipes off local @keyframes onto the channel - preset stamps (dropdown/context/select/combobox/tooltip/link-preview/ clipboard), new expand/collapse + value-flash signatures, shared-axis reverse pair, delayed-open open-alias in the preset trigger (PRESET_STATE_ALIASES), materials pattern for irreducible triggers (card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every recipe's tuned values. - buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 - stale alphas after applyColorScheme), intentSeeds so temper starts from the ACTIVE theme's intent mapping (risk stays orange), alpha background self-derived from the scheme's own neutral step 1 (was hardcoded #fff/#111); mode now forces the donor variant. - Inventory decisions (fase D): semanticTracking axis removed (all-zero), border-hover slot dropped (0 consumers), separator slot adopted across line dividers (step 6, Radix divider tone), size-bundle consumption pilot on toggle (canonical coordinates consumed, deliberate deviations kept visible). - Docs: building-a-component.md (the one door, 9-phase route + known traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh session), THEMING wiring updates. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
3 months ago |
|
|
ebc742e73b |
fix(eidos): component-coherence audit FASE 2 — focus-ring, fields, segments, langs, API nits
Bundles the uncommitted audit work on this branch (active-uix): - DIM 5A: focus-ring unified to `outline` across the control/field set (kills ~18 box-shadow rings; closes forced-colors a11y). NOTE: spin-field + drawer-close orphan-token loose ends from this migration still trip the eidos contract test — to clean when that migration settles. - DIM 5D: field/input backgrounds homogenized to surface-default; list-surface padding recalibrated 2/4/6/8/10; menu-dial internal vars privatized. - DIM 5E: date/time/color-field + date-range-picker segments delegate the active state to the shared field-segment-state layer; the input transition is reduced to `background` only so the focus border no longer flickers on keyboard increment (border-color is now instant; the ring is an outline). - Langs (cero-hardcodes): IconButton-cascade wrappers (carousel/combobox/ tree-grid/table/search-field/banner) + onion-menu + cropper + time-picker day-period now route aria-labels through morfo langs instead of hardcoded English (the hardcode was overriding soma's already-resolved label). Fixes 2 contract divergences (combobox Clear->Clear value, table toggle label). - DIM 5B: code-block/kbd variants aliased to ControlVariant (no duplicate literals); image-picker default size sm->md. Excludes words/palabras/chronos and the metrics/demos tracks (separate work). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
4 months ago |
|
|
d229447a33 |
feat(floating): cascade the canonical gap to all menus + panels
Stamp `data-floating-gap` on every floating content so the token-driven offset
(the foundation from the previous commit) drives the whole set, replacing the
hardcoded per-component sideOffsets (0/4/6/8):
- menus (dropdown, context, their sub-menus, menubar, select, navigation-menu) =
flush (`menu`, gap 0);
- panels (combobox, link-preview, popover, and the 5 pickers via composed
PopoverContent) = `panel` (gap --space-1-5).
The stamp is CONDITIONAL (`sideOffset === undefined ? archetype : undefined`,
matching split-button): a consumer-set `sideOffset` still wins (the Popover /
picker demos document `sideOffset={N}`); only the default falls through to the
canonical token. The pickers default their `sideOffset` to undefined so they
follow the panel token instead of a hardcoded 6.
Verified in-browser: navigation-menu (demo sets no sideOffset) stamps
`data-floating-gap="menu"` (STAMP branch); combobox / date-picker / dropdown
(demos set sideOffset) stamp nothing (SUPPRESS branch -- override respected). The
token-driven offset itself was validated in the pilot commit. check 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
8272a02884 |
refactor(select, combobox): concentric item radius via [data-shape-nest] (A2)
Both popups hand-rolled the item's concentric radius
(`calc(<panel-radius> − <content-inline-padding>)`). Consume the shared
shape-engine rule instead: each Content panel exposes its radius + inline inset as
`--shape-outer-radius` + `--shape-nest-gap`, the Item stamps `data-shape-nest`, and
the global `[data-shape-nest]` rule computes the concentric radius once.
No-op (same radius): combobox item = 4px (lg 10 − content-px 6), verified live;
select item = 4px, verified via a detached probe (the real select popup hangs the
preview renderer — known infra issue). Extends the menubar migration (
|
4 months ago |
|
|
d578f83281 |
feat(select, combobox): plane-constant popup elevation (B2)
Per the elevation doctrine (variant = emphasis, elevation = plane), the select / combobox popups now take their surface · border · shadow from the `overlay` plane via `data-depth="overlay"` — constant across variants. The variant (surface / outline / ghost) tints only the trigger / control, no longer the popup elevation. - Drop the content's own border / bg / shadow + the per-variant elevation overrides (outline/ghost were `raised` / lighter / borderless). - Point the arrows at `--depth-overlay-surface` / `--depth-overlay-border`. - Prune select's 6 now-orphaned `content-*` elevation recipe tokens. Verified in-browser (measured): combobox surface AND ghost both paint bg oklch(0.285) + 1px border + overlay shadow from the plane (ghost was transparent/borderless before — now flattened to the plane). select is the identical change; its open popup hangs the preview renderer (no console errors — preview infra), so it rides the same plane mechanism + check 0 + eidos-lint 0 invalid + contract test (no new orphans). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
599c142124 |
feat(eidos): non-modal menus + unified list-surface size layer (control-height rows)
Non-modal menus:
- DropdownMenu + ContextMenu default to trapFocus=false + preventScroll=false
(were modal — hard focus-trap + body scroll-lock that made them feel stuck).
Menus stay navigable while open (Chakra-style); the props remain for an opt-in
modal menu. morfo focus.trap=false + the demo control defaults aligned.
list-surface — ONE shared size source for list surfaces:
- new lib/list-surface.css (--list-* keyed on [data-list-surface][data-size], 1:1
with the control sizes) + lib/list-surface-context.ts (shared size context for
portaled sub-panels). DropdownMenu/ContextMenu/Menubar/Listbox bridge their
--{c}-* size tokens to --list-*; ContextMenu gained the size axis it lacked.
Row-height doctrine — unified to CONTROL-HEIGHT:
- archetypes.css [data-archetype=item/option] gains a fallback-guarded control-
height FLOOR (min-block-size: var(--list-item-height, auto) + padding-block:
var(--list-item-py, var(--space-1-5))) — ZERO regression off a list-surface
(the ~45 non-list archetype consumers are untouched). Select/Combobox/Command
stamp data-list-surface so their option rows inherit the floor, matching menu
items. Verified: select option md 36px / lg 44px = menu items; bare archetype
item unchanged (0 floor, --space-1-5 padding).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
b8637976a0 |
feat(uix): elevation archetype (A1) + coherence audit + popover/dialog/option-list polish
Coherence audit (ARCHETYPE_COHERENCE_AUDIT_2026-06-19): 8 archetypes + 8 closed decisions, the §13 construction contract, per-component deviation matrix (88/117 deviate). Master guides (soma/COMPONENT_GUIDE, eidos/components/README) point to it. A1 — elevation bundle via `data-depth`: the plane paints surface·border·shadow·halo (added `border` to the depth bundle). z-index is NOT painted — stacking is a positioning concern owned by the floating-wrapper. Popover migrated to the overlay plane (panel + arrow consume it); recipe orphans pruned. Popover fixes: arrow un-clipped via an inner [data-popover-viewport] (Radix-style; the absolute arrow escapes the scroll clip), sized via density tokens (not soma's hardcoded 10×5), border-seam overlap keyed on data-side, hover-bounce guard in scheduleHoverOpen (ignore hover-open when already open). Dialog.Close composes IconButton/Button (neutral) — closes the Lote ② debt. Option lists: density-driven padding/radius via --space-* + concentric radius, ScrollArea adoption, emerge open/close events (combobox/select/command), and the canonical option-highlight in archetypes.css. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
189932d939 |
feat(eidos): IconButton primitive + Lote 0 iconOnly->IconButton cascade
Lote 0 of the component-coherence audit (FASE 2): - New IconButton primitive (composes Button: inherits variant/size/intent/ color/rounded/shape/loading + Button's morfo + sema, no new morfo; aria-label required; glyph as children). New svg/ glyphs: SvgX, SvgPlus, SvgMinus. - Button: rounded='full' 9999px -> var(--radius-full) (theme-driven radius, value-identical). - Migrate icon-only Button consumers to IconButton: carousel prev/next (pilot), tree-grid expand, table row-detail, search-field clear, combobox clear. Pattern: glyph->children, label->aria-label, drop iconOnly. - carousel.css: fix arrow positioning (specificity vs Button's base position:relative, exposed by the IconButton import-order flip) + the press-squeeze jump (centre via the translate property so the contact press transform:scale composes instead of replacing the centring). - Doc: COMPONENT_COHERENCE_AUDIT - indicator-chevron vs discrete IconButton distinction (tree-view/accordion stay out); 5F width closed (full-width); Lote 0 hand-off + pending select-family faults. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
dc62a0268b |
feat(eidos): canonize theming scales + tokenize magic numbers
Audit-driven canonization of the eidos theming layer: a canonical scale that components bypass with literals drifts into N variants. Every axis is now retunable-by-theme AND consumed via token, never a bare literal. Bloque A/B (scales): --blur-* (Tailwind-aligned, depth planes consume it); inner-shadow --shadow-inset-* (mode-aware) for the recessed plane; gradient angle/named tokens; --breakpoint-* sourced from ActiveDom (runtime, dev-settable) + container queries; opacity dual numeric+semantic scale; border-width none/thin/medium/thick/heavy (adds real 3px); tracking caps/widest. Fase 7: 3 size archetypes documented + coherence guard (no px/rem in recipe font-size/icon-size). Bloque C (magic numbers): z-index 80/50/99 (combobox/nav-menu/drag-drop) -> recipe content-z/preview-z tokens (overlay micro-band soma mirrors); on-scale durations -> var(--duration-*) (dialog fast/slow, card slow); 12 single border/ring widths -> var(--border-width-*), value-preserving. Off-scale kept only as justified recipe tokens (continuous spinner/loading periods, sub-fast press). Self-contained dimensional scales (avatar ring, ring-thickness) left whole. Docs: THEMING.md SS35 + SS6 + SS29, THEMING_NOTES, README, TSC. Excludes words/palabras/chronos (active dev tracks). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
5c79ee4ec5 |
perf(eidos): code-split 15 form-control recipes (Phase 3, batch 3)
field form number-field toggle toggle-group switch checkbox radio-group rating-group search-field select combobox tags-input file-upload editable. Caught + fixed a real coupling: toggle-group items are DOM-equivalent to a standalone <Toggle> (carry data-toggle via the morfo, per the 2026-05-28 structural-identity refactor) and rely on toggle.css for their base treatment — but the group never mounts an eidos <Toggle>. Without the aggregate, items rendered as raw buttons (bg #f0f0f0, 2px outset border). Fix: toggle-group.svelte imports toggle.css FIRST (before its own grouping rules, so attached-corner overrides still win). Verified: item now bg srgb(0.133), 1px border, font-weight 500, min-block-size 36px. All recipes left the monolith (residual [data-*] are base.css token contracts, verified base==monolith counts). Portaled select content verified styled. index.css 51→36 @imports. Monolith 633,277→533,103 raw (−100 KB) / 86,535→74,716 gz (−11.8 KB). check 0 errors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
271a2f8ff0 |
feat(eidos): depth adoption — elevated components consume the channel (shadow + halo)
The Fase 2 rim halo now reaches real UI, not just the showcase. Each elevated
component's shadow signal (recipe tokens in recipes/base.ts + the few direct
box-shadow uses) now composes `var(--depth-{plane}-shadow), var(--depth-{plane}-halo)`.
Reaches: popover, dialog, drawer, dropdown/context/navigation-menu, menubar,
select, tooltip, card, combobox, command, link-preview, words.
Shadow signal only — z-index stays component-managed (the z bands are finer than
the 5 planos), so zero stacking risk. Verified: dialog keeps its own z-index 71
and composes drop shadow + oklab halo. Retuning a plane now retunes every
component on it.
Verified: npm run check 0 errors; eidos 183/186 (3 pre-existing `words` failures,
unrelated). Regenerated generated/base.css. THEMING 29 updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
218ccfcc5e |
Theming: untitled-ui demo theme, engine fixes, audit + P0/P1 fixes
- New untitled-ui demo theme + theming showcase route (web/routes/temas) - Engine: density tokens scale via calc(var(--density-*-scale)); contrast slot defaults to on-solid - Eidos theming audit (THEMING_AUDIT_2026-06-01.md) + two-tier color-model RFC (COLOR_MODEL_RFC.md) - P0: replace phantom foundation tokens in recipes + component CSS — shadows -> semantic scale (subtle/raised/overlay), add --space-7, --border-width-strong -> thick; neutral solid contrast -> step 12 (AA in light + dark) - P1: validate hex color values + per-theme semantic completeness; regression tests for contrast, density, dark output, and TSC multi-part/composition emission Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
4 months ago |
|
|
0b55be5c36 |
refactor(combobox + search-field): ClearButton/Clear render <Button>
Closes #120. The two icon-only clear affordances now render as eidos `<Button>` via soma's `child` snippet, retiring the per-recipe chrome (border, padding, focus ring, hover, dimensions) in favour of button.css. The X glyph is provided through Button's `icon` snippet slot; `iconOnly` collapses the body and keeps the label sr-only. Both narrow `variant` to ControlVariant (`'surface' | 'outline' | 'ghost'`) per DEMO_AUTHORING_GUIDE §12.7 — same 3-set as DropdownMenu.Trigger and AlertDialog.Cancel. Default `variant='ghost'` (subtle X that reveals chrome on hover) which is the canonical clear affordance. Defaults: - Combobox.ClearButton: ghost · xs · iconOnly · color=neutral - SearchField.ClearTrigger: ghost · sm · iconOnly · color=neutral Per-component CSS gutted to the empty-state visibility rule only — `[data-…][data-empty] [data-…-clear-…] { opacity: 0; pointer-events: none }` stays because hiding the X when there's nothing to clear is component-specific behavior, not Button chrome. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
20709caf9c |
refactor(combobox): SelectedTags as band above the Control (Chakra pattern)
Switched the multi-mode chips from MUI-style "inline inside the input" to the Chakra v3 multi-select pattern — chips render as a separated band ABOVE the Control. Two wins: - The dropdown popover (opens downward) never covers the selected chips, which sit comfortably above the input. - The Control stays a normal-height single-line input. No layout shifts, no absolute-positioned affordances, no `display: contents` gymnastics, no input flex tuning. Reverts the inside-the-Control CSS gymnastics from `30e9517a` / `64bbe9b1` / `87e3d68f` (flex-wrap, padding-right reservation, absolute clear+trigger, input flex basis). `<Combobox.SelectedTags>` now renders as a plain `flex-wrap` row with chip gap and a margin- block-end separating it from the Control. Demo composes `<Combobox.SelectedTags />` BEFORE `<Combobox.Control>` when `mode === 'multiple'`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
91b0efc461 |
fix(combobox): inline chips + input flow as siblings via display:contents
`<Combobox.SelectedTags>` was a nested flex container so the input always wrapped to its own row below the entire chip block — wasting the empty space on the last chip row. Use `display: contents` so each chip becomes a direct flex child of `<Combobox.Control>`. Chips + input now share the same wrap context: the input flows on the same row as the last chip when there's room. `[data-empty]` still toggles to `display: none` so empty-state still collapses correctly (and the `:has(...:not([data-empty]))` selector that pins clear/trigger absolutely keeps working). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
87e3d68f86 |
fix(combobox): pin clear+trigger to first row, not vertical center
With many chips wrapping into 3+ rows, the previous `top: 50%` + translateY centered the clear/trigger pair at the midpoint of the whole stack — visually below the first row of chips. Pin to `top: var(--space-1)` instead so they sit flush with the first chip row no matter how many additional rows of chips wrap below. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
64bbe9b158 |
fix(combobox): pin clear+trigger absolute when chips present (MUI pattern)
When `<Combobox.SelectedTags>` has at least one chip, anchor the ClearButton + Trigger absolutely at the right edge of the Control (MUI Autocomplete pattern). Chips + input can now wrap freely without ever pushing the right-side affordances to a new row. `--_combobox-affordances-w` reserves the right-padding the absolutely-positioned buttons consume, scaled to the control's current height token. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
30e9517a9a |
feat(combobox): SelectedTags inline chips for multi mode
New parts `<Combobox.SelectedTags>`, `<Combobox.SelectedTag>` and `<Combobox.SelectedTagRemove>` render the current selection as removable chips inside `<Combobox.Control>` when `type='multiple'` (Material UI Autocomplete pattern): - Morfo: 3 new public parts with kebab names + texts entries. - Langs: es/en entries `selected-tags` / `selected-tag-remove`. - Soma: `ComboboxSelectedTagsProvider` exposes `items` derived from the provider's label registry; `ComboboxSelectedTagProvider` surfaces `data-value` / `data-label`; `ComboboxSelectedTagRemoveProvider` resolves its parent tag via context and calls `provider.removeValue` on click. Provider gains `getSelectedItems()` and `removeValue()` helpers; `selectedTagsEmpty` runtime prop drives `[data-empty]`. - Soma item registry: stop unregistering labels on Item cleanup so chips keep proper labels after the listbox closes/lazy-unmounts. - Eidos: default snippet loops items and renders a chip + X icon per entry; consumer can override the snippet for custom rendering. - CSS: chip styling, wrap-friendly Control with breathing padding when chips are present, ClearButton pinned right via auto margin, input flex basis reduced to 4rem so it shares a row with chips. - Demo: renders `<Combobox.SelectedTags />` inside Control when `mode === 'multiple'`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
9fbf8e48b5 |
feat(number-field, search-field, combobox): audit-driven improvements
Three components closing the 6-component audit batch.
number-field
- N1 RTL scrubber: invert horizontal delta sign when dir='rtl' so
dragging right decrements (visually backward) in RTL layouts. Vertical
unaffected. Added 2 RTL scrub tests; existing scrub test pinned to ltr.
- N2 stepper height: Increment/Decrement now use --_number-field-height
for inline-size/block-size/min-inline-size so they always match the
input row at every size token (xs/sm/md/lg/xl).
- N3 input focus ring: explicit [data-number-field-input]:focus-visible
with --_number-field-accent-border box-shadow, alongside the existing
Provider-level ring.
search-field
- S1 icon tokens: added --search-field-icon-size-{xs..xl} + icon-color +
icon-margin-inline-end + a Morfo Icon part + soma/eidos wrappers.
Demo uses <SearchField.Icon><Search /></SearchField.Icon>.
- S2 debounceMs prop: soma wraps onValueChange in a timers.schedule with
the provided delay. clear() cancels, submit() flushes synchronously.
- S3 loading slot: new LoadingIndicator part (morfo + soma + eidos) +
data-loading on Provider + CSS spinner via @keyframes search-field-spin
honoring prefers-reduced-motion.
combobox
- C1 ClearButton part: new morfo trigger + soma provider + eidos wrapper
with X icon. Hidden via [data-empty] (opacity + pointer-events:none).
Click clears value + inputValue and refocuses input.
- C2 allowsCustomValue: when true and no highlighted item, Enter commits
the current inputValue as the value. Single mode closes after commit;
multi appends + clears input + stays open.
- C4 Backspace removes last tag in multi mode when input is empty.
- C5 Sticky group headers: CSS position:sticky with content-overlay bg.
Plus: fixed search-field demo's brittle parts[1] index reference to a
named lookup (parts.find(p => p.kebab === 'input')).
Verified: svelte-check --threshold error → 0 errors / 0 warnings /
4584 files. All component tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
dfb64511de |
eidos: theming fixes + size/variant parity batch + docs
- theme: add surface.muted + content.muted to color contract (neutral-3 + neutral-10). Plugs 17 broken --color-content-muted and 3 broken --color-surface-muted references in recipes/components. - form.css: fix --color-neutral-element-hover typo → --color-neutral-hover. - archetypes.css + events.css: replace raw hsl/rgba indigo with color-mix(var(--color-primary-solid) …) — no raw colors left in eidos. - combobox dark scrollbar: unscope ::-webkit-scrollbar rules in uix.css and duplicate --uix-line on :root + :root[data-mode='dark'] so portaled overlays (Combobox listbox, Popover, Dialog, Drawer) inherit the theme. - sizes: 20 components expand from sm/md/lg to xs..xl (form controls, text inputs, progress/meter, field/form) or xs..lg (nav controls: breadcrumb, pagination, tag-group, toolbar). Composite panels keep sm/md/lg deliberately. - variants: field + toolbar drop arbitrary ControlVariant narrowings; both expose all 3 (surface | outline | ghost) with new outline CSS. - pagination demo: disambiguate siblingCount/boundaryCount as "per side" in label + API table (Radix/MUI convention). - docs: CHECKLIST §C-2.6 (contract token presence) + §D-7.4 (chip parity) + §D-7.5 (size category) added. DEMO_AUTHORING §12.7 (chip parity) + §12.8 (size category cheatsheet) added. eidos/README + active_architecture.md sync texts/migration nomenclature. - PENDIENTES.md: normas N-1..N-5 implantadas en esta sesión. Verification: 88/88 eidos tests, 0 type errors, 67/67 component:audit PASS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
714df0e5c9 |
combobox: PASS audit + extend focus-move list for listbox/menu nav
Full walk of combobox (popover + editable input + listbox): - Morfo: validated. 10 parts (Provider/Input/Trigger/Content/Viewport/ Item/Group/GroupHeading/Separator/Arrow). Single + multiple via `data-type` on Provider, `aria-multiselectable` conditional on `prop:multiple`. Item declares `data-state` checked/unchecked, `data-value`, `data-highlighted`, `data-disabled`. Keyboard: 6 keys but only 2 mutate state (Enter→select, Escape→close-delegated). - Decision documented: combobox does NOT emit emerge events for open/close/typing/filtering/highlighting — these are navigation mechanics, not commits. Escape close is delegated to the popover layer's `close-dismiss` event. The 2 `commit-*` events cover the actual user intent (choosing an item). - `texts.label` added with catalog entry. The toggle key already existed. Audit script refinements: - Extended focus-move action list to cover listbox/menu/tablist navigation (`next-item`, `prev-item`, `first-item`, `last-item`, `next-tab`, `prev-tab`, `first-tab`, `last-tab`) plus the popover/ dialog actions that are delegated to the containing overlay layer (`open`, `close`, `dismiss`, `toggle`). A combobox / select / menu that hosts Escape→close is not under-declared if the overlay layer owns the sema event. README rewritten with canonical sections: - `## Baseline` summarizing air + soma + morfo coverage. - `## Comparativa` (was `## Comparison`) — table preserved. - `## Decisiones` documenting the no-emerge-events policy, focus-only keys, Control composition rationale, multi-select aria propagation. - `## Gaps` (was `## Out of scope`) rewritten with disposition tokens (implementar / diferir / descartar) per row. ClearTrigger and Validation state get `implementar`; Modal+footer gets `descartar` (combobox is inline by design, not a confirm-style picker). Audit: PASS 6 → 7. No regressions; the relaxed focus-move list benefits other listbox/menu components too (will surface on their audits). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
fb5dd0919c |
Advance Eidos demos and form validation docs
|
5 months ago |