Thrive Design System

Components

PageSectionWizard

A specialized page header for multi-step wizard flows with editable titles, step indicators, and sidebar integration.

Installation

npm install @thrivecart/ui
yarn add @thrivecart/ui
pnpm add @thrivecart/ui
bun add @thrivecart/ui

Usage

import { PageSectionWizard } from '@thrivecart/ui';

Examples

Basic Wizard Header

Step Indicators

Wizard header with title and step progress

Create Campaign

<SidebarProvider mainNavItems={[]} config={{ defaultSecondaryOpen: false }}>
			<div className="w-full border border-border rounded-lg overflow-hidden">
				<PageSectionWizard
					title="Create Campaign"
					currentStep={1}
					totalSteps={4}
					steps={[
						{ id: 'details', label: 'Details' },
						{ id: 'content', label: 'Content' },
						{ id: 'audience', label: 'Audience' },
						{ id: 'review', label: 'Review' },
					]}
				/>
			</div>
		</SidebarProvider>

Editable Title

When onTitleChange is provided, the title becomes inline-editable. Click the title or the pencil icon to edit. Press Enter to save or Escape to cancel.

Editable Title

Click the title to rename the wizard

My New Campaign

<SidebarProvider mainNavItems={[]} config={{ defaultSecondaryOpen: false }}>
			<div className="w-full border border-border rounded-lg overflow-hidden">
				<PageSectionWizard
					title={title}
					onTitleChange={setTitle}
					onTitleChangeEnd={(newTitle) => console.log('Saved:', newTitle)}
					titlePlaceholder="Untitled Campaign"
					currentStep={0}
					totalSteps={3}
					steps={[
						{ id: 'details', label: 'Details' },
						{ id: 'content', label: 'Content' },
						{ id: 'review', label: 'Review' },
					]}
				/>
			</div>
		</SidebarProvider>

With Step Navigation

Clickable Steps

Click completed steps to navigate back

Campaign Builder

<SidebarProvider mainNavItems={[]} config={{ defaultSecondaryOpen: false }}>
			<div className="w-full border border-border rounded-lg overflow-hidden">
				<PageSectionWizard
					title="Campaign Builder"
					currentStep={currentStep}
					totalSteps={steps.length}
					steps={steps}
					onStepClick={setCurrentStep}
				/>
			</div>
		</SidebarProvider>

With Stepper Context

When used inside a Stepper component, PageSectionWizard automatically reads the current step and navigation from context. No need to pass currentStep, totalSteps, or onStepClick.

Stepper Integration

Automatic step management via Stepper context

Campaign Builder

import { Stepper, StepperContent, PageSectionWizard } from '@thrivecart/ui';

function CampaignWizard() {
const [activeStep, setActiveStep] = useState('details');

return (
  <Stepper value={activeStep} onValueChange={setActiveStep}>
    <PageSectionWizard
      title="Campaign Builder"
      onTitleChange={(title) => updateCampaignName(title)}
      steps={[
        { id: 'details', label: 'Campaign Details' },
        { id: 'content', label: 'Email Content' },
        { id: 'audience', label: 'Select Audience' },
        { id: 'review', label: 'Review & Send' },
      ]}
    />
    <StepperContent value="details">
      <CampaignDetailsForm />
    </StepperContent>
  </Stepper>
);
}

Full Layout with Sidebar

In a real application, PageSectionWizard sits inside a SidebarProvider alongside SideNavigation. The sidebar toggle button appears when the sidebar is collapsed.

Wizard in Full Layout

PageSectionWizard inside a SidebarProvider with SideNavigation

Create Campaign

Email Content

