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/components/dropdown-menu/dropdown-menu-provider.svel...

1192 lines
35 KiB

import { context, type ProviderOpts, type WithRefOpts } from '../../provider';
import { createAttrs } from '$uix/morfo';
import { boolToEmptyStrOrUndef, getDataOpenClosed } from '$adom';
import {
readableActive,
state,
type Active,
type ActiveProps,
type StateProps
remove backward-compat re-export shims Per architectural feedback: when relocating code to its correct layer, do the migration completely — update every consumer directly and delete the original. No re-export barrels at the old paths. Removed shims: - `src/uix/soma/attrs/` — was re-exporting `createAttrs` / `registerContract` / `assertContract` / `getContract` from `$uix/morfo` and the bool/data-attr formatters from `$libs/dom`. All 66 importing files updated to import from the canonical locations directly. - `src/uix/soma/reactive/` — `reactive.svelte.ts` was a thin re-export of `$libs/reactive`. The 79 consumers (every soma provider + layers + types) now import primitives directly from `$libs/reactive`. The `opts.ts` Props↔Opts bridge moved to `src/uix/soma/provider/opts.ts` (its natural home — provider plumbing, not reactive primitives). - `attachRef` / `RefAttachment` re-export from `src/uix/soma/provider/provider.svelte.ts` and from `src/uix/soma/index.ts`. Both removed. Consumers (`floating.svelte.ts`, `date-field-provider.svelte.ts`) now import directly from `$libs/reactive`. Also: - Moved `ActiveProps<T>` / `StateProps<T>` types to `src/libs/reactive/types.ts` — they're trivial generic helpers over `Active<T>` / `State<T>` and shouldn't have lived in soma. - Stripped soma's root barrel (`src/uix/soma/index.ts`) of every re-export of libs/morfo concerns. It now only re-exports actually-soma surfaces (Provider base, mergeProps, css helpers, id, types, Soma class). Result: - `grep -r '\$soma' src/uix/morfo` → 0 matches - `grep -r '\$uix' src/libs` → 0 matches - `src/uix/soma/attrs/` and `src/uix/soma/reactive/` no longer exist - Every import statement now reflects the real architectural layer Verified: vitest 19/20 files / 214 tests (1 pre-existing air dead- branch fail using `bun:test`), smoke 68/68, morfo-check 66/66.
5 months ago
} from '$libs/reactive';
import type {
OnChangeFn,
SomaMouseEvent,
SomaKeyboardEvent,
Direction,
Arrayable,
StyleProperties
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
} from '../../types';
import { KEYS, getDirectionalKeys } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { Presence } from '../../layers/presence.svelte';
import { FocusScope } from '../../layers/focus-scope.svelte';
import { Dismissal, type DismissalBehavior } from '../../layers/dismissal.svelte';
import { ScrollLock } from '../../layers/scroll-lock.svelte';
import { TextSelection } from '../../layers/text-selection.svelte';
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
import {
FloatingProvider,
FloatingContent,
FloatingArrow,
FloatingAnchor,
type Side,
type Align,
type Boundary
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
} from '../../layers/floating';
import { SafePolygon } from '../../layers/floating/safe-polygon';
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
morfo: port 65 components + sium.lazy + morfo-check passes 66/66 All 65 soma components now consume their morfo as the cross-layer contract. createAttrs(morfo) and registerContract(morfo) overloads removed — the Morfo form is now mandatory. Each component provider has a 3-line morfo import + wire-up block instead of 20+ lines of inline declarations. Additions: sium/core/lazy.ts — lazy() combinator for recursive schemas (unblocks morfo's eventual lazy part-tree validation; tests included). sium/examples/ — booking, color, login, settings, signup, survey, tree form demos. Route demos at src/routes/test/sium/{booking,color,login,settings, signup,survey,tree}. Tooling: morfo-check.ts — now tolerates sibling parts sharing a physical element (Link variant of Item, etc.). Queries via allPartAttrs cross-scope. morfo-vocabulary-check.ts — 28 WARN (legitimate per-component vocabularies or subsets like switch missing "indeterminate"). All reviewed, none are bugs. Fixes caught by morfo-check: table: data-sorted / data-pinned marked severity:'optional' (only emitted when sorting/pinning active, not always). tree-grid: data-expanded on Row severity:'optional' (branches only). menubar: data-menubar-value declared on Trigger. splitter: data-splitter-panel-id declared on Panel. Verify: npm run check — 0 morfo errors (4 pre-existing in sium/examples, unrelated). npx vitest run src/uix/morfo — 7/7 tests pass. npm run smoke — 65/65 routes pass. npm run morfo:check — 66/66 morfos validate against real DOM. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
import { dropdownMenuMorfo } from '../../../morfo/components/dropdown-menu';
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
import type { ActiveTimers, TimerHandle } from '$timer';
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
morfo: port 65 components + sium.lazy + morfo-check passes 66/66 All 65 soma components now consume their morfo as the cross-layer contract. createAttrs(morfo) and registerContract(morfo) overloads removed — the Morfo form is now mandatory. Each component provider has a 3-line morfo import + wire-up block instead of 20+ lines of inline declarations. Additions: sium/core/lazy.ts — lazy() combinator for recursive schemas (unblocks morfo's eventual lazy part-tree validation; tests included). sium/examples/ — booking, color, login, settings, signup, survey, tree form demos. Route demos at src/routes/test/sium/{booking,color,login,settings, signup,survey,tree}. Tooling: morfo-check.ts — now tolerates sibling parts sharing a physical element (Link variant of Item, etc.). Queries via allPartAttrs cross-scope. morfo-vocabulary-check.ts — 28 WARN (legitimate per-component vocabularies or subsets like switch missing "indeterminate"). All reviewed, none are bugs. Fixes caught by morfo-check: table: data-sorted / data-pinned marked severity:'optional' (only emitted when sorting/pinning active, not always). tree-grid: data-expanded on Row severity:'optional' (branches only). menubar: data-menubar-value declared on Trigger. splitter: data-splitter-panel-id declared on Panel. Verify: npm run check — 0 morfo errors (4 pre-existing in sium/examples, unrelated). npx vitest run src/uix/morfo — 7/7 tests pass. npm run smoke — 65/65 routes pass. npm run morfo:check — 66/66 morfos validate against real DOM. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
const attrs = createAttrs(dropdownMenuMorfo);
soma: audit fixes — 84 issues across 25 components, Table complete Table component: - Complete state manager: sorting, filtering, pagination, selection, column pinning (sticky), column sizing, expandable rows (sub-rows + detail panels), column visibility - Provider renders <table> with translated aria-label - Sorting opt-in per column, consumer places sort buttons - filteredRowCount/totalRowCount for correct pagination count - Sub-row IDs hierarchical (parentId.subIndex), no collisions - Production-grade test page (Swiss Industrial design) - Full README with all features documented Critical fixes (10): - Toast: memory leaks (timer + hotkey listener cleanup via $effect) - Toast: restartTimer() method for promise-based toasts - ScrollArea: type='always' now works (check order fix) - ScrollArea: thumb click no longer triggers track jump - Tooltip: no crash without <Tooltip.Group> (ctx.getOr) - Combobox: click-outside-to-close fixed (isValidEvent) - Popover: stray 'n' character removed from popover.svelte - TreeView: ARIA ownership fixed (role=treeitem on Branch, not Control) - Splitter: documented required array spread for reactivity High fixes (14): - Checkbox: group disabled/name propagation + checked sync via $effect - Select: aria-labelledby on content, aria-disabled on items - Stepper: aria-controls + aria-labelledby cross-linking - TagsInput: highlightPrev returns to input, role on Control/Item - Editable: Preview role=button + aria-label - Pagination: translated aria-label on items - RadioGroup: removed unused Soma import Medium fixes (60): - registerContract() added to all 25 components - Dead config=getSoma() removed from 7 providers - Dead imports removed (Tooltip, Popover, Slider, Combobox) - Dialog: aria-modal conditional on modal prop - Slider: pointer capture release + onpointercancel - Popover: hover timeout cleanup, aria-modal support - Tabs: inactive content hidden + aria-hidden + tabindex=-1 - ToggleGroup: aria-orientation + roving tabindex fallback - Toolbar: data-disabled on Button - Stepper: Content tabindex - TreeView: RTL keyboard support (expand/collapse key swap) - NumberField: Enter key commit, clampOnBlur, allowMouseWheel, scrubber a11y - Toast: data-state on root, aria-live on viewport - ScrollArea: scrollbar aria-label + tabindex - Collapsible: part root (not provider), aria-controls, role=region - Tooltip: removed dead provider part from attrs Architecture: - COMPONENT_GUIDE.md: 14 audit-derived rules (A1-A14) - Checklist expanded from 15 to 23 steps - 8 new HTML primitive types (Table, THead, TBody, TFoot, TR, TH, TD, Caption) 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
// ── Typeahead helper ─────────────────────────────────────────────────────────
class Typeahead {
constructor(
private readonly timers: ActiveTimers,
private readonly key: () => string
) {}
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
private search = '';
private timer: TimerHandle | null = null;
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
handle(key: string, items: HTMLElement[]): HTMLElement | null {
if (key.length !== 1) return null;
this.search += key.toLowerCase();
this.cancelTimer();
this.timer = this.timers.schedule(
this.key(),
500,
() => {
this.search = '';
this.timer = null;
},
{ replace: true, meta: { component: 'dropdown-menu', action: 'typeahead-reset' } }
);
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
const match = items.find((el) => {
const text = el.getAttribute('data-text-value') || el.textContent || '';
return text.toLowerCase().startsWith(this.search);
});
return match ?? null;
}
reset() {
this.search = '';
this.cancelTimer();
}
private cancelTimer() {
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
if (this.timer) {
this.timer.cancel();
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.timer = null;
}
}
destroy() {
this.reset();
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
}
}
// ── Root ─────────────────────────────────────────────────────────────────────
interface MenuOpts
extends
ProviderOpts,
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
StateProps<{ open: boolean }>,
ActiveProps<{
modal: boolean;
dir: Direction;
accessibleWhenDisabled: boolean;
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
onOpenChangeComplete: OnChangeFn<boolean>;
}> {}
export class MenuProvider {
readonly opts: MenuOpts;
readonly runtimePart: SomaRuntimePart;
readonly soma: Soma;
readonly runtime: SomaRuntime;
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
static readonly ctx = context<MenuProvider>('DropdownMenu');
static get(): MenuProvider | undefined {
return this.ctx.getOr(undefined) as MenuProvider | undefined;
}
static require(): MenuProvider {
return this.ctx.get();
}
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
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(opts: MenuOpts) {
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
return new MenuProvider(opts);
}
readonly floatingProvider: FloatingProvider;
readonly contentPresence: Presence;
readonly typeahead: Typeahead;
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
contentId = state('');
triggerId = state('');
private contentRef = state<HTMLElement | null>(null);
private constructor(opts: MenuOpts) {
this.opts = opts;
this.soma = Soma.require();
this.typeahead = new Typeahead(
this.soma.uix.timers,
() => `soma:dropdown-menu:${this.opts.id.current}:typeahead`
);
this.runtime = this.soma.runtime(dropdownMenuMorfo, {});
this.runtimePart = this.runtime.part('provider', {
id: opts.id,
ref: opts.ref,
owner: this,
context: MenuProvider.ctx
});
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
this.floatingProvider = FloatingProvider.create();
this.contentPresence = new Presence({
open: opts.open,
ref: this.contentRef,
onComplete: (open) => opts.onOpenChangeComplete.current(open)
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
});
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 typeahead timer on unmount
$effect(() => {
return () => this.typeahead.destroy();
});
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
}
handleOpen() {
this.opts.open.current = true;
}
handleClose() {
this.typeahead.reset();
this.opts.open.current = false;
}
setContentRef(el: HTMLElement | null) {
this.contentRef.current = el;
}
/**
* Focusable items in content, scoped to exclude nested submenus.
* When `accessibleWhenDisabled` is true (APG-compliant default), disabled
* items are included in the navigation order and can receive focus — they
* just cannot be activated.
*/
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
getItems(container: HTMLElement | null): HTMLElement[] {
if (!container) return [];
const skip = this.opts.accessibleWhenDisabled.current ? '' : ':not([data-disabled])';
const selector = `[${attrs.item}]${skip}, [${attrs['checkbox-item']}]${skip}, [${attrs['radio-item']}]${skip}, [${attrs['sub-trigger']}]${skip}`;
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
return Array.from(container.querySelectorAll<HTMLElement>(selector)).filter(
(el) => el.closest(`[${attrs.content}], [${attrs['sub-content']}]`) === container
);
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
}
}
// ── Trigger ──────────────────────────────────────────────────────────────────
interface MenuTriggerOpts extends WithRefOpts {}
export class MenuTriggerProvider {
readonly opts: MenuTriggerOpts;
readonly runtimePart: 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
static create(opts: MenuTriggerOpts) {
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
return new MenuTriggerProvider(opts);
}
readonly provider: MenuProvider;
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
private constructor(opts: MenuTriggerOpts) {
this.opts = opts;
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.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('trigger', {
id: opts.id,
ref: opts.ref,
owner: this
});
this.provider.triggerId.current = opts.id.current;
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
FloatingAnchor.create({
id: opts.id,
ref: readableActive(() => opts.ref.current)
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
});
}
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
if (this.provider.opts.open.current) this.provider.handleClose();
else this.provider.handleOpen();
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
};
readonly onkeydown = (e: SomaKeyboardEvent<HTMLButtonElement>) => {
if (e.key === KEYS.ARROW_DOWN || e.key === KEYS.ENTER || e.key === KEYS.SPACE) {
e.preventDefault();
this.provider.handleOpen();
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
}
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
type: 'button' as const,
'aria-haspopup': 'menu' as const,
'aria-expanded': this.provider.opts.open.current,
'aria-controls': this.provider.contentId.current || undefined,
'data-state': getDataOpenClosed(this.provider.opts.open.current),
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
onclick: this.onclick,
onkeydown: this.onkeydown
} as const)
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
);
}
// ── Content ──────────────────────────────────────────────────────────────────
interface MenuContentOpts
extends
WithRefOpts,
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
ActiveProps<{
side: Side;
sideOffset: number;
align: Align;
alignOffset: number;
arrowPadding: number;
avoidCollisions: boolean;
collisionBoundary: Arrayable<Boundary>;
collisionPadding: number | Partial<Record<Side, number>>;
sticky: 'partial' | 'always';
hideWhenDetached: boolean;
updatePositionStrategy: 'optimized' | 'always';
strategy: 'fixed' | 'absolute';
loop: boolean;
trapFocus: boolean;
preventScroll: boolean;
onOpenAutoFocus: (e: Event) => void;
onCloseAutoFocus: (e: Event) => void;
onEscapeKeydown: (e: KeyboardEvent) => void;
escapeKeydownBehavior: DismissalBehavior;
onInteractOutside: (e: PointerEvent) => void;
interactOutsideBehavior: DismissalBehavior | undefined;
onFocusOutside: (e: FocusEvent) => void;
dir: Direction;
style: StyleProperties | null | undefined | string;
}> {}
export class MenuContentProvider {
readonly opts: MenuContentOpts;
readonly runtimePart: 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
static create(opts: MenuContentOpts) {
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
return new MenuContentProvider(opts);
}
readonly provider: MenuProvider;
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
readonly floating: FloatingContent;
readonly focusScope: ReturnType<typeof FocusScope.use>;
readonly dismissal: Dismissal;
readonly scrollLock: ScrollLock;
readonly textSelection: TextSelection;
private constructor(opts: MenuContentOpts) {
this.opts = opts;
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.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('content', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.provider.setContentRef(el);
}
});
this.provider.contentId.current = opts.id.current;
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
// Floating
this.floating = FloatingContent.create({
id: opts.id,
wrapperId: readableActive(() => `${opts.id.current}-wrapper`),
side: opts.side,
sideOffset: opts.sideOffset,
align: opts.align,
alignOffset: opts.alignOffset,
arrowPadding: opts.arrowPadding,
avoidCollisions: opts.avoidCollisions,
collisionBoundary: opts.collisionBoundary,
collisionPadding: opts.collisionPadding,
sticky: opts.sticky,
hideWhenDetached: opts.hideWhenDetached,
updatePositionStrategy: opts.updatePositionStrategy,
strategy: opts.strategy,
onPlaced: readableActive(() => () => {}),
dir: opts.dir,
style: opts.style,
enabled: readableActive(() => this.provider.opts.open.current),
customAnchor: readableActive(() => null)
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
});
// Focus
this.focusScope = FocusScope.use({
onOpenAutoFocus: opts.onOpenAutoFocus,
onCloseAutoFocus: opts.onCloseAutoFocus,
trap: opts.trapFocus,
loop: opts.loop,
ref: opts.ref,
enabled: readableActive(() => this.provider.contentPresence.isPresent)
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
});
// Dismissal — menus always close on outside click (unlike dialogs where modal=true ignores it)
const resolvedInteractBehavior = readableActive(
() => opts.interactOutsideBehavior.current ?? 'close'
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
);
this.dismissal = Dismissal.use({
ref: readableActive(() => opts.ref.current),
enabled: readableActive(() => this.provider.opts.open.current),
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
onEscapeKeydown: readableActive(() => (e: KeyboardEvent) => {
opts.onEscapeKeydown.current(e);
if (!e.defaultPrevented) this.provider.handleClose();
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
}),
escapeKeydownBehavior: opts.escapeKeydownBehavior,
onInteractOutside: readableActive(() => (e: PointerEvent) => {
opts.onInteractOutside.current(e);
if (!e.defaultPrevented) this.provider.handleClose();
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
}),
interactOutsideBehavior: resolvedInteractBehavior,
onFocusOutside: opts.onFocusOutside,
isValidEvent: readableActive(() => () => false)
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
});
// Scroll lock
this.scrollLock = new ScrollLock();
$effect(() => {
this.scrollLock.locked.current =
this.provider.opts.open.current && opts.preventScroll.current;
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
});
// Text selection
this.textSelection = TextSelection.use({
ref: readableActive(() => opts.ref.current),
dom: this.provider.soma.dom,
enabled: readableActive(() => this.provider.opts.open.current),
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
onPointerDown: readableActive(() => () => {}),
onPointerUp: readableActive(() => () => {})
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
});
}
readonly isPresent = $derived.by(() => this.provider.contentPresence.isPresent);
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
readonly wrapperProps = $derived.by(() => ({
...this.floating.wrapperProps,
style: {
...(typeof this.floating.wrapperProps.style === 'object'
? this.floating.wrapperProps.style
: {}),
'pointer-events': 'auto'
}
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
}));
readonly onkeydown = (e: KeyboardEvent) => {
const container = this.opts.ref.current;
if (!container) return;
const items = this.provider.getItems(container);
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
const active = document.activeElement as HTMLElement;
const currentIndex = items.indexOf(active);
const dir = this.provider.opts.dir.current;
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
const { nextKey, prevKey } = getDirectionalKeys(dir, 'vertical');
let targetIndex = -1;
if (e.key === nextKey) {
e.preventDefault();
targetIndex = this.opts.loop.current
? (currentIndex + 1) % items.length
: Math.min(currentIndex + 1, items.length - 1);
} else if (e.key === prevKey) {
e.preventDefault();
targetIndex = this.opts.loop.current
? (currentIndex - 1 + items.length) % items.length
: Math.max(currentIndex - 1, 0);
} else if (e.key === KEYS.HOME) {
e.preventDefault();
targetIndex = 0;
} else if (e.key === KEYS.END) {
e.preventDefault();
targetIndex = items.length - 1;
} else {
// Typeahead
const match = this.provider.typeahead.handle(e.key, items);
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
if (match) match.focus();
return;
}
if (targetIndex >= 0 && items[targetIndex]) {
items[targetIndex].focus();
}
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'menu' 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
'aria-labelledby': this.provider.triggerId.current || undefined,
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
'aria-orientation': 'vertical' as const,
'data-state': getDataOpenClosed(this.provider.opts.open.current),
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
...this.floating.props,
...this.provider.contentPresence.transitionAttrs,
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
...this.focusScope.props,
...this.dismissal.props,
onkeydown: this.onkeydown
} as const)
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
);
}
// ── Arrow ────────────────────────────────────────────────────────────────────
interface MenuArrowOpts extends WithRefOpts {}
export class MenuArrowProvider {
readonly opts: MenuArrowOpts;
readonly runtimePart: 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
static create(opts: MenuArrowOpts) {
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
return new MenuArrowProvider(opts);
}
readonly floatingArrow: FloatingArrow;
private constructor(opts: MenuArrowOpts) {
this.opts = opts;
const provider = MenuProvider.require();
this.runtimePart = provider.runtime.part('arrow', {
id: opts.id,
ref: opts.ref,
owner: this
});
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
this.floatingArrow = FloatingArrow.create(opts);
}
readonly props = $derived.by(() =>
this.runtimePart.assert({ ...this.runtimePart.props, ...this.floatingArrow.props } as const)
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
);
}
// ── Item ─────────────────────────────────────────────────────────────────────
interface MenuItemOpts
extends
WithRefOpts,
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
ActiveProps<{
disabled: boolean;
textValue: string;
closeOnSelect: boolean;
onSelect: () => void;
}> {}
export class MenuItemProvider {
readonly opts: MenuItemOpts;
readonly runtimePart: 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
static create(opts: MenuItemOpts) {
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
return new MenuItemProvider(opts);
}
readonly provider: MenuProvider;
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
private constructor(opts: MenuItemOpts) {
this.opts = opts;
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.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('item', {
id: opts.id,
ref: opts.ref,
owner: this
});
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
}
readonly onclick = (_e: SomaMouseEvent<HTMLElement>) => {
if (this.opts.disabled.current) return;
this.opts.onSelect.current();
if (this.opts.closeOnSelect.current) this.provider.handleClose();
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
};
readonly onkeydown = (e: SomaKeyboardEvent<HTMLElement>) => {
if (this.opts.disabled.current) return;
if (e.key === KEYS.ENTER || e.key === KEYS.SPACE) {
e.preventDefault();
this.opts.onSelect.current();
if (this.opts.closeOnSelect.current) this.provider.handleClose();
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
}
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'menuitem' as const,
tabindex:
this.opts.disabled.current && !this.provider.opts.accessibleWhenDisabled.current
? undefined
: -1,
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
'aria-disabled': this.opts.disabled.current || undefined,
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
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled.current),
'data-text-value': this.opts.textValue.current || undefined,
onclick: this.onclick,
onkeydown: this.onkeydown
} as const)
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
);
}
// ── Group ────────────────────────────────────────────────────────────────────
interface MenuGroupOpts extends WithRefOpts {}
export class MenuGroupProvider {
readonly opts: MenuGroupOpts;
readonly runtimePart: SomaRuntimePart;
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
static readonly ctx = context<MenuGroupProvider>('DropdownMenuGroup');
static get(): MenuGroupProvider | undefined {
return this.ctx.getOr(undefined) as MenuGroupProvider | undefined;
}
static require(): MenuGroupProvider {
return this.ctx.get();
}
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
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(opts: MenuGroupOpts) {
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
return new MenuGroupProvider(opts);
}
headingId = state('');
private constructor(opts: MenuGroupOpts) {
this.opts = opts;
const provider = MenuProvider.require();
this.runtimePart = provider.runtime.part('group', {
id: opts.id,
ref: opts.ref,
owner: this,
context: MenuGroupProvider.ctx
});
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
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'group' as const,
'aria-labelledby': this.headingId.current || undefined
} as const)
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
);
}
// ── GroupHeading ─────────────────────────────────────────────────────────────
interface MenuGroupHeadingOpts extends WithRefOpts {}
export class MenuGroupHeadingProvider {
readonly opts: MenuGroupHeadingOpts;
readonly runtimePart: 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
static create(opts: MenuGroupHeadingOpts) {
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
return new MenuGroupHeadingProvider(opts);
}
private constructor(opts: MenuGroupHeadingOpts) {
this.opts = opts;
const provider = MenuProvider.require();
this.runtimePart = provider.runtime.part('group-heading', {
id: opts.id,
ref: opts.ref,
owner: this
});
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
// Register with parent group if available
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 group = MenuGroupProvider.get() as MenuGroupProvider | undefined;
if (group) {
group.headingId.current = opts.id.current;
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
}
readonly props = $derived.by(() =>
this.runtimePart.assert({ ...this.runtimePart.props } as const)
);
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
}
// ── Separator ────────────────────────────────────────────────────────────────
interface MenuSeparatorOpts extends WithRefOpts {}
export class MenuSeparatorProvider {
readonly opts: MenuSeparatorOpts;
readonly runtimePart: 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
static create(opts: MenuSeparatorOpts) {
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
return new MenuSeparatorProvider(opts);
}
private constructor(opts: MenuSeparatorOpts) {
this.opts = opts;
const provider = MenuProvider.require();
this.runtimePart = provider.runtime.part('separator', {
id: opts.id,
ref: opts.ref,
owner: this
});
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
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'separator' as const,
'aria-orientation': 'horizontal' as const
} as const)
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
);
}
// ── CheckboxGroup (optional parent — Bits UI pattern) ───────────────────────
interface MenuCheckboxGroupOpts extends StateProps<{ value: string[] }> {}
export class MenuCheckboxGroupProvider {
static readonly ctx = context<MenuCheckboxGroupProvider>('DropdownMenuCheckboxGroup');
static get(): MenuCheckboxGroupProvider | undefined {
return this.ctx.getOr(undefined) as MenuCheckboxGroupProvider | undefined;
}
static require(): MenuCheckboxGroupProvider {
return this.ctx.get();
}
static create(opts: MenuCheckboxGroupOpts) {
return MenuCheckboxGroupProvider.ctx.set(new MenuCheckboxGroupProvider(opts));
}
readonly opts: MenuCheckboxGroupOpts;
private constructor(opts: MenuCheckboxGroupOpts) {
this.opts = opts;
}
contains(value: string): boolean {
return this.opts.value.current.includes(value);
}
toggle(value: string): void {
const arr = this.opts.value.current;
this.opts.value.current = arr.includes(value)
? arr.filter((v) => v !== value)
: [...arr, value];
}
}
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
// ── CheckboxItem ─────────────────────────────────────────────────────────────
interface MenuCheckboxItemOpts
extends
WithRefOpts,
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
StateProps<{ checked: boolean }>,
ActiveProps<{
value: string | undefined;
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
disabled: boolean;
textValue: string;
closeOnSelect: boolean;
onSelect: () => void;
}> {}
export class MenuCheckboxItemProvider {
readonly opts: MenuCheckboxItemOpts;
readonly runtimePart: 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
static create(opts: MenuCheckboxItemOpts) {
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
return new MenuCheckboxItemProvider(opts);
}
readonly provider: MenuProvider;
readonly group: MenuCheckboxGroupProvider | undefined;
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
private constructor(opts: MenuCheckboxItemOpts) {
this.opts = opts;
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.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('checkbox-item', {
id: opts.id,
ref: opts.ref,
owner: this
});
this.group = MenuCheckboxGroupProvider.get();
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
}
/** Effective checked state: group membership when inside a CheckboxGroup, own `checked` otherwise. */
readonly effectiveChecked = $derived.by(() => {
if (this.group && this.opts.value.current !== undefined) {
return this.group.contains(this.opts.value.current);
}
return this.opts.checked.current;
});
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
private activate() {
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
if (this.opts.disabled.current) return;
if (this.group && this.opts.value.current !== undefined) {
this.group.toggle(this.opts.value.current);
} else {
const next = !this.opts.checked.current;
this.opts.checked.current = next;
}
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
this.opts.onSelect.current();
if (this.opts.closeOnSelect.current) this.provider.handleClose();
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 onclick = (_e: SomaMouseEvent<HTMLElement>) => {
this.activate();
};
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
readonly onkeydown = (e: SomaKeyboardEvent<HTMLElement>) => {
if (e.key === KEYS.ENTER || e.key === KEYS.SPACE) {
e.preventDefault();
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.activate();
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
}
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'menuitemcheckbox' as const,
'aria-checked': this.effectiveChecked,
tabindex:
this.opts.disabled.current && !this.provider.opts.accessibleWhenDisabled.current
? undefined
: -1,
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
'aria-disabled': this.opts.disabled.current || undefined,
'data-state': this.effectiveChecked ? 'checked' : 'unchecked',
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
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled.current),
'data-text-value': this.opts.textValue.current || undefined,
onclick: this.onclick,
onkeydown: this.onkeydown
} as const)
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
);
}
// ── RadioGroup ───────────────────────────────────────────────────────────────
interface MenuRadioGroupOpts extends WithRefOpts, StateProps<{ value: string }> {}
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
export class MenuRadioGroupProvider {
readonly opts: MenuRadioGroupOpts;
readonly runtimePart: SomaRuntimePart;
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
static readonly ctx = context<MenuRadioGroupProvider>('DropdownMenuRadioGroup');
static get(): MenuRadioGroupProvider | undefined {
return this.ctx.getOr(undefined) as MenuRadioGroupProvider | undefined;
}
static require(): MenuRadioGroupProvider {
return this.ctx.get();
}
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
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(opts: MenuRadioGroupOpts) {
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
return new MenuRadioGroupProvider(opts);
}
private constructor(opts: MenuRadioGroupOpts) {
this.opts = opts;
const provider = MenuProvider.require();
this.runtimePart = provider.runtime.part('radio-group', {
id: opts.id,
ref: opts.ref,
owner: this,
context: MenuRadioGroupProvider.ctx
});
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
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
role: 'group' as const
} as const)
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
);
}
// ── RadioItem ────────────────────────────────────────────────────────────────
interface MenuRadioItemOpts
extends
WithRefOpts,
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
ActiveProps<{
value: string;
disabled: boolean;
textValue: string;
closeOnSelect: boolean;
onSelect: () => void;
}> {}
export class MenuRadioItemProvider {
readonly opts: MenuRadioItemOpts;
readonly runtimePart: 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
static create(opts: MenuRadioItemOpts) {
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
return new MenuRadioItemProvider(opts);
}
readonly provider: MenuProvider;
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
readonly radioGroup: MenuRadioGroupProvider;
private constructor(opts: MenuRadioItemOpts) {
this.opts = opts;
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.provider = MenuProvider.require();
this.runtimePart = this.provider.runtime.part('radio-item', {
id: opts.id,
ref: opts.ref,
owner: this
});
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.radioGroup = MenuRadioGroupProvider.require();
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
}
readonly isChecked = $derived.by(
() => this.radioGroup.opts.value.current === this.opts.value.current
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
);
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
private activate() {
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
if (this.opts.disabled.current) return;
this.radioGroup.opts.value.current = this.opts.value.current;
this.opts.onSelect.current();
if (this.opts.closeOnSelect.current) this.provider.handleClose();
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 onclick = (_e: SomaMouseEvent<HTMLElement>) => {
this.activate();
};
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
readonly onkeydown = (e: SomaKeyboardEvent<HTMLElement>) => {
if (e.key === KEYS.ENTER || e.key === KEYS.SPACE) {
e.preventDefault();
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.activate();
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
}
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'menuitemradio' as const,
'aria-checked': this.isChecked,
tabindex:
this.opts.disabled.current && !this.provider.opts.accessibleWhenDisabled.current
? undefined
: -1,
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
'aria-disabled': this.opts.disabled.current || undefined,
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
'data-state': this.isChecked ? 'checked' : 'unchecked',
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled.current),
'data-text-value': this.opts.textValue.current || undefined,
onclick: this.onclick,
onkeydown: this.onkeydown
} as const)
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
);
}
// ── Sub ──────────────────────────────────────────────────────────────────────
interface MenuSubOpts extends StateProps<{ open: boolean }> {}
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
export class MenuSubProvider {
static readonly ctx = context<MenuSubProvider>('DropdownMenuSub');
static get(): MenuSubProvider | undefined {
return this.ctx.getOr(undefined) as MenuSubProvider | undefined;
}
static require(): MenuSubProvider {
return this.ctx.get();
}
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
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(opts: MenuSubOpts) {
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
return MenuSubProvider.ctx.set(new MenuSubProvider(opts));
}
readonly opts: MenuSubOpts;
readonly provider: MenuProvider;
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
readonly contentPresence: Presence;
readonly floatingProvider: FloatingProvider;
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 safePolygon: SafePolygon;
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
contentId = state('');
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
subTriggerId = state('');
subTriggerRef = state<HTMLElement | null>(null);
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
private contentRef = state<HTMLElement | null>(null);
private constructor(opts: MenuSubOpts) {
this.opts = opts;
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.provider = MenuProvider.require();
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
this.floatingProvider = FloatingProvider.create();
this.contentPresence = new Presence({
open: opts.open,
ref: this.contentRef
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
});
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
// SafePolygon handles the pointer gap between SubTrigger and SubContent
this.safePolygon = new SafePolygon({
enabled: () => opts.open.current,
triggerNode: () => this.subTriggerRef.current,
contentNode: () => this.contentRef.current,
onPointerExit: () => this.handleClose(),
buffer: 2,
transitIntentTimeout: 300
});
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
}
handleOpen() {
this.opts.open.current = true;
}
handleClose() {
this.opts.open.current = false;
}
setContentRef(el: HTMLElement | null) {
this.contentRef.current = el;
}
}
// ── SubTrigger ───────────────────────────────────────────────────────────────
interface MenuSubTriggerOpts
extends WithRefOpts, ActiveProps<{ disabled: boolean; textValue: string }> {}
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
export class MenuSubTriggerProvider {
readonly opts: MenuSubTriggerOpts;
readonly runtimePart: 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
static create(opts: MenuSubTriggerOpts) {
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
return new MenuSubTriggerProvider(opts);
}
readonly sub: MenuSubProvider;
private openTimer: TimerHandle | null = null;
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
private constructor(opts: MenuSubTriggerOpts) {
soma/morfo: typed createAttrs + 6 audit batches + form hang fix + A36 ## morfo: typed createAttrs - `types.ts`: all array fields are now `readonly` so morfos can be authored with `as const satisfies Morfo` without casts. - `createAttrs` is a generic `<const M extends MorfoShape>` that infers the emitted attr map from the morfo's literal shape. Typos like `attrs.trigerr` are now compile errors; autocomplete lists every valid part. - All 66 morfos migrated: `export const xMorfo = { ... } as const satisfies Morfo`. - Two latent bugs the new typing caught: `dateRangeFieldAttrs.root` and `timeRangeFieldAttrs.root` — legacy from the root→provider refactor, fixed to `.provider`. - Docs (morfo/README, COMPONENT_GUIDE) mandate `as const satisfies Morfo`; the older `: Morfo` annotation widens literals and loses autocomplete. ## Audit batches 1–7 (soma-audit-2026-04-20) Batch 1 — Keyboard a11y (A14/A12): - Tabs: `isFallbackTabStop(el)` using `untrack` → first trigger gets `tabindex=0` when no tab matches (WCAG 2.1.1 was failing). - RatingGroup: `dir` prop + `getDirectionalKeys(dir, 'horizontal')` for RTL. - Accordion P1-1/P1-6 dismissed: roving/labelledby already correct per APG. Batch 2 — A33 reactive collections: Select `labelRegistry` and NavigationMenu `triggerRefs` migrated to `SvelteMap`. Batch 3 — A31 O(N²) fix: RadioGroup lifts `hasSelection` + `isFallbackTabStop` to the provider with `untrack`-wrapped DOM walk. Per-item derivations drop from O(N²) to O(1) per trigger. Batch 4 — Morfo aria sync: toast / time-field / date-field / tabs / tag-group / navigation-menu declare every aria the provider emits (14 entries across 6 files). Batch 5 — Accessible naming props: Tabs.List, ToggleGroup, TreeView, NavigationMenu expose `aria-label?` / `aria-labelledby?` with explicit "required unless labelledby is set" JSDoc. Batch 6 — A30 cleanup: Checkbox `setLabelId` and 5 trigger-ref providers (select/tooltip/link-preview/dropdown-menu/context-menu) migrated from `$effect(() => parent.ref = opts.ref)` to the `Provider` base's `onRefChange` callback (fires via attachRef inside `untrack`). Batch 7 — A11 wrapper thinning: stepper/tree-view wrappers removed `ctx.get()`, providers expose proxy derivations; time/date-range-field inputs use `untrack(() => …)` for one-shot id registration; menubar content's 40-line keyboard nav moved to `MenubarMenuProvider.onContentKeydown`; color-picker area + channel-slider pointer state machines moved to the providers with `onpointerdown/move/up` emitted via `props`. form-auto-fields deferred with justification (reflective schema renderer, not a state-holding wrapper). ## Form hang fix (A36) `runValidate` entered the `isPromiseLike` branch even for sync schemas because sium's Standard-Schema adapter declares `validate: async`. The fallback `return { errors, issues }` read both reactive vars inside the validation `$effect` while the `.then(...)` microtask wrote them → microtask-mediated loop, silent to Svelte's sync effect-depth guard. Symptom: kitchen-sink hung the tab on mount with onChange / onBlur. Fix: `return untrack(() => ({ errors, issues }))`. Regression locked by two new 5s-timeout tests in `form-auto-fields.svelte.test.ts`. Pattern codified as A36 in COMPONENT_GUIDE; CLAUDE.md count updated to A1–A36 / 39 items. ## Verification - `npm run check`: 0 errors in soma/morfo scope (sema demo pre-existing errors untouched). - `npx vitest run src/uix/soma src/uix/morfo`: all tests green (94 + 7 = 101 tests, inc. 2 new form regression tests). - `npm run smoke`: 65/65 routes. - `npx tsx scripts/morfo-check.ts`: 66/66 morfos. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
// A30: register subTriggerRef via `onRefChange` (attachRef fires at
// mount/unmount inside `untrack`), avoiding the `$effect` feedback.
this.opts = opts;
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.sub = MenuSubProvider.require();
this.runtimePart = this.sub.provider.runtime.part('sub-trigger', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.sub.subTriggerRef.current = el;
}
});
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.sub.subTriggerId.current = opts.id.current;
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
FloatingAnchor.create({
id: opts.id,
ref: readableActive(() => opts.ref.current)
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
});
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 open timeout on unmount
$effect(() => {
return () => this.clearOpenTimeout();
});
}
private clearOpenTimeout() {
if (this.openTimer) {
this.openTimer.cancel();
this.openTimer = null;
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
}
readonly onpointerenter = () => {
if (this.opts.disabled.current) return;
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.clearOpenTimeout();
// SafePolygon handles the close coordination — just open on enter
this.openTimer = this.sub.provider.soma.uix.timers.schedule(
this.openTimerKey,
100,
() => {
this.openTimer = null;
this.sub.handleOpen();
},
{ replace: true, meta: { component: 'dropdown-menu', action: 'submenu-open' } }
);
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
};
readonly onpointerleave = () => {
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.clearOpenTimeout();
// Don't schedule close here — SafePolygon tracks the pointer
// and calls onPointerExit when it leaves the safe zone
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
};
/**
* Click-to-open (pointer + touch + pen). Required because:
* - touch taps don't reliably fire the hover-based `onpointerenter` path
* - a user can reach the trigger with the mouse without triggering enter
* (e.g. focus via keyboard, then click) and expect a click to open
* - matches Radix/Bits/Ariakit behavior
*/
readonly onclick = (e: SomaMouseEvent<HTMLElement>) => {
if (this.opts.disabled.current) return;
this.clearOpenTimeout();
// Don't let the item-level "select" handler on the surrounding content
// interpret this click as an activation that closes the whole menu.
e.preventDefault();
e.stopPropagation();
if (!this.sub.opts.open.current) this.sub.handleOpen();
};
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
readonly onkeydown = (e: SomaKeyboardEvent<HTMLElement>) => {
if (this.opts.disabled.current) return;
const dir = this.sub.provider.opts.dir.current;
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 { nextKey } = getDirectionalKeys(dir, 'horizontal');
if (e.key === nextKey || e.key === KEYS.ENTER || e.key === KEYS.SPACE) {
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
e.preventDefault();
this.sub.handleOpen();
}
};
private get openTimerKey() {
return `soma:dropdown-menu:${this.opts.id.current}:submenu-open`;
}
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
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'menuitem' as const,
'aria-haspopup': 'menu' as const,
'aria-expanded': this.sub.opts.open.current,
'aria-controls': this.sub.contentId.current || undefined,
tabindex:
this.opts.disabled.current && !this.sub.provider.opts.accessibleWhenDisabled.current
? undefined
: -1,
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
'aria-disabled': this.opts.disabled.current || undefined,
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
'data-state': getDataOpenClosed(this.sub.opts.open.current),
'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled.current),
'data-text-value': this.opts.textValue.current || undefined,
onclick: this.onclick,
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
onpointerenter: this.onpointerenter,
onpointerleave: this.onpointerleave,
onkeydown: this.onkeydown
} as const)
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
);
}
// ── SubContent ───────────────────────────────────────────────────────────────
interface MenuSubContentOpts
extends
WithRefOpts,
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
ActiveProps<{
side: Side;
sideOffset: number;
align: Align;
alignOffset: number;
avoidCollisions: boolean;
collisionBoundary: Arrayable<Boundary>;
collisionPadding: number | Partial<Record<Side, number>>;
loop: boolean;
dir: Direction;
style: StyleProperties | null | undefined | string;
}> {}
export class MenuSubContentProvider {
readonly opts: MenuSubContentOpts;
readonly runtimePart: 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
static create(opts: MenuSubContentOpts) {
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
return new MenuSubContentProvider(opts);
}
readonly sub: MenuSubProvider;
readonly floating: FloatingContent;
private constructor(opts: MenuSubContentOpts) {
this.opts = opts;
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.sub = MenuSubProvider.require();
this.runtimePart = this.sub.provider.runtime.part('sub-content', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.sub.setContentRef(el);
}
});
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
this.sub.contentId.current = opts.id.current;
this.floating = FloatingContent.create({
id: opts.id,
wrapperId: readableActive(() => `${opts.id.current}-wrapper`),
side: opts.side,
sideOffset: opts.sideOffset,
align: opts.align,
alignOffset: opts.alignOffset,
arrowPadding: readableActive(() => 0),
avoidCollisions: opts.avoidCollisions,
collisionBoundary: opts.collisionBoundary,
collisionPadding: opts.collisionPadding,
sticky: readableActive(() => 'partial' as const),
hideWhenDetached: readableActive(() => true),
updatePositionStrategy: readableActive(() => 'optimized' as const),
strategy: readableActive(() => 'fixed' as const),
onPlaced: readableActive(() => () => {}),
dir: opts.dir,
style: opts.style,
enabled: readableActive(() => this.sub.opts.open.current),
customAnchor: readableActive(() => null)
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
});
}
readonly isPresent = $derived.by(() => this.sub.contentPresence.isPresent);
readonly wrapperProps = $derived.by(() => ({
...this.floating.wrapperProps,
style: {
...(typeof this.floating.wrapperProps.style === 'object'
? this.floating.wrapperProps.style
: {}),
'pointer-events': 'auto'
}
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
}));
readonly onkeydown = (e: KeyboardEvent) => {
const dir = this.sub.provider.opts.dir.current;
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 { prevKey } = getDirectionalKeys(dir, 'horizontal');
const { nextKey: downKey, prevKey: upKey } = getDirectionalKeys(dir, 'vertical');
if (e.key === prevKey || e.key === KEYS.ESCAPE) {
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
e.preventDefault();
this.sub.handleClose();
}
// Arrow nav within sub
const container = this.opts.ref.current;
if (!container) return;
const items = this.sub.provider.getItems(container);
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
const active = document.activeElement as HTMLElement;
const currentIndex = items.indexOf(active);
let targetIndex = -1;
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
if (e.key === downKey) {
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
e.preventDefault();
targetIndex = this.opts.loop.current
? (currentIndex + 1) % items.length
: Math.min(currentIndex + 1, items.length - 1);
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
} else if (e.key === upKey) {
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
e.preventDefault();
targetIndex = this.opts.loop.current
? (currentIndex - 1 + items.length) % items.length
: Math.max(currentIndex - 1, 0);
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
} else if (e.key === KEYS.HOME) {
e.preventDefault();
targetIndex = 0;
} else if (e.key === KEYS.END) {
e.preventDefault();
targetIndex = items.length - 1;
} else {
// Typeahead fallback
const match = this.sub.provider.typeahead.handle(e.key, items);
if (match) match.focus();
return;
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
}
if (targetIndex >= 0 && items[targetIndex]) {
items[targetIndex].focus();
}
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
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
role: 'menu' 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
'aria-labelledby': this.sub.subTriggerId.current || undefined,
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
'aria-orientation': 'vertical' as const,
'data-state': getDataOpenClosed(this.sub.opts.open.current),
...this.floating.props,
...this.sub.contentPresence.transitionAttrs,
onkeydown: this.onkeydown
} as const)
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
);
}

Powered by TurnKey Linux.