Skip to content

FAQ section

A list of questions that expand to reveal answers, built on Collapsible — one open/close disclosure per question. Stacking several Collapsibles is the documented way to get an accordion. Answers are ReactNode, so you can drop links or short lists inside. Set defaultOpenIndex to leave one question expanded on load.

'use client';
import type { ReactNode } from 'react';
import { Collapsible, Stack, Text } from '@helix-ui/core';
export interface FaqItem {
question: string;
answer: ReactNode;
}
export interface FaqSectionProps {
title?: string;
items: FaqItem[];
/** Index of the entry to leave expanded initially. */
defaultOpenIndex?: number;
}
export function FaqSection({
title = 'Frequently asked',
items,
defaultOpenIndex,
}: FaqSectionProps) {
return (
<Stack gap={4} style={{ maxWidth: 680 }}>
<Text as="h2" size="2xl" weight="semibold">
{title}
</Text>
<Stack gap={2}>
{items.map((item, i) => (
<Collapsible
key={item.question}
title={item.question}
defaultExpanded={i === defaultOpenIndex}
>
<Text as="p" size="sm" tone="secondary">
{item.answer}
</Text>
</Collapsible>
))}
</Stack>
</Stack>
);
}

Usage

<FaqSection
defaultOpenIndex={0}
items={[
{
question: 'Is helix-ui free to use?',
answer: 'Yes. The core and icons packages are MIT-licensed.',
},
{
question: 'Do I need Tailwind?',
answer: 'No. Styling is driven by CSS custom properties — no utility framework required.',
},
{
question: 'Can I theme it?',
answer: 'Override the token custom properties on :root, or wrap a subtree in ThemeProvider.',
},
]}
/>

Notes

  • Leave at most one entry open by default. A wall of expanded answers defeats the point of collapsing them.
  • Questions should read as questions. “Pricing” is a nav label; “How much does it cost?” is an FAQ.