Component guideEditable source

Date Picker

A date-selection recipe combining a trigger, popover, and calendar.

Original component docs
On this page4 sectionsBack to top

Use Date Picker when a date field should open a calendar on demand. This is a composition recipe, not a standalone registry endpoint. It keeps selected-date and popup state in your application.

Live preview
Loading preview...

#Installation

Complete the base setup, then install Button, Popover, and Calendar. Copy the recipe into your application.

npx shadcn@latest add https://neobrutal-ui.andongmin.com/r/button.json https://neobrutal-ui.andongmin.com/r/popover.json https://neobrutal-ui.andongmin.com/r/calendar.json

The live preview uses date-fns; install it when copying that preview. The standalone Usage example below uses native date formatting instead.

npm install date-fns

#Usage

"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";

export default function AppointmentDate() {
  const [date, setDate] = useState<Date | undefined>();
  const [open, setOpen] = useState(false);
  return (
    <div className="grid max-w-sm gap-2">
      <label htmlFor="appointment-date">Appointment date</label>
      <Popover open={open} onOpenChange={setOpen}>
        <PopoverTrigger render={<Button id="appointment-date" variant="outline" />}>
          {date ? date.toLocaleDateString() : "Choose a date"}
        </PopoverTrigger>
        <PopoverContent aria-label="Choose an appointment date" align="start" sideOffset={8} className="w-auto border-0! bg-transparent p-0 shadow-none">
          <Calendar
            mode="single"
            selected={date}
            defaultMonth={date}
            autoFocus
            onSelect={(next) => {
              setDate(next);
              setOpen(false);
            }}
          />
        </PopoverContent>
      </Popover>
    </div>
  );
}

#API reference

Recipe state / partPurposeDefault
date / setDateSelected Date or undefinedNo date
open / setOpenPopup visibilityfalse
Calendar.modeSelection modesingle here
Calendar.disabledPrevent selection of matching datesNone
PopoverContent.alignTrigger-relative placementstart here
Calendar.onSelectSave date and optionally closeApplication callback

#Accessibility

Label the trigger and keep the chosen date visible. Verify keyboard date navigation, Escape, and focus return after closing. A button does not submit a date value automatically: add application form state or a hidden input when needed. Store date-only values without unintended timezone conversion, and distinguish navigation bounds from disabled dates.