Calendar

A date field component that allows users to enter and edit date.

SuMoTuWeThFrSa

Installation

Install the following dependencies:

pnpm add react-day-picker date-fns

Add the Button component to your project.

Copy and paste the following code into your project.

"use client";

import * as React from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { DayPicker } from "react-day-picker";

import { cn } from "~/utils/tailwind";
import { buttonVariants } from "./Button";

export type CalendarProps = React.ComponentProps<typeof DayPicker>;

function Calendar({
  className,
  classNames,
  showOutsideDays = true,
  ...props
}: CalendarProps) {
  return (
    <DayPicker
      showOutsideDays={showOutsideDays}
      className={cn("bg-background px-3 py-2.5", className)}
      classNames={{
        caption: "flex justify-between items-center mb-0.5",
        caption_label: "text-3.5 font-medium text-foreground",
        nav: "gap-x-1 flex items-center",
        nav_button: cn(
          buttonVariants({ variant: "outline", size: "icon" }),
          "size-7 rounded-1.5",
        ),
        table: "w-full border-collapse",
        head_row: "flex",
        head_cell:
          "text-muted-foreground size-8 flex justify-center items-center font-normal text-[12.8px]",
        row: "flex w-full",
        cell: "relative p-0 text-center text-3.5 focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 rounded-1.5",
        day: cn(
          buttonVariants({ variant: "ghost", size: "icon" }),
          "size-8 p-0 font-normal aria-selected:opacity-100",
        ),
        day_range_start: "day-range-start",
        day_range_end: "day-range-end",
        day_selected:
          "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
        day_today: "bg-accent",
        day_outside:
          "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
        day_disabled: "text-muted-foreground opacity-50",
        day_range_middle:
          "aria-selected:bg-accent aria-selected:text-accent-foreground",
        day_hidden: "invisible",
        ...classNames,
      }}
      components={{
        IconLeft: () => <ChevronLeft size={16} />,
        IconRight: () => <ChevronRight size={16} />,
      }}
      {...props}
    />
  );
}
Calendar.displayName = "Calendar";

export { Calendar };

Update the import paths to match your project setup.

Usage

import { Calendar } from "~/components/ui/Calendar";
const [date, setDate] = React.useState<Date | undefined>(new Date());
 
return (
  <Calendar
    mode="single"
    selected={date}
    onSelect={setDate}
    className="rounded-3 border"
  />
);