# Slider A value chosen along a range. - Group: Forms - Import: `import { Slider } from '@misoto22/folio'` - Page: https://ui.misoto22.com/components/slider/ - Related: progress ## Anatomy - **Track** (required) — A 1px rule in --stone that thickens to 1.5 when the pointer is anywhere over the control, not only over the thumb. - **Range** — The --accent fill from the minimum to the thumb, or between the two thumbs of a range. - **Thumb** — One per entry in the value array — so the number of thumbs comes from the value, not from a prop, and a slider given neither value nor defaultValue falls back to the primitive’s own default of one thumb at the minimum. Each is a 16px circle with an invisible 44px hit area from a before pseudo-element. - **Value readout** — Only with showValue: a mono row above the track, the names on the start edge and the formatted values on the end, each joined by an en dash and in the thumbs’ own order — so a two-ended range reads “Minimum – Maximum” over “10 – 90”. - **Editable readout** — What editable turns those figures into: one box per thumb, showing format’s output at rest and the bare number while it has focus, so a reader still sees “$1,200” and a typist is never asked to type a currency symbol back. Each is named separately from its thumb — two controls announcing “Quality” is one control announced twice. ## Best practices ### Do - Pass defaultValue or value whenever there is more than one end to it. The thumb count comes from that array, so a price filter left to the default is a single thumb sitting at the minimum. - Pass an array of two names for a two-thumb range: every thumb after the first falls back to names[0], so both ends of a price filter otherwise announce themselves as “Minimum”. - Turn on editable when the exact number matters. A slider on its own cannot be typed into, and someone who needs 37 rather than roughly 40 is dragging a 16px thumb across a hundred steps to get it — the box in the readout is the way out, and it replaces the second Input this used to ask for. ### Don’t - format becomes each thumb’s aria-valuetext, which REPLACES the number rather than decorating it — so a formatter that rounds hard or drops the unit is what a screen reader gets instead of the value. - editable typing is bounded by the NEIGHBOURING thumb as well as by min and max, and it has to be: 90 typed into the lower end of a range sitting at 70 would otherwise cross the two thumbs over. So a number can be accepted and then land somewhere else, and the box shows where it landed. - Do not disable a slider to make it read-only: the whole control dims and stops taking the pointer, and Radix drops the thumb out of the tab order, so the value becomes unreachable rather than uneditable. - Do not pass two names to a one-thumb slider: the heading prints one name per THUMB, so the second is drawn nowhere and announced nowhere. - A Field’s label above it does not name it and does not click through: the role is on the THUMB and the root is a , so the label prop here is the only name a reader hears. The hint and the error do reach the thumb. ## Accessibility - label is required. A thumb that announces "42" and nothing else leaves a screen reader user with a number and no idea what it measures. - A 44px hit area sits invisibly around the 16px thumb. - format is announced as aria-valuetext, so a thumb showing “$1,200” says that rather than 1200. - Arrows step, Page keys jump, Home and End reach the ends. ## Keyboard - ← / → — Moves by one step. - Page Up / Page Down — Moves by a larger step. - Home / End — Jumps to the minimum or maximum. ## Slider A value chosen along a range. Radix owns the keyboard contract — arrows step, Page keys jump, Home and End reach the ends — and the ARIA that reports the value. What is here is the look, and the labelling, which is the part a slider most often gets wrong: a thumb that announces "42" and nothing else leaves a screen reader user with a number and no idea what it measures. A 44px hit area sits invisibly around the 16px thumb, because a thumb sized for the design is well under any pointer-target guideline. `editable` is the answer to the thing a slider cannot do. Reach for it whenever the exact figure is the point — a budget, a timeout, a price — and leave it off when the value is genuinely approximate, because a box invites precision the setting may not have. Inside a `Field`, the hint, the error and the requirement land on the THUMB, which is the element carrying `role="slider"` — on the root they would sit on a `` with no role and announce nothing. The NAME still comes from `label` here: a field's label above a slider points at that same roleless root, so it neither names the control nor clicks through to it. ### Props - `label` (required) — `string | [string, string]`. Names the control. Required: a slider with no name announces only a number, and a number with no noun is not information. A range slider (two thumbs) needs one name per thumb — pass an array. - `showValue` — `boolean` default `false`. Prints the current value beside the label. A two-thumb range prints both names and both values, in the same order — the heading used to print the first name over a pair of numbers, which read as "Minimum" over "10 – 90". - `editable` — `boolean` default `false`. Turns that readout into a box the number can be typed into, and implies `showValue`. A slider is a control for a NEIGHBOURHOOD; someone who needs 1,150 rather than roughly 1,200 is dragging a 16px thumb across a hundred steps to get it. This is the way out, in the place the value already is, rather than a second field beside the track that has to be kept in step by hand. The box shows `format`'s output at rest and the bare number while it has focus, so a reader still sees "$1,200" and a typist is never asked to type a currency symbol back. - `format` — `(value: number) => string`. Renders the value with a unit or a currency, e.g. `(n) => n + '%'`. Reaches assistive tech as well as the readout: it becomes each thumb's `aria-valuetext`, so a thumb showing "$1,200" announces that rather than the bare number. Left off, the platform announces the value itself. Also accepts: `ComponentProps`. ## Example — default ```tsx import { Slider } from '@misoto22/folio'
`${n}%`} /> `$${n}`} />
``` ## Example — typing the exact value ```tsx import { Slider } from '@misoto22/folio'
`$${n}`} /> `$${n}`} />
``` ## Example — naming the unit ```tsx import { Slider } from '@misoto22/folio'
`${n}s`} />
```