Back to Wizard Flow

README

🧙 Wizard Flow - Config-Driven Wizard with Visual Editor

A powerful, type-safe wizard system with drag-and-drop visual flow editor, conditional navigation, and comprehensive field validation.

✨ Features

  • 🎨 Visual Flow Editor: Drag-and-drop interface using React Flow
  • 📝 Config-Driven: Define entire wizards in JSON
  • 🔀 Conditional Navigation: Dynamic routing based on user answers
  • ✅ Comprehensive Validation: Built-in and custom validation rules
  • 💾 Persistence: Auto-save and resume functionality
  • 📊 Progress Tracking: Steps or percentage display
  • 🎯 Type-Safe: Full TypeScript support
  • ♿ Accessible: ARIA labels and keyboard navigation
  • 🎭 Preview Mode: Test wizards directly in the editor
  • 📦 Modular: Separate packages for runtime, editor, and shared code
  • 🔄 Variable Accumulation: Data flows through the entire wizard journey
  • 🎯 Template Processing: Personalize content with {{variables.name}} syntax

🚀 Quick Start

Prerequisites

  • Node.js >= 18.0.0
  • pnpm >= 8.0.0

Installation

bash
# Clone the repository
git clone https://github.com/jonathanleahy/wizard-flow.git
cd wizard-flow

# Install dependencies
pnpm install

# Build all packages
pnpm build

Development

bash
# Run the demo application (port 3000)
pnpm dev:demo

# Run the visual editor (port 3001)
pnpm dev:editor

# Run everything in parallel
pnpm dev:all

🎯 Demo Features

The demo application includes four comprehensive examples showcasing different aspects of the variable accumulation system:

1. User Registration Flow

  • Age-based conditional routing
  • Parental consent for minors
  • Senior benefits for 65+
  • Account type selection with enterprise details
  • Personalized messaging throughout

2. Health Assessment

  • BMI calculation using global variables
  • Risk level assessment
  • Conditional medical history based on age/smoking
  • Personalized recommendations
  • Complex variable expressions

3. Product Recommendation Quiz

  • Dynamic product recommendations
  • Budget and tech level scoring
  • Conditional paths for gaming/creative users
  • Complex variable-based product matching

4. Customer Satisfaction Survey

  • Conditional feedback paths based on rating
  • Dynamic follow-up questions
  • Personalized thank you messages
  • Email visibility based on follow-up preference
Debug Panel: Toggle the debug panel to see how variables accumulate and flow through the wizard in real-time.

📦 Packages

@wizard-flow/shared

Core types, schemas, expression evaluator, and utilities shared across packages.

@wizard-flow/runtime

React components for rendering wizards:
  • WizardProvider & Context
  • Field components (Text, Number, Select, Checkbox, Radio, Date, etc.)
  • Navigation and Progress components
  • Page renderer with conditional logic

@wizard-flow/editor

Visual flow editor built with React Flow:
  • Drag-and-drop page creation
  • Field palette
  • Property inspectors
  • Live JSON preview with Monaco Editor
  • Import/Export functionality
  • Validation and testing

@wizard-flow/demo

Interactive demo application showcasing variable accumulation features with:
  • Multiple example wizards (registration, health assessment, product quiz, survey)
  • Debug panel toggle to visualize variable states
  • Responsive design with polished UI

📋 JSON Schema

json
{
  "version": "1.0",
  "name": "My Wizard",
  "startPageId": "page_start",
  "pages": [
    {
      "id": "page_start",
      "title": "Welcome",
      "fields": [
        {
          "id": "name",
          "type": "text",
          "label": "Name",
          "required": true,
          "variableName": "userName"
        },
        {
          "id": "age",
          "type": "number",
          "label": "Age",
          "required": true,
          "variableName": "userAge"
        }
      ],
      "edges": [
        {
          "when": "variables.userAge >= 18",
          "to": "page_adult"
        },
        {
          "when": "variables.userAge < 18",
          "to": "page_minor"
        }
      ]
    },
    {
      "id": "page_adult",
      "title": "Welcome {{variables.userName}}!",
      "description": "You are eligible for our adult services.",
      "fields": []
    }
  ]
}

🎯 Expression Language

The wizard supports a powerful expression language for conditions:

  • Simple: true, false
  • Comparisons: answers.age >= 18
  • Equality: answers.country === "UK"
  • Logic: answers.age >= 18 && answers.hasLicense
  • Functions: min(answers.income, 50000), length(answers.name)
  • Variables: variables.isAdult (computed values)

🎨 Field Types

  • Text: Basic text input with validation
  • Number: Numeric input with min/max
  • Select: Dropdown selection
  • Checkbox: Boolean choice
  • Radio: Single choice from options
  • Date: Date picker
  • Email: Email with validation
  • Tel: Phone number input

🔧 Validation Rules

javascript
{
  "validation": [
    { "type": "required" },
    { "type": "minLength", "value": 2 },
    { "type": "pattern", "value": "^[A-Z]", "message": "Must start with capital" },
    { "type": "custom", "expression": "value !== 'test'", "message": "Cannot be 'test'" }
  ]
}

🎮 Usage Examples

Basic Wizard with Variable Accumulation

tsx
import { Wizard } from '@wizard-flow/runtime';

const wizardConfig = {
  "version": "1.0",
  "name": "Registration",
  "startPageId": "personal_info",
  "pages": [
    {
      "id": "personal_info",
      "title": "Personal Information",
      "fields": [
        {
          "id": "name",
          "type": "text",
          "label": "Name",
          "required": true,
          "variableName": "userName"
        },
        {
          "id": "age",
          "type": "number",
          "label": "Age",
          "required": true,
          "variableName": "userAge"
        }
      ],
      "edges": [
        {
          "when": "variables.userAge >= 18",
          "to": "adult_content"
        }
      ]
    },
    {
      "id": "adult_content",
      "title": "Welcome {{variables.userName}}!",
      "description": "You are eligible for adult services.",
      "fields": []
    }
  ]
};

function App() {
  return (
    <Wizard
      flow={wizardConfig}
      onComplete={(answers) => console.log('Complete!', answers)}
      onPageChange={(pageId) => console.log('Page:', pageId)}
    />
  );
}

With Custom Storage

tsx
import { Wizard, LocalStorageProvider } from '@wizard-flow/runtime';

function App() {
  const storage = new LocalStorageProvider('my-wizard');
  
  return (
    <Wizard
      flow={wizardConfig}
      storageProvider={storage}
      onComplete={handleComplete}
    />
  );
}

🛠️ Development

Project Structure

shell
wizard-flow/
├── packages/
│   ├── shared/       # Shared types and utilities
│   ├── runtime/      # Wizard runtime components
│   ├── editor/       # Visual flow editor
│   └── demo/         # Demo application
├── turbo.json        # Turborepo configuration
├── pnpm-workspace.yaml
└── package.json

Commands

bash
# Development
pnpm dev              # Run all packages in dev mode
pnpm dev:demo         # Run demo only
pnpm dev:editor       # Run editor only

# Building
pnpm build            # Build all packages
pnpm typecheck        # Type check all packages

# Testing
pnpm test             # Run tests
pnpm lint             # Run linting

# Maintenance
pnpm clean            # Clean all build artifacts

📚 Documentation

🤝 Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

📄 License

MIT License - see LICENSE file for details

🙏 Acknowledgments

  • React Flow for the amazing graph editor
  • Monaco Editor for JSON editing
  • Zod for schema validation
  • The React team for an excellent framework

© 2026 Jonathan Leahy · v1.0.11