Moltenship Time
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, and setExpandedResourceIds.
  • getSnapshot(): the current state as one frozen object. It's a new object after each change.
  • subscribe(listener): calls listener after 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>;
  • Root shows the store's values. TypeScript still asks for defaultAnchorDate and defaultTimeZone, but Root ignores them when it has a store.
  • store.actions go through the mounted Root: 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 Root leaves the store as it was.
Edit on GitHub

Last updated on

On this page