Getting Started
Components
- Advanced Toast
- ArrowButton
- Arrows
- Avatar
- Backdrop
- Basic Toast
- Breadcrumb
- Button
- CardBackground
- Card
- ChatButton
- Checkbox
- Checkboxes
- Chip
- ChoiceExpander
- Clickable
- Date Field
- Dropdown
- ElasticHeight
- ExpandableCard
- Filter
- FormCheckbox
- Form Control
- Form Label
- HamburgerIcon
- Heading
- Image
- Link
- Loader
- Number Field
- Pagination
- Password
- Phone Field
- Popin
- Portal
- Prose
- Radio Group
- Radio
- Range
- Select
- SidebarLayout
- Spinner
- Switch
- Tabs
- Tag
- TextField
- ValidationMessage
'use client';
import { Range } from '@/ui/forms/Range';
export function RangeDemo() {
return (
<Range
options={[
{ value: 0, label: '$0' },
{ value: 25, label: '$25' },
{ value: 50, label: '$50' },
{ value: 75, label: '$75' },
{ value: 100, label: '$100' },
]}
ariaLabel="Price range"
className="max-w-md"
/>
);
}
Installation
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/range.json
Usage
'use client';
import { Range } from '@/docs/lib/ui/forms/range';
import { useState } from 'react';
export function Component() {
const [values, setValues] = useState<number[]>([0, 4]);
const options = [
{ value: 0, label: '$0' },
{ value: 25, label: '$25' },
{ value: 50, label: '$50' },
{ value: 75, label: '$75' },
{ value: 100, label: '$100' },
];
return (
<Range options={options} onChange={(name, value) => setValues(value)} ariaLabel="Price range" />
);
}API Reference
Range
| Prop | Type | Default | Description |
|---|---|---|---|
options | { value: number; label: string }[] | Required | Array of option objects defining the selectable values and their labels for the range slider |
onChange | (name: string, value: number[]) => void | - | Callback function triggered when slider values change, receives name and array of selected values |
singleCursorMode | boolean | false | When true, displays only one slider handle instead of two for single value selection |
min | number | 0 | Minimum value for the range slider (index in options array) |
ariaLabel | string | "Range" | Accessible label for the range input elements, important for screen readers |
className | string | - | Additional CSS classes to apply to the range container |
dataTestId | string | "range" | Test ID for the range container element, useful for automated testing |
step | number | 1 | Step increment for the slider (inherited from input[type="range"]) |
disabled | boolean | false | When true, disables both slider handles and prevents user interaction |
readOnly | boolean | false | When true, prevents onChange from firing but doesn't visually disable the sliders |
id | string | Auto | Custom ID for the range inputs (auto-generated with useId if not provided) |
name | string | Auto | Name attribute for the range inputs (defaults to id value) |
| ...rest | InputHTMLAttributes<HTMLInputElement> | - | All standard HTML input attributes (except onChange which is overridden) |
Notes
- Dual-handle slider: By default, the Range component displays two slider handles for selecting a range of values. The first handle (valueA) starts at the maximum index and the second (valueB) starts at the minimum.
- Single cursor mode: Set
singleCursorMode={true}to display only one slider handle for single value selection instead of a range. - Options-based: Unlike traditional range sliders that work with continuous numeric values, this component uses an array of options with discrete values and labels. The slider positions correspond to indices in the options array.
- Visual feedback: Each handle has an associated output element that displays the label of the currently selected option, positioned dynamically based on the slider value.
- ResizeObserver integration: The component uses ResizeObserver to measure the container width and adjust CSS custom properties for accurate slider positioning and handle placement.
- CSS custom properties: The component uses CSS variables (--min, --max, --valueA, --valueB, --inputWidth, --thumbWidth) to control the visual appearance and positioning of the range slider and handles.
- State management: Internal state tracks both slider values (valueA and valueB) independently. Changes to either slider trigger the onChange callback with both values as an array.
- Read-only behavior: When
readOnlyis true, the sliders remain interactive visually but the onChange handler is not called, preventing state updates. - Accessibility: Use the
ariaLabelprop to provide descriptive labels for screen readers. Each input element receives this label for proper accessibility support. - Data attributes: The component sets
data-name="Range"anddata-testidattributes on the container for testing and debugging purposes. - Client component: This is a client component that uses hooks (useState, useId, useMeasure) and requires the "use client" directive in Next.js App Router.