KQ-2130 · DATE/WINDOW
Date Window
The header of a sales dashboard and the figures it governs: the date presets are a radiogroup whose selected pill slides to the new choice on springs.snap through one shared layoutId, the range label cross-slides and the tiles re-settle in a cascade() on springs.glide. Turning compare on slides a muted second range label in beside the first on glide, its width growing from nothing so the row makes room instead of jumping, and each tile's change against it rises in on snap; Custom opens a calendar under the bar whose height glides open — one month, two side by side, or a scrolling strip of days — where a span longer than maxDays turns to a danger hatch and Apply says why it is off. Arrow keys move between presets, C toggles compare, Escape closes the calendar, and below 34rem the presets collapse into one dropdown.
Last 30 days · 09-18 to 10-17 · no comparison
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/date-window
Props
- presets
- DateWindowPreset[]
- default defaultDateWindowPresets
- The preset pills, in order: { id, label, short, days? , kind?: "today" | "qtd" | "ytd" | "custom" }. A days preset is a trailing window ending today; custom opens the calendar.
- range / defaultRange
- DateWindowRange
- default defaultDateWindowRange (the last 30 days)
- The range, controlled or initial: { preset, start, end } with ISO days in the dashboard's time zone. A range whose start is after its end shows as invalid.
- onRangeChange
- (range: DateWindowRange) => void
- default —
- Fires from the pill, arrow key, dropdown or Apply that changed the range.
- compare / defaultCompare
- boolean
- default false
- Whether the figures are compared with another range, controlled or initial.
- compareMode / defaultCompareMode
- "previous" | "year"
- default "previous"
- What the range is compared with: the period of the same length just before it, or the same days a year earlier.
- onCompareChange
- (compare: boolean, mode: "previous" | "year") => void
- default —
- Fires from the switch, the C key or the mode radios, with both values.
- series
- DateWindowDay[]
- default defaultDateWindowSeries
- Daily figures the tiles add up: { date, revenue, orders }. Days missing from it count as no data.
- now
- number
- default defaultDateWindowNow
- The moment today is taken from, ms since the epoch — never the clock during render.
- timeZone
- { label: string; offsetMinutes: number }
- default { label: "Pacific", offsetMinutes: -420 }
- The dashboard's time zone: today and every day shown are in it, and the chip names it.
- dataDelay
- number
- default 120
- How far behind the figures run, minutes, shown as a note; 0 hides it.
- maxDays
- number
- default 90
- The longest custom range Apply accepts. A longer span is the invalid state: a danger hatch and a reason, with Apply off.
- weekStart
- 0 | 1
- default 1
- First day of the week in the calendar: 0 Sunday, 1 Monday.
- title
- string
- default "Sales"
- The dashboard's name.
- product
- string
- default "Coldbrook"
- Whose dashboard it is; shown under the title and part of the accessible name.
- formatMoney
- (dollars: number) => string
- default compact dollars by hand ($48.2K)
- Formats revenue for the tiles. The default avoids Intl compact notation, which prints differently on the server and in the browser.
- pillStyle
- "solid" | "soft" | "line"
- default "soft"
- The selected preset's look: a filled accent pill, a soft accent wash, or a 2 px underline that slides.
- calendarLayout
- "single" | "double" | "strip"
- default "single"
- The custom calendar: one month, two months side by side when there is room, or one sideways-scrolling strip of days that settles on whole days.
- accent
- "cobalt" | "plum" | "mint" | "ink" | string
- default "cobalt"
- The pill, the compare switch and the range ends: a named accent or any CSS colour.
- status
- "ready" | "loading" | "error"
- default "ready"
- Figures state: loading shows skeleton tiles, error offers Retry. The header keeps working.
- onRetry
- () => void
- default —
- Called by the error state's Retry button.
- disabled
- boolean
- default false
- Turns the presets, the switch and the calendar off.
- className
- string
- default —
- Classes for the outer section. Give it a max height to have it scroll inside its own box while the calendar is open.
| Prop | Type | Default | Description |
|---|---|---|---|
| presets | DateWindowPreset[] | defaultDateWindowPresets | The preset pills, in order: { id, label, short, days? , kind?: "today" | "qtd" | "ytd" | "custom" }. A days preset is a trailing window ending today; custom opens the calendar. |
| range / defaultRange | DateWindowRange | defaultDateWindowRange (the last 30 days) | The range, controlled or initial: { preset, start, end } with ISO days in the dashboard's time zone. A range whose start is after its end shows as invalid. |
| onRangeChange | (range: DateWindowRange) => void | — | Fires from the pill, arrow key, dropdown or Apply that changed the range. |
| compare / defaultCompare | boolean | false | Whether the figures are compared with another range, controlled or initial. |
| compareMode / defaultCompareMode | "previous" | "year" | "previous" | What the range is compared with: the period of the same length just before it, or the same days a year earlier. |
| onCompareChange | (compare: boolean, mode: "previous" | "year") => void | — | Fires from the switch, the C key or the mode radios, with both values. |
| series | DateWindowDay[] | defaultDateWindowSeries | Daily figures the tiles add up: { date, revenue, orders }. Days missing from it count as no data. |
| now | number | defaultDateWindowNow | The moment today is taken from, ms since the epoch — never the clock during render. |
| timeZone | { label: string; offsetMinutes: number } | { label: "Pacific", offsetMinutes: -420 } | The dashboard's time zone: today and every day shown are in it, and the chip names it. |
| dataDelay | number | 120 | How far behind the figures run, minutes, shown as a note; 0 hides it. |
| maxDays | number | 90 | The longest custom range Apply accepts. A longer span is the invalid state: a danger hatch and a reason, with Apply off. |
| weekStart | 0 | 1 | 1 | First day of the week in the calendar: 0 Sunday, 1 Monday. |
| title | string | "Sales" | The dashboard's name. |
| product | string | "Coldbrook" | Whose dashboard it is; shown under the title and part of the accessible name. |
| formatMoney | (dollars: number) => string | compact dollars by hand ($48.2K) | Formats revenue for the tiles. The default avoids Intl compact notation, which prints differently on the server and in the browser. |
| pillStyle | "solid" | "soft" | "line" | "soft" | The selected preset's look: a filled accent pill, a soft accent wash, or a 2 px underline that slides. |
| calendarLayout | "single" | "double" | "strip" | "single" | The custom calendar: one month, two months side by side when there is room, or one sideways-scrolling strip of days that settles on whole days. |
| accent | "cobalt" | "plum" | "mint" | "ink" | string | "cobalt" | The pill, the compare switch and the range ends: a named accent or any CSS colour. |
| status | "ready" | "loading" | "error" | "ready" | Figures state: loading shows skeleton tiles, error offers Retry. The header keeps working. |
| onRetry | () => void | — | Called by the error state's Retry button. |
| disabled | boolean | false | Turns the presets, the switch and the calendar off. |
| className | string | — | Classes for the outer section. Give it a max height to have it scroll inside its own box while the calendar is open. |