Dropdown Menu Example Fix
Problem
The Dropdown Menu example showed a button labeled "Actions" but when clicked, the dropdown menu was empty - no items were displayed.
Root Cause
The example was passing a simple string array to the items attribute:
// ❌ WRONG - Simple string array
'items': '["Edit", "Delete", "Share"]'
But the pan-dropdown component expects an array of objects with specific properties:
// ✅ CORRECT - Array of objects with label, value, icon
items: [
{ label: 'Edit', value: 'edit', icon: '✏️' },
{ label: 'Delete', value: 'delete', icon: '🗑️' },
{ label: 'Share', value: 'share', icon: '📤' }
]
Why It Failed
Looking at the component code (pan-dropdown.mjs, lines 255-269):
this.items.map(item => {
if (item.divider) {
return '<div class="dropdown-divider"></div>';
}
return `
<div
class="dropdown-item"
data-value="${item.value || item.label}"
${item.disabled ? 'disabled' : ''}
>
${item.icon ? `<span class="item-icon">${item.icon}</span>` : ''}
${item.label} // ❌ undefined when item is a string
</div>
`;
}).join('')
When the component receives ["Edit", "Delete", "Share"]:
- Each
itemis a string (e.g.,"Edit") item.labelisundefined(strings don't have a.labelproperty)item.valueisundefineditem.iconisundefined- Result: Empty divs with no text
Expected Item Format
From the component documentation (lines 1-14):
// Attributes:
// - items: JSON array of menu items [{label, value, icon?, disabled?}]
Each item object can have:
label(required) - Display text for the menu itemvalue(optional) - Value sent in PAN message (defaults to label)icon(optional) - Icon/emoji to display before labeldisabled(optional) - Whether item is disableddivider(special) - Shows a divider line instead of an item
Solution
Updated the example to use properly formatted item objects:
{
id: 'dropdown-menu',
name: 'Dropdown Menu',
description: 'Dropdown with menu items',
components: [
{
name: 'pan-dropdown',
attributes: {
'label': 'Actions',
'topic': 'action.selected',
'items': JSON.stringify([
{ label: 'Edit', value: 'edit', icon: '✏️' },
{ label: 'Delete', value: 'delete', icon: '🗑️' },
{ label: 'Share', value: 'share', icon: '📤' }
])
}
}
]
}
Why This Works
Now when the component renders:
item.label→'Edit'✅item.value→'edit'✅item.icon→'✏️'✅- Result: Visible menu item with icon and text
Enhanced Features
The fix also adds icons to make the menu more visually appealing:
- ✏️ Edit
- 🗑️ Delete
- 📤 Share
Example with Dividers and Disabled Items
You can also use more advanced features:
'items': JSON.stringify([
{ label: 'Edit', value: 'edit', icon: '✏️' },
{ label: 'Duplicate', value: 'duplicate', icon: '📋' },
{ divider: true }, // Adds a separator line
{ label: 'Delete', value: 'delete', icon: '🗑️', disabled: true }, // Grayed out
{ divider: true },
{ label: 'Share', value: 'share', icon: '📤' }
])
Testing
Before Fix
1. Load "Dropdown Menu" example
2. See: "Actions" button
3. Click button
4. See: Empty dropdown (no items) ❌
After Fix
1. Load "Dropdown Menu" example
2. See: "Actions" button
3. Click button
4. See: Dropdown with 3 items:
- ✏️ Edit
- 🗑️ Delete
- 📤 Share
5. Click an item
6. PAN Monitor shows: action.selected.select { value: 'edit', label: 'Edit' }
7. Dropdown closes ✅
PAN Messages
When you click a menu item, the component publishes:
Topic: {topic}.select
Data: { value: 'edit', label: 'Edit' }
For the example:
- Topic:
action.selected.select - Data:
{ value: 'edit', label: 'Edit' }
action.selected.opened- When dropdown opensaction.selected.closed- When dropdown closes
Files Changed
/Users/cdr/Projects/larc-repos/playground/examples.mjs
Lines 425-429: Changed from string array to object array
// Before:
'items': '["Edit", "Delete", "Share"]'
// After:
'items': JSON.stringify([
{ label: 'Edit', value: 'edit', icon: '✏️' },
{ label: 'Delete', value: 'delete', icon: '🗑️' },
{ label: 'Share', value: 'share', icon: '📤' }
])
Component Registry Update Needed?
Let me check if the component registry has proper help text for the items attribute...
The component registry should document:
- Items must be objects, not strings
- Required:
label - Optional:
value,icon,disabled,divider - Example format
Related Components
Other components that might have similar issues with JSON attributes:
pan-tabs- Usestabsattribute with arraydrag-drop-list- Usesitemsattribute- Any component with complex JSON data
Key Takeaway
When a component expects JSON data via attributes:
{label, value}, use objectsSummary
The dropdown menu example was fixed by changing the items attribute from a simple string array to an array of properly formatted objects with label, value, and icon properties. The dropdown now displays menu items correctly and publishes proper PAN events when items are selected.