Skip to content
Primitives

Date Picker

An outline-tech trigger that reads the chosen date in a mono readout and opens the Calendar on a hard-shadow popover. Controlled via `value`/`onValueChange`, so it drops straight into a Form field.

● LIVE
npx shadcn@latest add https://okibi.cndr.dev/r/date-picker.json

Installation

Install the theme first, then add the component:

npx shadcn@latest add https://okibi.cndr.dev/r/date-picker.json

Install the required dependencies:

npm install lucide-react

Add the okibi building blocks it composes: button, calendar, popover.

Copy the source from the Code tab above into components/ui/date-picker.tsx. It uses the cn helper and the okibi theme tokens — install the theme first if you haven't.

Usage

import { DatePicker } from "@/components/ui/date-picker"

const [date, setDate] = React.useState<Date | undefined>(undefined)

<DatePicker value={date} onValueChange={setDate} />

API Reference

DatePicker

PropTypeDefaultDescription
valueDate | undefinedThe selected date (controlled).
onValueChange(date: Date | undefined) => voidFires when a date is picked.
placeholderstring"Pick a date"Trigger text when empty.
disabledbooleanfalseDisable the trigger.
calendarDisabledMatcher | Matcher[]Constrain selectable days — forwarded to the Calendar's disabled matcher.
startMonthDateEarliest navigable month — forwarded to the Calendar.
endMonthDateLatest navigable month — forwarded to the Calendar.

Accessibility

  • The trigger sets aria-haspopup='dialog' and aria-expanded so assistive tech announces the popover and its open/closed state.
  • It's a real Button, so it inherits the 2px signal focus ring plus disabled:pointer-events-none when disabled.
  • Keyboard date selection, roving focus, and autoFocus-on-open are inherited wholesale from the embedded Calendar grid.
  • The trigger has no built-in label — wire a Label via htmlFor={id} so the field is named for screen readers.
  • Picking a day fires onValueChange and closes the popover, returning focus to the trigger.

Guidelines

Do

  • Always pair an id with a Label htmlFor so the control announces what it picks.
  • Constrain selectable days with calendarDisabled and bound navigation with startMonth / endMonth rather than validating after the fact.
  • Treat it as controlled — own the Date in state and read it back through value.

Don't

  • Don't rely on it for native <form> submission; it's controlled-only, so serialize the Date yourself.
  • Don't assume the readout is stable across environments — toLocaleDateString() follows the runtime locale and timezone.

On this page