React Tabs Component Implementation
Create a reusable React component that displays content in a tabbed interface. This is a fundamental UI pattern used across many web applications to organize and present information efficiently, allowing users to switch between different views or sections of content without leaving the current page.
Problem Description
You are tasked with building a Tabs component in React using TypeScript. This component should accept an array of tab definitions, where each definition includes a label for the tab and the content to be displayed when that tab is active.
Key Requirements:
- The
Tabscomponent should accept a prop, typically namedtabs, which is an array of objects. Each object in the array should have at least two properties:label: A string representing the text displayed on the tab button.content: The React node (JSX, string, etc.) to be rendered when the tab is selected.
- The component should render a set of tab buttons (e.g.,
<button>or<a>elements) based on thelabelof each tab definition. - Only one tab's content should be visible at a time.
- Clicking a tab button should make that tab active and display its corresponding content.
- The component should manage its internal state to keep track of the currently active tab.
- The component should visually indicate which tab is currently active (e.g., by applying a specific CSS class or style).
Expected Behavior:
- When the
Tabscomponent is first rendered, the first tab in thetabsarray should be active by default, and its content should be displayed. - Clicking on any other tab button should de-activate the current tab, activate the clicked tab, and render its associated content.
- The component should handle cases where the
tabsarray might be empty.
Edge Cases to Consider:
- An empty
tabsarray. - Tab content that is complex JSX or other React nodes.
Examples
Example 1:
Input:
const myTabs = [
{ label: 'Section 1', content: <p>Content for Section 1</p> },
{ label: 'Section 2', content: <div><h2>Another Section</h2><p>Details here.</p></div> },
{ label: 'Section 3', content: 'Just plain text content.' },
];
// Rendered as <Tabs tabs={myTabs} />
Output:
The component renders:
- Three clickable buttons labeled "Section 1", "Section 2", and "Section 3".
- Initially, "Section 1" is active. The text "Content for Section 1" is displayed below the tab buttons.
- Clicking "Section 2" makes it active, hides "Content for Section 1", and displays the
divwith "Another Section" and "Details here.". - Clicking "Section 3" makes it active, hides the previous content, and displays "Just plain text content.".
Example 2:
Input:
const emptyTabs: Tab[] = []; // Assuming Tab interface is defined
// Rendered as <Tabs tabs={emptyTabs} />
Output:
The component renders nothing or a placeholder indicating no tabs are available, as the tabs array is empty.
Constraints
- The
tabsprop will be an array of objects, where each object strictly adheres to the definedTabinterface (or a similar structure withlabelandcontent). - The
labelproperty will always be a non-empty string. - The
contentproperty can be any valid React node. - The component should be efficient and avoid unnecessary re-renders.
Notes
- You will need to define the type for the
tabsprop. Consider using an interface or type alias for this. - Think about how you will manage the active tab state. React's
useStatehook is likely your best friend here. - Consider how you will apply styling to indicate the active tab. You might pass down CSS class names or inline styles, or expect the parent component to handle styling through context. For this challenge, simply applying a distinct CSS class to the active tab button is sufficient.
- For this challenge, you do not need to implement any complex animations for tab switching.
- You are free to use any standard React hooks and features.