# Dropdown Dropdown component for creating menus, selectors, and action panels that appear when triggered. Supports both array-based items and custom content. ## Tag `Dropdown` ## Props | Prop | Type | Default | Description | | :----------- | :-------------------------------------- | :---------- | :----------------------------------------------- | | `label` | `string \| VNode \| Signal` | `-` | Button label or content | | `icon` | `string \| VNode \| Signal` | `-` | Icon displayed next to label | | `items` | `Array \| Signal` | `-` | Array of menu items (alternative to children) | | `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | | `children` | `VNode \| function` | `-` | Custom dropdown content (alternative to items) | ### MenuItem Structure (when using `items`) | Property | Type | Description | | :---------- | :--------------------------- | :----------------------------------------------- | | `label` | `string \| VNode` | Menu item text | | `icon` | `string \| VNode` | Optional icon for the menu item | | `onclick` | `function` | Click handler | | `class` | `string` | Additional CSS classes for the menu item | ## Live Examples ### Basic Dropdown (Items Array)

Live Demo

```javascript const BasicDemo = () => { return Dropdown({ label: 'Options', items: [ { label: 'Profile', onclick: () => Toast('Profile clicked', 'alert-info', 2000) }, { label: 'Settings', onclick: () => Toast('Settings clicked', 'alert-info', 2000) }, { label: 'Logout', onclick: () => Toast('Logged out', 'alert-warning', 2000), class: 'text-error' } ] }); }; Mount(BasicDemo, '#demo-basic'); ``` ### With Icons (Items Array)

Live Demo

```javascript const IconsDemo = () => { return Dropdown({ label: 'Menu', icon: '☰', items: [ { icon: '👤', label: 'Profile', onclick: () => Toast('Profile', 'alert-info', 2000) }, { icon: '⭐', label: 'Favorites', onclick: () => Toast('Favorites', 'alert-info', 2000) }, { icon: '📁', label: 'Documents', onclick: () => Toast('Documents', 'alert-info', 2000) }, { icon: '⚙️', label: 'Settings', onclick: () => Toast('Settings', 'alert-info', 2000) } ] }); }; Mount(IconsDemo, '#demo-icons'); ``` ### Action Dropdown (Items Array)

Live Demo

```javascript const ActionsDemo = () => { const handleAction = (action) => { Toast(`${action} action`, 'alert-info', 2000); }; return Dropdown({ label: 'Actions', class: 'dropdown-end', items: [ { icon: '✏️', label: 'Edit', onclick: () => handleAction('Edit') }, { icon: '📋', label: 'Copy', onclick: () => handleAction('Copy') }, { icon: '🗑️', label: 'Delete', onclick: () => handleAction('Delete'), class: 'text-error' } ] }); }; Mount(ActionsDemo, '#demo-actions'); ``` ### User Dropdown (Items Array)

Live Demo

```javascript const UserDropdown = () => { return Dropdown({ label: Span({ class: 'flex items-center gap-2' }, [ Div({ class: 'avatar placeholder' }, [ Div({ class: 'bg-primary text-primary-content rounded-full w-8 h-8 flex items-center justify-center text-sm' }, 'JD') ]), 'John Doe' ]), class: 'dropdown-end', items: [ { label: 'Profile', onclick: () => Toast('Profile', 'alert-info', 2000) }, { label: 'Settings', onclick: () => Toast('Settings', 'alert-info', 2000) }, { label: 'Sign Out', onclick: () => Toast('Signed out', 'alert-warning', 2000), class: 'text-error' } ] }); }; Mount(UserDropdown, '#demo-user'); ``` ### Reactive Items

Live Demo

```javascript const ReactiveDropdown = () => { const count = $(0); const items = () => [ { label: `Count: ${count()}`, onclick: () => {} }, { label: 'Increment', onclick: () => count(count() + 1) }, { label: 'Decrement', onclick: () => count(count() - 1) }, { label: 'Reset', onclick: () => count(0) } ]; return Dropdown({ label: () => `Counter (${count()})`, items: items }); }; Mount(ReactiveDropdown, '#demo-reactive'); ``` ### Notification Dropdown (Custom Children)

Live Demo

```javascript const NotificationsDropdown = () => { const notifications = $([ { id: 1, title: 'New message', time: '5 min ago', read: false }, { id: 2, title: 'Update available', time: '1 hour ago', read: false }, { id: 3, title: 'Task completed', time: '2 hours ago', read: true } ]); const markAsRead = (id) => { notifications(notifications().map(n => n.id === id ? { ...n, read: true } : n )); }; const unreadCount = () => notifications().filter(n => !n.read).length; return Dropdown({ label: Span({ class: 'relative' }, [ '🔔', () => unreadCount() > 0 ? Span({ class: 'badge badge-xs badge-error absolute -top-1 -right-2' }, unreadCount()) : null ]), class: 'dropdown-end', children: () => Div({ class: 'w-80' }, [ Div({ class: 'p-3 border-b border-base-300 font-bold' }, `Notifications (${unreadCount()} unread)`), Div({ class: 'max-h-64 overflow-y-auto' }, notifications().map(notif => Div({ class: `p-3 border-b border-base-300 cursor-pointer hover:bg-base-200 ${!notif.read ? 'bg-primary/5' : ''}`, onclick: () => markAsRead(notif.id) }, [ Div({ class: 'font-medium' }, notif.title), Div({ class: 'text-xs opacity-60' }, notif.time), !notif.read && Span({ class: 'badge badge-xs badge-primary mt-1' }, 'New') ]) )), Div({ class: 'p-2 text-center' }, [ Button({ class: 'btn btn-xs btn-ghost w-full', onclick: () => notifications([]) }, 'Clear all') ]) ]) }); }; Mount(NotificationsDropdown, '#demo-notifications'); ``` ### Custom Content Dropdown

Live Demo

```javascript const CustomDropdown = () => { const selected = $('Option 1'); return Dropdown({ label: () => selected(), children: () => Div({ class: 'p-4 min-w-48' }, [ Div({ class: 'text-sm font-bold mb-2' }, 'Select an option'), Div({ class: 'flex flex-col gap-1' }, [ Button({ class: 'btn btn-ghost btn-sm justify-start', onclick: () => selected('Option 1') }, 'Option 1'), Button({ class: 'btn btn-ghost btn-sm justify-start', onclick: () => selected('Option 2') }, 'Option 2'), Button({ class: 'btn btn-ghost btn-sm justify-start', onclick: () => selected('Option 3') }, 'Option 3') ]) ]) }); }; Mount(CustomDropdown, '#demo-custom'); ``` ### All Variants

Live Demo

```javascript const VariantsDemo = () => { const commonItems = [ { label: 'Item 1', onclick: () => Toast('Item 1', 'alert-info', 2000) }, { label: 'Item 2', onclick: () => Toast('Item 2', 'alert-info', 2000) }, { label: 'Item 3', onclick: () => Toast('Item 3', 'alert-info', 2000) } ]; return Div({ class: 'flex flex-wrap gap-4 justify-center' }, [ Dropdown({ label: 'Default', items: commonItems }), Dropdown({ label: 'With Icon', icon: '☰', items: commonItems }), Dropdown({ label: 'End Position', class: 'dropdown-end', items: commonItems }) ]); }; Mount(VariantsDemo, '#demo-variants'); ```