Mini Project: Dynamic FAQ Accordion0%

Mini Project: Dynamic FAQ Accordion

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Mini Project: Dynamic FAQ Accordion

1. Project Overview & Requirements

Accordions are ubiquitous UI patterns in modern web engineering, seen on landing pages, documentation portals, and knowledge bases.

In this project, we will engineer a Dynamic FAQ Accordion with support for:

  1. 1
    Collapsible Panels: Expanding and collapsing individual questions smoothly.
  2. 2
    Single-Open vs Multi-Open Mode: A toggle allowing either one question open at a time (standard accordion) or multiple questions open simultaneously.
  3. 3
    Category Filtering: Filter questions by topic (General, Curriculum, Certification).
  4. 4
    Keyboard Accessibility: Semantic markup and ARIA attributes (aria-expanded, aria-controls).
Output
┌────────────────────────────────────────────────────────┐
│ Frequently Asked Questions │
│ │
│ Mode: [x] Allow multiple sections open │
│ │
│ [▼] What prerequisites are required for React? │
│ └─ Solid foundation in HTML, CSS, and modern ES6 │
│ JavaScript (arrow functions, destructuring). │
│ │
│ [►] Is job placement assistance provided? │
│ [►] Can I access the lab environment on mobile? │
└────────────────────────────────────────────────────────┘

2. Component Implementation

JSX
import React, { useState } from 'react';
 
const FAQ_DATA = [
{
id: 'faq-1',
question: 'What prerequisites are required before starting React?',
answer: 'You should be comfortable with HTML5, modern CSS layouts (Flexbox/Grid), and ES6+ JavaScript concepts including let/const, arrow functions, destructuring, and array methods (map/filter).'
},
{
id: 'faq-2',
question: 'Why should I learn Vite instead of Create React App?',
answer: 'Vite leverages native browser ES Modules and esbuild, resulting in near-instant local server start times, lightning-fast Hot Module Replacement, and optimized production bundles.'
},
{
id: 'faq-3',
question: 'Does MSK Institute provide industry-recognized certificates?',
answer: 'Yes! Upon completing the comprehensive capstone projects and passing the graded quizzes, students receive a cryptographically verifiable MSK Institute Certificate of Completion.'
}
];
 
export default function FaqAccordion() {
// Store an array of active open IDs (supports both single and multi mode)
const [openIds, setOpenIds] = useState(['faq-1']);
const [allowMultiple, setAllowMultiple] = useState(false);
 
const toggleItem = (id) => {
if (allowMultiple) {
// Multi-open mode: toggle id in array
setOpenIds((prev) =>
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
);
} else {
// Single-open mode: open clicked item, or close if already open
setOpenIds((prev) => (prev.includes(id) ? [] : [id]));
}
};
 
return (
<div className="faq-wrapper">
<header className="faq-header">
<h2>Frequently Asked Questions</h2>
{/* Toggle Mode Option */}
<label className="toggle-label">
<input
type="checkbox"
checked={allowMultiple}
onChange={(e) => {
setAllowMultiple(e.target.checked);
// Reset to at most 1 item when switching back to single mode
if (!e.target.checked && openIds.length > 1) {
setOpenIds(openIds.slice(0, 1));
}
}}
/>
Allow multiple sections open at once
</label>
</header>
 
<div className="accordion-list">
{FAQ_DATA.map((item) => {
const isOpen = openIds.includes(item.id);
 
return (
<div key={item.id} className={`accordion-item ${isOpen ? 'active' : ''}`}>
{/* Header Button */}
<button
type="button"
className="accordion-trigger"
onClick={() => toggleItem(item.id)}
aria-expanded={isOpen}
aria-controls={`panel-${item.id}`}
>
<span className="accordion-title">{item.question}</span>
<span className="accordion-icon">{isOpen ? '−' : '+'}</span>
</button>
 
{/* Collapsible Panel */}
{isOpen && (
<div
id={`panel-${item.id}`}
className="accordion-panel"
role="region"
>
<p>{item.answer}</p>
</div>
)}
</div>
);
})}
</div>
</div>
);
}

3. Accessibility & Architectural Highlights

  1. 1
    ARIA Attributes: aria-expanded={isOpen} informs screen readers whether the dropdown is currently open.
  2. 2
    Unified Data Structure: Storing openIds as an array cleanly supports both single-item ([id]) and multi-item ([id1, id2]) expansion modes without duplicate state logic.
  3. 3
    Conditional DOM Mounting: {isOpen && <div ...>} unmounts the panel when closed, keeping the DOM lightweight.

Interactive Quiz

Practice Quiz

Question 1
What ARIA attribute should be added to an accordion trigger button to communicate its expansion state to assistive technologies?
Question 2
How does the accordion component support toggling an item in multi-open mode?
Question 3
What happens when the user unchecks "Allow multiple sections open at once" while 3 sections are open?
Question 4
Why is type="button" explicitly added to the <button> trigger inside the accordion?
Question 5
Why is item.id used as the key instead of the index in the accordion list?
Next Lesson

Mini Project: Real-Time Character Counter and Text Utility

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext