Docs Components Forms

DatePicker

React example follows below.
ts
const datePickerFixture = {
id: "datepicker",
label: "Kickoff date",
// Pinned for the same reason as calendarFixture: the trigger's mono readout
// and the popover's today-ring must not move with the wall clock.
selectedIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
label: 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 { DatePicker } from "@grassroot/ui-react";
export default function DatePickerDemo() {
return (
<div>
<DatePicker
id={`${datePickerFixture.id}-react`}
label={datePickerFixture.label}
defaultValue={isoDayToDate(datePickerFixture.selectedIsoDay)}
today={isoDayToDate(datePickerFixture.todayIsoDay)}
/>
</div>
);
}
ts
<script setup lang="ts">
import { ref } from "vue";
const datePickerFixture = {
id: "datepicker",
label: "Kickoff date",
// Pinned for the same reason as calendarFixture: the trigger's mono readout
// and the popover's today-ring must not move with the wall clock.
selectedIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
label: 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 { DatePicker } from "@grassroot/ui-vue";
const selected = ref(isoDayToDate(datePickerFixture.selectedIsoDay));
const today = isoDayToDate(datePickerFixture.todayIsoDay);
</script>
<template>
<div>
<DatePicker
v-model="selected"
:id="`${datePickerFixture.id}-vue`"
:label="datePickerFixture.label"
:today="today"
/>
</div>
</template>
ts
import { Component } from "@angular/core";
const datePickerFixture = {
id: "datepicker",
label: "Kickoff date",
// Pinned for the same reason as calendarFixture: the trigger's mono readout
// and the popover's today-ring must not move with the wall clock.
selectedIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
label: 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 { GrassrootDatePicker } from "@grassroot/ui-angular";
@Component({
selector: "app-date-picker-demo",
standalone: true,
imports: [GrassrootDatePicker],
template: `<div>
<grassroot-date-picker
[id]="id"
[label]="fixture.label"
[defaultValue]="selected"
[today]="today"
/>
</div>`,
})
export class DatePickerDemoComponent {
protected readonly fixture = datePickerFixture;
protected readonly id = `${datePickerFixture.id}-angular`;
protected readonly selected = isoDayToDate(datePickerFixture.selectedIsoDay);
protected readonly today = isoDayToDate(datePickerFixture.todayIsoDay);
}
export default DatePickerDemoComponent;
ts
<script lang="ts">
const datePickerFixture = {
id: "datepicker",
label: "Kickoff date",
// Pinned for the same reason as calendarFixture: the trigger's mono readout
// and the popover's today-ring must not move with the wall clock.
selectedIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
label: 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 { DatePicker } from "@grassroot/ui-svelte";
</script>
<div>
<DatePicker
id={`${datePickerFixture.id}-svelte`}
label={datePickerFixture.label}
defaultValue={isoDayToDate(datePickerFixture.selectedIsoDay)}
today={isoDayToDate(datePickerFixture.todayIsoDay)}
/>
</div>
ts
/** @jsxImportSource solid-js */
const datePickerFixture = {
id: "datepicker",
label: "Kickoff date",
// Pinned for the same reason as calendarFixture: the trigger's mono readout
// and the popover's today-ring must not move with the wall clock.
selectedIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
label: 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 { DatePicker } from "@grassroot/ui-solid";
export default function DatePickerDemo() {
return (
<div>
<DatePicker
id={`${datePickerFixture.id}-solid`}
label={datePickerFixture.label}
defaultValue={isoDayToDate(datePickerFixture.selectedIsoDay)}
today={isoDayToDate(datePickerFixture.todayIsoDay)}
/>
</div>
);
}

Installation

API Reference

Import

import { DatePicker } from "@grassroot/ui-react";

Props

Prop
Type
Default
Requirement
Description
value
Date | undefined
—
optional
—
defaultValue
Date | undefined
—
optional
—
onValueChange
((date: Date) => void) | undefined
—
optional
—
open
boolean | undefined
—
optional
—
onOpenChange
((open: boolean) => void) | undefined
—
optional
—
label
string | undefined
—
optional
—
placeholder
string | undefined
—
optional
—
defaultOpen
boolean | undefined
false
optional
Render initially open — handy for layout/stories.
today
Date | undefined
—
optional
Override "today" for the hairline ring (testing/stories/demos).
locale
string | undefined
—
optional
Locale used for the visible date, month, and weekday labels.
dir
"ltr" | "rtl" | undefined
—
optional
Text direction.
weekStartsOn
WeekStart | undefined
—
optional
First weekday (0 = Sunday).
min
Date | undefined
—
optional
—
max
Date | undefined
—
optional
—
Prop
value
Type
Date | undefined
Default
—
Requirement
optional
Description
—
Prop
defaultValue
Type
Date | undefined
Default
—
Requirement
optional
Description
—
Prop
onValueChange
Type
((date: Date) => void) | undefined
Default
—
Requirement
optional
Description
—
Prop
open
Type
boolean | undefined
Default
—
Requirement
optional
Description
—
Prop
onOpenChange
Type
((open: boolean) => void) | undefined
Default
—
Requirement
optional
Description
—
Prop
label
Type
string | undefined
Default
—
Requirement
optional
Description
—
Prop
placeholder
Type
string | undefined
Default
—
Requirement
optional
Description
—
Prop
defaultOpen
Type
boolean | undefined
Default
false
Requirement
optional
Description
Render initially open — handy for layout/stories.
Prop
today
Type
Date | undefined
Default
—
Requirement
optional
Description
Override "today" for the hairline ring (testing/stories/demos).
Prop
locale
Type
string | undefined
Default
—
Requirement
optional
Description
Locale used for the visible date, month, and weekday labels.
Prop
dir
Type
"ltr" | "rtl" | undefined
Default
—
Requirement
optional
Description
Text direction.
Prop
weekStartsOn
Type
WeekStart | undefined
Default
—
Requirement
optional
Description
First weekday (0 = Sunday).
Prop
min
Type
Date | undefined
Default
—
Requirement
optional
Description
—
Prop
max
Type
Date | undefined
Default
—
Requirement
optional
Description
—
Prop
disabledDates
Type
readonly Date[] | undefined
Default
—
Requirement
optional
Description
Calendar days unavailable for selection.
Prop
disabled
Type
boolean | undefined
Default
—
Requirement
optional
Description
—
Prop
readOnly
Type
boolean | undefined
Default
—
Requirement
optional
Description
—
Prop
required
Type
boolean | undefined
Default
—
Requirement
optional
Description
—
Prop
invalid
Type
boolean | undefined
Default
—
Requirement
optional
Description
—
Prop
name
Type
string | undefined
Default
—
Requirement
optional
Description
—
Prop
className
Type
string | undefined
Default
—
Requirement
optional
Description
—
Prop
id
Type
string | undefined
Default
—
Requirement
optional
Description
—

Events

EventPayload
onValueChange((date: Date) => void) | undefined
onOpenChange((open: boolean) => void) | undefined

Import

import { ref } from "vue";
import { DatePicker } from "@grassroot/ui-vue";

Props

Prop
Type
Default
Requirement
modelValue
Date | undefined
—
optional
defaultValue
Date | undefined
—
optional
label
string | undefined
—
optional
placeholder
string | undefined
"Pick a date"
optional
open
boolean | undefined
undefined
optional
defaultOpen
boolean | undefined
false
optional
today
Date | undefined
—
optional
locale
string | undefined
—
optional
dir
"ltr" | "rtl" | undefined
—
optional
weekStartsOn
WeekStart | undefined
—
optional
min
Date | undefined
—
optional
max
Date | undefined
—
optional
disabledDates
readonly Date[] | undefined
—
optional
disabled
boolean | undefined
false
optional
Prop
modelValue
Type
Date | undefined
Default
—
Requirement
optional
Prop
defaultValue
Type
Date | undefined
Default
—
Requirement
optional
Prop
label
Type
string | undefined
Default
—
Requirement
optional
Prop
placeholder
Type
string | undefined
Default
"Pick a date"
Requirement
optional
Prop
open
Type
boolean | undefined
Default
undefined
Requirement
optional
Prop
defaultOpen
Type
boolean | undefined
Default
false
Requirement
optional
Prop
today
Type
Date | undefined
Default
—
Requirement
optional
Prop
locale
Type
string | undefined
Default
—
Requirement
optional
Prop
dir
Type
"ltr" | "rtl" | undefined
Default
—
Requirement
optional
Prop
weekStartsOn
Type
WeekStart | undefined
Default
—
Requirement
optional
Prop
min
Type
Date | undefined
Default
—
Requirement
optional
Prop
max
Type
Date | undefined
Default
—
Requirement
optional
Prop
disabledDates
Type
readonly Date[] | undefined
Default
—
Requirement
optional
Prop
disabled
Type
boolean | undefined
Default
false
Requirement
optional
Prop
readOnly
Type
boolean | undefined
Default
false
Requirement
optional
Prop
required
Type
boolean | undefined
Default
false
Requirement
optional
Prop
invalid
Type
boolean | undefined
Default
false
Requirement
optional
Prop
name
Type
string | undefined
Default
—
Requirement
optional
Prop
className
Type
string | undefined
Default
—
Requirement
optional
Prop
id
Type
string | undefined
Default
—
Requirement
optional

Events

EventPayload
update:modelValue[date: Date]
update:open[open: boolean]

Import

import { Component } from "@angular/core";
import { GrassrootDatePicker } from "@grassroot/ui-angular";

Props

Prop
Type
Default
Requirement
value
Date
—
optional
defaultValue
Date
—
optional
open
boolean
—
optional
label
string
—
optional
placeholder
string
"Pick a date"
optional
defaultOpen
boolean
false
optional
id
string
—
optional
today
Date
—
optional
locale
string
—
optional
dir
"ltr" | "rtl"
—
optional
weekStartsOn
WeekStart
—
optional
min
Date
—
optional
max
Date
—
optional
disabledDates
readonly Date[]
—
optional
Prop
value
Type
Date
Default
—
Requirement
optional
Prop
defaultValue
Type
Date
Default
—
Requirement
optional
Prop
open
Type
boolean
Default
—
Requirement
optional
Prop
label
Type
string
Default
—
Requirement
optional
Prop
placeholder
Type
string
Default
"Pick a date"
Requirement
optional
Prop
defaultOpen
Type
boolean
Default
false
Requirement
optional
Prop
id
Type
string
Default
—
Requirement
optional
Prop
today
Type
Date
Default
—
Requirement
optional
Prop
locale
Type
string
Default
—
Requirement
optional
Prop
dir
Type
"ltr" | "rtl"
Default
—
Requirement
optional
Prop
weekStartsOn
Type
WeekStart
Default
—
Requirement
optional
Prop
min
Type
Date
Default
—
Requirement
optional
Prop
max
Type
Date
Default
—
Requirement
optional
Prop
disabledDates
Type
readonly Date[]
Default
—
Requirement
optional
Prop
disabled
Type
boolean
Default
false
Requirement
optional
Prop
readOnly
Type
boolean
Default
false
Requirement
optional
Prop
required
Type
boolean
Default
false
Requirement
optional
Prop
invalid
Type
boolean
Default
false
Requirement
optional
Prop
name
Type
string
Default
—
Requirement
optional

Events

EventPayload
valueChangeDate
openChangeboolean

Import

import { DatePicker } from "@grassroot/ui-svelte";

Props

Prop
Type
Default
Requirement
value
Date
—
optional
defaultValue
Date
—
optional
label
string
—
optional
placeholder
string
"Pick a date"
optional
defaultOpen
boolean
false
optional
open
boolean
—
optional
today
Date
—
optional
id
string
—
optional
name
string
—
optional
min
Date
—
optional
max
Date
—
optional
disabledDates
readonly Date[]
—
optional
disabled
boolean
false
optional
readOnly
boolean
false
optional
Prop
value
Type
Date
Default
—
Requirement
optional
Prop
defaultValue
Type
Date
Default
—
Requirement
optional
Prop
label
Type
string
Default
—
Requirement
optional
Prop
placeholder
Type
string
Default
"Pick a date"
Requirement
optional
Prop
defaultOpen
Type
boolean
Default
false
Requirement
optional
Prop
open
Type
boolean
Default
—
Requirement
optional
Prop
today
Type
Date
Default
—
Requirement
optional
Prop
id
Type
string
Default
—
Requirement
optional
Prop
name
Type
string
Default
—
Requirement
optional
Prop
min
Type
Date
Default
—
Requirement
optional
Prop
max
Type
Date
Default
—
Requirement
optional
Prop
disabledDates
Type
readonly Date[]
Default
—
Requirement
optional
Prop
disabled
Type
boolean
Default
false
Requirement
optional
Prop
readOnly
Type
boolean
Default
false
Requirement
optional
Prop
required
Type
boolean
Default
false
Requirement
optional
Prop
invalid
Type
boolean
Default
false
Requirement
optional
Prop
locale
Type
string
Default
—
Requirement
optional
Prop
dir
Type
"ltr" | "rtl"
Default
—
Requirement
optional
Prop
weekStartsOn
Type
0 | 1 | 2 | 3 | 4 | 5 | 6
Default
—
Requirement
optional
Prop
onValueChange
Type
(date: Date) => void
Default
—
Requirement
optional
Prop
onOpenChange
Type
(open: boolean) => void
Default
—
Requirement
optional
Prop
className
Type
string
Default
—
Requirement
optional

Events

EventPayload
onValueChange(date: Date) => void
onOpenChange(open: boolean) => void

Import

import { DatePicker } from "@grassroot/ui-solid";

Props

Prop
Type
Default
Requirement
value
Date
—
optional
defaultValue
Date
—
optional
onValueChange
(date: Date) => void
—
optional
label
string
—
optional
placeholder
string
"Pick a date"
optional
open
boolean
—
optional
defaultOpen
boolean
false
optional
onOpenChange
(open: boolean) => void
—
optional
today
Date
—
optional
locale
string
—
optional
dir
"ltr" | "rtl"
—
optional
weekStartsOn
WeekStart
—
optional
min
Date
—
optional
max
Date
—
optional
Prop
value
Type
Date
Default
—
Requirement
optional
Prop
defaultValue
Type
Date
Default
—
Requirement
optional
Prop
onValueChange
Type
(date: Date) => void
Default
—
Requirement
optional
Prop
label
Type
string
Default
—
Requirement
optional
Prop
placeholder
Type
string
Default
"Pick a date"
Requirement
optional
Prop
open
Type
boolean
Default
—
Requirement
optional
Prop
defaultOpen
Type
boolean
Default
false
Requirement
optional
Prop
onOpenChange
Type
(open: boolean) => void
Default
—
Requirement
optional
Prop
today
Type
Date
Default
—
Requirement
optional
Prop
locale
Type
string
Default
—
Requirement
optional
Prop
dir
Type
"ltr" | "rtl"
Default
—
Requirement
optional
Prop
weekStartsOn
Type
WeekStart
Default
—
Requirement
optional
Prop
min
Type
Date
Default
—
Requirement
optional
Prop
max
Type
Date
Default
—
Requirement
optional
Prop
disabledDates
Type
readonly Date[]
Default
—
Requirement
optional
Prop
disabled
Type
boolean
Default
—
Requirement
optional
Prop
readOnly
Type
boolean
Default
—
Requirement
optional
Prop
required
Type
boolean
Default
—
Requirement
optional
Prop
invalid
Type
boolean
Default
—
Requirement
optional
Prop
name
Type
string
Default
—
Requirement
optional
Prop
className
Type
string
Default
—
Requirement
optional
Prop
id
Type
string
Default
—
Requirement
optional

Events

EventPayload
onValueChange(date: Date) => void
onOpenChange(open: boolean) => void