Skip to content
txbrendan/ui

Date Picker

beta

A field that shows a day, like "Sat 3 Oct", and opens a calendar under it to pick one. Weeks start on Monday, and the year shows only when it is not this year.

Preview

size

Event date, sm
Event date, md
Event date, lg

states

Meeting day

Weeknights only.

Project starts

Another year shows its year.

Invoice due

limits

Workshop

Until 20 Dec. Two Saturdays are taken.

Locked

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the component.

    npx shadcn@latest add @txbrendan/date-picker

Use it for

  • One day for something people plan: a meeting, a workshop, an invoice's due date.
  • Give it a label, like "Event date". Without one, pass aria-label.
  • The value is a day as "YYYY-MM-DD", with no time and no time zone.
  • Set min and max for the days people may pick, and disabledDates for days that are taken.
  • Put what is wrong in error, like "Pick a day from today on." It replaces the hint and is said once.
  • Pass name to send the day with a form.

Avoid it for

  • A start and an end day. Use a Calendar with mode="range".
  • A calendar that stays on the page, like a schedule. Use a Calendar.
  • A birth date or another day far in the past. Typing it is quicker than paging back through months.

Props

  • label

    Names the field, above it. Pressing it focuses the button and does not open the calendar.

    ReactNode

  • value

    The picked day, "YYYY-MM-DD". Use it with onValueChange.

    string | null

  • defaultValue

    The picked day at first render, when you do not control it.

    string | null

  • onValueChange

    Called with the new day when someone picks one.

    (day: string) => void

  • placeholder

    Shown while no day is picked.

    string · default "Pick a date"

  • hint

    A short note under the field.

    ReactNode

  • error

    Replaces the hint, in red, and is announced once.

    ReactNode

  • min

    The earliest day people can pick, "YYYY-MM-DD".

    string

  • max

    The latest day people can pick, "YYYY-MM-DD".

    string

  • disabledDates

    Days people cannot pick.

    string[] | (date: string) => boolean

  • weekStartsOn

    The first column. 1 is Monday.

    0 | 1 | 2 | 3 | 4 | 5 | 6 · default 1

  • locale

    A language tag for the button and the calendar.

    string · default "en-GB"

  • size

    Height and text size of the button, the label, and the calendar.

    "sm" | "md" | "lg" · default "md"

  • disabled

    Blocks the button.

    boolean · default false

  • name

    Form field name. Sends the day, or nothing while none is picked.

    string

  • aria-label

    Names the field when there is no visible label.

    string

  • className

    Classes for the frame. Later classes win.

    string

Accessibility

  • The button's name is the label and then the day, like "Event date, Sat 3 Oct". It says it opens a dialog, and whether it is open.
  • The calendar opens with focus on the picked day, or today, or the month's first day.
  • In the calendar the arrows move a day or a week, Home and End go to the week's ends, and Page Up and Page Down move a month, with Shift a year.
  • Enter, Space, or a click picks a day. That closes the calendar and puts focus back on the button.
  • Escape or a click outside closes it without a change.
  • The hint or the error describes the button. The error is announced once when it appears.

Examples

With a picked day and a hint

<DatePicker label="Event date" defaultValue="2026-10-03" hint="It starts at 10:00." />

Limits and taken days

<DatePicker
  label="Friendly"
  min="2026-10-26"
  max="2026-12-20"
  disabledDates={["2026-10-31", "2026-11-07"]}
/>