Built with modern web technologies • Fully customizable • Production-ready
View Demo • Documentation • Report Bug • See the pro version
|
Switch seamlessly between Month, Week, and Day views Built-in dark mode with customizable CSS variables Responsive design with swipe navigation and touch-optimized interactions |
Virtualized rendering handles 10,000+ events smoothly Smart collision detection displays overlapping events side-by-side Full control over event appearance with render props |
npm install calendarkit-basicyarn add calendarkit-basicpnpm add calendarkit-basicimport { BasicScheduler } from "calendarkit-basic";
import { useState } from "react";
function MyCalendar() {
const [events, setEvents] = useState([]);
const [view, setView] = useState("week");
const [date, setDate] = useState(new Date());
return (
<div style={{ height: "700px" }}>
<BasicScheduler
events={events}
view={view}
onViewChange={setView}
date={date}
onDateChange={setDate}
onEventCreate={(event) => setEvents([...events, { ...event, id: crypto.randomUUID() }])}
onEventUpdate={(updatedEvent) => {
setEvents(events.map(e => e.id === updatedEvent.id ? updatedEvent : e));
}}
onEventDelete={(eventId) => {
setEvents(events.filter(e => e.id !== eventId));
}}
/>
</div>
);
}For complete documentation, including advanced usage, customization options, and API reference, visit:
| Prop | Type | Required | Description |
|---|---|---|---|
events |
CalendarEvent[] |
Yes | Array of events to display |
view |
'month' | 'week' | 'day' |
No | Current view mode (default: 'week') |
onViewChange |
(view: ViewType) => void |
No | Callback when view changes |
date |
Date |
No | Currently focused date |
onDateChange |
(date: Date) => void |
No | Callback when date changes |
calendars |
Calendar[] |
No | Calendar definitions for filtering |
onCalendarToggle |
(id: string, active: boolean) => void |
No | Callback for calendar visibility |
onEventCreate |
(event: Partial<CalendarEvent>) => void |
No | Callback when creating event |
onEventUpdate |
(event: CalendarEvent) => void |
No | Callback when updating event |
onEventDelete |
(eventId: string) => void |
No | Callback when deleting event |
onEventClick |
(event: CalendarEvent) => void |
No | Callback when clicking an event |
weekStartsOn |
0 | 1 | 2 | 3 | 4 | 5 | 6 |
No | First day of week (0=Sunday, 1=Monday, etc.) |
readOnly |
boolean |
No | Disable event creation/editing |
isLoading |
boolean |
No | Show loading overlay |
renderEvent |
(props) => ReactNode |
No | Custom event renderer |
renderEventForm |
(props) => ReactNode |
No | Custom event form |
theme |
ThemeConfig |
No | Theme customization |
interface CalendarEvent {
id: string;
title: string;
start: Date;
end: Date;
color?: string;
calendarId?: string;
description?: string;
allDay?: boolean;
}interface Calendar {
id: string;
label: string;
color: string;
active: boolean;
}Events scheduled at the same time are automatically displayed side-by-side with smart collision detection.
// No configuration needed - works automatically!
<BasicScheduler events={overlappingEvents} />Configure which day the week starts on:
<BasicScheduler
weekStartsOn={1} // Monday
// 0 = Sunday (default)
// 1 = Monday
// 6 = Saturday
/>Full control over how events are displayed:
<BasicScheduler
renderEvent={({ event, view, onClick }) => (
<div
onClick={onClick}
className="my-custom-event"
style={{ backgroundColor: event.color }}
>
<strong>{event.title}</strong>
{view !== 'month' && (
<span>{format(event.start, 'h:mm a')}</span>
)}
</div>
)}
/>Built-in skeleton components for loading states:
import { BasicScheduler, CalendarSkeleton } from "calendarkit-basic";
function MyCalendar() {
const { events, isLoading } = useEvents();
if (isLoading) {
return <CalendarSkeleton />;
}
return <BasicScheduler events={events} />;
}Available skeleton components:
CalendarSkeleton- Full calendar skeletonMonthViewSkeleton- Month view onlyWeekViewSkeleton- Week view onlyDayViewSkeleton- Day view only
Display a friendly message when there are no events:
import { BasicScheduler, EmptyState } from "calendarkit-basic";
function MyCalendar() {
const { events } = useEvents();
if (events.length === 0) {
return (
<EmptyState
title="No events yet"
description="Create your first event to get started"
actionLabel="Create Event"
onCreateEvent={() => openCreateModal()}
/>
);
}
return <BasicScheduler events={events} />;
}BasicScheduler uses CSS variables for easy theming. Customize by overriding these variables:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
/* ... and more */
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... dark theme overrides */
}const [calendars, setCalendars] = useState([
{ id: "work", label: "Work", color: "#3b82f6", active: true },
{ id: "personal", label: "Personal", color: "#10b981", active: true },
{ id: "birthdays", label: "Birthdays", color: "#f59e0b", active: false },
]);
<BasicScheduler
events={events}
calendars={calendars}
onCalendarToggle={(id, active) => {
setCalendars(cals =>
cals.map(c => c.id === id ? { ...c, active } : c)
);
}}
/><BasicScheduler
events={events}
readOnly={true}
/><BasicScheduler
events={events}
weekStartsOn={1}
/><BasicScheduler
events={events}
isLoading={isFetching}
/>- Month View - Grid layout with event pills
- Week View - Hourly timeline with overlap detection
- Day View - Detailed single-day timeline
- Event CRUD - Create, read, update, delete operations
- Event View Modal - Read-only event details with edit/delete options
- Calendar Filters - Toggle multiple calendar visibility
- Mobile Support - Swipe navigation and bottom sheet
- Dark Mode - Built-in theme switching
- TypeScript - Full type definitions
- Virtualization - Handles thousands of events
- Custom Rendering - Bring your own event components
- Loading Skeletons - Built-in loading states
- Empty States - Friendly no-content messaging
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feat/name-of-feature) - Commit your Changes (
git commit -m 'Add some name-of-feature') - Push to the Branch (
git push origin feat/name-of-feature) - Open a Pull Request
# Clone the repository
git clone https://github.com/Zesor/calendarkit-basic.git
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build- Website: calendarkit.io
- Documentation: calendarkit.io/docs
- npm Package: npmjs.com/package/calendarkit-basic
- Issues: GitHub Issues
This project is licensed under the MIT License - see the LICENSE file for details.
If you find this project helpful, please consider giving it a star on GitHub!