Add accordion behavior to menu builder for all levels
- Categories: Only one category expanded at a time - Items: Click item to expand/collapse modifiers - Modifiers: Click modifier with sub-options to expand/collapse nested options - Clicking a new parent auto-collapses siblings at that level Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a6259bccb0
commit
12b47c3e41
1 changed files with 79 additions and 12 deletions
|
|
@ -252,6 +252,27 @@
|
|||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
/* Item Toggle (for expanding modifiers) */
|
||||
.item-toggle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
color: var(--text-muted);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.item-toggle:hover {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.item-toggle.expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.items-list.drag-over {
|
||||
background: rgba(0, 255, 136, 0.02);
|
||||
}
|
||||
|
|
@ -988,6 +1009,8 @@
|
|||
redoStack: [],
|
||||
idCounter: 1,
|
||||
expandedCategoryId: null, // For accordion - only one category expanded at a time
|
||||
expandedItemId: null, // For item accordion - only one item expanded at a time
|
||||
expandedModifierIds: new Set(), // Track which modifiers are expanded
|
||||
|
||||
// Initialize
|
||||
async init() {
|
||||
|
|
@ -2731,15 +2754,24 @@
|
|||
|
||||
return modifiers.map(mod => {
|
||||
const hasOptions = mod.options && mod.options.length > 0;
|
||||
const modExpanded = this.expandedModifierIds.has(mod.id);
|
||||
return `
|
||||
<div class="item-card modifier depth-${depth}" data-modifier-id="${mod.id}" data-parent-item-id="${parentItemId}" data-depth="${depth}"
|
||||
<div class="item-card modifier depth-${depth} ${modExpanded ? 'expanded' : ''}" data-modifier-id="${mod.id}" data-parent-item-id="${parentItemId}" data-depth="${depth}"
|
||||
style="margin-left: ${indent}px;"
|
||||
onclick="event.stopPropagation(); MenuBuilder.selectOption('${parentItemId}', '${mod.id}', ${depth})">
|
||||
${hasOptions ? `
|
||||
<div class="item-toggle ${modExpanded ? 'expanded' : ''}" onclick="event.stopPropagation(); MenuBuilder.toggleModifier('${mod.id}')">
|
||||
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M9 18l6-6-6-6"/>
|
||||
</svg>
|
||||
</div>
|
||||
` : `
|
||||
<div class="drag-handle" style="visibility: hidden;">
|
||||
<svg width="12" height="12"></svg>
|
||||
</div>
|
||||
`}
|
||||
<div class="item-image" style="width: ${iconSize}px; height: ${iconSize}px; font-size: ${iconSize/2}px;">${icon}</div>
|
||||
<div class="item-info">
|
||||
<div class="item-info" onclick="event.stopPropagation(); ${hasOptions ? `MenuBuilder.toggleModifier('${mod.id}')` : `MenuBuilder.selectOption('${parentItemId}', '${mod.id}', ${depth})`}" style="cursor: pointer;">
|
||||
<div class="item-name">${this.escapeHtml(mod.name)}</div>
|
||||
<div class="item-meta">
|
||||
${mod.price > 0 ? `<span>+$${mod.price.toFixed(2)}</span>` : ''}
|
||||
|
|
@ -2757,7 +2789,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
${hasOptions ? this.renderModifiers(mod.options, mod.id, depth + 1) : ''}
|
||||
${hasOptions && modExpanded ? this.renderModifiers(mod.options, mod.id, depth + 1) : ''}
|
||||
`;
|
||||
}).join('');
|
||||
},
|
||||
|
|
@ -2817,9 +2849,19 @@
|
|||
<div class="items-list ${isExpanded ? '' : 'collapsed'}">
|
||||
${category.items.length === 0 ? `
|
||||
<div class="item-drop-zone">Drag items here or click + to add</div>
|
||||
` : category.items.map(item => `
|
||||
<div class="item-card" data-item-id="${item.id}" draggable="true"
|
||||
` : category.items.map(item => {
|
||||
const itemExpanded = this.expandedItemId === item.id;
|
||||
const hasModifiers = item.modifiers && item.modifiers.length > 0;
|
||||
return `
|
||||
<div class="item-card ${itemExpanded ? 'expanded' : ''}" data-item-id="${item.id}" draggable="true"
|
||||
onclick="event.stopPropagation(); MenuBuilder.selectElement(this)">
|
||||
${hasModifiers ? `
|
||||
<div class="item-toggle ${itemExpanded ? 'expanded' : ''}" onclick="event.stopPropagation(); MenuBuilder.toggleItem('${item.id}')">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M9 18l6-6-6-6"/>
|
||||
</svg>
|
||||
</div>
|
||||
` : ''}
|
||||
<div class="drag-handle">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
|
||||
<circle cx="9" cy="6" r="1.5"/><circle cx="15" cy="6" r="1.5"/>
|
||||
|
|
@ -2839,11 +2881,11 @@
|
|||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<div class="item-info" onclick="event.stopPropagation(); ${hasModifiers ? `MenuBuilder.toggleItem('${item.id}')` : `MenuBuilder.selectElement(this.closest('.item-card'))`}" style="cursor: pointer;">
|
||||
<div class="item-name">${this.escapeHtml(item.name)}</div>
|
||||
<div class="item-meta">
|
||||
<span class="item-price">$${(item.price || 0).toFixed(2)}</span>
|
||||
${item.modifiers.length > 0 ? `<span>${item.modifiers.length} modifiers</span>` : ''}
|
||||
${hasModifiers ? `<span>${item.modifiers.length} modifiers</span>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
|
|
@ -2860,8 +2902,8 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
${this.renderModifiers(item.modifiers, item.id, 1)}
|
||||
`).join('')}
|
||||
${itemExpanded ? this.renderModifiers(item.modifiers, item.id, 1) : ''}
|
||||
`}).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`}).join('');
|
||||
|
|
@ -2998,9 +3040,34 @@
|
|||
|
||||
// Toggle category expanded/collapsed (accordion behavior)
|
||||
toggleCategory(categoryId) {
|
||||
// If clicking the already expanded category, collapse it
|
||||
// Otherwise expand the clicked one (auto-collapses any other)
|
||||
this.expandedCategoryId = (this.expandedCategoryId === categoryId) ? null : categoryId;
|
||||
if (this.expandedCategoryId === categoryId) {
|
||||
this.expandedCategoryId = null;
|
||||
} else {
|
||||
this.expandedCategoryId = categoryId;
|
||||
this.expandedItemId = null;
|
||||
this.expandedModifierIds.clear();
|
||||
}
|
||||
this.render();
|
||||
},
|
||||
|
||||
// Toggle item expanded/collapsed
|
||||
toggleItem(itemId) {
|
||||
if (this.expandedItemId === itemId) {
|
||||
this.expandedItemId = null;
|
||||
} else {
|
||||
this.expandedItemId = itemId;
|
||||
this.expandedModifierIds.clear();
|
||||
}
|
||||
this.render();
|
||||
},
|
||||
|
||||
// Toggle modifier expanded/collapsed
|
||||
toggleModifier(modifierId) {
|
||||
if (this.expandedModifierIds.has(modifierId)) {
|
||||
this.expandedModifierIds.delete(modifierId);
|
||||
} else {
|
||||
this.expandedModifierIds.add(modifierId);
|
||||
}
|
||||
this.render();
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue