DateRangePicker

A range of days to look at — the admin's costs, a report. A button with the range on it, opening the usual presets beside a calendar for days of one's own. Built from Popover, Calendar and Button. On a phone it opens as a bottom sheet.

Playground

Examples are pinned to October 2026, with today on Tuesday the 13th. A preset applies at once; picked days apply with Apply, and a single day picked is that day alone. Two months side by side, one in a phone's sheet; nothing after today can be picked.

this-month · 2026-10-01 → 2026-10-13

On the button

A preset shows its name and, quieter, its days. Days of one's own show the days alone — the month once when they share it, the year only when it isn't this one.

7d · 2026-10-07 → 2026-10-13
custom · 2026-10-05 → 2026-10-12
custom · 2026-09-28 → 2026-10-04
custom · 2020-03-01 → 2020-03-31

On a phone, a sheet

Under sm the presets and calendar rise from the screen's foot as a bottom sheet (Sheet), as a Select's list does: the presets two to a row, 44px tall, over one month at full size, and Apply. Narrow this window to see it.

API

PropTypeDefaultDescription
presets{ value: string; label: string }[]—The ranges a click away, in the order shown.
presetstring—The preset in use; any value not in presets (“custom”) means picked days.
range{ from: string; to: string }—The days in use, YYYY-MM-DD, both counted.
todaystring—The last day there is to pick, YYYY-MM-DD; it also decides when a year is shown.
onPreset(preset: string) => void—A preset was clicked.
onRange({ from, to }) => void—Days were picked and applied.
classNamestring—Layout only — w-full on a phone.

Rules

  • The URL holds the choice — a preset by name, so a bookmark of “This month” stays this month; picked days as two dates.
  • Presets look back from today; nothing in the future can be picked.
  • Days are the data's days: the admin's are UTC, as its ledger is.