@super-calendar/dom
The react-dom renderer for super-calendar: a virtualized month / week / day calendar and date picker built from real DOM components. No React Native, no react-native-web.
It is built on the headless @super-calendar/core and Legend List's DOM renderer.
Install
npm install @super-calendar/dom
Also on JSR: deno add jsr:@super-calendar/dom.
Peer dependencies: @legendapp/list (>=3), date-fns (>=3), react (>=19), and react-dom (>=19).
Usage
import { useState } from "react";
import { Calendar, type CalendarEvent } from "@super-calendar/dom";
type MyEvent = { id: string; color: string };
const events: CalendarEvent<MyEvent>[] = [
{
id: "1",
color: "#1F6FEB",
title: "Lecture",
start: new Date(2026, 5, 19, 10, 0),
end: new Date(2026, 5, 19, 11, 30),
},
];
export function MyCalendar() {
const [date, setDate] = useState(new Date());
return (
<Calendar
mode="week"
date={date}
events={events}
weekStartsOn={1}
onPressDay={setDate}
onPressEvent={(event) => console.log(event.id)}
/>
);
}
For a custom picker, pair the headless hooks (useDateRange, useMonthGrid) with MonthList and TimeGrid, all re-exported from this package.
Touch event gestures
Touch and pen on TimeGrid wait for a 300 ms hold within 8 px before dragging.
A tap presses the event from its click; a vertical swipe scrolls the grid.
Additional contacts cancel pending holds and cannot take over an active drag.
Set touchDragDelay and touchDragThreshold on TimeGrid or Calendar to adjust
the hold. Mouse drag and resize retain their existing behavior. See the
dragging guide.
Moving events
Pass onDragEvent and update your event state with the returned start and end.
Time-grid edge paging requires a mouse drag. Touch and pen remain within the visible period, so resting near an edge cannot repeatedly change the date. See the dragging guide.
On the time grid, dragging any segment of a multi-day event previews the whole range moving together and preserves its duration. Drag a resize grip to change only the start or end. See the dragging guide.
Month chip dimensions
chipHeight and chipGap configure month lanes and overflow rows on Calendar,
MonthView, and MonthList. Native MonthPager forwards them too. DOM defaults
remain 18 px height and 2 px gaps; native height keeps its theme default.
Changing either dimension updates already mounted list and pager months.
See the month guide.
Styling
Out of the box the calendar is fully styled from the theme, no stylesheet required. To restyle a specific part with Tailwind or your own CSS, every element is a named slot: pass classNames (or styles) per slot, and use data-* state variants like data-[today]:.
<Calendar
mode="month"
date={date}
classNames={{
title: "text-center text-xl font-bold",
dayBadge: "rounded-full data-[today]:bg-indigo-600 data-[today]:text-white",
}}
/>
A slot's structural layout is always kept; only its themed look steps aside for your class, so the class wins over the inline default. See the styling guide.
On the time grid, an empty-slot touch tap calls onPressCell from the column's
click. Swipes and cancelled contacts do not press the slot. Mouse and pen retain
drag-to-create behavior. See the DOM guide.
Documentation
See the full documentation, the quickstart, and the API reference.
License
MIT