Xzero UI
Pro library

Date range picker

A range picker that grows from its trigger into two months with presets and a stretching range highlight.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/date-range-picker
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui/date-range-picker

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { useState } from "react";
import { DateRangePicker } from "@/components/xzero/date-range-picker/date-range-picker";
import type { DateRange } from "@/components/xzero/date-range-picker/date-range-picker";

export function ReportRange() {
  const [range, setRange] = useState<DateRange | null>(null);
  return (
    <DateRangePicker
      label="Report period"
      value={range}
      onChange={setRange}
      weekStartsOn={1}
      maxDate={new Date()}
    />
  );
}

API reference

DateRangePicker

A trigger that grows into a panel with one or two months and a preset rail, then shrinks back with the applied range.

PropTypeDefaultDescription
valueDateRange | null–Controlled value, { start, end } as inclusive whole days. Pass null for no selection.
defaultValueDateRange | nullnullUncontrolled starting value.
onChange(range: DateRange) => void–Called with the range on Apply.
labelstring"Date range"Accessible name of the trigger and the dialog.
placeholderstring"Select dates"Trigger text with no selection.
presetsDateRangePreset[]defaultDateRangePresetsShortcuts: { label, range: (today) => DateRange }. Defaults to Today through Year to date.
minDateDate–Earliest selectable day.
maxDateDate–Latest selectable day.
weekStartsOn0 | 100 is Sunday, 1 is Monday.
localestring"en-US"Locale for Intl.DateTimeFormat labels and month titles.
months"auto" | 1 | 2"auto"Force one or two months. auto shows two when the boundary is at least 712px wide.
boundary() => HTMLElement | null–Element the panel should stay inside. Defaults to the viewport.
classNamestring–Extra class on the root.

useToday

Hook returning the viewer's local date, or undefined during server render and hydration. Updates at local midnight and when the tab becomes visible.

No props.

Keyboard interactions

KeysAction
Enter / SpaceOpens the panel from the trigger; picks a start or end day in the grid.
Arrow keysMove by day or week in the grid, extending the range preview once a start is picked.
Home / EndJump to the start or end of the week.
PageUp / PageDownMove by month; add Shift to move by year.
ArrowUp / ArrowDownMove between presets in the rail; ArrowLeft and ArrowRight in the compact row.
EscapeCloses without applying and returns focus to the trigger.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in pickers

Guidance for AI tools

Date range picker: A range picker that grows from its trigger into two months with presets and a stretching range highlight. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components