npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@gawryco/reactquiz-engine

v0.1.1

Published

ReactQuiz Engine - A comprehensive React quiz component library with TypeScript support, multiple question types, and advanced features

Downloads

10

Readme

ReactQuiz Engine (use-quiz)

⚠️ WARNING: This is a Proof of Concept (POC) library and is not production-ready. It has not been thoroughly tested and may contain bugs or breaking changes. Use at your own risk.

Live Docs CI Deploy Docs npm version npm downloads Bundle size Size Limit License: MIT TypeScript React Tailwind CSS Coverage Dependencies PRs Welcome

ReactQuiz Engine is a comprehensive React quiz component library with TypeScript support, multiple question types, and advanced features. Perfect for creating interactive surveys, assessments, lead generation forms, and onboarding flows.

Features

  • 🎯 9 Question Types: Single choice, multiple choice, scale, slider, text input, image selection, date picker, matrix, and ranking
  • 📱 Mobile Optimized: Touch gestures, responsive design, and mobile-first approach
  • 🎨 Customizable: Full control over branding, colors, styling, and button text with Tailwind CSS
  • 🔄 Progress Persistence: Save and restore quiz progress with localStorage
  • 🧠 Conditional Logic: Show/hide questions based on previous answers
  • 📊 Result Strategies: Scoring, weighted, conditional, and custom calculation
  • 📝 Lead Capture: Built-in form with validation for collecting user information
  • 🌍 i18n-ready: Pluggable translation layer with language switch support
  • Accessible: WCAG-compliant semantics and keyboard navigation
  • 🎭 Animations: Smooth transitions and micro-interactions (slide, fade, scale, bounce)
  • 📦 TypeScript: Full type safety and IntelliSense support
  • 🎛️ Grid Layouts: BuzzFeed-style grid layouts for question options
  • 🔤 Custom Button Text: Customize all button labels for better UX
  • 📸 Shareable Results: Generate beautiful result images with html-to-image (lazy loaded) for social sharing

Table of Contents

Installation

npm install @gawryco/reactquiz-engine
# or
yarn add @gawryco/reactquiz-engine 
# or
pnpm add @gawryco/reactquiz-engine 

Documentation

🚀 Live Documentation on GitHub Pages

To see ReactQuiz Engine in action, you can either:

Option 1: View Live Documentation

Visit the live documentation hosted on GitHub Pages to see all features in action.

Option 2: Run Locally

Clone and run the documentation locally:

# Clone the repository
git clone https://github.com/gawryco/reactquiz-engine.git
cd reactquiz-engine

# Install dependencies
pnpm install

# Run the documentation
pnpm dev

The documentation includes five examples:

  • Simple Quiz: Love language assessment with basic question types
  • Advanced Quiz: Calculator finder with image selection, sliders, matrix, weighted scoring
  • Timer Quiz: Quiz-level and question-level timers with warning thresholds and auto-advance
  • Animation Showcase: Demonstrates all transition types, timings, and effects
  • Conditional Logic Demo: Questions appear dynamically based on previous answers

Open http://localhost:5173 to view the local documentation.

Quick Start

import React from 'react';
import { Quiz } from '@gawryco/reactquiz-engine';
import { Heart, User, Mail, Phone } from 'lucide-react';

const MyQuiz = () => {
  const quizConfig = {
    title: "What's Your Love Language? 💕",
    subtitle: "Discover how you express and receive love",

    branding: {
      colors: {
        primary: "from-pink-500 to-rose-600",
        secondary: "from-purple-500 to-pink-600",
        accent: "pink-500"
      },
      icon: Heart
    },

    behavior: {
      autoAdvance: true,
      showProgress: true,
      allowBack: true,
      saveProgress: false
    },

    questions: [
      {
        id: 1,
        question: "How do you prefer to show affection?",
        type: "single-choice",
        required: true,
        options: [
          { value: "words", label: "Saying 'I love you' and compliments" },
          { value: "touch", label: "Hugs, kisses, and physical contact" },
          { value: "time", label: "Spending quality time together" },
          { value: "gifts", label: "Giving thoughtful presents" },
          { value: "acts", label: "Doing helpful things for them" }
        ]
      }
    ],

    resultLogic: { type: "scoring" },
    results: {
      words: {
        title: "Words of Affirmation 💬",
        description: "You feel most loved when people express their feelings for you through words.",
        color: "from-blue-400 to-indigo-600"
      }
    },

    leadCapture: {
      enabled: true,
      title: "Get Your Results!",
      subtitle: "Enter your details to receive personalized insights",
      fields: [
        {
          key: 'name',
          label: 'Your Name',
          type: 'text',
          required: true,
          icon: User,
          placeholder: 'Enter your full name',
          validation: {
            minLength: 2,
            maxLength: 50,
            pattern: '^[a-zA-Z\\s\'-]+$',
            message: 'Please enter a valid name'
          }
        },
        {
          key: 'email',
          label: 'Email Address',
          type: 'email',
          required: true,
          icon: Mail,
          placeholder: '[email protected]'
        },
        {
          key: 'phone',
          label: 'Phone Number (Optional)',
          type: 'tel',
          required: false,
          icon: Phone,
          placeholder: '(555) 123-4567',
          validation: {
            pattern: '^(\\(?([0-9]{3})\\)?[-.\\s]?([0-9]{3})[-.\\s]?([0-9]{4}))$',
            message: 'Please enter a valid US phone number'
          }
        }
      ],
      privacyText: "🔒 We respect your privacy and won't spam you."
    },

    onSubmit: (leadData, answers, result) => {
      console.log('Quiz completed!', { leadData, answers, result });
    }
  };

  return <Quiz quizConfig={quizConfig} quizId="love-language-quiz" />;
};

