Shadcn DateTime Picker

repository·main·Indexed 42 days ago

https://github.com/maliksidk19/shadcn-datetime-picker

A collection of customizable date and time picker components built on shadcn/ui, @daypicker/react, and Base UI. It includes multiple variants: a combined picker, separate fields, a range picker for start/end selections, and a DateTimePickerField wrapper for seamless integration with react-hook-form and zod.

Tokens
5.4K
Snippets
11
Records
18
Agent score
49%

What's inside Shadcn DateTime Picker

  1. Use the DateTimePicker component

    main

    The DateTimePicker is an all-in-one calendar and time picker in a single popover. It is ideal for forms and scheduling.

    Basic Usage

    import { DateTimePicker } from "@/components/datetime-picker";
    
    export default function MyForm() {
      const [date, setDate] = useState<Date>();
    
      return <DateTimePicker value={date} onChange={setDate} />;
    }

    Common Configurations

    • 12-Hour Format: <DateTimePicker hourFormat={12} />
    • Business Hours: Restrict time using minTime and maxTime (e.g., minTime="09:00", maxTime="17:00") and set timeInterval (15, 30, or 60).
    • Timezone Selector: Use showTimezone to enable the dropdown. You can pre-set a timezone with timezone="America/New_York" or track changes with onTimezoneChange.
    • Date Restrictions: Use minDate and maxDate to constrain selectable dates. Use disabledDates with a callback function to disable specific days (e.g., weekends).
    • Week Start: Set weekStartsOn={1} to start the week on Monday (0 is Sunday).
  2. Install Shadcn DateTime Picker

    main

    To use the Shadcn DateTime Picker, follow these three steps in your project which must already have shadcn/ui configured.

    1. Install dependencies

    npm install @daypicker/react date-fns

    2. Add required Shadcn components

    npx shadcn@latest add popover button scroll-area select separator drawer

    3. Copy the components

    Copy the following files into your src/components/ directory. You can pick only the variants you need:

    • src/components/ui/calendar-dropdown.tsx (Required for custom calendar navigation)
    • src/components/datetime-picker.tsx (Variant 1: Combined picker)
    • src/components/datetime-picker-separate.tsx (Variant 2: Separate fields)
    • src/components/datetime-picker-range.tsx (Variant 3: Range picker)
    • src/components/datetime-picker-form.tsx (Variant 4: React Hook Form integration)
    npm install @daypicker/react date-fns
    
    npx shadcn@latest add popover button scroll-area select separator drawer
  3. Integrate DateTimePicker with HTML forms

    main

    To use the DateTimePicker within a standard HTML <form>, provide a name prop. The component will automatically render a hidden <input type="hidden" /> containing the selected date in ISO format, allowing it to be submitted alongside other form fields.

    <form action="/api/submit" method="POST">
      <label htmlFor="event-time">Event Time:</label>
      <DateTimePicker name="event_time" />
      <button type="submit">Submit</button>
    </form>
  4. Integrate DateTimePicker with React Hook Form

    main

    The DateTimePickerField component is a wrapper designed for seamless integration with react-hook-form and zod. It handles labels, descriptions, and error states automatically.

    Basic Usage

    import {
      DateTimePickerField,
      useForm,
      zodResolver,
    } from "@/components/datetime-picker-form";
    import { z } from "zod";
    
    const schema = z.object({
      appointment: z.date({ error: "Please select a date and time." }),
    });
    
    export default function MyForm() {
      const form = useForm({
        resolver: zodResolver(schema),
      });
    
      return (
        <form onSubmit={form.handleSubmit((data) => console.log(data))}>
          <DateTimePickerField
            control={form.control}
            name="appointment"
            label="Appointment"
            description="Select a date and time for your appointment."
            hourFormat={12}
            minTime="09:00"
            maxTime="17:00"
            timeInterval={30}
          />
          <button type="submit">Submit</button>
        </form>
      );
    }

    API Reference

    PropTypeDefaultDescription
    controlControl<T>requiredReact Hook Form control
    namePath<T>requiredField name (type-safe)
    labelstring—Field label
    descriptionstring—Help text below the picker

    Note: All other props from DateTimePicker are supported.

  5. Use DateTimePickerSeparate for individual fields

    main

    The DateTimePickerSeparate component provides individual date, time, and timezone fields that work together. This is best when you want each field to be independently accessible.

    Basic Usage

    import { DateTimePickerSeparate } from "@/components/datetime-picker-separate";
    
    <DateTimePickerSeparate />

    Additional Props

    In addition to all DateTimePicker props, it supports:

    • datePlaceholder: String for the date field placeholder (Default: "Pick a date").
    • timePlaceholder: String for the time field placeholder (Default: "Pick time").
  6. Use DateTimePickerRange for range selection

    main

    The DateTimePickerRange component allows for start/end date and time selection using tab-based navigation. It is ideal for booking systems or analytics filters.

    Workflow

    1. Open the picker via the trigger.
    2. From tab: Select the start date and time. Selecting a start date automatically switches to the To tab.
    3. To tab: Select the end date and time. Dates occurring before the start date are automatically disabled.
    4. Selecting the end time closes the picker.

    Basic Usage

    import { DateTimePickerRange, type DateTimeRange } from "@/components/datetime-picker-range";
    
    const [range, setRange] = useState<DateTimeRange>();
    
    <DateTimePickerRange value={range} onChange={setRange} />

    API Reference

    PropTypeDefaultDescription
    valueDateTimeRange—{ from?: Date, to?: Date }
    onChange(range: DateTimeRange) => void—Callback with range
  7. Reference: DateTimePicker props

    main

    The following props are available for the DateTimePicker component:

    PropTypeDefaultDescription
    valueDate | undefined—Controlled selected date/time
    onChange(date: Date | undefined) => void—Callback when date/time changes
    disabledbooleanfalseDisable the picker
    placeholderstring"Pick a date and time"Placeholder text
    hourFormat12 | 2424Time display format
    timeInterval15 | 30 | 6015Minutes between time slots
    minDateDate—Earliest selectable date
    maxDateDate—Latest selectable date
    minTimestring—Earliest time slot (e.g. "09:00")
    maxTimestring—Latest time slot (e.g. "17:00")
    timezonestringUser's localIANA timezone (e.g. "America/New_York")
    showTimezonebooleanfalseShow timezone selector dropdown
    onTimezoneChange(tz: string) => void—Callback when timezone changes
    weekStartsOn0-6—Week start day (0=Sun, 1=Mon, ...)
    disabledDates(date: Date) => boolean—Custom date disable function
    namestring—Form field name (renders hidden input)
    classNamestring—Custom class for trigger button
    refRef<HTMLInputElement>—Ref forwarded to hidden input
  8. Configure DateTimePickerProps

    main

    The DateTimePicker component accepts the following props to control its behavior and appearance:

    PropTypeDefaultDescription
    valueDateundefinedThe currently selected date and time.
    onChange(date: Date | undefined) => voidundefinedCallback triggered when a new date/time is selected.
    disabledbooleanfalseDisables the entire picker.
    minDateDateundefinedThe earliest selectable date.
    maxDateDateundefinedThe latest selectable date.
    placeholderstring"Pick a date and time"Text shown when no value is selected.
    timeInterval15 | 30 | 6015The interval in minutes for time slot increments.
    hourFormat12 | 2424Use 12 for AM/PM format, or 24 for 24-hour format.
    timezonestringundefinedInitial timezone (e.g., America/New_York). If omitted, defaults to local browser timezone.
    showTimezonebooleanfalseIf true, displays a timezone selector within the picker.
    onTimezoneChange(timezone: string) => voidundefinedCallback triggered when the timezone is changed.
    minTimestringundefinedMinimum time allowed (format: HH:mm or h:mm A).
    maxTimestringundefinedMaximum time allowed (format: HH:mm or h:mm A).
    weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 6undefinedDay of the week the calendar starts on (0 = Sunday).
    disabledDates(date: Date) => booleanundefinedA function that returns true to disable specific dates.
    namestringundefinedThe name attribute for the hidden input field (enables form integration).
    classNamestringundefinedAdditional CSS classes for the trigger button.
  9. Customize time intervals and formats in DateTimePickerSeparate

    main

    You can control the granularity and display format of the time picker using timeInterval and hourFormat.

    • timeInterval: Accepts 15, 30, or 60. This determines the steps available in the time selection list.
    • hourFormat: Set to 12 for AM/PM style or 24 for military time.

    Example of a 12-hour picker with 30-minute increments:

    <DateTimePickerSeparate
      value={date}
      onChange={setDate}
      timeInterval={30}
      hourFormat={12}
    />
  10. Integrate DateTimePicker with React Hook Form using DateTimePickerField

    main

    The DateTimePickerField component is a generic wrapper designed to integrate the DateTimePicker component directly into a react-hook-form workflow. It handles the connection between the form state and the picker, including value updates, error display, and field descriptions.

    To use it, you must provide a control object from useForm and a name that matches a key in your form's data schema. It accepts all standard DateTimePickerProps (excluding those handled by the controller) such as disabled or other picker-specific configurations.

    import {
      useForm,
      zodResolver
    } from "./src/components/datetime-picker-form";
    import { DateTimePickerField } from "./src/components/datetime-picker-form";
    import { z } from "zod";
    
    const formSchema = z.object({
      appointmentDate: z.date(),
    });
    
    export function MyForm() {
      const form = useForm({
        resolver: zodResolver(formSchema),
        defaultValues: {
          appointmentDate: undefined,
        },
      });
    
      return (
        <form onSubmit={form.handleSubmit(console.log)}>
          <DateTimePickerField
            control={form.control}
            name="appointmentDate"
            label="Select Date"
            description="Please choose a time for your appointment."
          />
          <button type="submit">Submit</button>
        </form>
      );
    }
  11. Use the DateTimePicker component

    main

    The DateTimePicker component provides an all-in-one interface for selecting both a date and a time. It supports responsive layouts (Popover for desktop, Drawer for mobile), timezone selection, and various time formats. It can be used as a controlled or uncontrolled component and is compatible with HTML forms via a hidden input field.

    import { DateTimePicker, DateTimePickerProps } from "@/components/datetime-picker";
    
    export default function MyForm() {
      const [date, setDate] = useState<Date | undefined>(new Date());
    
      return (
        <DateTimePicker
          value={date}
          onChange={setDate}
          placeholder="Select date and time"
          hourFormat={12}
          timeInterval={15}
        />
      );
    }