Skip to content

Rollout Ruler

Set a feature’s rollout stage and show when a kill switch rolls it back.

import { RolloutRuler, RolloutStage } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use a rollout ruler to show and set how far a feature has rolled out: internal, beta, 10%, 50%, GA. The track is cut into its stages, each an equal stretch, so the early cohorts get as much room as the late ones; the axis under it says what each gate is worth. For a free percentage, use a Slider.

import { RolloutRuler } from '@youj/react'

const [share, setShare] = useState(10)

<RolloutRuler label="Rolled out to" value={share} onValueChange={setShare} />

value is the share of users, 0–100, and while it's interactive it's always a stage's value (or 0). The default stages are Internal 1%, Beta 5%, 10%, 50% and GA 100%; pass stages for your own, in any order:

<RolloutRuler
  stages={[
    { value: 0.5, label: 'Canary' },
    { value: 2, label: 'Staff' },
    { value: 25, label: '25%' },
    { value: 100, label: 'All' },
  ]}
/>

Ticks already rolled out light in tone (the accent), the stretch to the next gate is a runway at a third of it, and the gate the value sits on names itself in the tone. A kill switch is a change from outside: set value to 0 (with tone="danger") and the ruler sweeps back tick by tick.

Reference

Propsvalue, defaultValue, onValueChange… (12)

Props

RolloutRuler props
PropType
valuenumber

The share rolled out, 0–100. Interactive, it's always a stage's value (or 0).

–
defaultValuenumber

default 0

0
onValueChange(value: number) => void–
onValueCommitted(value: number) => void

Called once a drag or key press ends, with the final value.

–
stagesreadonly RolloutStage[]

The gates, in any order. Default: Internal 1%, Beta 5%, 10%, 50% and GA 100%.

–
readOnlyboolean

A meter to read, without a playhead to move.

default false

false
disabledboolean

default false

false
size'default' | 'sm'

sm: the bare track, no header, names or axis, for a list row.

default 'default'

'default'
toneRolloutTone
'accent''success''warning''danger''neutral'

The lit ticks.

default 'accent'

'accent'
labelstring

The visible name over the track, and its accessible name. Default: the labels' "Rollout".

–
ticksnumber

Minor intervals per stage. Default 10, or 5 at sm.

–
localestring

Default: the YoujProvider locale.

–
Other props pass through: extends ComponentProps<'div'>.
MotionA step you take, A change from outside, reveal · reduced motion

Motion

Motion tokens
MomentTokens
A step you takedrag, a press on the ruler or a key: the playhead snaps to the gate
spring.snappy

0.2s, bounce 0

0.2s, bounce 0
A change from outsidea kill switch or a schedule: the ticks light or go dark one after another at a constant rate, the playhead riding the front
duration.deliberateease.linear

560ms · cubic-bezier(0, 0, 1, 1)

560mscubic-bezier(0, 0, 1, 1)
Revealit sweeps up from zero as it scrolls into view
duration.deliberateease.linear

560ms · cubic-bezier(0, 0, 1, 1)

560mscubic-bezier(0, 0, 1, 1)

Reduced motion

Drawn at its value; changes jump.

Reduced motion

The ruler is drawn at its value, and changes jump without the sweep.

AccessibilityKeyboard

Accessibility

  • Interactive, it's a slider over the stages, named by label (or the labels' "Rollout"). Its value is spoken with the stage's name: "Beta at 5%", "50%", "Off".
  • The arrow keys and Page keys step one gate; Home and End go to off and the last stage. A press anywhere on the ruler moves to the nearest gate.
  • readOnly and size="sm" are meters with the same spoken value.
  • Its built-in text (the default stage names, "Off") comes from the labels, so <YoujProvider labels> translates it.