context menu submenu support

This commit is contained in:
Jan Prochazka
2021-06-05 08:14:03 +02:00
parent 6b8bf8161e
commit 50b90e181a
3 changed files with 69 additions and 6 deletions

View File

@@ -51,7 +51,8 @@
label: 'Export', label: 'Export',
isExport: true, isExport: true,
}, },
electron && { // electron &&
{
label: 'Quick export', label: 'Quick export',
isQuickExport: true, isQuickExport: true,
}, },
@@ -394,6 +395,23 @@
.filter(x => x) .filter(x => x)
.map(menu => { .map(menu => {
if (menu.divider) return menu; if (menu.divider) return menu;
if (menu.isQuickExport) {
return {
text: menu.label,
submenu: [
{
text: 'CSV file',
isQuickExport: true,
},
{
text: 'Excel',
isQuickExport: true,
},
],
};
}
return { return {
text: menu.label, text: menu.label,
onClick: async () => { onClick: async () => {

View File

@@ -67,6 +67,7 @@
'icon chevron-left': 'mdi mdi-chevron-left', 'icon chevron-left': 'mdi mdi-chevron-left',
'icon chevron-right': 'mdi mdi-chevron-right', 'icon chevron-right': 'mdi mdi-chevron-right',
'icon chevron-up': 'mdi mdi-chevron-up', 'icon chevron-up': 'mdi mdi-chevron-up',
'icon menu-right': 'mdi mdi-menu-right',
'icon plugin': 'mdi mdi-toy-brick', 'icon plugin': 'mdi mdi-toy-brick',
'icon menu': 'mdi mdi-menu', 'icon menu': 'mdi mdi-menu',

View File

@@ -1,9 +1,10 @@
<script context="module"> <script context="module">
function getElementOffset(element) { function getElementOffset(element, side = null) {
var de = document.documentElement; var de = document.documentElement;
var box = element.getBoundingClientRect(); var box = element.getBoundingClientRect();
var top = box.top + window.pageYOffset - de.clientTop; var top = box.top + window.pageYOffset - de.clientTop;
var left = box.left + window.pageXOffset - de.clientLeft; var left = box.left + window.pageXOffset - de.clientLeft;
if (side == 'right') return { top: top, left: left + box.width };
return { top: top, left: left }; return { top: top, left: left };
} }
@@ -52,6 +53,7 @@
} }
return item; return item;
} }
</script> </script>
<script> <script>
@@ -61,6 +63,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { commandsCustomized, visibleCommandPalette } from '../stores'; import { commandsCustomized, visibleCommandPalette } from '../stores';
import { extractMenuItems } from '../utility/contextMenu'; import { extractMenuItems } from '../utility/contextMenu';
import FontIcon from '../icons/FontIcon.svelte';
export let items; export let items;
export let top; export let top;
@@ -68,10 +71,24 @@
let element; let element;
let hoverItem;
let hoverOffset;
let submenuItem;
let submenuOffset;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
function handleClick(item) { function handleClick(e, item) {
if (item.disabled) return; if (item.disabled) return;
if (item.submenu) {
hoverItem = item;
hoverOffset = getElementOffset(e.target, 'right');
submenuItem = item;
submenuOffset = hoverOffset;
return;
}
dispatch('close'); dispatch('close');
if (item.onClick) item.onClick(); if (item.onClick) item.onClick();
} }
@@ -80,9 +97,15 @@
fixPopupPlacement(element); fixPopupPlacement(element);
}); });
const changeActiveSubmenu = _.throttle(() => {
submenuItem = hoverItem;
submenuOffset = hoverOffset;
}, 500);
$: extracted = extractMenuItems(items); $: extracted = extractMenuItems(items);
$: compacted = _.compact(extracted.map(x => mapItem(x, $commandsCustomized))); $: compacted = _.compact(extracted.map(x => mapItem(x, $commandsCustomized)));
$: filtered = compacted.filter(x => !x.disabled || !x.hideDisabled); $: filtered = compacted.filter(x => !x.disabled || !x.hideDisabled);
</script> </script>
<ul <ul
@@ -95,17 +118,31 @@
{#if item.divider} {#if item.divider}
<li class="divider" /> <li class="divider" />
{:else} {:else}
<li> <li
<a on:click={() => handleClick(item)} class:disabled={item.disabled}> on:mouseenter={e => {
hoverOffset = getElementOffset(e.target, 'right');
hoverItem = item;
changeActiveSubmenu();
}}
>
<a on:click={e => handleClick(e, item)} class:disabled={item.disabled}>
{item.text} {item.text}
{#if item.keyText} {#if item.keyText}
<span class="keyText">{item.keyText}</span> <span class="keyText">{item.keyText}</span>
{/if} {/if}
{#if item.submenu}
<div class="menu-right">
<FontIcon icon="icon menu-right" />
</div>
{/if}
</a> </a>
</li> </li>
{/if} {/if}
{/each} {/each}
</ul> </ul>
{#if submenuItem?.submenu}
<svelte:self items={submenuItem?.submenu} {...submenuOffset} />
{/if}
<style> <style>
ul { ul {
@@ -136,9 +173,10 @@
a { a {
padding: 3px 20px; padding: 3px 20px;
line-height: 1.42; line-height: 1.42;
display: block;
white-space: nop-wrap; white-space: nop-wrap;
color: #262626; color: #262626;
display: flex;
justify-content: space-between;
} }
a.disabled { a.disabled {
@@ -156,4 +194,10 @@
border-top: 1px solid #f2f2f2; border-top: 1px solid #f2f2f2;
border-bottom: 1px solid #fff; border-bottom: 1px solid #fff;
} }
.menu-right {
position: relative;
left: 15px;
}
</style> </style>