Skip to Content
ComponentsDateRangePicker

DateRangePicker

Calendar popover that lets user pick date ranges.

Documentation

Usage

"use client"; import { DateRangePicker, DateRangePickerContent, DateRangePickerTrigger, } from "@optiaxiom/react"; export function App() { return ( <DateRangePicker> <DateRangePickerTrigger w="224" /> <DateRangePickerContent /> </DateRangePicker> ); }

Anatomy

import { DateRangePicker, DateRangePickerContent, DateRangePickerTrigger, } from "@optiaxiom/react"; export default () => ( <DateRangePicker> <DateRangePickerTrigger /> <DateRangePickerContent /> </DateRangePicker> );

Controlled

Use the value and defaultValue props to toggle between controlled and uncontrolled usage. And combine it with onValueChange to listen for changes to the state.

Selected: June 6 – 15, 2025

"use client"; import { DateRangePicker, DateRangePickerContent, DateRangePickerTrigger, Flex, Text, } from "@optiaxiom/react"; import { useState } from "react"; const formatter = new Intl.DateTimeFormat(undefined, { dateStyle: "long" }); export function App() { const [value, setValue] = useState<null | { from: Date; to: Date }>({ from: new Date("2025-06-06T00:00"), to: new Date("2025-06-15T23:59"), }); return ( <Flex> <DateRangePicker onValueChange={setValue} value={value}> <DateRangePickerTrigger w="224" /> <DateRangePickerContent /> </DateRangePicker> <Text fontSize="md"> Selected: {value && formatter.formatRange(value.from, value.to)} </Text> </Flex> ); }

Addons

Use the addonBefore and addonAfter prop on DateRangePickerContent to add content to either side of the calendar.

"use client"; import { DateRangePicker, DateRangePickerContent, DateRangePickerTrigger, SegmentedControl, SegmentedControlItem, } from "@optiaxiom/react"; import { useState } from "react"; import { presetToRange } from "./presetToRange"; export function App() { const [preset, setPreset] = useState("custom"); const [value, setValue] = useState<null | { from: Date; to: Date }>(null); return ( <DateRangePicker onValueChange={(value) => { setPreset("custom"); setValue(value); }} value={value} > <DateRangePickerTrigger w="224" /> <DateRangePickerContent addonBefore={ <SegmentedControl flexDirection="column" gap="2" mr="8" onValueChange={(preset: string) => { if (!preset || preset === "custom") { return; } setPreset(preset); setValue(presetToRange(preset)); }} value={preset} > <SegmentedControlItem value="today">Today</SegmentedControlItem> <SegmentedControlItem value="week">This week</SegmentedControlItem> <SegmentedControlItem value="month"> This month </SegmentedControlItem> <SegmentedControlItem value="next-week"> Next week </SegmentedControlItem> <SegmentedControlItem value="next-month"> Next month </SegmentedControlItem> <SegmentedControlItem value="custom">Custom</SegmentedControlItem> </SegmentedControl> } /> </DateRangePicker> ); }

Props

DateRangePicker

Supports all Popover props in addition to its own. Doesn't render its own HTML element.

Prop

defaultOpen

The initial open state in uncontrolled mode.

false | true

Default: false

defaultValue

The initial selected value in uncontrolled mode.

DateRange

Default: null

disabled

false | true

modal

When enabled interaction with outside elements will be disabled and only popover content will be visible to screen readers.

false | true

onOpenChange

Handler that is called when the open state changes.

(open: boolean) => void

onValueChange

Handler that is called when the selected value changes.

(value: DateRange) => void

open

The open state in controlled mode.

false | true

value

The selected value in controlled mode.

DateRange

DateRangePickerTrigger

Supports all Button props in addition to its own. Renders a <button> element.

Prop

addonAfter

Display content inside the button after children.

ReactNode

addonBefore

Display content inside the button before children.

ReactNode

appearance

Control the appearance by selecting between the different button types.

"default" | "danger" | "primary" | "subtle" | "danger-outline" | "inverse"

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

disabled

Whether the button is disabled.

false | true

formatRange

any

hasCustomAnchor

false | true

icon

Display an icon before or after the button content or omit children to only show the icon.

ReactNode

iconPosition

Control whether to show the icon before or after the button content.

"end" | "start"

loading

Whether to show loading spinner inside the button.

false | true

placeholder

string

Default: Pick a date

size

Control the size of the button.

"sm" | "md" | "lg"

square

Whether button should have square shape.

false | true

DateRangePickerContent

Supports all Box props in addition to its own. Renders a <div> element.

Prop

addonAfter

Display content inside the popover after the calendar.

ReactNode

addonBefore

Display content inside the popover before the calendar.

ReactNode

align

"center" | "end" | "start"

alignOffset

number

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

holiday

Apply the holiday modifier to the matching days.

false | true | (date: Date) => boolean | Date | Date[] | DateRange | DateBefore | DateAfter | DateInterval | DayOfWeek | Matcher[]

max

The latest date that is allowed.

Date

maxH

Whether to restrict the max-height of the content.

Content is also restricted by the available height in the screen relative to the trigger.

"xs" | "sm" | "md" | "lg" | "full"

min

The earliest date that is allowed.

Date

minW

Whether to set the min-width to the width of the trigger.

"0" | "trigger"

onCloseAutoFocus

Event handler called when auto-focusing on close. Can be prevented.

(event: Event) => void

onEscapeKeyDown

Event handler called when the escape key is down. Can be prevented.

(event: KeyboardEvent) => void

onFocusOutside

Event handler called when the focus moves outside of the DismissableLayer. Can be prevented.

(event: FocusOutsideEvent) => void

onInteractOutside

Event handler called when an interaction happens outside the DismissableLayer. Specifically, when a pointerdown event happens outside or focus moves outside of it. Can be prevented.

(event: FocusOutsideEvent | PointerDownOutsideEvent) => void

onOpenAutoFocus

Event handler called when auto-focusing on open. Can be prevented.

(event: Event) => void

onPointerDownOutside

Event handler called when the a pointerdown event happens outside of the DismissableLayer. Can be prevented.

(event: PointerDownOutsideEvent) => void

side

"bottom" | "left" | "right" | "top"

sideOffset

number

today

The today’s date. Default is the current date. This date will get the today modifier to style the day.

https://daypicker.dev/guides/custom-modifiers#today-modifier

Date

weekend

Apply the weekend modifier to the matching days.

false | true | (date: Date) => boolean | Date | Date[] | DateRange | DateBefore | DateAfter | DateInterval | DayOfWeek | Matcher[]

withArrow

Whether to show an arrow.

false | true

Accessibility

Keyboard interactions

Key

Description

SpaceWhen focus is on DateRangePickerTrigger, opens the calendar and focuses the selected day (or today’s date). When focus is on a day, selects the focused day.
EnterWhen focus is on DateRangePickerTrigger, opens the calendar and focuses the selected day (or today’s date). When focus is on a day, selects the focused day.
ArrowUp ArrowDown
ArrowRight ArrowLeft
Navigate between days in the calendar.
PageUp PageDown
Navigate between months in the calendar.
PageUp PageDown
Navigate between years in the calendar.
EscCloses the calendar popover and moves focus back to DateRangePickerTrigger.

Changelog

1.4.0

  • Moved component out of Alpha.

    // Before import { DateRangePicker } from "@optiaxiom/react/unstable"; // After import { DateRangePicker } from "@optiaxiom/react";

0.13.10

  • Added component
Last updated on