Skip to content
SuperCoach

Components · Inputs

Slider

Beta

Picks a value in a range, such as target RPE.

8

How hard the last set should feel. 10 means no reps left.

When to use

  • To set a value on a known scale where the rough position matters more than the exact number: target RPE, session length, rest time.
  • To set a range with two thumbs: a daily carb range, a price range for packages.
  • Always with a visible label and the current value next to it.

When not to use

  • When the exact number matters, or the range is large (a body weight, a price): use an Input with a unit. Coaches can type 82.5 faster than they can drag to it.
  • For settings with a few named steps ("Beginner, Intermediate, Advanced"): use a Radio group or a Select.
  • To set values across a grid such as sets × weeks: that is the Matrix slider.
  • To show progress: use a progress bar. A slider is always an input.

Anatomy

7
  1. 1. Label: names the value, above the slider
  2. 2. Value: the current value and its unit, at the end of the label row
  3. 3. Slider: the track (muted), the range fill (primary) from the start to the thumb, and the thumb

Variants

45 min
150–220 g
  • Single value: one thumb; the range fills from the start of the track to the thumb.
  • Range: pass two values ([150, 220]) for two thumbs; the fill sits between them. minStepsBetweenThumbs keeps them apart.
  • Stepped: step sets the increment: 0.5 for RPE, 5 for minutes, 10 for grams. Pick the step coaches would write down.

Vertical sliders (orientation="vertical") are supported but not used in coach-admin today.

States

90 s
60 s

Set by the program template.

StateWhat changesToken
DefaultMuted track, primary range, thumb with a primary borderbg-muted, bg-primary, border-primary
Hover, focus-visible (thumb)A 4px ring around the thumbring-ring/50, ring-4
DraggingThumb follows the pointer; the value updates as it moves—
DisabledWhole slider at half opacity, thumbs can't be focusedopacity-(--opacity-disabled)

There is no invalid state: the slider can't hold a value outside min and max. Put limits in the scale, not in an error message.

Each thumb carries role="slider", so the component forwards aria-label or aria-labelledby to the thumbs. A range slider names each thumb with thumbLabels ("Minimum carbs", "Maximum carbs"), and getValueText sets what a screen reader speaks for the value ("120 g"). Upstream shadcn put the label on the root, where screen readers don't read it; this version fixes that.

Usage guidelines

45 min
Do.The value and its unit next to the label, updated as the thumb moves.
Don't.No visible value. Coaches can't tell 40 from 45 minutes by the thumb's position.
  • Use a scale that fits the decision: RPE 1–10 in steps of 0.5, not 0–100.
  • Keep the default on a sensible value (RPE 8, 45 minutes), not at the minimum.
  • Save on release (onValueCommit) when a change triggers a request; update the visible value on every move (onValueChange).
  • Pair a slider with an input when coaches sometimes need an exact number.

Content guidelines

  • Label: the thing being set, sentence case: "Target RPE", "Session length", "Daily carbs".
  • Value: digits and a unit, as on the Content page: "45 min", "150–220 g", "90 s". Use an en dash in ranges.
  • If the scale needs explaining, add one line of help text below: "10 means no reps left."
  • Arabic: units follow the number in Arabic ("45 دقيقة", "150–220 غ"), with Western digits (QUESTIONS Q22).

Accessibility

KeyDoes
TabMoves to the thumb (each thumb of a range is a separate stop)
Arrow right / upIncreases by one step (in RTL, Arrow left increases)
Arrow left / downDecreases by one step
Shift + Arrow, Page up / downChanges by 10 steps
Home / EndJumps to the minimum or maximum
  • Each thumb has role="slider" with aria-valuemin, aria-valuemax and aria-valuenow. Once the naming gap above is fixed, a screen reader announces "Target RPE, slider, 8".
  • Numbers alone can be unclear: pass a value text with the unit ("45 minutes") so the announcement matches the screen.
  • The thumb is 16px. It meets WCAG 2.5.8 through the spacing exception, so keep other targets at least 24px from its center. Pointer users can also click anywhere on the track.
  • Changes are announced as the value changes; don't add a live region for the visible value too, or screen readers read it twice.

RTL

  • The track fills from the right: the minimum is on the right and the range grows to the left. Radix reads the direction from the provider.
  • Arrow keys follow the visual direction: Arrow left increases in RTL. Up and down don't change.
  • The label stays at the start of the row and the value at the end, so they swap sides too.
  • Numbers keep Western digits and read left to right inside the Arabic value ("150–220 غ").

Tokens used

Read from components/ui/slider.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.

Semantic color tokens used by this component
TokenUtilitiesSuperCoachCoach
--backgroundbg-backgroundwhitewhite
--mutedbg-mutedneutral-100neutral-100
--primarybg-primary border-primarybrand-600orange-500
--ringring-ring/50brand-600orange-500
  • Opacityopacity-(--opacity-disabled)
  • Radiusrounded-full
  • Shadowshadow-sm

Props

<Slider>

Also takes every prop of Radix Slider.Root

Slider props
PropTypeDefault
thumbLabels?string[]—
getValueText?(value: number) => string—

Replaces in coach-admin

From the read-only audit of coach-admin: 27 style values, 29 uses.

coach-admin has one reusable slider (src/reusableComponents/slider/, el-slider classes) with a value tooltip above the thumb. The tooltip becomes the value next to the label. The program matrix slider is separate: see Matrix slider.

Classes and selectors

  • .el-slider-tooltip-arrow5
  • .el-slider-tooltip-content4
  • .el-slider-thumb3
  • .el-slider-track2
  • .el-slider-thumb:focus2
  • .plan__slider-labels2
  • .el-slider-tooltip-desc1
  • .el-slider-tooltip1

Files

  • src/reusableComponents/slider/slider.scss26
  • src/reusableComponents/slider/Slider.tsx1

The inventory lists the first 12 locations of each value, so file counts are a lower bound.

Input, Radio group, Matrix slider, Form.