Step player

An iOS-style stepped progress track with a play, pause and replay control. The active step stretches into a bar that fills as it plays.

Dependencies

motionflubber

Interaction Type

Press play to start the sequence. The current step stretches into a bar and fills as it runs, then shrinks to a filled dot when it hands off to the next one. Press again to pause mid-fill; the play icon splits into the pause bars as it goes. At the end it fades into a replay arrow. Steps can be clicked to jump.

Props

Options you can pass to customize this component.

Prop
Type
Description
steps
numberStepPlayerStep[]

How many steps to show. Pass an array to give each one its own duration or label.

value
number

Active step index, for controlled use. Leave it out and the component tracks its own index.

defaultValue
number

Step to start on when uncontrolled. Clamped to the last step.

onValueChange
(value: number) => void

Fires when the step advances, wraps, or is clicked. Also fires on replay.

playing
boolean

Play state, for controlled use. Leave it out to let the button drive it.

defaultPlaying
boolean

Whether the sequence starts running on mount when uncontrolled.

onPlayingChange
(playing: boolean) => void

Fires when the button is pressed, and when the last step ends without loop.

duration
number

Milliseconds each step runs for. A per-step duration overrides it; 0 stops the timer so you can drive the index yourself.

loop
boolean

Wraps back to the first step instead of stopping. The replay button never appears when this is on.

onComplete
() => void

Fires when the last step finishes, on every pass when looping.

size
number

Height of the track and button in pixels. Every other dimension is a fixed ratio of it, so the dots, bar, gaps, padding, icon, and tap targets all scale from this one number.

showControl
boolean

Shows the round play button. Turn it off for a track on its own and drive it with the playing prop.

controlPosition
leftright

Which side of the track the button sits on.

seekable
boolean

Lets a step be clicked to jump to it. The dots keep a finger-sized tap target at every size.

className
string

Extra classes merged onto the root element. It sizes itself from the size prop, so give it a width only if you want the track wider than its content.

Installation

npx shadcn@latest add swamimalode07/rare-ui/step-player

How to use

import { StepPlayer } from "@/components/ui/step-player"
export function Demo() {
return <StepPlayer steps={5} duration={3000} />
}
// drive your own carousel off the index
<StepPlayer
steps={slides.length}
value={index}
onValueChange={setIndex}
loop
/>

Source Code

Click the code icon in the top-right corner to view the source code.

Keep in mind

Most components here are recreations of great work from around the web. I don't claim to be the original creator - this is my attempt to reverse-engineer, replicate, and often add a few extra features. I've tried to credit everyone; if I missed someone, let me know.

Contact

Found a bug or issue? Feel free to drop a DM.

License & Usage

  • Free to use and modify in both personal and commercial projects.
  • Attribution to Rare UI is appreciated when using a component.
  • Please don't resell the components as your own kit.
Step player

Step 1 of 5