1.0.5 • Published 7 months ago

@monarkmarkets/question-types v1.0.5

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

@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

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)

PropTypeDefaultDescription
idstringundefinedOptional unique identifier
disabledbooleanfalseWhether the component is disabled
errorstringundefinedCustom error message
optionsstring[](required)Array of options to display
onSelect(selected: string[]) => void(required)Callback function when selection changes
explanationstringundefinedOptional explanation or help text
showNoneOptionbooleanfalseWhether to show "None of the Above" option

SingleChoiceQuestion Props

PropTypeDefaultDescription
selectedOptionstringundefinedThe currently selected option
allowDeselectbooleanfalseWhether options can be deselected
renderOption(option: string, isSelected: boolean) => React.ReactNodeundefinedCustom render function for options

MultiChoiceQuestion Props

PropTypeDefaultDescription
selectedOptionsstring[][]The currently selected options
allowDeselectbooleantrueWhether options can be deselected
renderOption(option: string, isSelected: boolean) => React.ReactNodeundefinedCustom render function for options

ScaleQuestion Props

PropTypeDefaultDescription
minnumber(required)Minimum value of the scale
maxnumber(required)Maximum value of the scale
stepnumber(required)Step value for the scale
defaultValuenumber0Default value for the scale
minLabelstringundefinedLabel for the minimum value
maxLabelstringundefinedLabel for the maximum value
marksScaleMark[]undefinedCustom scale mark points
showNumberLabelsbooleanfalseWhether to show number labels on the scale
currencyCurrencyConfigundefinedConfiguration for currency formatting
formatDisplay(value: number) => stringundefinedCustom function to format the display value
selectedValuesstring[][]Previously selected values

CurrencyConfig

PropertyTypeDescription
symbolstringCurrency symbol (e.g., 'USD', 'EUR')
position'prefix' | 'suffix'Position of the currency symbol
localestringOptional locale for number formatting

ScaleMark

PropertyTypeDescription
valuenumberThe value where the mark should appear
labelstringThe 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>
  );
};

Dependencies

  • React 18.0+
  • @emotion/react 11.0+
  • @emotion/styled 11.0+
  • @mui/material 5.14+
  • lodash 4.17+

License

Copyright © 2025 Monark Markets. All rights reserved.

1.0.5

7 months ago

1.0.4

7 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

8 months ago

1.0.0

8 months ago