Skip to content
weftGitHub

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_000

Installation

npm install @weft-js/warp

Usage

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_000

Disabled

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_000

Autoscale 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 = 42

When to use

Use it for

  • A value in a known range where the feel matters more than the digit

Reach for something else

Playground

Min1
Max12
Step1
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 slider role and is named by the label.
  • People who can't drag can tap the track or use the keys.

API Reference

PropTypeDefaultDescription
labelstring—Its accessible name. Fields show it; icon-only controls speak it.
valueV—One number, or two for a range.
minnumber0The lowest allowed value.
maxnumber100The highest allowed value.
stepnumber1How far one key press moves it.
format((v: number) => string)StringTurns the number into the text shown and read out.
names[string, string]—What each thumb of a range means, for screen readers.
disabledbooleanfalseTurns it off, and takes it out of the tab order.
namestring—Posts with a form: one entry per thumb.
EventTypeDefaultDescription
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