Overview
Controlled start/end date range picker with preset shortcuts and validation feedback, designed for time-window filtering on dashboards, event streams, and audit logs.
Overview
DateRangeField renders two text inputs backed by custom calendar/time popovers (start and end) along with preset shortcut buttons. It is fully controlled: the consumer owns the value and responds to onchange callbacks. It does not own routing, query-string synchronization, timezone conversion, or data fetching.
Values are ISO-8601 local strings. granularity="day" emits YYYY-MM-DD; time granularities use the custom time popover and emit values truncated to the selected precision.
Usage
With custom presets
With validation error
Props
Types
Accessibility
The component implements accessible form labelling throughout:
- Each date input is associated with a
<label>viafor/id. - The optional legend (
labelprop) is a<p>associated with the group visually. - The preset button row carries
role="group"witharia-label="Date range presets". - Each preset button carries
aria-pressedto communicate current selection state to assistive technology. - The error region uses
aria-live="polite"and is always in the DOM so screen readers reliably pick up the live region before text is injected. - When
erroris set, both inputs carryaria-invalid="true". - The root carries
role="group"andaria-labelledbypointing to the legend element when alabelprop is provided, associating the label with the start/end input group. descriptionanderrorelements are wired into each input viaaria-describedby, so a screen reader user tabbing to an input hears the description and any active error.- Forced-colors (Windows High Contrast) mode: inputs and preset buttons receive a solid
outlineinstead ofbox-shadowfocus rings, which are ignored in that mode.
Scope limits
- Timezone conversion is caller-owned. Emitted date-time values are local wall-clock strings without timezone offsets.
- The component owns the custom date and date-time picker UI.
- Start and end constrain each other through DatePicker's
min/maxcontract: the calendar disables out-of-range dates and manual edits are validated and clamped. Consumers still own domain-specific validation and error messaging through theerrorprop.
When to use
- Filtering a list or dashboard by a start and end date (e.g. created between, updated between).
- Offering common presets (last 7 days, last 24 hours) alongside a manual date range.
- A single date is sufficient — use a plain date input instead.
- Timezone conversion or a standalone time-of-day value is required — use time-field for the latter.
Examples
Basic date range
Start and end date inputs with built-in presets for today, yesterday & today, and last 7 days.
Custom presets
Consumer-supplied presets with labels suited to a billing or audit log context.
Disabled state
All inputs and preset buttons are disabled. Use when the date range cannot be edited in the current context.
Workflow list filter
Filter an operational workflow list by creation date with custom presets and validation feedback.
Props
| Name | Type | Default | Required | Bindable | Description |
|---|---|---|---|---|---|
id | text | Unique identifier used to generate accessible IDs for labels and error
regions. Optional — a stable id is generated via $props.id() when omitted. | |||
value | { /** Start of the range as an ISO-8601 local string, or undefined when not set. */ start: string | undefined; /** End of the range as an ISO-8601 local string, or undefined when not set. */ end: string | undefined; } | bind | Current date range value. Bindable. Both fields start undefined when unset. | ||
label | text | Visible legend rendered above the start/end inputs. | |||
startLabel | text | Accessible label for the start input. Defaults to "Start date" for day granularity and "Start date and time" for datetime granularities. | |||
endLabel | text | Accessible label for the end input. Defaults to "End date" for day granularity and "End date and time" for datetime granularities. | |||
granularity | 'day' | 'hour' | 'minute' | 'second' | 'day' | Date-time precision. Defaults to day precision. | ||
presets | DateRangeDatePreset[] | Consumer-defined preset options shown above the date inputs. Each preset has a label and a resolve() function that returns a DateRangeValue. Defaults to today, yesterday-today, last-7d built-ins when omitted. | |||
hidePresets | boolean | false | When true, hides the preset buttons and shows only the date inputs. | ||
description | text | Helper text displayed below the field; wired via aria-describedby. | |||
error | text | Validation error message. When provided, marks both inputs as aria-invalid="true" and renders the message in a live region. | |||
disabled | boolean | false | Disables the entire field including presets and date inputs. | ||
onchange | (value: DateRangeValue) => void | Called when the user changes the date range (preset or manual input). |