Date Picker - React Hook Form
A Date Picker component that uses react-hook-form Controller.
Installation
npx shadcn@latest add /registry/rhf-date-picker.json
Manual Installation
This component is dependent on date-picker and floating-button components. Please add that component first before adding this one.
Install the following dependencies:
npm install date-fns
1. Copy and paste the following code into your project.
"use client";
import type { ComponentPropsWithoutRef } from "react";
import { Controller, type FieldPath, type FieldValues, useFormContext } from "react-hook-form";
import { DatePicker } from "@/components/ui/date/date-picker";
import { FloatingLabelButon } from "@/components/ui/buttons/floating-label-button";
import { Calendar } from "@/components/ui/calendar";
// ----------------------------------------------------------------------
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface ICalendar extends Omit<ComponentPropsWithoutRef<typeof Calendar>, "selected" | "onSelect" | "mode"> {}
interface RHFDatePickerProps<TFieldValues extends FieldValues>
extends Omit<ComponentPropsWithoutRef<typeof Controller>, "name" | "control" | "render"> {
name: FieldPath<TFieldValues>;
btnProps?: Omit<React.ComponentPropsWithoutRef<typeof FloatingLabelButon>, "value" | "label">;
calendarProps?: ICalendar;
helperText?: string;
label?: string;
}
export default function CustomRHFDatePicker<TFieldValues extends FieldValues>({
name,
helperText,
defaultValue,
rules,
btnProps = {
size: "md",
className: "[&>svg]:size-6",
},
label,
calendarProps,
}: RHFDatePickerProps<TFieldValues>) {
const { control } = useFormContext();
return (
<Controller
name={name}
control={control}
defaultValue={defaultValue}
rules={rules}
render={({ field, fieldState: { error } }) => (
<div className="flex flex-col">
<DatePicker
label={label}
btnProps={{
...btnProps,
error: !!error,
}}
date={field.value}
onSelect={field.onChange}
calendarProps={calendarProps}
/>
{!!helperText && <p className="text-sm leading-none text-muted-foreground ml-1.5 mt-2">{helperText}</p>}
{!!error && <p className="text-sm leading-none text-error ml-1.5 mt-2">{error?.message}</p>}
</div>
)}
/>
);
}
2. Update your calendar
component after installing shadcn date-picker
component.
import { ChevronLeft, ChevronRight } from "lucide-react";
function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) {
return (
<DayPicker
...
components={{
IconLeft: () => <ChevronLeft className="h-4 w-4" />,
IconRight: () => <ChevronRight className="h-4 w-4" />,
}}
{...props}
/>
);
}
3. Add this to your @/components/ui/hook-form/index.tsx
file for easy import.
export { default as RHFDatePicker } from "./rhf-date-picker";
Shadcn
This date-picker component is built on top of the excellent foundation provided by Shadcn/UI.
For a deeper dive into the core concepts and building blocks, check out the original Shadcn date-picker component.