1.0.5 • Published 7 months ago
@monarkmarkets/question-types v1.0.5
@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-typesFeatures
- 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>
);
};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.