FAQ Block
FAQ is an accordion-style frequently asked questions block built on MUI with a centered title, subtitle, and expandable question-and-answer items.
Installation
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-faq-block
yarn add @nodeblocks/frontend-faq-block
pnpm add @nodeblocks/frontend-faq-block
bun add @nodeblocks/frontend-faq-block
What You Need
| Item | Why it matters |
|---|---|
faqTitle | Primary heading |
subtitle | Supporting line below the title |
items | Question-and-answer pairs rendered as accordion rows |
FAQ manages accordion expand/collapse internally. Pass faqTitle, subtitle, and items from your page or CMS. Each item needs question and answer strings.
Code Examples
- Quick Start
- Compound Components
- Block Override
function Example() { const faqItems = [ { question: 'What is this service?', answer: 'This is a comprehensive platform designed to help you manage your business operations efficiently.', }, { question: 'How do I get started?', answer: 'Simply sign up for an account, complete your profile, and you can start using all the features immediately.', }, { question: 'Is there a free trial?', answer: 'Yes, we offer a 14-day free trial with full access to all features. No credit card required.', }, { question: 'How can I contact support?', answer: 'You can reach our support team through email, live chat, or by calling our support hotline during business hours.', }, ]; return ( <FAQ faqTitle="Frequently Asked Questions" subtitle="Find answers to the most common questions about our service" items={faqItems} /> ); }
Compose FAQ.Title and FAQ.ItemList directly and style each block with sx.
function Example() { const faqItems = [ { question: 'What is this service?', answer: 'This is a comprehensive platform designed to help you manage your business operations efficiently.', }, { question: 'How do I get started?', answer: 'Simply sign up for an account, complete your profile, and you can start using all the features immediately.', }, { question: 'Is there a free trial?', answer: 'Yes, we offer a 14-day free trial with full access to all features. No credit card required.', }, ]; return ( <FAQ faqTitle="Frequently Asked Questions" subtitle="Find answers to the most common questions about our service" items={faqItems} > <FAQ.Title sx={{ px: 2, py: 3, borderRadius: 2, bgcolor: 'grey.50', '& .MuiTypography-root:first-of-type': { letterSpacing: 1, textTransform: 'uppercase' }, }} /> <FAQ.ItemList sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 2, overflow: 'hidden', '& .nbb-faq-item': { '&::before': { opacity: 0 } }, }} /> </FAQ> ); }
Use function children with defaultBlocks and defaultBlockOrder to inject blocks, replace defaults, and control order.
function Example() { const faqItems = [ { question: 'What is this service?', answer: 'This is a comprehensive platform designed to help you manage your business operations efficiently.', }, { question: 'How do I get started?', answer: 'Simply sign up for an account, complete your profile, and you can start using all the features immediately.', }, { question: 'Is there a free trial?', answer: 'Yes, we offer a 14-day free trial with full access to all features. No credit card required.', }, { question: 'How can I contact support?', answer: 'You can reach our support team through email, live chat, or by calling our support hotline during business hours.', }, ]; return ( <FAQ faqTitle="Frequently Asked Questions" subtitle="Find answers to the most common questions about our service" items={faqItems} > {({ defaultBlocks }) => ({ blocks: { ...defaultBlocks, supportBanner: ( <Alert severity="info" sx={{ mb: 2 }}> Can't find what you're looking for? Contact our support team for personalized assistance. </Alert> ), itemList: ( <FAQ.ItemList sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 2, overflow: 'hidden', bgcolor: 'background.paper', }} /> ), }, blockOrder: ['title', 'supportBanner', 'itemList'], })} </FAQ> ); }
When to use block overrides
Default defaultBlockOrder is title, item, itemList. The root render uses title and itemList; item is available for granular accordion overrides. Use overrides to prepend banners, replace default blocks, or reorder sections while keeping items on the root component.
Important Props
Core Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
faqTitle | ReactNode | Yes | — | Primary heading rendered by FAQ.Title |
subtitle | ReactNode | Yes | — | Supporting line below the title |
items | { question: string; answer: string }[] | Yes | — | FAQ entries mapped to accordion rows in FAQ.ItemList |
Layout and Composition Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | ReactNode | function | No | undefined | Compound sub-components (FAQ.Title, FAQ.ItemList) or a function ({ defaultBlocks, defaultBlockOrder }) => ({ blocks, blockOrder }) to inject or reorder layout blocks |
className | string | No | undefined | Class name on the root stack (nbb-faq) |
sx | SxProps | No | undefined | MUI system styles for the root stack |
spacing | StackProps['spacing'] | No | { xs: 5, sm: 6 } | Vertical spacing on the root stack |
FAQ inherits StackProps (except children). Default defaultBlockOrder: title, item, itemList.
Sub-component props
Sub-components read from context and accept the same content keys as props to override locally.
| Sub-component | Main Props | Inherits | Built on |
|---|---|---|---|
FAQ.Title | faqTitle, subtitle, children, spacing (default 1), className, sx | StackProps | Stack + Typography |
FAQ.ItemList | items, activeIndex, toggleAccordion, children, className, sx | StackProps | Stack + Divider + FAQ.Item rows |
FAQ.Item | question, answer, index, isActive, onToggle, className, sx | AccordionProps | Accordion + AccordionSummary + AccordionDetails + ExpandMore icon |
Default UI Blocks
| Block | Built on | Notes |
|---|---|---|
FAQ (root) | Stack | Column layout with responsive spacing (nbb-faq) |
title (FAQ.Title) | Stack + Typography | Centered title (variant="h6" / responsive h4) and subtitle (variant="h1") |
itemList (FAQ.ItemList) | Stack + Divider | Maps items to FAQ.Item accordions with dividers above and below |
item (FAQ.Item) | Accordion | Single row with Q. prefix, bold question, and answer body |
Default root render order: title → itemList.
TypeScript
import * as React from 'react';
import { FAQ } from '@nodeblocks/frontend-faq-block';
import type { ReactNode } from 'react';
type FaqItem = {
question: string;
answer: string;
};
type FaqSectionProps = {
faqTitle: ReactNode;
subtitle: ReactNode;
items: FaqItem[];
};
export function FaqSection({ faqTitle, subtitle, items }: FaqSectionProps) {
return <FAQ faqTitle={faqTitle} subtitle={subtitle} items={items} />;
}