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/carousel/carousel-provider.svelte.ts

709 lines
23 KiB

import { context, type WithRefOpts } from '../../provider';
import { createAttrs } from '$uix/morfo';
import { boolToEmptyStrOrUndef } from '$adom';
import { readableActive, type Active, type ActiveProps, type StateProps } from '$libs/reactive';
import type { OnChangeFn, Orientation, SomaKeyboardEvent, SomaMouseEvent } from '../../types';
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
import { KEYS, getDirectionalKeys } from '../../keyboard';
import { Soma } from '../../core/soma.svelte';
import { Gesture } from '../../layers/gesture';
import { CAROUSEL_LANGS } from './langs';
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 { carouselMorfo } from '../../../morfo/components/carousel';
import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte';
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (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(carouselMorfo);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
// ── Root provider ──────────────────────────────────────────────────────────
interface CarouselOpts
extends
WithRefOpts,
StateProps<{ value: number }>,
ActiveProps<{
orientation: Orientation;
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
slidesPerView: number;
slidesToScroll: number;
align: 'start' | 'center' | 'end';
gap: string;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
loop: boolean;
dragEnabled: boolean;
dragThreshold: number;
autoplay: boolean;
autoplayDelay: number;
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
playOnInit: boolean;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
pauseOnHover: boolean;
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
stopOnInteraction: boolean;
stopOnFocusIn: boolean;
stopOnMouseEnter: boolean;
stopOnLastSnap: boolean;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
disabled: boolean;
ariaLabel: string | undefined;
onValueChange: OnChangeFn<number> | undefined;
}> {}
export class CarouselProvider {
readonly opts: CarouselOpts;
readonly runtimePart: SomaRuntimePart;
readonly soma: Soma;
readonly runtime: SomaRuntime;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static readonly ctx = context<CarouselProvider>('Carousel');
static get(): CarouselProvider | undefined {
return this.ctx.getOr(undefined) as CarouselProvider | undefined;
}
static require(): CarouselProvider {
return this.ctx.get();
}
static create(opts: CarouselOpts) {
return new CarouselProvider(opts);
}
// Refs — set by the respective child providers.
viewportRef = $state<HTMLElement | null>(null);
itemGroupRef = $state<HTMLElement | null>(null);
// Drag state (px offset during active drag).
dragOffset = $state(0);
// Autoplay pause state.
hovering = $state(false);
focused = $state(false);
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/** User explicitly stopped (via play/pause API or stopOnInteraction). */
userStopped = $state(false);
/** Latched once interaction occurred when stopOnInteraction is true. */
interactionStopped = $state(false);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
readonly gesture: ReturnType<typeof Gesture.base>;
private constructor(opts: CarouselOpts) {
this.opts = opts;
this.soma = Soma.require();
this.runtime = this.soma.runtime(carouselMorfo, {});
this.runtimePart = this.runtime.part('provider', {
id: opts.id,
ref: opts.ref,
owner: this,
context: CarouselProvider.ctx
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// Apply `playOnInit=false` — start in user-stopped state so the
// timer effect doesn't tick until the consumer calls `play()`.
if (opts.autoplay.current && opts.playOnInit.current === false) {
this.userStopped = true;
}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.gesture = Gesture.base({
dom: this.soma.dom,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
ref: readableActive(() => this.itemGroupRef),
enabled: readableActive(() => !this.isDisabled && this.opts.dragEnabled.current),
axis: readableActive(() => (this.opts.orientation.current === 'horizontal' ? 'x' : 'y')),
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
onCancel: () => {
this.dragOffset = 0;
}
});
// ── Autoplay ─────────────────────────────────────────────────────────
$effect(() => {
if (!opts.autoplay.current) return;
if (this.isDisabled) return;
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
if (!this.isPlaying) return;
const handle = this.soma.uix.timers.interval(
this.autoplayTimerKey,
opts.autoplayDelay.current,
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
() => {
if (this.opts.stopOnLastSnap.current && !this.opts.loop.current) {
if (this.opts.value.current >= this.slideCount - 1) {
this.userStopped = true;
return;
}
}
this.next();
},
{ replace: true, meta: { component: 'carousel', action: 'autoplay' } }
);
return () => handle.cancel();
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
});
}
private get autoplayTimerKey() {
return `soma:carousel:${this.opts.id.current}:autoplay`;
}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
// ── Slide detection (live DOM query) ────────────────────────────────────
getItems(): HTMLElement[] {
const group = this.itemGroupRef;
if (!group) return [];
return Array.from(group.querySelectorAll<HTMLElement>(`[${attrs.item}]`));
}
readonly slideCount = $derived.by(() => this.getItems().length);
// ── Flags ────────────────────────────────────────────────────────────────
readonly isDisabled = $derived.by(() => this.opts.disabled.current);
readonly canGoPrev = $derived.by(() => this.opts.loop.current || this.opts.value.current > 0);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
readonly canGoNext = $derived.by(
() => this.opts.loop.current || this.opts.value.current < this.slideCount - 1
);
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/** Combined autoplay-paused state — true means the timer should not tick. */
readonly isPlaying = $derived.by(() => {
if (!this.opts.autoplay.current) return false;
if (this.isDisabled) return false;
if (this.userStopped) return false;
if (this.interactionStopped) return false;
if (this.opts.pauseOnHover.current && this.hovering) return false;
if (this.opts.stopOnMouseEnter.current && this.hovering) return false;
if (this.opts.stopOnFocusIn.current && this.focused) return false;
return true;
});
/** Public name kept for back-compat; `isPlaying` is the canonical signal. */
readonly paused = $derived.by(() => !this.isPlaying);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
// ── Geometry ─────────────────────────────────────────────────────────────
/** Size (px) of the viewport along the primary axis. */
readonly viewportSize = $derived.by(() => {
const vp = this.viewportRef;
if (!vp) return 0;
return this.opts.orientation.current === 'horizontal' ? vp.clientWidth : vp.clientHeight;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
});
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/** Slide size (px) along the primary axis = viewport / slidesPerView. */
readonly slideSize = $derived.by(() => {
const spv = Math.max(1, this.opts.slidesPerView.current);
return this.viewportSize / spv;
});
/** Align offset (px) applied to the translate so the active slide(s) line up. */
readonly alignOffset = $derived.by(() => {
const align = this.opts.align.current;
const spv = Math.max(1, this.opts.slidesPerView.current);
if (align === 'start' || spv <= 1) return 0;
const free = this.viewportSize - this.slideSize;
if (align === 'center') return free / 2;
if (align === 'end') return free;
return 0;
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
/** Translate value (px) for the item-group. */
readonly translate = $derived.by(() => {
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const base = -this.opts.value.current * this.slideSize + this.alignOffset;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
return base + this.dragOffset;
});
readonly itemGroupTransform = $derived.by(() => {
const v = this.translate;
return this.opts.orientation.current === 'horizontal'
? `translate3d(${v}px, 0, 0)`
: `translate3d(0, ${v}px, 0)`;
});
// ── Navigation ───────────────────────────────────────────────────────────
commit(next: number) {
if (this.isDisabled) return;
const count = this.slideCount;
if (count === 0) return;
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const spv = Math.max(1, this.opts.slidesPerView.current);
const lastSnap = Math.max(0, count - spv);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
let target: number;
if (this.opts.loop.current) {
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const wrap = lastSnap + 1;
target = ((next % wrap) + wrap) % wrap;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
} else {
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
target = Math.max(0, Math.min(lastSnap, next));
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
if (target === this.opts.value.current) return;
this.opts.value.current = target;
this.opts.onValueChange.current?.(target);
}
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/** Mark this navigation as user-driven so `stopOnInteraction` can latch. */
private noteInteraction() {
if (this.opts.stopOnInteraction.current && this.opts.autoplay.current) {
this.interactionStopped = true;
}
}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
next() {
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const step = Math.max(1, this.opts.slidesToScroll.current);
this.commit(this.opts.value.current + step);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
prev() {
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const step = Math.max(1, this.opts.slidesToScroll.current);
this.commit(this.opts.value.current - step);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
goto(index: number) {
this.commit(index);
}
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// ── Imperative API surface ───────────────────────────────────────────────
scrollNext() {
this.noteInteraction();
this.next();
}
scrollPrev() {
this.noteInteraction();
this.prev();
}
scrollTo(index: number) {
this.noteInteraction();
this.commit(index);
}
play() {
this.userStopped = false;
this.interactionStopped = false;
}
pause() {
this.userStopped = true;
}
reset() {
this.userStopped = false;
this.interactionStopped = false;
}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
// ── Keyboard ─────────────────────────────────────────────────────────────
readonly onkeydown = (e: SomaKeyboardEvent<HTMLDivElement>) => {
if (this.isDisabled) return;
const { nextKey, prevKey } = getDirectionalKeys('ltr', this.opts.orientation.current);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
if (e.key === nextKey) {
e.preventDefault();
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
this.scrollNext();
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
} else if (e.key === prevKey) {
e.preventDefault();
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
this.scrollPrev();
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
} else if (e.key === KEYS.HOME) {
e.preventDefault();
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
this.scrollTo(0);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
} else if (e.key === KEYS.END) {
e.preventDefault();
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const spv = Math.max(1, this.opts.slidesPerView.current);
this.scrollTo(Math.max(0, this.slideCount - spv));
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
};
readonly onpointerenter = () => {
this.hovering = true;
};
readonly onpointerleave = () => {
this.hovering = false;
};
readonly onfocusin = () => {
this.focused = true;
};
readonly onfocusout = (e: FocusEvent) => {
const next = e.relatedTarget as Node | null;
if (next && this.opts.ref.current?.contains(next)) return;
this.focused = false;
};
// ── Drag release → commit ────────────────────────────────────────────────
/** Called by the ItemGroup's drag lifecycle when the gesture ends. */
finishDrag() {
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
const size = this.slideSize;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
if (size === 0) {
this.dragOffset = 0;
return;
}
const horizontal = this.opts.orientation.current === 'horizontal';
const offset = horizontal ? this.gesture.offsetX : this.gesture.offsetY;
const velocity = horizontal ? this.gesture.velocityX : this.gesture.velocityY;
const fraction = offset / size;
const threshold = this.opts.dragThreshold.current;
const fastSwipe = Math.abs(velocity) > 0.5;
const shouldAdvance = Math.abs(fraction) > threshold || fastSwipe;
this.dragOffset = 0;
if (!shouldAdvance) return;
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
this.noteInteraction();
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
// Negative offset = dragged left/up = advance to next slide.
if (offset < 0) this.next();
else this.prev();
}
// ── Snippet + root props ─────────────────────────────────────────────────
readonly snippetProps = $derived.by(() => ({
index: this.opts.value.current,
slideCount: this.slideCount,
canGoNext: this.canGoNext,
canGoPrev: this.canGoPrev,
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
isDragging: this.gesture.isDragging,
isPlaying: this.isPlaying,
api: {
scrollNext: () => this.scrollNext(),
scrollPrev: () => this.scrollPrev(),
scrollTo: (i: number) => this.scrollTo(i),
play: () => this.play(),
pause: () => this.pause(),
reset: () => this.reset()
}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}));
readonly resolvedAriaLabel: Active<string | undefined> = readableActive(
() => this.opts.ariaLabel.current || this.soma.langs.ts(CAROUSEL_LANGS.LABEL) || undefined
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
);
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
role: 'region' as const,
'aria-roledescription': 'carousel',
'aria-label': this.resolvedAriaLabel.current,
tabindex: this.isDisabled ? -1 : 0,
'data-orientation': this.opts.orientation.current,
'data-disabled': boolToEmptyStrOrUndef(this.isDisabled),
'data-dragging': boolToEmptyStrOrUndef(this.gesture.isDragging),
'data-autoplay': boolToEmptyStrOrUndef(this.opts.autoplay.current && !this.paused),
onkeydown: this.onkeydown,
onpointerenter: this.onpointerenter,
onpointerleave: this.onpointerleave,
onfocusin: this.onfocusin,
onfocusout: this.onfocusout
} as const)
);
}
// ── Viewport ───────────────────────────────────────────────────────────────
interface CarouselViewportOpts extends WithRefOpts {}
export class CarouselViewportProvider {
readonly opts: CarouselViewportOpts;
readonly runtimePart: SomaRuntimePart;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static create(opts: CarouselViewportOpts) {
return new CarouselViewportProvider(opts);
}
readonly provider: CarouselProvider;
private constructor(opts: CarouselViewportOpts) {
this.opts = opts;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider = CarouselProvider.require();
this.runtimePart = this.provider.runtime.part('viewport', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.provider.viewportRef = el;
}
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
'data-orientation': this.provider.opts.orientation.current,
style: { overflow: 'hidden' }
} as const)
);
}
// ── ItemGroup ──────────────────────────────────────────────────────────────
interface CarouselItemGroupOpts extends WithRefOpts {}
export class CarouselItemGroupProvider {
readonly opts: CarouselItemGroupOpts;
readonly runtimePart: SomaRuntimePart;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static create(opts: CarouselItemGroupOpts) {
return new CarouselItemGroupProvider(opts);
}
readonly provider: CarouselProvider;
private constructor(opts: CarouselItemGroupOpts) {
this.opts = opts;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider = CarouselProvider.require();
this.runtimePart = this.provider.runtime.part('item-group', {
id: opts.id,
ref: opts.ref,
owner: this,
onRefChange: (el) => {
this.provider.itemGroupRef = el;
}
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
// Drag lifecycle — track offset during drag, commit on release.
let wasDragging = false;
$effect(() => {
const isDragging = this.provider.gesture.isDragging;
if (isDragging) {
const horizontal = this.provider.opts.orientation.current === 'horizontal';
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider.dragOffset = horizontal
? this.provider.gesture.offsetX
: this.provider.gesture.offsetY;
} else if (wasDragging) {
this.provider.finishDrag();
}
wasDragging = isDragging;
});
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
'data-orientation': this.provider.opts.orientation.current,
'data-dragging': boolToEmptyStrOrUndef(this.provider.gesture.isDragging),
style: {
display: 'flex',
'flex-direction':
this.provider.opts.orientation.current === 'horizontal' ? 'row' : 'column',
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
gap: this.provider.opts.gap.current,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
transform: this.provider.itemGroupTransform,
transition: this.provider.gesture.isDragging ? 'none' : 'transform 300ms ease-out',
'touch-action': this.provider.opts.orientation.current === 'horizontal' ? 'pan-y' : 'pan-x'
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
},
...this.provider.gesture.props
} as const)
);
}
// ── Item ───────────────────────────────────────────────────────────────────
interface CarouselItemOpts extends WithRefOpts, ActiveProps<{ index: number }> {}
export class CarouselItemProvider {
readonly opts: CarouselItemOpts;
readonly runtimePart: SomaRuntimePart;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static create(opts: CarouselItemOpts) {
return new CarouselItemProvider(opts);
}
readonly provider: CarouselProvider;
private constructor(opts: CarouselItemOpts) {
this.opts = opts;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider = CarouselProvider.require();
this.runtimePart = this.provider.runtime.part('item', {
id: opts.id,
ref: opts.ref,
owner: this
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
readonly isActive = $derived.by(() => {
const i = this.opts.index.current;
const start = this.provider.opts.value.current;
const spv = Math.max(1, this.provider.opts.slidesPerView.current);
return i >= start && i < start + spv;
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
readonly snippetProps = $derived.by(() => ({
index: this.opts.index.current,
isActive: this.isActive
}));
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
readonly props = $derived.by(() => {
const spv = Math.max(1, this.provider.opts.slidesPerView.current);
const gap = this.provider.opts.gap.current;
// `flex-basis: calc((100% - (spv - 1) * gap) / spv)` keeps slides
// uniformly sized when gap > 0; falls through to `100% / spv` when
// gap is the default `0px`.
const basis = spv === 1 ? '100%' : `calc((100% - ${spv - 1} * ${gap}) / ${spv})`;
return this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
role: 'group' as const,
'aria-roledescription': 'slide',
'aria-label': `Slide ${this.opts.index.current + 1} of ${this.provider.slideCount}`,
'data-state': this.isActive ? 'active' : 'inactive',
'data-index': this.opts.index.current,
'data-orientation': this.provider.opts.orientation.current,
style: {
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
flex: `0 0 ${basis}`,
'min-width': 0,
'min-height': 0
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
fix(carousel): vertical overflow + close gaps vs embla/ark-ui/mantine Real reference audit walked the published embla `.d.ts`, Mantine docs, ark-ui, shadcn-svelte and Swiper. Found three classes of gaps in the initial port (a) the vertical bug breaking the only non-default orientation, (b) layout primitives every other lib ships (slidesPerView, slidesToScroll, align, gap), (c) autoplay granularity (playOnInit, stopOnInteraction, stopOnFocusIn, stopOnMouseEnter, stopOnLastSnap), plus an imperative API every consumer needs. ## Vertical bug fix Recipe now gives the root a default `block-size` in vertical orientation (`16rem`, overridable via `--_carousel-vertical-block-size` or the new eidos `verticalBlockSize` prop) and stretches the viewport to fill it. Without this the viewport collapses to content height and items spill. ## Soma extensions - `defaultValue` (uncontrolled init) - `slidesPerView` (1+) — each Item basis = (100% − gap·(n−1)) / n - `slidesToScroll` (1+) — paged group navigation - `align: 'start' | 'center' | 'end'` — viewport alignment - `gap: string` (CSS length) — between-slide spacing on the ItemGroup - `playOnInit` — start autoplay on mount (default true) - `stopOnInteraction` — latch-stop after user clicks prev/next/indicator or drags - `stopOnFocusIn` — pause while focus is inside (default true) - `stopOnMouseEnter` — pause while cursor over root (Embla parity) - `stopOnLastSnap` — latch-stop at last snap when loop=false - Snippet exposes `isPlaying` + an `api` handle with `scrollNext / scrollPrev / scrollTo / play / pause / reset` `commit()` now respects `slidesPerView` (last snap = count − spv). `next()` / `prev()` step by `slidesToScroll`. Translate calc derives from `slideSize = viewportSize / slidesPerView` so multi-view works. Item flex-basis adapts to slidesPerView + gap. ## Eidos additions - `verticalBlockSize` prop — forwarded as CSS custom property for the vertical recipe override - Recipe selectors for vertical orientation enforcing the block-size + viewport stretch - Style composition so consumers can still pass inline `style` ## Demo Live tab now has 4 organized sections (layout / drag / autoplay / imperative API) covering every new prop. The imperative API row drives the carousel from external buttons via the snippet handle so consumers see the pattern in action. `verticalBlockSize` slider exercises the vertical fix. Snippet preview emits every set prop. ## Reference comparison Following the canon's mandate to compare with references BEFORE declaring done, the actual feature matrix from embla published `.d.ts`, Mantine docs, ark-ui, shadcn-svelte, Swiper: | Feature | embla | mantine | ark | swiper | UIX | |------------------------|-------|---------|-----|--------|-----| | Index nav | ✓ | ✓ | ✓ | ✓ | ✓ | | Loop | ✓ | ✓ | ✓ | ✓ | ✓ | | Drag | ✓ | ✓ | ✓ | ✓ | ✓ | | Autoplay | plug | plug | ✓ | ✓ | ✓ | | Orientation H/V | ✓ | ✓ | ✓ | ✓ | ✓ | | slidesPerView | indir | ✓ | ✓ | ✓ | ✓ | | slidesToScroll | ✓ | ✓ | ✓ | ✓ | ✓ | | Align | ✓ | indir | per | ✓ | ✓ | | Gap | css | ✓ | ✓ | ✓ | ✓ | | defaultValue | startIndex | ✓ | ✓ | ✓ | ✓ | | playOnInit | ✓ | indir | ✓ | ✓ | ✓ | | stopOnInteraction | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnFocusIn | ✓ | ✓ | ✓ | partl | ✓ | | stopOnMouseEnter | ✓ | ✓ | ✓ | ✓ | ✓ | | stopOnLastSnap | ✓ | ✓ | ✗ | ✓ | ✓ | | Imperative API | ✓ | ✓ | ✓ | ✓ | ✓ | | Indicators / triggers | DIY | ✓ | ✓ | ✓ | ✓ | | Fade effect | plug | plug | ✗ | ✓ | ✗ deferred | | Virtual slides | ✗ | ✗ | ✗ | ✓ | ✗ deferred | | Multirow grid | ✗ | ✗ | ✗ | ✓ | ✗ deferred | Deferred power-user features (fade, virtual, multirow grid, cube/cards, parallax) are documented as power-user in the reference audit, not table-stakes, and would require Embla-class internals to ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
} as const);
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
// ── PrevTrigger ────────────────────────────────────────────────────────────
interface CarouselPrevTriggerOpts
extends WithRefOpts, ActiveProps<{ ariaLabel: string | undefined }> {}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
export class CarouselPrevTriggerProvider {
readonly opts: CarouselPrevTriggerOpts;
readonly runtimePart: SomaRuntimePart;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static create(opts: CarouselPrevTriggerOpts) {
return new CarouselPrevTriggerProvider(opts);
}
readonly provider: CarouselProvider;
private constructor(opts: CarouselPrevTriggerOpts) {
this.opts = opts;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider = CarouselProvider.require();
this.runtimePart = this.provider.runtime.part('prev-trigger', {
id: opts.id,
ref: opts.ref,
owner: this
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
readonly isDisabled = $derived.by(() => this.provider.isDisabled || !this.provider.canGoPrev);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
if (this.isDisabled) return;
this.provider.prev();
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
type: 'button' as const,
'aria-label': this.opts.ariaLabel.current || this.provider.soma.langs.ts(CAROUSEL_LANGS.PREV),
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
disabled: this.isDisabled || undefined,
'data-disabled': boolToEmptyStrOrUndef(this.isDisabled),
onclick: this.onclick
} as const)
);
}
// ── NextTrigger ────────────────────────────────────────────────────────────
interface CarouselNextTriggerOpts
extends WithRefOpts, ActiveProps<{ ariaLabel: string | undefined }> {}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
export class CarouselNextTriggerProvider {
readonly opts: CarouselNextTriggerOpts;
readonly runtimePart: SomaRuntimePart;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static create(opts: CarouselNextTriggerOpts) {
return new CarouselNextTriggerProvider(opts);
}
readonly provider: CarouselProvider;
private constructor(opts: CarouselNextTriggerOpts) {
this.opts = opts;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider = CarouselProvider.require();
this.runtimePart = this.provider.runtime.part('next-trigger', {
id: opts.id,
ref: opts.ref,
owner: this
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
readonly isDisabled = $derived.by(() => this.provider.isDisabled || !this.provider.canGoNext);
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
if (this.isDisabled) return;
this.provider.next();
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
type: 'button' as const,
'aria-label': this.opts.ariaLabel.current || this.provider.soma.langs.ts(CAROUSEL_LANGS.NEXT),
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
disabled: this.isDisabled || undefined,
'data-disabled': boolToEmptyStrOrUndef(this.isDisabled),
onclick: this.onclick
} as const)
);
}
// ── IndicatorGroup ─────────────────────────────────────────────────────────
interface CarouselIndicatorGroupOpts extends WithRefOpts {}
export class CarouselIndicatorGroupProvider {
readonly opts: CarouselIndicatorGroupOpts;
readonly runtimePart: SomaRuntimePart;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static create(opts: CarouselIndicatorGroupOpts) {
return new CarouselIndicatorGroupProvider(opts);
}
readonly provider: CarouselProvider;
private constructor(opts: CarouselIndicatorGroupOpts) {
this.opts = opts;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider = CarouselProvider.require();
this.runtimePart = this.provider.runtime.part('indicator-group', {
id: opts.id,
ref: opts.ref,
owner: this
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
role: 'tablist' as const,
'aria-orientation': this.provider.opts.orientation.current,
'data-orientation': this.provider.opts.orientation.current
} as const)
);
}
// ── Indicator ──────────────────────────────────────────────────────────────
interface CarouselIndicatorOpts
extends WithRefOpts, ActiveProps<{ index: number; ariaLabel: string | undefined }> {}
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
export class CarouselIndicatorProvider {
readonly opts: CarouselIndicatorOpts;
readonly runtimePart: SomaRuntimePart;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
static create(opts: CarouselIndicatorOpts) {
return new CarouselIndicatorProvider(opts);
}
readonly provider: CarouselProvider;
private constructor(opts: CarouselIndicatorOpts) {
this.opts = opts;
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
this.provider = CarouselProvider.require();
this.runtimePart = this.provider.runtime.part('indicator', {
id: opts.id,
ref: opts.ref,
owner: this
});
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
}
readonly isActive = $derived.by(
() => this.opts.index.current === this.provider.opts.value.current
);
readonly snippetProps = $derived.by(() => ({
index: this.opts.index.current,
isActive: this.isActive
}));
readonly onclick = (_e: SomaMouseEvent<HTMLButtonElement>) => {
if (this.provider.isDisabled) return;
this.provider.goto(this.opts.index.current);
};
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
type: 'button' as const,
role: 'tab' as const,
'aria-selected': this.isActive,
'aria-label': this.opts.ariaLabel.current || `Go to slide ${this.opts.index.current + 1}`,
soma: 10 new components + reactivity audit + guide rules A30–A33 Components shipped: - AlertDialog (thin Dialog specialisation with Escape=close default) - Breadcrumb (+ interactive Ellipsis composing DropdownMenu) - Carousel (gesture + autoplay + indicators) - Listbox (roving tabindex + typeahead + Ctrl+A multi-select) - NavigationMenu (hover-intent + data-motion direction + Indicator CSS vars) - PinInput (Field-aware segmented input with paste transformer) - RatingGroup (half-step + clearable + keyboard digits) - Toggle (standalone two-state with Field OR-merge) - VirtualGrid (2D windowing for spreadsheets / thumbnail grids) - VirtualList (fixed + dynamic heights, ResizeObserver anti-jump, WindowViewport) Guide rules (src/uix/soma/COMPONENT_GUIDE.md): - A30 + item 32: id registration via direct assign, never $effect — the $effect(() => parent.id = opts.id) pattern causes reactive loops that freeze the page. Ref: PinInput + Listbox incidents. - A31 + item 33: per-entity $derived must not call provider methods that read global state — lift to single provider $derived, per-entity derivations pointer-compare. Ref: Command (2026-04-17), Listbox rovingTarget. - A32 + items 34–35: present comparison table in conversation before declaring done. Every ❌/⚠️ gets an explicit decision (implement / defer to v2 / drop); deferred features become their own README section. - A33 + item 36: reactive collections use SvelteMap / SvelteSet from svelte/reactivity — $state(new Map()) only tracks field reassignment, not per-entry .set/.get/.has reads inside $derived. Reactivity audits + fixes: - VirtualList sizeCache → SvelteMap (dynamic heights were silently stuck). - Form touched + registry → SvelteMap (isTouched / isDirty / onBlur validation $derived never re-ran with plain Map). - Combobox labelRegistry → SvelteMap (removed clone-and-reassign workaround, O(N)→O(1) per registration). Other fixes this pass: - ColorField/ColorPicker RGB co-increment bug (HSV round-trip was lossy). - 24 state_referenced_locally warnings swept across date/time/color field+picker wrappers (removed `void X;` placeholders that Svelte 5 flagged, added svelte-ignore for intentional mount-time reads). - AlertDialog Content wrapper forces escapeKeydownBehavior=close (overrides Dialog's alertdialog→ignore default → matches WAI-ARIA). - Breadcrumb Ellipsis interactive prop renders <button aria-haspopup> so DropdownMenu composition works without manual trigger plumbing. - VirtualList Viewport drops `contain: strict` (was breaking programmatic scrollTo in some engines). - Memory entries: feedback_id_effect_assign_directly, feedback_scope_approval, feedback_svelte_reactivity_collections. Sium library (delegated session, landed in tree): - Core schema + primitives + combinators + pipe + refines + modifiers. - Langs module with idlangref resolver. - Svelte form adapter. - Protocol docs + status ledger for Codex coordination. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 months ago
tabindex: this.isActive ? 0 : -1,
'data-state': this.isActive ? 'active' : 'inactive',
'data-index': this.opts.index.current,
onclick: this.onclick
} as const)
);
}

Powered by TurnKey Linux.