<SidebarProvider mainNavItems={[]} config={{ defaultSecondaryOpen: true }}>
			<div className="flex h-[400px] w-full border border-secondary overflow-hidden">
				<SidebarPanel>
					<SidebarPanelHeader>
						<SidebarPanelTitle>Navigation</SidebarPanelTitle>
					</SidebarPanelHeader>
					<SidebarPanelContent>
						<SidebarItem
							label="Dashboard"
							iconOutlined={MdOutlineDashboard}
							iconFilled={MdDashboard}
						/>
						<SidebarItem
							label="Campaigns"
							iconOutlined={MdOutlineCampaign}
							iconFilled={MdCampaign}
							isActive
						>
							<SidebarSubItem label="Templates" />
							<SidebarSubItem label="All Campaigns" isActive />
						</SidebarItem>
					</SidebarPanelContent>
				</SidebarPanel>
				<div className="flex-1 flex flex-col overflow-hidden">
					<PageSectionWizard
						title="Create Campaign"
						showSidebarToggle
						currentStep={1}
						totalSteps={4}
						steps={[
							{ id: 'details', label: 'Details' },
							{ id: 'content', label: 'Content' },
							{ id: 'audience', label: 'Audience' },
							{ id: 'review', label: 'Review' },
						]}
					/>
					<main className="flex-1 overflow-y-auto px-space-2xl">
						<div className="max-w-2xl">
							<h3 className="font-medium mb-4">Email Content</h3>
							<div className="space-y-4">
								<div className="h-8 bg-bg rounded w-full" />
								<div className="h-32 bg-bg rounded w-full" />
							</div>
						</div>
					</main>
				</div>
			</div>
		</SidebarProvider>

Simple Step Counter

If you don't provide steps, the wizard shows a simple "Step X of Y" text.

Step Counter

Minimal step indicator without labels

Setup Wizard

Step 3 of 5
<SidebarProvider mainNavItems={[]} config={{ defaultSecondaryOpen: false }}>
			<div className="w-full border border-border rounded-lg overflow-hidden">
				<PageSectionWizard
					title="Setup Wizard"
					currentStep={2}
					totalSteps={5}
				/>
			</div>
		</SidebarProvider>

Custom Steps Content

Use stepsContent to render custom content in the steps area instead of the default step indicators.

Custom Steps Area

Replace step indicators with custom content

Import Contacts

<SidebarProvider mainNavItems={[]} config={{ defaultSecondaryOpen: false }}>
			<div className="w-full border border-border rounded-lg overflow-hidden">
				<PageSectionWizard
					title="Import Contacts"
					stepsContent={
						<div className="flex items-center gap-2">
							<Button variant="secondary" size="sm">Cancel</Button>
							<Button variant="primary" size="sm">Import 234 Contacts</Button>
						</div>
					}
				/>
			</div>
		</SidebarProvider>

Best Practices

Use descriptive step labels

Step labels should clearly describe what happens in each step (e.g., "Campaign Details" not "Step 1").

Enable editable titles

When the wizard creates a named entity (campaign, template), let users name it inline rather than in a separate field.

Keep steps to 3-5

More than 5 steps feels overwhelming. Group related steps or use sub-steps.

Enable showSidebarToggle

Always set showSidebarToggle when using inside a SidebarProvider so users can re-open a collapsed sidebar.

Don't use for non-sequential flows

If users can complete sections in any order, use Tabs instead.

Don't mix with PageSection

Use one header type per page. Don't combine PageSection and PageSectionWizard.

Props

PageSectionWizard

PropTypeDefaultDescription
titlestringWizard title text
onTitleChange(newTitle: string) => voidMakes title editable; called on each keystroke
onTitleChangeEnd(newTitle: string) => voidCalled when editing ends (blur or Enter)
titlePlaceholderstring'Untitled'Placeholder text when title is empty
currentStepnumberCurrent step index (0-based). Auto-detected from Stepper context if omitted.
totalStepsnumberTotal steps. Auto-detected from Stepper context if omitted.
stepsWizardStepItem[]Step definitions for indicators. Uses Stepper context if omitted.
onStepClick(stepIndex: number) => voidCalled when a step indicator is clicked
showSidebarTogglebooleantrueShow sidebar toggle when sidebar is collapsed
stepsContentReactNodeCustom content replacing the default step indicators
classNamestringAdditional className

Accessibility

  • Title input supports keyboard editing (Enter to save, Escape to cancel)
  • Step indicators are keyboard navigable when onStepClick is provided
  • Current step is communicated to screen readers
  • Sidebar toggle button has proper aria-label
  • Editable title has an edit button with tooltip for discoverability