Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Calendar
  2. Date Picker
  3. Usage

Date Picker

Usage

Overview

DatePicker from @prepared911/ui-calendar is the core calendar-grid primitive. It wraps react-day-picker with a Prepared-styled MonthCaption, optional Apply / Reset buttons, and a trigger slot that turns the grid into popover content. Use it when operators need to see dates in calendar context—proximity to today, day-of-week, span across weeks—rather than just type a value into a field.

DatePicker supports three modes via DatePickerMode:

  • Single: one date.
  • Range: a contiguous start / end range.
  • DaysAgo: a single date resolved N days before the anchor (for "last 7 days" style filters).
SuMoTuWeThFrSa

When to use

  • Filter bars in analytics and log search. Operators comparing flagged incidents, radio transmissions, and logged chatrooms need to see a date's weekday and position in the month before committing. This is the primary in-product pattern: see the custom-range popover in supervisor-analytics and logging-recorder dispatch surfaces.
  • Scheduling and non-emergency intents. When an operator chooses a committed date, a visible grid reduces transposition errors (picking the 3rd instead of the 13th).
  • Side-by-side review. When the date supports something the operator is already reading—an incident list, a transmission timeline—render DatePicker inline rather than hiding it behind a field.

When not to use

  • Dense forms where the date is memorable. Birthdates, expiration dates, and other well-known values are faster to type. Use DateInput or a plain Input with type="date".
  • Time-of-day only. Use TimePicker.
  • Inequality semantics ("before", "after", "between"). Reach for AdvancedDateRangePicker, which pairs a mode strip with the grid.
  • Repeating schedules. Use EventRecurrencePicker so the operator sees the whole rule, not just one date.

Composition

  • MonthCaption. Shared header with month / year Selects and chevron navigation. Hide the selects with hideMonthYearSelect when the surrounding popover is already short.
  • Day grid. react-day-picker provides the grid, weekday header, and selected / range-span styling.
  • Optional Apply / Reset. Pass cta to render the buttons and defer commits until Apply fires.
  • Optional trigger. Without it, DatePicker is an inline block. With it, the grid mounts as Popover content anchored to your trigger. Use open / onOpenChange / onClose to coordinate with surrounding UI.

Modes

  • DatePickerMode.Single. value?: Date, onChange(value: Date). The simplest case; pair with a label and optional Apply button.
  • DatePickerMode.Range. value?: { start: Date; end: Date }, onChange(value). Selecting an earlier date after an end date resets the range start.
  • DatePickerMode.DaysAgo. Adds a required daysAgo: number. Pick any date and the committed value is daysAgo days earlier: useful for "look back N days from today" shortcuts where the display anchor moves but the stored value is always relative.

Customization

  • minSelectableDate / maxSelectableDate. Constrain navigation and selection. MonthCaption disables months and years outside the window so operators cannot page past a cliff.
  • disableFuture. Shorthand for "today or earlier"; preferable to computing maxSelectableDate = new Date() yourself because it also hides future months from the year Select.
  • disabled. Accepts boolean or (date: Date) => boolean. Use the predicate to gray out weekends, holidays, or days with no data.
  • hideMonthYearSelect. Drops the month / year Selects in favor of chevrons-only. Use for narrow popovers where the selects would wrap.
  • Inline vs popover. Omit trigger for inline layouts (two pickers side-by-side in the dispatch analytics popover); pass trigger for a date field that opens on click.

Behavior and states

  • Deferred commits. With cta or onApply, internal state tracks the in-progress selection and only fires onApply when the operator confirms. Without cta, onChange fires on every click.
  • Month navigation. Chevrons and the month / year Selects stay disabled at the minSelectableDate / maxSelectableDate boundaries so the grid cannot render an empty month.
  • Range reselection. Clicking a third date after a start + end are set begins a new range from that click.
  • Time zone. The component receives and emits Date objects. Pair with convertLocalToUTC / convertUTCToLocal from @prepared911/util-helpers at the boundary; the component does not assume a storage time zone.

Best practices

Do

  • Render the grid inline when operators scan dates in context (analytics filters, scheduling panels).
  • Clamp with minSelectableDate / maxSelectableDate whenever a constraint exists: do not rely on validation alone.
  • Pair cta (Apply / Reset) with deferred commits for filter and form workflows so mid-selection does not dispatch a network request.
  • Keep the selection visible in surrounding UI (a filter pill, a summary line) after the popover closes so keyboard and assistive-tech users retain context.

Don't

  • Don't mount two DatePickers bound to the same value without coordinating open state: they will fight for focus.
  • Don't use DatePicker for time-only or duration entry; the grid is noise in those cases.
  • Don't fake a range with two Single pickers: use DatePickerMode.Range so the component handles the span highlight and end-before-start correction for you.

Accessibility

DatePicker inherits react-day-picker's grid semantics (roving tabindex, arrow-key navigation) and routes Apply / Reset through @prepared911/ui-core Buttons. The app is responsible for a visible label on the trigger, focus handoff when used in a popover, and announcing the committed value after Apply. See the Accessibility page for the full contract.

Related

  • Date Input: DatePicker wrapped in a Popover around a text field.
  • Advanced Date Range Picker: Before / After / Between inequality semantics.
  • Date Time Picker: DatePicker paired with a native time input.
  • Event Recurrence Picker: DatePicker inside a multi-step recurrence rule.

Previous

Date Input / Accessibility

Next

Date Picker / API and Development

On this page

Overview
When to use
When not to use
Composition
Modes
Customization
Behavior and states
Best practices
Accessibility
Related