export default MyQuiz;

Question Types

Single Choice

{
  id: 1,
  question: "What's your favorite color?",
  type: "single-choice",
  required: true,
  options: [
    { value: "red", label: "Red" },
    { value: "blue", label: "Blue" },
    { value: "green", label: "Green" }
  ]
}

Slider

{
  id: 2,
  question: "Rate your satisfaction",
  type: "slider",
  min: 0,
  max: 10,
  step: 1,
  unit: "points"
}

Note: Slider questions always show a continue button for better UX.

Multiple Choice

{
  id: 2,
  question: "Which activities do you enjoy?",
  type: "multi-choice",
  description: "Select all that apply",
  options: [
    { value: "reading", label: "Reading" },
    { value: "sports", label: "Sports" },
    { value: "music", label: "Music" }
  ]
}

Scale (1-5 Rating)

{
  id: 3,
  question: "How satisfied are you?",
  type: "scale",
  scaleMax: 5,
  scaleLabels: { min: "Not satisfied", max: "Very satisfied" },
  required: true
}

Slider

{
  id: 4,
  question: "What's your budget range?",
  type: "slider",
  min: 1000,
  max: 10000,
  step: 500,
  unit: "USD"
}

Text Input

{
  id: 5,
  question: "Tell us about yourself",
  type: "text-input",
  placeholder: "Share your thoughts...",
  maxLength: 500,
  required: true
}

Image Selection

{
  id: 6,
  question: "Which style appeals to you?",
  type: "image-selection",
  options: [
    { 
      value: "modern", 
      label: "Modern", 
      image: "https://example.com/modern.jpg" 
    },
    { 
      value: "classic", 
      label: "Classic", 
      image: "https://example.com/classic.jpg" 
    }
  ]
}

Date Picker

{
  id: 7,
  question: "When is your event?",
  type: "date-picker",
  minDate: "2024-01-01",
  maxDate: "2024-12-31",
  required: true
}

Matrix (Grid)

{
  id: 8,
  question: "Rate each feature",
  type: "matrix",
  columns: ["Poor", "Fair", "Good", "Excellent"],
  rows: ["Ease of use", "Performance", "Design", "Support"]
}

Advanced Features

Conditional Logic

Show questions based on previous answers:

{
  conditionalLogic: [
    {
      questionId: 5, // Show this question only if...
      dependsOn: 1,  // ...answer to question 1...
      operator: 'equals', // ...equals...
      value: 'yes' // ...'yes'
    }
  ]
}

Weighted Scoring

Assign different weights to questions and answers:

{
  resultLogic: {
    type: "weighted",
    weights: {
      1: 3, // Question 1 has 3x weight
      2: 1, // Question 2 has normal weight
      3: 2  // Question 3 has 2x weight
    }
  }
}

Custom Result Calculation

{
  resultLogic: {
    type: "custom",
    calculation: (answers) => {
      // Your custom logic here
      const score = calculateCustomScore(answers);
      return score > 80 ? 'expert' : 'beginner';
    }
  }
}

Progress Persistence

{
  behavior: {
    saveProgress: true, // Automatically save progress
    allowBack: true,    // Allow users to go back
    autoAdvance: false, // Manual navigation
    showProgress: true  // Show progress bar
  }
}

Timers

Support quiz-level and question-level timers with warning thresholds and callbacks.

{
  behavior: {
    timer: {
      enabled: true,
      duration: 120,
      showDisplay: true,
      autoAdvanceOnExpiry: true,
      warningThreshold: 30,
      onExpiry: () => console.log('Quiz timer expired')
    }
  }
}

Question-level timer example:

{
  id: 2,
  question: 'Rate your programming experience',
  type: 'slider',
  timer: {
    enabled: true,
    duration: 30,
    showDisplay: true,
    autoAdvanceOnExpiry: true,
    warningThreshold: 10
  }
}

Animations

Fine-tune transitions, timings, and interactive effects.

{
  behavior: {
    animations: {
      transitions: { slideLeft: true, fadeIn: true, bounce: false, scale: true, slideUp: true },
      timing: { questionTransition: 350, optionHover: 150, buttonHover: 200, progressUpdate: 300 },
      effects: { pulseOnSelect: true, shakeOnError: true, glowOnFocus: true }
    }
  }
}

Shareable Results

Generate beautiful result images for social sharing using html-to-image (lazy loaded):

{
  onExportImage: (blob: Blob, options: { aspect: 'square' | 'story' | 'tweet' }) => {
    // Handle the generated image blob
    const url = URL.createObjectURL(blob);
    // Share or download the image
  }
}

