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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@monarkmarkets/question-types

v1.0.9

Published

Question type components for Monark Markets

Readme

@monarkmarkets/question-types

A package of reusable React components for building interactive question interfaces including single choice, multiple choice, and scale-based questions.

Installation

npm install @monarkmarkets/question-types

Peer dependencies: Install react and react-dom ^18.2.0 || ^19.0.0 in the consuming app. Styling helpers use Emotion and MUI (@emotion/react, @emotion/styled, @mui/material), which ship as direct dependencies of this package.

Features

  • Multiple question formats - Single choice, multiple choice, and scale/slider questions
  • Highly customizable - Extensive props for tailoring appearance and behavior
  • Type-safe - Written in TypeScript with comprehensive type definitions

Components

SingleChoiceQuestion

A radio button-based question component that allows users to select exactly one option.

import {SingleChoiceQuestion} from '@monarkmarkets/question-types';

function MyForm() {
    return (
        <SingleChoiceQuestion
            options={["Option 1", "Option 2", "Option 3"]}
            explanation="Please select one option"
            selectedOption="Option 1"
            onSelect={(selected) => {
                // Handle selection
            }}
        />
    );
}

MultiChoiceQuestion

A checkbox-based question component that allows users to select multiple options.

import {MultiChoiceQuestion} from '@monarkmarkets/question-types';

function MyForm() {
    return (
        <MultiChoiceQuestion
            options={["Option 1", "Option 2", "Option 3"]}
            explanation="Please select all that apply"
            selectedOptions={["Option 1"]}
            onSelect={(selected) => {
                // Handle selection
            }}
        />
    );
}

ScaleQuestion

A slider-based question component for numeric or scale-based inputs.

import {ScaleQuestion} from '@monarkmarkets/question-types';

function MyForm() {
    return (
        <ScaleQuestion
            options={["How much would you like to invest?"]}
            explanation="Drag the slider to select an amount"
            min={0}
            max={1000000}
            step={5000}
            selectedValues={["50000"]}
            defaultValue={0}
            minLabel="Minimum Investment"
            maxLabel="Maximum Investment"
            currency={{
                symbol: 'USD',
                position: 'prefix',
                locale: 'en-US'
            }}
            onSelect={(selected) => {
                // Handle selection
            }}
            showNumberLabels={true}
        />
    );
}

Props

Common Props (BaseQuestionProps)

| Prop | Type | Default | Description | |----------------|------------------------------|------------|--------------------------------------------| | id | string | undefined | Optional unique identifier | | disabled | boolean | false | Whether the component is disabled | | error | string | undefined | Custom error message | | options | string[] | (required) | Array of options to display | | onSelect | (selected: string[]) => void | (required) | Callback function when selection changes | | explanation | string | undefined | Optional explanation or help text | | showNoneOption | boolean | false | Whether to show "None of the Above" option |

SingleChoiceQuestion Props

| Prop | Type | Default | Description | |----------------|----------------------------------------------------------|-----------|------------------------------------| | selectedOption | string | undefined | The currently selected option | | allowDeselect | boolean | false | Whether options can be deselected | | renderOption | (option: string, isSelected: boolean) => React.ReactNode | undefined | Custom render function for options |

MultiChoiceQuestion Props

| Prop | Type | Default | Description | |-----------------|----------------------------------------------------------|-----------|------------------------------------| | selectedOptions | string[] | [] | The currently selected options | | allowDeselect | boolean | true | Whether options can be deselected | | renderOption | (option: string, isSelected: boolean) => React.ReactNode | undefined | Custom render function for options |

ScaleQuestion Props

| Prop | Type | Default | Description | |------------------|---------------------------|------------|---------------------------------------------| | min | number | (required) | Minimum value of the scale | | max | number | (required) | Maximum value of the scale | | step | number | (required) | Step value for the scale | | defaultValue | number | 0 | Default value for the scale | | minLabel | string | undefined | Label for the minimum value | | maxLabel | string | undefined | Label for the maximum value | | marks | ScaleMark[] | undefined | Custom scale mark points | | showNumberLabels | boolean | false | Whether to show number labels on the scale | | currency | CurrencyConfig | undefined | Configuration for currency formatting | | formatDisplay | (value: number) => string | undefined | Custom function to format the display value | | selectedValues | string[] | [] | Previously selected values |

