Ballmac UI home

Event Calendar

A full calendar with month, week, day and agenda views: overlapping events side by side, multi-day bars, drag to move, resize or create, keyboard moves, a live now line and locale-aware weeks.

October 2026

Mon
Tue
Wed
Thu
Fri
Sat
Sun

Installation

$ pnpm dlx shadcn@latest add @ballmac/event-calendar

Usage

import { EventCalendar } from "@/components/ballmac/event-calendar"

The full example is in the Code tab above.

Examples

Week, drag to move and create

Oct 19 – 25, 2026

Mon
Tue
Wed
Thu
Fri
Sat
Sun
All day
Team calendar

Day

Tuesday, October 20, 2026

Tue
Team calendar

Editable month

October 2026

Mon
Tue
Wed
Thu
Fri
Sat
Sun

Agenda

October 2026

  1. 19Oct Monday

  2. 20Oct Tuesday

  3. 21Oct Wednesday

  4. 22Oct Thursday

  5. 23Oct Friday

  6. 26Oct Monday

  7. 27Oct Tuesday

  8. 28Oct Wednesday

  9. 29Oct Thursday

  10. 30Oct Friday

Loading

No events

October 2026

No events this month

Events you add will be listed here by day.

Could not load

API reference

<EventCalendar>

PropTypeDefault
label*

What the calendar is, read by screen readers: "Team calendar".

string—
events*CalendarEvent[]—
viewEventCalendarView—
defaultViewEventCalendarView"month"
onViewChange(view: EventCalendarView) => void—
views

Which views people can switch between.

EventCalendarView[]ALL_VIEWS
date

Any day in the period on show.

Date—
defaultDateDate—
onDateChange(date: Date) => void—
today

The day treated as today. It is read from the clock after the page loads when you leave it out, so a server render never shows the wrong day.

Date—
localestring—
weekStartsOn

0 is Sunday, 1 is Monday. Defaults to what the locale uses.

WeekStart—
editable

Let people drag events to move them and drag their bottom edge to change the length.

booleanfalse
selectable

Let people drag across empty time to make an event.

booleanfalse
onEventClick(event: CalendarEvent) => void—
onEventChange(event: CalendarEvent, change: EventChange) => void—
onRangeSelect(range: EventRange) => void—
onDateClick

Called when a day is chosen in the month view. Default: open that day.

(date: Date) => void—
slotMinutes

Minutes in one step when dragging.

15 | 30 | 6030
hourHeight

Pixels in an hour of the week and day views.

number56
scrollToHour

The first hour of the day on show, so the grid opens on working hours.

number7
height

Height of the scrolling week and day views.

number560
maxLanes

How many bars a month cell shows before "+n more".

number3
renderEvent

Replace what an event shows inside its block.

(event: CalendarEvent, info: { view: EventCalendarView; compact: boolean }) => React.ReactNode—
view*EventCalendarView—
compact*boolean—

<Chip>

PropTypeDefault
event*CalendarEvent—
variant*

`block` is a tinted block with an accent edge. `inline` is a dot, the time and the title, for a short event in a month cell.

"block" | "inline"—
classNamestring—
styleReact.CSSProperties—
continues

Where the event continues, for a bar that is cut by the edge of a week.

{ before: boolean; after: boolean }—
onKeyMove

Which keys move it, and what they do. Set by the view.

(event: CalendarEvent, key: string, shift: boolean) => boolean—
onPointerDown(e: React.PointerEvent<HTMLButtonElement>) => void—
draggingboolean—
ghostboolean—
showTimeboolean—
childrenReact.ReactNode—
before*boolean—
after*boolean—

Also accepts the standard attributes of its root element.

Accessibility

KeyAction
Arrow keys (month)Move between days; Page Up and Page Down change month; Home and End go to the week's ends
Enter / Space (month)Open the focused day
Enter on an eventCalls onEventClick
Alt + arrow keys on an eventMove it by a day or a slot; Alt+Shift+arrows change its length. The move is announced
Add event buttonStarts an event without dragging, for keyboard and switch users
Screen readersThe month is a grid with each day named and counted; every event button reads its title, date, time and place

Quality scorecard

8/8

Every applicable check passes

Measured in Chromium 153.0.8010.12 on October 19, 2026, on version 1.0.0, across 8 examples.

How we measure
  • Passed: Accessibility scan

    No serious or critical issues in light and dark, on a phone and a desktop (axe-core 4.13.0, WCAG 2.1 AA and best-practice rules). Not part of the pass mark: some controls are smaller than the 24 px WCAG 2.2 target size (event-calendar-demo, event-calendar-week and 1 more).

  • Passed: Small screens

    No sideways scrolling at 360, 390 or 1280 px wide.

  • Passed: Reduced motion

    Every endless animation stops when the visitor asks for less motion.

  • Passed: Right to left

    Mirrors correctly in Arabic, Hebrew, Persian and Urdu layouts (7% of elements off the mirror, limit 15%).

  • Passed: Clean console

    No console errors or React hydration errors while loading.

  • Passed: Keyboard

    114 tab stops, each showing a visible change when it takes focus. 6 documented keys.

  • Passed: Loading, empty and error

    Ships loading, empty, error states, each with an example.

  • Passed: Automated tests

    Covered by event-calendar.test.tsx.

  • For information: Footprint

    13.1 KB of source (gzip) in 1 file. Installs lucide-react.

Automated checks find a subset of problems and do not replace testing with a screen reader and a keyboard in your own app. What they miss.

Use with AI

Pass events [{ id, title, start, end?, allDay?, tone?, location? }] and a label. Hold view and date in state if you need them. For editing set editable and selectable and handle onEventChange(event, { start, end, allDay }) and onRangeSelect. With the shadcn MCP server set up (guide), ask your agent:

Add the Ballmac UI Event Calendar (@ballmac/event-calendar) to this project with the shadcn MCP, then use it where it fits.

Use it for

  • Team, booking, room and delivery calendars with several views
  • Schedulers where people drag events to reschedule or drag across time to add one
  • A month overview with multi-day events and an agenda list for phones

Not for

  • Picking a date in a form; use calendar or date-picker
  • A resource timeline with rows per person or room
  • Recurring-event rules or time zone conversion; compute those yourself and pass plain events

Registry JSON: https://ui.ballmac.com/r/event-calendar.json

Credits

Free to use in personal and commercial projects.

Ballmac UI Pro

Need the whole screen, not one piece?

150 premium blocks (dashboards, settings, calendars, mail, shops, onboarding), a private shadcn registry and Figma tokens. Blocks that show data come with loading, empty and error states built in.

Not ready? Try three Pro blocks free

Leave your email and the blocks appear right here, ready to copy. Yours to use in any project.