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/src/uix/soma/README.md

1047 lines
37 KiB

# soma
docs: prune obsolete audits + studies, refresh remaining references Deleted 60 obsolete documents that no longer reflect the active-uix state: - 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md) - 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21, audit-prompt template) - 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/ PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24) - 2 superseded refactor proposals (refactor_claude, refactor_code) - 1 stale bug log (form/BUG-onchange-onblur-hang — repro path src/routes/test/sium/kitchen-sink no longer exists) Updated the remaining operational references to drop dead links and reflect the post-cleanup architecture: - src/uix/README.md — rewritten links section, dropped pointers to terra/air/CONTINUITY/refactor docs, updated adom/dom paths - src/uix/active_architecture.md — header now dated 2026-05-08, lists the major shifts since 2026-04-26 (provider inheritance dropped, eidos in production, doctrina parte IV, sound eager-init); pendings section reflects the eidos migration roadmap; "see also" purged of deleted files - src/uix/morfo/README.md — file tree updated (removed DESIGN/study, added compile/runtime/PERMUTATION_RUNNER); see-also pruned - src/uix/sema/README.md — SoundChannel section now describes the eager-init pattern (constructor-time, not lazy); pointer to sema-implementation-guide added - src/uix/soma/README.md — drops terra/air mentions, declares the actual dependency direction (eidos -> soma, not the reverse) - src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual y deuda histórica" reflecting Provider-inheritance-drop; demo path updated to web/routes/ - src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to $libs/days (no external/dates façade); demo paths swapped from /test/soma/* to web/routes/ - src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/ with a relocation note - CLAUDE.md — Refactor Documents section replaced with Reference Documents pointing to per-layer READMEs npm run check holds at baseline (39 pre-existing errors, none new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Librería headless de componentes compuestos para Svelte 5. Capa de
comportamiento dentro de UIX — emite los `data-*` y `aria-*` que el
contrato declara en `morfo`, gestiona estado y eventos, y delega lo
visual a `eidos` mediante el DOM.
docs: prune obsolete audits + studies, refresh remaining references Deleted 60 obsolete documents that no longer reflect the active-uix state: - 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md) - 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21, audit-prompt template) - 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/ PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24) - 2 superseded refactor proposals (refactor_claude, refactor_code) - 1 stale bug log (form/BUG-onchange-onblur-hang — repro path src/routes/test/sium/kitchen-sink no longer exists) Updated the remaining operational references to drop dead links and reflect the post-cleanup architecture: - src/uix/README.md — rewritten links section, dropped pointers to terra/air/CONTINUITY/refactor docs, updated adom/dom paths - src/uix/active_architecture.md — header now dated 2026-05-08, lists the major shifts since 2026-04-26 (provider inheritance dropped, eidos in production, doctrina parte IV, sound eager-init); pendings section reflects the eidos migration roadmap; "see also" purged of deleted files - src/uix/morfo/README.md — file tree updated (removed DESIGN/study, added compile/runtime/PERMUTATION_RUNNER); see-also pruned - src/uix/sema/README.md — SoundChannel section now describes the eager-init pattern (constructor-time, not lazy); pointer to sema-implementation-guide added - src/uix/soma/README.md — drops terra/air mentions, declares the actual dependency direction (eidos -> soma, not the reverse) - src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual y deuda histórica" reflecting Provider-inheritance-drop; demo path updated to web/routes/ - src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to $libs/days (no external/dates façade); demo paths swapped from /test/soma/* to web/routes/ - src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/ with a relocation note - CLAUDE.md — Refactor Documents section replaced with Reference Documents pointing to per-layer READMEs npm run check holds at baseline (39 pre-existing errors, none new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
> **Doctrina del API**: soma mantiene la forma compound (`Toggle.Provider`,
> `Tabs.Provider + Tabs.Trigger + ...`) por simetria con los multi-parte.
> Eidos no inventa una API flat paralela: aplica la capa visual sobre la
> anatomia declarada por morfo y materializada por soma.
## Handoff 2026-05-14
Soma no debe crecer ahora con `ActiveSoma`/`EngineSoma` por simetria. El
contrato minimo de `SomaRuntime` con `ActiveUix` (`dom`, `events`, `langs`,
`format`, `prefs`) queda descrito en `src/uix/contracts.ts`. La regla de
ownership ya queda cerrada: Soma no crea servicios
compartidos. Recibe `dom` desde el scope `Soma.runtime(...)`; si no hay una
superficie `ActiveDom`, falla en la raiz activa, no dentro de un componente.
Punto critico para manana: confirmar que todo atributo mutable sigue pasando
por el servicio DOM activo, y que ninguna ausencia de `dom` hace que Soma o
Sema caigan a escrituras directas.
---
## 1. Proposito
docs: prune obsolete audits + studies, refresh remaining references Deleted 60 obsolete documents that no longer reflect the active-uix state: - 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md) - 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21, audit-prompt template) - 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/ PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24) - 2 superseded refactor proposals (refactor_claude, refactor_code) - 1 stale bug log (form/BUG-onchange-onblur-hang — repro path src/routes/test/sium/kitchen-sink no longer exists) Updated the remaining operational references to drop dead links and reflect the post-cleanup architecture: - src/uix/README.md — rewritten links section, dropped pointers to terra/air/CONTINUITY/refactor docs, updated adom/dom paths - src/uix/active_architecture.md — header now dated 2026-05-08, lists the major shifts since 2026-04-26 (provider inheritance dropped, eidos in production, doctrina parte IV, sound eager-init); pendings section reflects the eidos migration roadmap; "see also" purged of deleted files - src/uix/morfo/README.md — file tree updated (removed DESIGN/study, added compile/runtime/PERMUTATION_RUNNER); see-also pruned - src/uix/sema/README.md — SoundChannel section now describes the eager-init pattern (constructor-time, not lazy); pointer to sema-implementation-guide added - src/uix/soma/README.md — drops terra/air mentions, declares the actual dependency direction (eidos -> soma, not the reverse) - src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual y deuda histórica" reflecting Provider-inheritance-drop; demo path updated to web/routes/ - src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to $libs/days (no external/dates façade); demo paths swapped from /test/soma/* to web/routes/ - src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/ with a relocation note - CLAUDE.md — Refactor Documents section replaced with Reference Documents pointing to per-layer READMEs npm run check holds at baseline (39 pre-existing errors, none new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
soma resuelve **behavior, accesibilidad, composicion y estado** para componentes compuestos. No resuelve presentacion visual — eso es responsabilidad de eidos.
soma existe para:
- keyboard navigation entre partes de un componente
- focus management (trap, scope, roving)
- ARIA relationships entre partes (trigger↔content, tab↔panel)
- floating/positioning de overlays
- portal rendering
- presence management (enter/exit animations)
- dismiss on outside click / Escape
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- gesture tracking (drag, swipe, resize)
- state machines para componentes con multiples estados
- form integration (hidden inputs, validation context)
soma NO existe para:
- colores, tipografia, espaciado, animaciones visuales
- tokens de tema
- responsive design
- iconografia
- componentes de una sola parte sin behavior complejo
---
## 2. Criterio de pertenencia
Un componente pertenece a soma si cumple **ambos** criterios:
### Composicion de partes
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
El componente tiene 2 o mas subcomponentes que se comunican via context. Ejemplo: Accordion tiene Root, Item, Trigger, Content — cada parte lee estado del padre.
### Behavior complejo
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
El componente implementa al menos uno de:
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Keyboard navigation no trivial (roving focus, arrow keys, typeahead)
- Focus management (trap, scope, restore)
- Floating positioning (popover, tooltip, dropdown)
- ARIA relationships que requieren IDs cruzados (aria-controls, aria-labelledby)
- State machine con transiciones (open/closed, editing/preview)
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Drag/gesture behavior (slider, splitter, drawer, toast)
- Form integration via context (validation state, hidden inputs)
docs: prune obsolete audits + studies, refresh remaining references Deleted 60 obsolete documents that no longer reflect the active-uix state: - 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md) - 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21, audit-prompt template) - 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/ PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24) - 2 superseded refactor proposals (refactor_claude, refactor_code) - 1 stale bug log (form/BUG-onchange-onblur-hang — repro path src/routes/test/sium/kitchen-sink no longer exists) Updated the remaining operational references to drop dead links and reflect the post-cleanup architecture: - src/uix/README.md — rewritten links section, dropped pointers to terra/air/CONTINUITY/refactor docs, updated adom/dom paths - src/uix/active_architecture.md — header now dated 2026-05-08, lists the major shifts since 2026-04-26 (provider inheritance dropped, eidos in production, doctrina parte IV, sound eager-init); pendings section reflects the eidos migration roadmap; "see also" purged of deleted files - src/uix/morfo/README.md — file tree updated (removed DESIGN/study, added compile/runtime/PERMUTATION_RUNNER); see-also pruned - src/uix/sema/README.md — SoundChannel section now describes the eager-init pattern (constructor-time, not lazy); pointer to sema-implementation-guide added - src/uix/soma/README.md — drops terra/air mentions, declares the actual dependency direction (eidos -> soma, not the reverse) - src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual y deuda histórica" reflecting Provider-inheritance-drop; demo path updated to web/routes/ - src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to $libs/days (no external/dates façade); demo paths swapped from /test/soma/* to web/routes/ - src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/ with a relocation note - CLAUDE.md — Refactor Documents section replaced with Reference Documents pointing to per-layer READMEs npm run check holds at baseline (39 pre-existing errors, none new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
Si un componente cumple solo uno de los criterios o ninguno, no necesita pasar por soma — su lógica puede vivir directamente en el wrapper de eidos.
---
## 3. Independencia
soma solo depende de:
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- svelte (runes: $state, $derived, $effect)
- runed (Context, watch)
- clsx (class merging)
- @floating-ui (positioning)
docs: prune obsolete audits + studies, refresh remaining references Deleted 60 obsolete documents that no longer reflect the active-uix state: - 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md) - 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21, audit-prompt template) - 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/ PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24) - 2 superseded refactor proposals (refactor_claude, refactor_code) - 1 stale bug log (form/BUG-onchange-onblur-hang — repro path src/routes/test/sium/kitchen-sink no longer exists) Updated the remaining operational references to drop dead links and reflect the post-cleanup architecture: - src/uix/README.md — rewritten links section, dropped pointers to terra/air/CONTINUITY/refactor docs, updated adom/dom paths - src/uix/active_architecture.md — header now dated 2026-05-08, lists the major shifts since 2026-04-26 (provider inheritance dropped, eidos in production, doctrina parte IV, sound eager-init); pendings section reflects the eidos migration roadmap; "see also" purged of deleted files - src/uix/morfo/README.md — file tree updated (removed DESIGN/study, added compile/runtime/PERMUTATION_RUNNER); see-also pruned - src/uix/sema/README.md — SoundChannel section now describes the eager-init pattern (constructor-time, not lazy); pointer to sema-implementation-guide added - src/uix/soma/README.md — drops terra/air mentions, declares the actual dependency direction (eidos -> soma, not the reverse) - src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual y deuda histórica" reflecting Provider-inheritance-drop; demo path updated to web/routes/ - src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to $libs/days (no external/dates façade); demo paths swapped from /test/soma/* to web/routes/ - src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/ with a relocation note - CLAUDE.md — Refactor Documents section replaced with Reference Documents pointing to per-layer READMEs npm run check holds at baseline (39 pre-existing errors, none new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- `$libs/reactive`, `$libs/days`, etc. — utilidades puras del repo (no façades)
- `$uix/morfo` — el contrato cross-layer (compileMorfo + SomaRuntime)
docs: prune obsolete audits + studies, refresh remaining references Deleted 60 obsolete documents that no longer reflect the active-uix state: - 47 per-component audit logs (*-audit.md, audit_N.md, AUDIT.md) - 5 global soma audits (AUDIT_1, codex_audit, soma-audit-04-20/21, audit-prompt template) - 5 closed studies (soma/study, morfo/study, morfo/DESIGN, morfo/ PROVIDER_STUDY_2026-04-23, uix/CONTINUITY_2026-04-24) - 2 superseded refactor proposals (refactor_claude, refactor_code) - 1 stale bug log (form/BUG-onchange-onblur-hang — repro path src/routes/test/sium/kitchen-sink no longer exists) Updated the remaining operational references to drop dead links and reflect the post-cleanup architecture: - src/uix/README.md — rewritten links section, dropped pointers to terra/air/CONTINUITY/refactor docs, updated adom/dom paths - src/uix/active_architecture.md — header now dated 2026-05-08, lists the major shifts since 2026-04-26 (provider inheritance dropped, eidos in production, doctrina parte IV, sound eager-init); pendings section reflects the eidos migration roadmap; "see also" purged of deleted files - src/uix/morfo/README.md — file tree updated (removed DESIGN/study, added compile/runtime/PERMUTATION_RUNNER); see-also pruned - src/uix/sema/README.md — SoundChannel section now describes the eager-init pattern (constructor-time, not lazy); pointer to sema-implementation-guide added - src/uix/soma/README.md — drops terra/air mentions, declares the actual dependency direction (eidos -> soma, not the reverse) - src/uix/soma/SOMA_ARCHITECTURE.md — §15 rewritten as "Estado actual y deuda histórica" reflecting Provider-inheritance-drop; demo path updated to web/routes/ - src/uix/soma/COMPONENT_GUIDE.md — A23 dates section now points to $libs/days (no external/dates façade); demo paths swapped from /test/soma/* to web/routes/ - src/uix/morfo/PERMUTATION_RUNNER.md — paths swapped to web/routes/ with a relocation note - CLAUDE.md — Refactor Documents section replaced with Reference Documents pointing to per-layer READMEs npm run check holds at baseline (39 pre-existing errors, none new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
- `$uix/sema` — vocabulario semántico + EngineSemantic
soma NO depende de eidos. La capa visual lee del DOM y de los tipos
públicos del soma; la dirección del acoplamiento es eidos → soma, no
al revés.
Todo lo demas vive dentro de `src/uix/soma/`.
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Imports
**Dentro de soma** (provider files, layer files, utility files): usar **paths relativos**. Hace la libreria portable sin forzar aliases en el build del consumidor.
```ts
// Inside soma — relative
import { DRAWER_LANGS } from './langs';
import type { DrawerSide } from './types';
import { Presence } from '../../layers/presence.svelte';
```
**Consumidores** (layouts, app code, test pages): usan el alias `$soma/` que configuran en su build.
```ts
// Consumer code — alias
import { componentLangs } from '$soma/core/langs';
import * as Drawer from '$soma/components/drawer';
```
soma no importa de `$lib` — cualquier utilidad que necesite (e.g., funciones triviales) debe vivir dentro de soma.
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
soma **sí importa** del paquete hermano **morfo** (`$uix/morfo`), que es el contrato declarativo de la superficie DOM de cada componente (partes, data-attrs, ARIA, keyboard, focus). Ver §4b.
---
## 4. Estructura
```
src/uix/soma/
│
├── README.md
│
├── reactive/ ← sistema reactivo (propio, sin deps externas)
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── reactive.svelte.ts ← state, readableActive, writableActive, autoReset
│ └── index.ts
│
├── provider/ ← context + opts bridge
│ ├── provider.svelte.ts ← ProviderOpts/WithRefOpts
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── context.ts ← context<T>(name) — wraps runed Context
│ └── index.ts
│
├── props/ ← prop merging
│ ├── merge-props.ts ← mergeProps(...sources)
│ ├── compose-handlers.ts
│ └── index.ts
│
├── keyboard/ ← keyboard system
│ ├── keys.ts ← KEYS constant
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── directional.ts ← getDirectionalKeys
│ ├── is-using-keyboard.svelte.ts
│ └── index.ts
│
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
├── dom/ ← DOM utilities
│ ├── core.ts ← isHTMLElement, contains, getDocument, etc.
│ ├── env.ts ← isBrowser, isIOS, isTouch
│ ├── context.svelte.ts ← DOMContext class
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── focus/ ← focus utilities
│ │ ├── focus.ts ← focus(), focusFirst(), focusWithoutScroll()
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ │ ├── tabbable.ts ← getTabbableCandidates(), edges
│ │ ├── roving-focus.svelte.ts ← RovingFocusGroup class
│ │ ├── arrow-nav.ts ← useArrowNavigation()
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ │ └── guards.ts ← isElementHidden, isFocusVisible
│ └── index.ts
│
├── events/ ← event system
│ ├── types.ts ← EventCallback, typed helpers
│ ├── add-event-listener.ts
│ └── index.ts
│
├── css/ ← style utilities
│ ├── parse.ts ← cssToStyleObj, styleToString
│ ├── sr-only.ts ← srOnlyStyles
│ └── index.ts
│
├── id/ ← ID generation
│ ├── create-id.ts
│ └── index.ts
│
├── types/ ← shared types
│ ├── component.ts ← WithChild, WithRefOpts, Orientation, Direction
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── events.ts ← SomaEvent, SomaKeyboardEvent, SomaMouseEvent
│ ├── html.ts ← PrimitiveDivAttributes, PrimitiveButtonAttributes
│ ├── guards.ts ← isNull, isFunction, isNumberString
│ └── index.ts
│
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
├── layers/ ← behavior layers (ver §10)
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── presence.svelte.ts ← animation-aware mount/unmount
│ ├── focus-scope.svelte.ts ← focus trap, auto-focus, restore
│ ├── dismissal.svelte.ts ← escape + interact-outside (merged)
│ ├── text-selection.svelte.ts ← prevenir selection overflow
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── scroll-lock.svelte.ts ← body scroll lock con refcount
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── resize-observer.svelte.ts ← ResizeObserver con lifecycle Svelte
│ ├── floating/ ← posicionamiento relativo a anchor (@floating-ui)
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ │ ├── floating.svelte.ts
│ │ ├── use-floating.svelte.ts
│ │ ├── safe-polygon.ts
│ │ ├── types.ts
│ │ ├── utils.ts
│ │ └── index.ts
│ ├── gesture/ ← drag/swipe/resize gesture tracking
│ │ ├── gesture.svelte.ts ← Gesture.base(), Gesture.drag(), Gesture.resize()
│ │ ├── velocity.ts ← ring buffer + velocity calculation (pure)
│ │ ├── types.ts
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ │ └── index.ts
│ └── index.ts
│
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
├── core/
│ ├── soma.svelte.ts ← Soma class (root instance, service accessors)
│ └── langs.ts ← legacy componentLangs catalog during morfo migration
│
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
├── components/
│ ├── internal/ ← componentes Svelte internos de soma
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ │ ├── arrow.svelte
│ │ ├── visually-hidden.svelte
│ │ ├── portal.svelte
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ │ ├── portal-consumer.svelte
│ │ └── index.ts
│ │
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ └── [componente]/ ← each headless component
│ ├── [comp]-provider.svelte.ts ← state classes concretas
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── types.ts ← public props + canonical field shapes
│ ├── langs.ts ← optional idlangref constants for imperative strings
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── components/ ← svelte wrappers
│ ├── exports.ts ← barrel (Provider, not Root)
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ └── index.ts
│
├── exports.ts ← barrel principal
└── index.ts
```
---
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
## 4b. Morfo — contrato declarativo cross-layer
Cada componente tiene un archivo en `src/uix/morfo/components/{kebab}.ts` que declara, en un único objeto tipado, la **superficie DOM pública** del componente:
- **parts** — el árbol de partes (name, kebab, kind, defaultElement, role, states, supportsNesting).
- **data** — qué data-attrs emite cada parte, con valores enum cuando aplica y severity (`required` / `recommended` / `optional`).
- **aria** — qué atributos ARIA emite cada parte, con la fuente del valor tipada vía tagged union (`v.literal`, `v.stateRef`, `v.partRef`, `v.propRef`, `v.translationRef`) y condición de emisión opcional.
- **keyboard** — los atajos de teclado relevantes por parte.
- **focus** — política de foco para overlays (`initial`, `trap`, `return`, `restore`).
- **translations** — catálogo de traducciones propio del componente, registrado bajo `components.{kebab}`.
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
- **apg** — URL al patrón WAI-ARIA APG cuando aplica.
- **scope** — las capas que implementan el componente: `['soma']`, `['soma', 'eidos']`, etc.
El morfo es la **única fuente de verdad** del contrato público. soma, air, eidos, sema y la docs auto-generada lo consumen todos.
### ¿Por qué morfo existe?
Antes de morfo, la información estructural de un componente vivía en seis sitios:
1. mapas manuales de attrs — nombres de partes dentro del provider.
2. registro manual de contrato — enums de data-attrs en el provider.
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
3. ARIA hard-coded en cada `$derived.by(...)` de props.
4. Keyboard handlers distribuidos por el provider.
5. Prose en el README.
6. Selectores en CSS de air/eidos, `.csem` de sema y tablas de docs.
Renombrar una parte (`content` → `panel`) tocaba 6+ sitios sin verificación automática. Drift cross-layer (soma emite `data-dialog-content`, eidos estiliza `data-dialog-panel`) era silencioso.
Con morfo, **todo se declara una sola vez**. `compileMorfo`, `registerMorfo`,
`SomaRuntime` y el helper tipado `createAttrs` consumen el morfo directamente.
El script `npm run morfo:check` valida el DOM real contra la declaración en CI.
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
### Cómo soma consume un morfo
Cada provider raíz crea un runtime con su morfo. Ese paso registra el contrato
`data-*`, compila la declaración y publica `morfo.translations` en los `ActiveLangs`
conectados por `ActiveUix`:
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
```ts
import { dialogMorfo } from '../../../morfo/components/dialog';
this.runtime = Soma.require().runtime(dialogMorfo, sources);
```
Cuando un provider necesita un selector DOM, puede usar `createAttrs(morfo)`
desde `$uix/morfo`. Es solo un helper tipado de nombres, no registra contrato
ni escribe en el DOM:
```ts
import { createAttrs } from '$uix/morfo';
const attrs = createAttrs(dialogMorfo); // { provider: 'data-dialog', trigger: 'data-dialog-trigger', ... }
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
```
`createAttrs` es **genérica con `const` type parameter** (TS 5.0+): infiere el
tipo del objeto retornado a partir de la forma literal del morfo. Si un wrapper
o provider escribe `attrs.trigerr`, es error de compilación. El soporte de
autocomplete lista las partes válidas.
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
El registro ejecutable ocurre al crear el runtime: `createSomaRuntime(morfo, sources)` y `soma.runtime(morfo, sources)` llaman internamente a `registerMorfo(morfo)`. Ese registro compila el morfo, registra su contrato `data-*` y publica `morfo.translations` en los `ActiveLangs` conectados por `ActiveUix`.
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
**Requisito de autoría**: cada morfo se declara como `as const satisfies Morfo`:
```ts
// ✅ Obligatorio
export const dialogMorfo = { ... } as const satisfies Morfo;
// ❌ Pierde literales, degrada `createAttrs` a `Record<string, string>`
export const dialogMorfo: Morfo = { ... };
```
Ver el dev guide completo en [`src/uix/morfo/README.md`](../morfo/README.md).
### Validación
Tres capas atrapan tres clases de drift:
- **Schema (build/dev)**: `validateMorfo(morfo)` en `src/uix/morfo/schema.ts` valida shape (sium) + invariantes cruzados (kebabs únicos, `partRef.target` resuelve, `stateRef.state` está en `states[]`, etc.).
- **Strict mode en `assertContract` (dev runtime)**: valida que los data-attrs emitidos por el provider tienen valores declarados en el morfo. Logs warnings en consola cuando algo se desvía.
- **CI**: `npm run morfo:check` navega a cada demo y valida el DOM real contra el morfo; `npm run morfo:vocabulary` detecta divergencias de vocabulario canónico (`open|closed`, `active|inactive`, etc.).
### Qué NO va en morfo
| No | Va en |
| -------------------------------- | -------------------------------- |
| Props del componente | `{component}/types.ts` con JSDoc |
| Summary, comparativa, ejemplos | `{component}/README.md` |
| Traducciones shared/common | app/langs catalog bajo `common.*` |
| Constantes idlangref imperativas | `{component}/langs.ts`, opcional |
| Event handlers, state machines | `{component}-provider.svelte.ts` |
| Recetas visuales | `src/uix/eidos/` (futuro) |
soma: fix slider thumb alignment + document morfo in README ## Slider thumb misalignment `SliderThumbProvider.thumbStyle` used `translate(50%, -50%)` for both LTR and RTL. For LTR that pushed the thumb RIGHT by half its width from the `left: X%` anchor — visible symptoms in the time-picker / time-range-picker demos: - thumb never reached `left: 0` (centre at value=0 was offset by thumbWidth/2) - thumb overshot the track on the right edge at value=max - drag felt off by the same amount throughout Fix: use `translate(-50%, -50%)` for LTR (thumb centre aligns with anchor) and keep `translate(50%, -50%)` for RTL (anchor is `right: X%`, thumb must shift right by half its width to centre-align). Matches the logic already used by `SliderTickProvider` which chose `tx = isRtl ? '50%' : '-50%'`. Browser probe confirms: value=0 now centres at 0%, value=30/59 at ~50.8%, style attribute reports `translate(-50%, -50%)` in LTR. ## soma README documents morfo Added §4b "Morfo — contrato declarativo cross-layer" covering: why morfo exists (6-place drift without it), how providers consume it (`createAttrs(morfo)` + `registerContract(morfo)`), the mandatory `as const satisfies Morfo` authoring pattern for literal-typed inference, the 3-layer validation pipeline (schema / assertContract / morfo-check), and the boundary (what does NOT go in morfo — props, prose, langs, state machines, visual recipes). Updated the §4 structure listing so `attrs/create-attrs.ts` shows the new signature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
---
## 5. Sistema reactivo
Los runes de Svelte 5 (`$state`, `$derived`) son compiler magic — solo funcionan en archivos `.svelte` y `.svelte.ts`, y no se pueden pasar como valores entre clases o funciones en TypeScript puro. soma necesita exactamente eso: pasar estado reactivo como argumento de constructor para componer Providers, layers y gestures. La capa `reactive/` resuelve esto con contenedores (`Active<T>`, `State<T>`) que envuelven runes y exponen `.current` — el mismo patrón que React refs y Solid signals. Cuando Svelte ofrezca signals exportables de primera clase, esta capa se convierte en un alias thin migrable sin tocar los consumidores.
### Primitivas
```ts
// Mutable container — backed by $state
const count = state(0);
count.current++;
// Readonly derived — backed by $derived.by
const double = readableActive(() => count.current * 2);
double.current; // 2
// Writable derived — getter + setter (para two-way binding)
const bound = writableActive(
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
() => pressed,
(v) => (pressed = v)
);
```
### Tipos
```ts
// Readonly reactive container
type Active<T> = { readonly current: T };
// Mutable reactive container
type State<T> = { current: T };
// Mapping helpers — wraps all properties
type ActiveProps<T> = { [K in keyof T]: Active<T[K]> };
type StateProps<T> = { [K in keyof T]: State<T[K]> };
```
### Regla
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Los providers de soma reciben sus opciones como `Active<T>` o `State<T>`. Los wrappers svelte convierten props normales a Active/State con `readableActive`/`writableActive`. Esta conversion es la frontera entre el mundo de props de Svelte y el mundo de clases reactivas de soma.
---
## 6. Sistema de contexto
Hay dos niveles: la funcion `context()` (interna) y los static methods de cada clase provider (API publica).
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Nivel interno — `context()`
```ts
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
import { context } from '../provider';
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
const ctx = context<AccordionProvider>('Accordion');
ctx.set(instance); // registra en Svelte context
ctx.get(); // lee — throws si no existe
ctx.getOr(fallback); // lee con fallback
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
`context()` wraps runed's `Context` con mensajes de error descriptivos.
### Nivel publico — static methods
Los consumidores (sub-parts, otros componentes) nunca tocan `ctx` directamente. Usan los static methods:
```ts
// Root provider registra via create()
static create(opts) {
return new AccordionProvider(opts);
}
private constructor(opts) {
this.runtimePart = this.runtime.part('provider', {
id: opts.id,
ref: opts.ref,
owner: this,
context: AccordionProvider.ctx,
syncAttrs: true
});
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
}
// Sub-parts leen via require() o get()
this.provider = AccordionProvider.require(); // throws
this.group = TooltipGroupProvider.get(); // undefined si no existe
```
| Method | Returns | Use |
| ----------- | --------------------- | -------------------- |
| `create()` | instance | Root crea + registra |
| `get()` | instance \| undefined | Padre opcional |
| `require()` | instance (throws) | Padre obligatorio |
---
## 7. Runtime parts
Soma ya no usa una clase base `Provider`. Cada provider es una clase concreta
del componente, y registra sus partes mediante `SomaRuntime`. El runtime es la
autoridad de morfo en soma: registra la parte, crea el ref attachment, expone la
identidad renderizable (`id`, marker `data-*`, archetype) y valida los props
autorizados por el contrato.
```ts
import { context, type WithRefOpts } from '../provider';
import { Soma } from '../core/soma.svelte';
import type { SomaRuntimePart } from '../runtime.svelte';
import { accordionMorfo } from '$uix/morfo/components/accordion';
export class AccordionProvider {
static readonly ctx = context<AccordionProvider>('Accordion');
static get() {
return this.ctx.getOr(undefined) as AccordionProvider | undefined;
}
static require() {
return this.ctx.get();
}
readonly opts: AccordionOpts;
readonly runtimePart: SomaRuntimePart;
static create(opts: AccordionOpts) {
return new AccordionProvider(opts);
}
private constructor(opts: AccordionOpts) {
this.opts = opts;
this.runtimePart = Soma.require().runtime(accordionMorfo, {}).part('provider', {
id: opts.id,
ref: opts.ref,
owner: this,
context: AccordionProvider.ctx,
syncAttrs: true
});
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
'data-orientation': this.opts.orientation?.current,
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled.current)
} as const)
);
}
```
### Lo que `runtime.part()` proporciona
```ts
interface SomaRuntimePart {
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
readonly attachment: RefAttachment;
readonly props: { id, [partAttr], 'data-archetype'?, ...attachment };
resolveProps(bindings?): Record<string, unknown>;
assert<P>(props: P): P; // validates data-* contract
}
```
`runtime.part()` es la única API pública para registrar partes. Cuando una parte
ya declara sus `states`/`props` como sources del runtime, activa
`syncAttrs: true`; en ese modo los attrs derivados por morfo se escriben
mediante `uix.dom`. Si el provider todavía compone attrs en sus props
renderizados, deja `syncAttrs` sin activar para evitar doble autoridad DOM.
### Lo que cada componente define
- `static ctx` — solo si usa context
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `static create()` / `get()` / `require()` — static method convention
- Constructor — asigna `opts` y registra `runtimePart`
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `readonly props = $derived.by(...)` — ARIA, data-\*, events
- Event handlers — logica de interaccion
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Derived state — valores computados
---
## 8. Sistema de attrs
```ts
import { accordionMorfo } from '$uix/morfo/components/accordion';
const attrs = createAttrs(accordionMorfo);
attrs.provider; // "data-accordion"
attrs.item; // "data-accordion-item"
attrs.trigger; // "data-accordion-trigger"
// Selector: `[${attrs.content}]`
```
`createAttrs` vive en `morfo` y solo expone nombres tipados para selectors o
tooling. La emisión de markers (`data-accordion`, `data-accordion-item`, etc.)
y la escritura de attrs dinámicos pertenecen a `SomaRuntime.part(...)`.
### Regla de naming
- La parte `provider` genera `data-{component}` (sin sufijo `-provider`)
- Las demas partes generan `data-{component}-{part}`
- Estos attrs son API publica — cambiarlos es breaking change
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- air/eidos los usa como selectores CSS
### Contracts (via morfo)
El morfo declara cada parte y sus `data-*` attrs (`required`/`recommended`/`optional`,
con valores enumerados cuando aplica). `runtimePart.assert()` valida en desarrollo que los
atributos emitidos cumplen el morfo. `scripts/morfo-check.ts` valida contra el DOM real.
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Boolean helpers
```ts
boolToStr(true); // 'true'
boolToEmptyStrOrUndef(true); // ''
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
boolToEmptyStrOrUndef(false); // undefined
boolToTrueOrUndef(true); // true
boolToTrueOrUndef(false); // undefined
```
---
## 9. mergeProps
```ts
const merged = mergeProps(restProps, state.props);
```
Comportamiento:
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Event handlers (`onclick`, `onfocus`, etc.) → compuestos con `composeHandlers`
- `class` → merged con clsx
- `style` → merged (object + string)
- `hidden: false` / `disabled: false` → eliminados (fix Svelte)
- Resto → last wins
---
## 10. Layers
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Los layers son infraestructura compartida que los componentes compuestos usan para resolver problemas transversales.
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Principio
`layers/` contiene **solo clases de comportamiento** (`.svelte.ts`). Son infraestructura consumida por Providers.
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Los componentes Svelte internos de soma (Portal, Arrow, VisuallyHidden) viven en `components/internal/` — no son layers.
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Behavior layers — consumo en Provider
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Los behavior layers se instancian dentro del Provider y exponen `.props` para merge:
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
```ts
class DrawerContentProvider {
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
readonly focusScope = FocusScope.use({ ref, trap, ... });
readonly dismissal = Dismissal.use({ ref, onEscapeKeydown, ... });
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
readonly scrollLock = new ScrollLock();
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
readonly gesture = Gesture.drag({ ref, direction, threshold, ... });
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
readonly props = $derived.by(() => this.runtimePart.assert({
...this.runtimePart.props,
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
...this.focusScope.props,
...this.dismissal.props,
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
...this.gesture.props,
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
role: 'dialog',
}));
}
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Convencion `.use()` vs `new` vs `Gesture.x()`
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `X.use(opts)` — el layer gestiona su propio lifecycle via `watch`/`$effect`. Constructor privado.
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `new X(opts)` — el consumidor controla el lifecycle.
- `Gesture.base/drag/resize(opts)` — factory functions, tres especializaciones.
| Layer | API | Props | Descripcion |
| ----------------- | --------------------------------- | ----------------------------------- | -------------------------------------------------- |
| `Presence` | `new Presence(opts)` | — | Animation-aware mount/unmount. Expone `isPresent`. |
| `FocusScope` | `FocusScope.use(opts)` | `{ tabindex: -1 }` | Focus trap, loop, auto-focus, restore. |
| `Dismissal` | `Dismissal.use(opts)` | `{ onfocuscapture, onblurcapture }` | Escape + interact-outside. Global registry. |
| `TextSelection` | `TextSelection.use(opts)` | — | Previene selection overflow durante drag. |
| `ScrollLock` | `new ScrollLock()` | — | Body scroll lock con refcount. |
| `ResizeObserver$` | `new ResizeObserver$(getter, cb)` | — | ResizeObserver con lifecycle Svelte. |
| `Gesture.base` | `Gesture.base(opts)` | `{ onpointerdown }` | Pointer tracking + axis lock + velocity. |
| `Gesture.drag` | `Gesture.drag(opts)` | `{ onpointerdown }` | Base + progress + snap points + dismiss. |
| `Gesture.resize` | `Gesture.resize(opts)` | `{ onpointerdown }` | Base + delta + min/max constraints. |
| `SafePolygon` | `new SafePolygon(opts)` | — | Hover-gap corridor between trigger↔content. |
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Gesture layer
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Three specializations, shared base. The layer measures — the component decides what it means.
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
```
Gesture.base() → pointer tracking + axis lock + velocity + cancel
Gesture.drag() → base + offset + progress + snap points + threshold + dismiss
Gesture.resize() → base + delta forwarding + min/max constraints
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Key rules:
- `setPointerCapture` deferred until moveBuffer exceeded for containers with child buttons (Drawer, Slider). Pure drag handles (Splitter) capture immediately — the handle IS the drag target
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Cleanup on unmount: `$effect(() => { return () => { this.gesture.cancel(); }; })`
- CSS vars (`--drawer-progress`, `--drawer-offset-x/y`) set by provider, consumed by visual layer
- During drag: `transition: none` + inline `transform` for immediate feedback
- Design: `src/uix/soma/layers/GESTURES.md`
### SafePolygon
Handles pointer gap between trigger and floating content (DropdownMenu submenus, Tooltip). Calculates a corridor polygon — pointer can traverse the gap without closing. Used by any component where trigger and content have physical separation.
### Patterns
**Registry over DOM queries**: Sub-parts register in a Map on mount, unregister on unmount. Keyboard nav iterates the registry instead of `querySelectorAll`. Used by Stepper triggers, Select labels.
**Virtual focus (`aria-activedescendant`)**: For Select, Combobox — focus stays on trigger, items highlighted via `data-highlighted`. DOM focus (roving tabindex) for Menu, Toolbar, RadioGroup.
**Exit animation via Presence**: Toast, Drawer — dismiss marks element as `dismissing`, Presence animates exit, `onComplete` removes from array.
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Naming
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Archivo = concepto: `dismissal.svelte.ts`, `presence.svelte.ts`
- Clase = concepto: `Dismissal`, `Presence`, `FocusScope`, `ScrollLock`, `Gesture`
- Opts type: `{Concepto}Opts`: `DismissalOpts`, `GestureBaseOpts`
- Sin sufijos redundantes: no `Layer`, no `State`, no `Body`
---
## 11. Keyboard
```ts
KEYS.ENTER; // 'Enter'
KEYS.ESCAPE; // 'Escape'
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
KEYS.ARROW_DOWN; // 'ArrowDown'
KEYS.SPACE; // ' '
const { nextKey, prevKey } = getDirectionalKeys('ltr', 'horizontal');
// nextKey: 'ArrowRight', prevKey: 'ArrowLeft'
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
IsUsingKeyboard.current; // boolean — teclado vs pointer
```
---
## 12. DOM utilities
### Focus
```ts
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
focusWithoutScroll(element)
focusFirst(candidates[])
getTabbableCandidates(container)
getTabbableEdges(container)
```
### Roving Focus
```ts
const roving = new RovingFocusGroup({
candidateAttr: attrs.trigger,
rootNode: ref,
loop: true,
orientation: 'horizontal'
});
roving.handleKeydown(currentElement, event);
```
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Scroll Lock
```ts
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
const lock = new ScrollLock();
lock.locked.current = true; // locks body scroll
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
lock.locked.current = false; // restores
```
---
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
## 13. Soma (root instance)
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Soma es la identidad runtime del framework. Lee servicios de App via context. No inyecta traducciones — el consumidor las carga.
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Clase
```ts
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
class Soma {
static create(opts?: SomaOptions): Soma; // crea y registra en context
static get(): Soma | undefined; // lee del context (safe)
static require(): Soma; // throws si no existe
readonly uix: ActiveUix;
readonly portalTo: string | HTMLElement | undefined;
// Service accessors (delegan a ActiveUix)
get langs(): ActiveLangs;
get nums(): ActiveNumbers | undefined;
get money(): ActiveCurrency | undefined;
get dates(): ActiveDates | undefined;
get units(): ActiveUnits | undefined;
get prefs(): ActiveUixPrefsView; // adaptador historico respaldado por uix.prefs
get logger(): EngineLogger;
runtime(morfo, sources): SomaRuntime;
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
}
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Traducciones
El catálogo nuevo de traducciones de componente vive en el morfo:
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
```ts
export const drawerMorfo = {
name: 'Drawer',
kebab: 'drawer',
translations: {
trigger: { es: 'Abrir cajon', en: 'Open drawer' }
}
// ...
} as const satisfies Morfo;
```
`ActiveUix` conecta el registro de morfos con `ActiveLangs`: cuando un provider
crea `createSomaRuntime(morfo, sources)` o llama `soma.runtime(morfo, sources)`,
el morfo se registra y sus `translations` se extienden bajo `components.{kebab}`.
`commonLangs` en `core/langs.ts` aporta los defaults para `v.commonRef(...)`
(`common.buttons.close`, `common.buttons.cancel`, etc.). El integrador puede
predefinir sus propias claves en el schema de langs; `ActiveUix` solo rellena
las que falten.
`componentLangs` en `core/langs.ts` sigue existiendo como catálogo legado de
transición. Mientras convive con `morfo.translations`, `ActiveUix` evita re-registrar
desde morfo los componentes que ya están cubiertos por ese catálogo para no
duplicar hojas.
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Namespace structure:
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
common.buttons.close ← shared (soma + eidos + app)
common.buttons.open
components.dialog.trigger ← component-specific
components.drawer.trigger
```
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Uso en Providers
```ts
// drawer/langs.ts — optional constants for imperative strings
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
export const DRAWER_LANGS = {
CLOSE: '#?common.buttons.close|Close'
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
} as const;
// drawer-provider.svelte.ts
import { DRAWER_LANGS } from './langs';
class DrawerCloseProvider {
readonly props = $derived.by(() => ({
'aria-label': this.provider.soma?.langs.ts(DRAWER_LANGS.CLOSE)
}));
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
}
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Rules:
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `langs.ts()` for simple strings, `langs.t()` only for interpolated templates
- Fallback inline via idlangref (`#?path|fallback`), never `?? 'fallback'`
- No `translate()` helpers in providers
- Text owned by the component goes in `morfo.translations` and is referenced with `v.translationRef`
- Common keys (`close`, `open`, `cancel`) use `common.*` / `v.commonRef`, not per-component duplicates
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Setup
```svelte
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
<Soma>
<App />
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
</Soma>
```
---
## 14. Naming conventions
### Clases
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `AccordionProvider` — root provider del componente
- `AccordionItemProvider` — sub-parte
- `AccordionTriggerProvider` — sub-parte
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Files
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `accordion-provider.svelte.ts` — state classes/providers (NOT `accordion.svelte.ts`)
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `accordion.svelte` — root wrapper (in `components/`)
- `accordion-item.svelte` — sub-part wrapper
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `types.ts` — public props + canonical field shapes
- `langs.ts` — optional idlangref constants for imperative provider strings
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `exports.ts` — barrel (exports `Provider`, not `Root`)
### Props
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `AccordionProps` not `AccordionProviderProps` (root doesn't need "Provider" suffix in type name)
- `AccordionItemProps` — sub-part
- `AccordionTriggerProps` — sub-part
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Documentacion de props (norma obligatoria)
Todas las props de todos los componentes deben documentarse con JSDoc en `types.ts`.
Cada prop lleva: descripcion, `@default` si tiene valor por defecto, notas de comportamiento si aplica.
### Comparacion con librerias de referencia
Cada componente headless debe compararse con su equivalente en ark-ui, bits-ui y radix-ui.
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Documentar: que props tienen ellos que soma no, y justificar si se omiten o se incluyen.
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Attrs
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `data-accordion` — root (sin `-root`)
- `data-accordion-item` — sub-parte
- `data-state` — estado compartido (`open`/`closed`, `on`/`off`, `checked`/`unchecked`)
- `data-disabled` — flag de disabled
- `data-orientation` — orientacion
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- `data-dragging` — gesture activo
### Events
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- DOM handlers: `onclick`, `onkeydown`, `onfocus` (lowercase, Svelte convention)
- User callbacks: `onOpenChange`, `onValueChange` (camelCase)
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Layers
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Archivo = concepto: `dismissal.svelte.ts`, `presence.svelte.ts`
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Clase = concepto: `Dismissal`, `Presence`, `FocusScope`, `ScrollLock`, `Gesture`
- Opts = `{Concepto}Opts`: `DismissalOpts`, `GestureBaseOpts`
- Sin sufijos redundantes
Refactor soma: consolidate layers, add Soma class, Dialog component, animation system Layers: - Consolidate 28 files/10 dirs → 13 files/2 dirs - Separate behavior layers (classes) from internal components - Normalize naming: Dismissal, ScrollLock, TextSelection, FocusScope - Adapt floating layer from terra to soma (imports, CSS vars --soma--) - Presence rewritten: data-starting/ending-style, forceMount, onComplete, getAnimations API Architecture: - Replace config/ with Soma class (root instance with services) - Add SomaFormat namespace (date, number, currency, unit formatters) - Add generic resolve() for prop → config → fallback chain - Provider supports optional ref (ProviderOpts vs WithRefOpts) - Hierarchical component barrel: import { Dialog } from '$soma/components' - Descriptive IDs: soma-dialog-trigger-c12 Dialog component (7 parts): - Provider, Trigger, Content, Overlay, Title, Description, Close - Content integrates all behavior layers as classes (no template nesting) - modal prop controls interactOutsideBehavior automatically - Nested dialog support: depth, data-nested, --soma-dialog-depth CSS vars - Animation support: forceMount, data-starting/ending-style, onOpenChangeComplete - Translator integration for aria-labels - JSDoc documentation on all props Bug fixes: - Presence mount without ref (chicken-and-egg) - ScrollLock unlock path restores body style - Nested dialog infinite loop (untrack mutation) - pointer-events: none blocking dialog interaction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
---
## 15. Patron de componente
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Provider ({name}-provider.svelte.ts)
```ts
import { accordionMorfo } from '$uix/morfo/components/accordion';
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
// Canonical field shapes defined in types.ts, referenced here
interface AccordionOpts
extends WithRefOpts, StateProps<AccordionStateFields>, ActiveProps<AccordionActiveFields> {}
export class AccordionProvider {
static readonly ctx = context<AccordionProvider>('Accordion');
static get() {
return this.ctx.getOr(undefined) as AccordionProvider | undefined;
}
static require() {
return this.ctx.get();
}
readonly opts: AccordionOpts;
readonly runtimePart: SomaRuntimePart;
static create(opts: AccordionOpts) {
return new AccordionProvider(opts);
}
private constructor(opts: AccordionOpts) {
this.opts = opts;
this.runtimePart = Soma.require().runtime(accordionMorfo, {}).part('provider', {
id: opts.id,
ref: opts.ref,
owner: this,
context: AccordionProvider.ctx,
syncAttrs: true
});
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
'data-orientation': this.opts.orientation?.current,
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled.current)
} as const)
);
}
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Wrapper svelte ({name}.svelte)
```svelte
<script lang="ts">
import { readableActive, writableActive } from '../../reactive';
import { mergeProps } from '../../props';
import { createId } from '../../id';
import { AccordionProvider } from '../accordion-provider.svelte';
import type { AccordionProps } from '../types';
const uid = $props.id();
let {
ref = $bindable(null),
id = createId(uid, 'accordion'),
value = $bindable([]),
disabled = false,
children,
child,
...restProps
}: AccordionProps = $props();
const state = AccordionProvider.create({
id: readableActive(() => id),
ref: writableActive(
() => ref,
(v) => (ref = v)
),
value: writableActive(
() => value,
(v) => (value = v)
),
disabled: readableActive(() => disabled)
});
const mergedProps = $derived(mergeProps(restProps, state.props));
</script>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
```
---
## 16. Patron de composicion
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Los componentes compuestos siguen el patron Provider → Parts con contexto:
```svelte
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
<Accordion.Provider bind:value>
<Accordion.Item value="one">
<Accordion.Header>
<Accordion.Trigger>Click me</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content>Content here</Accordion.Content>
</Accordion.Item>
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
</Accordion.Provider>
```
### Flujo de datos
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Provider
├── crea AccordionProvider
├── registra en context via runtime.part(..., { context, owner })
└── children
├── Item
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── crea AccordionItemProvider
│ ├── lee AccordionProvider via AccordionProvider.require()
│ └── children
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
│ ├── Trigger → lee AccordionItemProvider.require()
│ └── Content → lee AccordionItemProvider.require()
└── Item
└── ...
```
### Regla de context
- Root siempre registra en context al crear su `runtimePart`
(`runtime.part(..., { owner: this, context: XProvider.ctx })`)
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Sub-parts leen con `XProvider.require()` (obligatorio) o `XProvider.get()` (opcional)
- Si una sub-part tiene hijos que necesitan su estado, crea su propio context (Item tiene ctx, Trigger lo lee)
- El context es por componente instance — multiples Accordion en la misma pagina funcionan independientemente
---
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
## 17. Relacion con air/eidos
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
soma → headless behavior, accesibilidad, data-* contracts, context
air → visual layer: tokens, CSS recipes, sizes, variants
eidos → enhanced visual layer: motion, sound, advanced interactions
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
air/eidos consume soma:
- Importa componentes: `import { Accordion } from '$uix/soma'`
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Responde a data-\*: `[data-accordion][data-state='open'] { ... }`
- Añade props visuales: `size`, `variant`, `color`
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Usa mismas translations: `#?common.buttons.close|Close`, `#?components.dialog.trigger|Open dialog`
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
air/eidos NUNCA:
- Importa Provider classes internas de soma
- Depende de estructura DOM incidental
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
- Accede a propiedades privadas
- Duplica behavior que soma ya resuelve
---
## 18. Checklist de componente nuevo
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
Referencia completa con todos los pasos en `COMPONENT_GUIDE.md`. Resumen:
```
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
[ ] 1. Comparar con ark-ui, bits-ui, radix-ui — feature table
[ ] 2. Verificar criterio de pertenencia
[ ] 3. Definir partes + attrs + contract
[ ] 4. Crear types.ts (props + canonical field shapes)
[ ] 5. Añadir `morfo.translations` para texto propio; `langs.ts` solo si hacen falta constantes imperativas
[ ] 6. Crear {name}-provider.svelte.ts (state classes concretas, sin heredar de Provider)
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
[ ] 7. Crear wrappers .svelte (thin)
[ ] 8. Crear exports.ts + index.ts
[ ] 9. Crear test page + link en index
[ ] 10. svelte-check + test in browser
```
---
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
## 19. Inventory
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Implemented
Accordion, Checkbox (Group), Collapsible, Combobox, ContextMenu, Dialog (AlertDialog variant), Drawer, DropdownMenu, Editable, LinkPreview, NumberField, Pagination, Popover, RadioGroup, ScrollArea, Select, Slider, Splitter, Stepper, Switch, Tabs, Table, TagsInput, Toast, Toggle (Group), Toolbar, Tooltip, TreeView.
soma: gesture layer, drawer component, full audit fixes across 26 components Gesture Layer: - Gesture.base(), Gesture.drag(), Gesture.resize() — shared pointer tracking - VelocityTracker with ring buffer, staleness check, projection - 52 tests (velocity + gesture integration) - setPointerCapture deferred until moveBuffer exceeded (prevents click stealing) Drawer Component: - 8 parts: Provider, Trigger, Content, Overlay, Handle, Title, Description, Close - Gesture.drag() integration for swipe dismiss - Snap points (fractional + px), fadeFromIndex, handle tap-to-cycle - Modal/non-modal/non-dismissible modes - Logical directions (start/end) RTL-aware via soma presentation - CSS custom properties (--drawer-progress, --drawer-offset-x/y) Architecture: - T1: 219 files migrated from $soma/ alias to relative paths - T2: 35 wrappers — noop replaced with () => {} inline - Translation system: componentLangs + common.buttons.* + idlangref constants - COMPONENT_GUIDE.md + README.md fully updated to reflect current patterns - contracts.ts: case-normalized registerContract/assertContract Audit Fixes (P0 critical): - DI1/PO1/TO1: 'provider' → 'root' in parts/contract/super - TB1: data-table attr on wrapper - CH1/SW1/NF4: hidden input rendering fixes - SP2: panel cleanup on unmount - RG1: roving tabindex fallback to first item - CO1: aria-labelledby on collapsible content Audit Fixes (P1 high): - SafePolygon integrated in dropdown-menu SubProvider + tooltip - 9 langs.ts files with idlangref constants - Dialog: aria-label removed (WCAG 2.5.3), handleOpen/Close guards - Stepper: count decrement + private, aria-label on List - ToggleGroup: roving tabindex in multiple mode - Select: pure aria-activedescendant (no mixed focus), label registry - NumberField: startValue respects min, scrubber commit on pointerup only - Toolbar: element-based focus tracking (not index) Audit Fixes (P2 medium): - A6: timer/listener cleanup in 6 components - A12: getDirectionalKeys in 4 components - A10: DOM queries scoped to root in 3 components - Dropdown-menu: typeahead + Home/End in SubContent, activate() pattern - Checkbox: PrimitiveLabelAttributes, getAriaChecked helper, stale value cleanup - Pagination: reactive page clamping, Set-based computePageRange - Scroll-area: thumbSize zero-guard, mount flash prevention - Splitter: collapse/expand respects adjacent constraints, immediate pointer capture 5 issues remain (design decisions): stepper registry, table sub-row IDs, tags-input ARIA model, tags-input paste, toast exit animation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Planned
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
**Tier 2 (menu + form):** Menubar, Command, Field/Form, FileUpload
**Tier 3 (dates):** Calendar, RangeCalendar, DateField, DatePicker, DateRangeField, DateRangePicker
**Tier 4 (time):** TimeField, TimePicker, TimeRangeField
**Tier 5 (color):** ColorPicker, ColorField, ColorRangePicker, ColorRangeField
**Tier 6 (sound):** SoundPicker, SoundRangePicker
soma: 12 components, architecture docs, naming fixes, form tier complete Components (12): - Accordion (keyboard nav, single/multiple, collapsible, loop) - Checkbox (indeterminate, group, readonly) - Collapsible - Combobox (input + floating listbox, consumer-side filtering) - Dialog (variant dialog/alertdialog, modal, nested, animations, forceMount) - DropdownMenu (15 parts, submenus, typeahead, checkbox/radio items) - Popover (floating, openOnHover, modal, custom anchor) - RadioGroup (roving tabindex, orientation, readonly) - Select (single/multiple, typeahead, scroll-into-view, hidden select) - Slider (drag, keyboard, single/range, ticks, vertical) - Switch (hidden input, data-checked) - Tooltip (skip-delay group, 3-state, hover/focus) Architecture: - State class files renamed: {name}.svelte.ts → {name}-provider.svelte.ts (avoids Vite module resolution ambiguity with .svelte wrappers) - Export name standardized: always Provider, never Root - COMPONENT_GUIDE.md: step-by-step implementation guide with checklist - SOMA_ARCHITECTURE.md: updated structure, anti-patterns, improvements table - README.md: updated naming, file structure, inventory - context.ts: error message uses Provider not Root - Demo index page at /test/soma/ Bug fixes: - DropdownMenu trigger missing onclick/onkeydown in props - DropdownMenu interactOutsideBehavior always 'close' (not modal-dependent) - Checkbox getContext in event handler → captured in constructor - Select context not found → was Vite cache issue (not naming) - ScrollLock unlock path - Floating wrapper z-index: auto override Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 months ago
### Visual-native (no soma)
Avatar (eidos-native), Badge, Button, Label, Meter, Progress, Separator, Spinner, PinInput, RatingGroup, ColorPicker, AspectRatio, Typography, Layout, Icon.

Powered by TurnKey Linux.