Range Dial
betaA 24-hour circular two-thumb range — drag or key the start and end round a ticked clock face, with the duration in the middle.
- Forms
- 1 file
- No extra npm packages
- Accessibility notes
pnpm dlx @dowel-ui/cli add range-dialNo npm packages are needed beyond what Dowel already requires.
import { RangeDial } from "@/components/ui/range-dial";Default
Gallery
Controlled
Quiet Hours
Disabled
<RangeDial>
| Prop | Type | Default |
|---|---|---|
defaultValueUncontrolled start value. Defaults to 23:00 → 06:30 (7h30m). | RangeDialValue | [23 * 60, 6 * 60 + 30] |
densityNumber of ticks round the dial, 24–96 (the source's slider stepped by 8). | number | 48 |
disabled | boolean | false |
formatDurationFormats a duration in minutes for the live announcement. | (minutes: number) => string | spokenDuration |
formatTimeFormats a time (minutes after midnight) for | (minutes: number) => string | — |
localeLocale for the default time format. | string | — |
onValueChangeCalled on every change: while dragging and per key press. | (value: RangeDialValue) => void | — |
onValueCommitCalled when an interaction ends: pointer released or key press. | (value: RangeDialValue) => void | — |
reachTick ring radius in viewBox units, 44–68. Scales the whole dial geometry. | number | 56 |
snapStep in minutes for the pointer and the arrow keys. | 5 | 15 | 30 | 15 |
thumbLabelsAccessible names of the two thumbs. | [start: string, end: string] | ["Start time", "End time"] |
value
| RangeDialValue | — |
Plus every attribute of <div> except defaultValue, onChange, children.
9/9
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — passes
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — does not apply
- className merged — passes
- Visible focus — passes
- No fixed widths — passes