MiHCM
primitives/@mihcm/ui·v0.21.0·stable

DatePicker

DayPicker v10-backed trigger + popover for single dates, ranges, date-time, and time-only fields. Calendar and DatePicker share one date engine.

Overview

DatePicker now uses the same @daypicker/react v10 engine as Calendar. This keeps date, date range, date-time, and time-only UI on one dependency and one styling model.

Use Cases

  • Single date input — pick one date from a popover calendar.
  • Date range — select start and end dates with the same DayPicker range mode used by Calendar.
  • Date and time — select a date and edit the time in the popover footer.
  • Time only — use the same trigger and form surface for time values.
  • Icon trigger — use a square calendar button where the date value is displayed elsewhere.

Dependency Rule

Do not add another calendar library for new date fields. Use:

  • Calendar for the raw DayPicker grid.
  • DatePicker for trigger + popover + optional time controls.
  • TanStack Form validators for form-level validation.

Props

PropDescription
selectedSingle-date value.
selectsRangeEnables range mode.
startDate / endDateRange values.
showTimeSelectAdds time controls under the calendar.
showTimeSelectOnlyShows only the time control.
calendarPropsPass-through DayPicker v10 props via Calendar.
disabledDaysDayPicker matcher or matcher array for blocked dates.
minDate / maxDateConvenience boundaries mapped to DayPicker disabled matchers.
triggerVariant'field' for the normal field button, or 'icon' for a square icon-only trigger.
triggerIcon, triggerClassName, triggerWidthTrigger customization using MiHCM tokens. Default width is compact; use triggerWidth="full" for grid forms.
closeOnRangeCompleteOpt-in close behavior after both range endpoints are selected. Default keeps the popover open.

Responsive Forms

Use triggerWidth="full" when DatePicker sits inside a form column, responsive grid, or mobile sheet. Full width is applied through the component root, Popover wrapper, and trigger so the field does not shrink to the content width.

<div className="grid gap-4 sm:grid-cols-2">
  <DatePicker selected={startDate} onChange={setStartDate} triggerWidth="full" />
  <DatePicker selected={endDate} onChange={setEndDate} triggerWidth="full" />
</div>

The popup matches the trigger width and remains viewport capped. If a small mobile viewport shows a wide multi-month calendar, the popup scrolls horizontally instead of clipping interactive days.

Calendar Header

The picker defaults calendarProps.captionLayout to dropdown, with broad startMonth and endMonth boundaries. This gives users direct month and year changes without adding a second date library. Override those boundaries with minDate, maxDate, or explicit calendarProps.startMonth / calendarProps.endMonth.

Accessibility

The trigger is a button with dialog semantics. The calendar grid comes from DayPicker v10, so keyboard navigation and date semantics stay consistent between Calendar and DatePicker. Icon-only triggers must keep an explicit placeholderText because that text becomes the accessible button label when no value is selected.