Filters
PeriodSelector
A date-range picker with preset periods, custom ranges, and comparison mode.
Use PeriodSelector to let users choose a time window for their dashboard. It's pure UI— it captures the user's selection and exposes it via context, but never touches, fetches, or filters your data. You read the active period and pass it to your own data-fetching logic. See the Filtering guide for the full architecture.
Basic Example
<FilterProvider>
<PeriodSelector />
</FilterProvider>Custom Presets
Pass a presets array to control which time periods appear. Available presets: 7d, 14d, 30d, 90d, month, quarter, ytd, year, all.
<PeriodSelector presets={["7d", "14d", "30d", "90d", "year", "all"]} />Custom Range
By default, a "Custom range" option appears below the presets with date inputs. Disable it with allowCustom={false}.
With custom range (default)
Without custom range
// With custom range (default)
<PeriodSelector allowCustom />
// Without custom range
<PeriodSelector allowCustom={false} />Comparison Toggle
Enable comparison to show a toggle button that cycles through comparison modes: none → previous → year-over-year → none. The comparison period is auto-computed from the active period.
<FilterProvider defaultPreset="30d">
<PeriodSelector comparison />
</FilterProvider>Dense Mode
The dense prop reduces padding and font sizes. Also inherits from MetricProvider.
Normal
Dense
<PeriodSelector dense />
// or via MetricProvider
<MetricProvider dense>
<PeriodSelector /> {/* inherits dense */}
</MetricProvider>Connected (FilterProvider)
Wrap your dashboard in a FilterProvider. Any component can then call useMetricFilters() to read the active period, comparison mode, and dimension filters. Select a preset below to see the context values update live.
useMetricFilters() output
preset: null
period.start: null
period.end: null
comparisonMode: "none"
import { FilterProvider, useMetricFilters } from "metricui";
import { PeriodSelector } from "metricui";
function Dashboard() {
return (
<FilterProvider defaultPreset="30d">
<PeriodSelector comparison />
<MyChart />
</FilterProvider>
);
}
function MyChart() {
const filters = useMetricFilters();
// filters.period → { start: Date, end: Date }
// filters.preset → "30d" | null
// filters.comparisonMode → "none" | "previous" | "year-over-year"
// filters.comparisonPeriod → { start: Date, end: Date } | null
// Use these to fetch/filter your data
return <div>...</div>;
}Standalone (onChange)
Use onChange without a FilterProvider for simple use cases where you just need the selected dates.
No selection yet
<PeriodSelector
onChange={(period, preset) => {
console.log(period.start, period.end, preset);
// Fetch data for this range
}}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
presets | PeriodPreset[] | ["7d","30d","90d","month","quarter","ytd"] | Which preset periods to show in the dropdown. |
allowCustom | boolean | true | Show the custom date-range inputs. |
comparison | boolean | false | Show the comparison toggle button. |
comparisonOptions | ComparisonMode[] | ["previous","year-over-year"] | Which comparison modes to cycle through. |
onChange | (period, preset) => void | — | Standalone callback. Fires when a period is selected. |
onComparisonChange | (mode, period) => void | — | Standalone callback for comparison mode changes. |
dense | boolean | false | Compact mode. Falls back to MetricProvider. |
className | string | — | Additional CSS classes. |
id | string | — | HTML id. |
data-testid | string | — | Test id. |
Notes
- PeriodSelector is UI only — it tells you what the user selected, but it does not filter your data. You bring the data; the filter tells you what range to fetch.
- Without a FilterProvider, PeriodSelector still works via onChange. Context is optional.
- Comparison periods are auto-computed. "previous" shifts the range backward by its own duration. "year-over-year" shifts it back one year.
- PeriodSelector uses forwardRef and passes through id, data-testid, and className.
- Dense mode can be set per-component or inherited from MetricProvider.
- The dropdown closes on outside click and on preset selection.