AniUI Academy
easy+160 XP

Build an accordion

Render three FAQ-style panels, each with a clickable header and hidden body content.

Clicking a header's panel open toggles it — but opening one panel must close whichever other panel was open, since only one can be expanded at a time.

Requirements

  • Each panel header is a `<button data-testid="accordion-header-ID">`.
  • Each panel body renders only while open, as `<div data-testid="accordion-body-ID">` — absent from the DOM while closed, not just hidden.
  • All panels start closed.
  • Opening a panel closes any other panel that was open — at most one body is ever present at once.
  • Clicking the header of the currently-open panel closes it, leaving none open.

Your workspace

import { useState } from "react";

const PANELS = [
  { id: 1, title: "What is this?", body: "A frequently-asked-questions accordion." },
  { id: 2, title: "How do I use it?", body: "Click a question to reveal its answer." },
  { id: 3, title: "Can more than one be open?", body: "No — opening one should close any other." },
];

export default function App() {
  const [openId, setOpenId] = useState(null);

  // TODO: clicking a header should toggle its panel, and opening one
  // panel should close whichever other one was open.

  return (
    <div style={{ fontFamily: "sans-serif", padding: 16 }}>
      {PANELS.map((panel) => (
        <div key={panel.id} style={{ borderBottom: "1px solid #ddd" }}>
          <button
            data-testid={`accordion-header-${panel.id}`}
            style={{ width: "100%", textAlign: "left", padding: 12, fontWeight: "bold" }}
          >
            {panel.title}
          </button>
          <div data-testid={`accordion-body-${panel.id}`} style={{ padding: 12 }}>
            {panel.body}
          </div>
        </div>
      ))}
    </div>
  );
}

Ready to check it?

5 tests run against your rendered component, right here in your browser. Sign in to claim the XP when you pass.

Stuck? The react course covers the ideas this problem is built on.