SunMonTueWedThuFriSat
Composition

SimpleCalendar

Use this when
You need a working date picker in one line, today.
What it demonstrates
The flagship prebuilt: navigation header + day grid, plain-Date props. Same shared props everywhere — locale, min/max, disabled, theme, appearance, scheme, gradient.
prebuiltone importsingle
Code
import { useState } from "react";
import { SimpleCalendar } from "@dateforge/react-calendar/prebuilt";

export function SimpleCalendarExample() {
  import { SimpleCalendar } from "@dateforge/react-calendar/prebuilt";

  const [date, setDate] = useState<Date | null>(null);

  return (
    <SimpleCalendar value={date} onChange={setDate} />

    // Dress it up without composing anything:
    <SimpleCalendar
      defaultValue={new Date()}
      min={new Date()}
      theme="noir"
      appearance="zenith"
      gradient
    />
  );
}
SunMonTueWedThuFriSat
Composition

DatePicker

Use this when
Forms where users type the date as often as they click it.
What it demonstrates
Prebuilt with a typed, segment-based input above the grid plus a Today jump — keyboard-first entry, grid as fallback.
prebuiltmanual inputone import
Code
import { useState } from "react";
import { DatePicker } from "@dateforge/react-calendar/prebuilt";

export function DatePickerExample() {
  import { DatePicker } from "@dateforge/react-calendar/prebuilt";

  const [date, setDate] = useState<Date | null>(null);

  return (
    <DatePicker value={date} onChange={setDate} />

    // Rules work the same as everywhere else:
    <DatePicker onChange={setDate} disabled={{ weekends: true }} />

    // Clear button in the input is on by default — opt out:
    <DatePicker onChange={setDate} allowClear={false} />
  );
}
Composition

MonthPicker

Use this when
Billing periods, campaign months, or season selectors.
What it demonstrates
Prebuilt month selector: year-stepping header + 12-month grid (unit: "month" under the hood). Picking a month selects the whole month, reported as its first day.
prebuiltmonths gridone import
Code
import { useState } from "react";
import { MonthPicker } from "@dateforge/react-calendar/prebuilt";

export function MonthPickerExample() {
  import { MonthPicker } from "@dateforge/react-calendar/prebuilt";

  const [month, setMonth] = useState<Date | null>(null);

  // onChange reports the first day of the picked month (or null).

  return (
    <MonthPicker value={month} onChange={setMonth} />
  );
}
SunMonTueWedThuFriSat
SunMonTueWedThuFriSat
SunMonTueWedThuFriSat
Composition

Quarter board

Use this when
Roadmaps, quarters, or long bookings that need several months at once.
What it demonstrates
MultiMonthCalendar — a 3-month range board generated from one prop set; one shared selection drags across months.
appearance: compact
prebuilt3 monthsrange
Code
import { MultiMonthCalendar } from "@dateforge/react-calendar/prebuilt";

export function QuarterBoardExample() {
  import { MultiMonthCalendar } from "@dateforge/react-calendar/prebuilt";

  return (
    <MultiMonthCalendar
      months={3}
      cols={3}
      mode="range"
      startMonth={new Date(2026, 6, 1)}
    />
  );
}
SunMonTueWedThuFriSat
Composition

The basics

Use this when
You're starting a new flow and just need a working date picker.
What it demonstrates
Bare minimum composition — Calendar shell + nav + days + selected dates.
singlestarter
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function TheBasicsExample() {
  const [basicDate, setBasicDate] = useState<Date | null>(new Date());

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={basicDate} onChange={(value) => setBasicDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarSelectedDates allowClear={false} />
    </Calendar>
  );
}
WeekSunMonTueWedThuFriSat
26
27
28
29
30
31
Composition

Week picker

Use this when
Timesheets, weekly reports, or anything that snaps to whole weeks.
What it demonstrates
unit: "week" — one click selects the whole week and emits a { start, end } span.
theme: fjordappearance: soft
unit: weekspans
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarInfo } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function WeekPickerExample() {
  const config = createCalendarConfig({ unit: "week" });
  const [week, setWeek] = useState<{ start: Date; end: Date } | null>(null);

  return (
    <Calendar config={config} value={week} onChange={(value) => setWeek(value as { start: Date; end: Date } | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays weekNumbers />
      <CalendarInfo showSummary rangeStyle="duration" />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Shift blocks

Use this when
Rotas, maintenance windows, or anything collecting several separate ranges.
What it demonstrates
mode: "multi-range" with maxRanges — several { start, end } spans, chips with per-span removal.
theme: industrialappearance: compact
multi-rangemaxRanges
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
  CalendarToolbarClear,
} from "@dateforge/react-calendar/modules/toolbar";

export function ShiftBlocksExample() {
  const config = createCalendarConfig({ mode: "multi-range", maxRanges: 3 });
  const [shifts, setShifts] = useState<{ start: Date; end: Date }[]>([]);

  return (
    <Calendar config={config} value={shifts} onChange={(value) => setShifts(value as { start: Date; end: Date }[])}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarSelectedDates allowClear allowClearPerChip allowNavigate />
    </Calendar>
  );
}
SunMonTueWedThuFriSat

Drag a range across a weekend

Composition

Business days

Use this when
SLAs, delivery estimates, or any flow counting working days only.
What it demonstrates
exclude: { weekends: true } — weekends stay spannable but are cut from the emitted value; details.segments reports the working-day blocks.
theme: meadowappearance: soft
excludesegmentsrange
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarInfo } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
  CalendarToolbarClear,
} from "@dateforge/react-calendar/modules/toolbar";

export function BusinessDaysExample() {
  const config = createCalendarConfig({
    mode: "range",
    exclude: { weekends: true },           // cut from emitted spans
    excludedEndpointPolicy: "snap-inward", // or "reject"
  });

  const [range, setRange] = useState<{ start: Date; end: Date } | null>(null);
  const [segments, setSegments] = useState<number | null>(null);

  return (
    <Calendar
      config={config}
      value={range}
      onChange={(value, details) => {
        setRange(value as { start: Date; end: Date } | null);
        setSegments(details.segments?.length ?? null);
      }}
    >
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays highlightWeekends />
      <CalendarInfo showSummary rangeStyle="days" />
    </Calendar>

    {segments !== null && <p>{segments} working-day block(s) in the selection</p>}
  );
}
KWMDMDFSS
27
28
29
30
31
32
Composition

German locale + labels

Use this when
Localized products where every visible and screen-reader string must match the language.
What it demonstrates
locale drives names/digits/week start via Intl; the labels registry localizes every aria-label in one place.
theme: chalkappearance: square
localelabelsweek numbers
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
  CalendarToolbarClear,
} from "@dateforge/react-calendar/modules/toolbar";

