Full Calendar Component for shadcn/ui with Events

Integrate a sleek, customizable calendar into your React project with the shadcn/ui full calendar component.

This is a fully functional calendar built with the popular shadcn/ui component library.

It provides various view modes (day, week, month, year), keyboard shortcuts, and a clean, customizable interface to help developers easily display and manage events within their applications.

Features

  • Day, week, month, and year view modes.
  • Previous, today, and next date controls.
  • Event colors in default, blue, green, pink, and purple variants.
  • Keyboard shortcuts for view switching and date navigation.
  • Locale-aware weekday labels through date-fns locale objects.
  • View state and event state access through useCalendar().

Use Cases

  • Project dashboards that display deadlines, milestones, and scheduled work across several calendar views.
  • Internal scheduling screens that render event data from application state or an API.
  • Personal planning screens with day-to-year navigation and keyboard controls.

Installation

The copied file imports @/components/ui/button, @/lib/utils, and class-variance-authority. Confirm those imports resolve in your shadcn/ui project.

1. Install the two external dependencies used by the calendar:

pnpm add date-fns react-hotkeys-hook

2. Copy components/ui/full-calendar.tsx from GitHub into your project. Update the local import aliases if your project uses a different folder structure.

Usage

Pass events to Calendar, then render the view triggers, date controls, and four view components inside it.

'use client';
import {
  Calendar,
  CalendarCurrentDate,
  CalendarDayView,
  CalendarMonthView,
  CalendarNextTrigger,
  CalendarPrevTrigger,
  CalendarTodayTrigger,
  CalendarViewTrigger,
  CalendarWeekView,
  CalendarYearView,
} from '@/components/ui/full-calendar';
const events = [
  {
    id: '1',
    start: new Date('2026-09-08T09:30:00'),
    end: new Date('2026-09-08T10:30:00'),
    title: 'Design review',
    color: 'pink',
  },
  {
    id: '2',
    start: new Date('2026-09-09T13:00:00'),
    end: new Date('2026-09-09T14:30:00'),
    title: 'Sprint planning',
    color: 'blue',
  },
];
export default function CalendarExample() {
  return (
    <Calendar events={events}>
      <div className="flex h-dvh flex-col py-6">
        <div className="mb-6 flex items-center gap-2 px-6">
          <CalendarViewTrigger
            view="day"
            className="aria-[current=true]:bg-accent"
          >
            Day
          </CalendarViewTrigger>
          <CalendarViewTrigger
            view="week"
            className="aria-[current=true]:bg-accent"
          >
            Week
          </CalendarViewTrigger>
          <CalendarViewTrigger
            view="month"
            className="aria-[current=true]:bg-accent"
          >
            Month
          </CalendarViewTrigger>
          <CalendarViewTrigger
            view="year"
            className="aria-[current=true]:bg-accent"
          >
            Year
          </CalendarViewTrigger>
          <span className="flex-1" />
          <CalendarCurrentDate />
          <CalendarPrevTrigger aria-label="Previous">
            <span aria-hidden="true">‹</span>
          </CalendarPrevTrigger>
          <CalendarTodayTrigger>Today</CalendarTodayTrigger>
          <CalendarNextTrigger aria-label="Next">
            <span aria-hidden="true">›</span>
          </CalendarNextTrigger>
        </div>
        <div className="relative flex-1 overflow-auto px-6">
          <CalendarDayView />
          <CalendarWeekView />
          <CalendarMonthView />
          <CalendarYearView />
        </div>
      </div>
    </Calendar>
  );
}

Calendar Props

PropDescription
childrenRequired React content rendered inside the calendar context provider.
defaultDateInitial Date. Defaults to new Date().
eventsInitial CalendarEvent[] copied into internal state. Defaults to an empty array. Later prop changes do not synchronize that state.
viewInitial view: day, week, month, or year. Defaults to month.
localeA date-fns Locale object used for date labels. Defaults to enUS.
enableHotkeysTurns the built-in keyboard shortcuts on or off. Defaults to true.
onChangeViewCallback that receives the new view when a view trigger or view hotkey changes the calendar view.
onEventClickStored in calendar context, but the built-in event renderers never call it. Custom event-click behavior requires editing full-calendar.tsx.

Calendar Event Data

FieldDescription
idRequired string identifier.
startRequired JavaScript Date for the event start.
endRequired JavaScript Date for the event end.
titleRequired event title.
colorOptional style variant: default, blue, green, pink, or purple. An omitted value uses the default variant.

Public Exports

ExportPurpose
CalendarCalendar context provider with the props listed above.
CalendarViewTriggerChanges the active view. Requires view and accepts generic React HTML attributes. A passed onClick is overwritten by the built-in handler.
CalendarCurrentDateRenders the active day or month/year label. It accepts no props and does not apply the calendar locale value to its month name.
CalendarPrevTriggerMoves backward by the active view interval. Accepts generic React HTML attributes and runs a passed onClick after the date change.
CalendarTodayTriggerMoves the active date to today. Accepts generic React HTML attributes and runs a passed onClick after the date change.
CalendarNextTriggerMoves forward by the active view interval. Accepts generic React HTML attributes and runs a passed onClick after the date change.
CalendarDayViewRenders a 24-hour day grid with events positioned from their start and end times. Accepts no props.
CalendarWeekViewRenders a seven-day hourly grid. Weeks begin on Sunday. Accepts no props.
CalendarMonthViewRenders a six-row month grid with event title, color, and start time. Accepts no props.
CalendarYearViewRenders twelve date grids without event entries. Accepts no props.
CalendarEventExported TypeScript type for event objects.
useCalendar()Returns the calendar context for custom controls or child components.

useCalendar() Context

ValueDescription
viewActive calendar view.
setViewUpdates the active view directly. Calling it does not run onChangeView.
dateActive calendar date.
setDateUpdates the active date directly.
eventsCalendar event array held by the provider.
setEventsReplaces the provider’s event array.
localeActive date-fns locale object.
onChangeViewView-change callback passed to Calendar.
onEventClickEvent-click callback value passed to Calendar. Built-in event renderers do not invoke it.
enableHotkeysHotkey setting passed to Calendar.
todayA Date created by the provider for today’s date.

Keyboard Shortcuts

D, W, M, and Y are registered by Calendar. ArrowLeft, ArrowRight, and T work only when the previous, next, and today trigger components are mounted.

KeyAction
DSwitch to day view.
WSwitch to week view.
MSwitch to month view.
YSwitch to year view.
ArrowLeftMove to the previous day, week, month, or year.
ArrowRightMove to the next day, week, month, or year.
TJump to today.

Related Resources

FAQs

Do updates to the events prop sync automatically?

No. The events prop initializes internal state on mount. Update events through useCalendar().setEvents or remount the provider when external event data changes.

Does the component include event creation, editing, or deletion?

No built-in forms or CRUD controls are included. Build those controls in your application and push event changes into the calendar through useCalendar().setEvents.

Which views display event data?

Day, week, and month views render events. Year view renders the twelve-month date grid without event entries.

Can the week start on Monday?

weekStartsOn is hard-coded to 0, which starts weeks on Sunday. Change the date-fns startOfWeek() calls in full-calendar.tsx for a Monday-first calendar.

Preview

Full Calendar for shadcn day view
Day View
Full Calendar for shadcn month view
Month View
nino

nino

Web Developer.

Leave a Reply

Your email address will not be published. Required fields are marked *