Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Calendar
  2. Advanced Date Time Range Picker
  3. Accessibility

Advanced Date Time Range Picker

Accessibility

Overview

AdvancedDateTimeRangePicker nests a date AdvancedDateRangePicker with one or two time inputs. Keyboard and screen reader semantics come from three places—@prepared911/ui-core SegmentedControl, react-day-picker's grid, and native <input type="time">—wired together by the component. The app owns the accessible name for the whole control, focus handoff between mode strip, date grid, and time fields, and any Apply-time announcement.

What the component handles

  • Mode strip. SegmentedControl with Before / After / Between items; arrow keys move between them, Space / Enter activates.
  • Grid semantics. The same DatePicker grid as AdvancedDateRangePicker (roving tabindex, arrow navigation, aria-selected, aria-disabled).
  • Time fields. TimePicker for single-bound modes; TimeRangeInputs (two TimePickers with an en-dash separator) for Between. Each TimePicker renders a native <input type="time"> with an associated Label.
  • maxRange-style clamping. When the time range exceeds a configured maximum in TimeRangeInputs, the component clamps the end: the change fires onChange so assistive tech hears the field update.
  • Apply / Reset. @prepared911/ui-core Buttons when onApply is provided.
  • Default times. 00:00 / 23:59 padding applies to the committed value automatically.

What you must provide

  • Group accessible name. Wrap the picker in role="group" with an aria-label or aria-labelledby pointing at a visible heading ("Incident created").
  • Distinct time-field labels. TimeRangeInputs ships with localized "From" / "To" labels for its internal pickers; if you compose TimePicker directly, set explicit label values so start and end are distinguishable in speech.
  • Committed-value announcement. Apply does not announce the full constraint. Echo it in a pill, summary line, or polite live region.
  • Timezone copy. The picker has no built-in timezone indicator. Clarify the stored timezone in surrounding helper text when it's not local.

Keyboard behavior

  • Tab enters the mode strip, then moves into the grid (when applicable), then into the time fields in visual order, then to Apply / Reset (if set).
  • Arrow keys in the mode strip move between Before / After / Between; Space / Enter activates.
  • Arrow keys in the grid match DatePicker: Up / Down by week, Left / Right by day.
  • Time fields use native <input type="time">; keyboard behavior is platform-defined (arrow keys adjust hours or minutes depending on focus inside the segmented control some browsers render).
  • Escape closes the hosting popover.

Semantics and roles

  • Root wrapper. No landmark or group role by default; add one.
  • Mode strip. SegmentedControl (Radix-based).
  • Grid. role="grid" + role="gridcell" cells from react-day-picker.
  • Time inputs. Native <input type="time"> with an adjacent Label; the @prepared911/ui-core Input supplies the name association.
  • Apply / Reset. Native <button> via @prepared911/ui-core Button.

Focus management

When hosted in a Popover, the trigger carries the accessible name; the popover's default focus lands in the mode strip. Operators Tab through mode → grid → start time (→ end time) → Apply / Reset. On commit, the hosting surface closes the popover and restores focus to the trigger. When the operator changes mode mid-flight, focus stays on the mode strip and the next Tab moves into the newly configured grid.

Screen reader announcements

SegmentedControl announces each mode as it receives focus; the grid announces the focused day; the native time input announces the current value. None of these announce the full committed constraint on Apply—echo the result visibly:

Be careful with live regions on fast-changing fields—keep them polite, not assertive, and only announce the result after Apply, not during draft edits.

Known caveats

  • No landmark / group role by default. Wrap the picker; announce what the control governs.
  • Time fields depend on the browser. Native <input type="time"> rendering and keyboard handling vary across browsers and locales; test in the browsers your operators use.
  • Mode switches reconfigure the grid below the strip. Focus stays on the strip; visible copy should reinforce the mode change for operators who aren't watching for the layout shift.
  • Timezone is implicit. Commit values are Date objects; the timezone assumption lives in your app, not in the picker.

Previous

Advanced Date Time Range Picker / API and Development

Next

Calendar Utilities / Usage

On this page

Overview
What the component handles
What you must provide
Keyboard behavior
Semantics and roles
Focus management
Screen reader announcements
Known caveats