Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

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

Advanced Date Range Picker

Accessibility

Overview

AdvancedDateRangePicker stacks a SegmentedControl over a DatePicker. Keyboard and screen reader semantics come from @prepared911/ui-core and react-day-picker; the component wires them together but does not announce mode changes or the committed value. The app owns the accessible name for the control group, the trigger (when hosted in a popover), focus handoff between mode strip and grid, and any Apply-time announcement.

What the component handles

  • Mode strip semantics. SegmentedControl renders a radio-group-like set of SegmentedControlItems. The current mode carries aria-checked / pressed state; keyboard users move between items with arrow keys.
  • Grid semantics. The underlying DatePicker ships react-day-picker's grid (roving tabindex, arrow keys, aria-selected, aria-disabled).
  • MonthCaption controls. Previous / next IconButtons with localized titles; month / year Selects inherit @prepared911/ui-core Select listbox semantics.
  • Apply / Reset. @prepared911/ui-core Buttons when onApply is set (or when hideReset is false).
  • Mode-sensitive grid. Between mode renders DatePickerMode.Range; Before / After render DatePickerMode.Single. The grid's roles match the active mode automatically.

What you must provide

  • Group accessible name. The component does not set role="group" or aria-label on its root. Wrap it in a Box with role="group" and an aria-label or aria-labelledby that names the constraint ("Incident created").
  • Trigger accessible name. When hosted in a popover, the trigger carries its own label; pair an icon-only trigger with aria-label.
  • Announce the committed value. Apply / Reset do not announce the result. Echo the committed constraint ("after Mar 3") in a visible pill or a polite live region.
  • Tooltip / copy for disabled constraints. Explain disablePastDates / disableFutureDates / disableFuture in surrounding copy; disabled styling alone is not a name.

Keyboard behavior

  • Tab enters the mode strip, then moves into the grid, then to Apply / Reset (if set).
  • Arrow keys inside the mode strip move between Before / After / Between. The newly focused item is not activated until Space / Enter; this matches Radix SegmentedControl semantics.
  • Space / Enter activates the focused mode (reconfigures the grid below) or commits the focused day.
  • Arrow keys inside the grid behave as in DatePicker: Up / Down by week, Left / Right by day, Home / End within a week.
  • Escape closes the hosting popover and returns focus to the trigger.

Semantics and roles

  • Root wrapper. The component does not render a landmark. Wrap it in role="group" with aria-labelledby pointing at a visible label, or aria-label when no visible label is present.
  • Mode strip. SegmentedControl from @prepared911/ui-core (Radix-backed) with aria-checked or aria-pressed per item.
  • Grid. role="grid" with role="gridcell" days; aria-selected indicates the selected date or range endpoints.
  • Apply / Reset. Native <button> elements via @prepared911/ui-core Button.

Focus management

When the picker is mounted inside a Popover, the hosting surface opens the popover and focus lands in the mode strip. Switching modes changes the grid below but keeps focus on the mode item; the next Tab moves into the newly configured grid. On Apply, the hosting surface should close the popover and restore focus to its trigger.

Screen reader announcements

SegmentedControl announces each mode's label as it receives focus. The grid announces the focused day. Neither surface announces the committed value after Apply. Echo the committed constraint in visible copy—a filter pill or summary line—so assistive technology users hear the full rule:

Keep announcements polite (not assertive) unless the change is urgent; Before / After / Between are filter refinements, not alerts.

Known caveats

  • Mode changes are not announced automatically. Focus stays on the mode strip while the grid reconfigures below. Your surface should use visible text to reinforce the mode (a heading or inline summary) when operators might miss the shift.
  • No built-in landmark or group role. Wrap the picker in role="group" with a name.
  • Grid-mode round trip can feel abrupt. Between → Before preserves the more recent endpoint, not both; communicate that tradeoff in surrounding copy if operators rely on returning to Between with their previous range intact.

Previous

Advanced Date Range Picker / API and Development

Next

Advanced Date Time Range Picker / 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