Expand description
<switch> behavior: an on/off toggle rendered as a pill track with a
thumb that slides between the two ends, built on the same shared
Toggleable machinery as <checkbox>.
The markup parser spawns <switch> as a track element (tag switch,
carrying Toggleable + crate::controls::TrackStyle) with a single absolute-
positioned child - the .switch-thumb tile (carrying SwitchThumb).
Every visual is design-token / CSS reachable through the skins:
switch { width: 52; height: 28; bg: ...; } /* track (off) */
switch:checked { bg: var(--lumen-accent); } /* track (on) */
.switch-thumb { knob-color: ... } /* thumb fill */Behavior reuse - identical to <checkbox>, nothing bespoke:
- Click anywhere on the track (or the thumb) toggles -
crate::controls::flip_toggle_on_clickresolves a child hit to the ancestorToggleable. - Space / Enter on the focused switch toggles -
lumen_input::activate_focused_on_enter’s press-and-release FSM emits the sameClickEvent(mirrors SlintSwitchBase’skey-pressed: if event.text == " " || "\n" { toggle-checked() }and QtQAbstractButton’s space-bar activation). bind-checkedtwo-way signal binding comes withToggleable(apply_checked_bindings/push_toggle_to_signal) - mirrors Slint’sin-out property <bool> checkedtwo-way binding.disabledinserts the genericDisabledmarker; interaction is ejected bycrate::state_style::eject_interaction_on_disable.
What IS bespoke: the thumb slides between off and on with an implicit
animation driven by the shared transition primitive
(crate::transition::Transition) rather than snapping - mirroring
Slint’s animate ... x { duration: 75ms } on the switch handle and Qt
QML Switch’s Behavior on position { NumberAnimation }. The tween is
reactive: step_switch_thumb samples it and pings
AnimationsActive only while a slide is in flight, then retires the
component - no per-frame loop.
The slide’s duration + easing come from a transition: bg <duration> <easing> declaration on the track (see [slide_tween_params]) - the
same mechanism crate::hover uses for its hover / press tint tween -
falling back to SWITCH_SLIDE_MS / SWITCH_SLIDE_EASING when
none is authored. Track / thumb geometry (the inset gap and the
thumb’s diameter) come from crate::controls::KnobGeometry,
populated from the CSS knob-inset property, with the same
today’s-appearance fallback.
Accessibility: <switch> carries an explicit
lumen_core::components::A11yRole::Switch, so the a11y tree exposes
it as Role::Switch with the Toggled state derived from
Toggleable::checked - the Role::Switch analogue of how
<checkbox> surfaces Role::CheckBox.
Structs§
- Switch
Plugin - Plugin registering the switch visual-sync + thumb-slide systems.
- Switch
Thumb - Marker for the thumb child spawned inside every
<switch>. Absolute-positioned;sync_switch_visualsslides it between the two track ends, animating flips throughSwitchThumbSlide. - Switch
Thumb Slide - Active thumb-slide tween driving a
SwitchThumb’s horizontal inset. Reuses the sharedTransition<f32>primitive;step_switch_thumbsamples it and removes the component when the slide completes.
Constants§
- SWITCH_
SLIDE_ EASING - Fallback easing for the thumb slide, used under the same condition as
SWITCH_SLIDE_MS. Ease-out (fast start, gentle settle) is the Cocoa / Material short-transition curve; the same curve<checkbox>and the hover tints reach for. - SWITCH_
SLIDE_ MS - Fallback duration of the thumb slide when the switch flips, used when
the track carries no
transition: bg ...TransitionSpecs(see [slide_tween_params]). 140 ms sits between Slint’s 75 ms handle tween and the 200 ms Qt QMLSwitchdefault - long enough to read as motion, short enough to feel instant.
Functions§
- register_
switch_ systems - Register
sync_switch_visuals+step_switch_thumbinTickStage::Systems. Called by bothSwitchPluginandcrate::ControlsPlugin; system de-duplication makes a double install harmless. - step_
switch_ thumb - Advance every active
SwitchThumbSlide, writing the eased offset into the thumb’sStyle::inset.leftand marking it dirty so layout repositions it. PingsAnimationsActivewhile running so the loop keeps ticking without an unrelated OS event; snaps to the endpoint and retires the component when done (or immediately if the thumb is hidden - adisplay: nonesubtree runs no animation, matching the CSS transition drivers incrate::transition). - sync_
switch_ visuals - Place the
SwitchThumbchild: size + corner radius from the laid-out track height, and the horizontal inset toward the checked/unchecked end. The first placement snaps; a subsequentcheckedflip starts aSwitchThumbSlidefrom the thumb’s current position so it glides.