Files
sigpro-ui/docs/components/menu.md
2026-04-03 01:41:07 +02:00

12 KiB
Raw Blame History

Menu

Menu component for creating navigation menus, sidebars, and dropdowns with support for nested items, icons, and active states.

Tag

Menu

Props

Prop Type Default Description
items Array<MenuItem> [] Menu items configuration
class string '' Additional CSS classes (DaisyUI + Tailwind)

MenuItem Structure

Property Type Description
label string | VNode Menu item text or content
icon string | VNode Optional icon to display
active boolean | Signal<boolean> Active state highlighting
onclick function Click handler
children Array<MenuItem> Nested submenu items
open boolean Whether submenu is open (for nested items)

Styling

Menu supports all daisyUI Menu classes:

Category Keywords Description
Direction menu-vertical (default), menu-horizontal Menu orientation
Size menu-xs, menu-sm, menu-md, menu-lg Menu scale
Style menu-compact Reduced padding
Background bg-base-100, bg-base-200 Background colors

For further details, check the daisyUI Menu Documentation Full reference for CSS classes.

Live Examples

Basic Menu

Live Demo

const BasicDemo = () => {
  const activeItem = $('home');
  
  return Menu({
    items: [
      { 
        label: 'Home', 
        active: () => activeItem() === 'home',
        onclick: () => activeItem('home')
      },
      { 
        label: 'About', 
        active: () => activeItem() === 'about',
        onclick: () => activeItem('about')
      },
      { 
        label: 'Contact', 
        active: () => activeItem() === 'contact',
        onclick: () => activeItem('contact')
      }
    ]
  });
};
$mount(BasicDemo, '#demo-basic');

With Icons

Live Demo

const IconsDemo = () => {
  const activeItem = $('dashboard');
  
  return Menu({
    items: [
      { 
        icon: '🏠', 
        label: 'Dashboard',
        active: () => activeItem() === 'dashboard',
        onclick: () => activeItem('dashboard')
      },
      { 
        icon: '📊', 
        label: 'Analytics',
        active: () => activeItem() === 'analytics',
        onclick: () => activeItem('analytics')
      },
      { 
        icon: '⚙️', 
        label: 'Settings',
        active: () => activeItem() === 'settings',
        onclick: () => activeItem('settings')
      },
      { 
        icon: '👤', 
        label: 'Profile',
        active: () => activeItem() === 'profile',
        onclick: () => activeItem('profile')
      }
    ]
  });
};
$mount(IconsDemo, '#demo-icons');

Nested Menu

Live Demo

const NestedDemo = () => {
  const activeItem = $('products');
  
  return Menu({
    items: [
      { 
        label: 'Dashboard',
        onclick: () => activeItem('dashboard'),
        active: () => activeItem() === 'dashboard'
      },
      { 
        label: 'Products',
        icon: '📦',
        open: true,
        children: [
          { 
            label: 'All Products',
            onclick: () => activeItem('all-products'),
            active: () => activeItem() === 'all-products'
          },
          { 
            label: 'Add New',
            onclick: () => activeItem('add-product'),
            active: () => activeItem() === 'add-product'
          },
          { 
            label: 'Categories',
            children: [
              { 
                label: 'Electronics',
                onclick: () => activeItem('electronics'),
                active: () => activeItem() === 'electronics'
              },
              { 
                label: 'Clothing',
                onclick: () => activeItem('clothing'),
                active: () => activeItem() === 'clothing'
              }
            ]
          }
        ]
      },
      { 
        label: 'Orders',
        icon: '📋',
        onclick: () => activeItem('orders'),
        active: () => activeItem() === 'orders'
      },
      { 
        label: 'Settings',
        icon: '⚙️',
        onclick: () => activeItem('settings'),
        active: () => activeItem() === 'settings'
      }
    ]
  });
};
$mount(NestedDemo, '#demo-nested');

Horizontal Menu

Live Demo

const HorizontalDemo = () => {
  const activeItem = $('home');
  
  return Menu({
    class: 'menu-horizontal rounded-box',
    items: [
      { 
        label: 'Home',
        active: () => activeItem() === 'home',
        onclick: () => activeItem('home')
      },
      { 
        label: 'Products',
        children: [
          { label: 'Electronics', onclick: () => activeItem('electronics') },
          { label: 'Clothing', onclick: () => activeItem('clothing') },
          { label: 'Books', onclick: () => activeItem('books') }
        ]
      },
      { 
        label: 'About',
        onclick: () => activeItem('about'),
        active: () => activeItem() === 'about'
      },
      { 
        label: 'Contact',
        onclick: () => activeItem('contact'),
        active: () => activeItem() === 'contact'
      }
    ]
  });
};
$mount(HorizontalDemo, '#demo-horizontal');

Sidebar Menu

