SliderBar draws a value between minimumValue and maximumValue as a filled portion of a pill-shaped track. By default it is display-only: it reports role="progressbar", takes no focus, and handles no keys. Passing onChange opts it into an interactive mode where it becomes a real role="slider" with a tab stop and arrow-key adjustment.showSlider; for a compact adjustable control prefer IsolatedControl; for read-only progress prefer ProgressIndicator. Reach for SliderBar directly when you need a bare bar and already own the surrounding label and layout.import { SliderBar, SliderBarSize } from '@wearables-ui-toolkit/mrbd';
<SliderBar
value={bytesDownloaded}
maximumValue={bytesTotal}
size={SliderBarSize.THIN}
animated
aria-label="Download progress"
/>;
import { useState } from 'react';
import { SliderBar, SliderBarState } from '@wearables-ui-toolkit/mrbd';
export function BrightnessBar() {
const [level, setLevel] = useState(0.5);
const [isFocused, setIsFocused] = useState(false);
return (
<SliderBar
value={level}
onChange={setLevel}
incrementPercentage={0.05}
state={isFocused ? SliderBarState.FOCUSED : SliderBarState.IDLE}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
animated
aria-label="Brightness"
/>
);
}
.brightness-row {
display: flex;
align-items: center;
gap: var(--uit-spacing-medium);
padding-inline: var(--uit-spacing-large);
}
.brightness-row .bar {
flex: 1 1 auto;
}
import { SliderBar, SliderBarOrientation } from '@wearables-ui-toolkit/mrbd';
<div className="level-column">
<SliderBar
value={level}
orientation={SliderBarOrientation.VERTICAL}
aria-label="Level"
/>
</div>;
SliderBarProps.| Prop | Type | Default | Description |
|---|---|---|---|
minimumValue | number | 0 | Lower bound of the range. |
maximumValue | number | 1 | Upper bound of the range. |
value | number | 0 | Current value, clamped into the range before rendering and before it is announced. |
state | SliderBarState | SliderBarState.IDLE | Visual state. Drives the fill colour and, with the default size, the expanded thickness. The component does not derive this from focus; you set it. |
size | SliderBarSize | SliderBarSize.DEFAULT | Thickness variant. DEFAULT expands when focused, THIN stays constant. |
orientation | SliderBarOrientation | SliderBarOrientation.HORIZONTAL | Fill direction: left to right, or bottom to top when vertical. |
shouldExpandOnFocus | boolean | true | Whether the FOCUSED state thickens the track. Ignored by THIN. |
animated | boolean | false | Whether the fill, the focus thickening, and the colour change transition smoothly instead of snapping. |
onChange | (newValue: number) => void | — | Enables interactive mode. Called with the next value on each arrow key press; the parent must apply it to value. |
incrementPercentage | number | 0.1 | Step per key press, as a fraction of maximumValue minus minimumValue. |
disabled | boolean | false | Turns interactive mode back off and marks the element as disabled. |
SliderBarProps also accepts the standard div attribute surface — className, style, aria-label, data-* (including data-uit-*), and DOM event handlers such as onFocus and onBlur — which is spread onto the root element. There is no onChange DOM handler slot: the onChange above replaces it.role, tabIndex, aria-valuenow, aria-valuemin, aria-valuemax, aria-valuetext, aria-disabled, and aria-hidden are applied after the rest props and cannot be overridden. aria-label is honoured when you supply one. onKeyDown behaves differently again: in interactive mode a handler you pass takes the place of the built-in arrow stepping, so the bar stops responding to Left and Right; in display-only mode it is dropped and never attached.SliderBarStateIDLE — resting thickness and the idle fill colour (--uit-color-control-idle).FOCUSED — the active fill colour (--uit-color-control-active), and expanded thickness with the default size.SliderBarSizeDEFAULT — expands on the cross axis in the focused state.THIN — constant compact thickness in both states.SliderBarOrientationHORIZONTAL — the bar spans the full width of its parent, the fill grows from the left edge, and thickness is the height.VERTICAL — the bar stretches to the parent’s height, the fill grows from the bottom, and thickness is the width.value is clamped into the range before it is drawn and before it is announced, so an out-of-range value never overflows the track.minimumValue and maximumValue are equal the bar renders completely filled rather than dividing by zero.onChange, the bar reports role="progressbar", has no tab stop, and ignores all keys.onChange and not disabled, the bar reports role="slider", becomes a tab stop, and consumes ArrowLeft and ArrowRight. Right increments, Left decrements, each by incrementPercentage of the range, clamped to the bounds. Held keys repeat, which accelerates naturally. Up and Down are deliberately left alone so vertical focus navigation still works.orientation is VERTICAL. Only the drawing axis changes.value. It calls onChange with the next value and re-renders from the prop.disabled turns interactive mode off entirely: the role falls back to progressbar, the tab stop is removed, keys are ignored, and aria-disabled is set. There is no dimmed visual treatment.--uit-color-background-track. The fill uses --uit-color-control-idle in the idle state and --uit-color-control-active in the focused state.animated transitions the fill along the value axis, and the colour and thickness across state changes. The thickness transition is limited to IDLE and FOCUSED changes: the mount render snaps, and a change to size, orientation, or shouldExpandOnFocus snaps rather than tweening so a layout change never looks like a value change.usePrefersReducedMotion and leave animated off when the user has asked for less motion; every change then snaps.role="slider" with aria-valuemin, aria-valuemax, aria-valuenow (the clamped raw value) and aria-valuetext (the value as a rounded percentage of the range).role="progressbar" with the same range attributes.aria-orientation, and unlike the role and value attributes it does not overwrite one you pass. Supply aria-orientation="vertical" on a vertical bar so the axis is announced.aria-label defaults to the percentage, which is not a name. Always pass a descriptive aria-label unless a parent component supplies the accessible name.state={SliderBarState.FOCUSED} gives no visible focus feedback. Drive state from onFocus and onBlur, as in the example above.aria-label and keep value in application state.THIN for dense or secondary contexts and the default size where the bar is the focus target.ListItem with showSlider or IsolatedControl for a production adjustment interface, so label, focus, value, and stepping come as one pattern.onKeyDown; interactive mode already consumes Left and Right, and your handler would take the place of that stepping.SliderBar where media time semantics matter — use Scrubber.