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

oho-quiz

v1.0.1

Published

A customizable quiz game module

Downloads

8

Readme

Below is an updated README.md file for your oho-quiz npm module, reflecting the latest setup with Rollup, TypeScript, and CSS bundling, as well as its usage in both plain JavaScript and React applications. This version incorporates the fixes we’ve made (e.g., tslib, postcss, etc.) and provides clear instructions for users.


oho-quiz

A customizable, interactive quiz game module built with TypeScript and bundled with Rollup for web applications. oho-quiz allows you to create engaging quizzes with features like timers, sound effects, overlay images, customizable buttons, and detailed result logging. It works seamlessly in vanilla JavaScript projects and React applications.

Features

  • Customizable Questions and Answers: Define questions with text or images, and style answers with colors, fonts, and images.
  • Timer Support: Global or per-question timers with automatic submission on timeout.
  • Overlay Image: Add an SVG border (e.g., a frame) around the quiz content.
  • Sound Effects: Play sound on quiz start and stop on completion.
  • Feedback Control: Toggle feedback and completion messages with custom styling.
  • Result Logging: Track question IDs, selected answer IDs, and correctness in a detailed log.
  • Bundled CSS: Includes styles in dist/style.css for easy integration.
  • Dual Module Support: Provides CommonJS and ES Module outputs for flexibility.

Installation

Install oho-quiz via npm:

npm install oho-quiz

Usage

Vanilla JavaScript Example

Use oho-quiz in a plain HTML/JavaScript project:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Oho-Quiz Example</title>
    <link rel="stylesheet" href="node_modules/oho-quiz/dist/style.css" />
  </head>
  <body>
    <div id="quiz-container"></div>
    <button id="start-btn">Start Quiz</button>

    <script type="module">
      import OhoQuiz from 'oho-quiz/dist/index.esm.js';

      const quiz = new OhoQuiz({
        container: "#quiz-container",
        quizTitle: "Sample Quiz",
        quizSynopsis: "Test your knowledge!",
        progressBarColor: "#9de1f6",
        globalTiming: true,
        globalTimer: 30,
        questions: [
          {
            question: "What is 2 + 2?",
            questionType: "text",
            question_id: "q1",
            answers: [
              { text: "3", answer_id: "a1" },
              { text: "4", answer_id: "a2" },
            ],
            correctAnswer: 1,
            messageForCorrectAnswer: "Correct!",
            messageForIncorrectAnswer: "Wrong!",
            explanation: "2 + 2 equals 4.",
            point: 10,
          },
        ],
        onQuizComplete: (result) => {
          console.log("Quiz Result:", result);
        },
      });

      document.getElementById("start-btn").addEventListener("click", () => quiz.start());
    </script>
  </body>
</html>

React Example

Integrate oho-quiz into a React application:

// QuizComponent.tsx
import React, { useEffect, useRef } from 'react';
import OhoQuiz from 'oho-quiz';
import 'oho-quiz/dist/style.css'; // Import styles

const QuizComponent: React.FC = () => {
  const quizContainerRef = useRef<HTMLDivElement>(null);
  const quizInstanceRef = useRef<OhoQuiz | null>(null);

  useEffect(() => {
    if (quizContainerRef.current && !quizInstanceRef.current) {
      quizInstanceRef.current = new OhoQuiz({
        container: '#quiz-container',
        quizTitle: 'React Quiz Demo',
        quizSynopsis: 'Test your React skills!',
        progressBarColor: '#9de1f6',
        globalTiming: true,
        globalTimer: 30,
        questions: [
          {
            question: 'What is React?',
            questionType: 'text',
            question_id: 'q1',
            answers: [
              { text: 'A library', answer_id: 'a1' },
              { text: 'A framework', answer_id: 'a2' },
            ],
            correctAnswer: 0,
            messageForCorrectAnswer: 'Correct!',
            messageForIncorrectAnswer: 'Wrong!',
            explanation: 'React is a JavaScript library.',
            point: 10,
          },
        ],
        onQuizComplete: (result) => {
          console.log('Quiz Result:', result);
          alert(`Quiz finished! Your score: ${result.score}`);
        },
      });
    }

    return () => {
      quizInstanceRef.current = null;
    };
  }, []);

  const handleStartQuiz = () => {
    if (quizInstanceRef.current) {
      quizInstanceRef.current.start();
    }
  };

  return (
    <div>
      <div id="quiz-container" ref={quizContainerRef}></div>
      <button onClick={handleStartQuiz}>Start Quiz</button>
    </div>
  );
};

export default QuizComponent;
// App.tsx
import React from 'react';
import QuizComponent from './QuizComponent';

const App: React.FC = () => {
  return (
    <div className="App">
      <h1>Welcome to the Quiz App</h1>
      <QuizComponent />
    </div>
  );
};

export default App;

Configuration Options

