Date picker

Choose a date without losing context.

datefield
Preview
Date picker preview

When to use

  • A date field in a form, such as a start or due date.
  • Dates with limits or blocked days, shown in a locale format.

When not to use

  • Use calendar inline when the grid should stay visible.
  • Use time-picker for times, and pair it with this for a full timestamp.

shadcn CLI

Also installs (2)

  • manicat-foundation
  • calendar
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "date-picker",
  "type": "registry:ui",
  "title": "Date picker",
  "description": "Choose a date without losing context.",
  "categories": [
    "inputs"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json",
    "https://manicat.viraza.net/r/calendar.json"
  ],
  "files": [
    {
      "path": "registry/components/date-picker/date-picker.tsx",
      "type": "registry:component",
      "target": "@components/manicat/date-picker/date-picker.tsx"
    },
    {
      "path": "registry/components/date-picker/date-picker.module.css",
      "type": "registry:component",
      "target": "@components/manicat/date-picker/date-picker.module.css"
    },
    {
      "path": "registry/components/calendar/calendar.tsx",
      "type": "registry:component",
      "target": "@components/manicat/calendar/calendar.tsx"
    },
    {
      "path": "registry/components/calendar/calendar.module.css",
      "type": "registry:component",
      "target": "@components/manicat/calendar/calendar.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/date-picker",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/date-picker",
    "markdown": "https://uiarc.dev/components/date-picker/markdown",
    "tags": [
      "date",
      "field"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { useState } from "react";
import { DatePicker } from "@/components/manicat/date-picker/date-picker";

export function DatePickerExample() {
  const [date, setDate] = useState<Date | null>(new Date(2026, 9, 5));

  return <DatePicker label="Ship date" value={date ?? undefined} onChange={(next) => setDate(next ?? null)} />;
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Ship date A date field that opens a calendar and tells the user how far away the date is.

Ship date A date field that opens a calendar and tells the user how far away the date is. preview

Mon Oct 05 2026

Keyboard interactions

KeysAction
Enter / Space / ArrowDownOpens the calendar and focuses the selected or current day.
EscapeCloses the popover and returns focus to the trigger.
Calendar keysArrows, Home, End, PageUp, and PageDown navigate days as in Calendar.

Accessibility

  • Trigger has aria-haspopup="dialog" and aria-expanded; the popover is role="dialog" labelled "<label> calendar".
  • The formatted value lives in a visually hidden span; the rolling text is aria-hidden.
  • Tabbing out or clicking outside closes it, and focus returns to the trigger when it was inside.

Motion

  • Changed date parts roll up for a later date and down for an earlier one; the popover springs in and closes about 240 ms after a pick so the highlight can land.
  • Reduced motion crossfades the value and closes immediately after a pick.

Responsive behavior

  • The popover is min(320px, 100vw minus 32px) wide, left-aligned to the field.
  • Below 360px of viewport the popover stretches to both field edges.
  • It closes on any pointerdown outside, so a tap elsewhere dismisses it.

Performance

  • The calendar mounts only while open, and changed date parts roll with layout position animation.

Notes for AI

  • Use for a date field in forms. Use calendar inline when the grid should stay visible, and time-picker for times.
  • value is controlled only. There is no name prop; serialize the Date into a hidden input for plain forms.