Features
Dark Mode
Built-in dark mode toggle controlled via isDarkMode and onThemeToggle props.
Dark Mode
CalendarKit Pro has first-class dark mode support driven by the isDarkMode prop. When true, a dark class is applied to the calendar root and Tailwind's darkMode: 'class' strategy activates the dark palette.
Basic usage
const [isDark, setIsDark] = useState(false);
<ProScheduler
isDarkMode={isDark}
onThemeToggle={() => setIsDark(!isDark)}
...
/>The built-in header shows a sun/moon toggle button that calls onThemeToggle.
Wrap your page in dark class
To apply dark mode to the entire page (not just the calendar), wrap the component in a div with the dark class:
<div className={isDark ? 'dark' : ''}>
<div className="min-h-screen bg-background text-foreground">
<div className="h-[700px] border rounded-xl overflow-hidden">
<ProScheduler
isDarkMode={isDark}
onThemeToggle={() => setIsDark(!isDark)}
events={events}
...
/>
</div>
</div>
</div>Persist preference
Store the preference in localStorage so it survives page refreshes:
'use client';
import { useState, useEffect } from 'react';
function useDarkMode() {
const [isDark, setIsDark] = useState(() => {
if (typeof window === 'undefined') return false;
return localStorage.getItem('theme') === 'dark';
});
useEffect(() => {
localStorage.setItem('theme', isDark ? 'dark' : 'light');
}, [isDark]);
return [isDark, () => setIsDark((d) => !d)] as const;
}
export default function App() {
const [isDark, toggleDark] = useDarkMode();
return (
<div className={isDark ? 'dark' : ''}>
<div className="h-[700px] border rounded-xl overflow-hidden">
<ProScheduler
isDarkMode={isDark}
onThemeToggle={toggleDark}
events={[]}
/>
</div>
</div>
);
}Respect system preference
'use client';
import { useState, useEffect } from 'react';
function useSystemDarkMode() {
const [isDark, setIsDark] = useState(false);
useEffect(() => {
const mq = window.matchMedia('(prefers-color-scheme: dark)');
setIsDark(mq.matches);
const handler = (e: MediaQueryListEvent) => setIsDark(e.matches);
mq.addEventListener('change', handler);
return () => mq.removeEventListener('change', handler);
}, []);
return isDark;
}
export default function App() {
const systemDark = useSystemDarkMode();
const [isDark, setIsDark] = useState(false);
// Initialize from system preference once
useEffect(() => { setIsDark(systemDark); }, [systemDark]);
return (
<div className={isDark ? 'dark' : ''}>
<div className="h-[700px] border rounded-xl overflow-hidden">
<ProScheduler
isDarkMode={isDark}
onThemeToggle={() => setIsDark(!isDark)}
events={[]}
/>
</div>
</div>
);
}Full example
'use client';
import { useState } from 'react';
import { ProScheduler } from 'calendarkit-prov2';
import type { CalendarEvent } from 'calendarkit-prov2';
const events: CalendarEvent[] = [
{
id: '1',
title: 'Team Meeting',
start: new Date(new Date().setHours(10, 0, 0, 0)),
end: new Date(new Date().setHours(11, 30, 0, 0)),
color: '#3b82f6',
},
];
export default function DarkModeExample() {
const [isDark, setIsDark] = useState(false);
return (
<div className={`min-h-screen p-8 transition-colors ${isDark ? 'dark bg-zinc-950' : 'bg-zinc-50'}`}>
<h1 className={`text-2xl font-bold mb-6 ${isDark ? 'text-white' : 'text-zinc-900'}`}>
Dark Mode Demo
</h1>
<div className="h-[700px] border rounded-xl overflow-hidden">
<ProScheduler
view="week"
events={events}
date={new Date()}
isDarkMode={isDark}
onThemeToggle={() => setIsDark(!isDark)}
onEventCreate={(e) => console.log('create', e)}
/>
</div>
</div>
);
}CSS variable reference
The theme CSS (calendarkit-prov2/calendarkit.css) defines these variables in :root (light) and .dark (dark):
:root {
--background: 0 0% 100%;
--foreground: 224 71.4% 4.1%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--muted: 220 14.3% 95.9%;
--muted-foreground: 220 8.9% 46.1%;
--accent: 220 14.3% 95.9%;
--border: 220 13% 91%;
/* ... */
}
.dark {
--background: 224 71.4% 4.1%;
--foreground: 210 20% 98%;
/* ... */
}You can override any of these variables to customize colors without touching the theme prop.