Skip to content
Live coding ยท 25 minutes

Tabs with keyboard support

Build a tabs component in React in 25 minutes, with no UI library. It shows a row of tabs and one panel at a time, and a click on a tab shows its panel. It must follow the standard tabs pattern for keyboard and screen reader users. Start with the simplest version that works, then add the keyboard support. Explain your decisions while you code, as in a live round.

Requirements

  • A row of tabs and one visible panel; a click on a tab selects it
  • Roles: tablist on the container, tab on each tab, tabpanel on each panel
  • The selected tab has aria-selected true and aria-controls with the id of its panel; the panel has aria-labelledby with the id of its tab
  • Only the selected tab has tabindex 0 and the others have -1, so the Tab key leaves the tab list and goes to the panel
  • A panel with no focusable content has tabindex 0, so the keyboard can reach it
  • Left and Right arrows move focus between tabs and wrap at the ends; Home and End go to the first and the last tab
  • The API takes a list of items, or composed children, and an optional default tab

What reviewers look for

  • Minimal state: one selected id or index, and the rest is derived
  • Correct roles, and correct links between each tab and its panel
  • Keyboard handling in one place, with wrapping, and with focus moved to the new tab
  • Unique ids for tabs and panels, for example from useId
  • You say whether an arrow key selects the tab at once or only moves focus, and why
  • An API that another developer can use without reading the code

Check before you hand it in

  • A click on a tab shows its panel and hides the other panels
  • Left and Right arrows move focus between the tabs and wrap from the last tab to the first
  • Home moves to the first tab and End moves to the last tab
  • The Tab key goes from the selected tab to the panel or its first control, not to the next tab
  • The accessibility inspector shows tablist, tab and tabpanel roles, aria-selected on the active tab, and ids that match in aria-controls and aria-labelledby
  • I explained each decision aloud while I coded
  • Selection by click and by arrow keys worked within 25 minutes

If there is time

  • A disabled tab that the arrow keys skip
  • A controlled mode with value and onChange
  • A vertical tab list with Up and Down arrows and aria-orientation