Staaarter

FAQ Accordion with Plus/Minus Icons

A single-column FAQ accordion under a centered heading. Each question shows a plus icon that cross-fades into a minus icon the moment it's opened, and back again when it's closed, and only one answer is visible at a time.

By Staaarter Team
Feature
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/faq-accordion-plus-minus.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/feature/feature120.tsx instead.

Usage

The file also exports feature120Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Feature120, feature120Demo } from "@/components/blocks/feature/feature120";

export default function Page() {
  return <Feature120 {...feature120Demo} />;
}

Props

PropTypeDefaultDescription
eyebrowstringundefinedSmall label above the heading; omitted entirely when unset.
headingReactNodenoneSection heading.
descriptionstringundefinedSupporting copy under the heading.
itemsFeature120FaqItem[]noneFAQ entries; all collapsed by default.
classNamestringundefinedExtra classes for the outer section element.

Types

interface Feature120FaqItem {
  question: string;
  answer: string;
}

Behavior notes

  • Real client-side state: `openIndex` (number | null) tracks a single open question via useState, starting at null so every item is collapsed on mount.
  • Implements single-open mode as the real default: opening a question closes whichever one was previously open, and clicking the open question again collapses it. A multi-open variant (each item tracked with its own boolean instead of one shared index, so several answers can stay open at once) is a straightforward variant of the same pattern but is not built here.
  • The plus/minus icon swap is a real state-driven cross-fade (two absolutely-stacked icons, opacity/scale toggled by `isOpen`), not a CSS-only rotate trick, so it's driven by the same state as the accordion panel.
  • "use client" component, so its demo props live in the sibling feature120.demo.tsx file per this repo's client/demo-file-split rule, not in feature120.tsx itself.
  • aria-expanded and aria-controls wire each question button to its answer panel for screen readers; the plus/minus icon pair is aria-hidden since the button's aria-expanded state already conveys open/closed.