Date Range Picker
A single-trigger date-range picker with a preset rail and a calendar.
A single-trigger date-range picker with a preset rail down the left and a calendar on the right. Selecting a preset highlights its range on the calendar; picking days directly clears the preset and becomes a custom range.
Built from design-system primitives: Menu (popover + radio rail), Calendar, Button, and an icon.
Usage
import { useState } from "react";
import {
DateRangePicker,
DEFAULT_PRESETS,
type DateRangeSelection,
} from "@smartacteam/ambient-web/date-range-picker";
const [value, setValue] = useState<DateRangeSelection>({
preset: "15d",
range: DEFAULT_PRESETS.find((preset) => preset.key === "15d")!.getRange(
new Date(),
),
});
<DateRangePicker value={value} onChange={setValue} />;The component is controlled — it never holds its own selection. onChange fires with { preset, range }:
- Choosing a preset →
{ preset: "<key>", range: { from, to } } - Picking days on the calendar →
{ preset: null, range: { from, to } }, plus the clicked day as a second argument
A consumer that adjusts the selection uses that second argument to decide which bound to hold — the day the user just clicked keeps its place.
Custom presets
Pass your own presets. Each resolves to a concrete range relative to now, so it stays correct regardless of when the picker opens. Supply translated labels here to localize the rail. Use the now prop to anchor presets to a fixed clock (handy when working against historical data). Build ranges with date-fns helpers.
import { addDays, endOfDay, startOfDay } from "date-fns";
const presets: DateRangePreset[] = [
{
key: "24h",
label: "Last 24 hours",
getRange: (now) => ({ from: addDays(now, -1), to: now }),
},
{
key: "7d",
label: "Last 7 days",
getRange: (now) => ({
from: startOfDay(addDays(now, -6)),
to: endOfDay(now),
}),
},
{
key: "30d",
label: "Last 30 days",
getRange: (now) => ({
from: startOfDay(addDays(now, -29)),
to: endOfDay(now),
}),
},
];
<DateRangePicker value={value} onChange={setValue} presets={presets} />;Notice
A consumer that constrains the selection — a maximum span, a floor on how far
back data goes — passes notice to explain the constraint in the popup. It
renders below the preset rail and is announced when it appears, so a selection
the consumer adjusts says so where the user is looking.
The rail runs shorter than the calendar, so the notice occupies spare height: the popup keeps its size whether or not one is showing. Keep the text short — the rail is 10rem wide and the notice wraps within it.
<DateRangePicker
value={value}
onChange={setValue}
notice={
trimmed ? "Range trimmed to 7 days, the most sensor data covers." : null
}
/>Props
Exports
Build custom preset ranges with date-fns (startOfDay, endOfDay, addDays).