Stepper
jarvis-ui/stepperFreeComponent
A keyboard-navigable multi-step flow with flexible triggers and panels.
Live preview
live · rendered by the registry
Rendered by jarvis-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.jarv.is/r/stepper.jsonSource
1"use client";23import { mergeProps } from "@base-ui/react/merge-props";4import { useRender } from "@base-ui/react/use-render";5import * as React from "react";67import { cn } from "@/lib/utils";89type StepperOrientation = "horizontal" | "vertical";10type StepState = "active" | "completed" | "inactive";11type StepIndicators = Partial<Record<StepState | "loading", React.ReactNode>>;1213type StepperContextValue = {14 activeStep: number;15 setActiveStep: (step: number) => void;16 stepsCount: number;17 orientation: StepperOrientation;18 indicators: StepIndicators;19 triggerNodes: HTMLButtonElement[];20 registerTrigger: (node: HTMLButtonElement) => () => void;21 focusNext: (currentIndex: number) => void;22 focusPrevious: (currentIndex: number) => void;23 focusFirst: () => void;24 focusLast: () => void;25};2627type StepItemContextValue = {28 step: number;29 state: StepState;30 isDisabled: boolean;31 isLoading: boolean;32};3334type StepperProps = React.ComponentProps<"div"> & {35 defaultValue?: number;36 value?: number;37 onValueChange?: (value: number) => void;38 orientation?: StepperOrientation;39 indicators?: StepIndicators;40};4142type StepperItemProps = React.ComponentProps<"div"> & {43 step: number;44 completed?: boolean;45 disabled?: boolean;46 loading?: boolean;47};4849type StepperTriggerState = Record<string, unknown> & {50 state: StepState;51 isLoading: boolean;52 isSelected: boolean;53};5455type StepperTriggerProps = Omit<React.ComponentProps<"button">, "children"> & {56 render?: useRender.RenderProp<StepperTriggerState>;57 children?: React.ReactNode;58};5960type StepperContentProps = React.ComponentProps<"div"> & {61 value: number;62 forceMount?: boolean;63};6465const defaultIndicators = {};66const StepperContext = React.createContext<StepperContextValue | null>(null);67const StepItemContext = React.createContext<StepItemContextValue | null>(null);6869function Stepper({70 defaultValue = 1,71 value,72 onValueChange,73 orientation = "horizontal",74 indicators = defaultIndicators,75 className,76 children,77 ...props78}: StepperProps) {79 const [uncontrolledStep, setUncontrolledStep] = React.useState(defaultValue);80 const [triggerNodes, setTriggerNodes] = React.useState<HTMLButtonElement[]>([]);81 const activeStep = value ?? uncontrolledStep;8283 const setActiveStep = React.useCallback(84 (step: number) => {85 if (value === undefined) {86 setUncontrolledStep(step);87 }8889 onValueChange?.(step);90 },91 [onValueChange, value],92 );9394// … truncated
What it pulls in
npm packages
Files it writes
More from jarvis-ui
All 10 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Browser Windowbrowser-window | jarvis-ui | Components | Free | no deps | |
| Cookie Consentcookie-consent | jarvis-ui | Components | Free | no deps | |
| Copy Buttoncopy-button | jarvis-ui | Components | Free | 1 dep | |
| Copyable Fieldcopyable-field | jarvis-ui | Components | Free | no deps | |
| Parallax Cardparallax-card | jarvis-ui | Components | Free | 1 dep | |
| Scroll Areascroll-area | jarvis-ui | Components | Free | 1 dep | |
| Tipovertipover | jarvis-ui | Components | Free | 1 dep · 2 files | |
| Toasttoast | jarvis-ui | Components | Free | 2 deps |
