Circular Slider

A radial input you drag around a ring or turn like a knob

Composableoriginal, no Base UI counterpart

The circular slider sets a value by dragging around a ring or turning a raised knob. Use it for dials where the circle means something: temperature, volume, an angle, or a window of hours on a clock face.

For a value on a straight line, use Slider instead.

Preview

Installation

Usage

Composition

CircularSlider is the ready-made ring. Compose the parts with CircularSliderRoot for ticks, a reference mark, a knob face, or your own center content.

Features

  • Clicks, Home/End/Page keys and outside changes sweep along the ring. Arrow steps and drags land at once, so a held key keeps up.
  • Grabbing a thumb holds it where it is. Clicking elsewhere on the band jumps the nearest thumb there.
  • A range thumb pushes the other along when they collide, and the two merge into one pill when they meet. Press where they overlap and the drag takes the one that can move your way.
  • Dragging past either end of a dial pins at that end instead of flipping to the other.
  • Ticks change as the indicator's head passes them, not all at once.
  • Only the band takes the pointer. Buttons in the middle of a ring stay usable, and on touch a swipe from the middle scrolls the page.
  • A partial sweep is only as tall as its arc, so a 180° dial takes about half the height of a full one.

Examples

Thumb shape

Use thumbShape to choose the thumb's look. On a ring the pill reaches past both edges of the band, and the band moves in to make room so the dial keeps its size. On a knob it sets the face's marker.

Bead

Pill

Pill, thin band

Knob, pill

Knob, bead

ShapeDescription
beadA round bead set inside the end of the indicator, or a dot on a knob. Default on a ring.
pillA slim handle across the band, or a line on a knob. Default on a knob.

Knob

Set variant="knob" and render CircularSliderKnob with CircularSliderTicks for a face you turn. Grabbing a knob never jumps its value.

Volume 40

VariantDescription
ringA stroke with a thumb, grabbed anywhere on the band. Default.
knobA raised face ringed by ticks that light up.

Reference mark

Use CircularSliderMark to show a second reading, and set origin to it so the indicator spans the distance between the reading and the target.

Heating toNow 19.4°

Origin

Set origin to a midpoint for a bipolar control; the indicator grows from there in either direction.

Pan L 20

Range

Pass an array of two values for a range, and drag the filled span to move both ends. On a wrap dial the span runs clockwise from the first value, so 22:00 to 07:00 runs through midnight.

Quiet hours9h

Sweep

Use sweep to set the dial's arc in degrees. Partial sweeps center on the top, with the gap at the bottom; set startAngle to move them.

360°

270°

180°

Wrap

Set wrap on a full circle to let values loop past max back to min, for angles and times of day.

Vertical drag

Set dragMode="vertical" to turn the value with up and down drags, like an audio knob. It suits small knobs in a row, where circling each one is fiddly.

Drive 30

Tone 60

Level 75

Sizes

Use size for the diameter and thickness for the band; the thumb follows the band.

Direction

Use direction to set which way the value increases.

ValueDescription
clockwiseValue increases clockwise. Default.
counterclockwiseValue increases counterclockwise.

Accessibility

Each thumb is a visually hidden native <input type="range">, so it takes focus, joins forms, and announces as a slider. Name it with aria-label on the root. Screen readers speak the value through formatValue; pass getAriaValueText when the spoken form should differ from the displayed one ("21.5 degrees" for "21.5°").

A range renders as a group named by aria-label, with thumbs named "Start" and "End". Use getAriaLabel to name them yourself.

Keyboard

KeyAction
↑ / →Increase by step.
↓ / ←Decrease by step.
Shift + arrowChange by largeStep.
Page Up / Page DownChange by largeStep.
Home / EndJump to min / max.

On a wrap dial the arrow keys loop past the ends, and End stops one step short of max, which shares min's position.

API Reference

The Circular Slider is a custom SVG component. Every part renders through Base UI's useRender, so each accepts a render prop.

Props

CircularSliderRoot

Holds the value and geometry, and renders a hidden range input per thumb.

name, form, id and aria-describedby go to the hidden inputs. aria-label and aria-labelledby name the input on a single-value dial, and the group on a range.

CircularSlider

The ready-made ring: Track, Indicator, Thumb and Value inside a root. Takes the root's props, except variant; compose a knob with CircularSliderRoot.

CircularSliderTrack

The full sweep of the band, drawn behind the indicator.

CircularSliderIndicator

The filled arc: from origin to the value, or between a range's thumbs.

CircularSliderThumb

The thumb for each value, shaped by the root's thumbShape: a bead set into the end of the indicator, or a slim pill across the band. When a range's two beads meet, they join into one pill.

CircularSliderTicks

A scale of ticks: just inside a ring's band, or as a knob's band. Ticks up to the value carry data-active; a value between two ticks lights the nearer one. Pick a count that divides your range by step, so the value lands on ticks.

CircularSliderMark

A read-only line across the band for a second value. Glides when the value changes.

CircularSliderKnob

The raised face of a knob dial. Turns with the value and presses in while held. Pass children to replace the notch.

CircularSliderValue

The value as text, centered in the dial.