Morfo (src/uix/morfo/): machine-readable contract of a component's public
DOM surface, shared between soma/sema/eidos. Shape v5 consolidated across
three independent AI reviews (Gemini, Grok, ChatGPT) plus Sema alignment.
Types, sium-based validator with cross-field invariants, dialog.ts as the
first canonical morfo with data-last-action for Sema-causal exits, 7 passing
unit tests.
createAttrs(morfo) and registerContract(morfo) now consume a Morfo — legacy
inline signature removed. Dialog provider refactored to derive parts +
data contract from dialogMorfo. The other 65 soma components need porting
(svelte-check lists them) — tracked work.
Tooling:
scripts/smoke-check.mjs — Playwright smoke over 65 soma demo routes
scripts/morfo-check.ts — validates emitted DOM vs morfo
scripts/morfo-vocabulary-check.ts — canonical vocabulary consistency
npm run smoke / morfo:check / morfo:vocabulary
WAI-ARIA APG components added (100% APG coverage now):
Announce, Avatar, Clipboard, DragDrop, Feed, GridList, Meter, Progress,
SearchField, TagGroup, TreeGrid + Table.RowDetail/Trigger (detail panel
pattern; hierarchical Table rows deprecated — use TreeGrid instead).
air: Link, Banner.
Sema prep:
src/uix/sema/sema_pre.md documents the semantic layer's DOM requirements.
Morfo already provides everything Sema needs (data-last-action patterns,
transition markers, enumerable state values, cross-component consistency).
Sema implementation deferred.
COMPONENT_GUIDE updated: items 37-39 (translation namespace grep, DOM
topology vs .require() audit, npm run smoke is part of done) + A34 rule
with incident log. WAI-ARIA pattern listed as soma membership criterion.
Pagination translation bug fixed (soma.pagination.page -> idlangref
PAGINATION_LANGS.PAGE). Table demo namespace fix (soma.table.*
-> components.table.*). Avatar demo now offline-safe (SVG data URL).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
soma — new headless component system replacing terra:
- Provider base class with opt-in context injection
- Reactive system (state, readableActive, writableActive)
- Attrs system (createAttrs, contracts, helpers)
- Props system (mergeProps with on-prefix detection, no hardcoded event list)
- DOM utils (consolidated core, focus/, env)
- Keyboard, events, CSS, ID, config modules
- Layers: scroll, observers, visually-hidden, arrow, portal, text-selection,
dismissal (merged escape+dismissible), presence, focus-scope
- Collapsible component as first soma validation
air components:
- Pagination, Editable, PinInput (air-native), RatingGroup (air-native),
Stepper, FileUpload wrappers over terra
- Terra defaultContent refactor for children snippet pattern
- Avatar, Meter, Progress, Separator migrated to air-native
- Reactive utilities extracted to $lib/util/reactive (shared)
- $soma and $reactive aliases added
Architecture:
- soma is independent: no imports from terra or $lib/util/reactive
- Terra exports deprecated for migrated components
- README fundacional documenting all design decisions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Components:
- AlertDialog: Provider, Content (context transition), Action, Cancel + demo
- DropdownMenu: Provider (revelation sound), Content (floating), Item, Separator,
GroupHeading + checkbox/radio indicators via CSS pseudo-elements + demo
- ContextMenu: Provider, Content sharing dropdown-menu visual language + demo
Terra fix — menu variant registry:
- Add menuRegistryByVariant in menu.svelte.ts to track open menus per variant
- MenuMenuState.onOpen() closes all other menus of same variant before opening
- Prevents concurrent context-menus (or dropdown-menus) from being open simultaneously
- Registry lives in terra infrastructure, not air — clean architectural boundary
- Cleanup via onDestroyEffect when component unmounts
CSS fixes:
- DropdownMenu content: z-index: 50 for proper stacking
- Checkbox/radio items: visual indicators via ::before pseudo-elements
- Selectors duplicated for both dropdown-menu and context-menu data-attr prefixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Command Dialog demo (⌘K style) with proper Dialog.Trigger
- Make all inline demos collapsible to prevent UI clutter
- Add keyboard shortcut (cmd+k / ctrl+k) for Command Dialog
- Add close button (✕) and onSelect handlers to close dialog
- Fix CSS import paths in air/ and terra/ test pages
- Fix various syntax errors in test pages (toggle, toggle-group, meter)
- Update Switch and RadioGroup contracts with missing attributes
- Fix missing ctx declarations in time-field and time-range-field
- Fix checkbox group import error
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Merge internal/ and shared/ into utilities/ with semantic subdirs:
floating/, focus/, keyboard/, datetime/, presence/, typeahead/
- Fix tooltip/popover positioning: wrapperProps.style was a plain object,
causing Svelte 5 spread to serialize it as "[object Object]" — wrapped
with styleToString() so CSS is applied correctly
- Fix WithChild<T,{},Ref> producing Snippet<[{}]> instead of Snippet:
use keyof check so empty SnippetProps yields plain Snippet (no args)
- Fix TooltipContentProps.children: switch to WithChildNoChildrenSnippetProps
so children is Snippet while child retains { open: boolean } props
- Fix field component: move field.svelte.ts to root dir, add exports.ts,
simplify index.ts, normalize import paths across all field components
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>