Slider
Pick a number or a range by dragging, when about right is good enough.
SourcePackage @weft-js/warpPlayground
Preview
tsx
import { state } from '@weft-js/core'import { Slider } from '@weft-js/warp'export function Basic() { const copies = state(3) return <Slider label="Copies" value={copies.value} min={1} max={8} onChange={v => (copies.value = v)} />}const min = 60_000Installation
npm install @weft-js/warpUsage
tsx
import { Slider } from '@weft-js/warp'Formatted value
format draws the number with its unit.
tsx
import { state } from '@weft-js/core'import { Slider } from '@weft-js/warp'export function Format() { const memory = state(4) return <Slider label="Memory" value={memory.value} min={1} max={32} format={gigabytes} onChange={v => (memory.value = v)} />}const min = 60_000const gigabytes = (v: number) => `${v} GB`Steps
Use step to snap the value to fixed jumps, here every 25.
tsx
import { state } from '@weft-js/core'import { Slider } from '@weft-js/warp'export function Step() { const rollout = state(25) return <Slider label="Rollout" value={rollout.value} step={25} format={percent} onChange={v => (rollout.value = v)} />}const percent = (v: number) => `${v}%`A range
Two numbers make two thumbs. names tells screen readers which is which.
tsx
import { state } from '@weft-js/core'import { Slider } from '@weft-js/warp'export function Range() { const copies = state<[number, number]>([2, 6]) return <Slider label="Copies" value={copies.value} min={1} max={12} names={['Fewest copies', 'Most copies']} onChange={v => (copies.value = v)} />}const min = 60_000Disabled
Use disabled to show a value that cannot be changed.
tsx
import { Slider } from '@weft-js/warp'export function Disabled() { return ( <Slider label="Copies" value={3} min={1} max={8} disabled onChange={() => {}} /> )}const min = 60_000Autoscale limits
Pass a pair of numbers as value for a range with a low and a high end, and names to label each end.
tsx
import { state } from '@weft-js/core'import { Row, Slider, Stack, Text } from '@weft-js/warp'export function Autoscale() { const copies = state<[number, number]>([2, 6]) return ( <Stack gap="group"> <Slider label="Keep between" value={copies.value} min={1} max={12} names={['Fewest copies', 'Most copies']} onChange={v => (copies.value = v)} /> <Stack gap="tight"> <Row justify="between"><Text subtle>When quiet</Text><Text>€{copies.value[0] * COPY_COST} a month</Text></Row> <Row justify="between"><Text subtle>At full load</Text><Text>€{copies.value[1] * COPY_COST} a month</Text></Row> </Stack> </Stack> )}const min = 60_000const COPY_COST = 42When to use
Use it for
- A value in a known range where the feel matters more than the digit
Reach for something else
- NumberField, when people need an exact number
- Segmented, when there are only a few fixed steps
Playground
Min
Max
Step
import { Slider } from '@weft-js/warp'<Slider value={v.value} onChange={next => (v.value = next)} label="Copies" min={1} max={12} />Accessibility
- ←→
- One step down or up
- PageUpPageDown
- A bigger step
- HomeEnd
- The minimum or maximum
- Each thumb has the
sliderrole and is named by the label. - People who can't drag can tap the track or use the keys.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Its accessible name. Fields show it; icon-only controls speak it. |
value | V | — | One number, or two for a range. |
min | number | 0 | The lowest allowed value. |
max | number | 100 | The highest allowed value. |
step | number | 1 | How far one key press moves it. |
format | ((v: number) => string) | String | Turns the number into the text shown and read out. |
names | [string, string] | — | What each thumb of a range means, for screen readers. |
disabled | boolean | false | Turns it off, and takes it out of the tab order. |
name | string | — | Posts with a form: one entry per thumb. |
| Event | Type | Default | Description |
|---|---|---|---|
onChange | (value: V) => void | — | Called with the new number or pair. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="range-head"] [data-part="track"]
trackrangethumb
RelatedNumber fieldSegmented