← Components/Navigation

SidebarNav

sidebarnav-1779354218951.tsx
'use client';

import { useState } from 'react';

interface NavItem {
  label: string;
  icon: string;
  active?: boolean;
  submenu?: NavItem[];
}

const navItems: NavItem[] = [
  { label: 'Dashboard', icon: 'dashboard', active: true },
  { label: 'Settings', icon: 'settings' },
  {
    label: 'Menu',
    icon: 'menu',
    submenu: [
      { label: 'Submenu 1', icon: 'submenu-1' },
      { label: 'Submenu 2', icon: 'submenu-2' },
    ],
  },
];

const SidebarNav = () => {
  const [collapsed, setCollapsed] = useState(false);
  const [activeItemId, setActiveItemId] = useState('');
  const [openSubmenuIds, setOpenSubmenuIds] = useState<string[]>([]);

  const handleToggleCollapse = () => {
    setCollapsed(!collapsed);
  };

  const handleSetActiveItem = (id: string) => {
    setActiveItemId(id);
  };

  const handleToggleSubmenu = (id: string) => {
    if (openSubmenuIds.includes(id)) {
      setOpenSubmenuIds(openSubmenuIds.filter((itemId) => itemId !== id));
    } else {
      setOpenSubmenuIds([...openSubmenuIds, id]);
    }
  };

  return (
    <div
      className={`h-screen p-4 bg-zinc-950 text-gold-500 transition-width duration-300 ${
        collapsed ? 'w-20' : 'w-64'
      }`}
    >
      <div className="flex justify-between mb-4">
        <span
          className={`text-lg font-bold ${
            collapsed ? 'hidden' : 'block'
          } transition-opacity duration-300`}
        >
          Navigation
        </span>
        <button
          className="p-2 rounded-full hover:bg-zinc-800 transition-colors duration-300"
          onClick={handleToggleCollapse}
        >
          <svg
            xmlns="http://www.w3.org/2000/svg"
            className="h-6 w-6"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
            strokeWidth={2}
          >
            {collapsed ? (
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M9 5l7 7-7 7"
              />
            ) : (
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M15 19l-7-7 7-7"
              />
            )}
          </svg>
        </button>
      </div>
      <ul>
        {navItems.map((item, index) => (
          <li key={index}>
            <button
              className={`flex items-center p-2 rounded-lg hover:bg-zinc-800 transition-colors duration-300 ${
                activeItemId === item.label ? 'bg-zinc-800' : ''
              }`}
              onClick={() => handleSetActiveItem(item.label)}
            >
              <svg
                xmlns="http://www.w3.org/2000/svg"
                className="h-6 w-6 mr-2"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                strokeWidth={2}
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d={item.icon === 'dashboard' ? 'M3 12l2-2m0 5 7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1H9m2 6a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6-2h2' : item.icon === 'settings' ? 'M12 6V4m0 2a2 2 0 100 4m6 4a2 2 0 100 4m-6 4a2 2 0 100-4m0 2a2 2 0 100-4' : item.icon === 'menu' ? 'M3 12l2-2m0 5 7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2-2m-2-2v10a1 1 0 01-1 1H9m2 6a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6-2h2' : ''}
                />
              </svg>
              <span
                className={`text-lg ${
                  collapsed ? 'hidden' : 'block'
                } transition-opacity duration-300`}
              >
                {item.label}
              </span>
              {item.submenu && (
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-6 w-6 ml-2"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  strokeWidth={2}
                  onClick={(e) => {
                    e.stopPropagation();
                    handleToggleSubmenu(item.label);
                  }}
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M19 9l-7 7-7-7"
                  />
                </svg>
              )}
            </button>
            {item.submenu && openSubmenuIds.includes(item.label) && (
              <ul className="pl-4 mt-2">
                {item.submenu.map((submenuItem, submenuIndex) => (
                  <li key={submenuIndex}>
                    <button
                      className={`flex items-center p-2 rounded-lg hover:bg-zinc-800 transition-colors duration-300 ${
                        activeItemId === submenuItem.label ? 'bg-zinc-800' : ''
                      }`}
                      onClick={() => handleSetActiveItem(submenuItem.label)}
                    >
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        className="h-6 w-6 mr-2"
                        fill="none"
                        viewBox="0 0 24 24"
                        stroke="currentColor"
                        strokeWidth={2}
                      >
                        <path
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          d={submenuItem.icon === 'submenu-1' ? 'M3 12l2-2m0 5 7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2-2m-2-2v10a1 1 0 01-1 1H9m2 6a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6-2h2' : submenuItem.icon === 'submenu-2' ? 'M3 12l2-2m0 5 7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2-2m-2-2v10a1 1 0 01-1 1H9m2 6a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6-2h2' : ''}
                        />
                      </svg>
                      <span
                        className={`text-lg ${
                          collapsed ? 'hidden' : 'block'
                        } transition-opacity duration-300`}
                      >
                        {submenuItem.label}
                      </span>
                    </button>
                  </li>
                ))}
              </ul>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default SidebarNav;

Component info

CategoryNavigation
Frameworkreact
TierFREE
Views0
Copies0

About

Collapsible sidebar navigation

More from Navigation

import * as React from 'react';
import * as ReactDOM from 'react-dom';

interface FloatingDockProps {
  icons: { id: number; src: string; }[];
}

class FloatingDock extends React.Component<FloatingDockProps, {}> {
  constructor(props: FloatingDockPro
FloatingDock
Navigation
'use client';

import React, { useState } from 'react';

interface Tab {
  id: number;
  label: string;
}

const tabs: Tab[] = [
  { id: 1, label: 'Tab 1' },
  { id: 2, label: 'Tab 2' },
  { id: 3, label: 'Tab 3' },
  { id: 4, label: 'Tab 4' },
];

c
TabsNav
Navigation
'use client';

import React from 'react';

interface PaginationNavProps {
  currentPage: number;
  totalPages: number;
  onPageChange: (page: number) => void;
}

const PaginationNav: React.FC<PaginationNavProps> = ({ currentPage, totalPages, onPageCh
PaginationNav
Navigation
'use client';

import React from 'react';

interface Step {
  title: string;
  completed: boolean;
  active: boolean;
}

const steps: Step[] = [
  { title: 'Step 1', completed: true, active: false },
  { title: 'Step 2', completed: true, active: fals
StepperNav
Navigation