React Tabs Component Implementation
This challenge asks you to build a reusable tab component in React using TypeScript. A tabs component allows users to switch between different views or content sections by clicking on tab headers. This is a common UI pattern used to organize information and improve user experience.
Problem Description
You need to implement a Tabs component that renders a set of tab headers and their corresponding content panels. The component should accept an array of tab objects, each containing a title (string) and a content (React.ReactNode). Only one tab's content should be visible at a time, corresponding to the currently selected tab. Clicking a tab header should update the active tab and display its content.
Key Requirements:
- Dynamic Tabs: The component should be able to handle a variable number of tabs passed as props.
- Active Tab Management: The component must maintain the state of the currently active tab.
- Content Rendering: The content associated with the active tab should be rendered.
- Accessibility: The tab headers should be focusable and navigable using the keyboard (arrow keys to move between tabs, Enter to select).
- Styling: While specific styling isn't required, the component should be structured in a way that allows for easy styling. Consider using CSS classes for styling.
Expected Behavior:
- Initially, the first tab in the array should be active.
- Clicking a tab header should:
- Update the component's state to reflect the new active tab.
- Render the content of the newly selected tab.
- The other tab content should be hidden.
- Keyboard navigation should allow users to cycle through the tabs and select them using the Enter key.
Edge Cases to Consider:
- Empty tab array: The component should render gracefully (e.g., display a message indicating no tabs are available).
- Invalid tab data: Handle cases where a tab object might be missing a
titleorcontent. - Large number of tabs: Consider performance implications if a very large number of tabs are rendered.
Examples
Example 1:
Input:
tabs = [
{ title: "Home", content: <div>Home Content</div> },
{ title: "About", content: <div>About Content</div> },
{ title: "Contact", content: <div>Contact Content</div> }
]
Output:
Renders a tab component with three tabs: "Home", "About", and "Contact". Initially, "Home" is active and displays "Home Content". Clicking "About" makes "About" active and displays "About Content". Clicking "Contact" makes "Contact" active and displays "Contact Content".
Example 2:
Input:
tabs = []
Output:
Renders a message like "No tabs available." or an empty container.
Example 3: (Edge Case - Invalid Data)
Input:
tabs = [
{ title: "Tab 1", content: <div>Content 1</div> },
{ title: "", content: <div>Content 2</div> }, // Missing title
{ title: "Tab 3", content: null } // Null content
]
Output:
Renders "Tab 1" and "Tab 3". The tab with the missing title is either skipped or rendered with a default title (e.g., "Untitled"). The tab with null content renders an empty container or a placeholder.
Constraints
- Component Structure: The component should be well-structured and easy to understand.
- TypeScript: Use TypeScript for type safety.
- React Hooks: Utilize React Hooks (e.g.,
useState) for state management. - Performance: The component should render efficiently, even with a moderate number of tabs (e.g., up to 10). Avoid unnecessary re-renders.
- Accessibility: Ensure the component is accessible to users with disabilities, following ARIA best practices.
Notes
- Consider using CSS classes for styling to keep the component flexible.
- Think about how to handle potential errors or invalid data in the
tabsarray. - Focus on creating a reusable and maintainable component.
- You can use any React library for styling (e.g., styled-components, emotion) or plain CSS. The focus is on the component's logic and structure.
- Keyboard navigation is a crucial aspect of accessibility. Pay close attention to how users will interact with the tabs using the keyboard.