Live Demo

const SidebarDemo = () => {
  const activeItem = $('dashboard');
  
  return Div({ class: 'flex' }, [
    Div({ class: 'w-64' }, [
      Menu({
        class: 'rounded-box w-full',
        items: [
          { 
            icon: '📊', 
            label: 'Dashboard',
            active: () => activeItem() === 'dashboard',
            onclick: () => activeItem('dashboard')
          },
          { 
            icon: '👥', 
            label: 'Users',
            children: [
              { 
                label: 'All Users',
                onclick: () => activeItem('all-users'),
                active: () => activeItem() === 'all-users'
              },
              { 
                label: 'Add User',
                onclick: () => activeItem('add-user'),
                active: () => activeItem() === 'add-user'
              }
            ]
          },
          { 
            icon: '📁', 
            label: 'Files',
            onclick: () => activeItem('files'),
            active: () => activeItem() === 'files'
          },
          { 
            icon: '⚙️', 
            label: 'Settings',
            onclick: () => activeItem('settings'),
            active: () => activeItem() === 'settings'
          }
        ]
      })
    ]),
    Div({ class: 'flex-1 p-4' }, [
      Div({ class: 'alert alert-info' }, () => `Current page: ${activeItem()}`)
    ])
  ]);
};
$mount(SidebarDemo, '#demo-sidebar');

Account Menu

Live Demo

const AccountDemo = () => {
  const notifications = $(3);
  
  return Menu({
    class: 'rounded-box w-56',
    items: [
      { 
        icon: '👤', 
        label: 'My Profile',
        onclick: () => Toast('Profile clicked', 'alert-info', 2000)
      },
      { 
        icon: '📧', 
        label: 'Messages',
        onclick: () => Toast('Messages opened', 'alert-info', 2000)
      },
      { 
        icon: '🔔', 
        label: 'Notifications',
        badge: () => notifications(),
        onclick: () => {
          notifications(0);
          Toast('Notifications cleared', 'alert-success', 2000);
        }
      },
      { 
        icon: '⚙️', 
        label: 'Settings',
        onclick: () => Toast('Settings opened', 'alert-info', 2000)
      },
      { 
        icon: '🚪', 
        label: 'Logout',
        onclick: () => Toast('Logged out', 'alert-warning', 2000)
      }
    ]
  });
};
$mount(AccountDemo, '#demo-account');

Collapsible Sidebar

Live Demo

const CollapsibleDemo = () => {
  const collapsed = $(false);
  const activeItem = $('dashboard');
  
  return Div({ class: 'flex gap-4' }, [
    Div({ class: `transition-all duration-300 ${collapsed() ? 'w-16' : 'w-64'}` }, [
      Button({ 
        class: 'btn btn-ghost btn-sm mb-2 w-full',
        onclick: () => collapsed(!collapsed())
      }, collapsed() ? '→' : '←'),
      Menu({
        class: `rounded-box ${collapsed() ? 'menu-compact' : ''}`,
        items: [
          { icon: '📊', label: collapsed() ? '' : 'Dashboard', active: () => activeItem() === 'dashboard', onclick: () => activeItem('dashboard') },
          { icon: '👥', label: collapsed() ? '' : 'Users', active: () => activeItem() === 'users', onclick: () => activeItem('users') },
          { icon: '📁', label: collapsed() ? '' : 'Files', active: () => activeItem() === 'files', onclick: () => activeItem('files') },
          { icon: '⚙️', label: collapsed() ? '' : 'Settings', active: () => activeItem() === 'settings', onclick: () => activeItem('settings') }
        ]
      })
    ]),
    Div({ class: 'flex-1' }, [
      Div({ class: 'alert alert-info' }, () => `Selected: ${activeItem()}`)
    ])
  ]);
};
$mount(CollapsibleDemo, '#demo-collapsible');

All Variants

Live Demo

const VariantsDemo = () => {
  const items = [
    { label: 'Item 1' },
    { label: 'Item 2' },
    { label: 'Item 3', children: [
      { label: 'Subitem 1' },
      { label: 'Subitem 2' }
    ]}
  ];
  
  return Div({ class: 'flex flex-wrap gap-8' }, [
    Div({ class: 'w-48' }, [
      Div({ class: 'text-sm font-bold mb-2' }, 'Default'),
      Menu({ items })
    ]),
    Div({ class: 'w-48' }, [
      Div({ class: 'text-sm font-bold mb-2' }, 'Compact'),
      Menu({ items, class: 'menu-compact' })
    ]),
    Div({ class: 'w-48' }, [
      Div({ class: 'text-sm font-bold mb-2' }, 'With Shadow'),
      Menu({ items, class: 'shadow-lg' })
    ])
  ]);
};
$mount(VariantsDemo, '#demo-variants');