Date picker

A field that opens a calendar. DatePicker picks a day; DateRangePicker picks a start and an end. On a phone both open as a drawer.

Date pickerOpen it and pick a day. The panel closes on the pick, and the arrow keys move through the month.
Date range pickerTwo picks make a draft, with the range and its length in the footer. Nothing changes until Apply.

Features

  • DatePicker picks as soon as a day is chosen. Presets such as Tomorrow are there when you pass them.
  • DateRangePicker keeps a draft: two picks, a live preview between them, the range and its length in the footer, then Apply. Cancel and Escape leave the value as it was.
  • Presets are functions of today, so "Last 7 days" stays right tomorrow. They're clamped to minDate and maxDate, and turned off when none of their range is allowed.
  • Below the sm breakpoint the panel is a drawer: presets in a chip row, months in one vertical scroll with 44 pixel days, Apply at the bottom. type forces either.

Examples

Open

The range panel as it opens on a desktop: presets, two months, and the footer with Cancel and Apply. Here open holds it open inside a frame given as its container, and modal={false} keeps it from taking focus from the page. defaultOpen opens it once and lets it close.

OpenHeld open in a frame. Below the md breakpoint the popover shows one month.

Single day

With presetsdefaultDatePresets in a rail beside the month. A preset picks and closes, like a day does.
Min and maxBounds and a rule for weekends. Days outside them are struck through, and a preset that lands on one is turned off.

Wed Oct 14 2026

Controlledvalue and onChange from the parent, which here prints the day.
On a phonetype="drawer" shows the phone layout at any width. It opens over the page, and a pick closes it.

The drawer scrolls through a year either side of the picked day. In a phone's frame:

DrawerThe handle, the label as its title with Cancel beside it, and the months in one vertical scroll.

Range

Mon Oct 05 2026 to Sun Oct 11 2026

Range, controlledThe value held by the parent. onChange fires on Apply, never on a half-picked range.
Range with custom presetspresets replaces the rail. Each one gets today and returns a range; this one also starts the week on Monday.
Range, one monthmonths={1} and no presets, for a narrow column. presets={[]} leaves the rail out.
Range on a phoneThe drawer, opened over the page.

The range drawer: a chip row of presets, the weekday header fixed over a vertical scroll of months, and the range with Apply at the bottom.

Range drawerPick two days, or a preset from the chip row. The footer counts the days.

Which layout appears

ScreenDatePickerDateRangePicker
sm and up (640px)DatePickerPopover below the trigger: an optional preset rail and one month. A pick closes it.DateRangePickerPopover: preset rail, two months (one below md, 768px), and a footer with the range, its length, Cancel and Apply.
Below smDatePickerDrawer from the bottom: handle, the label as title with Cancel, chip row, and months in a vertical scroll. A pick closes it.DateRangePickerThe same drawer, with a footer of the range, its length and a full-width Apply.

Layout and spacing

PartSizeSpacingTokens
TriggerSize36px tall, or 32 at sm; hugs its valueSpacing12px sides, 8px between icon, value and chevronTokensinput-subtle fill, input border, radius-sm; muted-foreground placeholder and icons
PopoverSizeHugs the calendar and railSpacing12px around the calendarTokenspopover fill, border, radius-xl, large shadow
Preset railSize144px wide; 32px rowsSpacing8px padding, 2px between rowsTokensGhost buttons; the active one on muted. A border rule on its right
DaySize36px circle; 44px in the drawerSpacingNo gap, so the range bar runs onTokensEnds on primary with primary-foreground; the bar on muted; today bold with a dot
FooterSizeFull widthSpacing12px sides, 10px top and bottom; 16px in the drawerTokensborder rule above; the count in muted-foreground
DrawerSize85% of the screen's heightSpacing16px sides; 4×40px handleTokensbackground fill, border top, radius-xl top corners

States

EmptyThe placeholder in muted-foreground says what to pick.
FilledThe range as the locale writes it, sharing what both ends share.
October 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
Start Oct 14, 2026. Choose an end date.
PickingAfter the first pick: a solid thumb on the start and nothing else until the pointer moves.
October 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
Oct 14 – 23, 2026, 10 days
PickedSolid thumbs on both ends and one bar per week between them.
October 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
Disabled daysMuted, struck through and half opacity. They still take focus.
DisabledThe whole trigger at half opacity; it doesn't open.

Anatomy

The trigger is the only element in the page until it opens. The panel is a popover from it, or a drawer on a phone, and holds a Calendar.

The partsThe trigger, and the popover with its preset rail, calendar and footer.

Guidelines

  • 01Use DatePicker for one day, such as a due date, and DateRangePicker for a span, such as a report period or a stay. Don't use two DatePickers for a range.
  • 02Offer presets for the ranges people pick most. The defaults suit reports; a booking flow wants This weekend or Next week.
  • 03Bound the calendar to what's allowed rather than validating after Apply.
  • 04Leave type on auto in products. Force drawer or popover only to show or test one.

Best practices

DoUse one range picker for a span of dates.
Don'tDon't split it into two pickers. Nothing stops the end coming before the start, and nobody sees the range.

Accessibility

  • 01The trigger is a button named by the label and the value, such as Date range: Oct 5 – 11, 2026. Inside a Field, the FieldLabel and the value name it instead, and clicking the label focuses it. The panel is a dialog named by the label, which the drawer also shows as its title.
  • 02Opening moves focus to the picked day, or today, so the arrows work at once. Escape closes and returns focus to the trigger.
  • 03The calendar's grid keyboard model applies inside; see Calendar.
  • 04Presets are toggle buttons: the one matching the draft is aria-pressed.
  • 05Apply stays disabled until both ends are picked, and the footer says what's missing.
  • 06Day cells in the drawer are 44 pixels, above the minimum touch target.

References