- Accordion
- Action Bar
- Action Toast
- Alert Banner
- Alert Dialog
- Alert
- Alphabet Index
- Amount Field
- Aspect Ratio
- Attachment
- Availability List
- Avatar
- Badge
- Bank Card
- Breadcrumb
- Bubble
- Button Group
- Button
- Calendar
- Camera Frame
- Card Design Picker
- Card Details
- Card Peek
- Card Stack
- Card
- Carousel
- Chart
- Chat Thread
- Checkbox
- Chip Group
- Choice Tile
- Code Block
- Code Dots
- Collapsible
- Combobox
- Command
- Context Menu
- Copy Field
- Countdown
- Country Select
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Direction
- Document Paper
- Drawer
- Dropdown Menu
- Empty
- Entity Avatar
- Field
- File Trigger
- File Upload Item
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Key Value
- Keypad
- Label
- Live Region
- Marker
- Message Scroller
- Message
- Money Amount
- Native Select
- Number Field
- Pagination
- Percent Split Editor
- Phone Field
- Popover
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Histogram
- Rating
- Resizable
- Scroll Area
- Search Field
- Select
- Separator
- Share Bar
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Sortable List
- Spinner
- Status Timeline
- Step Header
- Steps List
- Swipe Row
- Switch
- Table
- Tabs
- Text Field
- Textarea
- Tier Ladder
- Toggle Group
- Toggle
- Token Search Field
- Tooltip
- Trace
- Transaction Row
- Usage Meter
"use client"
import { RangeHistogram } from "@/components/ui/range-histogram"The RangeHistogram component is a two-thumb range slider over a histogram of the values it filters, such as transaction amounts. Bars inside the selected range are emphasized, so people see how many payments a range keeps before they let go. Use it in a filter sheet when the shape of the data helps pick a range. Pick a plain Slider when the values are spread evenly or the shape of the data doesn't matter, or two amount inputs when people already know the exact bounds.
Installation#
pnpm dlx shadcn@latest add @dots/range-histogram
Usage#
import { RangeHistogram } from "@/components/ui/range-histogram"<RangeHistogram
label="Amount"
data={[8, 14, 26, 44, 62, 78, 100, 86, 70, 58, 46, 40]}
minValue={0}
maxValue={600}
defaultValue={[50, 350]}
formatOptions={{ style: "currency", currency: "USD" }}
/>Features#
- Two thumbs on the React Aria
Slider, with keyboard, touch and screen reader support - A decorative histogram above the track, with bars inside the range emphasized as the thumbs move
- The selected range shown as formatted text next to the label, using
formatOptions - Works controlled or uncontrolled, with
onChangeEndfor work that should wait until the thumb is let go - Bad counts, such as negative or
NaN, draw as empty bars instead of breaking the chart
Data#
data holds how many values fall in each bucket. The buckets are spread evenly from minValue to maxValue, so 24 counts for 0 to 600 make $25 buckets. A bar is emphasized when its bucket overlaps the selected range. Counts are scaled to the highest one, so they don't need to be normalized.
// 24 buckets of $25 between $0 and $600.
<RangeHistogram data={counts} minValue={0} maxValue={600} step={25} />Controlled#
Control the range with value and onChange. Use onChangeEnd for work that should run once the thumb is let go, such as fetching results or announcing a match count.
540 of 776 payments
540 of 776 payments
"use client"
import * as React from "react"Without output#
Set showOutput={false} to hide the range text, such as when the filter's results already show the range. Without a visible label, pass aria-label.
"use client"
import { RangeHistogram } from "@/components/ui/range-histogram"Disabled#
Use isDisabled while the data loads or the filter doesn't apply.
"use client"
import { RangeHistogram } from "@/components/ui/range-histogram"Accessibility#
RangeHistogram is built on the React Aria Slider. Each thumb is a native range input: arrow keys move by step, Page Up and Page Down move by a larger step, and Home and End jump to the ends. The histogram is decorative and hidden from assistive tech.
Label the slider#
Pass a visible label, which also names the slider. Without one, pass aria-label.
<RangeHistogram aria-label="Amount" data={counts} />Name the thumbs#
The thumbs are named "Minimum" and "Maximum" by default. Pass thumbLabels with words that fit the data and your interface language.
<RangeHistogram
label="Amount"
data={counts}
thumbLabels={["Lowest amount", "Highest amount"]}
/>Format values#
Pass formatOptions so each thumb reads as a value, such as "$50", not a bare number.
Announce results#
Assistive tech doesn't see the bars. If the range changes a count of results, show it as text and announce it from onChangeEnd, so it is read once and not on every step of a drag.
API Reference#
RangeHistogram#
Accepts the React Aria Slider props for a number[] value except orientation, children and className.
| Prop | Type | Default | Description |
|---|---|---|---|
data | number[] | - | How many values fall in each bucket, spread evenly from minValue to maxValue. |
label | ReactNode | - | The visible label. It also names the slider. Without it, pass aria-label. |
thumbLabels | [string, string] | ["Minimum", "Maximum"] | The accessible names of the two thumbs. |
showOutput | boolean | true | Show the selected range as text next to the label. |
minValue | number | 0 | The lowest value. |
maxValue | number | 100 | The highest value. |
step | number | 1 | The step between values. |
value | number[] | - | The selected range (controlled). |
defaultValue | number[] | [minValue, maxValue] | The selected range (uncontrolled). |
onChange | (value: number[]) => void | - | Called as the thumbs move. |
onChangeEnd | (value: number[]) => void | - | Called when a thumb is let go. |
formatOptions | Intl.NumberFormatOptions | - | Formats the output and the values read by assistive tech. |
isDisabled | boolean | - | Disables the slider. |
className | string | - | Additional classes to apply to the root element. |