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 }
23 Commits (6f42eebfe80bc9ac5656be2bbf621c6d62e768fb)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
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 |
|
|
4adcc4c7fd |
uix(color): enruta `data-color` crudo por `resolveComponentColor` en la familia date/time (custom hex sin fuga)
Al ensanchar `*PickerColor` a `ComponentColorProp`, los sub-wrappers que
enhebraban `data-color={color|resolvedColor|visual.getColor()}` CRUDO podían
recibir un valor custom (hex) y estamparlo tal cual en `data-color` (inválido;
roles/escalas ya pintaban por la capa compartida, solo el custom hex no).
Se pasan por el helper `resolveComponentColor` (patrón de `select-trigger.svelte`):
canonical -> `data-color`; valor crudo -> `data-color-custom` + el seed
`--color-custom` que la capa compartida rampa. 12 sub-partes:
- date-picker: root, trigger, calendar
- date-range-picker: root, trigger, calendar, input
- time-picker: trigger, clock
- time-range-picker: trigger, clock
- time-range-field: input
Verificado en navegador (demo date-range-field, custom #00b894): ambos endpoints
quedan data-color=null, data-color-custom='' y --_field-palette-text =
color-mix(...#00b894...) exacto. El soma range-field hace `{...restProps}`
wholesale sobre el [data-field] de cada endpoint, así que data-color-custom + el
seed llegan solos. check: 76 errores ajenos, 0 propios.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
861427fe12 |
uix(color): Fase 3 (parcial) — abre `color` en field-family · calendar · month-grid · time-picker/range
Continúa la apertura de la jaula del color hacia el sistema completo
(role · intent · 33 escalas · valor custom), tipando a `ComponentColorProp`
y enrutando por el forward `--palette-*` compartido:
- Field family: field base gana el forward `_palette-text`; search-field
y 8 hojas (password/mask/number/css/color/date/date-range/time-field)
adoptan `data-field` y heredan el forward. Wrappers vía
`resolveComponentColor`; demos con picker de roles/intents/escalas/custom.
- Calendar base: recipe `_palette-{solid,solid-hover,track,border,text}`;
calendar.css migra su cascada per-rol al forward compartido.
- month-grid: patrón mini-recipe (5 tokens `_palette-*`, sin recipe previo);
el generador emite base default + forward `[data-month-grid][data-color]`.
- time-picker / time-range-picker: tipo + wrapper.
Fix de regresión de runtime: la migración de la field-family dejó huérfana
la cascada `--_time-field-accent-*`, y time-range-picker re-exportaba el
Input crudo de soma, así que sus endpoints no recibían el color del picker.
Nuevo `time-range-picker-input.svelte` enhebra `data-color`/`data-color-custom`
a cada endpoint (verificado en navegador: color del picker -> ambos extremos).
time-picker (single) ya se salvaba por el overlay `data-field` en su raíz.
Fix de 9 errores de tipo: los factories de opts de los tests de provider
de switch/toggle no pasaban `colorCustom` (lo hicimos required en Fase 2b).
Regenera generated/base.css. check: 76 errores ajenos, 0 propios.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
3 months ago |
|
|
d1670caa45 |
refactor(eidos): de-alias date/time pickers off sibling field recipe tokens
The date-range / time / time-range pickers referenced --date-field-* / --time-field-* recipe tokens to paint their field-shaped parts (standalone trigger box, wrap gap/font, embedded trigger). That is a cross-component alias — the exact drift the S6 Field composition eliminates. Point every one at the FIELD FAMILY public tokens instead (--field-control-* / --field-* / the B.1 --field-segment-height), or at the underlying primitive where Field has no matching token (the wrap column-gap keeps the tighter segment rhythm). Each substitution is computed-value-identical (both sides resolve to the same primitive) — adversarially verified + browser-confirmed on all four pickers. Also drop dead private declarations the compositions left behind (--_time-field-padding-inline / --_time-field-segment-padding-inline, and --_time-field-gap in time-picker) and, now that nothing aliases them, prune the 32 newly-orphaned date-field/time-field chrome tokens from the recipe + generated CSS (recipe-css-contract orphan guard green, 25/25). TimeRangePicker's embedded clock-trigger keeps sizing from the picker-local --_time-field-height (not --field-segment-height): its composed endpoints don't carry their own [data-size], so the field-family segment-height would pin to md. That endpoint size-threading gap is pre-existing (DateRangePicker threads it, TimeRangePicker doesn't) and tracked separately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
c4ea7f571f |
feat(fields): time-* family composes real TimeFields via field.css (S6)
Applies the proven date-* pattern to the time family (exact structural parallel): - time-field: chrome / label / invalid / disabled / focus come from field.css via the fieldRole identity (data-field / data-field-control); time-field.css keeps only segment specifics. No tokens aliasing the Field base. Imports field.css. - time-range-field: COMPOSES two real <TimeField>s (soma TimeRangeField.Input → TimeField.Provider > TimeField.Input per endpoint) bound to the range slice; size/variant/color thread through a visual context; CSS is layout-only. (No syncPlaceholderToValue opt-out needed — TimeField has no calendar to auto-page, and the controlled placeholder keeps the endpoints from mutating each other.) - TimePicker (single field): root carries data-field/data-time-field (A27); imports field.css. - TimeRangePicker: inherits the composed endpoints; imports field.css (no double-box — its recipe never re-declared the endpoint box). Baseline unchanged (59). Verified in browser: time-field paint + label, range endpoints = composed TimeFields (nested provider>control, size threaded, value renders), both pickers paint, no double-box. 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 |
|
|
cae3d2e0ce |
refactor(uix): pickers delegate the dialog to the composed Popover (+ DateTimePicker time parts)
All 5 pickers (date / date-range / time / time-range / color) modelled themselves as standalone APG dialogs while ALSO composing a Popover that already provides the dialog — producing nested role="dialog" (the calendar/clock was a role=dialog child of the popover-content dialog). Reconcile per soma SOMA_ARCHITECTURE.md §2 (the Popover IS the authoritative dialog): drop apg:dialog-modal, focus.trap, the content part's role:'dialog', the trigger's redundant aria-controls, and the own open/close events from each morfo; providers stop firing their own close (commit/cancel just toggle open). time-picker/time-range-picker Clock made morfo-driven (renderProps). Also lands this session's picker UX: - composable <DatePicker.Time /> / <DateRangePicker.Time /> + shared picker-time helpers/row - TimeRangePicker: canonical column gap + vertical divider, slider sizing, AM/PM ToggleGroup, granularity-aware sliders Verified: all 5 pickers show a single dialog in the browser; morfo:vocabulary clean; svelte-check 0 new picker errors; provider tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
3 months ago |
|
|
f20efd4681 |
fix(eidos): picker triggers flush via field-trigger archetype + footer follows picker size
Two picker-coherence fixes:
1. Field-trigger flush treatment — popover.css excluded the picker's generic
button envelope only for `[data-field-control-trigger]`. The time-picker /
time-range-picker clock icons carry `data-{component}-trigger` (NOT the
field-control marker), so they still got the popover button border/bg —
looking like a bordered button instead of a flush field icon. The exclusion
now keys off the `field-trigger` archetype, which the morfo/soma stamp on
EVERY picker trigger; added the missing override to time-range-picker.
All five pickers verified: date / time / time-range / date-range render a
flush 28px icon; color renders its own field-box (its border is the field's,
not the popover envelope's).
2. Footer follows picker size — picker-shell Clear/Cancel/Close were pinned to
`size="xs"`, so md/lg pickers had a tiny incoherent footer. New shared
`picker-shell/visual-context` lets each picker publish its resolved size;
the footer buttons read it (fallback xs). Wired into all five pickers.
Verified: at picker md the footer buttons are md (36px).
svelte-check clean. Excludes words/palabras/chronos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
4 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 |
|
|
1431970371 |
fix(time-range-picker): lay the field on one line
The picker root was `flex-direction: column`, stacking label + start + end into three rows. The `1fr auto 1fr` grid that would place start — end on one row lives on `[data-time-range-field]`, which the picker never renders (its field provider is context-only, ref=null) — so it never activated. Mirror the date-range-picker reference: the root becomes a wrapping flex row, the label claims its own full row (`flex: 1 0 100%`), and each endpoint re-flexes to share one line (a non-auto basis overrides the `inline-size: 100%` that `[data-time-field-input]` inherits from time-field.css). Root height 102 → 60px; no console errors; eidos-lint 0 invalid. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
8f84b36f6d |
feat(eidos): field-family font-scaling coherence (input 1:1 + label step-down)
- Field font scale: input 1:1 (size N -> --font-size-N, md now 16px), label one step below (10/12/14/16/18). Recipes: field, spin-field, date/time/color-field, search-field, password-field, select, editable, tags-input. Segmented-field labels via CSS calc; generic Field label via label-font-size tokens. - Picker triggers (date/time/range): box now scales off the local --_X-field-height + font:inherit so the 1em icon follows the field font; added the missing xs size variant to time-picker + time-range-picker. - color-field/time-field commit-set fires + sounds on increment (compare by ColorValue.hex; time-field passes fallbackTarget for the double-registered 'input' part). - color-field format-select: reverted the segment-active tint back to its focus ring. - Docs: THEMING.md field font rule; COMPONENT_COHERENCE_AUDIT.md. words / palabras / chronos untouched. 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 |
|
|
725f7abe37 |
perf(eidos): code-split 16 picker-family recipes (Phase 3, batch 4)
time-range-field date-range-field date-field time-field color-field calendar range-calendar month-grid year-grid date-picker date-range-picker time-picker time-range-picker color-picker picker-shell slider. The picker family composes via SOMA headless parts (Calendar, Slider, Popover) + `import type` for grids — so the eidos recipes don't auto-load on mount. Added explicit recipe imports to each composite (leaf-first so the composite overrides it): - date-picker → calendar + month-grid + year-grid - date-range-picker → range-calendar - date-range-field → date-field ; time-range-field → time-field - color/time/time-range-picker → slider - picker-shell → popover (shell content is a soma Popover) Verified in browser: date-picker calendar day inline-flex/30px (was block); date-range-field segment grid/radius 4px; color-picker slider thumb 20px (was 0px). index.css 36→20 @imports. Monolith 533,103→402,082 raw (−131 KB) / 74,716→63,500 gz (−11.2 KB). check 0 errors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
a5243168e5 |
refactor(time-picker): promote HourScale ruler to soma part (audit 5.3 P2)
Eliminates `Provider.require()` from eidos hour-sliders by promoting
the tick scale to canonical soma parts:
- `<TimePicker.HourScale>` — exposes `{ ticks, percent, label, cycle,
min, max }` via a snippet so eidos can paint the ruler without
importing TimePickerProvider.
- `<TimeRangePicker.HourScale>` — same shape for the range variant.
Scale is global (both endpoints share the cycle), so no endpoint
prop.
Eidos hour-sliders become pure composition + paint via snippet props.
No JS coupling between eidos and the soma provider class.
Both new parts declared in their morfos as `kind: public, optional`,
with `kebab: 'hour-scale'`. Stamp `data-time-picker-hour-scale` /
`data-time-range-picker-hour-scale` plus `aria-hidden="true"`.
Test result unchanged: 2391/2397 passing. No regressions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |
|
|
a804c39208 |
feat(eidos): Button + 9 demo rebuilds + picker recipe polish
Build: - New <Button> compound (morfo + soma + sema + eidos): 6 variants (solid/soft/surface/outline/ghost/plain), 8 colors, 5 sizes, optional icon/endIcon snippets, loading state with built-in Spinner, asChild Slot pattern, intent-driven sema (commit-action with fromProp:intent). Demo rebuilds (canonical depth per DEMO_AUTHORING_GUIDE): - context-menu, dropdown-menu, pin-input, alert-dialog, toggle-group: full per-part Morfo contracts, reference-parity tables, ARIA contract tables, keyboard tables, composition controls. - color-field, time-field, time-picker, time-range-picker, color-picker, month-grid, year-grid: same canonical treatment; per-part data/aria/ keyboard iteration of raw morfo, reference parity vs react-aria/ ark-ui/Chakra/bits-ui/Mantine. Picker recipe polish: - PickerShell.Clear/Cancel/Close refactored to use <Button size="xs"> (affects 5 pickers — date / date-range / time / time-range / color). - TimePicker + TimeRangePicker: popover condensed (min-width 18rem -> 14 / 32 -> 28), per-channel accent (hour=primary, minute=secondary, second=neutral; end variant muted), ruler off by default, hour ruler cleaned to 0/6/12/18/23. - ColorPicker: typography token --_color-picker-trigger-font-size that scales with data-size (10/12/14px); autoFormat default true; Area recipe override for [data-x-channel='hue'] with rainbow gradient + saturation/brightness Y overlays. - ValueText eidos wrapper: fix children snippet bug that suppressed soma's displayValue fallback. - date-field.css: segment editing affordance (cursor + hover + active ring) via new --_date-field-accent-element token across 8 color cascades. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
ec66999b6c |
docs+style: close last 3 NEEDS-WORK → 77/77 PASS audit
`npm run component:audit` now reports 77 / 77 PASS, 0 NEEDS-WORK, 0 BROKEN. **month-grid + year-grid READMEs** Add Baseline / Comparativa / Decisiones / Gaps sections (F-1.1 / F-1.2 / F-1.3 / F-1.4). Both grids are standalone primitives extracted from DatePicker's `kind: 'month' | 'year'` views (task `#70`); they have no air counterpart. Documented Sema event design (single `commit-set` for value mutation, `nav-step` for paginated header navigation), the 4×3 grid choice, configurable `decadeSize` for YearGrid, and known gaps (multi-year range, quick-jump, localized month names — all deferred). **Audit script `focusMoveActions` extension** `A-3.7` was firing on month-grid/year-grid because the script didn't recognise `next-row`, `prev-row`, `first-month`, `last-month`, `first-year`, `last-year`, `next-page`, `prev-page` as focus moves. They ARE focus moves inside their respective grids (same semantic as `next-day` / `first-day-of-week` inside Calendar). Added to the focusMoveActions set in `scripts/component-audit.ts` so the event-vs-keyboard ratio heuristic no longer over-counts. **time-range-picker** - README Gaps section rewritten as a table with explicit disposition markers (`implementar` / `diferir` / `descartar`) per F-1.4. - Recipe `time-range-picker.css` now styles `[data-readonly]` (lower opacity + pointer-events: none on trigger/clear) and `[data-invalid]` (threat-colour border + focus ring) — closes R-1.3 / R-1.4. Both attrs were declared in morfo but unstyled. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
afb09c2254 |
feat(picker-shell): extend to Root + Header + Body + Footer layout
Promote PickerShell from action-row-only to a canonical 4-zone shell (Root → Header / Body / Footer) shared by every composite picker so date/time/color popovers get the same visual contract for free. - Add `<PickerShell.Root>` flex-column wrapper (emits data-picker-shell, data-mode) plus `<PickerShell.Header>` and `<PickerShell.Body>` zones matching the existing Footer's spacing + border tokens. - Auto-wrap all 5 *-content.svelte popovers (date / date-range / time / time-range / color) in `<PickerShell.Root>` so consumers only compose Body + Footer. - Refresh all 5 demos to use `<PickerShell.Body>` around picker content; date-picker demo gains a `showShellHeader` toggle showcasing the new Header zone. - CSS scales section gap + header spacing across xs/sm/md/lg picker sizes via [data-popover-content][data-picker-size] scopes, in sync with the existing Footer scale. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
79c94d85d5 |
wip(popover): unified min-width = anchor + sideOffset 6 across pickers
Day-end checkpoint for the floating-layer normalization work. Documented in CONTINUE.md. Done: - popover.css: new `--_popover-min-width` defaults to `var(--floating-anchor-width, auto)` so popover layer is NEVER narrower than its anchor (Radix / React Aria convention). Consumers that should opt out (tooltip, dialog) override with `auto`. - soma popover-content default sideOffset 0 → 6. - 5 picker eidos contents: sideOffset 10 → 6 (matches the new default; per-component override removed visually but kept as explicit prop). - combobox provider: reverted the multi-on-close stamp-labels patch. Multi-mode selections will be rendered as inline tags via a future `Combobox.SelectedTags` part (Material UI Autocomplete pattern, decided with user). Pending (see CONTINUE.md): - Re-anchor pickers to their Input wrapper (currently anchored to the chevron trigger ~14px). Required for the min-width normalization to actually show — research vs Ark UI / Radix / React Aria confirmed composite-input pickers anchor to the control wrapper, not the trigger button. - Combobox `SelectedTags` part for multi-mode inline tags. - SearchField floating Results part (user opted to make it Combobox-like rather than reuse Combobox). svelte-check --threshold error → 0 errors / 0 warnings / 4584 files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
826481f1d5 |
fix(picker-shell): footer buttons scale with picker size (xs/sm/md/lg)
The footer buttons (Clear / Cancel / Done) were hardcoded to control-height-sm + font-size-sm + space-3 padding regardless of the host picker's size. At xs the buttons looked oversized next to a compact picker; at lg they looked undersized. - picker-shell.css: refactored button rules to consume four `--_picker-shell-*` CSS vars (control-h, padding-x, font, gap, row-spacing). Defaults match the previous sm sizing. Added explicit xs/md/lg variant blocks keyed off `[data-popover-content][data-picker-size='X']`. - date-picker-content / date-range-picker-content / time-picker-content / time-range-picker-content / color-picker-content: forward the picker's resolvedSize to the popover via a separate `data-picker-size` attr, independent from the popover chrome's clamped `data-size`. This decouples the popover's own chrome (which still clamps xs → sm because the popover layer has no xs variant) from the picker-shell button scaling, which now uses the picker's true size. Verified at /uix/components/date-picker: - xs → 22 / 12px (control-height-xxs, font-size-xs) - sm → 30 / 14px (default) - md → 36 / 16px - lg → 44 / 16px Also fixes the horizontal scroll at xs that surfaced the issue. The date-picker.css `[data-popover-content]:has(...)` rule lets the popover grow to max-content when it hosts a calendar / grid. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
dd22cfc2bc |
feat(time-range-picker): eidos wrapper + canonical picker-shell parity
Builds the Eidos time-range-picker layer end-to-end and brings color-picker's morfo into parity with the other pickers. time-range-picker - soma: `mode` prop, `pickerShellContext` registration with commit/cancel/clear and `valueOnOpen` snapshot for revert; Provider now renders a div with data-state/disabled/readonly/required + aria mirrors. - soma: new `Clock` part (mirrors TimePicker.Clock with role="dialog" and data-state). - morfo: scope ['soma','sema'] + apg dialog-modal; promoted Provider to public div with states/data-state; added Clock part; declared the 6 canonical picker events (open / close-commit / close-cancel / close-dismiss / close-dismiss-outside / commit-clear); slider parts declare data-endpoint + data-disabled. - eidos: full namespace (Trigger / Content / Clock / HourSlider / MinuteSlider / SecondSlider / DayPeriodToggle + re-exported PickerShell Footer / Clear / Cancel / Close). Sliders compose generic SliderProvider (N-8) and ship with optional rulers above hour / below minute+second. - eidos css: 2-column endpoint grid in the clock; per-endpoint range tint; AM/PM toggle styling; reuses time-field tokens. - demo: interactive testbed at /uix/components/time-range-picker mirroring the time-picker demo — every soma + eidos prop has a live control, closeOnRangeComplete + start/endReadonlySegments toggles, footer composition switches, sema play buttons, soma+eidos snippets. - nav: added entry between Time picker and Color field. color-picker (audit fixes) - morfo: Provider declares states ['open','closed'] + data-state attr; added the same 6 canonical picker events targeting the `content` part (handle-pick / handle-drag / commit-set preserved). - soma: runtime now feeds open state + disabled/readonly/required/invalid props to the morfo runtime so data-state actually emits. Verified: svelte-check --threshold error → 0 errors / 0 warnings / 4524 files. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |