uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
<script lang="ts">
|
|
|
|
|
|
import { onDestroy } from 'svelte';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { createActiveUix, setActiveUix } from '$active-uix';
|
|
|
|
|
|
import { createActivePrefsDomProjection, standardPrefsDimensions } from '$prefs';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { page } from '$app/state';
|
|
|
|
|
|
import { Soma } from '$soma/core/soma.svelte';
|
|
|
|
|
|
import { siumLangs } from '$sium/langs/langs';
|
fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers
Resolves 34 of 40 failures from src/uix/audit-uix-kimi-1.md. The remaining
6 are all Words component (excluded per project owner — actively developed
on a separate track) or unrelated infra (cookie-adapter-client jsdom timeout).
Key changes:
- soma/provider/context.ts: swallow Svelte's `lifecycle_outside_component`
in `context.set()` so unit tests can instantiate providers without a
component tree (unblocked 18 picker tests in one line).
- soma/textarea: route inline style writes through `dom.apply({attrs})`
instead of direct `el.style.X = Y` (contract regex compliance).
- soma/picker-shell: add minimal Provider component + morfo so the shared
handle utility passes the morfo/component contract.
- eidos/_layout: lift `shared.ts` to `eidos/lib/layout-helpers.ts` (the
`_layout` directory wasn't a real component) and update 8 layout
primitive imports.
- eidos/command: replace `onMount` with `$effect` (visual layer can't use
Svelte 4 lifecycle hooks per component-api contract); restructure
`Item.Icon`/`Item.Shortcut` namespace so contract regex matches.
- eidos/color-picker: extract hue spectrum hsl literals to sidecar
`color-picker-spectrum.css`; keep main recipe color-literal-free.
- eidos/lib/recipes/base.ts: declare 196 layout-primitive + chrome CSS
vars (box, flex, grid, float, group, banner, container, section,
separator, toggle-group, pin-input, scroll-area, splitter,
navigation-menu, dropdown-menu, context-menu, date-range-field,
time-range-field, plus per-component additions to date-field,
color-picker, button, select). 197 missing → 0 non-Words.
- morfo: add `data-dir` to carousel, `data-kind` to date-picker, add
StrengthMeterLabel sub-part to password-field, register picker-shell.
- 5 pickers (date/color/date-range/time/time-range): add `internals.ts`
indirection so `exports.ts` doesn't re-export `*provider.svelte.ts`
directly (contract D); rewrite virtual root types to plain object
literals (no `WithChild`/`PrimitiveDivAttributes`).
- 4 new READMEs (button, textarea, password-field, picker-shell)
following the search-field canonical template.
Test result: 2391/2397 passing (99.75%). Remaining 6 failures are all
Words-scope or jsdom infra timeout — explicitly out of scope.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { secsLangs } from '$libs/secs';
|
|
|
|
|
|
import { ActiveEidos } from '$uix/eidos';
|
|
|
|
|
|
import type { Gradient } from '$libs/gradient';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { dialogSema } from '$uix/sema/components/dialog';
|
|
|
|
|
|
import { drawerSema } from '$uix/sema/components/drawer';
|
|
|
|
|
|
import { editableSema } from '$uix/sema/components/editable';
|
|
|
|
|
|
import { fileUploadSema } from '$uix/sema/components/file-upload';
|
|
|
|
|
|
import { floatPanelSema } from '$uix/sema/components/float-panel';
|
|
|
|
|
|
import { formSema } from '$uix/sema/components/form';
|
|
|
|
|
|
import { gradientBuilderSema } from '$uix/sema/components/gradient-builder';
|
|
|
|
|
|
import { gradientPickerSema } from '$uix/sema/components/gradient-picker';
|
feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer
Three new components across all 4 layers (morfo/soma/sema/eidos) + demos + langs + READMEs:
- ImageAdjustments — reusable image-filter sliders subcomponent.
- ImagePicker — composes file-upload + image + image-adjustments (fill modes, rotation).
- Cropper — Ark image-cropper anatomy: normalized 0-1 crop rect, rect + round shapes,
8 resize handles, fixedSize move-only (avatar), canvas Blob output (5-arg drawImage
for SVG safety), wheel/pan zoom, two-zone gesture (selection moves the area, the
background pans to set focus; img draggable=false guards native DnD per zag).
New reusable soma/layers/zoom-pan: cursor-centered zoom, clamped pan, transform +
viewport-frac-to-content-frac mapping. Image-viewer / diagram-pan / map can reuse it.
sema: add 'zoom' verb to the handle family (direct manipulation, documented extension).
slider: track visible at zero (gray, not white), thumb lifts on drag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
import { imageAdjustmentsSema } from '$uix/sema/components/image-adjustments';
|
|
|
|
|
|
import { imagePickerSema } from '$uix/sema/components/image-picker';
|
|
|
|
|
|
import { knobSema } from '$uix/sema/components/knob';
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
import { maskFieldSema } from '$uix/sema/components/mask-field';
|
|
|
|
|
|
import { navTreeSema } from '$uix/sema/components/nav-tree';
|
uix(sidebar): F1.7 eidos + demo · raíl, modo icono y submenú flotante
Segunda tanda del sidebar: la capa visual, la demo canónica de 9 pestañas y
la verificación en navegador real. Con esto el componente está vivo; queda el
review adversarial.
Eidos
- Recipe con los dos ejes: off-canvas por `transform` (trabajo de compositor,
el inset no reflowea) y `width` animado SOLO en modo icono, donde el inset
sí tiene que seguir al raíl. El raíl NO lleva `will-change` (una franja
fina tiembla a DPR fraccionario — memoria NavMenu).
- Anchos como TOKENS: `--sidebar-width` 16rem · `--sidebar-width-icon` 3rem ·
`--sidebar-width-mobile` 18rem, más raíl, gaps, altura de fila y colores.
- Tres composiciones que la capa headless no puede hacer: `Drawer` para la
presentación móvil, `Tooltip` para nombrar filas en modo icono y `Badge`
para los contadores. El trigger compone `Button` por el patrón `child`.
- Convención de icono documentada: sobrevive el PRIMER elemento de la fila.
Arreglos que destapó el navegador
- **`mobile` en SSR**: sin viewport, `isAtLeast` responde «por debajo de todo»
→ el HTML salía con `data-mobile` y la hidratación NO lo corrige (no diffea
atributos y el valor ya no cambia). Viewport desconocido = ESCRITORIO.
- **Estado móvil propio** (arranca cerrado): en escritorio `open` es
preferencia de layout persistida; en móvil sería un overlay tapando la
página, que jamás puede ser el estado inicial. `onOpenChange` solo se
dispara con el estado de escritorio.
- **`open` controlado/no controlado**: se adopta el patrón de la casa
(`$bindable` con default, el provider escribe siempre) — mi versión previa
con estado interno no propagaba `bind:open`.
- **El submenú flotante no se posicionaba**: `FloatingAnchor` resuelve su
provider por CONTEXTO y el eidos envuelve la fila en un `Tooltip`, que
publica el suyo → el ancla caía en el tooltip y el submenú se quedaba en
`translate(0,-200%)`. Ahora el ancla se cablea directamente al provider
flotante del item. Además el `<ul>` ya no se posiciona a sí mismo (colapsaba
el wrapper a tamaño cero) y toma elevación del plano `overlay` por
`data-depth`, como cualquier panel flotante del ecosistema.
- **Tooltip vs submenú**: una fila con submenú no lleva tooltip en modo icono
(dos superficies sobre el mismo ancla se pisan) — nuevo `useSidebarItemOr()`.
- El item envuelve (`flex-wrap`) para que el submenú caiga en su propia línea
en vez de ponerse al lado de la fila.
Demo: shell de app real (grupos, badge, acción, submenú, fila deshabilitada),
controles vivos de los tres props y las 9 pestañas del canon.
Verificado en navegador real (Playwright): dos landmarks nombrados en el
idioma activo · `aria-current="page"` en la fila activa · cada menú etiquetado
por SU grupo · raíl enfocable que alterna con Enter · colapso 256→48px ·
off-canvas por transform · submenú flotante anclado a su fila y Escape que
devuelve el foco · sema `emerge-expand/collapse` estampando en `panel` ·
móvil 600px = Drawer cerrado con el landmark dentro · RTL espeja el shell
entero · oscuro · 0 errores de consola.
Gates: `component:audit --only sidebar` PASS 0E/0W · eidos-lint 45
morfo-backed / 0 invalid / 0 class-hooks · `svelte-check` 0 errores propios ·
`vitest src/uix/eidos` 353/353 · `contracts.test` solo con fallos ajenos
(menubar, radio-group y las claves camelCase de aura).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
|
|
|
|
import { sidebarSema } from '$uix/sema/components/sidebar';
|
|
|
|
|
|
import { numberFieldSema } from '$uix/sema/components/number-field';
|
|
|
|
|
|
import { paginationSema } from '$uix/sema/components/pagination';
|
feat: build PasswordField (full stack)
Dedicated password input component — matches the Ark UI / Chakra v3 /
Mantine / PrimeReact / Ant Design pattern of treating PasswordField as
its own first-class component (not a TextField variant). Includes one
feature that NO surveyed library ships: a CapsLock indicator driven by
KeyboardEvent.getModifierState('CapsLock').
Anatomy (5 parts, 4 events):
- Provider (root, value + visibility state)
- Input (the textbox; type flips between password / text)
- VisibilityTrigger (eye toggle button; aria-pressed + aria-controls)
- CapsLockIndicator (status live region; data-active toggles via soma
listening to keydown/keyup on Input)
- StrengthMeter (composable; consumer provides 0-4 score; UIX bundles
no zxcvbn-style algorithm — dependency-free by design)
Events:
- commit-input (every keystroke)
- commit-submit (Enter)
- shift-toggle-visibility (eye click)
- shift-caps-state (Caps Lock state flips while focused)
Key behaviors:
- `purpose: 'current' | 'new'` drives native autocomplete attribute
('current-password' for login / 'new-password' for registration).
- Field integration: disabled/readonly/required/invalid OR-merged.
- VisibilityTrigger gets tabindex=-1 so it doesn't break the form's
natural tab order — mouse / programmatic focus only, matching Ark UI.
- Caps Lock indicator is aria-live="polite" — announces on activation
while focused, silent when inactive.
- Letter-spacing increased on the input for legibility while masked.
Reference library survey performed (10 libraries) before implementation —
all consensus around dedicated component, all have built-in toggle,
ZERO have caps lock warning. Documented in the demo's API tab with a
feature comparison table.
Demo follows DEMO_AUTHORING_GUIDE canonical 6-tab depth: Live (controls
grouped by layer + code snippets at the bottom), API (props + reference
comparison), Morfo (field/value + Parts + Events tables), Sema (events
table with ▶ play), Recipe (selectors with morfo/eidos owner tags), A11y
(concern/contract table).
Also includes external work in words/ from a separate session
(unrelated to PasswordField) — not touching Words is the standing rule,
but the diff was already in the working tree.
svelte-check: 0 errors in PasswordField files (Words errors are tracked
by its own development branch).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { passwordFieldSema } from '$uix/sema/components/password-field';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { popoverSema } from '$uix/sema/components/popover';
|
|
|
|
|
|
import { radioGroupSema } from '$uix/sema/components/radio-group';
|
|
|
|
|
|
import { ratingGroupSema } from '$uix/sema/components/rating-group';
|
|
|
|
|
|
import { searchFieldSema } from '$uix/sema/components/search-field';
|
|
|
|
|
|
import { selectSema } from '$uix/sema/components/select';
|
|
|
|
|
|
import { sliderSema } from '$uix/sema/components/slider';
|
|
|
|
|
|
import { splitterSema } from '$uix/sema/components/splitter';
|
|
|
|
|
|
import { stepperSema } from '$uix/sema/components/stepper';
|
|
|
|
|
|
import { tabsSema } from '$uix/sema/components/tabs';
|
|
|
|
|
|
import { tagGroupSema } from '$uix/sema/components/tag-group';
|
|
|
|
|
|
import { tagsInputSema } from '$uix/sema/components/tags-input';
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { textareaSema } from '$uix/sema/components/textarea';
|
|
|
|
|
|
import { timelineSema } from '$uix/sema/components/timeline';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { toastSema } from '$uix/sema/components/toast';
|
|
|
|
|
|
import { toolbarSema } from '$uix/sema/components/toolbar';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import { accordionSema } from '$uix/sema/components/accordion';
|
uix(chat): bloque de mensajería chat-* v1 (log · message · composer · typing)
Familia chat-* completa, componiendo el ecosistema (Feed + VirtualList
anclado, Textarea, FileUpload, Avatar, Popover, Icon). Transporte-agnóstica:
el modelo de datos es de la app, los componentes reciben props + snippets.
- chat-log: Feed + VirtualList(anchor:'end') en triple registro; day
separators, unread divider, filas de sistema (Feed.Article), pill "N
nuevos" + notifyIncoming (announce a live-region), to-latest distance-aware.
- chat-message: raíz Feed.Article; runs ($libs/chat), ticks de entrega,
reply embebido, reacciones (chip pressed + tapback panel), acciones hover.
- chat-composer: Textarea (doble registro) + FileUpload; teclado
Enter/Shift+Enter/Esc/ArrowUp; typing saliente debounced (uix.timers);
barra reply/edit.
- chat-typing: sustain-streaming (visual-only, loop del sistema);
aggregateTypers 1/2/3+ con plantillas plurales.
- $libs/chat: groupIntoRuns (ventana 8 min estilo Discord) + aggregateTypers.
- VirtualList: extensión anchor:'end' (followOutput, prepend por clave
estable, sticky monótono, onAtEndChange) — sin scroller paralelo.
Diseño de referencia (WhatsApp/Telegram, pase lado-a-lado): burbujas suaves
(out = primary-element + texto normal; in = surface card + sombra) sobre
lienzo muted del log, meta dentro de la burbuja, tapback bar horizontal,
iconos lucide del ecosistema (nada de SVG a mano). Contrato de tamaños:
size="md" = 16px canónico.
Fixes de framework (afectaban más allá de chat):
- EngineLangs.t() ahora pela el prefijo '#?': los idlangrefs imperativos
(pagination/file-upload/chronos/chat) caían al fallback EN en locale es.
Fix parseLangRef ?? parsePathFallback + test de regresión (132/132).
- virtual-list commit-set-resize con channels:[]: es bookkeeping de
ResizeObserver, no gesto → dejaba de emitir beep/vibrate pre-interacción
(interventions de navigator.vibrate / AudioContext).
Escaparate messenger en /uix/demos/chat (bot de eco con uix.timers;
variante $connection señalada). Gaps v2 registrados en next-features §7.
Pase: component:audit 4×PASS · eidos-lint invalid=0 · recipe-contract
29/29 · Playwright escaparate PASS end-to-end · consola limpia ·
npm run check en baseline (76, cero errores nuevos).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
import { chatComposerSema } from '$uix/sema/components/chat-composer';
|
|
|
|
|
|
import { chatLogSema } from '$uix/sema/components/chat-log';
|
|
|
|
|
|
import { chatMessageSema } from '$uix/sema/components/chat-message';
|
|
|
|
|
|
import { checkboxSema } from '$uix/sema/components/checkbox';
|
|
|
|
|
|
import { calendarSema } from '$uix/sema/components/calendar';
|
|
|
|
|
|
import { colorPickerSema } from '$uix/sema/components/color-picker';
|
|
|
|
|
|
import { comboboxSema } from '$uix/sema/components/combobox';
|
feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer
Three new components across all 4 layers (morfo/soma/sema/eidos) + demos + langs + READMEs:
- ImageAdjustments — reusable image-filter sliders subcomponent.
- ImagePicker — composes file-upload + image + image-adjustments (fill modes, rotation).
- Cropper — Ark image-cropper anatomy: normalized 0-1 crop rect, rect + round shapes,
8 resize handles, fixedSize move-only (avatar), canvas Blob output (5-arg drawImage
for SVG safety), wheel/pan zoom, two-zone gesture (selection moves the area, the
background pans to set focus; img draggable=false guards native DnD per zag).
New reusable soma/layers/zoom-pan: cursor-centered zoom, clamped pan, transform +
viewport-frac-to-content-frac mapping. Image-viewer / diagram-pan / map can reuse it.
sema: add 'zoom' verb to the handle family (direct manipulation, documented extension).
slider: track visible at zero (gray, not white), thumb lifts on drag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
import { cropperSema } from '$uix/sema/components/cropper';
|
|
|
|
|
|
import { cssFieldSema } from '$uix/sema/components/css-field';
|
|
|
|
|
|
import { dateFieldSema } from '$uix/sema/components/date-field';
|
|
|
|
|
|
import { Popover } from '$uix/eidos/components/popover';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import '@/uix/eidos/index.css';
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
// Opt-in full 31-scale donor palette — lets component `color="teal"` /
|
|
|
|
|
|
// `color="plum"` (THEMING §25.5, the Radix per-instance override) resolve
|
|
|
|
|
|
// the raw `--scale-{name}-*` tokens in the docs. The slim foundation
|
|
|
|
|
|
// (`generated/base.css`) ships only role-referenced scales; the demos need
|
|
|
|
|
|
// the whole palette so the System axis can exercise every scale.
|
|
|
|
|
|
import '@/uix/eidos/generated/palette.css';
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
import './uix.css';
|
|
|
|
|
|
|
|
|
|
|
|
let { children } = $props();
|
|
|
|
|
|
|
|
|
|
|
|
type Language = 'es' | 'en' | 'fr' | 'de';
|
|
|
|
|
|
type Currency = 'EUR' | 'USD' | 'GBP' | 'JPY';
|
|
|
|
|
|
type UnitSystem = 'metric' | 'imperial';
|
|
|
|
|
|
type NumberFormat = 'es-ES' | 'en-US' | 'en-GB' | 'de-DE';
|
|
|
|
|
|
|
|
|
|
|
|
const docsPrefsSchema = standardPrefsDimensions({
|
|
|
|
|
|
languages: ['es', 'en', 'fr', 'de'] satisfies readonly Language[],
|
|
|
|
|
|
locales: ['es-ES', 'en-US', 'en-GB', 'de-DE'] satisfies readonly NumberFormat[],
|
|
|
|
|
|
currencies: ['EUR', 'USD', 'GBP', 'JPY'] satisfies readonly Currency[],
|
|
|
|
|
|
defaults: {
|
|
|
|
|
|
language: 'es',
|
|
|
|
|
|
locale: 'es-ES',
|
|
|
|
|
|
currency: 'EUR'
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
const uix = createActiveUix({
|
fix(uix audit): apply Kim audit remediations across morfo/soma/eidos/recipe layers
Resolves 34 of 40 failures from src/uix/audit-uix-kimi-1.md. The remaining
6 are all Words component (excluded per project owner — actively developed
on a separate track) or unrelated infra (cookie-adapter-client jsdom timeout).
Key changes:
- soma/provider/context.ts: swallow Svelte's `lifecycle_outside_component`
in `context.set()` so unit tests can instantiate providers without a
component tree (unblocked 18 picker tests in one line).
- soma/textarea: route inline style writes through `dom.apply({attrs})`
instead of direct `el.style.X = Y` (contract regex compliance).
- soma/picker-shell: add minimal Provider component + morfo so the shared
handle utility passes the morfo/component contract.
- eidos/_layout: lift `shared.ts` to `eidos/lib/layout-helpers.ts` (the
`_layout` directory wasn't a real component) and update 8 layout
primitive imports.
- eidos/command: replace `onMount` with `$effect` (visual layer can't use
Svelte 4 lifecycle hooks per component-api contract); restructure
`Item.Icon`/`Item.Shortcut` namespace so contract regex matches.
- eidos/color-picker: extract hue spectrum hsl literals to sidecar
`color-picker-spectrum.css`; keep main recipe color-literal-free.
- eidos/lib/recipes/base.ts: declare 196 layout-primitive + chrome CSS
vars (box, flex, grid, float, group, banner, container, section,
separator, toggle-group, pin-input, scroll-area, splitter,
navigation-menu, dropdown-menu, context-menu, date-range-field,
time-range-field, plus per-component additions to date-field,
color-picker, button, select). 197 missing → 0 non-Words.
- morfo: add `data-dir` to carousel, `data-kind` to date-picker, add
StrengthMeterLabel sub-part to password-field, register picker-shell.
- 5 pickers (date/color/date-range/time/time-range): add `internals.ts`
indirection so `exports.ts` doesn't re-export `*provider.svelte.ts`
directly (contract D); rewrite virtual root types to plain object
literals (no `WithChild`/`PrimitiveDivAttributes`).
- 4 new READMEs (button, textarea, password-field, picker-shell)
following the search-field canonical template.
Test result: 2391/2397 passing (99.75%). Remaining 6 failures are all
Words-scope or jsdom infra timeout — explicitly out of scope.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
langs: { schema: { sium: siumLangs, secs: secsLangs }, defaultLocale: 'es' as const },
|
|
|
|
|
|
prefs: { schema: docsPrefsSchema },
|
|
|
|
|
|
events: {
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
sound: true,
|
|
|
|
|
|
haptic: true,
|
|
|
|
|
|
components: [
|
|
|
|
|
|
accordionSema,
|
|
|
|
|
|
calendarSema,
|
uix(chat): bloque de mensajería chat-* v1 (log · message · composer · typing)
Familia chat-* completa, componiendo el ecosistema (Feed + VirtualList
anclado, Textarea, FileUpload, Avatar, Popover, Icon). Transporte-agnóstica:
el modelo de datos es de la app, los componentes reciben props + snippets.
- chat-log: Feed + VirtualList(anchor:'end') en triple registro; day
separators, unread divider, filas de sistema (Feed.Article), pill "N
nuevos" + notifyIncoming (announce a live-region), to-latest distance-aware.
- chat-message: raíz Feed.Article; runs ($libs/chat), ticks de entrega,
reply embebido, reacciones (chip pressed + tapback panel), acciones hover.
- chat-composer: Textarea (doble registro) + FileUpload; teclado
Enter/Shift+Enter/Esc/ArrowUp; typing saliente debounced (uix.timers);
barra reply/edit.
- chat-typing: sustain-streaming (visual-only, loop del sistema);
aggregateTypers 1/2/3+ con plantillas plurales.
- $libs/chat: groupIntoRuns (ventana 8 min estilo Discord) + aggregateTypers.
- VirtualList: extensión anchor:'end' (followOutput, prepend por clave
estable, sticky monótono, onAtEndChange) — sin scroller paralelo.
Diseño de referencia (WhatsApp/Telegram, pase lado-a-lado): burbujas suaves
(out = primary-element + texto normal; in = surface card + sombra) sobre
lienzo muted del log, meta dentro de la burbuja, tapback bar horizontal,
iconos lucide del ecosistema (nada de SVG a mano). Contrato de tamaños:
size="md" = 16px canónico.
Fixes de framework (afectaban más allá de chat):
- EngineLangs.t() ahora pela el prefijo '#?': los idlangrefs imperativos
(pagination/file-upload/chronos/chat) caían al fallback EN en locale es.
Fix parseLangRef ?? parsePathFallback + test de regresión (132/132).
- virtual-list commit-set-resize con channels:[]: es bookkeeping de
ResizeObserver, no gesto → dejaba de emitir beep/vibrate pre-interacción
(interventions de navigator.vibrate / AudioContext).
Escaparate messenger en /uix/demos/chat (bot de eco con uix.timers;
variante $connection señalada). Gaps v2 registrados en next-features §7.
Pase: component:audit 4×PASS · eidos-lint invalid=0 · recipe-contract
29/29 · Playwright escaparate PASS end-to-end · consola limpia ·
npm run check en baseline (76, cero errores nuevos).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
chatComposerSema,
|
|
|
|
|
|
chatLogSema,
|
|
|
|
|
|
chatMessageSema,
|
|
|
|
|
|
checkboxSema,
|
|
|
|
|
|
colorPickerSema,
|
|
|
|
|
|
comboboxSema,
|
feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer
Three new components across all 4 layers (morfo/soma/sema/eidos) + demos + langs + READMEs:
- ImageAdjustments — reusable image-filter sliders subcomponent.
- ImagePicker — composes file-upload + image + image-adjustments (fill modes, rotation).
- Cropper — Ark image-cropper anatomy: normalized 0-1 crop rect, rect + round shapes,
8 resize handles, fixedSize move-only (avatar), canvas Blob output (5-arg drawImage
for SVG safety), wheel/pan zoom, two-zone gesture (selection moves the area, the
background pans to set focus; img draggable=false guards native DnD per zag).
New reusable soma/layers/zoom-pan: cursor-centered zoom, clamped pan, transform +
viewport-frac-to-content-frac mapping. Image-viewer / diagram-pan / map can reuse it.
sema: add 'zoom' verb to the handle family (direct manipulation, documented extension).
slider: track visible at zero (gray, not white), thumb lifts on drag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
cropperSema,
|
|
|
|
|
|
cssFieldSema,
|
|
|
|
|
|
dateFieldSema,
|
|
|
|
|
|
dialogSema,
|
|
|
|
|
|
drawerSema,
|
|
|
|
|
|
editableSema,
|
|
|
|
|
|
fileUploadSema,
|
|
|
|
|
|
floatPanelSema,
|
|
|
|
|
|
formSema,
|
|
|
|
|
|
gradientBuilderSema,
|
|
|
|
|
|
gradientPickerSema,
|
feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer
Three new components across all 4 layers (morfo/soma/sema/eidos) + demos + langs + READMEs:
- ImageAdjustments — reusable image-filter sliders subcomponent.
- ImagePicker — composes file-upload + image + image-adjustments (fill modes, rotation).
- Cropper — Ark image-cropper anatomy: normalized 0-1 crop rect, rect + round shapes,
8 resize handles, fixedSize move-only (avatar), canvas Blob output (5-arg drawImage
for SVG safety), wheel/pan zoom, two-zone gesture (selection moves the area, the
background pans to set focus; img draggable=false guards native DnD per zag).
New reusable soma/layers/zoom-pan: cursor-centered zoom, clamped pan, transform +
viewport-frac-to-content-frac mapping. Image-viewer / diagram-pan / map can reuse it.
sema: add 'zoom' verb to the handle family (direct manipulation, documented extension).
slider: track visible at zero (gray, not white), thumb lifts on drag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
imageAdjustmentsSema,
|
|
|
|
|
|
imagePickerSema,
|
|
|
|
|
|
knobSema,
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
maskFieldSema,
|
|
|
|
|
|
navTreeSema,
|
uix(sidebar): F1.7 eidos + demo · raíl, modo icono y submenú flotante
Segunda tanda del sidebar: la capa visual, la demo canónica de 9 pestañas y
la verificación en navegador real. Con esto el componente está vivo; queda el
review adversarial.
Eidos
- Recipe con los dos ejes: off-canvas por `transform` (trabajo de compositor,
el inset no reflowea) y `width` animado SOLO en modo icono, donde el inset
sí tiene que seguir al raíl. El raíl NO lleva `will-change` (una franja
fina tiembla a DPR fraccionario — memoria NavMenu).
- Anchos como TOKENS: `--sidebar-width` 16rem · `--sidebar-width-icon` 3rem ·
`--sidebar-width-mobile` 18rem, más raíl, gaps, altura de fila y colores.
- Tres composiciones que la capa headless no puede hacer: `Drawer` para la
presentación móvil, `Tooltip` para nombrar filas en modo icono y `Badge`
para los contadores. El trigger compone `Button` por el patrón `child`.
- Convención de icono documentada: sobrevive el PRIMER elemento de la fila.
Arreglos que destapó el navegador
- **`mobile` en SSR**: sin viewport, `isAtLeast` responde «por debajo de todo»
→ el HTML salía con `data-mobile` y la hidratación NO lo corrige (no diffea
atributos y el valor ya no cambia). Viewport desconocido = ESCRITORIO.
- **Estado móvil propio** (arranca cerrado): en escritorio `open` es
preferencia de layout persistida; en móvil sería un overlay tapando la
página, que jamás puede ser el estado inicial. `onOpenChange` solo se
dispara con el estado de escritorio.
- **`open` controlado/no controlado**: se adopta el patrón de la casa
(`$bindable` con default, el provider escribe siempre) — mi versión previa
con estado interno no propagaba `bind:open`.
- **El submenú flotante no se posicionaba**: `FloatingAnchor` resuelve su
provider por CONTEXTO y el eidos envuelve la fila en un `Tooltip`, que
publica el suyo → el ancla caía en el tooltip y el submenú se quedaba en
`translate(0,-200%)`. Ahora el ancla se cablea directamente al provider
flotante del item. Además el `<ul>` ya no se posiciona a sí mismo (colapsaba
el wrapper a tamaño cero) y toma elevación del plano `overlay` por
`data-depth`, como cualquier panel flotante del ecosistema.
- **Tooltip vs submenú**: una fila con submenú no lleva tooltip en modo icono
(dos superficies sobre el mismo ancla se pisan) — nuevo `useSidebarItemOr()`.
- El item envuelve (`flex-wrap`) para que el submenú caiga en su propia línea
en vez de ponerse al lado de la fila.
Demo: shell de app real (grupos, badge, acción, submenú, fila deshabilitada),
controles vivos de los tres props y las 9 pestañas del canon.
Verificado en navegador real (Playwright): dos landmarks nombrados en el
idioma activo · `aria-current="page"` en la fila activa · cada menú etiquetado
por SU grupo · raíl enfocable que alterna con Enter · colapso 256→48px ·
off-canvas por transform · submenú flotante anclado a su fila y Escape que
devuelve el foco · sema `emerge-expand/collapse` estampando en `panel` ·
móvil 600px = Drawer cerrado con el landmark dentro · RTL espeja el shell
entero · oscuro · 0 errores de consola.
Gates: `component:audit --only sidebar` PASS 0E/0W · eidos-lint 45
morfo-backed / 0 invalid / 0 class-hooks · `svelte-check` 0 errores propios ·
`vitest src/uix/eidos` 353/353 · `contracts.test` solo con fallos ajenos
(menubar, radio-group y las claves camelCase de aura).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
|
|
|
|
sidebarSema,
|
|
|
|
|
|
numberFieldSema,
|
|
|
|
|
|
paginationSema,
|
feat: build PasswordField (full stack)
Dedicated password input component — matches the Ark UI / Chakra v3 /
Mantine / PrimeReact / Ant Design pattern of treating PasswordField as
its own first-class component (not a TextField variant). Includes one
feature that NO surveyed library ships: a CapsLock indicator driven by
KeyboardEvent.getModifierState('CapsLock').
Anatomy (5 parts, 4 events):
- Provider (root, value + visibility state)
- Input (the textbox; type flips between password / text)
- VisibilityTrigger (eye toggle button; aria-pressed + aria-controls)
- CapsLockIndicator (status live region; data-active toggles via soma
listening to keydown/keyup on Input)
- StrengthMeter (composable; consumer provides 0-4 score; UIX bundles
no zxcvbn-style algorithm — dependency-free by design)
Events:
- commit-input (every keystroke)
- commit-submit (Enter)
- shift-toggle-visibility (eye click)
- shift-caps-state (Caps Lock state flips while focused)
Key behaviors:
- `purpose: 'current' | 'new'` drives native autocomplete attribute
('current-password' for login / 'new-password' for registration).
- Field integration: disabled/readonly/required/invalid OR-merged.
- VisibilityTrigger gets tabindex=-1 so it doesn't break the form's
natural tab order — mouse / programmatic focus only, matching Ark UI.
- Caps Lock indicator is aria-live="polite" — announces on activation
while focused, silent when inactive.
- Letter-spacing increased on the input for legibility while masked.
Reference library survey performed (10 libraries) before implementation —
all consensus around dedicated component, all have built-in toggle,
ZERO have caps lock warning. Documented in the demo's API tab with a
feature comparison table.
Demo follows DEMO_AUTHORING_GUIDE canonical 6-tab depth: Live (controls
grouped by layer + code snippets at the bottom), API (props + reference
comparison), Morfo (field/value + Parts + Events tables), Sema (events
table with ▶ play), Recipe (selectors with morfo/eidos owner tags), A11y
(concern/contract table).
Also includes external work in words/ from a separate session
(unrelated to PasswordField) — not touching Words is the standing rule,
but the diff was already in the working tree.
svelte-check: 0 errors in PasswordField files (Words errors are tracked
by its own development branch).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
passwordFieldSema,
|
|
|
|
|
|
popoverSema,
|
|
|
|
|
|
radioGroupSema,
|
|
|
|
|
|
ratingGroupSema,
|
|
|
|
|
|
searchFieldSema,
|
|
|
|
|
|
selectSema,
|
|
|
|
|
|
sliderSema,
|
|
|
|
|
|
splitterSema,
|
|
|
|
|
|
stepperSema,
|
|
|
|
|
|
tabsSema,
|
|
|
|
|
|
tagGroupSema,
|
|
|
|
|
|
tagsInputSema,
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
textareaSema,
|
|
|
|
|
|
timelineSema,
|
|
|
|
|
|
toastSema,
|
refactor(words)!: F1 — rework engine to base-Block model, drop v2 + sema
Per the user-directed rework. The engine is rebuilt around a single
base `Block` carrying the common properties (id, align, margin,
padding, background, text color, border), with each specialized block
(paragraph/heading/quote/code/list/table/image/divider/callout — plus
list-item/table-row/table-cell) EXTENDING it. The old `visual` sidecar
+ per-type `Pick<>` whitelist + loose `textAlign` are gone; common
props are first-class and universal.
Naming: dropped the `v2` noise everywhere — `operations-v2/`→
`operations/`, `types-v2`/`render-v2`/`validate-v2`/`serialize-*-v2`→
clean names, `*V2` symbols→bare, `WordsEvalIntent`→`WordsIntent`.
Sema: removed entirely from the editor — deleted `sema/components/
words.ts` + `engine/sema-parity`, dropped the registration from the
sema barrel + the demo layout, no `runtime.trigger`/semantic events.
Visual layer: deleted `eidos/components/words/*` (the bespoke chrome)
and stubbed the demo — both rebuilt next on the new model (F2 render
by components, F3 gutters/bubble/drawer, all eidos).
Engine tests 400/400 green; `npm run check` 0 errors (5142 files).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 months ago
|
|
|
|
toolbarSema
|
|
|
|
|
|
]
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
setActiveUix(uix);
|
|
|
|
|
|
Soma.create();
|
|
|
|
|
|
const prefsProjection = createActivePrefsDomProjection({ prefs: uix.prefs, dom: uix.dom });
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
|
|
|
|
|
|
type Section =
|
|
|
|
|
|
| { kind: 'top'; slug: string; label: string }
|
|
|
|
|
|
| { kind: 'group'; heading: string; items: { slug: string; label: string; tag?: string }[] };
|
|
|
|
|
|
|
|
|
|
|
|
// Information architecture — single source of truth for sidebar +
|
|
|
|
|
|
// breadcrumb. Each leaf maps to a route under `/uix/...`.
|
|
|
|
|
|
const nav: Section[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Get started',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix', label: 'Overview' },
|
|
|
|
|
|
{ slug: '/uix/architecture', label: 'Architecture' },
|
|
|
|
|
|
{ slug: '/uix/getting-started', label: 'Installation' }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Foundations',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/tokens', label: 'Design tokens' },
|
|
|
|
|
|
{ slug: '/uix/morfo', label: 'Morfo · contracts' },
|
|
|
|
|
|
{ slug: '/uix/sema', label: 'Sema · perception' },
|
|
|
|
|
|
{ slug: '/uix/eidos', label: 'Eidos · visual layer' }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Controls',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/toggle', label: 'Toggle' },
|
|
|
|
|
|
{ slug: '/uix/components/toggle-group', label: 'Toggle group' },
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/switch', label: 'Switch' },
|
|
|
|
|
|
{ slug: '/uix/components/checkbox', label: 'Checkbox' },
|
|
|
|
|
|
{ slug: '/uix/components/radio-group', label: 'Radio group' },
|
feat(uix): RadioCards — card-style single-select reusing RadioGroup
New eidos component built ON TOP of RadioGroup with zero duplicated
behaviour. RadioCards reuses RadioGroup's soma wholesale (selection,
roving focus, role=radio, native <form> via HiddenInput) and adds only
the card chrome: icon · title · description + an always-present corner
radio. Vertical, horizontal and grid layouts.
- morfo: scope:['eidos'], thin contract for presentation parts only
(Provider marker, Item-card, Indicator, Icon, Content, Title,
Description). The interactive contract + commit-select stay in
radio-group, reused via its soma. No new soma, no new sema.
- eidos: `radio-cards` recipe (card chrome) + wrappers + radio-cards.css.
radio-group.css is NOT loaded here, only its foundation tokens — the
card owns its visual, reusing --_radio-group-palette-* (inlined, since a
:root token referencing the palette is invalid-at-computed-value).
- demo: canonical structure (always-on stage + trace, tabs, chip/switch
controls, Untitled-UI example patterns) + nav entry + README.
check 0 · eidos-lint 0 invalid. Browser-verified: select (click + keyboard
roving), disabled, the three layouts, controls drive the preview.
Follow-up: icon/circle sizes are still px (mirroring radio-group's own size
tokens) — making the control-size scale density-aware is a separate,
family-wide change deferred per request.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
{ slug: '/uix/components/radio-cards', label: 'Radio cards' },
|
|
|
|
|
|
{ slug: '/uix/components/rating-group', label: 'Rating group' },
|
|
|
|
|
|
{ slug: '/uix/components/slider', label: 'Slider' },
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/collapsible', label: 'Collapsible' },
|
|
|
|
|
|
{ slug: '/uix/components/accordion', label: 'Accordion' },
|
|
|
|
|
|
{ slug: '/uix/components/tabs', label: 'Tabs' },
|
|
|
|
|
|
{ slug: '/uix/components/toolbar', label: 'Toolbar' },
|
|
|
|
|
|
{ slug: '/uix/components/button', label: 'Button' },
|
|
|
|
|
|
{ slug: '/uix/components/button-group', label: 'Button group' },
|
|
|
|
|
|
{ slug: '/uix/components/split-button', label: 'Split button' },
|
|
|
|
|
|
{ slug: '/uix/components/fab', label: 'Fab' }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Forms',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/form', label: 'Form' },
|
|
|
|
|
|
{ slug: '/uix/components/field', label: 'Field' },
|
|
|
|
|
|
{ slug: '/uix/components/field-langs', label: 'Field langs' },
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/label', label: 'Label' },
|
|
|
|
|
|
{ slug: '/uix/components/editable', label: 'Editable' },
|
palabras: retirar el chrome words deprecado (FW)
Decision de usuario 2026-07-14: words (chrome eidos + demo) quedo
deprecado en pos de palabras; existia como referencia historica.
- Migradas las 4 piezas que palabras importaba (git mv, historia
conservada, sin shims): words-activate -> palabras-activate,
words-block-drag -> palabras-block-drag, words-block-drag-type ->
palabras-block-drag-type, words-image-file -> palabras-image-file;
imports actualizados a rutas locales.
- Borrados src/uix/eidos/components/words/** (wrapper, menubar, bubble,
inspector, gutter, rail, words.css, langs-menu/inspector, AUDIT
visual) y la demo web/routes/uix/components/words/.
- Sidebar: fuera el link Words, entra Palabras (la demo era
inalcanzable desde la nav).
- Podado el bloque `words:` de lib/recipes/base.ts + regeneracion
(generated/base.css: -84 lineas, solo bajas --words-*).
- Docs del track: referencias al AUDIT visual de words apuntan a git
history.
NO muere: soma/components/words (motor + provider + tests), morfo y
langs de words — el fundamento vivo de palabras.
Verificacion: engine 493/493 - guards eidos (recipe-css-contract +
api-contract + visual-attrs) 35/35 - grep eidos/components/words en
codigo = 0 - navegador (server propio): demo palabras monta sin
errores de consola, activate fija bloque, grip abre panel (tabs +
pills H1-H6/HC + texto/enlace).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/palabras', label: 'Palabras' },
|
|
|
|
|
|
{ slug: '/uix/components/number-field', label: 'Number field' },
|
|
|
|
|
|
{ slug: '/uix/components/css-field', label: 'CSS field' },
|
|
|
|
|
|
{ slug: '/uix/components/search-field', label: 'Search field' },
|
feat: build PasswordField (full stack)
Dedicated password input component — matches the Ark UI / Chakra v3 /
Mantine / PrimeReact / Ant Design pattern of treating PasswordField as
its own first-class component (not a TextField variant). Includes one
feature that NO surveyed library ships: a CapsLock indicator driven by
KeyboardEvent.getModifierState('CapsLock').
Anatomy (5 parts, 4 events):
- Provider (root, value + visibility state)
- Input (the textbox; type flips between password / text)
- VisibilityTrigger (eye toggle button; aria-pressed + aria-controls)
- CapsLockIndicator (status live region; data-active toggles via soma
listening to keydown/keyup on Input)
- StrengthMeter (composable; consumer provides 0-4 score; UIX bundles
no zxcvbn-style algorithm — dependency-free by design)
Events:
- commit-input (every keystroke)
- commit-submit (Enter)
- shift-toggle-visibility (eye click)
- shift-caps-state (Caps Lock state flips while focused)
Key behaviors:
- `purpose: 'current' | 'new'` drives native autocomplete attribute
('current-password' for login / 'new-password' for registration).
- Field integration: disabled/readonly/required/invalid OR-merged.
- VisibilityTrigger gets tabindex=-1 so it doesn't break the form's
natural tab order — mouse / programmatic focus only, matching Ark UI.
- Caps Lock indicator is aria-live="polite" — announces on activation
while focused, silent when inactive.
- Letter-spacing increased on the input for legibility while masked.
Reference library survey performed (10 libraries) before implementation —
all consensus around dedicated component, all have built-in toggle,
ZERO have caps lock warning. Documented in the demo's API tab with a
feature comparison table.
Demo follows DEMO_AUTHORING_GUIDE canonical 6-tab depth: Live (controls
grouped by layer + code snippets at the bottom), API (props + reference
comparison), Morfo (field/value + Parts + Events tables), Sema (events
table with ▶ play), Recipe (selectors with morfo/eidos owner tags), A11y
(concern/contract table).
Also includes external work in words/ from a separate session
(unrelated to PasswordField) — not touching Words is the standing rule,
but the diff was already in the working tree.
svelte-check: 0 errors in PasswordField files (Words errors are tracked
by its own development branch).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/password-field', label: 'Password field' },
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/mask-field', label: 'Mask field' },
|
|
|
|
|
|
{ slug: '/uix/components/prose', label: 'Prose' },
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/textarea', label: 'Text area' },
|
|
|
|
|
|
{ slug: '/uix/components/select', label: 'Select' },
|
|
|
|
|
|
{ slug: '/uix/components/combobox', label: 'Combobox' },
|
feat(eidos): port Listbox (embedded selection list)
#131. Eidos wrapper + types + recipe + canonical-depth demo. Soma owns
single/multi selection (value as string[]), roving-tabindex keyboard
nav (Arrow + Home/End + typeahead + Ctrl+A), Field-merged flags
(disabled/readonly/required/invalid), hidden form inputs. Eidos adds
the visual surface and exposes variant + size + color.
Reference parity (no air baseline — port directly from soma):
| Feature | soma | react-aria | Headless UI | bits-ui | this port |
|---|---|---|---|---|---|
| Single + multiple selection | ✓ | ✓ | ✓ | ✓ | ✓ |
| bind:value (controlled) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Typeahead + Arrow / Home / End | ✓ | ✓ | ✓ | ✓ | ✓ |
| Loop nav | ✓ | ✗ | ✗ | ✗ | ✓ |
| Section / Group + label | ✓ | ✓ | ✗ | ✓ | ✓ |
| Ctrl+A select-all (multi) | ✓ | ✓ | ✗ | ✗ | ✓ |
| Form participation (hidden inputs) | ✓ | ✗ | ✓ | ✗ | ✓ |
| Field.Provider merge (disabled/invalid/…) | ✓ | ✗ | ✗ | ✗ | ✓ |
| Horizontal orientation | ✓ | ✓ | ✓ | ✓ | ✓ |
| Item indicator (✓ glyph) | ✓ | ✓ | ✗ | ✓ | ✓ shared partial |
| Drag-to-reorder | ✗ | ✓ | ✗ | ✗ | ⚠ deferred |
| Async / infinite loading | ✗ | ✓ | ✗ | ✗ | ⚠ deferred |
| selectionBehavior (toggle/replace) | ⚠ implicit | ✓ | ✗ | ✓ | ⚠ deferred |
| PageUp/Down nav | ✗ | ✓ | ✗ | ✗ | ⚠ deferred |
Parts (5): Listbox (Root, replaces soma's Provider name), Item,
ItemIndicator, Group, GroupLabel.
Variant set:
- variant: ControlVariant (`'surface' | 'outline' | 'ghost'`), default 'surface'
- size: xs..xl (5-step canonical form-control scale)
- color: ColorRole (primary/secondary/neutral/affirm/fulfill/risk/threat/loss)
- block: stretch to container width
Cross-component reuse:
- `ItemIndicator` shares the menu-indicator visual (`a2709476`) — ✓ glyph
identical to standalone Checkbox and Dropdown/Context Menu
CheckboxItems. CSS-only difference: shown only inside
`[data-listbox-item][data-selected]`.
- Item row hover / highlight tokens mirror Combobox.Item /
Command.Item — the form-control surface family stays coherent.
Disambiguation note (in index.ts comment):
- Listbox: atomic options, text rows, no inner interactive elements
(ARIA forbids interactive descendants inside role="listbox")
- GridList: rows with buttons / links / checkboxes inside (2D nav)
- Select / Combobox: closed picker surface (Listbox-like dropdown)
Gotcha: listbox.svelte and listbox-item.svelte rename `children` to
`bodyContent` on destructure to avoid shadowing the inner
`{#snippet children}` block (same recursion trap documented in
`feedback_button_consumer_pattern.md` Rule 3).
Demo: 6 tabs at canonical depth — Live wires all soma + eidos props,
all 3 ControlVariant chips, 5 size chips, 8 ColorRole chips, single +
multi mode toggle, RTL/horizontal toggle. Sidebar entry added under
Forms (between Combobox and Calendar).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/listbox', label: 'Listbox' },
|
feat(eidos): port GridList (selectable list w/ interactive row children)
Closes #133. Eidos wrapper + types + recipe + canonical-depth demo.
4 parts: Provider, Row, Cell, SelectionCheckbox. Soma owns selection
(none/single/multiple), 2D keyboard nav (Up/Down rows + Left/Right
cells), Shift/Ctrl range/toggle, Ctrl+A select-all, Escape-clear,
typeahead, hidden form input, Field merge. Eidos adds variant + size +
color + defaultValue (uncontrolled init).
Reference parity (no air baseline):
| Feature | soma | react-aria GridList | this port |
|---|---|---|---|
| selectionMode none/single/multiple | ✓ | ✓ | ✓ |
| bind:value (controlled) | ✓ | ✓ | ✓ |
| defaultValue (uncontrolled init) | ✗ | ✓ | ✓ added (parity with Combobox/Select) |
| Item with interactive descendants | ✓ | ✓ | ✓ |
| 2D keyboard nav (Up/Down rows, L/R cells) | ✓ | ✓ | ✓ |
| Shift/Ctrl range/toggle | ✓ | ✓ | ✓ |
| Ctrl+A select-all (multiple) | ✓ | ✓ | ✓ |
| Escape-clear | ✓ | ✓ | ✓ |
| Typeahead | ✓ | ✓ | ✓ |
| ARIA grid/row/gridcell | ✓ | ✓ | ✓ |
| Field merge (disabled/invalid/required/readonly) | ✓ | ✗ | ✓ |
| Form participation (hidden input) | ✓ | ✗ | ✓ |
| Drag-to-reorder | ✗ | ✓ | ⚠ deferred (compose w/ future DragDrop) |
| onAction (row click → navigate) | ✗ | ✓ | ⚠ deferred (use button/link inside Cell) |
| selectionBehavior toggle/replace | ✗ implicit | ✓ | ⚠ deferred |
| disabledBehavior 'selection'/'all' | ✗ skip-only | ✓ | ⚠ deferred |
| Async / infinite loading | ✗ | ✓ | ⚠ deferred |
| Empty state slot | ✗ | ✓ | ⚠ document `data-empty` styling |
Naming: keeps soma's part names (Provider, Row, Cell, SelectionCheckbox).
react-aria's "GridListItem" maps to `Row`; soma's vocabulary is more
precise and consistent with future Table / TreeGrid in the same family.
Variant set:
- variant: ControlVariant (surface/outline/ghost), default 'surface'
- size: xs..xl (5-step, mirrors Combobox/Listbox)
- color: ColorRole (primary/secondary/neutral/affirm/fulfill/risk/threat/loss)
- block: stretch to container width
Disambiguation (in index.ts comment): use GridList for rows with
interactive children; use Listbox for atomic text options (ARIA
forbids interactive descendants inside role="listbox"); use
Select/Combobox for closed-picker patterns; use Table for tabular
data with columns + sort.
Visual reuse:
- SelectionCheckbox uses the same `mask-image: url(svg-check)` pattern
as the shared menu-indicator partial (commit a2709476). Filled
accent box → white ✓ on `[data-state='checked']`.
- Row hover/highlight tokens mirror Combobox.Item / Listbox.Item so
the form-control surface family stays coherent.
- Same `max-block-size: min(60vh, 22rem) + overflow-y: auto` scroll
contract as Listbox (commit 830025b4).
Sidebar entry under Forms (between Listbox and Calendar).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/grid-list', label: 'Grid list' },
|
|
|
|
|
|
{ slug: '/uix/components/calendar', label: 'Calendar' },
|
feat(eidos): port range-calendar from soma + extract shared partial
Standalone eidos `<RangeCalendar>` wrapper over the soma range-calendar
primitive. Adds size / variant / color cascades; otherwise pass-through
14 compound parts (Provider, Header, Heading, PrevButton, NextButton,
MonthSelect, YearSelect, Grid, GridHead, GridBody, GridRow, HeadCell,
Cell, Day).
## Feature comparison
| Feature | bits-ui | ark-ui | react-aria | Eidos |
|----------------------|---------|--------|------------|-------|
| Range start/end | ✓ | ✓ | ✓ | ✓ |
| Hover preview state | ✓ | ✓ | ✓ | ✓ |
| minDays / maxDays | — | — | ✓ | ✓ |
| allowSingleDay | ✓ | ✓ | ✓ | ✓ |
| preventDeselect | ✓ | ✓ | — | ✓ |
| Multi-month display | ✓ | ✓ | ✓ | ✓ |
| Week-number column | — | — | ✓ | ✓ |
| Month/Year selects | — | ✓ | — | ✓ |
| Disabled / readonly | ✓ | ✓ | ✓ | ✓ |
| isDateUnavailable | ✓ | ✓ | ✓ | ✓ |
| Holiday markers | — | — | — | ✓ |
| Locale / dir | ✓ | ✓ | ✓ | ✓ |
| Size cascade | — | — | — | ✓ 4 |
| Variant cascade | — | — | — | ✓ 3 |
| Color cascade | — | — | — | ✓ 8 |
## Range-cells partial extracted
The recipe at `src/uix/eidos/components/range-calendar/range-calendar.css`
now owns ALL `[data-range-calendar-*]` selectors — the shared rules
that previously lived inside `date-range-picker.css` (lines 537-834)
moved here. Both consumers (the standalone `<RangeCalendar>` and
`<DateRangePicker>`'s popover content) stamp the same data-attrs, so the
same selectors paint without duplication.
`date-range-picker.css` drops 298 lines of duplication; it keeps only
the picker-specific scope overrides (`[data-date-range-picker-calendar]`
with no chrome, max-content sizing, transparent bg).
## Morfo
Extended `rangeCalendarMorfo.scope` to include `'eidos'` so the new
wrapper appears in the eidos-layer inventory and the demo Morfo tab
declares it correctly.
## Demo
Canonical 6-tab depth (~600L) at `/uix/components/range-calendar`. Live
tab exposes every range-specific prop: minDays / maxDays sliders,
allowSingleDay, preventDeselect, numberOfMonths chips (1 / 2 / 3),
pagedNavigation, fixedWeeks, showWeekNumbers, disableDaysOutsideMonth,
weekStartsOn, disabled, readonly, locale, plus size / variant / color
cascades.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/range-calendar', label: 'Range calendar' },
|
feat(month-grid, year-grid): standalone primitives parallel to date-picker views
DatePicker.MonthView / YearView require a DatePickerProvider context and
can't be used standalone. This commit introduces MonthGrid and YearGrid
as independent primitives that accept value / placeholder / minValue /
maxValue as props and work anywhere.
morfo
- New morfo/components/month-grid.ts and year-grid.ts.
- scope: ['soma','sema'], apg: grid pattern.
- 7 parts each: Provider (role=application) / Header / Heading /
PrevButton / NextButton / Grid (role=grid) / Cell (role=gridcell).
- Events: commit-set (cell click) + nav-step (prev/next).
- Cell data-attrs: data-value, data-selected, data-current, data-disabled,
data-focused.
- Keyboard map covers arrows / Home / End / PageUp/Down / Enter / Space.
soma
- New soma/components/{month-grid,year-grid}/ with provider class +
langs + types + exports + 7 thin svelte wrappers each.
- MonthGridProvider: 12-cell grid keyed to placeholder.year; localized
month names via Intl.DateTimeFormat with configurable monthFormat
('long'|'short'|'narrow'). Prev/Next step ±1 year.
- YearGridProvider: decadeSize-cell grid (default 12); page anchored at
placeholder.year - (placeholder.year % decadeSize). Prev/Next step ±
decadeSize.
- Both expose Cell sub-provider with snippetProps {selected, disabled,
current, value, label} + roving tabindex + RTL-aware keyboard nav.
eidos
- New eidos/components/{month-grid,year-grid}/ — namespace-style index
with size / variant / color visual props + dedicated CSS reusing the
--calendar-* token family.
- Each grid renders Header (Prev/Heading/Next) + 3-col Grid.
demo
- New /uix/components/month-grid and /uix/components/year-grid demo
pages with the standard live/api/morfo/sema/recipe/a11y tabs,
interactive controls for every public prop, soma+eidos snippets that
reactively rebuild from controls, and sema event play buttons.
Verified: svelte-check --threshold error -> 0 errors / 0 warnings /
4572 files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/month-grid', label: 'Month grid' },
|
|
|
|
|
|
{ slug: '/uix/components/year-grid', label: 'Year grid' },
|
|
|
|
|
|
{ slug: '/uix/components/date-field', label: 'Date field' },
|
|
|
|
|
|
{ slug: '/uix/components/date-range-field', label: 'Date range field' },
|
uix: date-picker + date-range-picker components + component audit infra
Two new Eidos components shipped end-to-end (wrapper + recipe + demo +
Soma provider hardening) plus a checklist-driven audit pipeline that
scores all 67 morfo components against doctrinal completion criteria.
New components:
- date-picker: full popover-anchored picker over date-field + calendar,
with calendar/content/trigger parts and demo route.
- date-range-picker: standalone wrapper with own calendar/grid/segment
surface, demo route, and recipe CSS.
- Both wrappers follow Option C disciplined (root + parts attached via
explicit assignment, no Object.assign).
Supporting Soma changes:
- range-calendar provider tightened (211 LOC of behavior, 167 LOC of
tests), README brought up to component doctrine.
- date-field, date-picker, date-range-field, date-range-picker Soma
providers + READMEs updated for new wrappers.
- popover provider/close gain props needed by the picker wrappers.
Morfo updates:
- date-picker / date-range-picker / range-calendar morfos refined for
the new APIs (parts, events, ARIA).
Audit infrastructure (new):
- src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across
morfo / eidos wrapper / recipe CSS / demo / README / cross-layer
scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION
and DEMO_AUTHORING_GUIDE.
- scripts/component-audit.ts + `npm run component:audit` — regex parser
over all 67 components, emits tmp/component-audit.md with summary
scoreboard + per-component findings. Validates against canonical
SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS.
- Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip,
date-range-picker). Top systemic gaps: translations.label (49),
README Gaps/Comparativa/Baseline sections (87 combined), keyboard
/event ratio under-declaration (15), apg URL absent (19).
Misc:
- src/uix/kimi-audit-eidos.md — supplementary audit notes.
- .gitignore: ignore .codex-* agent scratch artifacts at repo root.
- continue.md + READMEs updated through the migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/date-picker', label: 'Date picker' },
|
|
|
|
|
|
{ slug: '/uix/components/date-range-picker', label: 'Date range picker' },
|
|
|
|
|
|
{ slug: '/uix/components/time-field', label: 'Time field' },
|
|
|
|
|
|
{ slug: '/uix/components/time-range-field', label: 'Time range field' },
|
feat(eidos): add TimePicker wrapper + demo following P-1..P-5 picker contract
Builds on the existing soma TimePicker slider-based clock (HourSlider /
MinuteSlider / SecondSlider + DayPeriodToggle). Adds the canonical
picker shell:
- mode='inline' | 'modal' on the Provider, propagated to popover.modal
- Provider helpers commit() / cancel() / clear() with watch(open)
snapshot for cancel-revert
- Footer composition (TimePicker.Footer / Clear / Cancel / Close as
pure-composition Eidos parts; no *Button root props)
- New TimePicker.Clock soma component that carries the
data-time-picker-clock contract attr, wraps the slider stack
- Eidos shell: Provider visual root, Trigger (clock icon), Content
(popover content), Clock, Footer + action parts, slider/toggle
pass-throughs
Renews the time-picker morfo to declare Provider / Trigger / Clock /
DayPeriodToggle / DayPeriodItem / Footer / Clear / Cancel / Close,
plus all 6 commit/emerge events (open + close-commit/cancel/dismiss/
dismiss-outside + commit-clear). apg=dialog-modal.
Demo at /uix/components/time-picker exercises all controls, Footer
composition switches, soma + eidos code snippets, morfo / sema / recipe
/ a11y tabs. README documents the picker contract.
67/67 component-audit PASS, 39/39 morfo:check PASS, svelte-check
0 errors / 0 warnings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/time-picker', label: 'Time picker' },
|
|
|
|
|
|
{ slug: '/uix/components/time-range-picker', label: 'Time range picker' },
|
|
|
|
|
|
{ slug: '/uix/components/color-field', label: 'Color field' },
|
feat(eidos): add ColorPicker wrapper + demo
Composite popover: 2D saturation/brightness area, hue + alpha channel
sliders, preset swatches, eye-dropper, and a segmented channel input
composed from ColorField. Builds on the existing soma color-picker
(23 parts) — eidos layer is mostly thin pass-throughs adding visual
chrome.
What landed
-----------
- New `src/uix/eidos/components/color-picker/`:
- Root visual (Provider) + visual-context (size/variant/color)
- Trigger with a default swatch dot tinted from
`--cp-trigger-color` (the air pattern from morfo-runtime)
- Content (popover wrapper), Area (+ Background + Thumb),
TransparencyGrid
- ChannelSlider (+ Track + Thumb) — generic per-channel slider;
default-composes Track+Thumb when no children
- SwatchGroup + SwatchTrigger + Swatch + SwatchIndicator
- EyeDropper (Pipette icon by default)
- ChannelInput + ChannelSegment + FormatSelect (composed from
ColorField parts; same provider injected automatically)
- Label, Control, ValueSwatch, ValueText, HiddenInput
- Recipe section `color-picker` in `recipes/base.ts` (regenerated
`generated/base.css`) — trigger, content, area, channel slider,
swatches, eye-dropper tokens.
- CSS reuses color-field tokens for the segmented input portion and
adds picker-specific visuals. Transparency checker on trigger swatch
+ value swatch + alpha slider track via conic-gradient pattern.
- Morfo updates: scope `['soma','sema']`, `apg: dialog-modal`, added
`commit-set` event so audit classifies it as interactive.
- Soma exports: ColorPickerProvider class so eidos Trigger can read
the current value for the swatch tint.
- Demo at `/uix/components/color-picker` with the standard 6 tabs;
live stage exercises area drag + channel sliders + preset swatches
+ eye-dropper + format switch.
- README documents the surface, comparativa vs air/Ark/Chakra, and
flags the picker contract (mode/Footer/commit/cancel) as gap to
align with date/time-picker in a follow-up.
Checks
------
- 67/67 component-audit PASS
- 40/40 morfo:check PASS (new color-picker demo validates against
morfo DOM)
- svelte-check 0 errors / 0 warnings
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/color-picker', label: 'Color picker' },
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/picker', label: 'Picker (deferValue)' },
|
|
|
|
|
|
{ slug: '/uix/components/natural-time-picker', label: 'Natural time picker' },
|
|
|
|
|
|
{ slug: '/uix/components/stepper', label: 'Stepper' },
|
|
|
|
|
|
{ slug: '/uix/components/tag-group', label: 'Tag group' },
|
|
|
|
|
|
{ slug: '/uix/components/tags-input', label: 'Tags input' },
|
feat(pin-input): port from soma to eidos (Tier 1 sprint, 5/5 — DONE)
Multi-cell OTP / verification code input. Two parts (Provider, Cell)
with a snippet-driven cell iteration.
Architecture:
- A transparent absolutely-positioned <input> captures every
keystroke, paste and IME event (soma).
- Visible bordered cells follow the hidden input's caret via
data-active / data-filled emitted by the morfo.
- Single-input approach (shadcn / Bits family) — preserves paste
distribution, autocomplete='one-time-code' for SMS autofill on
iOS/Android, and IME quality.
Eidos surface:
- size: 'sm' | 'md' | 'lg' | 'xl' (responsive), cascades cell
dimension + glyph size tokens to all cells
- Recipe paints square bordered cells with focus ring tracking
data-active, subtle bg lift on data-filled, threat-toned border
when [data-invalid] cascades from the provider
Morfo:
- scope: ['soma'] → ['soma', 'sema', 'eidos']
- apg URL added (Textbox pattern — OTP has no formal ARIA pattern)
- Passive at the morfo layer (no events array; perceptual feedback
via the commit family base when onComplete fires)
- README documents the passive classification
Comparativa: aligned with shadcn / Bits UI (single hidden input).
Ark and Chakra use one input per cell which loses paste / IME
quality.
Sidebar nav: 'Pin input' added under Forms (next to Tags input).
=== Sprint Tier 1 — DONE ===
1. toggle-group 61ffbade
2. alert-dialog d5630a52
3. dropdown-menu 4e477e63
4. context-menu 21eb8a62
5. pin-input (this)
Checks: svelte-check 0 errors, component:audit 91/91 PASS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/pin-input', label: 'Pin input' },
|
|
|
|
|
|
{ slug: '/uix/components/file-upload', label: 'File upload' }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Navigation',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/anchor-nav', label: 'Anchor nav' },
|
|
|
|
|
|
{ slug: '/uix/components/breadcrumb', label: 'Breadcrumb' },
|
feat(eidos): port NavigationMenu (top-level site navigation w/ mega-menus)
#132. Eidos wrapper + types + recipe + canonical-depth demo. 7 parts:
Provider, List, Item, Trigger, Content, Link, Indicator. Soma owns
active-item state, hover delays (openDelay/skipDelayDuration/closeDelay),
hoverEnabled gate, loop arrow nav, data-motion directional swap,
Indicator rect CSS vars. Eidos paints the bar + trigger chrome +
Content panel + slide animations.
Reference parity (no air baseline — port directly from soma):
| Feature | soma | Radix | bits-ui | this port |
|---|---|---|---|---|
| Provider + List + Item + Trigger + Content + Link + Indicator | ✓ | ✓ | ✓ | ✓ |
| Hover open (openDelay/skipDelayDuration/closeDelay) | ✓ | ✓ | ✓ | ✓ |
| hoverEnabled (click-only mode) | ✓ | ⚠ | ✓ | ✓ |
| orientation horizontal + vertical | ✓ | ✓ | ⚠ | ✓ |
| dir / RTL | ✓ | ✓ | ✓ | ✓ |
| Indicator CSS vars (x/y/w/h rect) | ✓ | ✗ | ✗ | ✓ |
| data-motion directional swap (from-/to-start/end) | ✓ | ✓ | ⚠ | ✓ |
| forceMount on Content + Indicator | ✓ | ✓ | ✓ | ✓ |
| ARIA <nav> + translated aria-label | ✓ | ⚠ | ⚠ | ✓ |
| Keyboard nav (Arrow/Home/End/Enter/Space/Esc, ArrowDown → Content) | ✓ | ✓ | ✓ | ✓ |
| Sub (nested viewports) | ✗ | ✓ | ✓ | ⚠ deferred (matches soma) |
| Viewport (shared swap pane) | ✗ | ✓ | ✓ | ⚠ deferred |
| Modal variant (focus trap) | ✗ | ✓ | ✗ | ⚠ deferred |
| SafePolygon hover bridge | ✗ | ✗ | ✗ | ⚠ deferred |
Naming: matches soma's part names exactly. Both Trigger (button) and
Link (anchor) stay native — NOT routed through <Button> — because
top-nav has flat/borderless chrome distinct from action buttons. The
Link automatically picks up `aria-current="page"` styling for the
active route.
Variant set: only `size: 'sm' | 'md' | 'lg'` (no xs/xl). No
variant/color — NavigationMenu is chrome surface, not actionable
intent.
Fresh recipe — does NOT reuse dropdown-menu (floating click-driven)
or menubar (roving tabindex bar). NavigationMenu lives inline in the
page; per-item Content panels render via Floating but conceptually
attach to the bar. Indicator is a 2px underline that slides via CSS
vars (--navigation-menu-indicator-{x,y,w,h}) written by soma. Trigger
chevron rotates on [data-state='open']. Content animates via
data-motion directional slide on sibling swap.
Sidebar entry added under Navigation (between Pagination and a future
NavigationMenu entry).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/pagination', label: 'Pagination' },
|
uix(nav-tree): F1.8 CERRADA · demo + navegador + review adversarial
Cierra el árbol de navegación data-driven (E-1) de F1: demo canónica de 9
pestañas con el mapa real de docs (43 nodos, 3 niveles), verificación en
navegador real y review adversarial (5 dimensiones × 3 verificadores
escépticos; 22 hallazgos brutos, 10 confirmados) con todos los confirmados
arreglados.
Arreglos del review
- sema: la parte `group` —target de los eventos emerge— se registraba SIN
`ref`, así que `runtime.trigger` lanzaba `SomaRuntimeTargetError` en
silencio y el pack no sonaba nunca (cero `data-event-*` en el grupo frente
a los de collapsible). El provider posee ahora el ref del `<ul>`.
- eidos: en una fila navegable el chevron resolvía `inline-size: 100%` como
flex-basis y ocupaba media fila (101 de 231 px en «Soma»), robándole clics
al enlace. Toggle compacto con suelo de diana de 24 px (WCAG 2.5.8).
- soma: una clave duplicada podía volver cíclico `parentByKey` y colgar la
pestaña dentro de `trailKeys` (deriva en render) → clave sufijada + aviso
del logger + guarda de ciclo en el paseo.
- soma: el colapso es CONTEXTUAL (recuerda el `activeKey` bajo el que se
hizo): cerrar la sección que lees se respeta, pero caduca al navegar
DENTRO del grupo, para que la página actual nunca quede sin fila visible.
Sigue siendo query pura, sin `$effect` que escriba estado.
- soma: `child` recibe también `children` (el árbol renderizado); antes
dejaba el landmark vacío, porque un árbol data-driven no lo puede
reautorar el consumidor.
- morfo + langs: el nombre accesible del chevron se declara en el contrato y
se localiza («Alternar sección {label}»); ya no duplica el del enlace.
- eidos: RTL completo — el glyph espeja solo (bordes lógicos), lo que no
espeja es el giro, así que bajo `[dir='rtl']` las dos rotaciones se
intercambian. El Gap «dirección del chevron en RTL» queda RESUELTO.
- demo: paridad de snippet con los controles vivos; fuera el token fantasma
`--nav-tree-rail-width` del docblock del recipe.
badge en v1 (decisión del usuario, delegada)
Está en el suelo de paridad del dossier §P5 (los 6 refs lo llevan). Se
resuelve con SNIPPET, no con recursión a nivel de eidos: el morfo declara la
parte `badge`, soma renderiza el snippet recibido (sin él, el valor crudo —
sigue siendo headless) y el wrapper de eidos pasa el `Badge` canónico. Va
DENTRO del control de la fila, así su texto entra en el nombre accesible
(«TSC, New, enlace»). `disabled` se descarta en v1 (fuera del suelo, y un
enlace de navegación deshabilitado es semánticamente dudoso); ambos quedan
registrados en la tabla de Gaps.
Verificado: `component:audit` PASS · eidos-lint 26 morfo-backed / 0 invalid ·
`svelte-check` 0 errores en estos archivos · `vitest src/uix/eidos` 353/353 ·
navegador real (Playwright): trail auto-expandido, sema estampando en el
grupo, teclado nativo, foco visible, claro y oscuro, RTL, 375 px sin
desbordes, 0 errores de consola.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/navigation-menu', label: 'Navigation menu' },
|
uix(sidebar): F1.7 eidos + demo · raíl, modo icono y submenú flotante
Segunda tanda del sidebar: la capa visual, la demo canónica de 9 pestañas y
la verificación en navegador real. Con esto el componente está vivo; queda el
review adversarial.
Eidos
- Recipe con los dos ejes: off-canvas por `transform` (trabajo de compositor,
el inset no reflowea) y `width` animado SOLO en modo icono, donde el inset
sí tiene que seguir al raíl. El raíl NO lleva `will-change` (una franja
fina tiembla a DPR fraccionario — memoria NavMenu).
- Anchos como TOKENS: `--sidebar-width` 16rem · `--sidebar-width-icon` 3rem ·
`--sidebar-width-mobile` 18rem, más raíl, gaps, altura de fila y colores.
- Tres composiciones que la capa headless no puede hacer: `Drawer` para la
presentación móvil, `Tooltip` para nombrar filas en modo icono y `Badge`
para los contadores. El trigger compone `Button` por el patrón `child`.
- Convención de icono documentada: sobrevive el PRIMER elemento de la fila.
Arreglos que destapó el navegador
- **`mobile` en SSR**: sin viewport, `isAtLeast` responde «por debajo de todo»
→ el HTML salía con `data-mobile` y la hidratación NO lo corrige (no diffea
atributos y el valor ya no cambia). Viewport desconocido = ESCRITORIO.
- **Estado móvil propio** (arranca cerrado): en escritorio `open` es
preferencia de layout persistida; en móvil sería un overlay tapando la
página, que jamás puede ser el estado inicial. `onOpenChange` solo se
dispara con el estado de escritorio.
- **`open` controlado/no controlado**: se adopta el patrón de la casa
(`$bindable` con default, el provider escribe siempre) — mi versión previa
con estado interno no propagaba `bind:open`.
- **El submenú flotante no se posicionaba**: `FloatingAnchor` resuelve su
provider por CONTEXTO y el eidos envuelve la fila en un `Tooltip`, que
publica el suyo → el ancla caía en el tooltip y el submenú se quedaba en
`translate(0,-200%)`. Ahora el ancla se cablea directamente al provider
flotante del item. Además el `<ul>` ya no se posiciona a sí mismo (colapsaba
el wrapper a tamaño cero) y toma elevación del plano `overlay` por
`data-depth`, como cualquier panel flotante del ecosistema.
- **Tooltip vs submenú**: una fila con submenú no lleva tooltip en modo icono
(dos superficies sobre el mismo ancla se pisan) — nuevo `useSidebarItemOr()`.
- El item envuelve (`flex-wrap`) para que el submenú caiga en su propia línea
en vez de ponerse al lado de la fila.
Demo: shell de app real (grupos, badge, acción, submenú, fila deshabilitada),
controles vivos de los tres props y las 9 pestañas del canon.
Verificado en navegador real (Playwright): dos landmarks nombrados en el
idioma activo · `aria-current="page"` en la fila activa · cada menú etiquetado
por SU grupo · raíl enfocable que alterna con Enter · colapso 256→48px ·
off-canvas por transform · submenú flotante anclado a su fila y Escape que
devuelve el foco · sema `emerge-expand/collapse` estampando en `panel` ·
móvil 600px = Drawer cerrado con el landmark dentro · RTL espeja el shell
entero · oscuro · 0 errores de consola.
Gates: `component:audit --only sidebar` PASS 0E/0W · eidos-lint 45
morfo-backed / 0 invalid / 0 class-hooks · `svelte-check` 0 errores propios ·
`vitest src/uix/eidos` 353/353 · `contracts.test` solo con fallos ajenos
(menubar, radio-group y las claves camelCase de aura).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/nav-tree', label: 'Nav tree' },
|
|
|
|
|
|
{ slug: '/uix/components/sidebar', label: 'Sidebar' }
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Media',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/avatar', label: 'Avatar' },
|
feat(eidos): Card, Avatar ext, Image, SText, Badge, service components + dates engine fixes
Sprint completo:
- Card (eidos + sema): elevation/intent/interactive, eventos select+activate.
- Avatar: ring, AvatarBadge, AvatarGroup separados; demo Avatar standalone.
- Image: status surface (idle/loading/loaded/error) consumiendo soma ImageProvider.
- SText + STextVirtualList: canvas-text engine portado de morfo-driven-soma como
componentes separados para optimizar bundle (no se importa canvas si no se usa).
- Badge: primitivo eidos puro.
- Trans, FormatNumber, FormatDate, RelativeTime: 4 service components greppables
alrededor de uix.langs y uix.format. Nav group "Utilities".
Bugs fix arts/format/dates (engine-dates.ts):
1. Preset / per-axis conflict: Intl.DateTimeFormat rechaza dateStyle/timeStyle
con cualquier per-axis (weekday/era/year/month/day/dayPeriod/hour/minute/
second/fractionalSecondDigits) o con timeZoneName. Engine drop-ea ambos
presets por defecto cuando detecta conflict (regla estricta — un solo
per-axis hace ilegales los dos presets).
2. Per-call locale override: formatDate/Time/DateTime aceptan tercer arg
locale?: string. No muta engine state. Cache (getCachedDateFormat) keyea
por (locale x options). resolveCallHourCycle: cuando hay locale override
y pref auto, el ciclo horario se resuelve desde el locale OVERRIDE.
3. withHourCycle precedence: caller hourCycle/hour12 ahora gana sobre
preferencia del engine. Antes spread mal ordenado sobrescribia 'h12' del
caller con 'h23' del engine cuando locale resolvia a 24h.
FormatDate component vuelve a rutear siempre por uix.format.dates
(cache + hourCycle + locale reactivo), pasando locale como tercer arg.
Demos service components autonomos del toolbar global: cada uno owns su
demoLocale state con 7 chips (es-ES/en-US/en-GB/de-DE/fr-FR/ja-JP/ar-EG).
FormatDate stage filtra dateStyle/timeStyle por mode + chip hourCycle anadido.
Tests: 14/14 passing en engine-dates.test.ts (+6 nuevos: conflict handling,
locale override, hourCycle precedence).
Docs: arts/format/README.md (handoff 2026-05-25 con las 3 reglas),
README.md por service component, project_service_components_sprint_2026-05-25.md,
feedback_service_demos_own_locale.md (pattern reusable).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/avatar-group', label: 'AvatarGroup' },
|
feat(eidos): port carousel from soma
Eidos wrapper for the soma Carousel primitive — horizontally or
vertically scrollable rail of slides with keyboard, button, indicator,
drag and autoplay nav. Soma owns the index + autoplay timer + gesture;
eidos adds size/variant/color cascades and renders prev/next triggers
as `<Button iconOnly variant="ghost" rounded="full">` per the canonical
Button consumer pattern.
## Feature comparison
| Feature | embla | Mantine | ark-ui | Eidos |
|----------------------|-------|---------|--------|-------|
| Index nav | ✓ | ✓ | ✓ | ✓ |
| Loop | ✓ | ✓ | ✓ | ✓ |
| Drag / scrub | ✓ | — | ✓ | ✓ |
| Autoplay | plugin| ✓ | ✓ | ✓ |
| Pause on hover | plugin| ✓ | ✓ | ✓ |
| Orientation V/H | ✓ | ✓ | ✓ | ✓ |
| Keyboard nav | ✓ | ✓ | ✓ | ✓ |
| Indicators | — | ✓ | ✓ | ✓ |
| Prev/Next triggers | — | ✓ | ✓ | ✓ |
| Size cascade | — | — | — | ✓ 5 |
| Variant cascade | — | — | — | ✓ 3 |
| Color cascade | — | — | — | ✓ 8 |
| Multi-slides view | ✓ | ✓ | — | deferred |
| Lazy-mount slides | plugin| — | — | deferred |
## Parts (8)
Provider · Viewport · ItemGroup · Item · PrevTrigger · NextTrigger ·
IndicatorGroup · Indicator.
PrevTrigger and NextTrigger render Button via the soma `child` snippet
(canonical Button consumer pattern). Default chrome:
`iconOnly variant='ghost' rounded='full'` + chevron glyph. Size cascades
from Carousel root; consumers can override every Button visual prop
inline. Passing `child` bypasses Button entirely.
## Recipe
Card chrome around the rail (`variant='surface'`), absolute-positioned
triggers over the viewport edges (vertical flips to top/bottom). Active
indicator stretches inline-size 2.25× for clearer current-position hint.
8 ColorRole accents.
## Demo
Canonical 6-tab depth (~470L): Live / API / Morfo / Sema / Recipe /
A11y. Live controls cover all soma props (orientation, loop, dragEnabled,
autoplay + delay slider, pauseOnHover, disabled) and all eidos props
(variant, size, color). 4 colored placeholder slides for visual contrast.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/icon', label: 'Icon' },
|
feat(eidos): Card, Avatar ext, Image, SText, Badge, service components + dates engine fixes
Sprint completo:
- Card (eidos + sema): elevation/intent/interactive, eventos select+activate.
- Avatar: ring, AvatarBadge, AvatarGroup separados; demo Avatar standalone.
- Image: status surface (idle/loading/loaded/error) consumiendo soma ImageProvider.
- SText + STextVirtualList: canvas-text engine portado de morfo-driven-soma como
componentes separados para optimizar bundle (no se importa canvas si no se usa).
- Badge: primitivo eidos puro.
- Trans, FormatNumber, FormatDate, RelativeTime: 4 service components greppables
alrededor de uix.langs y uix.format. Nav group "Utilities".
Bugs fix arts/format/dates (engine-dates.ts):
1. Preset / per-axis conflict: Intl.DateTimeFormat rechaza dateStyle/timeStyle
con cualquier per-axis (weekday/era/year/month/day/dayPeriod/hour/minute/
second/fractionalSecondDigits) o con timeZoneName. Engine drop-ea ambos
presets por defecto cuando detecta conflict (regla estricta — un solo
per-axis hace ilegales los dos presets).
2. Per-call locale override: formatDate/Time/DateTime aceptan tercer arg
locale?: string. No muta engine state. Cache (getCachedDateFormat) keyea
por (locale x options). resolveCallHourCycle: cuando hay locale override
y pref auto, el ciclo horario se resuelve desde el locale OVERRIDE.
3. withHourCycle precedence: caller hourCycle/hour12 ahora gana sobre
preferencia del engine. Antes spread mal ordenado sobrescribia 'h12' del
caller con 'h23' del engine cuando locale resolvia a 24h.
FormatDate component vuelve a rutear siempre por uix.format.dates
(cache + hourCycle + locale reactivo), pasando locale como tercer arg.
Demos service components autonomos del toolbar global: cada uno owns su
demoLocale state con 7 chips (es-ES/en-US/en-GB/de-DE/fr-FR/ja-JP/ar-EG).
FormatDate stage filtra dateStyle/timeStyle por mode + chip hourCycle anadido.
Tests: 14/14 passing en engine-dates.test.ts (+6 nuevos: conflict handling,
locale override, hourCycle precedence).
Docs: arts/format/README.md (handoff 2026-05-25 con las 3 reglas),
README.md por service component, project_service_components_sprint_2026-05-25.md,
feedback_service_demos_own_locale.md (pattern reusable).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/image', label: 'Image' },
|
feat(uix): cropper, image-picker, image-adjustments + reusable zoom-pan layer
Three new components across all 4 layers (morfo/soma/sema/eidos) + demos + langs + READMEs:
- ImageAdjustments — reusable image-filter sliders subcomponent.
- ImagePicker — composes file-upload + image + image-adjustments (fill modes, rotation).
- Cropper — Ark image-cropper anatomy: normalized 0-1 crop rect, rect + round shapes,
8 resize handles, fixedSize move-only (avatar), canvas Blob output (5-arg drawImage
for SVG safety), wheel/pan zoom, two-zone gesture (selection moves the area, the
background pans to set focus; img draggable=false guards native DnD per zag).
New reusable soma/layers/zoom-pan: cursor-centered zoom, clamped pan, transform +
viewport-frac-to-content-frac mapping. Image-viewer / diagram-pan / map can reuse it.
sema: add 'zoom' verb to the handle family (direct manipulation, documented extension).
slider: track visible at zero (gray, not white), thumb lifts on drag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
{ slug: '/uix/components/image-adjustments', label: 'Image adjustments' },
|
|
|
|
|
|
{ slug: '/uix/components/image-picker', label: 'Image picker' },
|
|
|
|
|
|
{ slug: '/uix/components/cropper', label: 'Cropper' },
|
|
|
|
|
|
{ slug: '/uix/components/carousel', label: 'Carousel' },
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/qr-code', label: 'QR code' },
|
feat(eidos): `Barcode` — el código de barras 1D, con encoder propio y cero dependencias
Ocho simbologías desde su estándar ISO publicado (Code 128 con auto-switching
A/B/C, EAN-13/8, UPC-A/E, Code 39, ITF/ITF-14) en `$libs/barcode`: tablas
transcritas de la especificación o derivadas de su regla de construcción, sin
una sola dependencia npm añadida. JsBarcode y bwip-js son referencia de
corrección, jamás import — la misma doctrina con la que `$libs/qr` usó a Nayuki.
Ningún headless del mercado trae barcode: el terreno lo ocupan encoders
imperativos sin anatomía ni a11y.
- **La física manda sobre la ergonomía visual.** La dimensión X (`moduleWidth`)
es el ancla de escaneabilidad y la altura de barra un eje libre — un escáner
lee una franja horizontal. Por eso la geometría es px absolutos en el viewBox
(precedente: la familia `chart`) y no el token `size` cuadrado del QR:
colapsar los dos ejes en uno haría que la X dependiera de la altura, que es
justo lo que no puede flotar. La zona muda va en módulos, con el mínimo de
cada estándar.
- **Lo que hace reconocible a la familia.** Las guardas EAN/UPC bajan hasta la
línea base y los dígitos se imprimen dígito-bajo-dígito sobre su celda de 7
módulos, en mono (la HRI del estándar es OCR-B, de ancho fijo). ITF-14 lleva
su barra portadora por fuera de la zona muda, que no puede comerse.
- **Un valor no codificable es un ESTADO, no una excepción.** `encode` lanza un
`BarcodeError` tipado; el wrapper lo captura, marca `data-invalid`, avisa por
`onInvalid` (deduplicado por razón: `encoded` es un objeto nuevo por
pulsación) y deja un marco placeholder decorativo. Un EAN a medio teclear es
un paso normal de edición; dejarlo reventar dentro de un `$derived` tumbaría
la página.
- **`'text'` entra en `MorfoElement`** — y también en el schema de sium, que
tiene su propia lista literal. Añadir solo la unión de TypeScript compila y
falla en runtime; lo cazó `morfo:check`, no `npm run check`.
Verificación: 48 tests de encoder en tres capas (invariantes estructurales de
cada tabla · vectores publicados transcritos aparte · decoders independientes
que releen la retícula), la lectura real confirmada con escáner por el usuario,
y la retícula decodificada desde el SVG ya pintado en navegador. `component:audit`
PASS con 0 errores; los 2 warnings (D-1.5 / D-4.3) son los mismos que da
`button`, la demo canaria: sus regex buscan la forma v1 inline del
MutationObserver y del `emit`, que la v2 movió al harness compartido.
Demo v2 canónica de 9 pestañas. El alcance diferido (Codabar/MSI/Pharmacode,
GS1-128, add-ons EAN-2/5, y las 2D como componentes aparte) queda registrado en
`next-features.md` §10 — el hueco de numeración se cierra cuando el track de
blocks commitee sus §8/§9, hoy sin commitear.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
|
{ slug: '/uix/components/barcode', label: 'Barcode' },
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/media-player', label: 'Media player' }
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Status',
|
|
|
|
|
|
items: [
|
feat(eidos): Card, Avatar ext, Image, SText, Badge, service components + dates engine fixes
Sprint completo:
- Card (eidos + sema): elevation/intent/interactive, eventos select+activate.
- Avatar: ring, AvatarBadge, AvatarGroup separados; demo Avatar standalone.
- Image: status surface (idle/loading/loaded/error) consumiendo soma ImageProvider.
- SText + STextVirtualList: canvas-text engine portado de morfo-driven-soma como
componentes separados para optimizar bundle (no se importa canvas si no se usa).
- Badge: primitivo eidos puro.
- Trans, FormatNumber, FormatDate, RelativeTime: 4 service components greppables
alrededor de uix.langs y uix.format. Nav group "Utilities".
Bugs fix arts/format/dates (engine-dates.ts):
1. Preset / per-axis conflict: Intl.DateTimeFormat rechaza dateStyle/timeStyle
con cualquier per-axis (weekday/era/year/month/day/dayPeriod/hour/minute/
second/fractionalSecondDigits) o con timeZoneName. Engine drop-ea ambos
presets por defecto cuando detecta conflict (regla estricta — un solo
per-axis hace ilegales los dos presets).
2. Per-call locale override: formatDate/Time/DateTime aceptan tercer arg
locale?: string. No muta engine state. Cache (getCachedDateFormat) keyea
por (locale x options). resolveCallHourCycle: cuando hay locale override
y pref auto, el ciclo horario se resuelve desde el locale OVERRIDE.
3. withHourCycle precedence: caller hourCycle/hour12 ahora gana sobre
preferencia del engine. Antes spread mal ordenado sobrescribia 'h12' del
caller con 'h23' del engine cuando locale resolvia a 24h.
FormatDate component vuelve a rutear siempre por uix.format.dates
(cache + hourCycle + locale reactivo), pasando locale como tercer arg.
Demos service components autonomos del toolbar global: cada uno owns su
demoLocale state con 7 chips (es-ES/en-US/en-GB/de-DE/fr-FR/ja-JP/ar-EG).
FormatDate stage filtra dateStyle/timeStyle por mode + chip hourCycle anadido.
Tests: 14/14 passing en engine-dates.test.ts (+6 nuevos: conflict handling,
locale override, hourCycle precedence).
Docs: arts/format/README.md (handoff 2026-05-25 con las 3 reglas),
README.md por service component, project_service_components_sprint_2026-05-25.md,
feedback_service_demos_own_locale.md (pattern reusable).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/badge', label: 'Badge' },
|
uix(empty-state): F1.2 · componente base display (morfo+eidos) al suelo del dossier
Primera pieza F1 del plan blocks (PLAN-blocks.md; alcance E-2 = suelo de
paridad, dossier §P3). Ruta de 9 fases completa:
- morfo: 5 partes display (provider/media/title/description/actions),
scope ['eidos'], 0 eventos con justificacion pasiva (patron
renderEmptyState de las refs headless), Title role:'heading', texts.label
- langs: components.empty-state.label (es/en) — el indice tambien recoge la
retirada foranea del import de words (inseparable por staging de archivo;
coherente con la migracion palabras ya enviada; words.ts sigue en su arbol)
- eidos: compound EmptyState + Media(kind icon|media, placa 2x glifo) +
Title(level 2-6, default h3 — modelo Atlaskit, tamano visual desacoplado) +
Description(measure 45ch) + Actions(label -> role=group +aria-label,
buttonGroupLabel); recipe sobre el bundle --size-* (titulo un paso
discreto arriba; sm=in-collection, lg=hero); tokens publicos minimos
(gap/actions-gap/media-bg/media-fg/media-radius/description-measure)
- demo v2 9 tabs (harness: SystemAxes/MotionPanel/SemaPanel; snippet con
paridad; escena in-collection via Card) + entrada nav (grupo Status)
- README: Baseline · Comparativa (shadcn/Chakra/Atlaskit/AntD/Polaris) ·
Decisiones · Passive justification · Gaps con disposicion
Verificacion: component:audit PASS · eidos-lint 5 morfo-backed + 4
eidos-only sancionados · morfo:check + morfo:vocabulary verdes ·
recipe-css-contract/api-contract/visual-attrs 37/37 · svelte-check
76E/51W = baseline exacto (cero regresion) · navegador claro Y oscuro por
estilos computados (titulo 18->24px, placa 40->64px, chips vivos, cero
errores de consola).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/empty-state', label: 'Empty state' },
|
uix(result): F1.3 · estado terminal de flujo/pagina (morfo+eidos) al suelo del dossier
Segunda pieza F1 del plan blocks (alcance E-2 = suelo de paridad, dossier
§P3). Comparte el esqueleto de empty-state a proposito: EmptyState describe
AUSENCIA de datos, Result reporta un RESULTADO — un lenguaje de layout, dos
contratos (duplicacion consciente registrada en el README; revisable al 3er
consumidor).
- morfo: 6 partes display (provider/media/title/description/actions/extra;
extra SIN archetype — parte genuinamente propia), scope ['eidos'],
0 eventos justificados (el resultado ya OCURRIO antes de renderizar)
- status: enum de 7 = paridad AntD CON `warning` (decision firme del
dossier) y HTTP renombrados semanticos (forbidden/not-found/server-error,
nunca '404' stringly); default 'info'; data-status = attr eidos-only
- media default: compone el mapa doctrinal IntentIcon (success→fulfill ·
error→threat · warning→risk) + Info de catalogo; HTTP = codigo mono
grande NEUTRO aria-hidden (situaciones, no fallos — AntD jamas pinta 404
de rojo); children reemplazan el default entero (context local eidos-only
con getter reactivo)
- Title default h2 (vs h3 de empty-state — Result suele SER la pagina);
Actions con label→role=group; Extra alineado a inicio (detalle que lee)
- recipe: glifo display 3× xl bundle; tokens publicos
gap/actions-gap/measures + {status}-color como forwarders de rol
retintables; sin eje size (paridad AntD, gap diferido)
- demo v2 9 tabs con copy por status + entrada nav (Status) + README
(Comparativa · Decisiones · Passive justification · Gaps con disposicion)
Verificacion: component:audit PASS 0E/0W · eidos-lint 6 morfo-backed + 5
eidos-only sancionados · recipe/api/visual-attrs 37/37 · morfo:check verde
(los 7 fallos listados son deuda foranea preexistente) · svelte-check
76E/51W = baseline exacto · navegador: success=fulfill verde 84px ·
error=threat rojo · not-found=«404» mono neutro, copy conmutando, cero
errores de consola.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/result', label: 'Result' },
|
|
|
|
|
|
{ slug: '/uix/components/callout', label: 'Callout' },
|
|
|
|
|
|
{ slug: '/uix/components/progress', label: 'Progress' },
|
feat(eidos): add Skeleton and Spinner loader primitives
Two pure-eidos loader components with morfos at scope `['eidos']`
(no soma backing, no semantic events).
Skeleton — content placeholder:
- 3 shapes: rect (default), circle, text (multi-line with staggered widths)
- 5 sizes (xs..xl), 8 color accents
- Optional shimmer animation via CSS `background-position` keyframes
- Single `<div role="status" aria-busy="true">` with translated aria-label
- Reduced-motion freezes animation, keeps visual
Spinner — indeterminate progress:
- 3 variants: ring (rotating arc), dots (bouncing), bars (stretching)
- 5 sizes, 8 colors
- Optional inline label via children snippet
- `role="status"` + `aria-live="polite"` for SR announcements
- Reduced-motion freezes animation, keeps visual
Files:
- morfo: skeleton.ts, spinner.ts (scope eidos, no events)
- eidos: full component + types + css + langs + index per component
- langs: skeleton/spinner under componentLangs barrel
- demos: canonical 6-tab depth + composition examples (avatar+text card)
- layout: sidebar additions under Status group
Note: also includes responsive shell additions to web/routes/uix/uix.css
that surfaced from an external session — same file, leaving them in.
Reference libraries reviewed (Mantine, Chakra v3, Radix Themes, MUI):
all expose the same shape/variant/size/color surface. shadcn Skeleton uses
the same pulse animation. No surprises in our API.
svelte-check: 0 errors in skeleton/spinner files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/meter', label: 'Meter' },
|
|
|
|
|
|
{ slug: '/uix/components/spinner', label: 'Spinner' },
|
|
|
|
|
|
{ slug: '/uix/components/skeleton', label: 'Skeleton' }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Data',
|
|
|
|
|
|
items: [
|
feat(charts): unified Heatmap (matrix + calendar) + 5 new chart types
Heatmap is now one component, two modes by data shape: matrix {x,y,value}
(columns × rows) and calendar {date,value} (GitHub-style weeks × weekdays,
with granularity year/month, orientation, locale-aware week start, fade).
New standalone charts: Gauge, Funnel (multicolor + labelPosition), Bubble
(size-encoded, axis-padded), PolarArea (Nightingale, padAngle gap between
sectors), CalendarHeatmap (internal renderer behind Heatmap).
Funnel/Bubble/Heatmap/PolarArea gain hover tooltips + dim. CalendarHeatmap
week start + month/weekday labels follow the uix langs locale reactively.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
{ slug: '/uix/components/metrics', label: 'Metrics' },
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/table', label: 'Table' },
|
|
|
|
|
|
{ slug: '/uix/components/tree-view', label: 'Tree view' },
|
|
|
|
|
|
{ slug: '/uix/components/tree-grid', label: 'Tree grid' },
|
uix(chat): bloque de mensajería chat-* v1 (log · message · composer · typing)
Familia chat-* completa, componiendo el ecosistema (Feed + VirtualList
anclado, Textarea, FileUpload, Avatar, Popover, Icon). Transporte-agnóstica:
el modelo de datos es de la app, los componentes reciben props + snippets.
- chat-log: Feed + VirtualList(anchor:'end') en triple registro; day
separators, unread divider, filas de sistema (Feed.Article), pill "N
nuevos" + notifyIncoming (announce a live-region), to-latest distance-aware.
- chat-message: raíz Feed.Article; runs ($libs/chat), ticks de entrega,
reply embebido, reacciones (chip pressed + tapback panel), acciones hover.
- chat-composer: Textarea (doble registro) + FileUpload; teclado
Enter/Shift+Enter/Esc/ArrowUp; typing saliente debounced (uix.timers);
barra reply/edit.
- chat-typing: sustain-streaming (visual-only, loop del sistema);
aggregateTypers 1/2/3+ con plantillas plurales.
- $libs/chat: groupIntoRuns (ventana 8 min estilo Discord) + aggregateTypers.
- VirtualList: extensión anchor:'end' (followOutput, prepend por clave
estable, sticky monótono, onAtEndChange) — sin scroller paralelo.
Diseño de referencia (WhatsApp/Telegram, pase lado-a-lado): burbujas suaves
(out = primary-element + texto normal; in = surface card + sombra) sobre
lienzo muted del log, meta dentro de la burbuja, tapback bar horizontal,
iconos lucide del ecosistema (nada de SVG a mano). Contrato de tamaños:
size="md" = 16px canónico.
Fixes de framework (afectaban más allá de chat):
- EngineLangs.t() ahora pela el prefijo '#?': los idlangrefs imperativos
(pagination/file-upload/chronos/chat) caían al fallback EN en locale es.
Fix parseLangRef ?? parsePathFallback + test de regresión (132/132).
- virtual-list commit-set-resize con channels:[]: es bookkeeping de
ResizeObserver, no gesto → dejaba de emitir beep/vibrate pre-interacción
(interventions de navigator.vibrate / AudioContext).
Escaparate messenger en /uix/demos/chat (bot de eco con uix.timers;
variante $connection señalada). Gaps v2 registrados en next-features §7.
Pase: component:audit 4×PASS · eidos-lint invalid=0 · recipe-contract
29/29 · Playwright escaparate PASS end-to-end · consola limpia ·
npm run check en baseline (76, cero errores nuevos).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/chat-composer', label: 'Chat composer' },
|
uix(chat): v2 · chat-list — panel de conversaciones (compone Listbox)
Componente nuevo del bloque chat v2: el panel de lista de salas/DMs.
Compone el Listbox del ecosistema (doble registro id/ref compartido):
selección única + roving-tabindex + typeahead + role=option vienen de
Listbox; chat-list aporta la disposición de fila (avatar · título/preview ·
meta) y el estado visual data-unread (negrita + Badge compuesto).
- morfo: expression 'delegated', sin eventos propios (D.1 — el actor es el
Listbox compuesto); parts provider/item(data-unread)/avatar/title/preview/meta.
- soma: ChatListProvider crea ListboxProvider dentro (value string <-> string[]);
ChatListItemProvider per-instance (unread = boolean crudo); 4 clases de
contenido explicitas.
- eidos: rejilla avatar | (titulo/preview) | meta, avatar y meta abarcan las
dos filas; truncado; unread -> titulo en negrita. No neutraliza el arquetipo
item (la conversacion ES una opcion seleccionable). Sin @keyframes; ejes
logicos.
- demo: 5 salas, seleccion limpia unread, typing-en-lista (compone ChatTyping),
Badge de no-leidos; tabs live/system/api/morfo/a11y.
- READMEs dobles (eidos con Passive justification, delegated); next-features 7
marca chat-list SHIPPED.
Verificacion: check baseline 76 (0 nuevos) · component:audit PASS ·
eidos-lint invalid=0 · recipe-contract 30/30 · morfo:vocabulary 0 · Playwright
PASS (role=listbox, 5 salas, aria-selected, unread=2, badges=2, typing-en-lista,
click + teclado seleccionan).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/chat-list', label: 'Chat list' },
|
uix(chat): bloque de mensajería chat-* v1 (log · message · composer · typing)
Familia chat-* completa, componiendo el ecosistema (Feed + VirtualList
anclado, Textarea, FileUpload, Avatar, Popover, Icon). Transporte-agnóstica:
el modelo de datos es de la app, los componentes reciben props + snippets.
- chat-log: Feed + VirtualList(anchor:'end') en triple registro; day
separators, unread divider, filas de sistema (Feed.Article), pill "N
nuevos" + notifyIncoming (announce a live-region), to-latest distance-aware.
- chat-message: raíz Feed.Article; runs ($libs/chat), ticks de entrega,
reply embebido, reacciones (chip pressed + tapback panel), acciones hover.
- chat-composer: Textarea (doble registro) + FileUpload; teclado
Enter/Shift+Enter/Esc/ArrowUp; typing saliente debounced (uix.timers);
barra reply/edit.
- chat-typing: sustain-streaming (visual-only, loop del sistema);
aggregateTypers 1/2/3+ con plantillas plurales.
- $libs/chat: groupIntoRuns (ventana 8 min estilo Discord) + aggregateTypers.
- VirtualList: extensión anchor:'end' (followOutput, prepend por clave
estable, sticky monótono, onAtEndChange) — sin scroller paralelo.
Diseño de referencia (WhatsApp/Telegram, pase lado-a-lado): burbujas suaves
(out = primary-element + texto normal; in = surface card + sombra) sobre
lienzo muted del log, meta dentro de la burbuja, tapback bar horizontal,
iconos lucide del ecosistema (nada de SVG a mano). Contrato de tamaños:
size="md" = 16px canónico.
Fixes de framework (afectaban más allá de chat):
- EngineLangs.t() ahora pela el prefijo '#?': los idlangrefs imperativos
(pagination/file-upload/chronos/chat) caían al fallback EN en locale es.
Fix parseLangRef ?? parsePathFallback + test de regresión (132/132).
- virtual-list commit-set-resize con channels:[]: es bookkeeping de
ResizeObserver, no gesto → dejaba de emitir beep/vibrate pre-interacción
(interventions de navigator.vibrate / AudioContext).
Escaparate messenger en /uix/demos/chat (bot de eco con uix.timers;
variante $connection señalada). Gaps v2 registrados en next-features §7.
Pase: component:audit 4×PASS · eidos-lint invalid=0 · recipe-contract
29/29 · Playwright escaparate PASS end-to-end · consola limpia ·
npm run check en baseline (76, cero errores nuevos).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/chat-log', label: 'Chat log' },
|
|
|
|
|
|
{ slug: '/uix/components/chat-message', label: 'Chat message' },
|
|
|
|
|
|
{ slug: '/uix/components/chat-typing', label: 'Chat typing' },
|
uix(chat): v2 · emoji-picker (picker completo) + escaparate rico del bloque
Nuevo componente emoji-picker y rediseño del escaparate de mensajeria.
emoji-picker (ruta 9 fases):
- Compone Popover (open/close/foco/portal) + Command (busqueda + grid + nav de
teclado + a11y combobox/listbox, su "grid mode" documentado) + dos ToggleGroup
(categorias + tono de piel). Delegated: sin eventos propios (D.1); el grid y
las celdas doble-registran Command.List/Item, conservando la a11y pero con
contrato visual propio (gana especificidad con selectores de 2 niveles, sin
tocar attrs [data-command-*] ajenos — eidos-lint limpio).
- Datos: $libs/emoji, dataset vendorizado de emojibase (MIT) horneado por
scripts/generate-emoji-data.ts (precedente lucide: JSON crudo en static/ +
script generador). ~1906 emoji con nombre CLDR + keywords, 316 con tono de
piel single-person. Grid acotado (categoria activa o resultados de busqueda),
sin virtualizacion (refinamiento v2). Helpers puros + test (12/12).
- morfo delegated (7 partes + header/footer de layout); soma (root + trigger +
content + grid + option + preview, provider-test 4/4); eidos (panel
empaquetado, receta con tokens --emoji-picker-*); langs es/en; demo 5 tabs
(excepcion delegated documentada); READMEs dobles.
Escaparate del bloque (web/routes/uix/demos/chat) — rehecho rico y correcto:
- Avatares por-autor con color solido (Avatar del ecosistema): antes gris
neutro indefinido, ahora teal/ambar/verde/indigo/primary bien contrastados.
- Dos columnas: chat-list (sidebar con badges + typing-en-lista) + sala.
- Conversacion rica: separador de dia, run agrupado, reaccion, reply citado,
recibos de lectura, typing con avatar, y el emoji-picker integrado en el
composer (inserta en el draft).
- Solape de burbujas (transitorio, estimateSize=48 con mensajes ~90-126px)
mitigado subiendo el estimate a 76.
Auditoria de tamanos/espacios: recipes del bloque limpios (todo con tokens
--space-*/--size-*/--color-*); unico literal (punto tono-capable) tokenizado.
Verificacion: check baseline 76 (0 nuevos) · component:audit emoji-picker PASS ·
eidos-lint invalid=0 · recipe-contract 30/30 · morfo:vocabulary 0 · emoji lib
12/12 · provider-test 4/4 · Playwright PASS (busqueda 'rocket'->rocket+
astronautas, click->onSelect+cierra, teclado, tono oscuro 👋->👋🏿, picker abre
en el composer). Capturas claro miradas.
next-features §7 marca emoji-picker SHIPPED.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/emoji-picker', label: 'Emoji picker' },
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/feed', label: 'Feed' },
|
|
|
|
|
|
{ slug: '/uix/components/timeline', label: 'Timeline' },
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/virtual-list', label: 'Virtual list' },
|
|
|
|
|
|
{ slug: '/uix/components/virtual-grid', label: 'Virtual grid' }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
feat(charts): unified Heatmap (matrix + calendar) + 5 new chart types
Heatmap is now one component, two modes by data shape: matrix {x,y,value}
(columns × rows) and calendar {date,value} (GitHub-style weeks × weekdays,
with granularity year/month, orientation, locale-aware week start, fade).
New standalone charts: Gauge, Funnel (multicolor + labelPosition), Bubble
(size-encoded, axis-padded), PolarArea (Nightingale, padAngle gap between
sectors), CalendarHeatmap (internal renderer behind Heatmap).
Funnel/Bubble/Heatmap/PolarArea gain hover tooltips + dim. CalendarHeatmap
week start + month/weekday labels follow the uix langs locale reactively.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Charts',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/chart', label: 'Chart · overview' },
|
|
|
|
|
|
{ slug: '/uix/components/line-chart', label: 'Line chart' },
|
|
|
|
|
|
{ slug: '/uix/components/area-chart', label: 'Area chart' },
|
|
|
|
|
|
{ slug: '/uix/components/bar-chart', label: 'Bar chart' },
|
|
|
|
|
|
{ slug: '/uix/components/scatter-chart', label: 'Scatter chart' },
|
|
|
|
|
|
{ slug: '/uix/components/sparkline', label: 'Sparkline' },
|
|
|
|
|
|
{ slug: '/uix/components/pie-chart', label: 'Pie chart' },
|
|
|
|
|
|
{ slug: '/uix/components/bar-list', label: 'Bar list' },
|
|
|
|
|
|
{ slug: '/uix/components/bar-segment', label: 'Bar segment' },
|
|
|
|
|
|
{ slug: '/uix/components/radar-chart', label: 'Radar chart' },
|
|
|
|
|
|
{ slug: '/uix/components/gauge', label: 'Gauge' },
|
|
|
|
|
|
{ slug: '/uix/components/funnel', label: 'Funnel' },
|
|
|
|
|
|
{ slug: '/uix/components/bubble-chart', label: 'Bubble chart' },
|
|
|
|
|
|
{ slug: '/uix/components/polar-area', label: 'Polar area' },
|
|
|
|
|
|
{ slug: '/uix/components/heatmap', label: 'Heatmap' },
|
|
|
|
|
|
{ slug: '/uix/components/smith-chart', label: 'Smith chart' }
|
feat(charts): unified Heatmap (matrix + calendar) + 5 new chart types
Heatmap is now one component, two modes by data shape: matrix {x,y,value}
(columns × rows) and calendar {date,value} (GitHub-style weeks × weekdays,
with granularity year/month, orientation, locale-aware week start, fade).
New standalone charts: Gauge, Funnel (multicolor + labelPosition), Bubble
(size-encoded, axis-padded), PolarArea (Nightingale, padAngle gap between
sectors), CalendarHeatmap (internal renderer behind Heatmap).
Funnel/Bubble/Heatmap/PolarArea gain hover tooltips + dim. CalendarHeatmap
week start + month/weekday labels follow the uix langs locale reactively.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
|
|
|
|
]
|
|
|
|
|
|
},
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Utilities',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/announce', label: 'Announce' },
|
|
|
|
|
|
{ slug: '/uix/components/clipboard', label: 'Clipboard' },
|
feat(eidos): Card, Avatar ext, Image, SText, Badge, service components + dates engine fixes
Sprint completo:
- Card (eidos + sema): elevation/intent/interactive, eventos select+activate.
- Avatar: ring, AvatarBadge, AvatarGroup separados; demo Avatar standalone.
- Image: status surface (idle/loading/loaded/error) consumiendo soma ImageProvider.
- SText + STextVirtualList: canvas-text engine portado de morfo-driven-soma como
componentes separados para optimizar bundle (no se importa canvas si no se usa).
- Badge: primitivo eidos puro.
- Trans, FormatNumber, FormatDate, RelativeTime: 4 service components greppables
alrededor de uix.langs y uix.format. Nav group "Utilities".
Bugs fix arts/format/dates (engine-dates.ts):
1. Preset / per-axis conflict: Intl.DateTimeFormat rechaza dateStyle/timeStyle
con cualquier per-axis (weekday/era/year/month/day/dayPeriod/hour/minute/
second/fractionalSecondDigits) o con timeZoneName. Engine drop-ea ambos
presets por defecto cuando detecta conflict (regla estricta — un solo
per-axis hace ilegales los dos presets).
2. Per-call locale override: formatDate/Time/DateTime aceptan tercer arg
locale?: string. No muta engine state. Cache (getCachedDateFormat) keyea
por (locale x options). resolveCallHourCycle: cuando hay locale override
y pref auto, el ciclo horario se resuelve desde el locale OVERRIDE.
3. withHourCycle precedence: caller hourCycle/hour12 ahora gana sobre
preferencia del engine. Antes spread mal ordenado sobrescribia 'h12' del
caller con 'h23' del engine cuando locale resolvia a 24h.
FormatDate component vuelve a rutear siempre por uix.format.dates
(cache + hourCycle + locale reactivo), pasando locale como tercer arg.
Demos service components autonomos del toolbar global: cada uno owns su
demoLocale state con 7 chips (es-ES/en-US/en-GB/de-DE/fr-FR/ja-JP/ar-EG).
FormatDate stage filtra dateStyle/timeStyle por mode + chip hourCycle anadido.
Tests: 14/14 passing en engine-dates.test.ts (+6 nuevos: conflict handling,
locale override, hourCycle precedence).
Docs: arts/format/README.md (handoff 2026-05-25 con las 3 reglas),
README.md por service component, project_service_components_sprint_2026-05-25.md,
feedback_service_demos_own_locale.md (pattern reusable).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/drag-drop', label: 'Drag & drop' },
|
feat(proof-of-human): re-architect to orchestrator + pluggable challenge (PathTrace)
Split the anti-bot component into a purpose- and interaction-agnostic
orchestrator that owns the lifecycle stages + verdict, and a pluggable
challenge that runs the interaction and reports up via
ProofOfHumanChallengeHost. The primary challenge, PathTrace, has the user
follow a random curved path by pointer OR arrow keys.
This fixes the drag version's two real defects:
- keyboard bypass: the accessible path now yields genuine, non-replayable
behavioural signal (pathAdherence over a per-instance random curve); a
two-key script can't solve it.
- over-coupled abstraction: interaction + animation are decoupled from the
component identity (per-stage consumer slots; challenge is pluggable).
Layers:
- morfo: proof-of-human slimmed to orchestrator (Provider + 3 commits); new
path-trace morfo (Provider + Track + Token; handle-*).
- soma: orchestrator + ProofOfHumanChallengeHost; new path-trace (seeded
Catmull-Rom curve, corridor-gated monotonic progress, adherence telemetry,
pointer + arrow-key input). Old drag Token/Target wrappers retired.
- sema: verdict commits (proof-of-human) + trace handle earcons (path-trace).
- eidos: orchestrator + PathTrace that paints the curve/corridor/trail.
- demo rebuilt: carrier-pigeon skin over the per-stage slots.
Auto-focuses the token when the challenge is armed so the arrow keys start the
trace immediately (gated on the disabled->enabled transition).
Verified: 32/32 tests (incl. arrow trace completes with real signal + two-key
script can't solve, in real chromium) + visual in real Chrome (curve, failed,
verified; scorer rejects instant traces).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/proof-of-human', label: 'Proof of human' },
|
feat(eidos): Card, Avatar ext, Image, SText, Badge, service components + dates engine fixes
Sprint completo:
- Card (eidos + sema): elevation/intent/interactive, eventos select+activate.
- Avatar: ring, AvatarBadge, AvatarGroup separados; demo Avatar standalone.
- Image: status surface (idle/loading/loaded/error) consumiendo soma ImageProvider.
- SText + STextVirtualList: canvas-text engine portado de morfo-driven-soma como
componentes separados para optimizar bundle (no se importa canvas si no se usa).
- Badge: primitivo eidos puro.
- Trans, FormatNumber, FormatDate, RelativeTime: 4 service components greppables
alrededor de uix.langs y uix.format. Nav group "Utilities".
Bugs fix arts/format/dates (engine-dates.ts):
1. Preset / per-axis conflict: Intl.DateTimeFormat rechaza dateStyle/timeStyle
con cualquier per-axis (weekday/era/year/month/day/dayPeriod/hour/minute/
second/fractionalSecondDigits) o con timeZoneName. Engine drop-ea ambos
presets por defecto cuando detecta conflict (regla estricta — un solo
per-axis hace ilegales los dos presets).
2. Per-call locale override: formatDate/Time/DateTime aceptan tercer arg
locale?: string. No muta engine state. Cache (getCachedDateFormat) keyea
por (locale x options). resolveCallHourCycle: cuando hay locale override
y pref auto, el ciclo horario se resuelve desde el locale OVERRIDE.
3. withHourCycle precedence: caller hourCycle/hour12 ahora gana sobre
preferencia del engine. Antes spread mal ordenado sobrescribia 'h12' del
caller con 'h23' del engine cuando locale resolvia a 24h.
FormatDate component vuelve a rutear siempre por uix.format.dates
(cache + hourCycle + locale reactivo), pasando locale como tercer arg.
Demos service components autonomos del toolbar global: cada uno owns su
demoLocale state con 7 chips (es-ES/en-US/en-GB/de-DE/fr-FR/ja-JP/ar-EG).
FormatDate stage filtra dateStyle/timeStyle por mode + chip hourCycle anadido.
Tests: 14/14 passing en engine-dates.test.ts (+6 nuevos: conflict handling,
locale override, hourCycle precedence).
Docs: arts/format/README.md (handoff 2026-05-25 con las 3 reglas),
README.md por service component, project_service_components_sprint_2026-05-25.md,
feedback_service_demos_own_locale.md (pattern reusable).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/trans', label: 'Trans' },
|
|
|
|
|
|
{ slug: '/uix/components/format-number', label: 'FormatNumber' },
|
|
|
|
|
|
{ slug: '/uix/components/format-date', label: 'FormatDate' },
|
|
|
|
|
|
{ slug: '/uix/components/relative-time', label: 'RelativeTime' }
|
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
]
|
|
|
|
|
|
},
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Overlays',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/dialog', label: 'Dialog' },
|
|
|
|
|
|
{ slug: '/uix/components/alert-dialog', label: 'Alert dialog' },
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/drawer', label: 'Drawer' },
|
|
|
|
|
|
{ slug: '/uix/components/popover', label: 'Popover' },
|
|
|
|
|
|
{ slug: '/uix/components/float-panel', label: 'Float panel' },
|
|
|
|
|
|
{ slug: '/uix/components/dropdown-menu', label: 'Dropdown menu' },
|
|
|
|
|
|
{ slug: '/uix/components/context-menu', label: 'Context menu' },
|
|
|
|
|
|
{ slug: '/uix/components/menubar', label: 'Menubar' },
|
|
|
|
|
|
{ slug: '/uix/components/onion-menu', label: 'Onion menu' },
|
|
|
|
|
|
{ slug: '/uix/components/menu-dial', label: 'Menu dial' },
|
|
|
|
|
|
{ slug: '/uix/components/command', label: 'Command' },
|
|
|
|
|
|
{ slug: '/uix/components/link-preview', label: 'Link preview' },
|
|
|
|
|
|
{ slug: '/uix/components/toast', label: 'Toast' },
|
|
|
|
|
|
{ slug: '/uix/components/tooltip', label: 'Tooltip' }
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
]
|
|
|
|
|
|
},
|
feat(typography): Text — POC consuming new --style-* foundation tokens
First typography primitive consuming the named-style tokens added in
`015bd761`. Sets the canon for the remaining typography ports
(Heading, Display, Code, CodeBlock, Kbd, Mark, Highlight, Link).
API:
- `style: 'body' | 'prose' | 'label' | 'caption'` (default `body`).
Selects which `--style-{name}-*` token set the recipe consumes.
- Per-axis overrides via `size`, `family`, `weight`, `color`, `align`.
Each writes a local `--_text-{axis}` CSS variable that wins over
the named style's default via the cascade.
- `italic`, `underline` shorthand booleans.
- `truncate` (single-line ellipsis) + `clamp={N}` (multi-line via
CSS `-webkit-line-clamp`).
- `as` prop switches the tag (default `'span'` — inline composable).
- `tagStyle` escape hatch for one-off inline CSS that the prop
surface doesn't cover (separate from the `style` named-style prop).
Architectural choices documented in README:
- Sizes map to eidos `xxs..xxxl` (not air's `1..12`).
- Families use the eidos slot names (`primary/secondary/mono/display`)
not air's domain aliases (`ui/prose/code`) — coherence with the
foundation contract.
- Colors are restricted to the content-role slots
(`--color-content-*`) to preserve contrast guarantees. Free colors
via `tagStyle`.
- Canvas line-count measurement (air's `text` + bindable `lineCount`)
deferred; CSS line-clamp covers the visual-truncate use case.
Sidebar nav gains a `Typography` group with Text as its first entry.
`npm run component:audit`: 82 / 82 PASS, 0 NEEDS-WORK. svelte-check 0
errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Typography',
|
feat(typography): 8 primitives — Heading, Display, Code, CodeBlock, Kbd, Mark, Highlight, Link
Full canon for the rest of the typography family, following Text
(commit `03531709`) as template. Each primitive ships morfo (passive,
scope eidos, 0 events) + full eidos set (svelte/css/types/index +
README with required sections) + canon 6-tab demo (≥400 lines each).
**Heading** — semantic h1..h6 via `level` prop, visual style decoupled
via `style` prop (defaults to match level but `<Heading level={3}
style="h1">` allowed). Demo 594 lines.
**Display** — always-h1 page-title primitive. Always uses
`style="hero"`. Tracking via literal em values until foundation emits
hero-scale tracking tokens. Demo 546 lines.
**Code** — inline code via `<code>`. `variant: 'plain' | 'soft' |
'outline'` for subtle background chrome. Demo 423 lines.
**CodeBlock** — multi-line `<pre><code>` with optional title +
copy button (button utility, NOT a sema verb — kept out of morfo per
2-of-3 rule). Demo 402 lines.
**Kbd** — keyboard shortcut chrome over `style="code"`. Demo 418 lines.
**Mark** — text highlight via `<mark>`. Palette uses canonical
`ColorRole` intents (default `fulfill` ≈ legacy yellow). Demo 402 lines.
**Highlight** — substring highlighter inside Text. Scans children for
`query` and wraps matches. Same intent palette as Mark. Demo 407 lines.
**Link** — text link via `<a>`. `variant: 'default' | 'subtle' |
'plain'` for underline style, `intent: ColorRole` for color. Passive
on the morfo — hover/active is CSS-only, navigation belongs to the
consumer (router). Demo 448 lines.
**Architectural deviations from air documented per README's
Decisiones section:**
- Heading: semantic level vs visual style decoupling
- Code split into inline `<Code>` + block `<CodeBlock>` (was one
component with `variant='block'` in air)
- Mark/Highlight palette swapped from literal hue names to canonical
ColorRole intents (theme contract)
- Link palette opened to full ColorRole; `quiet`/`emphasized` air
variants dropped in favour of composable patterns
`npm run component:audit`: **90 / 90 PASS**, 0 NEEDS-WORK.
svelte-check: 0 errors, 0 new warnings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/text', label: 'Text' },
|
feat(eidos): Card, Avatar ext, Image, SText, Badge, service components + dates engine fixes
Sprint completo:
- Card (eidos + sema): elevation/intent/interactive, eventos select+activate.
- Avatar: ring, AvatarBadge, AvatarGroup separados; demo Avatar standalone.
- Image: status surface (idle/loading/loaded/error) consumiendo soma ImageProvider.
- SText + STextVirtualList: canvas-text engine portado de morfo-driven-soma como
componentes separados para optimizar bundle (no se importa canvas si no se usa).
- Badge: primitivo eidos puro.
- Trans, FormatNumber, FormatDate, RelativeTime: 4 service components greppables
alrededor de uix.langs y uix.format. Nav group "Utilities".
Bugs fix arts/format/dates (engine-dates.ts):
1. Preset / per-axis conflict: Intl.DateTimeFormat rechaza dateStyle/timeStyle
con cualquier per-axis (weekday/era/year/month/day/dayPeriod/hour/minute/
second/fractionalSecondDigits) o con timeZoneName. Engine drop-ea ambos
presets por defecto cuando detecta conflict (regla estricta — un solo
per-axis hace ilegales los dos presets).
2. Per-call locale override: formatDate/Time/DateTime aceptan tercer arg
locale?: string. No muta engine state. Cache (getCachedDateFormat) keyea
por (locale x options). resolveCallHourCycle: cuando hay locale override
y pref auto, el ciclo horario se resuelve desde el locale OVERRIDE.
3. withHourCycle precedence: caller hourCycle/hour12 ahora gana sobre
preferencia del engine. Antes spread mal ordenado sobrescribia 'h12' del
caller con 'h23' del engine cuando locale resolvia a 24h.
FormatDate component vuelve a rutear siempre por uix.format.dates
(cache + hourCycle + locale reactivo), pasando locale como tercer arg.
Demos service components autonomos del toolbar global: cada uno owns su
demoLocale state con 7 chips (es-ES/en-US/en-GB/de-DE/fr-FR/ja-JP/ar-EG).
FormatDate stage filtra dateStyle/timeStyle por mode + chip hourCycle anadido.
Tests: 14/14 passing en engine-dates.test.ts (+6 nuevos: conflict handling,
locale override, hourCycle precedence).
Docs: arts/format/README.md (handoff 2026-05-25 con las 3 reglas),
README.md por service component, project_service_components_sprint_2026-05-25.md,
feedback_service_demos_own_locale.md (pattern reusable).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/s-text', label: 'SText' },
|
|
|
|
|
|
{ slug: '/uix/components/s-text-virtual-list', label: 'STextVirtualList' },
|
feat(typography): 8 primitives — Heading, Display, Code, CodeBlock, Kbd, Mark, Highlight, Link
Full canon for the rest of the typography family, following Text
(commit `03531709`) as template. Each primitive ships morfo (passive,
scope eidos, 0 events) + full eidos set (svelte/css/types/index +
README with required sections) + canon 6-tab demo (≥400 lines each).
**Heading** — semantic h1..h6 via `level` prop, visual style decoupled
via `style` prop (defaults to match level but `<Heading level={3}
style="h1">` allowed). Demo 594 lines.
**Display** — always-h1 page-title primitive. Always uses
`style="hero"`. Tracking via literal em values until foundation emits
hero-scale tracking tokens. Demo 546 lines.
**Code** — inline code via `<code>`. `variant: 'plain' | 'soft' |
'outline'` for subtle background chrome. Demo 423 lines.
**CodeBlock** — multi-line `<pre><code>` with optional title +
copy button (button utility, NOT a sema verb — kept out of morfo per
2-of-3 rule). Demo 402 lines.
**Kbd** — keyboard shortcut chrome over `style="code"`. Demo 418 lines.
**Mark** — text highlight via `<mark>`. Palette uses canonical
`ColorRole` intents (default `fulfill` ≈ legacy yellow). Demo 402 lines.
**Highlight** — substring highlighter inside Text. Scans children for
`query` and wraps matches. Same intent palette as Mark. Demo 407 lines.
**Link** — text link via `<a>`. `variant: 'default' | 'subtle' |
'plain'` for underline style, `intent: ColorRole` for color. Passive
on the morfo — hover/active is CSS-only, navigation belongs to the
consumer (router). Demo 448 lines.
**Architectural deviations from air documented per README's
Decisiones section:**
- Heading: semantic level vs visual style decoupling
- Code split into inline `<Code>` + block `<CodeBlock>` (was one
component with `variant='block'` in air)
- Mark/Highlight palette swapped from literal hue names to canonical
ColorRole intents (theme contract)
- Link palette opened to full ColorRole; `quiet`/`emphasized` air
variants dropped in favour of composable patterns
`npm run component:audit`: **90 / 90 PASS**, 0 NEEDS-WORK.
svelte-check: 0 errors, 0 new warnings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/heading', label: 'Heading' },
|
|
|
|
|
|
{ slug: '/uix/components/display', label: 'Display' },
|
|
|
|
|
|
{ slug: '/uix/components/code', label: 'Code' },
|
|
|
|
|
|
{ slug: '/uix/components/code-block', label: 'CodeBlock' },
|
|
|
|
|
|
{ slug: '/uix/components/kbd', label: 'Kbd' },
|
|
|
|
|
|
{ slug: '/uix/components/mark', label: 'Mark' },
|
|
|
|
|
|
{ slug: '/uix/components/highlight', label: 'Highlight' },
|
|
|
|
|
|
{ slug: '/uix/components/link', label: 'Link' }
|
|
|
|
|
|
]
|
feat(typography): Text — POC consuming new --style-* foundation tokens
First typography primitive consuming the named-style tokens added in
`015bd761`. Sets the canon for the remaining typography ports
(Heading, Display, Code, CodeBlock, Kbd, Mark, Highlight, Link).
API:
- `style: 'body' | 'prose' | 'label' | 'caption'` (default `body`).
Selects which `--style-{name}-*` token set the recipe consumes.
- Per-axis overrides via `size`, `family`, `weight`, `color`, `align`.
Each writes a local `--_text-{axis}` CSS variable that wins over
the named style's default via the cascade.
- `italic`, `underline` shorthand booleans.
- `truncate` (single-line ellipsis) + `clamp={N}` (multi-line via
CSS `-webkit-line-clamp`).
- `as` prop switches the tag (default `'span'` — inline composable).
- `tagStyle` escape hatch for one-off inline CSS that the prop
surface doesn't cover (separate from the `style` named-style prop).
Architectural choices documented in README:
- Sizes map to eidos `xxs..xxxl` (not air's `1..12`).
- Families use the eidos slot names (`primary/secondary/mono/display`)
not air's domain aliases (`ui/prose/code`) — coherence with the
foundation contract.
- Colors are restricted to the content-role slots
(`--color-content-*`) to preserve contrast guarantees. Free colors
via `tagStyle`.
- Canvas line-count measurement (air's `text` + bindable `lineCount`)
deferred; CSS line-clamp covers the visual-truncate use case.
Sidebar nav gains a `Typography` group with Text as its first entry.
`npm run component:audit`: 82 / 82 PASS, 0 NEEDS-WORK. svelte-check 0
errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
},
|
fix(demos): reachable nav + real interactive Ambient testbed + visible fog/mesh
The catalog work shipped but was unreachable and impoverished:
- **Nav**: the sidebar IA (web/routes/uix/+layout@.svelte) is a manual list;
the new components were never added, so nothing linked to them. Add a
"Text effects" group (TextGradient/Circular/Blur/Focus/Scramble), CountUp
under Utilities, and a "Packs" group (Ambient · backgrounds).
- **Ambient demo → real testbed**: rebuild web/routes/uix/packs/ambient as a
proper interactive page — effect selector (32, grouped Agentic/Tier A/B),
live param controls AUTO-GENERATED from each effect's `defaults`
(number→slider, boolean→toggle, colors→editable token list, string→text),
a stage-background toggle (surface/black/white/transparent), reset, and a
copyable usage snippet. The old page only switched effect, no tuning.
- **fog + mesh painted nothing**: their seeded colors were near-invisible on
the dark base theme — fog used neutral-bg2 (L 0.21) + neutral-element
(L 0.25), mesh used four -element slots (L ~0.26) against surface L 0.18.
Reseed with high-contrast tokens (fog: surface bg + neutral-text; mesh:
-solid stops). Verified in a real browser: aurora/mesh/fog all paint.
- Repoint the six demo ledes from the ephemeral plan to
docs/decisions/design-text-effects.md (matches the READMEs).
check 0 own errors. Verified live (real Chrome): all effects paint, controls
tune params, nav reaches every new page.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Text effects',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/count-up', label: 'CountUp' },
|
fix(demos): reachable nav + real interactive Ambient testbed + visible fog/mesh
The catalog work shipped but was unreachable and impoverished:
- **Nav**: the sidebar IA (web/routes/uix/+layout@.svelte) is a manual list;
the new components were never added, so nothing linked to them. Add a
"Text effects" group (TextGradient/Circular/Blur/Focus/Scramble), CountUp
under Utilities, and a "Packs" group (Ambient · backgrounds).
- **Ambient demo → real testbed**: rebuild web/routes/uix/packs/ambient as a
proper interactive page — effect selector (32, grouped Agentic/Tier A/B),
live param controls AUTO-GENERATED from each effect's `defaults`
(number→slider, boolean→toggle, colors→editable token list, string→text),
a stage-background toggle (surface/black/white/transparent), reset, and a
copyable usage snippet. The old page only switched effect, no tuning.
- **fog + mesh painted nothing**: their seeded colors were near-invisible on
the dark base theme — fog used neutral-bg2 (L 0.21) + neutral-element
(L 0.25), mesh used four -element slots (L ~0.26) against surface L 0.18.
Reseed with high-contrast tokens (fog: surface bg + neutral-text; mesh:
-solid stops). Verified in a real browser: aurora/mesh/fog all paint.
- Repoint the six demo ledes from the ephemeral plan to
docs/decisions/design-text-effects.md (matches the READMEs).
check 0 own errors. Verified live (real Chrome): all effects paint, controls
tune params, nav reaches every new page.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/text-gradient', label: 'TextGradient' },
|
|
|
|
|
|
{ slug: '/uix/components/text-circular', label: 'TextCircular' },
|
|
|
|
|
|
{ slug: '/uix/components/text-blur', label: 'TextBlur' },
|
|
|
|
|
|
{ slug: '/uix/components/text-focus', label: 'TextFocus' },
|
|
|
|
|
|
{ slug: '/uix/components/text-scramble', label: 'TextScramble' }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Packs',
|
|
|
|
|
|
items: [{ slug: '/uix/packs/ambient', label: 'Ambient · backgrounds', tag: 'pack' }]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
kind: 'group',
|
|
|
|
|
|
heading: 'Layout',
|
|
|
|
|
|
items: [
|
|
|
|
|
|
{ slug: '/uix/components/box', label: 'Box' },
|
|
|
|
|
|
{ slug: '/uix/components/flex', label: 'Flex' },
|
|
|
|
|
|
{ slug: '/uix/components/grid', label: 'Grid' },
|
|
|
|
|
|
{ slug: '/uix/components/stack', label: 'Stack' },
|
|
|
|
|
|
{ slug: '/uix/components/group', label: 'Group' },
|
|
|
|
|
|
{ slug: '/uix/components/wrap', label: 'Wrap' },
|
|
|
|
|
|
{ slug: '/uix/components/container', label: 'Container' },
|
feat(layout): Layout Batch 2 — aspect-ratio, auto-grid, banner, float
4 new layout primitives, full canon (morfo + eidos full set + canon
demo + README). `npm run component:audit`: 81 / 81 PASS, 0 NEEDS-WORK.
**AspectRatio** — composes through Box; emits single `--aspect-ratio`
CSS var (uses modern CSS `aspect-ratio` property, drops legacy
padding-bottom hack). Accepts numeric (16/9 → 1.777…) or string
("16/9") values.
**AutoGrid** — composes through Grid. Resolves `templateColumns` from
`minItemWidth` to `repeat(auto-fill, minmax(MIN, 1fr))` in JS so the
recipe stays declarative. Uses `auto-fill` (not auto-fit) to preserve
empty tracks when item count is low.
**Banner** — `<header role="banner">` announcement strip with intent
(full 8-role UIX `ColorRole`), variant (`ChipVariant` soft/solid/
outline/ghost), size (sm/md/lg). Dismissal is composition-driven:
consumer wraps in {#if show} and adds `<Banner.Close>`. No
`dismissible` boolean.
**Float** — CSS `float` primitive with logical `inline-start` /
`inline-end` sides. Redefined from air's 9-zone overlay primitive
(which becomes a future `<Positioned>` component if real demand
surfaces). Useful for inline images / pull-quotes / drop caps.
Each component ships morfo (`scope: ['eidos']`, 1 part, 0 events,
justified) + eidos set + README (Baseline / Comparativa /
Decisiones / Eventos Sema / Gaps with disposition markers /
Referencias / Passive justification) + canon demo with 6 tabs.
Sidebar nav appends the 4 entries to the existing Layout group.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/section', label: 'Section' },
|
|
|
|
|
|
{ slug: '/uix/components/aspect-ratio', label: 'AspectRatio' },
|
|
|
|
|
|
{ slug: '/uix/components/auto-grid', label: 'AutoGrid' },
|
|
|
|
|
|
{ slug: '/uix/components/banner', label: 'Banner' },
|
feat(eidos): Card, Avatar ext, Image, SText, Badge, service components + dates engine fixes
Sprint completo:
- Card (eidos + sema): elevation/intent/interactive, eventos select+activate.
- Avatar: ring, AvatarBadge, AvatarGroup separados; demo Avatar standalone.
- Image: status surface (idle/loading/loaded/error) consumiendo soma ImageProvider.
- SText + STextVirtualList: canvas-text engine portado de morfo-driven-soma como
componentes separados para optimizar bundle (no se importa canvas si no se usa).
- Badge: primitivo eidos puro.
- Trans, FormatNumber, FormatDate, RelativeTime: 4 service components greppables
alrededor de uix.langs y uix.format. Nav group "Utilities".
Bugs fix arts/format/dates (engine-dates.ts):
1. Preset / per-axis conflict: Intl.DateTimeFormat rechaza dateStyle/timeStyle
con cualquier per-axis (weekday/era/year/month/day/dayPeriod/hour/minute/
second/fractionalSecondDigits) o con timeZoneName. Engine drop-ea ambos
presets por defecto cuando detecta conflict (regla estricta — un solo
per-axis hace ilegales los dos presets).
2. Per-call locale override: formatDate/Time/DateTime aceptan tercer arg
locale?: string. No muta engine state. Cache (getCachedDateFormat) keyea
por (locale x options). resolveCallHourCycle: cuando hay locale override
y pref auto, el ciclo horario se resuelve desde el locale OVERRIDE.
3. withHourCycle precedence: caller hourCycle/hour12 ahora gana sobre
preferencia del engine. Antes spread mal ordenado sobrescribia 'h12' del
caller con 'h23' del engine cuando locale resolvia a 24h.
FormatDate component vuelve a rutear siempre por uix.format.dates
(cache + hourCycle + locale reactivo), pasando locale como tercer arg.
Demos service components autonomos del toolbar global: cada uno owns su
demoLocale state con 7 chips (es-ES/en-US/en-GB/de-DE/fr-FR/ja-JP/ar-EG).
FormatDate stage filtra dateStyle/timeStyle por mode + chip hourCycle anadido.
Tests: 14/14 passing en engine-dates.test.ts (+6 nuevos: conflict handling,
locale override, hourCycle precedence).
Docs: arts/format/README.md (handoff 2026-05-25 con las 3 reglas),
README.md por service component, project_service_components_sprint_2026-05-25.md,
feedback_service_demos_own_locale.md (pattern reusable).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/card', label: 'Card' },
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
|
{ slug: '/uix/components/card-group', label: 'CardGroup' },
|
feat(layout): Layout Batch 3 — scroll-area, separator, splitter + splitter sema rewire
3 new layout primitives close the air port set (15 / 15 done).
`npm run component:audit`: 91 / 91 PASS, all 3 new PASS with 0 errors.
**scroll-area** — eidos compound wrapper over the existing soma:
`<ScrollArea><ScrollArea.Viewport>{content}</ScrollArea.Viewport>
<ScrollArea.Scrollbar orientation="vertical"><ScrollArea.Thumb />
</ScrollArea.Scrollbar><ScrollArea.Corner /></ScrollArea>`. Mirrors
Radix Primitives / Bits UI shape. Demo 667 lines.
**separator** — visual primitive (`scope: ['eidos']`) with conditional
ARIA: `role="separator"` + `aria-orientation` when not decorative,
`aria-hidden="true"` when decorative. New morfo
`src/uix/morfo/components/separator.ts`. Demo 645 lines.
**splitter** — eidos compound over existing soma:
`<Splitter orientation="horizontal"><Splitter.Panel>{a}</Splitter.Panel>
<Splitter.ResizeTrigger /><Splitter.Panel>{b}</Splitter.Panel>
</Splitter>`. Demo 824 lines.
**Splitter sema rewire — match Slider's handle/drag/commit shape:**
The morfo previously declared only `commit-resize`. Direct-manipulation
primitives (Slider, Splitter) should share the same event vocabulary so
audio/haptic projections feel coherent across the family. Renamed +
expanded to mirror Slider:
- `handle-pick` (family: handle, verb: pick, sequence: coincident,
target: resize-trigger) — fires on pointerdown when user grabs the
trigger.
- `handle-drag` (family: handle, verb: drag, sequence: coincident,
target: resize-trigger) — fires on each pointermove frame.
- `commit-set` (family: commit, verb: set, intent: neutral,
sequence: post, target: provider) — fires on pointerup. The runtime
`commit-set` handler is wired to call the consumer's `onResizeEnd`
callback, so sema and JS callback land at the same moment (parity
with Slider's `onValueCommit`).
Soma provider triggers these via `this.runtime.trigger(name)` in
`onpointerdown` / `onpointermove` / `notifyResizeEnd` (the latter
unchanged externally — internally now routes through the runtime
trigger).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{ slug: '/uix/components/float', label: 'Float' },
|
|
|
|
|
|
{ slug: '/uix/components/scroll-area', label: 'ScrollArea' },
|
|
|
|
|
|
{ slug: '/uix/components/separator', label: 'Separator' },
|
|
|
|
|
|
{ slug: '/uix/components/splitter', label: 'Splitter' }
,
|
|
|
|
|
|
{ slug: '/uix/components/sticky', label: 'Sticky' }
|
|
|
|
|
|
]
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const componentCount = $derived(
|
|
|
|
|
|
nav
|
|
|
|
|
|
.filter((s): s is Extract<Section, { kind: 'group' }> => s.kind === 'group')
|
|
|
|
|
|
.filter((g) => ['Controls', 'Media', 'Overlays'].includes(g.heading))
|
|
|
|
|
|
.reduce((acc, g) => acc + g.items.length, 0)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const current = $derived(page.url.pathname.replace(/\/$/, '') || '/uix');
|
|
|
|
|
|
|
|
|
|
|
|
// ── Theme ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
let theme = $state<'light' | 'dark'>('light');
|
|
|
|
|
|
const eidosModeListeners = new Set<(value: 'light' | 'dark') => void>();
|
|
|
|
|
|
const activeEidos = ActiveEidos.create({
|
|
|
|
|
|
applyDom: true,
|
|
|
|
|
|
theme: 'base',
|
|
|
|
|
|
modeSource: {
|
|
|
|
|
|
get: () => theme,
|
|
|
|
|
|
onChange(handler) {
|
|
|
|
|
|
eidosModeListeners.add(handler);
|
|
|
|
|
|
return () => eidosModeListeners.delete(handler);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// A small canonical named-gradient set for the docs site — role-derived, so
|
|
|
|
|
|
// they re-tint with the seed and flip light/dark for free (the whole point of
|
|
|
|
|
|
// the gradient axis). Components name them: `<TextGradient colors="brand">`,
|
|
|
|
|
|
// `background: var(--gradient-brand)`. Both are LINEAR (a single `<image>`),
|
|
|
|
|
|
// so they're valid `background-image` values and paint through `background-clip:
|
|
|
|
|
|
// text` — a role-derived MESH (aurora) carries a base color and would not.
|
|
|
|
|
|
const brandGradient: Gradient = {
|
|
|
|
|
|
kind: 'linear',
|
|
|
|
|
|
angle: 110,
|
|
|
|
|
|
interpolation: { space: 'oklch' },
|
|
|
|
|
|
stops: [
|
|
|
|
|
|
{ color: { kind: 'role', role: 'primary', slot: 'solid' } },
|
|
|
|
|
|
{ color: { kind: 'role', role: 'secondary', slot: 'solid' } },
|
|
|
|
|
|
{ color: { kind: 'role', role: 'tertiary', slot: 'solid' } }
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
const spectrumGradient: Gradient = {
|
|
|
|
|
|
kind: 'linear',
|
|
|
|
|
|
angle: 90,
|
|
|
|
|
|
interpolation: { space: 'oklch', hue: 'longer' },
|
|
|
|
|
|
stops: [
|
|
|
|
|
|
{ color: { kind: 'role', role: 'primary', slot: 'solid' } },
|
|
|
|
|
|
{ color: { kind: 'role', role: 'affirm', slot: 'solid' } },
|
|
|
|
|
|
{ color: { kind: 'role', role: 'secondary', slot: 'solid' } },
|
|
|
|
|
|
{ color: { kind: 'role', role: 'risk', slot: 'solid' } },
|
|
|
|
|
|
{ color: { kind: 'role', role: 'loss', slot: 'solid' } }
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
activeEidos.applyGradients({ brand: brandGradient, spectrum: spectrumGradient });
|
|
|
|
|
|
|
|
|
|
|
|
onDestroy(() => {
|
|
|
|
|
|
prefsProjection.dispose();
|
|
|
|
|
|
activeEidos.dispose();
|
|
|
|
|
|
uix.dispose();
|
|
|
|
|
|
});
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
|
if (typeof document === 'undefined') return;
|
|
|
|
|
|
const stored = localStorage.getItem('uix-docs-theme');
|
|
|
|
|
|
if (stored === 'dark' || stored === 'light') {
|
|
|
|
|
|
theme = stored;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches;
|
|
|
|
|
|
theme = prefersDark ? 'dark' : 'light';
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
|
if (typeof localStorage === 'undefined') return;
|
|
|
|
|
|
localStorage.setItem('uix-docs-theme', theme);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
|
const currentTheme = theme;
|
|
|
|
|
|
for (const listener of eidosModeListeners) listener(currentTheme);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
let search = $state('');
|
|
|
|
|
|
|
|
|
|
|
|
// ── Topbar prefs ──────────────────────────────────────────────────────
|
|
|
|
|
|
// All persisted to localStorage. The sema toggles will wire to the
|
|
|
|
|
|
// engine's channels once those expose runtime setEnabled APIs; today
|
|
|
|
|
|
// they store preference + reflect it in the UI.
|
|
|
|
|
|
|
|
|
|
|
|
let dir = $state<'ltr' | 'rtl'>('ltr');
|
|
|
|
|
|
let language = $state<Language>('es');
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
let currency = $state<Currency>('EUR');
|
|
|
|
|
|
let units = $state<UnitSystem>('metric');
|
|
|
|
|
|
let numberFormat = $state<NumberFormat>('es-ES');
|
|
|
|
|
|
let soundOn = $state(true);
|
|
|
|
|
|
let motionOn = $state(true);
|
|
|
|
|
|
let hapticOn = $state(true);
|
|
|
|
|
|
|
|
|
|
|
|
// ── Display axes — the interrelated theming knobs (density · scaling · border
|
|
|
|
|
|
// width). Projected onto :root (below) via a managed stylesheet so EVERY demo —
|
|
|
|
|
|
// including portaled overlays (dialog/popover) — reflects the change live.
|
|
|
|
|
|
type Density = 'compact' | 'comfortable' | 'spacious';
|
|
|
|
|
|
const DENSITIES: readonly Density[] = ['compact', 'comfortable', 'spacious'];
|
|
|
|
|
|
const DENSITY_SCALES: Record<Density, { space: number; control: number }> = {
|
|
|
|
|
|
compact: { space: 0.84, control: 0.9 },
|
|
|
|
|
|
comfortable: { space: 1, control: 1 },
|
|
|
|
|
|
spacious: { space: 1.16, control: 1.12 }
|
|
|
|
|
|
};
|
|
|
|
|
|
let density = $state<Density>('comfortable');
|
|
|
|
|
|
let scaling = $state(1);
|
|
|
|
|
|
let borderWidth = $state(1);
|
|
|
|
|
|
|
|
|
|
|
|
const LANGUAGE_LABELS: Record<Language, string> = {
|
|
|
|
|
|
es: 'Español',
|
|
|
|
|
|
en: 'English',
|
|
|
|
|
|
fr: 'Français',
|
|
|
|
|
|
de: 'Deutsch'
|
|
|
|
|
|
};
|
|
|
|
|
|
const CURRENCY_LABELS: Record<Currency, string> = {
|
|
|
|
|
|
EUR: 'Euro',
|
|
|
|
|
|
USD: 'US Dollar',
|
|
|
|
|
|
GBP: 'British Pound',
|
|
|
|
|
|
JPY: 'Japanese Yen'
|
|
|
|
|
|
};
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
const UNIT_LABELS: Record<UnitSystem, string> = { metric: 'Metric', imperial: 'Imperial' };
|
|
|
|
|
|
const NUMBER_LABELS: Record<NumberFormat, string> = {
|
|
|
|
|
|
'es-ES': 'Spain · 1.234,56',
|
|
|
|
|
|
'en-US': 'US · 1,234.56',
|
|
|
|
|
|
'en-GB': 'UK · 1,234.56',
|
|
|
|
|
|
'de-DE': 'Germany · 1.234,56'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Persist all topbar prefs in one bag.
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
|
if (typeof localStorage === 'undefined') return;
|
|
|
|
|
|
const stored = localStorage.getItem('uix-docs-prefs');
|
|
|
|
|
|
if (!stored) return;
|
|
|
|
|
|
try {
|
|
|
|
|
|
const p = JSON.parse(stored);
|
|
|
|
|
|
if (p.dir === 'ltr' || p.dir === 'rtl') dir = p.dir;
|
|
|
|
|
|
if (p.language) language = p.language;
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
if (p.currency) currency = p.currency;
|
|
|
|
|
|
if (p.units) units = p.units;
|
|
|
|
|
|
if (p.numberFormat) numberFormat = p.numberFormat;
|
|
|
|
|
|
if (typeof p.soundOn === 'boolean') soundOn = p.soundOn;
|
|
|
|
|
|
if (typeof p.motionOn === 'boolean') motionOn = p.motionOn;
|
|
|
|
|
|
if (typeof p.hapticOn === 'boolean') hapticOn = p.hapticOn;
|
|
|
|
|
|
if (p.density === 'compact' || p.density === 'comfortable' || p.density === 'spacious')
|
|
|
|
|
|
density = p.density;
|
|
|
|
|
|
if (typeof p.scaling === 'number') scaling = p.scaling;
|
|
|
|
|
|
if (typeof p.borderWidth === 'number') borderWidth = p.borderWidth;
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
} catch {
|
|
|
|
|
|
/* ignore corrupt prefs blob */
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
|
if (typeof localStorage === 'undefined') return;
|
|
|
|
|
|
const blob = {
|
|
|
|
|
|
dir,
|
|
|
|
|
|
language,
|
|
|
|
|
|
currency,
|
|
|
|
|
|
units,
|
|
|
|
|
|
numberFormat,
|
|
|
|
|
|
soundOn,
|
|
|
|
|
|
motionOn,
|
|
|
|
|
|
hapticOn,
|
|
|
|
|
|
density,
|
|
|
|
|
|
scaling,
|
|
|
|
|
|
borderWidth
|
|
|
|
|
|
};
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
localStorage.setItem('uix-docs-prefs', JSON.stringify(blob));
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
|
uix.prefs.setIntent('language', language);
|
|
|
|
|
|
uix.prefs.setIntent('direction', dir);
|
|
|
|
|
|
uix.prefs.setIntent('locale', numberFormat);
|
|
|
|
|
|
uix.prefs.setIntent('currency', currency);
|
|
|
|
|
|
uix.prefs.setIntent('unitSystem', units);
|
|
|
|
|
|
uix.prefs.setIntent('sound', soundOn ? 'allow' : 'reduce');
|
|
|
|
|
|
uix.prefs.setIntent('motion', motionOn ? 'allow' : 'reduce');
|
|
|
|
|
|
uix.prefs.setIntent('haptic', hapticOn ? 'allow' : 'reduce');
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Project the display axes onto :root through a managed <style> (id-keyed, so
|
|
|
|
|
|
// it replaces in place). :root — not the docs shell — so portaled overlays,
|
|
|
|
|
|
// which render outside the shell, inherit the same density/scaling/border.
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
|
const d = DENSITY_SCALES[density];
|
|
|
|
|
|
uix.dom.writeStyle(
|
|
|
|
|
|
'uix-docs-display',
|
|
|
|
|
|
`:root{--density-space-scale:${d.space};--density-control-scale:${d.control};--scaling:${scaling};--border-width:${borderWidth}px;}`
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
const filteredNav = $derived.by(() => {
|
|
|
|
|
|
const q = search.trim().toLowerCase();
|
|
|
|
|
|
if (!q) return nav;
|
|
|
|
|
|
return nav
|
|
|
|
|
|
.map((s) => {
|
|
|
|
|
|
if (s.kind !== 'group') return s;
|
|
|
|
|
|
const items = s.items.filter((i) => i.label.toLowerCase().includes(q));
|
|
|
|
|
|
return items.length ? { ...s, items } : null;
|
|
|
|
|
|
})
|
|
|
|
|
|
.filter((s): s is Section => s !== null);
|
|
|
|
|
|
});
|
feat: build PasswordField (full stack)
Dedicated password input component — matches the Ark UI / Chakra v3 /
Mantine / PrimeReact / Ant Design pattern of treating PasswordField as
its own first-class component (not a TextField variant). Includes one
feature that NO surveyed library ships: a CapsLock indicator driven by
KeyboardEvent.getModifierState('CapsLock').
Anatomy (5 parts, 4 events):
- Provider (root, value + visibility state)
- Input (the textbox; type flips between password / text)
- VisibilityTrigger (eye toggle button; aria-pressed + aria-controls)
- CapsLockIndicator (status live region; data-active toggles via soma
listening to keydown/keyup on Input)
- StrengthMeter (composable; consumer provides 0-4 score; UIX bundles
no zxcvbn-style algorithm — dependency-free by design)
Events:
- commit-input (every keystroke)
- commit-submit (Enter)
- shift-toggle-visibility (eye click)
- shift-caps-state (Caps Lock state flips while focused)
Key behaviors:
- `purpose: 'current' | 'new'` drives native autocomplete attribute
('current-password' for login / 'new-password' for registration).
- Field integration: disabled/readonly/required/invalid OR-merged.
- VisibilityTrigger gets tabindex=-1 so it doesn't break the form's
natural tab order — mouse / programmatic focus only, matching Ark UI.
- Caps Lock indicator is aria-live="polite" — announces on activation
while focused, silent when inactive.
- Letter-spacing increased on the input for legibility while masked.
Reference library survey performed (10 libraries) before implementation —
all consensus around dedicated component, all have built-in toggle,
ZERO have caps lock warning. Documented in the demo's API tab with a
feature comparison table.
Demo follows DEMO_AUTHORING_GUIDE canonical 6-tab depth: Live (controls
grouped by layer + code snippets at the bottom), API (props + reference
comparison), Morfo (field/value + Parts + Events tables), Sema (events
table with ▶ play), Recipe (selectors with morfo/eidos owner tags), A11y
(concern/contract table).
Also includes external work in words/ from a separate session
(unrelated to PasswordField) — not touching Words is the standing rule,
but the diff was already in the working tree.
svelte-check: 0 errors in PasswordField files (Words errors are tracked
by its own development branch).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
|
|
|
|
|
|
const currentBreakpoint = $derived(uix.dom.currentBreakpoint.current);
|
|
|
|
|
|
const compactShell = $derived(
|
|
|
|
|
|
currentBreakpoint === 'base' || currentBreakpoint === 'sm' || currentBreakpoint === 'md'
|
|
|
|
|
|
);
|
|
|
|
|
|
const phoneShell = $derived(currentBreakpoint === 'base');
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</script>
|
|
|
|
|
|
|
feat: build PasswordField (full stack)
Dedicated password input component — matches the Ark UI / Chakra v3 /
Mantine / PrimeReact / Ant Design pattern of treating PasswordField as
its own first-class component (not a TextField variant). Includes one
feature that NO surveyed library ships: a CapsLock indicator driven by
KeyboardEvent.getModifierState('CapsLock').
Anatomy (5 parts, 4 events):
- Provider (root, value + visibility state)
- Input (the textbox; type flips between password / text)
- VisibilityTrigger (eye toggle button; aria-pressed + aria-controls)
- CapsLockIndicator (status live region; data-active toggles via soma
listening to keydown/keyup on Input)
- StrengthMeter (composable; consumer provides 0-4 score; UIX bundles
no zxcvbn-style algorithm — dependency-free by design)
Events:
- commit-input (every keystroke)
- commit-submit (Enter)
- shift-toggle-visibility (eye click)
- shift-caps-state (Caps Lock state flips while focused)
Key behaviors:
- `purpose: 'current' | 'new'` drives native autocomplete attribute
('current-password' for login / 'new-password' for registration).
- Field integration: disabled/readonly/required/invalid OR-merged.
- VisibilityTrigger gets tabindex=-1 so it doesn't break the form's
natural tab order — mouse / programmatic focus only, matching Ark UI.
- Caps Lock indicator is aria-live="polite" — announces on activation
while focused, silent when inactive.
- Letter-spacing increased on the input for legibility while masked.
Reference library survey performed (10 libraries) before implementation —
all consensus around dedicated component, all have built-in toggle,
ZERO have caps lock warning. Documented in the demo's API tab with a
feature comparison table.
Demo follows DEMO_AUTHORING_GUIDE canonical 6-tab depth: Live (controls
grouped by layer + code snippets at the bottom), API (props + reference
comparison), Morfo (field/value + Parts + Events tables), Sema (events
table with ▶ play), Recipe (selectors with morfo/eidos owner tags), A11y
(concern/contract table).
Also includes external work in words/ from a separate session
(unrelated to PasswordField) — not touching Words is the standing rule,
but the diff was already in the working tree.
svelte-check: 0 errors in PasswordField files (Words errors are tracked
by its own development branch).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
<div
|
|
|
|
|
|
data-uix-docs
|
|
|
|
|
|
data-theme={theme}
|
|
|
|
|
|
data-mode={theme}
|
|
|
|
|
|
data-uix-breakpoint={currentBreakpoint}
|
|
|
|
|
|
data-uix-compact={compactShell ? 'true' : 'false'}
|
|
|
|
|
|
data-uix-phone={phoneShell ? 'true' : 'false'}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div data-uix-shell>
|
|
|
|
|
|
<header data-uix-topbar>
|
uix: date-picker + date-range-picker components + component audit infra
Two new Eidos components shipped end-to-end (wrapper + recipe + demo +
Soma provider hardening) plus a checklist-driven audit pipeline that
scores all 67 morfo components against doctrinal completion criteria.
New components:
- date-picker: full popover-anchored picker over date-field + calendar,
with calendar/content/trigger parts and demo route.
- date-range-picker: standalone wrapper with own calendar/grid/segment
surface, demo route, and recipe CSS.
- Both wrappers follow Option C disciplined (root + parts attached via
explicit assignment, no Object.assign).
Supporting Soma changes:
- range-calendar provider tightened (211 LOC of behavior, 167 LOC of
tests), README brought up to component doctrine.
- date-field, date-picker, date-range-field, date-range-picker Soma
providers + READMEs updated for new wrappers.
- popover provider/close gain props needed by the picker wrappers.
Morfo updates:
- date-picker / date-range-picker / range-calendar morfos refined for
the new APIs (parts, events, ARIA).
Audit infrastructure (new):
- src/uix/COMPONENT_COMPLETION_CHECKLIST.md — 81 doctrinal rules across
morfo / eidos wrapper / recipe CSS / demo / README / cross-layer
scripts. Each rule keyed to active_architecture.md, GUIA_IMPLEMENTACION
and DEMO_AUTHORING_GUIDE.
- scripts/component-audit.ts + `npm run component:audit` — regex parser
over all 67 components, emits tmp/component-audit.md with summary
scoreboard + per-component findings. Validates against canonical
SEMA_FAMILIES / SEMA_VERBS / ARCHETYPE_VOCABULARY / INTENTS.
- Initial baseline: 1 PASS, 64 NEEDS-WORK, 2 BROKEN (tooltip,
date-range-picker). Top systemic gaps: translations.label (49),
README Gaps/Comparativa/Baseline sections (87 combined), keyboard
/event ratio under-declaration (15), apg URL absent (19).
Misc:
- src/uix/kimi-audit-eidos.md — supplementary audit notes.
- .gitignore: ignore .codex-* agent scratch artifacts at repo root.
- continue.md + READMEs updated through the migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
<a
|
|
|
|
|
|
href="/uix"
|
|
|
|
|
|
data-uix-brand
|
|
|
|
|
|
data-sveltekit-preload-code="hover"
|
|
|
|
|
|
data-sveltekit-preload-data="hover"
|
|
|
|
|
|
>
|
|
|
|
|
|
<span data-uix-brand-mark>U</span>
|
|
|
|
|
|
<span>UIX</span>
|
|
|
|
|
|
<span data-uix-brand-version>v0.1</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
<nav data-uix-topbar-nav aria-label="Primary">
|
|
|
|
|
|
<a
|
|
|
|
|
|
href="/uix"
|
|
|
|
|
|
data-sveltekit-preload-code="hover"
|
|
|
|
|
|
data-sveltekit-preload-data="hover"
|
|
|
|
|
|
data-active={current === '/uix' ||
|
|
|
|
|
|
current.startsWith('/uix/architecture') ||
|
|
|
|
|
|
current.startsWith('/uix/getting-started')
|
|
|
|
|
|
? 'true'
|
|
|
|
|
|
: 'false'}>Docs</a
|
|
|
|
|
|
>
|
|
|
|
|
|
<a
|
|
|
|
|
|
href="/uix/components"
|
|
|
|
|
|
data-sveltekit-preload-code="hover"
|
|
|
|
|
|
data-sveltekit-preload-data="hover"
|
|
|
|
|
|
data-active={current.startsWith('/uix/components') ? 'true' : 'false'}>Components</a
|
|
|
|
|
|
>
|
|
|
|
|
|
<a href="https://github.com/" target="_blank" rel="noreferrer">GitHub ↗</a>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
|
|
<div data-uix-topbar-tools>
|
|
|
|
|
|
<!-- DIR: simple toggle. RTL flips the entire document direction
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
so all eidos components (which use logical properties)
|
|
|
|
|
|
reverse correctly. -->
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-icon-btn
|
|
|
|
|
|
title={dir === 'ltr' ? 'Switch to RTL' : 'Switch to LTR'}
|
|
|
|
|
|
aria-label="Toggle direction"
|
|
|
|
|
|
aria-pressed={dir === 'rtl'}
|
|
|
|
|
|
onclick={() => (dir = dir === 'ltr' ? 'rtl' : 'ltr')}
|
|
|
|
|
|
>
|
|
|
|
|
|
{#if dir === 'ltr'}
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="M5 12h14M13 6l6 6-6 6" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
{:else}
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="M19 12H5M11 6l-6 6 6 6" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- LANG: short uppercase code + popover with full language list -->
|
|
|
|
|
|
<Popover>
|
|
|
|
|
|
<Popover.Trigger>
|
|
|
|
|
|
<span data-uix-label-btn>
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<circle cx="12" cy="12" r="10" />
|
|
|
|
|
|
<path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20" />
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</svg>
|
|
|
|
|
|
{language.toUpperCase()}
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
data-caret
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="m6 9 6 6 6-6" />
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</Popover.Trigger>
|
|
|
|
|
|
<Popover.Content side="bottom" align="end" sideOffset={6}>
|
|
|
|
|
|
<div data-uix-menu>
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Language</div>
|
|
|
|
|
|
{#each Object.entries(LANGUAGE_LABELS) as [code, label]}
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-menu-item
|
|
|
|
|
|
data-checked={language === code ? 'true' : 'false'}
|
|
|
|
|
|
onclick={() => (language = code as Language)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<span>{label}</span>
|
|
|
|
|
|
<span data-uix-menu-item-meta>{code.toUpperCase()}</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
{/each}
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Popover.Content>
|
|
|
|
|
|
</Popover>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- FORMATS: currency + units + number formatting in one popover -->
|
|
|
|
|
|
<Popover>
|
|
|
|
|
|
<Popover.Trigger>
|
|
|
|
|
|
<span data-uix-label-btn>
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
Formats
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
data-caret
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="m6 9 6 6 6-6" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</Popover.Trigger>
|
|
|
|
|
|
<Popover.Content side="bottom" align="end" sideOffset={6}>
|
|
|
|
|
|
<div data-uix-menu style="min-inline-size: 240px;">
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Currency</div>
|
|
|
|
|
|
{#each Object.entries(CURRENCY_LABELS) as [code, label]}
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-menu-item
|
|
|
|
|
|
data-checked={currency === code ? 'true' : 'false'}
|
|
|
|
|
|
onclick={() => (currency = code as Currency)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<span>{label}</span>
|
|
|
|
|
|
<span data-uix-menu-item-meta>{code}</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Units</div>
|
|
|
|
|
|
{#each Object.entries(UNIT_LABELS) as [code, label]}
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-menu-item
|
|
|
|
|
|
data-checked={units === code ? 'true' : 'false'}
|
|
|
|
|
|
onclick={() => (units = code as UnitSystem)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<span>{label}</span>
|
|
|
|
|
|
<span data-uix-menu-item-meta
|
|
|
|
|
|
>{code === 'metric' ? 'KM · KG · °C' : 'MI · LB · °F'}</span
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
{/each}
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</div>
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Numbers</div>
|
|
|
|
|
|
{#each Object.entries(NUMBER_LABELS) as [code, label]}
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-menu-item
|
|
|
|
|
|
data-checked={numberFormat === code ? 'true' : 'false'}
|
|
|
|
|
|
onclick={() => (numberFormat = code as NumberFormat)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<span>{label}</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Popover.Content>
|
|
|
|
|
|
</Popover>
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
|
|
|
|
|
|
<!-- DISPLAY: density / scaling / border width — the interrelated
|
|
|
|
|
|
theming axes, applied to :root so every demo (including
|
|
|
|
|
|
portaled overlays) reflects the change live. -->
|
|
|
|
|
|
<Popover>
|
|
|
|
|
|
<Popover.Trigger>
|
|
|
|
|
|
<span data-uix-label-btn>
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<line x1="4" y1="7" x2="20" y2="7" />
|
|
|
|
|
|
<circle cx="9" cy="7" r="2.5" />
|
|
|
|
|
|
<line x1="4" y1="17" x2="20" y2="17" />
|
|
|
|
|
|
<circle cx="15" cy="17" r="2.5" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
Display
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
data-caret
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="m6 9 6 6 6-6" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</Popover.Trigger>
|
|
|
|
|
|
<Popover.Content side="bottom" align="end" sideOffset={6}>
|
|
|
|
|
|
<div data-uix-menu style="min-inline-size: 252px;">
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Density</div>
|
|
|
|
|
|
{#each DENSITIES as d}
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-menu-item
|
|
|
|
|
|
data-checked={density === d ? 'true' : 'false'}
|
|
|
|
|
|
onclick={() => (density = d)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<span style="text-transform: capitalize;">{d}</span>
|
|
|
|
|
|
<span data-uix-menu-item-meta
|
|
|
|
|
|
>{DENSITY_SCALES[d].space}× · {DENSITY_SCALES[d].control}×</span
|
|
|
|
|
|
>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Scaling · {scaling.toFixed(2)}×</div>
|
|
|
|
|
|
<input
|
|
|
|
|
|
data-uix-range
|
|
|
|
|
|
type="range"
|
|
|
|
|
|
min="0.85"
|
|
|
|
|
|
max="1.25"
|
|
|
|
|
|
step="0.05"
|
|
|
|
|
|
bind:value={scaling}
|
|
|
|
|
|
aria-label="Scaling factor"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Border width · {borderWidth}px</div>
|
|
|
|
|
|
<input
|
|
|
|
|
|
data-uix-range
|
|
|
|
|
|
type="range"
|
|
|
|
|
|
min="0"
|
|
|
|
|
|
max="4"
|
|
|
|
|
|
step="0.5"
|
|
|
|
|
|
bind:value={borderWidth}
|
|
|
|
|
|
aria-label="Border width"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-menu-item
|
|
|
|
|
|
onclick={() => {
|
|
|
|
|
|
density = 'comfortable';
|
|
|
|
|
|
scaling = 1;
|
|
|
|
|
|
borderWidth = 1;
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<span>Reset</span>
|
|
|
|
|
|
<span data-uix-menu-item-meta>comfortable · 1× · 1px</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Popover.Content>
|
|
|
|
|
|
</Popover>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- SEMANTICS: sound / motion / haptic toggles. These will hook
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
into the sema engine channels' enabled state once the
|
|
|
|
|
|
channels expose runtime setEnabled APIs; today they
|
|
|
|
|
|
persist preference + reflect in the UI. -->
|
|
|
|
|
|
<Popover>
|
|
|
|
|
|
<Popover.Trigger>
|
|
|
|
|
|
<span data-uix-label-btn>
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path
|
|
|
|
|
|
d="M12 2a4 4 0 0 1 4 4v6a4 4 0 0 1-8 0V6a4 4 0 0 1 4-4zM19 10v2a7 7 0 0 1-14 0v-2M12 19v3"
|
|
|
|
|
|
/>
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</svg>
|
|
|
|
|
|
Semantics
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
data-caret
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="m6 9 6 6 6-6" />
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</svg>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</Popover.Trigger>
|
|
|
|
|
|
<Popover.Content side="bottom" align="end" sideOffset={6}>
|
|
|
|
|
|
<div data-uix-menu style="min-inline-size: 240px;">
|
|
|
|
|
|
<div data-uix-menu-section>
|
|
|
|
|
|
<div data-uix-menu-label>Perceptual channels</div>
|
|
|
|
|
|
<label data-uix-menu-toggle>
|
|
|
|
|
|
<input type="checkbox" bind:checked={soundOn} />
|
|
|
|
|
|
Sound
|
|
|
|
|
|
<span data-uix-menu-toggle-meta>{soundOn ? 'on' : 'off'}</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
<label data-uix-menu-toggle>
|
|
|
|
|
|
<input type="checkbox" bind:checked={motionOn} />
|
|
|
|
|
|
Motion
|
|
|
|
|
|
<span data-uix-menu-toggle-meta>{motionOn ? 'on' : 'off'}</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
<label data-uix-menu-toggle>
|
|
|
|
|
|
<input type="checkbox" bind:checked={hapticOn} />
|
|
|
|
|
|
Haptic
|
|
|
|
|
|
<span data-uix-menu-toggle-meta>{hapticOn ? 'on' : 'off'}</span>
|
|
|
|
|
|
</label>
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Popover.Content>
|
|
|
|
|
|
</Popover>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- THEME -->
|
|
|
|
|
|
<button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
data-uix-icon-btn
|
|
|
|
|
|
title={theme === 'light' ? 'Switch to dark theme' : 'Switch to light theme'}
|
|
|
|
|
|
aria-label="Toggle theme"
|
|
|
|
|
|
onclick={() => (theme = theme === 'light' ? 'dark' : 'light')}
|
|
|
|
|
|
>
|
|
|
|
|
|
{#if theme === 'light'}
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
{:else}
|
|
|
|
|
|
<svg
|
|
|
|
|
|
viewBox="0 0 24 24"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
stroke="currentColor"
|
|
|
|
|
|
stroke-width="2"
|
|
|
|
|
|
stroke-linecap="round"
|
|
|
|
|
|
stroke-linejoin="round"
|
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
|
>
|
|
|
|
|
|
<circle cx="12" cy="12" r="4" />
|
|
|
|
|
|
<path
|
|
|
|
|
|
d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</svg>
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{/if}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
|
|
<aside data-uix-rail>
|
|
|
|
|
|
<div data-uix-rail-search>
|
|
|
|
|
|
<input type="search" placeholder="Search…" bind:value={search} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{#each filteredNav as section}
|
|
|
|
|
|
{#if section.kind === 'group'}
|
|
|
|
|
|
<div data-uix-rail-group>
|
|
|
|
|
|
<div data-uix-rail-group-head>
|
|
|
|
|
|
<span>{section.heading}</span>
|
|
|
|
|
|
<span data-uix-rail-group-count>{section.items.length}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
{#each section.items as item}
|
|
|
|
|
|
<li>
|
|
|
|
|
|
<a
|
|
|
|
|
|
href={item.slug}
|
|
|
|
|
|
data-uix-rail-link
|
|
|
|
|
|
data-sveltekit-preload-code="hover"
|
|
|
|
|
|
data-sveltekit-preload-data="hover"
|
|
|
|
|
|
data-active={current === item.slug ? 'true' : 'false'}
|
|
|
|
|
|
>
|
|
|
|
|
|
{item.label}
|
|
|
|
|
|
{#if item.tag}
|
|
|
|
|
|
<span data-uix-rail-link-tag>{item.tag}</span>
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</div>
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
{/if}
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
|
|
|
|
|
|
{#if filteredNav.length === 0}
|
|
|
|
|
|
<div data-uix-rail-group-head>No matches for "{search}"</div>
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
</aside>
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
|
|
|
|
|
|
<main data-uix-canvas>
|
|
|
|
|
|
{@render children?.()}
|
|
|
|
|
|
</main>
|
uix: drawer/popover/toast/accordion eidos wrappers + sema packs + /uix docs scaffold
- eidos: migrate drawer / popover / toast / accordion to wrapper subdirectory
pattern (provider + parts + tokens + recipe per component); avatar wrapper
added; toggle/switch/collapsible recipe polish.
- sema: per-component packs (accordion, drawer, popover, toast); engine /
resolver / event / sema-map updates; visual channel hold refinements.
- morfo: drawer event surface (variant, dragToDismiss, isDragging, minSize/
maxSize, onDragStart); popover/toast/accordion event refinements; schema +
types updates.
- soma: drawer provider rewrite (variant, dragToDismiss, isDragging binding,
drag callbacks); toast provider/toaster restructure with toast-main +
toast-status parts; popover content/arrow polish; gesture/floating layer
updates; manipulation layer scaffold; avatar removed (eidos owns it now).
- web/routes: legacy demos updated for new APIs; new /uix docs scaffold
(web/routes/uix/) with Radix-style shell, theme/lang/format/semantic prefs,
and standardized component template (Drawer page first — 6 tabs, live
controls, drag-hint arrows, scroll-safe body wrapper).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|