export function GermanLocaleLabelsExample() {
  const config = createCalendarConfig({ locale: "de-DE" });

  return (
    <Calendar
      config={config}
      value={date}
      onChange={(value) => setDate(value as Date | null)}
      labels={{
        clear: "Löschen",
        previousMonth: "Vorheriger Monat",
        nextMonth: "Nächster Monat",
        selectMonth: "Monat wählen",
        selectYear: "Jahr wählen",
      }}
    >
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays weekNumbers weekLabel="KW" weekdayFormat="narrow" />
    </Calendar>
  );
}
SunMonTueWedThuFriSat

App-side scheme: light

Composition

Controlled scheme

Use this when
The calendar must follow your app's own light/dark state.
What it demonstrates
Controlled scheme + onSchemeChange — the built-in toggle reports the next scheme instead of flipping itself.
theme: velvetappearance: loft
schemedark modetoggle
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
  CalendarToolbarThemeToggle,
} from "@dateforge/react-calendar/modules/toolbar";

export function ControlledSchemeExample() {
  const config = createCalendarConfig();
  const [scheme, setScheme] = useState<"light" | "dark">("light");

  return (
    <Calendar
      config={config}
      value={date}
      onChange={(value) => setDate(value as Date | null)}
      scheme={scheme}
      onSchemeChange={setScheme}
    >
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarThemeToggle />
      </CalendarToolbar>
      <CalendarDays />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Pinned toolbar actions

Use this when
A crowded toolbar that must stay tidy at any width.
What it demonstrates
The default toolbar is a wrapping flex row — overflow wraps to the next line instead of escaping the container. CalendarToolbarGroup push="end" pins the actions to the inline end regardless of what shares the row.
theme: graphite
toolbarpushsmart layout
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarClear,
  CalendarToolbarGroup,
  CalendarToolbarHome,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarPrev,
  CalendarToolbarThemeToggle,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function PinnedToolbarActionsExample() {
  const config = createCalendarConfig();
  const [date, setDate] = useState<Date | null>(null);

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarYearTrigger />
        <CalendarToolbarNext />
        {/* Rides the right edge; wraps as one unit when space runs out */}
        <CalendarToolbarGroup push="end">
          <CalendarToolbarHome />
          <CalendarToolbarClear />
          <CalendarToolbarThemeToggle />
        </CalendarToolbarGroup>
      </CalendarToolbar>
      <CalendarDays />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Stay booking

Use this when
Lodging or short-stay rentals where guests pick check-in and check-out.
What it demonstrates
Range mode with disabled past dates, quick-stay presets, a nights counter via CalendarInfo, and an animated summary.
appearance: soft
rangebookingpresets
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createDisabled, type PresetInput } from "@dateforge/react-calendar";
import { CalendarDays, CalendarPresets, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";
import { soft } from "@dateforge/react-calendar/appearances";

export function StayBookingExample() {
  const [stayRange, setStayRange] = useState<{ start: Date; end: Date } | null>(null);

  const noPast = useMemo(() => {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return createDisabled({ before: today });
  }, []);

  // Range mode wants range-kind presets: value + range, or getValue
  // returning { from, to }. Plain date presets show up disabled here.
  const stayPresets = useMemo<PresetInput[]>(
    () => [
      { label: "Tonight", value: 0, range: 1 },
      {
        id: "next-weekend",
        label: "Weekend",
        getValue: ({ now }) => {
          const sat = new Date(now);
          const daysToSat = (6 - sat.getDay() + 7) % 7 || 7;
          sat.setDate(sat.getDate() + daysToSat);
          const sun = new Date(sat);
          sun.setDate(sat.getDate() + 1);
          return { from: sat, to: sun };
        },
      },
      { label: "Week stay", value: 0, range: 6 },
      { label: "Two weeks", value: 0, range: 13 },
    ],
    [],
  );

  const config = createCalendarConfig({ mode: "range", disabled: noPast });

  return (
    <Calendar config={config} value={stayRange} onChange={(value) => setStayRange(value as { start: Date; end: Date } | null)} appearance={soft}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarHome />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarPresets presets={stayPresets} />
      <CalendarInfo showSummary rangeStyle="duration" />
      <CalendarSelectedDates allowClear allowNavigate />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
SunMonTueWedThuFriSat
SunMonTueWedThuFriSat
SunMonTueWedThuFriSat
SunMonTueWedThuFriSat
SunMonTueWedThuFriSat
Composition

Six-month availability

Use this when
Showing read-only open slots across half a year.
What it demonstrates
Read-only multiple-mode with a 3-column 6-month grid and defaultViewDate.
theme: industrialappearance: compact
read-only6 monthsavailability
Code
import { useMemo } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";
import { compact } from "@dateforge/react-calendar/appearances";

export function SixmonthAvailabilityExample() {
  const sixMonthDates = useMemo(
    () => [
      new Date(2026, 4, 8),
      new Date(2026, 4, 17),
      new Date(2026, 5, 4),
      new Date(2026, 5, 22),
      new Date(2026, 6, 9),
      new Date(2026, 6, 28),
      new Date(2026, 7, 13),
      new Date(2026, 7, 26),
      new Date(2026, 8, 10),
      new Date(2026, 8, 24),
      new Date(2026, 9, 6),
      new Date(2026, 9, 21),
    ],
    [],
  );

  const config = createCalendarConfig({ mode: "multiple", readOnly: true });

  return (
    <Calendar config={config} value={sixMonthDates} initialView={calendarDate(2026, 5, 1)} cols={3} appearance={compact}>
      <CalendarToolbar col={1}>
        <CalendarToolbarMonthLabel />
        <CalendarToolbarYearLabel />
      </CalendarToolbar>
      <CalendarToolbar col={1} offset={1}>
        <CalendarToolbarMonthLabel />
        <CalendarToolbarYearLabel />
      </CalendarToolbar>
      <CalendarToolbar col={1} offset={2}>
        <CalendarToolbarMonthLabel />
        <CalendarToolbarYearLabel />
      </CalendarToolbar>
      <CalendarDays col={1} />
      <CalendarDays offset={1} col={1} />
      <CalendarDays offset={2} col={1} />
      <CalendarToolbar col={1} offset={3}>
        <CalendarToolbarMonthLabel />
        <CalendarToolbarYearLabel />
      </CalendarToolbar>
      <CalendarToolbar col={1} offset={4}>
        <CalendarToolbarMonthLabel />
        <CalendarToolbarYearLabel />
      </CalendarToolbar>
      <CalendarToolbar col={1} offset={5}>
        <CalendarToolbarMonthLabel />
        <CalendarToolbarYearLabel />
      </CalendarToolbar>
      <CalendarDays offset={3} col={1} />
      <CalendarDays offset={4} col={1} />
      <CalendarDays offset={5} col={1} /> 
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Delivery slots

Use this when
Letting users pick several non-contiguous delivery dates with capacity.
What it demonstrates
Multiple mode with maxDates, weekend + past disable rule, animated selected list.
theme: mintappearance: soft
multiplecapacity
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createDisabled } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function DeliverySlotsExample() {
  const [deliveryDates, setDeliveryDates] = useState<Date[]>([]);

  const weekdaysOnly = useMemo(() => {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return createDisabled({ weekends: true, before: today });
  }, []);

  const config = createCalendarConfig({
    mode: "multiple",
    maxDates: 4,
    disabled: weekdaysOnly,
  });

  return (
    <Calendar config={config} value={deliveryDates} onChange={(value) => setDeliveryDates(value as Date[])}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger compact />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarSelectedDates allowClear />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Limited drop window

Use this when
Launch signup with only a handful of valid days.
What it demonstrates
hideOutOfRange + min/maxDate + createDisabled for a tightly bounded picker.
theme: risoappearance: compact
singlehideOutOfRangedisabledclock
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createDisabled } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function LimitedDropWindowExample() {
  const [dropDate, setDropDate] = useState<Date | null>(null);

  const dropDisabled = useMemo(
    () =>
      createDisabled({
        dates: [new Date("2026-07-12"), new Date("2026-07-15")],
        weekdays: [0, 6],
      }),
    [],
  );

  const config = createCalendarConfig({
    min: new Date("2026-07-10"),
    max: new Date("2026-07-18"),
    disabled: dropDisabled,
  });

  return (
    <Calendar
      config={config}
      value={dropDate}
      onChange={(value) => setDropDate(value as Date | null)}
      initialView={calendarDate(2026, 7, 10)}
    >
      <CalendarToolbar>
        <CalendarToolbarMonthLabel />
        <CalendarToolbarYearLabel />
        <CalendarToolbarClock />
      </CalendarToolbar>
      <CalendarDays hideOutOfRange fixedWeeks={false} />
      <CalendarSelectedDates allowClear />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
09
00
Composition

Appointment booking

Use this when
Doctor, salon, or restaurant reservations needing date and time in one step.
What it demonstrates
Single mode + CalendarTimeWheel + nav with showTime.
theme: auroraappearance: loft
singletimescheduling
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createDisabled } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import { CalendarTimeWheel } from "@dateforge/react-calendar/modules/time";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function AppointmentBookingExample() {
  const [appointment, setAppointment] = useState<Date | null>(null);

  const weekdaysOnly = useMemo(() => {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return createDisabled({ weekends: true, before: today });
  }, []);

  const config = createCalendarConfig({ withTime: true, disabled: weekdaysOnly });

  return (
    <Calendar gradient config={config} value={appointment} onChange={(value) => setAppointment(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarTimeWheel />
      <CalendarSelectedDates allowClear showTime />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Analytics dashboard

Use this when
Filtering reports by familiar ranges (Today / Last 7 / Quarter).
What it demonstrates
Range mode + CalendarPresets with relative offsets + animated summary.
theme: graphite
rangepresetsreports
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarPresets, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function AnalyticsDashboardExample() {
  const [reportRange, setReportRange] = useState<{ start: Date; end: Date } | null>(null);

  // range: 0 → a single-day range, so "Today" stays clickable in range mode
  const analyticsPresets = [
    { label: "Today", value: 0, range: 0 },
    { label: "Last 7 days", value: -6, range: 6 },
    { label: "Last 30 days", value: -29, range: 29 },
  ];

  const config = createCalendarConfig({ mode: "range" });

  return (
    <Calendar config={config} value={reportRange} onChange={(value) => setReportRange(value as { start: Date; end: Date } | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarPresets presets={analyticsPresets} />
      <CalendarSelectedDates allowClear allowNavigate />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Support quick dates

Use this when
Reminders or follow-ups where "Tomorrow" or "Next Monday" covers most cases.
What it demonstrates
Single mode with custom presets, including dynamic ones via getValue.
theme: mintappearance: soft
singlepresetssupport
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, type PresetInput } from "@dateforge/react-calendar";
import { CalendarDays, CalendarPresets, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function SupportQuickDatesExample() {
  const [singlePresetDate, setSinglePresetDate] = useState<Date | null>(null);

  const supportPresets = useMemo<PresetInput[]>(
    () => [
      { label: "Today", value: 0 },
      { label: "Tomorrow", value: 1 },
      { label: "In 3 days", value: 3 },
      {
        id: "next-monday",
        label: "Next Monday",
        getValue: ({ now }) => {
          const date = new Date(now);
          const delta = (8 - date.getDay()) % 7 || 7;
          date.setDate(date.getDate() + delta);
          return date;
        },
      },
    ],
    [],
  );

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={singlePresetDate} onChange={(value) => setSinglePresetDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarPresets presets={supportPresets} />
      <CalendarSelectedDates allowClear allowNavigate />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
2016–2027
Composition

Holiday planner

Use this when
Marketing or seasonal planning around fixed and computed holidays.
What it demonstrates
Multiple mode with advanced custom presets (Christmas, Thanksgiving, Black Friday).
theme: snowappearance: compact
multiplepresetsholidays
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, type PresetInput } from "@dateforge/react-calendar";
import { CalendarDays, CalendarMonthsGrid, CalendarPresets, CalendarSelectedDates, CalendarYearsGrid } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function HolidayPlannerExample() {
  const [holidayRange, setHolidayRange] = useState<Date[]>([]);

  function nthWeekdayOfMonth(year: number, month: number, weekday: number, occurrence: number) {
    const date = new Date(year, month, 1);
    const delta = (weekday - date.getDay() + 7) % 7;
    date.setDate(1 + delta + (occurrence - 1) * 7);
    return date;
  }

  const holidayPresets = useMemo<PresetInput[]>(
    () => [
      {
        id: "new-year",
        label: "New Year",
        getValue: ({ now }) => {
          const year =
            now.getMonth() > 0 || now.getDate() > 1
              ? now.getFullYear() + 1
              : now.getFullYear();
          const date = new Date(year, 0, 1);
          return date;
        },
      },
      {
        id: "independence-day",
        label: "Independence Day",
        getValue: ({ now }) => {
          const year =
            now.getMonth() > 6 || (now.getMonth() === 6 && now.getDate() > 4)
              ? now.getFullYear() + 1
              : now.getFullYear();
          const date = new Date(year, 6, 4);
          return date;
        },
      },
      {
        id: "christmas-day",
        label: "Christmas Day",
        getValue: ({ now }) => {
          const year =
            now.getMonth() > 11 || (now.getMonth() === 11 && now.getDate() > 25)
              ? now.getFullYear() + 1
              : now.getFullYear();
          const date = new Date(year, 11, 25);
          return date;
        },
      },
      {
        id: "thanksgiving-day",
        label: "Thanksgiving",
        getValue: ({ now }) => {
          const year = now.getMonth() > 10 ? now.getFullYear() + 1 : now.getFullYear();
          const date = nthWeekdayOfMonth(year, 10, 4, 4);
          return date;
        },
      },
      {
        id: "christmas-eve",
        label: "Christmas Eve",
        getValue: ({ now }) => {
          const year =
            now.getMonth() > 11 || (now.getMonth() === 11 && now.getDate() > 24)
              ? now.getFullYear() + 1
              : now.getFullYear();
          const date = new Date(year, 11, 24);
          return date;
        },
      },
      {
        id: "black-friday",
        label: "Black Friday",
        getValue: ({ now }) => {
          const year = now.getMonth() > 10 ? now.getFullYear() + 1 : now.getFullYear();
          const date = nthWeekdayOfMonth(year, 10, 4, 4);
          date.setDate(date.getDate() + 1);
          return date;
        },
      },
    ],
    [],
  );

  const config = createCalendarConfig({ mode: "multiple" });

  return (
    <Calendar config={config} value={holidayRange} onChange={(value) => setHolidayRange(value as Date[])} cols={2}>
      <CalendarPresets presets={holidayPresets} />
      <CalendarDays />
      <CalendarMonthsGrid col={1} />
      <CalendarYearsGrid col={1} />
      <CalendarSelectedDates col={2} allowClear allowNavigate />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Brand theme picker

Use this when
Branded checkout or onboarding where the picker has to match a custom palette in both light and dark.
What it demonstrates
createTheme with shared tokens plus light/dark variants, and a built-in theme toggle to flip between them.
theme: customappearance: soft
singlecreateThemebrand
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createTheme } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function BrandThemePickerExample() {
  const [brandDate, setBrandDate] = useState<Date | null>(null);

  // Shared tokens apply to both variants; light/dark override per mode.
  const brandTheme = useMemo(
    () =>
      createTheme({
        accent: "#7c3aed",
        focusRing: "#ede9fe",
        range: "#ddd6fe",
        weekend: "#db2777",
        light: { backdrop: "#faf5ff", tone: "#f3e8ff", text: "#3b0764", stroke: "#e9d5ff" },
        dark: { backdrop: "#1a0b2e", tone: "#2e1065", text: "#f5f3ff", stroke: "#4c1d95" },
      }),
    [],
  );

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={brandDate} onChange={(value) => setBrandDate(value as Date | null)} theme={brandTheme}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarThemeToggle />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarSelectedDates allowClear />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Dense product filter

Use this when
Compact dashboards where calendar rhythm needs to match dense data UI.
What it demonstrates
createAppearance with custom radius, spacing, font size, and dayRatio.
theme: graphiteappearance: custom
rangecreateAppearancedashboard
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createAppearance } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function DenseProductFilterExample() {
  const [denseRange, setDenseRange] = useState<{ start: Date; end: Date } | null>(null);

  const denseAppearance = useMemo(
    () =>
      createAppearance({
        radius: "5px",
        spacing: "0.42em",
        fontSize: "13px",
        dayHeight: "2.2em",
        transition: "120ms ease",
      }),
    [],
  );

  const config = createCalendarConfig({ mode: "range" });

  return (
    <Calendar config={config} value={denseRange} onChange={(value) => setDenseRange(value as { start: Date; end: Date } | null)} appearance={denseAppearance}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarSelectedDates allowClear />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Vacation request

Use this when
HR-style time off with min and max length rules.
What it demonstrates
Range mode with minRangeDays / maxRangeDays, weekday-only rule, and CalendarInfo showing the duration as the user drags.
theme: risoappearance: square
rangeconstraintsHR
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createDisabled } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function VacationRequestExample() {
  const [vacationRange, setVacationRange] = useState<{ start: Date; end: Date } | null>(null);

  const weekdaysOnly = useMemo(() => {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return createDisabled({ weekends: true, before: today });
  }, []);

  const config = createCalendarConfig({
    mode: "range",
    disabled: weekdaysOnly,
    minSpan: 2,
    maxSpan: 21,
  });

  return (
    <Calendar
      config={config}
      value={vacationRange}
      onChange={(value) => setVacationRange(value as { start: Date; end: Date } | null)}
    >
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarInfo showSummary rangeStyle="duration" />
      <CalendarSelectedDates allowClear />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Sprint planning

Use this when
Engineering planning around current sprint, next sprint, release week.
What it demonstrates
Range mode with custom-length presets (offset + range).
theme: industrial
rangepresetsplanning
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarPresets, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function SprintPlanningExample() {
  const [sprintRange, setSprintRange] = useState<{ start: Date; end: Date } | null>(null);

  const sprintPresets = [
    { label: "Current sprint", value: 0, range: 13 },
    { label: "Next sprint", value: 14, range: 13 },
    { label: "Release week", value: 28, range: 6 },
  ];

  const config = createCalendarConfig({ mode: "range" });

  return (
    <Calendar config={config} value={sprintRange} onChange={(value) => setSprintRange(value as { start: Date; end: Date } | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarPresets presets={sprintPresets} />
      <CalendarDays />
      <CalendarSelectedDates allowClear allowNavigate />
    </Calendar>
  );
}
MoDiMiDoFrSaSo
Composition

Invoice due date

Use this when
Billing form where users want to type or pick the date with a strict allowed window.
What it demonstrates
CalendarManualInput paired with the picker, locale, and min/max dates.
theme: snowappearance: soft
singlemanual inputbilling
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarManualInput } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function InvoiceDueDateExample() {
  const [manualDate, setManualDate] = useState<Date | null>(null);

  const config = createCalendarConfig({
    locale: "de-DE",
    min: new Date("2026-05-01"),
    max: new Date("2026-08-31"),
  });

  return (
    <Calendar
      config={config}
      value={manualDate}
      onChange={(value) => setManualDate(value as Date | null)}
    >
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarManualInput allowClear />
    </Calendar>
  );
}
2016–2027

Pick a year to browse the archive

Composition

Archive year browser

Use this when
Annual reports, archives, or timeline filters that only need year navigation.
What it demonstrates
Solo CalendarYearsGrid with onYearSelect driving external state.
theme: graphiteappearance: compact
years gridarchive
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarYearsGrid } from "@dateforge/react-calendar/modules";

export function ArchiveYearBrowserExample() {
  const [archiveYear, setArchiveYear] = useState<Date | null>(null);

  return (
    <>
      <Calendar
        config={createCalendarConfig({
          min: new Date("2018-01-01"),
          max: new Date("2030-12-31"),
        })}
        initialView={calendarDate(2026, 1, 1)}
      >
        <CalendarYearsGrid
          yearsPerPage={12}
          onYearSelect={(year: number) => setArchiveYear(new Date(year, 0, 1))}
        />
      </Calendar>
      {archiveYear && <p>Browsing archive · {archiveYear.getFullYear()}</p>}
    </>
  );
}

Pick a month to plan the campaign

Composition

Campaign month picker

Use this when
Lightweight season, campaign, or billing-period selectors.
What it demonstrates
Solo CalendarMonthsGrid with onMonthSelect driving external state.
theme: temporalappearance: soft
months gridcampaign
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarMonthsGrid } from "@dateforge/react-calendar/modules";

export function CampaignMonthPickerExample() {
  const [campaignMonth, setCampaignMonth] = useState<Date | null>(null);

  return (
    <>
      <Calendar
        config={createCalendarConfig({
          min: new Date("2026-01-01"),
          max: new Date("2026-12-31"),
        })}
        initialView={calendarDate(2026, 5, 1)}
        gradient
      >
        <CalendarMonthsGrid
          short
          onMonthSelect={(year: number, month: number) =>
                      setCampaignMonth(new Date(year, month - 1, 1))
                    }
        />
      </Calendar>
      {campaignMonth && (
        <p>
          Campaign ·{" "}
          {campaignMonth.toLocaleString("en-US", { month: "long", year: "numeric" })}
        </p>
      )}
    </>
  );
}
00
00

Pick a time slot

Composition

Time slot picker

Use this when
Slot pickers, reminders, or any flow where the date is fixed and only time matters.
What it demonstrates
Solo CalendarTimeWheel with timeStep={{ minute: 10 }} for snapped slots.
theme: auroraappearance: loft
timeslots
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarTimeWheel } from "@dateforge/react-calendar/modules/time";

export function TimeSlotPickerExample() {
  const [meetingTime, setMeetingTime] = useState<Date | null>(null);

  return (
    <>
      <Calendar
        config={createCalendarConfig({ withTime: true })}
        value={meetingTime}
        onChange={(value) => setMeetingTime(value as Date | null)}
      >
        <CalendarTimeWheel />
      </Calendar>
      {meetingTime && (
        <p>
          Slot ·{" "}
          {meetingTime.toLocaleTimeString("en-US", {
            hour: "2-digit",
            minute: "2-digit",
          })}
        </p>
      )}
    </>
  );
}
SunMonTueWedThuFriSat
00
00
Same moment around the world
  • New York
  • London
  • Berlin
  • Tokyo
Composition

Global meeting time

Use this when
Scheduling one slot that teammates in different time zones can read at a glance.
What it demonstrates
timeZone + hour12 on the calendar, with the same instant rendered in four cities.
theme: auroraappearance: loft
singletime zonehour12
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createDisabled } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import { CalendarTimeWheel } from "@dateforge/react-calendar/modules/time";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function GlobalMeetingTimeExample() {
  const ZONES = [
    { city: "New York", tz: "America/New_York" },
    { city: "London", tz: "Europe/London" },
    { city: "Berlin", tz: "Europe/Berlin" },
    { city: "Tokyo", tz: "Asia/Tokyo" },
  ];

  const [globalMeeting, setGlobalMeeting] = useState<Date | null>(null);

  const noPast = useMemo(() => {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return createDisabled({ before: today });
  }, []);

  const config = createCalendarConfig({
    withTime: true,
    hour12: true,
    timeZone: "America/New_York",
    disabled: noPast,
  });

  return (
    <Calendar
      config={config}
      value={globalMeeting}
      onChange={(value) => setGlobalMeeting(value as Date | null)}
    >
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarClear />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarTimeWheel />
    </Calendar>

    {globalMeeting && (
      <ul>
        {ZONES.map((z) => (
          <li key={z.tz}>
            <span>{z.city}</span>
            <span>
              {globalMeeting.toLocaleString("en-US", {
                timeZone: z.tz,
                weekday: "short",
                month: "short",
                day: "numeric",
                hour: "2-digit",
                minute: "2-digit",
                hour12: true,
              })}
            </span>
          </li>
        ))}
      </ul>
    )}
  );
}
2026
Jul
16
Composition

Profile birthday

Use this when
Older dates where jumping years and months matters more than a month grid.
What it demonstrates
Track-based UI (CalendarYearsTrack, CalendarMonthsTrack, CalendarDaysTrack).
theme: midnightappearance: bubble
singletracksbirthday
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDaysTrack, CalendarMonthsTrack, CalendarSelectedDates, CalendarYearsTrack } from "@dateforge/react-calendar/modules";
import { bubble } from "@dateforge/react-calendar/appearances";

export function ProfileBirthdayExample() {
  const [birthday, setBirthday] = useState<Date | null>(new Date(1994, 5, 14));

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={birthday} onChange={(value) => setBirthday(value as Date | null)} appearance={bubble}>
      <CalendarYearsTrack />
      <CalendarMonthsTrack short />
      <CalendarDaysTrack />
      <CalendarSelectedDates allowClear />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Blackout calendar

Use this when
Operations calendars with weekends, maintenance windows, and exact blackout dates.
What it demonstrates
Range mode with composite createDisabled (weekends + before + ranges + dates).
theme: snowappearance: square
rangedisabledoperations
Code
import { useMemo, useState } from "react";
import { Calendar, createCalendarConfig, createDisabled } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function BlackoutCalendarExample() {
  const [blackoutRange, setBlackoutRange] = useState<{ start: Date; end: Date } | null>(null);

  // Everything matching a rule renders greyed out and unclickable:
  // past days, weekends, the maintenance window, the exact date.
  const blackout = createDisabled({
    weekends: true,
    before: new Date(),
    ranges: [{ from: new Date("2026-06-10"), to: new Date("2026-06-14") }],
    dates: [new Date("2026-06-20")],
  });

  const config = createCalendarConfig({ mode: "range", disabled: blackout });

  return (
    <Calendar config={config} value={blackoutRange} onChange={(value) => setBlackoutRange(value as { start: Date; end: Date } | null)}>
      <CalendarToolbar>
        <CalendarToolbarMonthTrigger compact />
        <CalendarToolbarPrev unit="year" />
        <CalendarToolbarYearTrigger />
        <CalendarToolbarNext unit="year" />
        <CalendarToolbarHome />
      </CalendarToolbar>
      <CalendarDays highlightWeekends />
      <CalendarSelectedDates allowClear />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Launch day

Use this when
Locked launches, archive screens, or confirmed bookings.
What it demonstrates
readOnly flag plus allowNavigate on the selected dates display.
theme: snowappearance: soft
read-onlystatus
Code
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function LaunchDayExample() {
  const launchDate = new Date(2026, 8, 9);

  const config = createCalendarConfig({ readOnly: true });

  return (
    <Calendar config={config} value={launchDate}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthLabel />
        <CalendarToolbarNext />
        <CalendarToolbarYearLabel />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarSelectedDates allowNavigate />
    </Calendar>
  );
}
July
SunMonTueWedThuFriSat
Composition

Month wheel + day grid

Use this when
Compact pickers where month is spun via drum, day selected via grid.
What it demonstrates
cols={2}, arrows navigate by year, wheel handles month, YearTrigger compact at right.
theme: temporalappearance: soft
singlewheel2 cols
Code
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";

export function MonthWheelDayGridExample() {
  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)} cols={2}>
      <CalendarToolbar col={2}>
        <CalendarToolbarPrev unit="year" />
        <CalendarToolbarYearTrigger  />
        <CalendarToolbarNext unit="year" />
      </CalendarToolbar>
      <CalendarMonthsWheel col={1} showLabel />
      <CalendarDays col={1} />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Drum triggers in toolbar

Use this when
Compact headers where month and year are spun in a wheel popup instead of grids.
What it demonstrates
compact on CalendarToolbarMonthTrigger / CalendarToolbarYearTrigger — the popup becomes an iOS-style drum picker.
theme: velvetappearance: bubble
toolbarwheelcompact triggers
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function DrumTriggersInToolbarExample() {
  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        {/* compact = drum-style wheel picker in the popup */}
        <CalendarToolbarMonthTrigger compact />
        <CalendarToolbarYearTrigger compact />
        <CalendarToolbarNext />
      </CalendarToolbar>
      <CalendarDays />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
09
00
Composition

Quarter-hour slots

Use this when
Call bookings or service slots that snap to 15-minute steps.
What it demonstrates
CalendarTimeWheel step={{ minute: 15 }} — the minutes drum only offers 00 / 15 / 30 / 45; defaultTime seeds the first pick.
theme: prismappearance: soft
timestep15 min
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays, CalendarSelectedDates } from "@dateforge/react-calendar/modules";
import { CalendarTimeWheel } from "@dateforge/react-calendar/modules/time";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function QuarterhourSlotsExample() {
  const config = createCalendarConfig({
    withTime: true,
    defaultTime: { hour: 9 },
  });

  return (
    <Calendar config={config} value={slot} onChange={(value) => setSlot(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarTimeWheel step={{ minute: 15 }} labels="short" />
      <CalendarSelectedDates showTime />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Lunar phase strip

Use this when
Astrology apps, farming calendars, tide trackers, or any domain where lunar phase is meaningful.
What it demonstrates
CalendarLunar below the day grid — display-only, no interaction.
theme: nebulaappearance: soft
singlelunar
Code
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";

export function LunarPhaseStripExample() {
  import { CalendarLunar } from "@dateforge/react-calendar/modules/lunar";

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays />
      <CalendarLunar />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Weather forecast

Use this when
Trip planners or weather apps where each day shows an at-a-glance condition.
What it demonstrates
CalendarDays renderDay returning a custom cell — day number plus a per-day weather emoji.
theme: auroraappearance: soft
renderDaycustom cellcustom calendar
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function WeatherForecastExample() {
  // Deterministic per-day value so each date always looks the same.
  const seededRandom = (d: CalendarDate) => {
    const seed = d.year * 10000 + d.month * 100 + d.day;
    const x = Math.sin(seed) * 10000;
    return x - Math.floor(x);
  };

  const WEATHER_ICONS = ["☀️", "⛅", "☁️", "🌧", "⛈", "❄️"];
  const weatherFor = (d: CalendarDate) =>
    WEATHER_ICONS[Math.floor(seededRandom(d) * WEATHER_ICONS.length)];

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays
        renderDay={(d, state) => {
          if (state.outside) return <span>{d.day}</span>;
          return (
            <span style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 2, lineHeight: 1.1 }}>
              <span style={{ fontSize: 13 }}>{d.day}</span>
              <span aria-hidden style={{ fontSize: 13 }}>{weatherFor(d)}</span>
            </span>
          );
        }}
      />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Activity heatmap

Use this when
Contribution graphs, habit trackers, or any view where each day carries an intensity.
What it demonstrates
renderDay with an absolute-positioned fill behind the number to tint each cell.
theme: mintappearance: soft
renderDayheatmapcustom calendar
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function ActivityHeatmapExample() {
  const seededRandom = (d: CalendarDate) => {
    const seed = d.year * 10000 + d.month * 100 + d.day;
    const x = Math.sin(seed) * 10000;
    return x - Math.floor(x);
  };

  const heatColor = (intensity: number) => {
    const alpha = Math.min(0.85, 0.08 + intensity * 0.7);
    return `rgba(34, 139, 60, ${alpha})`;
  };

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays
        renderDay={(d, state) => {
          if (state.outside) return <span>{d.day}</span>;
          const intensity = seededRandom(d);
          return (
            <>
              {/* Absolute fill overrides the .activeItem background so the
                  heatmap color wins on every appearance / border-radius. */}
              <span aria-hidden style={{ position: "absolute", inset: 0, background: heatColor(intensity), borderRadius: "inherit" }} />
              <span style={{ position: "relative", fontSize: 13 }}>{d.day}</span>
            </>
          );
        }}
      />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Ticket prices

Use this when
Flight or event booking where users want to spot the cheapest day to buy.
What it demonstrates
renderDay showing a derived price under each day — green when cheap, red when pricey.
theme: temporalappearance: compact
renderDaypricingcustom calendar
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function TicketPricesExample() {
  const seededRandom = (d: CalendarDate) => {
    const seed = d.year * 10000 + d.month * 100 + d.day;
    const x = Math.sin(seed) * 10000;
    return x - Math.floor(x);
  };

  const priceFor = (d: CalendarDate) => {
    const dow = new Date(d.year, d.month - 1, d.day).getDay();
    const isWeekend = dow === 0 || dow === 6;
    return Math.round(79 + seededRandom(d) * 220 + (isWeekend ? 60 : 0));
  };

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays
        renderDay={(d, state) => {
          if (state.outside) return <span>{d.day}</span>;
          const price = priceFor(d);
          const isCheap = price < 140;
          return (
            <span style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 2, lineHeight: 1.1 }}>
              <span style={{ fontSize: 13 }}>{d.day}</span>
              <span aria-hidden style={{ fontSize: 10, fontWeight: 600, color: isCheap ? "#15803d" : "#b91c1c" }}>
                ${price}
              </span>
            </span>
          );
        }}
      />
    </Calendar>
  );
}
SunMonTueWedThuFriSat
Composition

Event dots

Use this when
Schedules or agendas that mark how many events fall on a given day.
What it demonstrates
renderDay rendering 1–3 dots under days that have events.
theme: nebulaappearance: soft
renderDayeventscustom calendar
Code
import { useState } from "react";
import { Calendar, createCalendarConfig } from "@dateforge/react-calendar";
import { CalendarDays } from "@dateforge/react-calendar/modules";
import {
  CalendarToolbar,
  CalendarToolbarPrev,
  CalendarToolbarMonthTrigger,
  CalendarToolbarNext,
  CalendarToolbarYearTrigger,
} from "@dateforge/react-calendar/modules/toolbar";

export function EventDotsExample() {
  const seededRandom = (d: CalendarDate) => {
    const seed = d.year * 10000 + d.month * 100 + d.day;
    const x = Math.sin(seed) * 10000;
    return x - Math.floor(x);
  };

  const EVENT_DAYS = new Set([3, 7, 14, 18, 22, 27]);
  const eventCount = (d: CalendarDate) => {
    if (!EVENT_DAYS.has(d.day)) return 0;
    return 1 + Math.floor(seededRandom(d) * 3);
  };

  const config = createCalendarConfig();

  return (
    <Calendar config={config} value={date} onChange={(value) => setDate(value as Date | null)}>
      <CalendarToolbar>
        <CalendarToolbarPrev />
        <CalendarToolbarMonthTrigger />
        <CalendarToolbarNext />
        <CalendarToolbarYearTrigger compact />
      </CalendarToolbar>
      <CalendarDays
        renderDay={(d, state) => {
          if (state.outside) return <span>{d.day}</span>;
          const count = eventCount(d);
          return (
            <span style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 2, lineHeight: 1.1 }}>
              <span style={{ fontSize: 13 }}>{d.day}</span>
              <span aria-hidden style={{ display: "flex", gap: 2, height: 4 }}>
                {Array.from({ length: count }, (_, i) => (
                  <span key={i} style={{ width: 4, height: 4, borderRadius: "50%", background: "currentColor", opacity: 0.7 }} />
                ))}
              </span>
            </span>
          );
        }}
      />
    </Calendar>
  );
}