cf.completefrontend

Write the codeEasy

Build an accessible Accordion with aria-expanded and aria-controls

Accordion takes items, a list of { id, title, content }, and shows each title as a <button> inside an <h3>, with its content in a panel under it. Every panel starts closed. Clicking a title opens its panel, and clicking it again closes it. Panels open and close on their own: opening one leaves the others as they are.

Make it work with a keyboard and a screen reader. Each button has aria-expanded ("true" or "false") and aria-controls set to its panel's id. Each panel is a <div role="region"> with aria-labelledby set to its button's id. A closed panel stays in the page with the hidden attribute, so aria-controls always points at an element. Two accordions on one page must not share any id.

<Accordion
  items={[
    { id: "delivery", title: "How long does delivery take?", content: "Two to three working days." },
    { id: "returns", title: "Can I return an opened tin?", content: "Yes, within 30 days." },
  ]}
/>
Write this (App.jsx)
import { useState } from "react";
 
export default function Accordion({ items }) {
  const [openIds, setOpenIds] = useState([]);
 
  function toggle(id) {
    setOpenIds((ids) => (ids.includes(id) ? ids.filter((openId) => openId !== id) : [...ids, id]));
  }
 
  return (
    <div>
      {items.map((item) => (
        <div key={item.id}>
          <h3 onClick={() => toggle(item.id)}>{item.title}</h3>
          {openIds.includes(item.id) && <div>{item.content}</div>}
        </div>
      ))}
    </div>
  );
}
The checks your code must pass
  • each title is a button inside a heading
  • every panel starts closed, and the buttons say so
  • a click opens a panel, and a second click closes it
  • panels open and close on their own
  • aria-controls points at the panel, which is named by its button
  • a closed panel stays in the page, hidden
  • works from the keyboard
  • two accordions on one page share no ids

Try it in the editor

The answer

Write it yourself first. Then compare it with a reference solution and the checks it passes.

Checking your sign-in…