Docs Components Advanced

DateRangePicker

React example follows below.
ts
const dateRangePickerFixture = {
id: "daterangepicker",
// A committed two-week range, pinned: the trigger reads "Jun 8 – Jun 21, 2026"
// plus the inclusive "14 days" count in all five frameworks, forever.
startIsoDay: "2026-06-08",
endIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
startIsoDay: string;
endIsoDay: 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 { DateRangePicker } from "@grassroot/ui-react/advanced";
export default function DateRangePickerDemo() {
return (
<div>
<DateRangePicker
defaultValue={{
start: isoDayToDate(dateRangePickerFixture.startIsoDay),
end: isoDayToDate(dateRangePickerFixture.endIsoDay),
}}
today={isoDayToDate(dateRangePickerFixture.todayIsoDay)}
/>
</div>
);
}
ts
<script setup lang="ts">
import { ref } from "vue";
const dateRangePickerFixture = {
id: "daterangepicker",
// A committed two-week range, pinned: the trigger reads "Jun 8 – Jun 21, 2026"
// plus the inclusive "14 days" count in all five frameworks, forever.
startIsoDay: "2026-06-08",
endIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
startIsoDay: string;
endIsoDay: 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 { DateRangePicker } from "@grassroot/ui-vue";
const range = ref({
start: isoDayToDate(dateRangePickerFixture.startIsoDay),
end: isoDayToDate(dateRangePickerFixture.endIsoDay),
});
const today = isoDayToDate(dateRangePickerFixture.todayIsoDay);
</script>
<template>
<div><DateRangePicker v-model="range" :today="today" /></div>
</template>
ts
import { Component } from "@angular/core";
const dateRangePickerFixture = {
id: "daterangepicker",
// A committed two-week range, pinned: the trigger reads "Jun 8 – Jun 21, 2026"
// plus the inclusive "14 days" count in all five frameworks, forever.
startIsoDay: "2026-06-08",
endIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
startIsoDay: string;
endIsoDay: 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 { GrassrootDateRangePicker } from "@grassroot/ui-angular";
@Component({
selector: "app-date-range-picker-demo",
standalone: true,
imports: [GrassrootDateRangePicker],
template: `<div><grassroot-date-range-picker [value]="range" [today]="today" /></div>`,
})
export class DateRangePickerDemoComponent {
protected readonly range = {
start: isoDayToDate(dateRangePickerFixture.startIsoDay),
end: isoDayToDate(dateRangePickerFixture.endIsoDay),
};
protected readonly today = isoDayToDate(dateRangePickerFixture.todayIsoDay);
}
export default DateRangePickerDemoComponent;
ts
<script lang="ts">
const dateRangePickerFixture = {
id: "daterangepicker",
// A committed two-week range, pinned: the trigger reads "Jun 8 – Jun 21, 2026"
// plus the inclusive "14 days" count in all five frameworks, forever.
startIsoDay: "2026-06-08",
endIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
startIsoDay: string;
endIsoDay: 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 { DateRangePicker } from "@grassroot/ui-svelte";
</script>
<div>
<DateRangePicker
defaultValue={{
start: isoDayToDate(dateRangePickerFixture.startIsoDay),
end: isoDayToDate(dateRangePickerFixture.endIsoDay),
}}
today={isoDayToDate(dateRangePickerFixture.todayIsoDay)}
/>
</div>
ts
/** @jsxImportSource solid-js */
const dateRangePickerFixture = {
id: "daterangepicker",
// A committed two-week range, pinned: the trigger reads "Jun 8 – Jun 21, 2026"
// plus the inclusive "14 days" count in all five frameworks, forever.
startIsoDay: "2026-06-08",
endIsoDay: "2026-06-21",
todayIsoDay: "2026-06-21",
} satisfies {
id: string;
startIsoDay: string;
endIsoDay: 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 { DateRangePicker } from "@grassroot/ui-solid";
export default function DateRangePickerDemo() {
return (
<div>
<DateRangePicker
defaultValue={{
start: isoDayToDate(dateRangePickerFixture.startIsoDay),
end: isoDayToDate(dateRangePickerFixture.endIsoDay),
}}
today={isoDayToDate(dateRangePickerFixture.todayIsoDay)}
/>
</div>
);
}

Installation

API Reference

Import

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

Props

Prop
Type
Default
Requirement
Description
value
Range | undefined
optional
defaultValue
Range | undefined
optional
onValueChange
((range: Range) => void) | undefined
optional
today
Date | undefined
optional
Override "today" (testing/stories).
defaultOpen
boolean | undefined
false
optional
Render the calendar open initially.
className
string | undefined
optional
Prop
value
Type
Range | undefined
Default
Requirement
optional
Description
Prop
defaultValue
Type
Range | undefined
Default
Requirement
optional
Description
Prop
onValueChange
Type
((range: Range) => void) | undefined
Default
Requirement
optional
Description
Prop
today
Type
Date | undefined
Default
Requirement
optional
Description
Override "today" (testing/stories).
Prop
defaultOpen
Type
boolean | undefined
Default
false
Requirement
optional
Description
Render the calendar open initially.
Prop
className
Type
string | undefined
Default
Requirement
optional
Description

Events

EventPayload
onValueChange((range: Range) => void) | undefined

Import

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

Props

Prop
Type
Default
Requirement
modelValue
Range | undefined
optional
today
Date | undefined
optional
defaultOpen
boolean | undefined
false
optional
Prop
modelValue
Type
Range | undefined
Default
Requirement
optional
Prop
today
Type
Date | undefined
Default
Requirement
optional
Prop
defaultOpen
Type
boolean | undefined
Default
false
Requirement
optional

Events

EventPayload
update:modelValue[range: Range]

Import

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

Props

Prop
Type
Default
Requirement
today
Date
optional
value
Range
{ start: null, end: null }
optional
defaultOpen
boolean
false
optional
Prop
today
Type
Date
Default
Requirement
optional
Prop
value
Type
Range
Default
{ start: null, end: null }
Requirement
optional
Prop
defaultOpen
Type
boolean
Default
false
Requirement
optional

Events

EventPayload
valueChangeRange

Import

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

Props

Prop
Type
Default
Requirement
value
Range
optional
defaultValue
Range
optional
onValueChange
(range: Range) => void
optional
today
Date
optional
defaultOpen
boolean
false
optional
className
string
optional
Prop
value
Type
Range
Default
Requirement
optional
Prop
defaultValue
Type
Range
Default
Requirement
optional
Prop
onValueChange
Type
(range: Range) => void
Default
Requirement
optional
Prop
today
Type
Date
Default
Requirement
optional
Prop
defaultOpen
Type
boolean
Default
false
Requirement
optional
Prop
className
Type
string
Default
Requirement
optional

Events

EventPayload
onValueChange(range: Range) => void

Import

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

Props

Prop
Type
Default
Requirement
value
Range
optional
defaultValue
Range
optional
onValueChange
(range: Range) => void
optional
today
Date
optional
defaultOpen
boolean
false
optional
className
string
optional
Prop
value
Type
Range
Default
Requirement
optional
Prop
defaultValue
Type
Range
Default
Requirement
optional
Prop
onValueChange
Type
(range: Range) => void
Default
Requirement
optional
Prop
today
Type
Date
Default
Requirement
optional
Prop
defaultOpen
Type
boolean
Default
false
Requirement
optional
Prop
className
Type
string
Default
Requirement
optional

Events

EventPayload
onValueChange(range: Range) => void