- Prop
value- Type
Date | null | undefined- Default
- —
- Requirement
- optional
- Description
- —
Docs Components Data Display
Calendar
React example follows below.
Vue example follows below.
Angular example follows below.
Svelte example follows below.
Solid example follows below.
- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
const calendarFixture = { id: "calendar", // Pinned, never `new Date()`: the demo has to render the same month, the // same selected cell and the same today-ring in every framework, on every // machine, forever. June 2026 also spans a full six-week grid with both // leading and trailing spillover days, so the dimmed out-of-month cells are // visible in the demo. selectedIsoDay: "2026-06-18", todayIsoDay: "2026-06-21",} satisfies { id: string; selectedIsoDay: string; todayIsoDay: string;}; /** * Turns a fixture's pinned `yyyy-mm-dd` string into the `Date` the calendar * adapters take. * * Fixtures stay plain JSON (the proof test rejects `Date` instances, and * `date` is a forbidden field name), but Calendar/DatePicker/DateRangePicker * are `Date`-valued — so the conversion lives here, once, instead of five * `new Date(...)` literals drifting apart in five demo files. * * Parsed field-by-field into *local* midnight on purpose: `new Date("2026-06-18")` * is parsed as UTC midnight, which renders as the 17th everywhere west of * Greenwich, so the demo month grid would highlight a different day depending * on the reader's timezone. Field-by-field construction pins the rendered * year/month/day in every timezone, forever. */function isoDayToDate(isoDay: string): Date { const [year, month, day] = isoDay.split("-").map(Number); return new Date(year!, month! - 1, day!);} import { Calendar } from "@grassroot/ui-react"; export default function CalendarDemo() { return ( <div> <Calendar defaultValue={isoDayToDate(calendarFixture.selectedIsoDay)} today={isoDayToDate(calendarFixture.todayIsoDay)} /> </div> );}- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
<script setup lang="ts">import { ref } from "vue";const calendarFixture = { id: "calendar", // Pinned, never `new Date()`: the demo has to render the same month, the // same selected cell and the same today-ring in every framework, on every // machine, forever. June 2026 also spans a full six-week grid with both // leading and trailing spillover days, so the dimmed out-of-month cells are // visible in the demo. selectedIsoDay: "2026-06-18", todayIsoDay: "2026-06-21",} satisfies { id: string; selectedIsoDay: string; todayIsoDay: string;}; /** * Turns a fixture's pinned `yyyy-mm-dd` string into the `Date` the calendar * adapters take. * * Fixtures stay plain JSON (the proof test rejects `Date` instances, and * `date` is a forbidden field name), but Calendar/DatePicker/DateRangePicker * are `Date`-valued — so the conversion lives here, once, instead of five * `new Date(...)` literals drifting apart in five demo files. * * Parsed field-by-field into *local* midnight on purpose: `new Date("2026-06-18")` * is parsed as UTC midnight, which renders as the 17th everywhere west of * Greenwich, so the demo month grid would highlight a different day depending * on the reader's timezone. Field-by-field construction pins the rendered * year/month/day in every timezone, forever. */function isoDayToDate(isoDay: string): Date { const [year, month, day] = isoDay.split("-").map(Number); return new Date(year!, month! - 1, day!);} import { Calendar } from "@grassroot/ui-vue";const selected = ref(isoDayToDate(calendarFixture.selectedIsoDay));const today = isoDayToDate(calendarFixture.todayIsoDay);</script><template> <div><Calendar v-model="selected" :today="today" /></div></template>- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
import { Component } from "@angular/core";const calendarFixture = { id: "calendar", // Pinned, never `new Date()`: the demo has to render the same month, the // same selected cell and the same today-ring in every framework, on every // machine, forever. June 2026 also spans a full six-week grid with both // leading and trailing spillover days, so the dimmed out-of-month cells are // visible in the demo. selectedIsoDay: "2026-06-18", todayIsoDay: "2026-06-21",} satisfies { id: string; selectedIsoDay: string; todayIsoDay: string;}; /** * Turns a fixture's pinned `yyyy-mm-dd` string into the `Date` the calendar * adapters take. * * Fixtures stay plain JSON (the proof test rejects `Date` instances, and * `date` is a forbidden field name), but Calendar/DatePicker/DateRangePicker * are `Date`-valued — so the conversion lives here, once, instead of five * `new Date(...)` literals drifting apart in five demo files. * * Parsed field-by-field into *local* midnight on purpose: `new Date("2026-06-18")` * is parsed as UTC midnight, which renders as the 17th everywhere west of * Greenwich, so the demo month grid would highlight a different day depending * on the reader's timezone. Field-by-field construction pins the rendered * year/month/day in every timezone, forever. */function isoDayToDate(isoDay: string): Date { const [year, month, day] = isoDay.split("-").map(Number); return new Date(year!, month! - 1, day!);} import { GrassrootCalendar } from "@grassroot/ui-angular";@Component({ selector: "app-calendar-demo", standalone: true, imports: [GrassrootCalendar], template: `<div><grassroot-calendar [defaultValue]="selected" [today]="today" /></div>`,})export class CalendarDemoComponent { protected readonly selected = isoDayToDate(calendarFixture.selectedIsoDay); protected readonly today = isoDayToDate(calendarFixture.todayIsoDay);}export default CalendarDemoComponent;- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
<script lang="ts"> const calendarFixture = { id: "calendar", // Pinned, never `new Date()`: the demo has to render the same month, the // same selected cell and the same today-ring in every framework, on every // machine, forever. June 2026 also spans a full six-week grid with both // leading and trailing spillover days, so the dimmed out-of-month cells are // visible in the demo. selectedIsoDay: "2026-06-18", todayIsoDay: "2026-06-21", } satisfies { id: string; selectedIsoDay: string; todayIsoDay: string; }; /** * Turns a fixture's pinned `yyyy-mm-dd` string into the `Date` the calendar * adapters take. * * Fixtures stay plain JSON (the proof test rejects `Date` instances, and * `date` is a forbidden field name), but Calendar/DatePicker/DateRangePicker * are `Date`-valued — so the conversion lives here, once, instead of five * `new Date(...)` literals drifting apart in five demo files. * * Parsed field-by-field into *local* midnight on purpose: `new Date("2026-06-18")` * is parsed as UTC midnight, which renders as the 17th everywhere west of * Greenwich, so the demo month grid would highlight a different day depending * on the reader's timezone. Field-by-field construction pins the rendered * year/month/day in every timezone, forever. */ function isoDayToDate(isoDay: string): Date { const [year, month, day] = isoDay.split("-").map(Number); return new Date(year!, month! - 1, day!); } import { Calendar } from "@grassroot/ui-svelte";</script> <div> <Calendar defaultValue={isoDayToDate(calendarFixture.selectedIsoDay)} today={isoDayToDate(calendarFixture.todayIsoDay)} /></div>- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
/** @jsxImportSource solid-js */const calendarFixture = { id: "calendar", // Pinned, never `new Date()`: the demo has to render the same month, the // same selected cell and the same today-ring in every framework, on every // machine, forever. June 2026 also spans a full six-week grid with both // leading and trailing spillover days, so the dimmed out-of-month cells are // visible in the demo. selectedIsoDay: "2026-06-18", todayIsoDay: "2026-06-21",} satisfies { id: string; selectedIsoDay: string; todayIsoDay: string;}; /** * Turns a fixture's pinned `yyyy-mm-dd` string into the `Date` the calendar * adapters take. * * Fixtures stay plain JSON (the proof test rejects `Date` instances, and * `date` is a forbidden field name), but Calendar/DatePicker/DateRangePicker * are `Date`-valued — so the conversion lives here, once, instead of five * `new Date(...)` literals drifting apart in five demo files. * * Parsed field-by-field into *local* midnight on purpose: `new Date("2026-06-18")` * is parsed as UTC midnight, which renders as the 17th everywhere west of * Greenwich, so the demo month grid would highlight a different day depending * on the reader's timezone. Field-by-field construction pins the rendered * year/month/day in every timezone, forever. */function isoDayToDate(isoDay: string): Date { const [year, month, day] = isoDay.split("-").map(Number); return new Date(year!, month! - 1, day!);} import { Calendar } from "@grassroot/ui-solid";export default function CalendarDemo() { return ( <div> <Calendar defaultValue={isoDayToDate(calendarFixture.selectedIsoDay)} today={isoDayToDate(calendarFixture.todayIsoDay)} /> </div> );}Installation
API Reference
Import
import { Calendar } from "@grassroot/ui-react";
Props
Prop
Type
Default
Requirement
Description
valueDate | null | undefined—
optional
—
defaultValueDate | null | undefined—
optional
—
onValueChange((date: Date) => void) | undefined—
optional
—
todayDate | undefined—
optional
Override "today" for the hairline ring (testing/stories).
- Prop
defaultValue- Type
Date | null | undefined- Default
- —
- Requirement
- optional
- Description
- —
- Prop
onValueChange- Type
((date: Date) => void) | undefined- Default
- —
- Requirement
- optional
- Description
- —
- Prop
today- Type
Date | undefined- Default
- —
- Requirement
- optional
- Description
- Override "today" for the hairline ring (testing/stories).
Events
| Event | Payload |
|---|---|
onValueChange | ((date: Date) => void) | undefined |
Native attributes
Standard DOM and ARIA attributes not listed above spread onto the root element.
Import
import { ref } from "vue";
import { Calendar } from "@grassroot/ui-vue";
Props
Prop
Type
Default
Requirement
modelValueDate | null | undefined—
optional
defaultValueDate | null | undefined—
optional
todayDate | undefined—
optional
- Prop
modelValue- Type
Date | null | undefined- Default
- —
- Requirement
- optional
- Prop
defaultValue- Type
Date | null | undefined- Default
- —
- Requirement
- optional
- Prop
today- Type
Date | undefined- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
update:modelValue | [date: Date] |
Import
import { Component } from "@angular/core";
import { GrassrootCalendar } from "@grassroot/ui-angular";
Props
Prop
Type
Default
Requirement
defaultValueDate | nullnulloptional
todayDate—
optional
valueDate | nullnulloptional
- Prop
defaultValue- Type
Date | null- Default
null- Requirement
- optional
- Prop
today- Type
Date- Default
- —
- Requirement
- optional
- Prop
value- Type
Date | null- Default
null- Requirement
- optional
Events
| Event | Payload |
|---|---|
valueChange | Date | null |
Import
import { Calendar } from "@grassroot/ui-svelte";
Props
Prop
Type
Default
Requirement
valueDate | null—
optional
modelValueDate | null—
optional
defaultValueDate | null—
optional
todayDate—
optional
classNamestring—
optional
onValueChange(date: Date) => void—
optional
- Prop
value- Type
Date | null- Default
- —
- Requirement
- optional
- Prop
modelValue- Type
Date | null- Default
- —
- Requirement
- optional
- Prop
defaultValue- Type
Date | null- Default
- —
- Requirement
- optional
- Prop
today- Type
Date- Default
- —
- Requirement
- optional
- Prop
className- Type
string- Default
- —
- Requirement
- optional
- Prop
onValueChange- Type
(date: Date) => void- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
onValueChange | (date: Date) => void |
Import
import { Calendar } from "@grassroot/ui-solid";
Props
Prop
Type
Default
Requirement
valueDate | null—
optional
defaultValueDate | null—
optional
onValueChange(date: Date) => void—
optional
todayDate—
optional
classNamestring—
optional
- Prop
value- Type
Date | null- Default
- —
- Requirement
- optional
- Prop
defaultValue- Type
Date | null- Default
- —
- Requirement
- optional
- Prop
onValueChange- Type
(date: Date) => void- Default
- —
- Requirement
- optional
- Prop
today- Type
Date- Default
- —
- Requirement
- optional
- Prop
className- Type
string- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
onValueChange | (date: Date) => void |