跳到主要内容

Slider

Range input with the kit's own track and handle. It is a styled <input type="range"> and nothing more — no ticks, no value bubble, no label.

SliderSlider

Use this when / not when​

  • Use for a rough setting on a continuous range where the exact number does not matter much: a quality, a zoom, an opacity.
  • Not when the number matters — a TextInput lets someone type it exactly.
  • Not to show progress. It is an input, and it invites dragging; ProgressBar is the read-only one.
  • Not for a handful of discrete choices; use RadioButtonGroup.

Import​

import { Slider } from "@onlyoffice/apps-ui-kit/components/slider";

Also exported from the root barrel @onlyoffice/apps-ui-kit.

SliderProps is not exported — type a wrapper's props yourself.

Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme for the track and handle colours.

Stories​

Default​

A 0–100 slider with the track filled up to the handle (withPouring), the usual choice for a setting such as volume or zoom; drag the handle or change any other prop live in the Controls panel below.

DefaultDefault

Disabled State​

For a setting that cannot be changed right now: the handle and the filled part of the track turn paler, the unfilled track stays as it is, and the handle no longer moves by mouse or keyboard (isDisabled).

Disabled StateDisabled State

With Custom Steps​

Slider with a custom step size of 5, allowing values of 0, 5, and 10 only.

With Custom StepsWith Custom Steps

Without Pouring​

Slider without the pouring (filled track) effect. The track remains a single color.

Without PouringWithout Pouring

With Custom Size​

Slider with larger custom thumb and track dimensions for improved touch targets.

With Custom SizeWith Custom Size

Right To Left​

In a right-to-left interface the minimum sits at the right edge: the fill starts there and grows to the left as the handle is dragged left.

Right To LeftRight To Left

Css Customization​

Every overridable variable set on one wrapper -- the variables are listed under CSS variables on this page.

The first slider shows every variable. The second is disabled, to show that the theme does not swap in its own colors there: it mixes the disabled thumb and fill from --slider-handle-color, so a custom accent survives as a paler version of itself.

Css CustomizationCss Customization

Minimal example​

The input is controlled: hold the value yourself and move it from onChange.

import { useState } from "react";
import { Slider } from "@onlyoffice/apps-ui-kit/components/slider";

export function Quality() {
const [quality, setQuality] = useState(70);

return (
<label>
Quality: {quality}%
<Slider
min={0}
max={100}
step={5}
value={quality}
withPouring
onChange={(event) => setQuality(Number(event.target.value))}
/>
</label>
);
}

Props​

PropertyTypeDescription
maxnumberHighest value of the range.
minnumberLowest value of the range.
valuenumberThe current value. This is a controlled input; it does not keep its own.
className?stringApplied to the input.
dataTestId?stringdata-testid of the input. Default: "slider".
id?stringApplied to the input.
isDisabled?booleanWhether the input is disabled, which also greys the handle. Default: false.
onChange?(e: React.ChangeEvent<HTMLInputElement>) => voidCalled on every move of the handle, with the range input's change event — event.target.value is a string. Required in practice: the input is controlled, so without this the handle cannot move.
runnableTrackHeight?stringHeight of the track the handle runs along, as a CSS length.
step?numberHow far one step of the handle moves.
style?CSSPropertiesApplied to the input.
thumbBorderWidth?stringBorder width of the drag handle, as a CSS length.
thumbHeight?stringHeight of the drag handle, as a CSS length.
thumbWidth?stringWidth of the drag handle, as a CSS length.
withPouring?booleanFills the track to the left of the handle. The fill is computed from value, min and max, and flipped for a right-to-left interface.

Recipes​

Disabled / read-only​

There is no read-only state — a range input that may be seen but not moved has to be disabled, which also greys the handle.

import { Slider } from "@onlyoffice/apps-ui-kit/components/slider";

export function LockedQuality({ quality }: { quality: number }) {
return (
<Slider
min={0}
max={100}
value={quality}
withPouring
isDisabled
onChange={() => {}}
/>
);
}

Behaviour the types don't state​

  • onChange is optional in the type and required in practice. value is passed straight to a controlled <input>, so leaving the handler out freezes the handle and React warns about a form field with a value and no onChange.
  • The value arrives as a string. It is a DOM change event, so event.target.value needs Number(...) before it goes back into state.
  • It is 100% wide and brings its own vertical margin. The input fills its container, has no width prop, and carries margin: 24px 0 so that the handle has room to overhang the track — which adds to a column gap rather than collapsing into it.
  • withPouring is computed, not native. The filled part is a background sized from (value - min) / (max - min), so a min equal to max divides by zero and the fill comes out as NaN% — nothing is drawn.
  • The text direction is read once, on mount. Whether the fill starts from the left or the right is decided by an effect with no dependencies — it pours from the right when document.dir, the <html> element's dir or the input's own computed direction is right-to-left at that moment. Switching the interface to right-to-left after mount leaves the fill on the wrong side until the component remounts; the stylesheet's data-dir rule cannot correct it, because the inline position wins.
  • The size props are custom properties, not attributes. thumbWidth, thumbHeight, thumbBorderWidth and runnableTrackHeight are written into the inline style as --thumb-* and --runnable-track-height, so they take CSS lengths ("16px"), not numbers.
  • style is spread before those properties, so it cannot override them.
  • There is no label, no tick marks and no value readout; all three are yours to add.

CSS variables​

VariableDefaultEffect
--slider-size8pxHeight of the track
--slider-handle-size24pxWidth and height of the handle
--slider-track-radius5.6pxCorner radius of the track; the handle keeps its own
--slider-handle-colorthemeFill of the handle, and the colour the focus ring is mixed from
--slider-background-colorthemeBackground of the unfilled track
--slider-pouring-imagethemeFill of the poured part, used only with withPouring

--slider-pouring-image is a background-image, so it takes a linear-gradient(...) or another <image>, not a plain colour; and it is used only while the slider is enabled. A disabled slider does not switch to theme colours: its handle and its poured part are mixed from --slider-handle-color, so a custom accent survives as a paler version of itself.

--thumb-width, --thumb-height, --thumb-border-width, --runnable-track-height and --size-prop are written inline by the props and beat all of the above; set the props rather than these.

Accessibility​

  • A native <input type="range">, so it is focusable, is moved one step with the arrow keys and in larger jumps with Page Up and Page Down, goes to min and max with Home and End, and reports its value, minimum and maximum to assistive technology by itself.
  • It has no accessible name. Wrap it in a <label>, or give it an id and point a <label htmlFor> at it, or a screen reader announces only "slider". aria-label cannot be passed: the props are not spread onto the input.
  • The value is announced as a bare number, and aria-valuetext cannot be passed either; where the number means something else — a percentage, a duration — show it in the label.
  • isDisabled sets the native disabled, which blocks dragging and the keyboard and takes the slider out of the tab order.
  • Keyboard focus is shown as a 3px halo around the handle, drawn on :focus-visible only and mixed from the handle's own colour. The browser's outline is turned off, so a browser that does not support :focus-visible shows nothing.

Test ids​

Elementdata-testid
The inputslider, or dataTestId