Update Slider
A miniature gradient-descent playground on a 1-D number line. The learner taps Step and watches a parameter m slide toward the optimum m*, with a learning-rate slider exposing the trade-off between tiny progress and runaway overshoot. The dot, status text, and ledger row all repaint together as m approaches the target — green when close, yellow when nearby, red when far.
Each step is m_new = m − lr × 2(m − m*). Whenever a step crosses the optimum, the component flashes an Overshoot! warning — the visceral "I picked too big a learning rate" moment.
m_new = 1.00 − 0.10 × grad → 1.00
Click Step to nudge the parameter toward the optimum.
Installation
npx shadcn@latest add https://craftbits.dev/r/update-slider.jsonUsage
import { UpdateSlider } from "@craft-bits/viz/update-slider";
<UpdateSlider />Start with an aggressive learning rate so the visitor sees an overshoot on the first tap:
<UpdateSlider defaultLearningRate={1.1} />Re-target the optimum and the parameter range for a different setup:
<UpdateSlider min={-5} max={5} optimum={-1.2} defaultValue={3} />Subscribe to step events for an external loss-vs-step chart:
<UpdateSlider
onStep={({ value, learningRate, step }) => {
/* push (step, value, learningRate) into a logger */
}}
/>Understanding the component
- Number line. A 520px-wide rule from
mintomaxis rendered in the muted border tone. A short vertical tick atoptimumis labelledoptimalin green so the target is unambiguous at any size. - Trail. Every visited position is plotted as a small dot. Older ghosts fade toward transparent so the eye reads the trajectory at a glance — the most recent
trailSize(default20) positions are kept on screen. - Current marker. A 16-px dot at
msprings to its new position via thetransitionprop (defaultSPRINGS.snap). The marker has a 2-px ring in the canvas colour so it lifts clearly over the trail dots. - Status colour. Distance to the optimum is bucketed into three bands —
< 0.1isclose,< 1isnear, otherwisefar. The bigm =readout, the dot, and the data-attributedata-statuson the root all reflect the same band. - Overshoot detector. Whenever a step crosses the optimum, the component flashes
Overshoot! m flew past the optimumunder the readout. - Learning-rate slider. A native
<input type="range">clamps to[0.01, 1.5]with a0.01step. The slider uses the canvas accent colour so it follows the theme. - Ledger row. Below the controls the literal arithmetic prints —
m_new = previous − lr × grad → next. This makes the math live for the learner instead of hiding it behind animation.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
min | number | -2 | Lower bound of the parameter line. |
max | number | 5 | Upper bound of the parameter line. |
optimum | number | 2.67 | Target the parameter is descending toward. |
defaultValue | number | 1 | Initial parameter value. Reset returns here. |
defaultLearningRate | number | 0.1 | Initial slider value. Clamped to [0.01, 1.5]. |
trailSize | number | 20 | Max number of trailing positions kept on screen. |
transition | Transition | SPRINGS.snap | Override the marker animation transition. |
onStep | (args) => void | — | Fires after each step with value, learningRate, step. |
onReset | () => void | — | Fires when the user clicks Reset. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The learning-rate
<input type="range">is labelled viaaria-labelledbyand announces its value througharia-valuetext(e.g.Learning rate 0.10). - The big
m =readout hasaria-live="polite"on its container so step results announce naturally; the slider drags themselves are not announced repeatedly. - The Step and Reset buttons have visible
focus-visiblerings. Reset only appears after the first step. - Colour is never the only signal — the
data-statusattribute on the root reflects the same band the colour does, the literal arithmetic ledger row prints the post-step value, and overshoots produce a textual warning. - The first render does not animate (via
AnimatePresencewithinitial={false}), matching the library's reduced-motion policy.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/viz/UpdateSlider.tsx). The source consumed the lesson palette (--color-accent-500,--color-success-500,--color-warn-500,--color-fail-500,--color-ink-*) and inlined a one-offSPRINGS.snappyspring. The viz extract drops the lesson tokens for thevar(--cb-*)semantic system so consumer themes repaint freely, swaps the spring for the canonicalSPRINGS.snap, and exposes the previously hard-codedmin/max/optimum/defaultValue/trailSize/transitionas props so the playground generalises beyond the one curriculum scenario.