The library automatically generates high-quality PNG images with customizable aspect ratios:

  • Square (1080x1080): Perfect for Instagram posts
  • Story (1080x1920): Ideal for Instagram/Snapchat stories
  • Tweet (1600x900): Optimized for Twitter/X sharing

The html-to-image library is lazy loaded to keep the initial bundle size small.

Internationalization (i18n)

Import the i18n instance and switch languages dynamically. See the documentation for a full example.

import i18n from '@gawryco/reactquiz-engine/i18n';

i18n.changeLanguage('fr');
{
  behavior: {
    saveProgress: true, // Automatically save progress
    allowBack: true,    // Allow users to go back
    autoAdvance: false, // Manual navigation
    showProgress: true  // Show progress bar
  }
}

Lead Capture Validation

The library includes comprehensive validation for lead capture forms with built-in validation rules and custom validation support.

Built-in Validation

The library automatically applies validation rules based on field type:

  • Email fields: Validates email format using RFC-compliant regex
  • Phone fields: Validates phone number format (supports international and US formats)
  • Text fields: Applies name validation for fields with "name" in the key

Custom Validation

You can define custom validation rules for any field:

{
  key: 'name',
  label: 'Full Name',
  type: 'text',
  required: true,
  icon: User,
  placeholder: 'Enter your full name',
  validation: {
    minLength: 2,
    maxLength: 50,
    pattern: '^[a-zA-Z\\s\'-]+$',
    message: 'Please enter a valid name (letters, spaces, hyphens, and apostrophes only)'
  }
}

Validation Rules

| Rule | Type | Description | |------|------|-------------| | minLength | number | Minimum character length | | maxLength | number | Maximum character length | | pattern | string | Regex pattern for validation | | message | string | Custom error message | | custom | function | Custom validation function that returns error message or null |

Custom Validation Function

{
  key: 'website',
  label: 'Website',
  type: 'text',
  required: false,
  icon: Globe,
  validation: {
    custom: (value) => {
      if (value && !value.startsWith('http')) {
        return 'Website must start with http:// or https://';
      }
      return null; // Valid
    }
  }
}

Visual Feedback

The library provides real-time visual feedback for validation errors:

  • Red border and background for invalid fields
  • Error icons next to invalid inputs
  • Detailed error messages below each field
  • Form submission is disabled until all validation passes

Styling and Branding

Custom Colors

{
  branding: {
    colors: {
      primary: "from-blue-500 to-purple-600",    // Gradient for buttons
      secondary: "from-green-500 to-emerald-600", // Secondary actions
      accent: "blue-500"                          // Accent color for selections
    },
    icon: YourIcon // Lucide React icon
  }
}

Custom Button Text

{
  behavior: {
    buttonText: {
      next: 'Next Question',
      back: 'Previous',
      continue: 'Continue',
      submit: 'Get My Results',
      start: 'Start Quiz'
    }
  }
}

Grid Layouts

{
  id: 1,
  question: "What's your favorite color?",
  type: "single-choice",
  layout: {
    type: 'grid',        // 'list' or 'grid'
    columns: 2,          // 2, 3, or 4 columns
    gap: 'md'            // 'sm', 'md', or 'lg'
  },
  options: [
    { value: "red", label: "Red" },
    { value: "blue", label: "Blue" },
    { value: "green", label: "Green" },
    { value: "yellow", label: "Yellow" }
  ]
}

Custom CSS Classes

<Quiz 
  quizConfig={config} 
  className="my-custom-quiz" 
/>

API Reference

Quiz Component Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | quizConfig | Partial<QuizConfig> | ✅ | Quiz configuration object | | quizId | string | ❌ | Unique identifier for progress persistence | | className | string | ❌ | Additional CSS classes |

QuizConfig Interface

interface QuizConfig {
  title: string;
  subtitle: string;
  startButtonText?: string;
  welcomeFooter?: string;
  branding: QuizBranding;
  behavior: QuizBehavior;
  questions: QuizQuestion[];
  conditionalLogic?: ConditionalLogic[];
  resultLogic: ResultLogic;
  results: Record<string, QuizResult>;
  leadCapture: LeadCapture;
  thankYouMessage?: string;
  onSubmit: (
    leadData: Record<string, string>,
    answers: Record<string, QuizAnswer>,
    result: string
  ) => void;
}

useQuiz Hook

For advanced usage, you can use the useQuiz hook directly:

import { useQuiz } from '@gawryco/reactquiz-engine';

const MyCustomQuiz = () => {
  const {
    config,
    state,
    visibleQuestions,
    totalSteps,
    progress,
    handleAnswerSelect,
    handleNext,
    handleBack,
    handleSubmit,
    resetQuiz
  } = useQuiz(quizConfig, 'my-quiz');

  // Your custom implementation
  return <div>...</div>;
};

Requirements

  • React 16.8+ (hooks support)
  • Lucide React for icons
  • Tailwind CSS for styling

Browser Support

  • Chrome 60+
  • Firefox 60+
  • Safari 12+
  • Edge 79+

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT © Gawry&Co

Support