Skip to content
Feeding a clanker? Grab this page as raw .md

Fader API#

Fader is a linear slider drawn to look like a channel fader on a mixing console: a cap slides along a slot, with a configurable tick scale (e.g. dB marks) alongside the track. It is vertical by default with max_value at the top; pass orientation="horizontal" for a left-to-right fader.

Ticks are configurable — ticks=N for evenly spaced marks, a list of values, or (value, label) pairs. Pass steps instead for a stepped fader that snaps to discrete detents. With midi=True the fader shows a "MIDI learn" button: click it, move a control on your hardware, and the next control-change message binds to the fader (Web MIDI, Chromium browsers). The binding is remembered in browser localStorage so it survives a restart.

See also: Knob for the rotary console version, and HoverSlider for a linear slider that also reports the value under the pointer.

Bases: AnyWidget

Mixing-console style fader: a cap that slides along a track.

A linear slider drawn to look like a channel fader, with a configurable tick scale (e.g. dB marks) alongside the track. Vertical by default, with max_value at the top; pass orientation="horizontal" for a left-to-right fader.

Examples:

import marimo as mo
from wigglystuff import Fader

level = mo.ui.anywidget(
    Fader(min_value=-60, max_value=6, value=0, ticks=[-60, -20, -6, 0, 6],
          label="Level")
)
level

Create a Fader.

Parameters:

Name Type Description Default
value Optional[float]

Initial value; defaults to min_value. Clamped to range.

None
min_value float

Lower bound of the value range (bottom / left).

0.0
max_value float

Upper bound of the value range (top / right).

100.0
step float

Snap increment in value units (must be > 0).

1.0
ticks TickSpec

Tick/scale marks. None for none, an int N for N evenly spaced ticks, a list of values, or a list of (value, label) pairs.

None
steps Optional[Sequence[Any]]

Discrete detents to snap to (a stepped fader). Same shape as ticks — numbers or (value, label) pairs. When given, min_value/max_value are derived from the steps, the detents double as the ticks, and dragging snaps to the nearest one. Mutually exclusive with ticks.

None
orientation str

"vertical" (default) or "horizontal".

'vertical'
length int

Track length in pixels (the long dimension).

200
label str

Optional text label shown above the fader.

''
show_value bool

Render the current value as text next to the fader.

True
color str

Optional CSS color for the filled track and cap. Empty string uses the theme default.

''
midi bool

Show a "MIDI learn" button. Click it, then move a control on your hardware; the next control-change (CC) message binds to this fader and drives its value. Uses the Web MIDI API (Chromium browsers, secure context). Read the binding back via midi_cc / midi_channel / midi_device.

False
midi_cc int

Bind a control-change number (0-127) up front instead of learning it. -1 (default) leaves it unbound.

-1
midi_channel int

MIDI channel (0-15) for the binding, or -1 for any.

-1
midi_key str

localStorage key for persisting the learned binding across restarts. Defaults to label. Empty (no label either) disables persistence.

''
midi_scope Optional[str]

Namespace for the persisted binding, so different notebooks don't collide. Empty (default) uses the browser's URL path automatically; pass an explicit string to pin it (or to intentionally share a mapping across notebooks).

None
**kwargs Any

Forwarded to anywidget.AnyWidget.

