Pasito

A tiny, fully-themeable, and dependency-free fluid stepper component — for Svelte 5.

Vertical

Set orientation="vertical" and the stepper stacks top-to-bottom. Works well as a sidebar rail or alongside vertically-scrolling content.

yellow, red, green, and black abstract painting

Photo by Steve A Johnson on Unsplash

Autoplay

useAutoPlay drives timed step changes with a visible fill animation. Pause, resume, and loop are all built in.

Photo by National Gallery of Art on Unsplash

Themes

Every visual detail is controlled by CSS custom properties — colors, sizes, radii, spacing. Override a few variables to match your branding needs. Pick one to re-skin this page.

Default

Minimal

$ _

Hacker

Warm

Brutalist

Using Default

Default is the built-in look — no CSS or class needed. Pick another theme to see how it's applied.

<Stepper count={5} {active} onStepClick={(i) => (active = i)} />

Installation

Original
npm i svelte-pasito

Or tell your agent:

Install svelte-pasito (npm i svelte-pasito). Import the Stepper component, then add a stepper to my Svelte file with 5 steps and click-to-navigate.

Usage

<script lang="ts">
import { Stepper } from 'svelte-pasito'
let active = $state(0)
</script>
<Stepper
count={5}
{active}
onStepClick={(i) => (active = i)}
/>

Autoplay Usage

<script lang="ts">
import { Stepper, useAutoPlay } from 'svelte-pasito'
let active = $state(0)
const autoplay = useAutoPlay({
count: () => 5,
active: () => active,
onStepChange: (i) => (active = i),
stepDuration: () => 5000,
loop: () => true
})
</script>
<Stepper
count={5}
{active}
onStepClick={(i) => (active = i)}
filling={autoplay.filling}
fillDuration={autoplay.fillDuration}
/>

API Reference

<Stepper />

PropTypeDescription
countnumberTotal number of steps
activenumberZero-based active step index
onStepClick(index: number) => voidCalled when a step is clicked
orientation"horizontal" | "vertical"Layout direction. Default: "horizontal"
maxVisiblenumberMax visible steps before windowing kicks in
transitionDurationnumberTransition duration in ms. Default: 500
easingstringCSS timing function. Default: cubic-bezier(0.215, 0.61, 0.355, 1)
fillingbooleanShow fill progress on the active step
fillDurationnumberFill animation duration in ms. Default: 3000
classNamestringExtra class on the container, for variable overrides

useAutoPlay(options)

OptionTypeDescription
count() => numberTotal number of steps
active() => numberCurrent active step
onStepChange(index: number) => voidCalled to advance the step
stepDuration() => numberTime per step in ms. Default: 3000
loop() => booleanLoop back to the first step. Default: true
enabled() => booleanEnable/disable autoplay. Default: true

Returns

PropertyTypeDescription
playingbooleanCurrent playback state (reactive)
toggle() => voidToggle play/pause
fillingbooleanPass to Stepper filling prop
fillDurationnumberPass to Stepper fillDuration prop

Theming

Override any of these on the container via className.

VariableDefaultDescription
--pill-dot-size8pxDiameter of inactive dots
--pill-active-width24pxWidth of the active pill
--pill-gap6pxSpace between steps
--pill-bgrgba(0,0,0,0.12)Inactive dot color
--pill-active-bgrgba(0,0,0,0.8)Active pill color
--pill-fill-bgrgba(255,255,255,0.45)Autoplay fill bar color
--pill-container-bgrgba(0,0,0,0.04)Container background
--pill-container-borderrgba(0,0,0,0.06)Container border color
--pill-container-radius999pxContainer border radius

Dark theme

.my-dark-stepper {
--pill-bg: rgba(255, 255, 255, 0.15);
--pill-active-bg: rgba(255, 255, 255, 0.9);
--pill-fill-bg: rgba(255, 255, 255, 0.3);
--pill-container-bg: rgba(255, 255, 255, 0.1);
--pill-container-border: rgba(255, 255, 255, 0.12);
}

Accessibility

Steps use role="tab" with aria-selected and an aria-label per step. The active step is keyboard-focusable, and all transitions resolve instantly under prefers-reduced-motion.