Compound-component tabs
Tabs.List, Tabs.Tab, Tabs.Panel — context inside.
Build a Tabs component using the compound component pattern: Tabs.List, Tabs.Tab, and Tabs.Panel as co-ordinated sub-components sharing state via context.
The Pattern
Instead of a single <Tabs panels={[...]} /> with data passed as props, compound components give callers control over structure:
<Tabs defaultTab="about"> <Tabs.List> <Tabs.Tab id="about">About</Tabs.Tab> <Tabs.Tab id="work">Work</Tabs.Tab> <Tabs.Tab id="contact">Contact</Tabs.Tab> </Tabs.List>
<Tabs.Panel id="about"> <About /> </Tabs.Panel> <Tabs.Panel id="work"> <Work /> </Tabs.Panel> <Tabs.Panel id="contact"> <Contact /> </Tabs.Panel></Tabs>The caller decides layout. The component handles the state wiring.
The Implementation
const TabsContext = createContext(null);
function Tabs({ defaultTab, children }) { const [activeTab, setActiveTab] = useState(defaultTab); return ( <TabsContext.Provider value={{ activeTab, setActiveTab }}> <div className="tabs">{children}</div> </TabsContext.Provider> );}
function TabList({ children }) { return <div role="tablist">{children}</div>;}
function Tab({ id, children }) { const { activeTab, setActiveTab } = useContext(TabsContext); const isActive = activeTab === id; return ( <button role="tab" aria-selected={isActive} aria-controls={`panel-${id}`} onClick={() => setActiveTab(id)} > {children} </button> );}
function Panel({ id, children }) { const { activeTab } = useContext(TabsContext); if (activeTab !== id) return null; return ( <div role="tabpanel" id={`panel-${id}`}> {children} </div> );}
Tabs.List = TabList;Tabs.Tab = Tab;Tabs.Panel = Panel;Why Compound Components
A prop-based <Tabs panels={data} /> locks callers into your layout. Compound components let callers render anything between <Tabs.List> and <Tabs.Panel> — extra controls, ads, whatever — without the component needing to know about it.
Why It Matters
The compound pattern is used in Radix UI, Headless UI, and React Aria. Understanding it means you can use those libraries fluently and recognize when to apply the pattern in your own work.