GitHub

Slider

A range slider component for selecting numeric values, ready for CMS integration.

CMSPayload CMS Integration

Sliders can be configured through CMS fields, allowing content editors to customize labels, min/max values, and step increments without code changes.

CMS Demo

See how content editors configure sliders in a CMS:

Loading...
CMS ConfigurationSimulates Payload CMS slider fields with localization

Payload Form Example

// In your Payload CMS form config
export const VolumeControl = {
  slug: "volume-control",
  fields: [
    {
      name: "volumeSlider",
      type: "group",
      fields: [
        { name: "label", type: "text", localized: true, required: true },
        { name: "min", type: "number", defaultValue: 0 },
        { name: "max", type: "number", defaultValue: 100 },
        { name: "step", type: "number", defaultValue: 1 },
        { name: "defaultValue", type: "number", defaultValue: 50 },
      ],
    },
  ],
}

Rendering the Form

import { Slider } from "@mordecai-design-system/ui"

export function VolumeControl({ data }) {
  const field = data.volumeSlider
  return (
    <div className="space-y-4">
      <label className="text-sm font-medium">{field.label}</label>
      <Slider
        min={field.min}
        max={field.max}
        step={field.step}
        defaultValue={[field.defaultValue]}
      />
    </div>
  )
}

Basic Usage

Loading...
SliderA default slider

Installation

pnpm add @corew500/ui

Usage

import { Slider } from "@mordecai-design-system/ui"
<Slider defaultValue={[50]} max={100} step={1} />

Examples

Default

<Slider defaultValue={[50]} />

Range Slider

<Slider defaultValue={[25, 75]} />

With Custom Min/Max

<Slider min={0} max={1000} step={10} defaultValue={[500]} />

Controlled

const [value, setValue] = useState([50])

<Slider value={value} onValueChange={setValue} />

With Label and Value Display

const [value, setValue] = useState([50])

<div className="space-y-4">
  <div className="flex justify-between">
    <label className="text-sm font-medium">Volume</label>
    <span className="text-sm text-muted-foreground">{value[0]}%</span>
  </div>
  <Slider value={value} onValueChange={setValue} />
</div>

Props

PropTypeDefaultDescription
classNameenum—CSS class applied to the element, or a function that returns a class based on the component’s state.
defaultValueenum—The uncontrolled value of the slider when it’s initially rendered. To render a controlled slider, use the `value` prop instead.
styleenum—Style applied to the element, or a function that returns a style object based on the component’s state.
disabledenumfalseWhether the slider should ignore user interaction.
formatNumberFormatOptions—Options to format the input value.
localeenum—The locale used by `Intl.NumberFormat` when formatting the value. Defaults to the user's runtime locale.
maxnumber100The maximum allowed value of the slider. Should not be equal to min.
minnumber0The minimum allowed value of the slider. Should not be equal to max.
minStepsBetweenValuesnumber0The minimum steps between values in a range slider.
namestring—Identifies the field when a form is submitted.
orientationenum'horizontal'The component orientation.
stepnumber1The granularity with which the slider can step through values. (A "discrete" slider.) The `min` prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.
largeStepnumber10The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down.
thumbAlignmentenum'center'How the thumb(s) are aligned relative to `Slider.Control` when the value is at `min` or `max`: - `center`: The center of the thumb is aligned with the control edge - `edge`: The thumb is inset within the control such that its edge is aligned with the control edge - `edge-client-only`: Same as `edge` but renders after React hydration on the client, reducing bundle size in return
thumbCollisionBehaviorenum'push'Controls how thumbs behave when they collide during pointer interactions. - `'push'` (default): Thumbs push each other without restoring their previous positions when dragged back. - `'swap'`: Thumbs swap places when dragged past each other. - `'none'`: Thumbs cannot move past each other; excess movement is ignored.
valueenum—The value of the slider. For ranged sliders, provide an array with two values.
onValueChange(value: number | readonly number[], eventDetails: SliderRootChangeEventDetails) => void—Callback function that is fired when the slider's value changed. You can pull out the new value by accessing `event.target.value` (any). The `eventDetails.reason` indicates what triggered the change: - `'input-change'` when the hidden range input emits a change event (for example, via form integration) - `'track-press'` when the control track is pressed - `'drag'` while dragging a thumb - `'keyboard'` for keyboard input - `'none'` when the change is triggered without a specific interaction
onValueCommitted(value: number | readonly number[], eventDetails: SliderRootCommitEventDetails) => void—Callback function that is fired when the `pointerup` is triggered. **Warning**: This is a generic event not a change event. The `eventDetails.reason` indicates what triggered the commit: - `'drag'` while dragging a thumb - `'track-press'` when the control track is pressed - `'keyboard'` for keyboard input - `'input-change'` when the hidden range input emits a change event (for example, via form integration) - `'none'` when the commit occurs without a specific interaction
renderenum—Allows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
sizeenum——