+
+ Forms · ColorField
+ ColorField
+
+ Segmented color input. Soma owns format switching (hex/rgb/hsl), channel editing, alpha,
+ ARIA spinbuttons and validation; Eidos adds size, variant, intent color and recipe styling.
+
+
+ parts {compiled.parts.order.length}
+ events {events.length}
+ formats 3
+ sizes 5
+
+
+
+
+
+
+
+ Brand color
+
+ {#snippet children({ segments }: InputSnippetProps)}
+ {#each segments as { part, value }, index (`${part}-${index}`)}
+ {value}
+ {/each}
+
+ {/snippet}
+
+
+
+
+
+ hex {value?.hex ?? '—'}
+ rgb {value
+ ? `rgb(${value.rgb.r}, ${value.rgb.g}, ${value.rgb.b}${value.rgb.a < 1 ? `, ${value.rgb.a}` : ''})`
+ : '—'}
+
+
+
+
+
+ trace
+ {#if trace.length === 0}
+ edit or play an event to see sema stamps
+ {:else}
+ {#each trace.slice(0, 3) as entry}
+ {entry.event} · {entry.family}{entry.intent
+ ? ' · ' + entry.intent
+ : ''}
+ {fmtTime(entry.at)}
+ {/each}
+ {/if}
+
+ value
+ {valueLabel}
+
+
+
+
+
+ (tab = 'live')}>Live
+ (tab = 'api')}>API
+ (tab = 'morfo')}>
+ morfo
+ {partsList.length}p · {events.length}e
+
+ (tab = 'sema')}>
+ sema
+ {events.length}
+
+ (tab = 'recipe')}
+ >Recipe
+ (tab = 'a11y')}>A11y
+
+
+ {#if tab === 'live'}
+
+ Controls
+
+ soma owns value, channel editing, format
+ switching and validation. eidos owns only the
+ visual treatment.
+
+
+
+ soma props · segmented value
+
+
+
+ value
+
+ setDemoValue('brand')}>brand
+ setDemoValue('accent')}>accent
+ setDemoValue('empty')}>empty
+
+
+
+ format
+
+ {#each ['hex', 'rgb', 'hsl'] as v}
+ (format = v as ColorFormat)}>{v}
+ {/each}
+
+
+
+ allowed formats
+
+ {#each ['hex', 'rgb', 'hsl'] as v}
+ toggleAllowedFormat(v as ColorFormat)}>{v}
+ {/each}
+
+
+
+ name
+
+
+
+ direction
+
+ {#each ['ltr', 'rtl'] as v}
+ (dir = v as Direction)}>{v}
+ {/each}
+
+
+
+ states
+
+
+ required
+
+
+
+ disabled
+
+
+
+ readonly
+
+
+
+ channels
+
+
+ enable alpha
+
+
+
+ alpha readonly
+
+
+
+
+
+ eidos props · visual treatment
+
+
+
+ size
+
+ {#each ['xs', 'sm', 'md', 'lg', 'xl'] as v}
+ (size = v as ColorFieldSize)}>{v}
+ {/each}
+
+
+
+ variant
+
+ {#each ['surface', 'outline', 'ghost'] as v}
+ (variant = v as ColorFieldVariant)}>{v}
+ {/each}
+
+
+
+ color
+
+ {#each ['primary', 'secondary', 'neutral', 'affirm', 'fulfill', 'risk', 'threat', 'loss'] as v}
+ (color = v as ColorFieldColor)}>{v}
+ {/each}
+
+
+
+
+
+
+ soma
+ headless · segment editing + ARIA
+ svelte
+
+
{somaSnippet}
+
+
+
+ eidos
+ visual · root + attached parts
+ svelte
+
+
{eidosSnippet}
+
+
+ {/if}
+
+ {#if tab === 'api'}
+
+ API + reference comparison
+
+
+
+ Feature Ark Chakra Bits UIX Decision
+
+
+ Segmented input no no no yes Soma owns editable channel segments — unique to UIX.
+ Format switch (hex/rgb/hsl) yes yes yes yes FormatSelect is a public part.
+ Alpha channel yes yes yes yes Opt-in via enableAlpha.
+ Validation yes yes yes yes Custom validate + incomplete reason.
+ Readonly segments no no no yes Per-channel lock (e.g. alpha).
+ Field integration — — — yes Soma integrates with Field context.
+ Visual variants CSS CSS CSS yes Eidos adds canonical control variants.
+
+
+
+
+
+ Prop Owner Default Notes
+
+ value / placeholder soma — Bindable ColorValue (hex + rgb + hsl + hsv all in sync).
+ format soma hex Bindable. Drives which segments render.
+ allowedFormats soma ['hex','rgb','hsl'] Whitelist exposed by FormatSelect.
+ enableAlpha soma true When false, hides the alpha segment entirely.
+ readonlySegments soma [] Lock individual channels.
+ validate soma — Returns error message string(s) when invalid.
+ dir soma services Keyboard navigation direction.
+ size / variant / color eidos md / surface / primary Visual-only data attrs.
+
+
+
+
+ {/if}
+
+ {#if tab === 'morfo'}
+
+ Morfo contract
+
+
+ Part Marker Element Role Optional
+
+ {#each partsList as part}
+
+ {part.kebab}
+ [{part.marker}]
+ <{part.defaultElement}>
+ {part.role ?? '—'}
+ {part.optional ? 'yes' : 'no'}
+
+ {/each}
+
+
+
+
+ {/if}
+
+ {#if tab === 'sema'}
+
+
+ sema · events + perceptual signature
+
+
+ ColorField only declares commit events. Channel editing remains headless until the value
+ is set.
+
+
+
+ Name Family Verb Sequence Target Play
+
+ {#each events as action}
+
+ {action.name}
+ {action.semantic.family}
+ {action.semantic.verb ?? '—'}
+ {action.semantic.sequence ?? 'pre'}
+ {action.target}
+
+ {
+ const target = stageRef?.querySelector(
+ '[data-color-field]'
+ ) as HTMLElement | null;
+ if (!target) return;
+ void uix.events?.emit({
+ name: action.name,
+ family: action.semantic.family,
+ target
+ });
+ }}>▶ play
+
+
+ {/each}
+
+
+
+
+ {/if}
+
+ {#if tab === 'recipe'}
+
+ Eidos recipe
+
+ Selectors live in src/uix/eidos/components/color-field/color-field.css and
+ consume Soma segment state plus Eidos data-size,
+ data-variant and data-color.
+
+
+
+ Selector Owner Purpose
+
+ [data-color-field]morfo Root color-field contract and state.
+ [data-color-field][data-size][data-variant][data-color]eidos Visual scale, control treatment and intent palette.
+ [data-color-field-input][data-format]morfo Segment group container reflecting active format.
+ [data-color-field-segment][data-segment][data-readonly]morfo Per-channel segment state.
+ [data-color-field-format-select][data-locked]morfo Format switcher; locked when allowedFormats has 1 entry.
+
+
+
+
+ {/if}
+
+ {#if tab === 'a11y'}
+
+ Accessibility
+
+
+ Concern Contract
+
+ Group Input exposes role="group" and an accessible name.
+ Channels Editable channels expose role="spinbutton" with min/max/current value.
+ Keyboard Arrow keys, Home/End, Backspace and digits handled by Soma.
+ Format select Native <select> with localised option labels.
+ Form Hidden input submits the formatted color string when name is set.
+
+
+
+
+ {/if}
+
+
+
diff --git a/web/routes/uix/components/time-field/+page.svelte b/web/routes/uix/components/time-field/+page.svelte
new file mode 100644
index 000000000..4c254c27d
--- /dev/null
+++ b/web/routes/uix/components/time-field/+page.svelte
@@ -0,0 +1,583 @@
+
+
+
+
+ Forms · TimeField
+ TimeField
+
+ Segmented time input. Soma owns hour/minute/second editing, ARIA spinbuttons, validation
+ and form submission; Eidos adds size, variant, intent color and recipe styling.
+
+
+ parts {compiled.parts.order.length}
+ events {events.length}
+ variants 3
+ sizes 5
+
+
+
+
+
+
+
+ Start
+
+ {#snippet children({ segments }: InputSnippetProps)}
+ {#each segments as { part, value }, index (`${part}-${index}`)}
+ {value}
+ {/each}
+ {/snippet}
+
+
+
+
+
+ trace
+ {#if trace.length === 0}
+ edit or play an event to see sema stamps
+ {:else}
+ {#each trace.slice(0, 3) as entry}
+ {entry.event} · {entry.family}{entry.intent
+ ? ' · ' + entry.intent
+ : ''}
+ {fmtTime(entry.at)}
+ {/each}
+ {/if}
+
+ value
+ {valueLabel}
+
+
+
+
+
+ (tab = 'live')}>Live
+ (tab = 'api')}>API
+ (tab = 'morfo')}>
+ morfo
+ {partsList.length}p · {events.length}e
+
+ (tab = 'sema')}>
+ sema
+ {events.length}
+
+ (tab = 'recipe')}
+ >Recipe
+ (tab = 'a11y')}>A11y
+
+
+ {#if tab === 'live'}
+
+ Controls
+
+ soma owns value, segment behavior and
+ validation. eidos owns only the visual
+ treatment.
+
+
+
+ soma props · segmented value
+
+
+
+ value
+
+ setDemoValue('start')}>start
+ setDemoValue('end')}>end
+ setDemoValue('empty')}>empty
+
+
+
+ granularity
+
+ {#each ['hour', 'minute', 'second'] as v}
+ (granularity = v as TimeGranularity)}>{v}
+ {/each}
+
+
+
+ hour cycle
+
+ {#each [12, 24] as v}
+ (hourCycle = v as HourCycle)}>{v}
+ {/each}
+
+
+
+ name
+
+
+
+ locale
+
+ en-US
+ es-ES
+ fr-FR
+
+
+
+ direction
+
+ {#each ['ltr', 'rtl'] as v}
+ (dir = v as Direction)}>{v}
+ {/each}
+
+
+
+ states
+
+
+ required
+
+
+
+ disabled
+
+
+
+ readonly
+
+
+
+ constraints
+
+
+ min 08:00 · max 20:00
+
+
+
+ seconds readonly
+
+
+
+
+
+ eidos props · visual treatment
+
+
+
+ size
+
+ {#each ['xs', 'sm', 'md', 'lg', 'xl'] as v}
+ (size = v as TimeFieldSize)}>{v}
+ {/each}
+
+
+
+ variant
+
+ {#each ['surface', 'outline', 'ghost'] as v}
+ (variant = v as TimeFieldVariant)}>{v}
+ {/each}
+
+
+
+ color
+
+ {#each ['primary', 'secondary', 'neutral', 'affirm', 'fulfill', 'risk', 'threat', 'loss'] as v}
+ (color = v as TimeFieldColor)}>{v}
+ {/each}
+
+
+
+
+
+
+ soma
+ headless · segment editing + ARIA
+ svelte
+
+
{somaSnippet}
+
+
+
+ eidos
+ visual · root + attached parts
+ svelte
+
+
{eidosSnippet}
+
+
+ {/if}
+
+ {#if tab === 'api'}
+
+ API + reference comparison
+
+
+
+ Feature React Aria Ark Bits UIX Decision
+
+
+ Segmented input yes yes yes yes Soma owns editable segments.
+ Granularity (hour/min/sec) yes yes yes yes Drives which segments render.
+ 12 / 24 hour cycle yes yes yes yes 12h adds dayPeriod (AM/PM) segment.
+ Validation yes yes yes yes Custom validate + min/max.
+ Readonly segments no no yes yes Per-segment lock without disabling input.
+ Field integration form context field manual yes Soma integrates with Field context.
+ Visual variants CSS CSS CSS yes Eidos adds canonical control variants.
+
+
+
+
+
+ Prop Owner Default Notes
+
+ value / placeholder soma — Bindable TimeValue.
+ minValue / maxValue soma — Validation bounds.
+ granularity soma minute hour | minute | second.
+ hourCycle soma locale 12h adds dayPeriod segment; 24h hides it.
+ hideTimeZone soma false Only affects ZonedDateTime values.
+ readonlySegments soma [] Lock individual segments (e.g. seconds).
+ locale / dir soma services Formatting + keyboard direction.
+ size / variant / color eidos md / surface / primary Visual-only data attrs.
+
+
+
+
+ {/if}
+
+ {#if tab === 'morfo'}
+
+ Morfo contract
+
+
+ Part Marker Element Role Optional
+
+ {#each partsList as part}
+
+ {part.kebab}
+ [{part.marker}]
+ <{part.defaultElement}>
+ {part.role ?? '—'}
+ {part.optional ? 'yes' : 'no'}
+
+ {/each}
+
+
+
+
+ {/if}
+
+ {#if tab === 'sema'}
+
+
+ sema · events + perceptual signature
+
+
+ TimeField only declares commit events. Segment editing remains headless until the value is set.
+
+
+
+ Name Family Verb Sequence Target Play
+
+ {#each events as action}
+
+ {action.name}
+ {action.semantic.family}
+ {action.semantic.verb ?? '—'}
+ {action.semantic.sequence ?? 'pre'}
+ {action.target}
+
+ {
+ const target = stageRef?.querySelector(
+ '[data-time-field]'
+ ) as HTMLElement | null;
+ if (!target) return;
+ void uix.events?.emit({
+ name: action.name,
+ family: action.semantic.family,
+ target
+ });
+ }}>▶ play
+
+
+ {/each}
+
+
+
+
+ {/if}
+
+ {#if tab === 'recipe'}
+
+ Eidos recipe
+
+ Selectors live in src/uix/eidos/components/time-field/time-field.css and
+ consume Soma segment state plus Eidos data-size,
+ data-variant and data-color.
+
+
+
+ Selector Owner Purpose
+
+ [data-time-field]morfo Root time-field contract and state.
+ [data-time-field][data-size][data-variant][data-color]eidos Visual scale, control treatment and intent palette.
+ [data-time-field-input]morfo Segment group container.
+ [data-time-field-segment][data-placeholder][data-readonly]morfo Individual segment state.
+ [data-time-field][data-event]eidos Transient perceptual event styling from Sema projection.
+
+
+
+
+ {/if}
+
+ {#if tab === 'a11y'}
+
+ Accessibility
+
+
+ Concern Contract
+
+ Group Input exposes role="group" and an accessible name.
+ Segments Editable segments expose role="spinbutton" with min/max/current value.
+ Keyboard Arrow keys, Home/End, Backspace, digits and A/P (for dayPeriod) handled by Soma.
+ Announcer Live region announces segment changes via aria-valuetext.
+ Form Hidden input submits the ISO time string when name is set.
+
+
+
+
+ {/if}
+