Slider
A number picked along a track, continuous or stepped, on either axis.
import { Slider } from "@glint/components/slider.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
in-out property <float> volume: 65;
VerticalLayout { alignment: center; spacing: 16px; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 320px;
Slider { minimum: 0; maximum: 100; value <=> root.volume; } } }
Text { text: "Volume: " + Math.round(root.volume) + "%"; color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } }}Usage
import { Slider } from "@glint/components/slider.slint";
export component AppWindow inherits Window { in-out property <float> brightness: 80;
VerticalLayout { alignment: center;
Slider { minimum: 0; maximum: 100; step: 5; value <=> root.brightness; changed(val) => { // handle adjustment } } }}Slider enables users to select a single numeric value from a bounded range by dragging the thumb, clicking the track, or using arrow keys.
Examples
Orientations
The orientation property sets the slider axis:
SliderOrientation.horizontal: Horizontal track filling left-to-right (default).SliderOrientation.vertical: Vertical track filling bottom-to-top (up increases value).
import { Slider, SliderOrientation } from "@glint/components/slider.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
in-out property <float> horizontal-val: 40; in-out property <float> vertical-val: 75;
VerticalLayout { alignment: center; spacing: 20px; padding: 24px;
HorizontalLayout { alignment: center; spacing: 48px;
VerticalLayout { alignment: center; width: 240px; spacing: 12px;
Slider { orientation: SliderOrientation.horizontal; value <=> root.horizontal-val; }
Text { text: "Horizontal: " + Math.round(root.horizontal-val); color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } }
VerticalLayout { alignment: center; spacing: 12px;
Slider { orientation: SliderOrientation.vertical; value <=> root.vertical-val; }
Text { text: "Vertical: " + Math.round(root.vertical-val); color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } } } }}Discrete stepping
Set step to define snapping increments (such as step: 25). Setting step: 0 enables smooth continuous sliding.
import { Slider } from "@glint/components/slider.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
in-out property <float> step-val: 50;
VerticalLayout { alignment: center; spacing: 16px; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 320px;
Slider { minimum: 0; maximum: 100; step: 25; value <=> root.step-val; } } }
Text { text: "Step value: " + Math.round(root.step-val); color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } }}Disabled state
Setting disabled: true dims the track and thumb and blocks interactions.
import { Slider } from "@glint/components/slider.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 300px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
VerticalLayout { width: 320px;
Slider { disabled: true; value: 45; } } } }}API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
value | in-out float | 0 | Two-way; current value snapped to step and clamped to minimum..maximum — see step for the one value that isn't. |
minimum | in float | 0 | Lower bound (inclusive). |
maximum | in float | 100 | Upper bound (inclusive). |
step | in float | 1 | The grid every user-driven value lands on, counted from minimum: the pointer snaps to it exactly as the keyboard does, so a stepped slider cannot be dragged into a value its consumer never allowed. 0 turns snapping off — the continuous slider HTML spells step="any". A value the *consumer* binds is left alone, off-grid or not, the way SpinBox leaves an out-of-range binding alone. |
disabled | in bool | false | When true, the thumb dims and stops responding. |
orientation | in SliderOrientation | SliderOrientation.horizontal | Which way the slider runs. Horizontal fills left-to-right; vertical fills bottom-to-top, so up is more. |
focus-visible | out bool | no default | Whether this control holds the keyboard *and* got it from the keyboard — the focus-visible a hover surface opens on. Published because Slint reports focus only to the element holding it, so a Tooltip wrapping this control cannot read it off the scope inside (tooltip.slint). |
focus-held | out bool | no default | The same focus, still true while a popup has borrowed the window's — what a hover surface opened by this control has to gate on, since showing itself is what takes focus-visible away. See Tooltip. |
Callbacks
| Callback | Description |
|---|---|
changed(float) | Fired with the new value while dragging. |
Functions
| Function | Description |
|---|---|
increment() | Adds one nudge, bounded by maximum and landing on the grid. |
decrement() | Removes one nudge, bounded by minimum and landing on the grid. |
focus-from-keyboard() | Hand the control the keyboard the way a key press does, ring and all. A host that moves the focus onto a control because the user pressed something — Questionnaire stepping to the next question — cannot use focus(): Slint reports that as programmatic, which is how a host parking the keyboard looks, and the scope drops the ring for it. Published by every control that publishes focus-visible, for the same reason: the scope inside cannot be reached from outside the component. |
Enums
| Enum | Values |
|---|---|
SliderOrientation | horizontal, vertical |
SliderGrid
The value arithmetic both sliders share, in a global so RangeSlider uses this one rather than re-deriving it. Both functions are pure and take the range they work in, so neither needs a component to live on — reach for them when you are computing a snapped value outside a slider.
Functions
| Function | Description |
|---|---|
snapped(v: float, minimum: float, step: float) -> float | Rounds to the nearest point of the grid, counted from minimum so the grid starts where the range does. Always measured from minimum rather than accumulated, so a fractional step cannot drift over a long drag or a held key. |
nudge(minimum: float, maximum: float, step: float) -> float | What one arrow key, or one accessible increment/decrement, moves by. That is step — except on a continuous slider, where the keyboard still has to move by *something*: a hundredth of the range, roughly the granularity the pointer has anyway. |
Accessibility
- Slider role. Publishes
accessible-role: sliderwithaccessible-value,accessible-value-minimum, andaccessible-value-maximum. - Keyboard navigation. ←/↓ decreases value, →/↑ increases value, Home jumps to minimum, and End jumps to maximum.
- Focus ring. Displays a 2px outer focus ring when keyboard focus is active.