AniUI Academy
easy+150 XP

Build accessible tabs

Build a tab list with three tabs, each showing its own panel.

Clicking a tab activates it. The keyboard has to work too: with a tab active, ArrowRight/ArrowLeft move to the next/previous tab and activate it immediately, wrapping around at each end.

Requirements

  • Each tab is a `<button role="tab" aria-selected="true|false">`, and there are exactly three.
  • Exactly one `<div role="tabpanel">` is present at a time — the one for the active tab.
  • Clicking a tab makes it the active one.
  • With the last tab active, ArrowRight moves to the first tab. With the first tab active, ArrowLeft moves to the last.

Your workspace

import { useState } from "react";

const TABS = [
  { key: "overview", label: "Overview", content: "Overview content" },
  { key: "specs", label: "Specs", content: "Specs content" },
  { key: "reviews", label: "Reviews", content: "Reviews content" },
];

export default function App() {
  const [active, setActive] = useState(0);

  function handleKeyDown(e) {
    // TODO: ArrowRight should move to the next tab (wrapping to the
    // first after the last), ArrowLeft to the previous (wrapping to
    // the last from the first) — and the newly reached tab should
    // become active, same as clicking it.
  }

  return (
    <div style={{ fontFamily: "sans-serif", padding: 16 }}>
      <div role="tablist" style={{ display: "flex", gap: 8 }}>
        {TABS.map((tab, index) => (
          <button
            key={tab.key}
            id={`tab-${tab.key}`}
            role="tab"
            aria-selected={index === active}
            onClick={() => setActive(index)}
            onKeyDown={handleKeyDown}
            style={{ padding: "8px 12px", fontWeight: index === active ? "bold" : "normal" }}
          >
            {tab.label}
          </button>
        ))}
      </div>
      <div id={`panel-${TABS[active].key}`} role="tabpanel" style={{ padding: 16, border: "1px solid #ddd" }}>
        {TABS[active].content}
      </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.