Components

Time Range Field

Coordinated segmented start and end times with aggregate validation and native form values.

TimeRangeField combines two Time Field controls under one range model and validity state. It supports locale order, granularity, constraints, partial input, Field integration, and separate form values.

The end time must be equal to or later than the start time.

Anatomy

  • #start-literal: Locale separators inside start field.
  • #start-day-period: Start AM/PM content and action.
  • #start-time-zone: Start zone content.
  • #separator: Decorative separator between endpoints.
  • #end-literal: Locale separators inside end field.
  • #end-day-period: End AM/PM content and action.
  • #end-time-zone: End zone content.

The root generates endpoint wrappers, two functional Time Fields, separator, and aggregate native validity input.

Usage

Both endpoints share one range validity state.

Range: 09:00:00 - 17:00:00

Examples

Required range with Field

Aggregate validation starts after interaction. Untouched empty fields remain neutral; blur or submit reveals missing endpoints and Field error text.

<Field label="Availability" name="window" required>
  <TimeRangeField v-model="range" />
</Field>

FormData receives window.start and window.end. Set startName and endName when a backend expects different keys.

Constraints

<TimeRangeField
  v-model="range"
  :min-value="new Time(8)"
  :max-value="new Time(20)"
  :is-time-unavailable="isUnavailable"
/>

Each endpoint validates boundaries and unavailable values. The parent additionally rejects reversed ranges.

Seconds and step

<TimeRangeField
  v-model="range"
  granularity="second"
  :step="{ minute: 15 }"
  step-snapping
/>

Custom endpoint presentation

Use nested startField and endField UI objects for segment parts while root UI keys style range layout.

<TimeRangeField
  :ui="{
    root: 'flex rounded border',
    startField: { segment: 'tabular-nums' },
    separator: 'text-neutral-500',
    endField: { segment: 'tabular-nums' },
  }"
/>

Cancel changes

value-change reports the proposed full range with reasons such as start-input and end-keyboard.

<TimeRangeField
  v-model="range"
  @value-change="(value, details) => {
    if (isLocked(value)) details.cancel()
  }"
/>

Reactive validation

Aggregate range validity includes partial endpoint drafts and reacts to changing min/max and other constraints. Child styling attributes are not the source of validation state. Native reset restores both initial endpoints unless canceled.

API Reference

Models

ModelTypeDefaultDescription
v-modelTimeRange{}Optional start and end TimeValues. Partial segment text stays internal.
v-model:placeholderTimeValue | undefinedplaceholderShared base value for both endpoints.

Props

PropTypeDefaultDescription
idstringField id or generatedStart field id; end adds -end.
namestringField nameDerives .start and .end form names.
startName / endNamestringderivedExplicit native form names.
localestring"en-US"Segment order, labels, and default hour cycle.
dir"ltr" | "rtl""ltr"Reading direction.
placeholderTimeValuemidnightShared base time and value type.
minValue / maxValueTimeValueEndpoint boundaries.
isTimeUnavailable(time) => booleanEndpoint application constraint.
granularity"hour" | "minute" | "second""minute"Smallest endpoint unit.
hourCycle12 | 24locale preferenceExplicit hour cycle.
hideTimeZonebooleanfalseHides zoned endpoint labels.
step{ hour?, minute?, second? }each 1Endpoint keyboard step.
stepSnappingbooleanfalseSnaps complete endpoint values.
requiredbooleanfalseRequires both endpoints.
disabledbooleanfalseDisables endpoints and form submission.
readOnlybooleanfalseAllows focus but blocks edits.
invalidbooleanfalseForces invalid presentation.
selectOnFocusbooleantrueSelects focused segment text.
autoAdvancebooleantrueAdvances after two digits.
startLabelstring"Start time"Accessible start label.
endLabelstring"End time"Accessible end label.
ariaLabelstring"Time range"Root label without Field label relation.
ariaLabelledby / ariaDescribedbystringField relationsExplicit ARIA relationships.
uiTimeRangeFieldUiClasses for range and endpoint parts.

Emits

EventPayloadDescription
update:modelValueTimeRangeFires after accepted endpoint changes.
update:placeholderTimeValue | undefinedFires after accepted placeholder changes.
value-change(range, details)Cancelable proposed range update.
value-commit(range, details)Accepted endpoint commit with prefixed reason.

Slots

SlotPropsDescription
start-literal / end-literalvalueEndpoint locale separators.
start-day-period / end-day-periodvalue, label, toggleEndpoint AM/PM content.
start-time-zone / end-time-zonevalueEndpoint zone content.
separatorVisual separator; hidden from assistive technology.

Methods

MethodDescription
focusStart() / focusEnd()Focuses first segment of endpoint.
clear(event?)Requests empty range.
setValue(range, reason, event?)Requests programmatic range change.

UI Options

KeyPart
rootRoot range group.
startStart endpoint wrapper.
startFieldNested TimeFieldUi for start.
separatorEndpoint separator.
endEnd endpoint wrapper.
endFieldNested TimeFieldUi for end.
hiddenInputAggregate native validity input.

Styling Hooks

UI keyCSS classData attributes
root.akaza-time-range-field`data-akaza-state="empty
start.akaza-time-range-field-startdata-akaza-endpoint="start", data-akaza-state
separator.akaza-time-range-field-separator
end.akaza-time-range-field-enddata-akaza-endpoint="end", data-akaza-state
hiddenInput.akaza-time-range-field-hidden-input
startField / endField.akaza-time-field-*All Time Field segment hooks.

Keyboard

Each endpoint uses Time Field keyboard behavior:

KeyBehavior
Number keys / pasteEdits focused endpoint segment.
ArrowUp / ArrowDownSteps segment.
PageUp / PageDownSteps by ten increments.
Home / EndSets segment boundary.
ArrowLeft / ArrowRightMoves within current endpoint.
Tab / Shift + TabUses native order across both endpoints and surrounding controls.
A / PSets focused endpoint day period.

Mouse and touch edit the native inputs and day-period buttons. The component does not require hover input.