API reference
State store
Create calendar state outside Root, and change it from anywhere in your app.
Root creates a store for its state automatically. Create one yourself when
code outside Root needs to change the calendar, or when the state should survive Root
unmounting. Everything here is exported from @moltenship/calendar.
createCalendarStore
import { createCalendarStore } from "@moltenship/calendar";
const store = createCalendarStore<"day" | "days">({
defaultView: "day",
defaultAnchorDate: Temporal.PlainDate.from("2026-10-08"),
defaultTimeZone: "Europe/Berlin",
});
store.actions.setView("days");
store.getSnapshot().view; // "days"Prop
Type
The type arguments are <TView, TSelection, TFocus, TResourceId>. The store has three members:
actions:setView,setAnchorDate,setTimeZone,setSelection,setFocus, andsetExpandedResourceIds.getSnapshot(): the current state as one frozen object. It's a new object after each change.subscribe(listener): callslistenerafter each change and returns an unsubscribe function.
getSnapshot and subscribe fit React's useSyncExternalStore, so any component can read the
store, inside Root or not:
import { useSyncExternalStore } from "react";
function ActiveViewName() {
const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
return <span>{state.view}</span>;
}Sharing a store with Root
Pass the store to Root with the store prop:
function JumpToHolidays() {
return (
<button onClick={() => store.actions.setAnchorDate(Temporal.PlainDate.from("2026-12-24"))}>
Holidays
</button>
);
}
<Calendar.Root
store={store}
events={meetings}
defaultAnchorDate={Temporal.PlainDate.from("2026-10-08")}
defaultTimeZone="Europe/Berlin"
locale="en-US"
weekRules={weekRules}
>
<Calendar.ActiveView />
</Calendar.Root>;Rootshows the store's values. TypeScript still asks fordefaultAnchorDateanddefaultTimeZone, butRootignores them when it has a store.store.actionsgo through the mountedRoot: controlled props stay controlled, and their change handlers run. If several mounted roots share the store, the most recently mounted one handles them.getSnapshot()returns the values the store holds. A value you control with a prop lives in your own state, not in the store.- Unmounting
Rootleaves the store as it was.
Edit on GitHub
Last updated on