Slider

May 14, 2026 · View on GitHub

Horizontal integer range input — value clamped to [min, max] with arrow-key and mouse interaction.

Constructor: NewSlider(id, class string) *Slider

Defaults: min=0, max=100, value=0, step=1. The widget is focusable.

The renderer picks the visual style from the available content height:

  • Height 1 — compact one-row style: a heavy horizontal track () with a heavy vertical thumb ().
  • Height ≥ 2 — centred two-row rounded box (╭─╮/╰─╯) with a double-stem thumb (/) piercing both rows. Extra height becomes padding above and below.

Methods

  • Set(value int) — sets the current value (clamped, dispatches EvtChange when it actually changes)
  • Value() int — returns the current value
  • Min() int, Max() int, Step() int
  • SetMin(int), SetMax(int) — bounds setters; current value is reclamped
  • SetStep(int) — coarse step used by arrow keys (clamped to ≥ 1)
  • Summary() stringvalue=N [min..max] for Dump output

Keyboard

KeyAction
/ hDecrease by step (clamps at min)
/ lIncrease by step (clamps at max)
HomeJump to min
EndJump to max

Mouse

Left-click on the slider maps the click column to a value. In box style the inner track (excluding the rounded corners) is the mappable area, so corner clicks resolve to the nearest bound.

Events

EventDataDescription
"change"intValue changed (only when the value differs)

Set() is not silent — every value change fires EvtChange, whether it came from a keystroke, mouse click, or programmatic setter.

Theme strings

The glyphs for both styles are configurable per theme.

Compact (height 1)

KeyDefaultDescription
slider.compact.trackHorizontal track glyph
slider.compact.thumbVertical thumb glyph

Box (height ≥ 2)

KeyDefaultDescription
slider.box.top-leftTop-left corner of the box
slider.box.top-rightTop-right corner of the box
slider.box.bottom-leftBottom-left corner of the box
slider.box.bottom-rightBottom-right corner of the box
slider.box.horizontalHorizontal border line
slider.box.thumb-topThumb top half (joins top border)
slider.box.thumb-bottomThumb bottom half (joins bottom)

Override via theme.SetStrings(...) or by registering an alternate string set (AddUnicodeStrings, AddNerdStrings).

Style selectors

The slider has no part selectors — the entire widget (track, box border, and thumb) renders in a single state-resolved style. To make the slider visually "come alive" on focus, change the colours on the :focused selector, not on a thumb sub-part.

SelectorPurpose
sliderWhole widget when not focused
slider:disabledWhole widget when disabled
slider:focusedWhole widget when the widget has focus
slider:hoveredHover state

Notes

  • Flags: "focusable"
  • Default hint = (0, 1) — fills horizontally, one row by default. Place in a layout that grants height ≥ 2 to opt into the rounded box style.
  • Readonly or Disabled widgets ignore keyboard and mouse input.

Example

Builder API:

NewBuilder(themes.TokyoNight()).
    Slider("volume").
    On("change", func(_ core.Widget, _ core.Event, data ...any) bool {
        fmt.Println("volume:", data[0].(int))
        return true
    })

Composition API:

Slider("volume", "",
    Range(0, 11),
    Step(1),
    Value(7),
    On(z.EvtChange, func(_ c.Widget, _ z.Event, data ...any) bool {
        fmt.Println("volume:", data[0].(int))
        return true
    }),
)