CurrencyConfig

| Property | Type | Description | |----------|----------------------|---------------------------------------| | symbol | string | Currency symbol (e.g., 'USD', 'EUR') | | position | 'prefix' | 'suffix' | Position of the currency symbol | | locale | string | Optional locale for number formatting |

ScaleMark

| Property | Type | Description | |----------|--------|----------------------------------------| | value | number | The value where the mark should appear | | label | string | The label to display at the mark |

Example

Here's an example of how to use the question components with data from the API:

import React, {useState} from 'react';
import {
    SingleChoiceQuestion,
    MultiChoiceQuestion,
    ScaleQuestion
} from '@monarkmarkets/question-types';
import {QuestionnaireQuestionFormat} from '@monarkmarkets/api-client';

const QuestionRenderer = ({question, onAnswer}) => {
    // Render the appropriate question component based on question format
    switch (question.format) {
        case QuestionnaireQuestionFormat.Scale:
            return (
                <ScaleQuestion
                    options={question.options}
                    explanation={question.explanation}
                    min={question.scaleMin || 0}
                    max={question.scaleMax || 1000000}
                    step={question.scaleStep || 5000}
                    selectedValues={[]}
                    defaultValue={0}
                    minLabel="Minimum Investment"
                    maxLabel="Maximum Investment"
                    currency={{
                        symbol: 'USD',
                        position: 'prefix',
                        locale: 'en-US'
                    }}
                    onSelect={onAnswer}
                    showNumberLabels={true}
                />
            );

        case QuestionnaireQuestionFormat.MultipleChoiceMultiple:
            return (
                <MultiChoiceQuestion
                    options={question.options}
                    explanation={question.explanation}
                    selectedOptions={[]}
                    onSelect={onAnswer}
                />
            );

        case QuestionnaireQuestionFormat.MultipleChoiceSingle:
            return (
                <SingleChoiceQuestion
                    options={question.options}
                    explanation={question.explanation}
                    selectedOption={undefined}
                    onSelect={onAnswer}
                />
            );

        default:
            return <div>Unsupported question format</div>;
    }
};

// Example usage in a parent component
const QuestionnaireForm = () => {
    const [answers, setAnswers] = useState({});

    const handleAnswer = (questionId) => (selected) => {
        setAnswers(prev => ({
            ...prev,
            [questionId]: selected
        }));
    };

    // Sample question data (normally from API)
    const sampleQuestions = [
        {
            id: "q1",
            format: QuestionnaireQuestionFormat.MultipleChoiceSingle,
            text: "What is your investment experience?",
            explanation: "Please select your experience level",
            options: [
                "No prior investment experience",
                "Some experience with public markets",
                "Experienced with private investments",
                "Professional investor"
            ]
        },
        {
            id: "q2",
            format: QuestionnaireQuestionFormat.Scale,
            text: "How much would you like to invest?",
            explanation: "Drag the slider to select an amount",
            options: ["Investment Amount"],
            scaleMin: 10000,
            scaleMax: 1000000,
            scaleStep: 10000
        }
    ];

    return (
        <div className="questionnaire-form">
            <h1>Investment Questionnaire</h1>

            {sampleQuestions.map(question => (
                <div key={question.id} className="question-container">
                    <h3>{question.text}</h3>
                    <QuestionRenderer
                        question={question}
                        onAnswer={handleAnswer(question.id)}
                    />
                </div>
            ))}

            <button
                onClick={() => console.log('Submitted answers:', answers)}
                className="submit-button"
            >
                Submit
            </button>
        </div>
    );
};

Development & Verification

  1. npm install
  2. npm run build — generates dist/index.js, dist/index.esm.js, and type declarations via Rollup.
  3. npx tsc --noEmit — fast regression check that catches type issues without touching dist/.

Dependencies

  • react / react-dom ^18.2.0 || ^19.0.0 (peer deps)
  • @emotion/react 11.14.x
  • @emotion/styled 11.14.x
  • @mui/material 7.3.x
  • lodash 4.17.21

License

Copyright © 2025 Monark Markets. All rights reserved.