| Property | Type | Default | Description | |---------------------------|-----------------------|---------------------|-----------------------------------------------------------------------------| | container | string | - | CSS selector for the quiz container element (required). | | quizTitle | string | - | Title of the quiz (required). | | quizSynopsis | string | - | Brief description of the quiz (required). | | progressBarColor | string | - | Color of the progress bar (e.g., "#9de1f6") (required). | | globalTiming | boolean | - | Use a global timer for all questions (required). | | globalTimer | number | 30 | Default time in seconds per question if no per-question timer is set. | | questions | Question[] | - | Array of question objects (required). See below for structure. | | soundEnabled | boolean | false | Enable sound effects. | | soundFile | string | - | URL or path to the sound file played during the quiz. | | overlayImage | string | '' | URL or path to an SVG overlay image (e.g., a border frame). | | contentMargin | number | 20 | Margin around the quiz content in pixels. | | buttonBackgroundColor | string | "#007bff" | Background color of the "Next" button. | | buttonTextColor | string | "#fff" | Text color of the "Next" button. | | buttonFontStyle | string | "normal" | Font style of the "Next" button (e.g., "bold italic"). | | buttonPadding | string | "10px 20px" | Padding of the "Next" button (e.g., "15px 25px"). | | buttonBorder | string | "none" | Border style of the "Next" button (e.g., "2px solid #fff"). | | canChangeAnswer | boolean | true | Allow changing answers after selection. | | showFeedback | boolean | true | Show feedback section (general toggle). | | showFeedbackMessage | boolean | true | Show specific feedback messages (e.g., "Correct!"). | | showCompletionMessage | boolean | true | Show "Quiz Over! Score: [score]" message on completion. | | onQuizComplete | (result: { score: number; log: QuizLogEntry[] }) => void | - | Callback function triggered on quiz completion with score and log. |

Question Object

| Property | Type | Default | Description | |----------------------------|-----------------------|---------|-----------------------------------------------------------------------------| | question | string | - | The question text (required). | | questionType | "text" \| "photo" | - | Type of question (required). | | questionPic | string \| null | null | URL or path to an image for photo-type questions. | | timer | number | - | Time in seconds for this question (overrides global timer if set). | | answerSelectionType | "single" \| "multiple" | - | Selection type (required). | | answers | Answer[] | - | Array of answer objects (required). See below for structure. | | correctAnswer | number \| number[] | - | Index or indices of correct answer(s) (required). | | messageForCorrectAnswer | string | - | Message shown for correct answers (required). | | messageForIncorrectAnswer| string | - | Message shown for incorrect answers (required). | | explanation | string | - | Explanation text for the answer (required). | | point | number | - | Points awarded for a correct answer (required). | | question_id | string | - | Unique ID for the question (required). |

Answer Object

| Property | Type | Default | Description | |-------------------|------------------|---------|-------------------------------------------------------| | text | string | - | Answer text (required). | | color | string | "#000"| Text color (e.g., "#fff"). | | backgroundColor | string | "#fff"| Background color (e.g., "#44ff44"). | | fontStyle | string | "normal" | Font style (e.g., "bold"). | | image | string \| null | null | URL or path to an image for the answer. | | answer_id | string | - | Unique ID for the answer (required). |

Methods

| Method | Description | |--------------|--------------------------------------------------| | start() | Starts or restarts the quiz. | | nextQuestion() | Advances to the next question (called internally). | | reset() | Resets the quiz to the beginning (alias for start()). |

Result Object

The onQuizComplete callback receives:

  • score: number - Total points earned.
  • log: QuizLogEntry[] - Array of log entries:
    • question_id: string - ID of the question.
    • selected_answer_id: string | null - ID of the selected answer (null if unanswered).
    • isCorrect: boolean - Whether the answer was correct.

Styling

The module includes a bundled CSS file at dist/style.css. Include it in your project:

  • Vanilla JS: <link rel="stylesheet" href="node_modules/oho-quiz/dist/style.css" />
  • React: import 'oho-quiz/dist/style.css';

Key CSS selectors:

  • #quiz-content: Main content wrapper.
  • #overlay: Overlay image.
  • #progress-bar: Progress bar.
  • #feedback: Feedback message.
  • #completion: Completion message.
  • #next-btn: Next button.
  • #answers button: Answer buttons.

Development

Prerequisites

  • Node.js (>= 18.x recommended)
  • npm

Setup

  1. Clone the repository:
    git clone https://github.com/yourusername/oho-quiz.git
    cd oho-quiz
  2. Install dependencies:
    npm install
  3. Build the module with Rollup:
    npm run build
  4. Run the demo:
    npm run start
    Open http://localhost:3000/ in your browser.

License

MIT License. See LICENSE for details.

Contributing

Contributions are welcome! Please submit a pull request or open an issue on GitHub.

Author

Koushik Mandal