Calendar
The Calendar is a React component for browsing a month and presenting events on their due dates. It includes month and year controls, an animated transition between periods, keyboard-focusable events, and an event detail dialog. Nausikaä provides the layout and event styles; your application provides the data and persistence callbacks.
The component uses React and date-fns. It is part of the nausikaa package: install that together with React and date-fns, load the Nausikaä stylesheet, and pass an asynchronous fetchEvents function.
Basic calendar
fetchEvents(startDate, endDate) is called whenever the displayed period changes. It must resolve to an array of events in that range. The basic example intentionally returns an empty list, which is useful while wiring the calendar to a new data source.
import Calendar from "nausikaa/calendar";
const fetchEvents = async (startDate, endDate) => {
const response = await fetch(`/api/events?start=${encodeURIComponent(startDate)}&end=${encodeURIComponent(endDate)}`);
return response.json();
};
<Calendar
fetchEvents={fetchEvents}
createEvent={async (event) => { /* save event */ }}
updateEvent={async (event) => { /* update event */ }}
deleteEvent={async (event) => { /* delete event */ }}
/>;
Calendar events
An event needs a stable slug, a title, and a due date that JavaScript can parse. Mark an event as allday to display it as a compact tag. Its first category supplies any Nausikaä tag color class, including rosewater, pink, red, orange, yellow, green, teal, blue, lavender, and magenta.
This demo generates one to five events for every visible date, with a few deliberately busy dates containing eight to twelve events to demonstrate the +x more overflow dropdown. The event data is generated only in the browser, but it is deterministic: a date receives the same events when you leave a month and return to it. No data is saved or sent anywhere.
const event = {
slug: "design-review-2026-04-14",
title: "Design review",
due: "2026-04-14T09:30:00.000Z",
allday: true,
categories: [{ slug: "design", color: "blue" }],
};
const fetchEvents = async (startDate, endDate) => {
return events.filter((event) => {
const due = new Date(event.due);
return due >= new Date(startDate) && due <= new Date(endDate);
});
};
E-ink: in the e-ink theme an event has the three looks of a tag: outlined, light grey or black. Give kinds of events that should stand apart a color from a different group, for example blue (black), yellow (light grey) and no color (outlined). The days of the neighboring months are grey instead of faded.
Event behaviour
Select an event to open the built-in detail dialog. The current version displays the event object there, making it a practical integration point for a read, edit, or delete interface. Clicking an unused part of a day opens the same dialog in its "new" state. The createEvent, updateEvent, and deleteEvent callbacks are reserved for that persistence layer.
Keep fetchEvents stable between renders—for example with a module-level function or useCallback—so React does not refetch simply because the callback identity changed. Return ISO date strings from an API when possible to avoid timezone ambiguity.
Props
| Prop | Type | Description |
|---|---|---|
fetchEvents | (startDate, endDate) => Promise<Event[]> | Required. Called whenever the displayed period changes. The dates span the full weeks shown in the grid, so they can fall in the previous or next month. Resolve to the events in that range. |
createEvent | (event) => Promise | Reserved for creating events from the detail dialog. Not called by the current version. |
updateEvent | (event) => Promise | Reserved for editing events from the detail dialog. Not called by the current version. |
deleteEvent | (event) => Promise | Reserved for deleting events from the detail dialog. Not called by the current version. |
icons | string | Where the icon file is served. Defaults to /images/icons.svg. |
Event object
| Field | Type | Description |
|---|---|---|
slug | string | Required. A unique identifier. It is also used in a CSS class name, so use only letters, digits and hyphens. |
title | string | Required. Shown in the day cell and as the tooltip. |
due | string or Date | Required. The day the event is shown on. An ISO 8601 string is recommended. |
allday | boolean | Displays the event as a compact, colored tag. |
categories | { slug, color }[] | The first category’s color sets the event color and accepts any tag color class. Further categories are shown as small colored markers. |