Skip to content

Event Calendar

DisplayMIT
View in Storybook

A monthly calendar with week and day views. Click to create when onEventCreate is set. Drag to resize in week or day when onEventResize is set.

bun add @otfdashkit/ui

Preview

Event Calendar
Loading Storybook preview…

Code

import { useMemo, useState } from 'react'
import { EventCalendar, type CalendarEvent, type EventCalendarView } from '@otfdashkit/ui'

const CHART_COLORS = [
  'hsl(var(--chart-1))',
  'hsl(var(--chart-2))',
  'hsl(var(--chart-3))',
  'hsl(var(--chart-4))',
  'hsl(var(--chart-5))',
] as const

function at(day: Date, hour: number, minute = 0): Date {
  const d = new Date(day)
  d.setHours(hour, minute, 0, 0)
  return d
}

function addDays(d: Date, days: number): Date {
  const next = new Date(d)
  next.setDate(next.getDate() + days)
  return next
}

function startOfMonth(d: Date): Date {
  const next = new Date(d)
  next.setDate(1)
  next.setHours(0, 0, 0, 0)
  return next
}

function buildMonthEvents(refDate: Date): CalendarEvent[] {
  const m = startOfMonth(refDate)
  const titles = [
    'Design review',
    'Standup',
    'Customer interview',
    '1:1 with Priya',
    'Marketing sync',
    'Roadmap planning',
    'Lunch w/ Theo',
    'Gym',
    'Sprint demo',
    'Investor update',
    'Onboarding call',
    'Hack night',
  ]
  const offsets = [2, 4, 5, 8, 10, 12, 14, 17, 19, 22, 24, 27]
  return titles.map((title, i) => {
    const day = addDays(m, offsets[i])
    return {
      id: `m-${i}`,
      title,
      start: at(day, 9 + (i % 6)),
      end: at(day, 10 + (i % 6)),
      color: CHART_COLORS[i % CHART_COLORS.length],
    }
  })
}

export function Example() {
  const today = useMemo(() => new Date(), [])
  const [view, setView] = useState<EventCalendarView>('month')
  const events = useMemo(() => buildMonthEvents(today), [today])
  return (
    <EventCalendar
      events={events}
      view={view}
      onViewChange={setView}
      defaultDate={today}
    />
  )
}

Free with the SDK. This component ships in @otfdashkit/ui under the MIT license.

Props

Props declared in the EventCalendar source. Inherited HTML attributes are not listed.

PropTypeDefaultDescription
eventsrequiredCalendarEvent[]
dateDate
defaultDateDate
onDateChange(date: Date) => void
onEventClick(event: CalendarEvent) => void
onEventCreate(range: { start: Date; end: Date; }) => voidOmit to disable click-to-create.
onEventResize(eventId: string, newEnd: Date) => voidOmit to disable drag-to-resize.
onViewChange(view: EventCalendarView) => void
view'month' | 'week' | 'day'
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 600 = Sunday, 1 = Monday, etc. Default 0.

Questions

How to create calendar?
Import EventCalendar from @otfdashkit/ui and pass events. The default view is month. With onEventCreate, a click on an empty month cell sends that whole day, and a click on an empty hour in week or day sends a one-hour range. Without that prop, a month-cell click switches to the day view.
How do I show a weekly calendar?
Set view to week, or use the Week tab. weekStartsOn defaults to 0 (Sunday) and accepts 0 through 6. onEventResize is passed through in week and day, not in the month view.
Is this an editable calendar?
Create and resize run only when you pass onEventCreate and onEventResize. The event list stays in your state. The component has no title editor and no recurring-event field.
Is this a calendar maker?
It is the Event Calendar component you render in an app. It does not print a calendar and it does not write a calendar file.