Creating Multi-Level Dropdowns in React with Tailwind CSS

In the world of web development, creating intuitive and user-friendly navigation is crucial for a positive user experience. One powerful tool in our UI toolkit is the multi-level dropdown menu. In this blog post, we’ll explore how to create a flexible and reusable multi-level dropdown component using React and Tailwind CSS.

Why Multi-Level Dropdowns?

Multi-level dropdowns are essential for organizing complex hierarchical data in a compact and navigable format. They’re particularly useful for:

  • E-commerce category navigation
  • File system browsing
  • Organizational charts
  • Complex menu structures

By implementing multi-level dropdowns, we can present a wealth of information without overwhelming the user or cluttering the interface.

Building the Component

Let’s break down the key aspects of our multi-level dropdown component:

1. MultiLevelDropdown Component

This component is responsible for rendering the multi-level dropdown menu. It uses recursion to render nested items.

import React, { useState } from 'react';

const MultiLevelDropdown = ({ items }) => {
  const [openMenus, setOpenMenus] = useState({});

  const toggleMenu = (key) => {
    setOpenMenus(prev => ({ ...prev, [key]: !prev[key] }));
  };

  const renderItems = (menuItems, level = 0) => {
    return menuItems.map((item, index) => {
      const key = `${level}-${index}`;
      const hasChildren = item.children && item.children.length > 0;

      return (
        <li key={key} className="relative">
          <button
            onClick={() => hasChildren && toggleMenu(key)}
            className={`flex items-center w-full px-4 py-2 text-left hover:bg-gray-100 ${hasChildren ? 'font-semibold' : ''}`}
          >
            {item.label}
            {hasChildren && (
              <svg
                className={`w-4 h-4 ml-2 transition-transform ${openMenus[key] ? 'rotate-180' : ''}`}
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
              </svg>
            )}
          </button>
          {hasChildren && openMenus[key] && (
            <ul className="pl-4 mt-2 space-y-2 bg-white rounded-md shadow-lg">
              {renderItems(item.children, level + 1)}
            </ul>
          )}
        </li>
      );
    });
  };

  return (
    <div className="relative inline-block text-left">
      <ul className="mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5">
        {renderItems(items)}
      </ul>
    </div>
  );
};

export default MultiLevelDropdown;

2. EcommerceExample Component

This component demonstrates how to use the MultiLevelDropdown component with example data, representing categories in an e-commerce setting.

import React from 'react';
import MultiLevelDropdown from './MultiLevelDropdown'; // Import the MultiLevelDropdown component

const EcommerceExample = () => {
  const categories = [
    {
      label: 'Electronics',
      children: [
        {
          label: 'Computers',
          children: [
            { label: 'Laptops' },
            { label: 'Desktops' },
            { label: 'Tablets' },
          ],
        },
        {
          label: 'Smartphones',
          children: [
            { label: 'Android' },
            { label: 'iOS' },
          ],
        },
      ],
    },
    {
      label: 'Clothing',
      children: [
        { label: 'Men\'s' },
        { label: 'Women\'s' },
        { label: 'Kids' },
      ],
    },
  ];

  return (
    <div className="p-4">
      <h2 className="text-xl font-bold mb-4">E-commerce Categories</h2>
      <MultiLevelDropdown items={categories} />
    </div>
  );
};

export default EcommerceExample;

3. Rendering EcommerceExample in Your Application

Finally, you would render the EcommerceExample component in your application, typically in the App.js or index.js file.

import React from 'react';
import EcommerceExample from './EcommerceExample'; 
const App = () => {
  return (
    <div className="App">
      <EcommerceExample />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
MultiLevelDropdown

Tailwind CSS Styling

We leverage Tailwind CSS for rapid styling of our component:

  • relative and absolute classes for proper positioning of submenus
  • flex items-center for aligning label and dropdown arrow
  • hover:bg-gray-100 for interactive feedback
  • rounded-md shadow-lg for a modern, elevated look

Conclusion

Multi-level dropdowns are a powerful tool for organizing complex data structures in a user-friendly manner. By combining React’s component-based architecture with Tailwind CSS’s utility-first approach, we can create flexible, reusable, and visually appealing dropdown menus.