FAQ section
FAQs as an accordion, a topic rail, or a searchable list that highlights matches.
pnpm dlx shadcn@latest add @uiarc/faq-section- FAQ sections on pricing, product, and support pages.
- Long FAQs that benefit from categories or live search.
- Use accordion for generic collapsible content that is not a question list.
- Use a docs page when answers need code, images, or long structure.
Installation
Add FAQ section with the shadcn CLI, or copy the source by hand.
pnpm dlx shadcn@latest add @uiarc/faq-sectionAdds the block and its local dependencies, and installs motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:
Usage
Use this as a starting point and replace the sample data with your own.
import { FaqSection } from "@/registry/blocks/faq-section/faq-section"; export function PricingFaq() { return ( <FaqSection variant="search" title="Questions about billing" items={[ { question: "Can I cancel anytime?", answer: "Yes. Your plan stays active until the end of the billing period." }, { question: "Do you offer refunds?", answer: "We refund annual plans within 14 days of purchase." }, ]} contact={{ label: "Talk to billing", href: "mailto:billing@example.com" }} /> );}API reference
2 parts. The first is the root.
FaqSection
An FAQ in three layouts: one centered accordion, questions grouped beside a category rail, or a list that filters as you type.
variant"accordion" | "columns" | "search""accordion"Layout.titlestring"Frequently asked questions"Section heading.descriptionstring–One line under the heading.items{ id?: string; question: string; answer: string; category?: string }[]faqExampleItemsQuestions. answer is plain text and is what search matches. category groups the columns variant.multiplebooleanfalseAllow several answers open at once.valuestring[]–Open item ids (controlled). Ids default to the question.defaultValuestring[]–Initially open ids when uncontrolled.onValueChange(value: string[]) => void–Called when answers open or close.categorystring–Active category in the columns variant (controlled).onCategoryChange(category: string) => void–Called when the category changes.querystring–Search text in the search variant (controlled).onQueryChange(query: string) => void–Called as the search text changes.contact{ label: string; description?: string; href?: string; onClick?: () => void } | null–A way to reach a person when the answer isn't here. Pass null to hide it.classNamestring–Extra class on the section.FaqSectionBlock
Default export: a preview with a layout switcher.
variantFaqSectionVariant"accordion"Initial variant.- ArrowUporArrowDown
- Move between questions in one list.
- HomeorEnd
- First or last question.
- EnterorSpace
- Opens or closes the focused answer.
- Questions are buttons with aria-expanded controlling their answer region.
- Search matches are wrapped in mark elements; closed items that match only in the answer show a short excerpt.
- The search variant uses Arc SearchField with a real label.
- Answers open with height and opacity together and the plus icon turns.
- Filtering and category changes move remaining items with layout animation.
- Reduced motion opens and filters instantly.
- Container queries: below 760px the category rail becomes a horizontal scrolling row above the questions; below 480px padding tightens.
- Search filters in memory on each keystroke; fine for dozens of items, not thousands.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Keep answers plain text; the search variant matches and highlights inside them.
- Pass stable ids when questions may be reworded, so controlled open state survives edits.
- Composes Arc SearchField and SegmentedControl.
The full library index for assistants is at /llms.txt.