Companion of TimeField for time ranges
({`{ start, end }`}). Two endpoint inputs share
one Label and the same Segment component; soma's
TimeRangeField provider creates a separate TimeField context per
endpoint so segment editing routes to the correct boundary.
Visual chrome is reused 1:1 from time-field.css —
the eidos root overlays data-time-field on top of
data-time-range-field so the entire size / variant /
color cascade applies inside the range without recipe
duplication. This recipe only adds the
1fr · auto · 1fr grid layout + em-dash separator.
{eidosSnippet}
4 parts: Provider, Label, Input (start/end), Segment.
| Prop | Type | Default | Description |
|---|---|---|---|
| value bindable | TimeRange | null | — | {`{ start, end }`} time pair. |
| placeholder | TimeValue | — | Used to seed segments before any value is set. |
| granularity | 'hour' | 'minute' | 'second' | 'minute' | Smallest segment. |
| hourCycle | 12 | 24 | locale | 12h vs 24h presentation. |
| hideTimeZone | boolean | false | Suppress timezone segment for ZonedDateTime values. |
| minValue · maxValue | TimeValue | — | Validation range applied to BOTH endpoints. |
| disabled · readonly · required | boolean | false | OR-merged with enclosing Field.Provider. |
| locale · dir | BCP47 · 'ltr' | 'rtl' | soma prefs | — |
| size eidos | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Visual size cascade (reuses TimeField tokens). |
| variant eidos | ControlVariant | 'surface' | Input chrome treatment. |
| color eidos | ColorRole | 'primary' | Focus + selection accent. |
| Prop | Type | Default | Description |
|---|---|---|---|
| type | 'start' | 'end' | required | Which endpoint this input represents. |
| name | string | — | Hidden form input name (per endpoint). |
| aria-label | string | — | Override accessible name. |
Label sits above the two inputs (grid row 1, full
width). Segment is re-exported from
TimeField — each endpoint's Input
scopes its own TimeField context so segment editing routes to
the right endpoint without ambiguity.
Source: src/uix/morfo/components/time-range-field.ts.
| Field | Value |
|---|---|
| name | "{timeRangeFieldMorfo.name}" |
| kebab | "{timeRangeFieldMorfo.kebab}" |
| parts.length | {timeRangeFieldMorfo.parts.length} |
| events.length | {events.length} |
| Part | Marker | Element | Role | Archetype | States | Optional |
|---|---|---|---|---|---|---|
| {part.kebab} | [{part.marker}] |
<{part.defaultElement}> | {part.role ?? '—'} | {part.archetype ?? '—'} | {part.states.length ? part.states.join(' | ') : '—'} | {part.optional ? 'yes' : 'no'} |
Events fire on segment commit (per endpoint).
| Name | Family | Verb | Sequence | Intent |
|---|---|---|---|---|
| {action.name} | {sem.family} | {sem.verb ?? '—'} | {sem.sequence ?? 'pre'} | {intentStr} |
Layout-only at src/uix/eidos/components/time-range-field/time-range-field.css.
Chrome on each endpoint Input comes from time-field.css because the
eidos root overlays data-time-field="" on top of
data-time-range-field — the entire size / variant / color cascade
applies inside the range without duplicating any rules.
| Selector | Source | What it paints |
|---|---|---|
| [data-time-range-field][data-time-field] | eidos | Grid wrapper (1fr · auto · 1fr). |
| [data-time-range-field-label] | morfo | Label spanning full row. |
| [data-time-range-field-input][data-endpoint='start' | 'end'] | morfo | Endpoint container — grid columns 1 / 3. |
| [data-time-range-field]::before | eidos | Em-dash separator in middle column. |
| [data-time-field-input], [data-time-field-segment] | eidos | Inherited from time-field.css — each endpoint paints like a standalone TimeField. |
Same ARIA contract as TimeField, applied per endpoint. Each
segment is a role="spinbutton" with
aria-valuemin / aria-valuemax /
aria-valuenow driven by the resolved value;
Tab moves across segments AND across the start↔end boundary.
| Key | Action |
|---|---|
| ArrowUp / ArrowDown | Increment / decrement the focused segment. |
| ArrowLeft / ArrowRight | Move focus to previous / next segment (crosses start↔end). |
| Home / End | First / last editable segment of the focused endpoint. |
| Digit | Type to fill the segment; auto-advances on overflow. |
| Backspace | Clear digit-by-digit. |
| Tab | Advance focus across endpoint segments. |