Skip to content

Slider

Slider renders a horizontal or vertical range slider. It supports keyboard navigation, mouse interaction, and change callbacks.

import { Slider, SliderEvents, createCliRenderer } from '@bettertui/core';
const renderer = await createCliRenderer({ exitOnCtrlC: true });
const slider = new Slider(renderer, {
orientation: 'horizontal',
width: 40,
height: 1,
min: 0,
max: 100,
value: 50,
step: 5,
trackColor: '#333333',
thumbColor: '#7aa2f7',
activeTrackColor: '#364A82',
});
slider.on(SliderEvents.CHANGE, (value: number) => {
console.log('Value:', value);
});
renderer.root.add(slider);
slider.focus();
renderer.start();
new Slider(renderer: CliRenderer, options?: SliderOptions)

SliderOptions extends BoxOptions with:

Prop Type Default Description
orientation 'horizontal' | 'vertical' 'horizontal' Slider direction
min number 0 Minimum value
max number 100 Maximum value
value number 0 Initial value
step number 1 Increment / decrement step
viewPortSize number 1 Thumb size as a fraction of range
trackColor string '#333333' Empty track color
thumbColor string '#0088ff' Thumb / handle color
activeTrackColor string '#0055cc' Filled track color
slider.value // Get / set current value (clamped to min..max)
slider.min // Get / set minimum
slider.max // Get / set maximum
slider.step // Get / set step
Event Payload When
SliderEvents.CHANGE number Value changes
RenderableEvents.FOCUSED — Slider gains focus
RenderableEvents.BLURRED — Slider loses focus
Key Action
← Decrease by step
→ Increase by step
Home Jump to min
End Jump to max
Key Action
↑ Increase by step
↓ Decrease by step
Home Jump to min
End Jump to max
import { Box, Text, Slider, SliderEvents, t, fg, bold, createCliRenderer } from '@bettertui/core';
const renderer = await createCliRenderer({ exitOnCtrlC: true });
const container = new Box(renderer, {
flexDirection: 'column',
padding: 1,
gap: 1,
});
const label = new Text(renderer, { content: 'Volume: 50', fg: '#c0caf5' });
const vol = new Slider(renderer, {
width: 40,
height: 1,
min: 0,
max: 100,
value: 50,
step: 1,
thumbColor: '#7aa2f7',
activeTrackColor: '#364A82',
});
vol.on(SliderEvents.CHANGE, (v) => {
label.content = `Volume: ${v}`;
});
container.add(label);
container.add(vol);
renderer.root.add(container);
vol.focus();
renderer.start();
const vSlider = new Slider(renderer, {
orientation: 'vertical',
width: 1,
height: 20,
min: 0,
max: 100,
value: 30,
step: 5,
thumbColor: '#9ece6a',
activeTrackColor: '#41a6b5',
});
renderer.root.add(vSlider);
vSlider.focus();
const form = new Box(renderer, { flexDirection: 'column', gap: 2, padding: 1 });
for (const [label, initVal] of [['Brightness', 80], ['Contrast', 50], ['Saturation', 60]] as const) {
const row = new Box(renderer, { flexDirection: 'row', gap: 2, alignItems: 'center' });
row.add(new Text(renderer, { content: label, width: 12, fg: '#a9b1d6' }));
row.add(new Slider(renderer, { width: 30, height: 1, value: initVal }));
form.add(row);
}
renderer.root.add(form);