{}
Source code in wigglystuff/fader.py
def __init__(
    self,
    value: Optional[float] = None,
    min_value: float = 0.0,
    max_value: float = 100.0,
    step: float = 1.0,
    ticks: TickSpec = None,
    steps: Optional[Sequence[Any]] = None,
    orientation: str = "vertical",
    length: int = 200,
    label: str = "",
    show_value: bool = True,
    color: str = "",
    midi: bool = False,
    midi_cc: int = -1,
    midi_channel: int = -1,
    midi_key: str = "",
    midi_scope: Optional[str] = None,
    **kwargs: Any,
) -> None:
    """Create a Fader.

    Args:
        value: Initial value; defaults to ``min_value``. Clamped to range.
        min_value: Lower bound of the value range (bottom / left).
        max_value: Upper bound of the value range (top / right).
        step: Snap increment in value units (must be > 0).
        ticks: Tick/scale marks. ``None`` for none, an int ``N`` for ``N``
            evenly spaced ticks, a list of values, or a list of
            ``(value, label)`` pairs.
        steps: Discrete detents to snap to (a stepped fader). Same shape as
            ``ticks`` — numbers or ``(value, label)`` pairs. When given,
            ``min_value``/``max_value`` are derived from the steps, the
            detents double as the ticks, and dragging snaps to the nearest
            one. Mutually exclusive with ``ticks``.
        orientation: ``"vertical"`` (default) or ``"horizontal"``.
        length: Track length in pixels (the long dimension).
        label: Optional text label shown above the fader.
        show_value: Render the current value as text next to the fader.
        color: Optional CSS color for the filled track and cap. Empty
            string uses the theme default.
        midi: Show a "MIDI learn" button. Click it, then move a control on
            your hardware; the next control-change (CC) message binds to
            this fader and drives its value. Uses the Web MIDI API (Chromium
            browsers, secure context). Read the binding back via
            ``midi_cc`` / ``midi_channel`` / ``midi_device``.
        midi_cc: Bind a control-change number (0-127) up front instead of
            learning it. ``-1`` (default) leaves it unbound.
        midi_channel: MIDI channel (0-15) for the binding, or ``-1`` for any.
        midi_key: localStorage key for persisting the learned binding across
            restarts. Defaults to ``label``. Empty (no label either) disables
            persistence.
        midi_scope: Namespace for the persisted binding, so different
            notebooks don't collide. Empty (default) uses the browser's URL
            path automatically; pass an explicit string to pin it (or to
            intentionally share a mapping across notebooks).
        **kwargs: Forwarded to ``anywidget.AnyWidget``.
    """
    if midi_scope is None:
        midi_scope = ""
    if step <= 0:
        raise ValueError("step must be positive.")
    if orientation not in _ORIENTATIONS:
        raise ValueError(
            f"orientation must be one of {_ORIENTATIONS}, got {orientation!r}."
        )

    if steps is not None:
        if ticks is not None:
            raise ValueError("`ticks` is mutually exclusive with `steps`.")
        step_values = normalize_steps(steps)
        min_value, max_value = step_values[0], step_values[-1]
        tick_dicts = normalize_ticks(steps, min_value, max_value)
        if value is None:
            value = step_values[0]
        else:
            value = min(step_values, key=lambda s: abs(s - float(value)))
    else:
        step_values = []
        if min_value >= max_value:
            raise ValueError("min_value must be less than max_value.")
        tick_dicts = normalize_ticks(ticks, min_value, max_value)
        if value is None:
            value = min_value
        value = clamp(float(value), min_value, max_value)

    super().__init__(
        value=float(value),
        min_value=float(min_value),
        max_value=float(max_value),
        step=float(step),
        ticks=tick_dicts,
        steps=step_values,
        orientation=orientation,
        length=length,
        label=label,
        show_value=show_value,
        color=color,
        midi=midi,
        midi_cc=midi_cc,
        midi_channel=midi_channel,
        midi_key=midi_key,
        midi_scope=midi_scope,
        **kwargs,
    )

Synced traitlets#

Traitlet Type Notes
value float Current value, mapped along the track.
min_value float Lower bound (bottom / left).
max_value float Upper bound (top / right).
step float Snap increment in value units (continuous mode).
ticks list[dict] Normalized {"value", "label"} tick marks.
steps list[float] Discrete detents to snap to; empty means continuous.
orientation str "vertical" (default) or "horizontal".
length int Track length in pixels (the long dimension).
label str Optional text label shown above the fader.
show_value bool Render the current value as text next to the fader.
color str CSS color for the filled track and cap. Empty follows the theme.
midi bool Show the MIDI-learn button and listen for control-change.
midi_cc int Bound control-change number (0-127), or -1 when unbound.
midi_channel int Bound MIDI channel (0-15), or -1 for any.
midi_device str Name of the bound MIDI input device.
midi_supported bool Whether the browser exposes Web MIDI (set from JS).
midi_learning bool Whether the fader is currently in learn mode.
midi_key str localStorage key for the persisted binding (defaults to label).
midi_scope str Namespace for the binding; empty uses the browser URL path.