Setup Wizard
Multi-step onboarding wizard with profile setup, preferences, and skippable optional steps. Built with React Context for state management.
Preview
Features
- 4-step flow: Welcome → Profile → Preferences → Complete
- React Context for centralized state management
- Simple dot indicator for progress
- Skip button for optional steps (Profile, Preferences)
- Back/Continue navigation
- Form data persistence across steps
- Compact theme toggle (Light/Dark/System)
- Clean notification toggles
- onComplete callback with collected data
- Fully accessible with keyboard navigation
Install Summary
This kit will add the following files and dependencies to your project. Download the bundle and extract it into your project root.
Component Files
| File | Path |
|---|---|
| setup-wizard.tsx | components/onboarding/setup-wizard/setup-wizard.tsx |
| setup-wizard-context.tsx | components/onboarding/setup-wizard/setup-wizard-context.tsx |
| wizard-steps.tsx | components/onboarding/setup-wizard/wizard-steps.tsx |
| step-welcome.tsx | components/onboarding/setup-wizard/step-welcome.tsx |
| step-profile.tsx | components/onboarding/setup-wizard/step-profile.tsx |
| step-preferences.tsx | components/onboarding/setup-wizard/step-preferences.tsx |
| step-complete.tsx | components/onboarding/setup-wizard/step-complete.tsx |
| types.ts | components/onboarding/setup-wizard/types.ts |
| index.ts | components/onboarding/setup-wizard/index.ts |
Utility Files
| File | Path |
|---|---|
| design-tokens.ts | lib/design-tokens.ts |
Dependencies
Install these dependencies before using the component:
Terminal
bash
npx shadcn@latest add dialog button input labelTerminal
bash
npm install @phosphor-icons/reactInstallation
Download the complete bundle as a ZIP file, or copy the text bundle to your clipboard:
Component Files
The component consists of the following files:
1. setup-wizard.tsx
setup-wizard.tsx
tsx
"use client";
import {
Dialog,
DialogContent,2. setup-wizard-context.tsx
setup-wizard-context.tsx
tsx
"use client";
import {
createContext,
useContext,3. wizard-steps.tsx
wizard-steps.tsx
tsx
"use client";
import { cn } from "@/lib/utils";
import { useSetupWizard, STEPS } from "./setup-wizard-context";
4. step-welcome.tsx
step-welcome.tsx
tsx
"use client";
import { RocketLaunch, ArrowRight } from "@phosphor-icons/react";
import { Button } from "@/components/ui/button";
import { radius } from "@/lib/design-tokens";5. step-profile.tsx
step-profile.tsx
tsx
"use client";
import { User, ArrowLeft, ArrowRight } from "@phosphor-icons/react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";6. step-preferences.tsx
step-preferences.tsx
tsx
"use client";
import { Gear as Settings, ArrowLeft, ArrowRight } from "@phosphor-icons/react";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";7. step-complete.tsx
step-complete.tsx
tsx
"use client";
import { SealCheck as CheckCircle2 } from "@phosphor-icons/react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";8. types.ts
types.ts
tsx
export type SetupStep = "welcome" | "profile" | "preferences" | "complete";
export interface StepConfig {
id: SetupStep;
title: string;9. index.ts
index.ts
tsx
export { SetupWizard } from "./setup-wizard";
export { SetupWizardProvider, useSetupWizard, STEPS } from "./setup-wizard-context";
export type {
SetupStep,
StepConfig,
ProfileData,
PreferencesData,
WizardData,
SetupWizardProps,
SetupWizardContextValue,
} from "./types";
Shared Utilities
This component uses shared utility functions. These are included in the bundle above:
design-tokens.ts
design-tokens.ts
tsx
// Border radius
export const radius = {
card: "rounded-xl",
badge: "rounded-full",
button: "rounded-lg",Usage
app/onboarding.tsx
tsx
import { useState } from "react";
import { SetupWizard, type WizardData } from "@/components/onboarding/setup-wizard";
function OnboardingPage() {
const [open, setOpen] = useState(true);SetupWizard Props
| Prop | Type | Default |
|---|---|---|
| open | boolean | required |
| onOpenChange | (open: boolean) => void | required |
| onComplete | (data: WizardData) => void | - |
| initialData | Partial<WizardData> | - |