A dashboard’s period and what it compares with, in one picker.
import { DashboardPeriod } from '@oztix/roadie-components/dashboard-period'
One button shows the period and, when there is one, the dates it compares with: “This month 1 to 31 Oct 2026 vs 1 to 30 Sept 2026”. It opens a DateRangePicker that waits for Apply, because each change refetches every card. Its presets look ahead 30 and 90 days, back 30 days and 12 months, and over this financial year. Under the range, the Compare switch turns the comparison on, and Previous period or Previous year picks it, with the dates it covers below. Apply sends the period and its comparison together. The value is { range, compare }, and no comparison leaves compare out. compareOptions changes the choices: see below.
readOnly shows the period and comparison with a lock, for a dashboard whose period the page sets, such as one show’s on-sale window. disabled turns it off.
Add 'custom' to compareOptions, and Custom dates opens a range of its own, starting from the previous period’s dates. The comparison is then { start, end }. Leave it out, as by default, and custom dates the app sets still show as Custom dates, without a picker, so switching away and back keeps them.
compareOptions lists the choices in order. Roadie’s are 'previous-period', 'previous-year' and 'custom'. The app’s own are { value, label, description? }, such as similar venues. Choosing one sets compare to its value, which comes back as it is: Roadie works out no dates for it, shows its description where the dates go, and the button reads “vs similar venues”. 'none' adds the Compare switch. Leave it out, as here, and nothing turns the comparison off once one is chosen. The default is ['none', 'previous-period', 'previous-year']. An empty list, or ['none'] alone, leaves the comparison out of the picker. A comparison the value holds that the list leaves out still shows among the choices. If you hoist the list, add as const, so TypeScript keeps your values.
presets replaces the period’s list, as on DateRangePicker. A sales dashboard reports on periods to date, so it takes the picker’s own dateRangePresets.
A preset can be fixed dates, such as a last 30 days that ends yesterday, worked out by the app. When the period is one of them, the button shows its label with its dates, as it does for relative presets, and the phone’s list shows its dates beside it.
Pass the same dataStart, dataEnd and alignWeekday you give resolveComparison, and the comparison shows the dates the app will fetch, or “Not enough history” or “Nothing to compare” when the data can’t cover them. Here sales data runs to today, so this month compares with the same days of last month, and the previous year lines up weekdays.
Pass the app’s other controls, such as a channel filter, as children, and they sit after the period. On a narrow container they stack.
Give a dashboard description a period, and DashboardView shows this toolbar above its sections. Its onPeriodChange gets the new period: resolve it with resolveDateRange and resolveComparison, fetch, and pass back a description with the new period and its history. A delta marked comparison: true follows the comparison. Here sales data starts on 1 March 2026, so month to date has nothing to compare with a year back. Choose the previous period to see the deltas.
dataEnd set to today, compares with 1 Jul to 7 Oct 2025, last financial year to the same day. The same year as fixed dates, { start: '2026-07-01', end: '2027-06-30' } with dataEnd set to yesterday, compares with the same number of days just before it instead: 25 Mar to 30 Jun 2026. Pick the form that matches how your data is compared.'none', 'custom', 'previous-period' or 'previous-year': an option with one of those values is left out, with a warning in development. Roadie treats any other compare as no comparison of its own: resolveComparison refuses it, DashboardView hides deltas marked comparison: true, and validateDashboard warns about them, and about one that reads like Roadie’s, such as 'previous_period'.dataStart to resolveComparison and to this toolbar. When the comparison starts before the data, the cards say “Not enough history”; when it ends before, “Nothing to compare”. Neither shows a delta.size='lg' Buttons, IconButtons and Selects.period, so cards and controls never disagree.resolveComparison(range, compare, { now, timeZone, dataEnd: today })
Do
Pass dataEnd for data recorded as it happens, such as sales. A period still in progress then compares with the same days of the period before. Leave it out for dates known ahead, such as shows coming up.
resolveComparison('this-month', 'previous-period', { now, timeZone })
Don’t
Don’t compare a month that’s two days old with a whole month. The delta looks like a fall.
<DashboardPeriod value={period} onValueChange={setPeriod}><Button size='lg'>Export</Button></DashboardPeriod>
Do
Put large Buttons, IconButtons and Selects beside it, so the row shares one height.
<DashboardPeriod value={period} onValueChange={setPeriod}><Button size='sm'>Export</Button></DashboardPeriod>
Don’t
Don't set small or medium controls beside it. They sit short of its edge.
compareOptions={['previous-period', 'previous-year', { value: 'similar', label: 'Similar venues' }]}
Do
Add a benchmark such as similar venues to compareOptions, so it sits with the other comparisons and the button names it.
Don’t
Don’t put a benchmark in its own toggle beside the period. Two controls then both say what the numbers compare with, and can disagree.
aria-label.commit='apply': Cancel, Escape or the drawer’s Close drops changes to both the period and the comparison.compareOptions has 'none', then a ToggleGroup named “Compare with”, then the comparison’s dates or your option’s description, which are announced as they change. On a phone the Compare row sits above Apply at the drawer’s foot, so it stays in view on both tabs, and the choices scroll sideways when they don’t fit.A dashboard's period, with what it compares with, in one picker.
The period and its comparison. Pair with `onValueChange`.
The period to start from when uncontrolled. Defaults to the past 30 days, compared with the first of `compareOptions` other than `'custom'`.
Called when Apply is pressed with the period and its comparison. Each change refetches the dashboard, so both wait for Apply.
The period's presets, as on `DateRangePicker`.
Defaults to [
{ value: { direction: 'next', amount: 30, unit: 'day' } },
{ value: { direction: 'next', amount: 90, unit: 'day' } },
{ value: { direction: 'past', amount: 30, unit: 'day' } },
{ value: { direction: 'past', amount: 12, unit: 'month' } },
{ value: { period: 'year', offset: 0, fiscal: true } }
].
The Compare choices, in order. `'previous-period'` and `'previous-year'` are Roadie's; `'custom'` picks dates; `{ value, label, description? }` is the app's own, passed through as `compare: value` with no dates, and read on the button as "vs " and the label with its first letter lowercased. `'none'` adds the Compare switch; without it nothing turns the comparison off. A comparison the value holds that the list leaves out still shows. Uncontrolled, the first choice other than `'custom'` starts on. With nothing listed but `'none'`, there is no Compare row. Hoist the list with `as const` so the app's values are kept.
Defaults to [
'none',
'previous-period',
'previous-year'
] as const.
The first day the data holds, as given to `resolveComparison`, so each comparison lists the dates the app will fetch.
The last day the data holds, as given to `resolveComparison`. Only for data recorded as it happens, such as sales.
Previous year goes back 52 weeks, as given to `resolveComparison`.
Shows the period with a lock, without letting it change.
Defaults to 'normal'.
IANA zone whose calendar decides today. Defaults to the viewer's.
Today as an ISO date. Defaults to today in `timeZone`.
Defaults to 1.
Defaults to 7.
Defaults to 'en-AU'.
Inherited from DOMAttributes
The app's own controls, placed after the period.