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);
|
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 {
|
.items-list.drag-over {
|
||||||
background: rgba(0, 255, 136, 0.02);
|
background: rgba(0, 255, 136, 0.02);
|
||||||
}
|
}
|
||||||
|
|
@ -988,6 +1009,8 @@
|
||||||
redoStack: [],
|
redoStack: [],
|
||||||
idCounter: 1,
|
idCounter: 1,
|
||||||
expandedCategoryId: null, // For accordion - only one category expanded at a time
|
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
|
// Initialize
|
||||||
async init() {
|
async init() {
|
||||||
|
|
@ -2731,15 +2754,24 @@
|
||||||
|
|
||||||
return modifiers.map(mod => {
|
return modifiers.map(mod => {
|
||||||
const hasOptions = mod.options && mod.options.length > 0;
|
const hasOptions = mod.options && mod.options.length > 0;
|
||||||
|
const modExpanded = this.expandedModifierIds.has(mod.id);
|
||||||
return `
|
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;"
|
style="margin-left: ${indent}px;"
|
||||||
onclick="event.stopPropagation(); MenuBuilder.selectOption('${parentItemId}', '${mod.id}', ${depth})">
|
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;">
|
<div class="drag-handle" style="visibility: hidden;">
|
||||||
<svg width="12" height="12"></svg>
|
<svg width="12" height="12"></svg>
|
||||||
</div>
|
</div>
|
||||||
|
`}
|
||||||
<div class="item-image" style="width: ${iconSize}px; height: ${iconSize}px; font-size: ${iconSize/2}px;">${icon}</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-name">${this.escapeHtml(mod.name)}</div>
|
||||||
<div class="item-meta">
|
<div class="item-meta">
|
||||||
${mod.price > 0 ? `<span>+$${mod.price.toFixed(2)}</span>` : ''}
|
${mod.price > 0 ? `<span>+$${mod.price.toFixed(2)}</span>` : ''}
|
||||||
|
|
@ -2757,7 +2789,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${hasOptions ? this.renderModifiers(mod.options, mod.id, depth + 1) : ''}
|
${hasOptions && modExpanded ? this.renderModifiers(mod.options, mod.id, depth + 1) : ''}
|
||||||
`;
|
`;
|
||||||
}).join('');
|
}).join('');
|
||||||
},
|
},
|
||||||
|
|
@ -2817,9 +2849,19 @@
|
||||||
<div class="items-list ${isExpanded ? '' : 'collapsed'}">
|
<div class="items-list ${isExpanded ? '' : 'collapsed'}">
|
||||||
${category.items.length === 0 ? `
|
${category.items.length === 0 ? `
|
||||||
<div class="item-drop-zone">Drag items here or click + to add</div>
|
<div class="item-drop-zone">Drag items here or click + to add</div>
|
||||||
` : category.items.map(item => `
|
` : category.items.map(item => {
|
||||||
<div class="item-card" data-item-id="${item.id}" draggable="true"
|
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)">
|
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">
|
<div class="drag-handle">
|
||||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
|
<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"/>
|
<circle cx="9" cy="6" r="1.5"/><circle cx="15" cy="6" r="1.5"/>
|
||||||
|
|
@ -2839,11 +2881,11 @@
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
</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-name">${this.escapeHtml(item.name)}</div>
|
||||||
<div class="item-meta">
|
<div class="item-meta">
|
||||||
<span class="item-price">$${(item.price || 0).toFixed(2)}</span>
|
<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>
|
</div>
|
||||||
<div class="item-actions">
|
<div class="item-actions">
|
||||||
|
|
@ -2860,8 +2902,8 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${this.renderModifiers(item.modifiers, item.id, 1)}
|
${itemExpanded ? this.renderModifiers(item.modifiers, item.id, 1) : ''}
|
||||||
`).join('')}
|
`}).join('')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`}).join('');
|
`}).join('');
|
||||||
|
|
@ -2998,9 +3040,34 @@
|
||||||
|
|
||||||
// Toggle category expanded/collapsed (accordion behavior)
|
// Toggle category expanded/collapsed (accordion behavior)
|
||||||
toggleCategory(categoryId) {
|
toggleCategory(categoryId) {
|
||||||
// If clicking the already expanded category, collapse it
|
if (this.expandedCategoryId === categoryId) {
|
||||||
// Otherwise expand the clicked one (auto-collapses any other)
|
this.expandedCategoryId = null;
|
||||||
this.expandedCategoryId = (this.expandedCategoryId === categoryId) ? null : categoryId;
|
} 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();
|
this.render();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue