cf.completefrontend

Write the codeMedium

Build compound Tabs components that share state through context

Write four components that work together: Tabs, TabList, Tab, and TabPanel, exported by name. Tabs keeps which tab is open, starting at its defaultValue. Each Tab and TabPanel has a value; a tab and a panel with the same value belong together.

TabList renders an element with role="tablist". Tab renders a button with role="tab" and aria-selected ("true" on the open tab, "false" on the others), and clicking it opens its panel. TabPanel renders an element with role="tabpanel", labelled by its tab (aria-labelledby), and only while it's open. The parts must work at any depth inside Tabs, even wrapped in other elements, and two Tabs on one page must not affect each other.

<Tabs defaultValue="details">
  <TabList>
    <Tab value="details">Details</Tab>
    <Tab value="reviews">Reviews</Tab>
  </TabList>
  <TabPanel value="details">Grown in Assam.</TabPanel>
  <TabPanel value="reviews">Lovely and malty.</TabPanel>
</Tabs>
Write this (Tabs.jsx)
export function Tabs({ defaultValue, children }) {
  return <div>{children}</div>;
}
 
export function TabList({ children }) {
  return <div role="tablist">{children}</div>;
}
 
export function Tab({ value, children }) {
  return (
    <button type="button" role="tab">
      {children}
    </button>
  );
}
 
export function TabPanel({ value, children }) {
  return <div role="tabpanel">{children}</div>;
}
The checks your code must pass
  • opens the defaultValue tab first
  • clicking a tab opens its panel
  • each panel is labelled by its tab
  • parts work when wrapped in other elements
  • two Tabs keep their own open tab

The answer

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

Checking your sign-in…