Theme
Sound
Jump to a component
Core · Forms
SliderRow
SliderRow is a labelled value on a track: the name, the track (0–100) and the readout as the creator reads it (+0.2, −3 dB, 100%). disabled dims the track.
Live, from @anicanon/sakuga 2.0.0
Sakuga for iOS and Android is coming
iOS
Web only
SliderRow is made for the web, and isn’t part of Sakuga for iOS yet.
Android
Web only
SliderRow is made for the web, and isn’t part of Sakuga for Android yet.
- Use it for
- A value set by feel on a track, with its readout in the unit people use: colour, volume, opacity and loudness in the editor.
- Not for
- A value where one unit matters, such as 1px or 2°NumberField
- A sound's level with its muteVolumeControl
- One setting on or offSwitch
- The playhead of an episode or a shortScrubber
Guidelines
- Used in the editor for colour, volume, opacity and loudness.
- The readout is in the unit people use, never the raw 0–100.
onChangemakes the track draggable and arrow-key operable (Shift moves 10). The thumb grows under the pointer and follows it with no easing.
import { useState } from 'react';
import { SliderRow } from '@anicanon/sakuga/ui';
function exposure(v) {
const x = (v - 50) / 25;
return (x < 0 ? '−' : '+') + Math.abs(x).toFixed(1);
}
function volume(v) {
const d = Math.round((v - 100) / 10);
return v === 0 ? 'Off' : (d < 0 ? '−' : '') + Math.abs(d) + ' dB';
}
export default function SliderRowExample() {
const [value, setValue] = useState(55);
const [value2, setValue2] = useState(70);
return (
<>
<SliderRow
label="Exposure"
value={value}
onChange={setValue}
readout={exposure(value)}
/>
<SliderRow
label="Volume"
value={value2}
onChange={setValue2}
readout={volume(value2)}
/>
<SliderRow label="Glow" value={0} readout="Off" disabled />
</>
);
}PropsSliderRowProps
labelrequiredstringvaluerequirednumber0–100 along the track.
readoutrequiredstringAs people read it: "+0.2", "−3 dB".
disabledbooleanonChange(value: number) => voidMakes the track draggable and arrow-key operable; called with 0–100.
classNamestringEach token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.
Colour
slidertrack-thumb-shadowSliderRow: the knob's shadow.black-a50rgba(0,0,0,0.5)black-a50rgba(0,0,0,0.5)Space and shape
slidertrack-heightits own value
4px
slidertrack-radiusradius-full9999px
slidertrack-thumb-topits own value
calc((4px - 16px) / 2)
slidertrack-thumb-sizeits own value
16px
slidertrack-thumb-margin-leftits own value
calc(16px / -2)
slidertrack-thumb-radiusradius-full9999px
slidertrack-before-live-insetits own value
calc(-1 * 8px)
slidertrack-thumb-live-scaleits own value
1.15
slidertrack-thumb-dragging-scaleits own value
1.25
slider-row-column-1its own value
96px
slider-row-column-3its own value
40px
slider-row-gapgap-md8px
slider-row-slidertrack-off-opacityopacity-disabled0.35
slidertrack-forced-thumb-edge-widthline-strong2px
slidertrack-target-sizespace-624px
Type
slider-row-fonttext-small500 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
slider-row-value-font-weightweight-strong600
Motion
slidertrack-thumb-durationmotion-fast160ms
slidertrack-thumb-easingease-standardcubic-bezier(0.2, 0, 0, 1)
Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.
- Result
- No issues found, in light or in dark.
- By design
- A slider named by
labelthat Tab reaches, its value spoken as thereadout(the name and readout beside it are hidden, so neither is read twice); withonChange, arrows move it by 1 (10 with Shift), Page Up and Page Down by 10, and Home and End to 0 and 100. WithoutonChangeit reads as read-only, anddisabledtakes it out of the tab order and marks it disabled. - Not tested
- The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.