dynamic-react-questionnare-component
v0.1.2
Published
A dynamic,JSON-driven multi-step questionnaire component for React with built-in validation,smooth animations,and a progress indicator.
Downloads
364
Maintainers
Readme
dynamic-react-questionnare-component
A dynamic, JSON-driven multi-step questionnaire component for React. Build fully functional multi-stage forms with built-in validation, smooth animations, and a clean progress indicator — all configured through a single JSON object. Zero form boilerplate.
Installation
npm install dynamic-react-questionnare-componentPeer Dependencies — your project must have
reactandreact-dominstalled:
npm install react react-domSupported peer versions: react >=18.0.0 < 20, react-dom >=18.0.0 < 20
Tailwind setup (required)
This package uses Tailwind utility classes internally. Your Tailwind content must include this package so the classes are not purged.
tailwind.config.js (Tailwind v3+)
Add the package path to content:
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
'./node_modules/dynamic-react-questionnare-component/**/*.{js,ts,jsx,tsx}',
],
theme: { extend: {} },
plugins: [],
};pnpm users
If you use pnpm, dependencies may live under node_modules/.pnpm. Add this too:
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
'./node_modules/dynamic-react-questionnare-component/**/*.{js,ts,jsx,tsx}',
'./node_modules/.pnpm/**/node_modules/dynamic-react-questionnare-component/**/*.{js,ts,jsx,tsx}',
],Quick Start
import React from 'react';
import { Questionnaire } from 'dynamic-react-questionnare-component';
const config = {
stages: ['Personal Info', 'Feedback'],
fields: [
{
name: 'user_name',
label: 'What is your full name?',
type: 'text',
required: true,
stage: 'Personal Info',
placeholder: 'e.g. John Doe',
},
{
name: 'satisfaction',
label: 'How satisfied are you?',
type: 'radio',
required: true,
stage: 'Feedback',
options: ['Very Satisfied', 'Satisfied', 'Neutral', 'Dissatisfied'],
},
],
};
function App() {
return (
<Questionnaire
config={config}
onSubmit={(formData) => console.log('Submitted:', formData)}
/>
);
}
export default App;Exports
| Export | Type | Description |
|---|---|---|
| Questionnaire | Component | Main multi-step form component |
| FieldRenderer | Component | Renders a single field — useful for custom layouts |
| ProgressBar | Component | Backwards-compatible alias for NumberedProgressBar1 |
| NumberedProgressBar1 | Component | Numbered progress bar with fill track |
| NamedProgressBar1 | Component | Stage-name progress bar (no numbers) with > separators |
| formConfig | Object | Built-in sample config as a starting template |
TypeScript types also exported:
| Type | Description |
|---|---|
| QuestionnaireConfig | Shape of the config prop |
| FieldConfig | Shape of a single field object |
| FieldType | Union of all supported field type strings |
| QuestionnaireProps | Props for <Questionnaire /> |
| FieldRendererProps | Props for <FieldRenderer /> |
| ProgressBarProps | Props for <ProgressBar /> |
| FormData | Shape of the object passed to onSubmit |
import {
Questionnaire,
FieldRenderer,
ProgressBar,
NumberedProgressBar1,
NamedProgressBar1,
formConfig,
} from 'dynamic-react-questionnare-component';
import type {
QuestionnaireConfig,
FieldConfig,
FieldType,
FormData,
} from 'dynamic-react-questionnare-component';<Questionnaire />
The primary component. Handles stage navigation, per-stage validation, and submission.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| config | QuestionnaireConfig | ✅ | — | The form configuration object |
| onSubmit | (data: FormData) => void | ❌ | console.log | Callback fired on final submission |
<Questionnaire
config={config}
onSubmit={(formData) =>
fetch('/api/submit', {
method: 'POST',
body: JSON.stringify(formData),
})
}
/>Config Object
interface QuestionnaireConfig {
stages: string[]; // Ordered list of stage names
fields: FieldConfig[]; // All field definitions across all stages
// Optional headings
topHeading?: string; // Outside the card (page-level)
topSubHeading?: string; // Outside the card (page-level)
mainHeading?: string; // Inside the card header
subHeading?: string; // Inside the card header
// Optional stage header copy (supports {stage} token)
stageHeading?: string;
stageDescription?: string;
// Progress bar UI
progressBarVariant?: 'numberedprogressbar1' | 'namedprogressbar1';
// Primary accent color used for themed UI (buttons, progress accents, stage heading)
themeColor?: string;
// Optional colors (CSS color strings)
colors?: {
background?: string; // Outermost page background
cardHeader?: string; // Header background (color or gradient string)
cardMain?: string; // Main area background
cardFooter?: string; // Footer background
headings?: {
topHeading?: string;
mainHeading?: string;
stageHeading?: string;
};
subHeadings?: {
topSubHeading?: string;
subHeading?: string;
stageDescription?: string;
};
text?: {
default?: string;
muted?: string;
};
};
// Optional layout sizing (percent-based)
area?: {
cardWidthPercent?: number; // 0–100 (% of container width)
cardHeightPercent?: number; // 0–100 (% of viewport height, via vh)
headerPercent?: number; // 0–100 (% of card height)
footerPercent?: number; // 0–100 (% of card height)
};
// Optional UI effects to run after successful submit
EffectOnSubmit?: 'confetti' | 'bigCheck' | 'firework';
// Success screen (after submit)
endHeader?: string;
endSubHeader?: string;
enableStartOver?: boolean;
// Show a scrollable preview page before final submit
previewMode?: boolean;
}stages
An ordered array of stage name strings. Each entry becomes one step in the progress bar.
stages: ['Personal Info', 'Preferences', 'Feedback']Important: every field's
stageproperty must exactly match one of these strings.
Field Object (FieldConfig)
interface FieldConfig {
name: string; // Unique key — appears in formData
label: string; // Displayed above the input
type: FieldType; // See supported types below
stage: string; // Must match a value in stages[]
required?: boolean; // Blocks advancement if empty
placeholder?: string;// For text / email / number / textarea
options?: string[]; // Required for radio / checkbox / select
}| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique field identifier — used as the key in formData |
| label | string | ✅ | Display label shown above the input |
| type | FieldType | ✅ | Input type (see supported types below) |
| stage | string | ✅ | Must exactly match one of the stages values |
| required | boolean | ❌ | If true, field must be filled before advancing |
| placeholder | string | ❌ | Placeholder text (text / email / number / textarea only) |
| options | string[] | ❌ | Required for radio, checkbox, and select |
Supported Field Types
type is a union: 'text' | 'email' | 'number' | 'textarea' | 'select' | 'radio' | 'checkbox'
text
{ name: 'user_name', label: 'Full Name', type: 'text', stage: 'Personal Info', required: true, placeholder: 'John Doe' }email
{ name: 'user_email', label: 'Email', type: 'email', stage: 'Personal Info', required: true, placeholder: '[email protected]' }number
{ name: 'user_age', label: 'Age', type: 'number', stage: 'Personal Info', required: false }textarea
{ name: 'comments', label: 'Comments', type: 'textarea', stage: 'Feedback', placeholder: 'Write here...' }select
{
name: 'experience_level',
label: 'Experience Level',
type: 'select',
stage: 'Preferences',
required: true,
options: ['Beginner', 'Intermediate', 'Advanced'],
}radio — single choice
{
name: 'satisfaction',
label: 'How satisfied are you?',
type: 'radio',
stage: 'Feedback',
required: true,
options: ['Very Satisfied', 'Satisfied', 'Neutral', 'Dissatisfied'],
}checkbox — multi-select
{
name: 'interests',
label: 'Areas of Interest',
type: 'checkbox',
stage: 'Preferences',
required: true,
options: ['Technology', 'Design', 'Marketing'],
}Note:
checkboxvalues informDataare always astring[].
formData Shape
The object passed to onSubmit maps each field name to its value:
type FormData = Record<string, string | string[]>
// Example:
{
user_name: 'Jane Doe',
user_email: '[email protected]',
experience_level: 'Intermediate',
interests: ['Technology', 'Design'], // checkbox → string[]
satisfaction: 'Very Satisfied',
comments: 'Great experience!',
}Using Individual Components
<ProgressBar />
ProgressBar is a backwards-compatible alias for the numbered progress bar (NumberedProgressBar1).
import { ProgressBar } from 'dynamic-react-questionnare-component';
<ProgressBar
stages={['Step 1', 'Step 2', 'Step 3']}
currentStageIndex={1}
/>| Prop | Type | Required | Description |
|---|---|---|---|
| stages | string[] | ✅ | Ordered array of stage names |
| currentStageIndex | number | ✅ | Zero-based index of the active stage |
Progress bar variants (via config)
Use the variant switch on <Questionnaire />:
const config = {
// ...
progressBarVariant: 'namedprogressbar1', // or 'numberedprogressbar1'
};Styling (colors)
All values are regular CSS colors (hex/rgb/hsl/named colors). Example:
const config = {
// ...
themeColor: '#16A34A', // green
colors: {
background: '#F1F5F9',
// Optional: override header background.
// If omitted, the header gets an automatic themeColor → white gradient.
cardHeader: 'linear-gradient(135deg, rgba(22,163,74,0.12) 0%, #FFFFFF 100%)',
cardMain: '#FFFFFF',
cardFooter: '#F8FAFC',
headings: { stageHeading: '#16A34A' },
text: { default: '#0F172A', muted: '#64748B' },
},
};Layout (area)
You can optionally constrain the card size using percentages:
const config = {
// ...
area: {
cardWidthPercent: 100,
cardHeightPercent: 86,
headerPercent: 24,
footerPercent: 10,
},
};If cardHeightPercent is set, the main area becomes scrollable automatically when content overflows (so the page itself doesn’t scroll).
Special effects (after submit)
Available options:
confetti: falling confettibigCheck: large 3D check that drops into the center with a bouncefirework: 3–5 colorful firework bursts
Example:
const config = {
// ...
EffectOnSubmit: 'firework',
};Success screen (after submit)
Configure the final screen text and whether the reset button shows:
const config = {
// ...
endHeader: 'Thanks!',
endSubHeader: 'We received your response.\nWe appreciate your time.',
enableStartOver: false,
};Preview mode (before submit)
When enabled, the last step becomes:
- Preview (shows a scrollable summary of all questions + answers grouped by stage)
- Confirm & Submit
const config = {
// ...
previewMode: true,
};<FieldRenderer />
Renders a single field with its label, input, and error message. Useful when building a fully custom layout.
import { FieldRenderer } from 'dynamic-react-questionnare-component';
const [formData, setFormData] = useState({});
const [errors, setErrors] = useState({});
<FieldRenderer
field={{ name: 'email', label: 'Email', type: 'email', stage: 'Info', required: true }}
value={formData.email}
onChange={(name, value) => setFormData(prev => ({ ...prev, [name]: value }))}
error={errors.email}
/>| Prop | Type | Required | Description |
|---|---|---|---|
| field | FieldConfig | ✅ | A field config object |
| value | string \| string[] | ✅ | Current controlled value |
| onChange | (name: string, value: string \| string[]) => void | ✅ | Change handler |
| error | string | ❌ | Validation error message |
Full Config Example
import { formConfig } from 'dynamic-react-questionnare-component';
// Use the built-in sample as a reference
console.log(formConfig);Or define your own:
const config = {
stages: ['Personal Info', 'Preferences', 'Feedback'],
fields: [
{ name: 'user_name', label: 'Full Name', type: 'text', required: true, stage: 'Personal Info', placeholder: 'e.g. John Doe' },
{ name: 'user_email', label: 'Email Address', type: 'email', required: true, stage: 'Personal Info', placeholder: '[email protected]' },
{ name: 'user_gender', label: 'Gender', type: 'radio', required: false, stage: 'Personal Info', options: ['Male', 'Female', 'Non-binary', 'Prefer not to say'] },
{ name: 'interests', label: 'Areas of Interest', type: 'checkbox', required: true, stage: 'Preferences', options: ['Technology', 'Design', 'Marketing', 'Engineering'] },
{ name: 'experience', label: 'Experience Level', type: 'select', required: true, stage: 'Preferences', options: ['Beginner', 'Intermediate', 'Advanced'] },
{ name: 'satisfaction',label: 'Satisfaction', type: 'radio', required: true, stage: 'Feedback', options: ['Very Satisfied', 'Satisfied', 'Neutral', 'Dissatisfied'] },
{ name: 'comments', label: 'Additional Comments',type: 'textarea', required: false, stage: 'Feedback', placeholder: 'Type your feedback here...' },
],
};TypeScript
This package ships with full TypeScript declarations. No @types/ package needed.
import { Questionnaire } from 'dynamic-react-questionnare-component';
import type { QuestionnaireConfig, FormData } from 'dynamic-react-questionnare-component';
const config: QuestionnaireConfig = {
stages: ['Info'],
fields: [
{ name: 'name', label: 'Name', type: 'text', stage: 'Info', required: true },
],
};
const handleSubmit = (data: FormData) => {
console.log(data.name); // string | string[]
};
<Questionnaire config={config} onSubmit={handleSubmit} />;Features
- ✅ JSON-driven — define your entire form without writing JSX
- ✅ Multi-stage with animated step-by-step navigation
- ✅ Built-in per-stage validation with inline error messages
- ✅ Supports
text,email,number,textarea,select,radio,checkbox - ✅ Smooth Framer Motion animations between stages
- ✅ Visual progress bar with stage labels
- ✅ Success screen on submission with reset capability
- ✅ Fully composable — use
FieldRendererandProgressBarindependently - ✅ Full TypeScript types included — no extra
@types/package needed - ✅ Peer-dep range
react >=18.0.0 < 20— no unnecessary install conflicts
Links
- npm:
https://www.npmjs.com/package/dynamic-react-questionnare-component - GitHub:
https://github.com/Ashish-cse38/Dynamic-React-Questionnaire-Component-Design-4586 - Issues:
https://github.com/Ashish-cse38/Dynamic-React-Questionnaire-Component-Design-4586/issues
License
MIT © questionnaire-react contributors
