Quiz Form
The QuizForm component provides a fully animated, multi-step survey and onboarding form interface. It supports single-choice, multiple-choice, and star/numeric rating questions, with a token-based variant system that makes adding new visual styles a zero-logic-change operation.
- Preview
- Code
Question 1 of 425%
Single Choice
How did you first hear about us?
import { QuizForm } from '@ignix-ui/quizform';
const questions = [
{ id: 'q1', type: 'single', question: 'How did you hear about us?', options: ['Social Media', 'Search', 'Referral'], required: true },
{ id: 'q2', type: 'multiple', question: 'Which features matter most?', hint: 'Select all that apply', options: ['Speed', 'Design', 'Price'], required: true },
{ id: 'q3', type: 'rating', question: 'Overall satisfaction', scale: 5, required: true },
{ id: 'q4', type: 'rating', question: 'How likely are you to recommend us to a friend?', scale: 10, required: true },
];
<QuizForm
questions={questions}
onSubmit={(answers) => console.log(answers)}
cardVariant="default"
showResult={true}
submitLabel="Submit"
nextLabel="Continue"
backLabel="Back"
/>
Installation
- CLI
- Manual
ignix add component quiz-form
// Dependencies: framer-motion, class-variance-authority, @radix-ui/react-icons
// Copy index.tsx to your components directory and adjust the cn import path.
Props
<QuizForm>
| Prop | Type | Default | Description |
|---|---|---|---|
questions | Question[] | — | Required. Array of question objects to render. |
onSubmit | (answers: QuizAnswers) => void | — | Required. Called with all answers when the user submits. |
onStepChange | (step: number, total: number) => void | undefined | Fires on every navigation step change. |
initialAnswers | QuizAnswers | {} | Pre-populate answers (e.g. editing a previous submission). |
cardVariant | 'default' | 'gradient' | 'bordered' | 'dark' | 'default' | Visual style of the question card. |
showResult | boolean | true | Show a results summary page after submission. |
stepLabels | string[] | undefined | Short labels rendered as pill-progress above the bar (onboarding mode). |
submitLabel | string | 'Submit' | Label for the submit button on the last question. |
nextLabel | string | 'Continue' | Label for the next/continue button. |
backLabel | string | 'Back' | Label for the back button. |
className | string | undefined | Extra classes applied to the outer page wrapper. |
children | React.ReactNode | undefined | Pass sub-components directly for compound usage. |
theme | 'light' | 'dark' | 'light' | theme selection. |
Question object
| Field | Type | Required | Description |
|---|---|---|---|
id | string | ✓ | Unique identifier; used as the key in the answers map. |
type | 'single' | 'multiple' | 'rating' | ✓ | Determines which input control is rendered. |
question | string | ✓ | The question text displayed to the user. |
hint | string | Secondary helper text shown below the question. | |
options | string[] | For single / multiple | Answer options for choice questions. |
scale | number | For rating | Number of steps — ≤ 5 renders stars, > 5 renders a numeric NPS row. |
required | boolean | Defaults to true. Set to false to allow skipping. |
Sub-components
All sub-components consume QuizFormContext internally — they must be rendered inside a <QuizForm> provider.
| Component | Description |
|---|---|
QuizForm.ProgressBar | Animated progress bar with optional step-label pills. |
QuizForm.QuestionCard | Renders the current question with a slide transition. |
QuizForm.RadioGroup | Single-choice radio button group. |
QuizForm.CheckboxGroup | Multiple-choice 2-column checkbox grid. |
QuizForm.RatingScale | Star rating (scale ≤ 5) or numeric NPS row (scale > 5). |
QuizForm.NavigationButtons | Back + Next/Submit buttons with disabled state handling. |
QuizForm.ResultPage | Submission confirmation with per-question answer summary. |
QuizForm.AccentBar | Thin accent bar using the primary theme color. |
useQuizForm hook
Access the full form context from any custom sub-component:
import { useQuizForm } from '@ignix-ui/quizform';
function MyCustomControl() {
const { step, total, answers, goNext, cardVariant } = useQuizForm();
return <span>{step + 1} / {total}</span>;
}
The hook throws if called outside a <QuizForm> provider.
Examples
Feedback survey
import { QuizForm } from '@ignix-ui/quizform';
<QuizForm
questions={questions}
onSubmit={(answers) => console.log(answers)}
cardVariant="default"
showResult={true}
/>
Onboarding flow with step labels
<QuizForm
questions={onboardingQuestions}
onSubmit={handleSubmit}
stepLabels={['Role', 'Team', 'Goals', 'Experience']}
submitLabel="Finish Setup"
nextLabel="Next Step"
/>
Gradient variant
<QuizForm questions={questions} onSubmit={handleSubmit} cardVariant="gradient" />
Pre-filled answers
<QuizForm
questions={questions}
onSubmit={handleSubmit}
initialAnswers={{ q1: 'Social Media', q3: 4 }}
/>