Hone logo
Hone
Problems

Building a Nested Dropdown Menu in React with TypeScript

This challenge focuses on creating a reusable, nested dropdown menu component in React using TypeScript. Nested dropdowns are commonly used in applications with hierarchical data, such as category selection in e-commerce or organizational structures, providing a clean and intuitive user experience for navigating complex options. Your task is to build a component that can render a dropdown menu with multiple levels of nested options.

Problem Description

You need to create a React component called NestedDropdown that renders a dropdown menu with nested options. The component should accept a data structure representing the menu hierarchy as a prop. Each level of the hierarchy should be rendered as a dropdown, allowing users to navigate through the options.

Key Requirements:

  • Data Structure: The component should accept a prop called options which is an array of objects. Each object represents a menu item and has the following structure:
    • label: (string) The text to display for the menu item.
    • children?: (NestedDropdownOptions[]) An optional array of objects representing the child menu items (nested dropdown). If children is present, a nested dropdown will be rendered.
    • value?: (any) An optional value associated with the menu item. This can be any data type.
  • Rendering: The component should render a dropdown menu for each level of the hierarchy.
  • State Management: The component should manage its own internal state to track the currently open dropdown level.
  • Click Handling: Clicking on a menu item with children should open the corresponding nested dropdown. Clicking on a menu item without children should trigger an action (e.g., updating a state variable, calling a callback function - this is not required for this challenge, but consider it for future extensibility).
  • Styling: Basic styling is expected to make the dropdown functional and visually understandable. You don't need to create a highly polished UI, but the dropdown should be clearly identifiable and usable.

Expected Behavior:

  • When the component mounts, no dropdowns should be open by default.
  • Clicking on a menu item with children should open the corresponding nested dropdown.
  • Clicking on the same menu item again should close the nested dropdown.
  • The dropdowns should be visually distinct and easy to navigate.

Edge Cases to Consider:

  • Empty options array: The component should render nothing or a placeholder message.
  • Deeply nested menus: The component should handle menus with multiple levels of nesting without performance issues.
  • Menu items with only text and no value.

Examples

Example 1:

Input:
options: [
  { label: 'Category 1', children: [
    { label: 'Subcategory 1.1', value: 'value1.1' },
    { label: 'Subcategory 1.2', value: 'value1.2' }
  ]},
  { label: 'Category 2', children: [
    { label: 'Subcategory 2.1', value: 'value2.1' },
    { label: 'Subcategory 2.2', value: 'value2.2' }
  ]}
]
Output:
A dropdown menu with two top-level options: "Category 1" and "Category 2". Clicking "Category 1" opens a dropdown with "Subcategory 1.1" and "Subcategory 1.2". Clicking "Category 2" opens a dropdown with "Subcategory 2.1" and "Subcategory 2.2".

Example 2:

Input:
options: [
  { label: 'Option 1', value: 'option1' },
  { label: 'Option 2', value: 'option2' },
  { label: 'Option 3', children: [
    { label: 'Suboption 3.1', value: 'suboption3.1' },
    { label: 'Suboption 3.2', value: 'suboption3.2' }
  ]}
]
Output:
A dropdown menu with three top-level options: "Option 1", "Option 2", and "Option 3". Clicking "Option 3" opens a dropdown with "Suboption 3.1" and "Suboption 3.2".

Example 3: (Edge Case)

Input:
options: []
Output:
(Nothing is rendered, or a message like "No options available")

Constraints

  • Time Limit: You have 60 minutes to complete this challenge.
  • Dependencies: You can only use React and TypeScript. No external libraries are allowed.
  • Performance: The component should render efficiently, even with deeply nested menus (up to 5 levels deep).
  • Code Quality: Write clean, readable, and well-documented code.

Notes

  • Consider using recursion to render the nested dropdowns.
  • Think about how to manage the state of the open/closed dropdowns efficiently.
  • Focus on creating a functional and reusable component. Styling is secondary.
  • Type safety is important. Leverage TypeScript to ensure the correctness of your code.
  • The value property is optional and not required for the core functionality of the dropdown. It's included for potential future extensions.
  • Consider using a unique key prop for each menu item to improve React's rendering performance.
Loading editor...
typescript