Interactive Collapsible Navigation in React
This challenge asks you to build a reusable React component that implements a collapsible navigation menu. Collapsible navigation is a common UI pattern used to conserve screen space, especially on smaller devices, by hiding less frequently used navigation items until explicitly requested. This component will allow users to toggle the visibility of navigation items, providing a clean and efficient user experience.
Problem Description
You are tasked with creating a CollapsibleNavigation component in React using TypeScript. This component should accept an array of navigation items, each with a label and an optional URL. The component should initially render all navigation items collapsed. Clicking on a navigation item's label should toggle its visibility (expand/collapse). When expanded, the navigation item should display its label and, if a URL is provided, a link to that URL. When collapsed, only the label should be visible.
Key Requirements:
- TypeScript: The solution must be written in TypeScript.
- Collapsible Behavior: Clicking a navigation item's label toggles its expanded state.
- Rendering: Expanded items display both label and URL (as a link). Collapsed items display only the label.
- Reusability: The component should be reusable with different navigation item data.
- Accessibility: Ensure the component is accessible (e.g., proper ARIA attributes for toggle functionality).
Expected Behavior:
- Initially, all navigation items are collapsed.
- Clicking a label expands the item, revealing the URL (if present).
- Clicking the same label collapses the item again.
- The component should handle cases where a navigation item does not have a URL.
- The component should render correctly with an empty array of navigation items (displaying nothing).
Edge Cases to Consider:
- Empty navigation item array.
- Navigation items with and without URLs.
- Clicking on the link itself (should not trigger the toggle).
- Keyboard navigation (using arrow keys to navigate between items and spacebar to toggle).
Examples
Example 1:
Input:
const navItems = [
{ label: 'Home', url: '/' },
{ label: 'About', url: '/about' },
{ label: 'Services' },
];
Output:
(Initial Render - All collapsed)
- Home
- About
- Services
(After clicking 'About')
- Home
- About (expanded, showing link to /about)
- Services
(After clicking 'About' again)
- Home
- About (collapsed)
- Services
Explanation: Clicking 'About' toggles its visibility and displays the link. Clicking it again collapses it.
Example 2:
Input:
const navItems = [];
Output:
(Empty component - nothing is rendered)
Explanation: Handles the case where there are no navigation items.
Example 3: (Edge Case - No URL)
Input:
const navItems = [
{ label: 'Contact' },
];
Output:
(Initial Render)
- Contact
(After clicking 'Contact')
- Contact (expanded, no link displayed)
Explanation: Handles navigation items without a URL gracefully.
Constraints
- Component Structure: The component should be a functional component using React Hooks.
- Styling: You can use inline styles or a CSS-in-JS library (e.g., styled-components) for styling. Focus on functionality over elaborate styling.
- Performance: The component should render efficiently, even with a large number of navigation items (assume up to 50 items).
- Dependencies: Minimize external dependencies. React and React DOM are assumed to be available.
- Typescript: Use appropriate Typescript types for props and state.
Notes
- Consider using the
useStatehook to manage the expanded state of each navigation item. - Use a unique key prop for each navigation item in the rendered list.
- Think about how to handle click events on the link itself to prevent the toggle from being triggered. You might need to use event delegation or conditional rendering.
- While full keyboard accessibility is not strictly required, consider how a user might navigate the menu using the keyboard. This is a good opportunity to demonstrate understanding of ARIA attributes.
- Focus on creating a clean, well-structured, and maintainable component.