Xzero UI
Pro library

Range histogram slider

A price range over a live histogram of the data, lighting the bars inside the range and settling on bar edges.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/range-histogram-slider
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui/range-histogram-slider

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { RangeHistogramSlider } from "@/components/xzero/range-histogram-slider/range-histogram-slider";

export function PriceFilter({ prices }: { prices: number[] }) {
  const [range, setRange] = useState<[number, number]>([80, 320]);
  return (
    <RangeHistogramSlider
      label="Price per night"
      data={prices}
      min={0}
      max={500}
      step={5}
      bins={25}
      value={range}
      onValueChange={setRange}
      onValueCommit={range => refetchListings(range)}
      format={value => `$${value}`}
    />
  );
}

API reference

RangeHistogramSlider

A two thumb range over a histogram of the data it filters. Bars inside the range light up, thumbs never cross, rubber-band at the ends, and settle on bar edges when released.

PropTypeDefaultDescription
label (required)string–Visible label. The thumbs are named from it unless thumbLabels is set.
data (required)number[]–Raw values the histogram counts, such as every listing's price.
value[number, number]–Controlled range. Leave it out for uncontrolled use.
defaultValue[number, number][min, max]Initial range when uncontrolled.
onValueChange(value: [number, number]) => void–Called on every change while dragging or pressing keys.
onValueCommit(value: [number, number]) => void–Called once a drag is released or a key changes the range.
minnumber–Lower bound. Defaults to the smallest data value (or 0).
maxnumber–Upper bound. Defaults to the largest data value.
stepnumber1Value increment.
binsnumber32How many bars the histogram draws.
snapToBinsbooleantrueA released thumb near a bar edge settles on it, so the range never cuts a bar in half.
minStepsBetweenThumbsnumber1Closest the two thumbs may sit, in steps.
format(value: number) => string–Formats the readout and aria-valuetext.
thumbLabels[string, string]–Accessible names for the two thumbs. Defaults to "<label>, minimum" and "<label>, maximum".
namestring–Submits the range with a form, one hidden input per thumb.
disabledbooleanfalseBlocks input and removes the thumbs from the tab order.
classNamestring–Extra class on the root.

histogram

Helper that counts values into equal bars between min and max. The last bar keeps max itself.

PropTypeDefaultDescription
(data, min, max, bins)(number[], number, number, number) => number[]–Returns one count per bar.

Keyboard interactions

KeysAction
TabMoves between the minimum and maximum thumbs.
ArrowRight / ArrowUpIncreases the focused thumb by one step.
ArrowLeft / ArrowDownDecreases the focused thumb by one step.
Shift + Arrow / PageUp / PageDownMoves the focused thumb to the next bar edge in that direction.
Home / EndMoves the focused thumb to its lowest or highest allowed value.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Range histogram slider: A price range over a live histogram of the data, lighting the bars inside the range and settling on bar edges. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components