dropdown menu implementation

This commit is contained in:
Jan Prochazka
2021-02-28 10:17:52 +01:00
parent e9430988f4
commit 2cc74b594e
7 changed files with 122 additions and 1 deletions

View File

@@ -0,0 +1,13 @@
<script>
import { currentDropDownMenu } from '../src/stores';
import DropDownMenu from './DropDownMenu.svelte';
</script>
{#if $currentDropDownMenu}
<DropDownMenu
left={$currentDropDownMenu.left}
top={$currentDropDownMenu.top}
items={$currentDropDownMenu.items}
on:close={() => ($currentDropDownMenu = null)}
/>
{/if}

View File

@@ -0,0 +1,77 @@
<script>
import clickOutside from '../src/utility/clickOutside';
import { createEventDispatcher } from 'svelte';
export let items;
export let top;
export let left;
const dispatch = createEventDispatcher();
function handleClick(item) {
dispatch('close');
if (item.onClick) item.onClick();
}
</script>
<ul style={`left: ${left}px; top: ${top}px`} use:clickOutside on:clickOutside={() => dispatch('close')}>
{#each items as item}
{#if item.divider}
<li class="divider" />
{:else}
<li>
<a on:click={() => handleClick(item)}>
{item.text}
{#if item.keyText}
<span class="keyText">{item.keyText}</span>
{/if}
</a>
</li>
{/if}
{/each}
</ul>
<style>
ul {
position: absolute;
list-style: none;
background-color: #fff;
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.15);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
min-width: 160px;
z-index: 1050;
cursor: default;
}
.keyText {
font-style: italic;
font-weight: bold;
text-align: right;
margin-left: 16px;
}
a {
padding: 3px 20px;
line-height: 1.42;
display: block;
white-space: nop-wrap;
color: #262626;
}
a:hover {
background-color: #f5f5f5;
text-decoration: none;
color: #262626;
}
.divider {
margin: 9px 0px 9px 0px;
border-top: 1px solid #f2f2f2;
border-bottom: 1px solid #fff;
}
</style>

View File

@@ -7,7 +7,7 @@
import CommandPalette from './commands/CommandPalette.svelte';
import Toolbar from './widgets/Toolbar.svelte';
import splitterDrag from './utility/splitterDrag';
import { update } from 'lodash';
import CurrentDropDownMenu from '../modals/CurrentDropDownMenu.svelte';
</script>
<div class={`${$currentTheme} root`}>
@@ -43,6 +43,7 @@
<Toolbar />
</div>
{/if}
<CurrentDropDownMenu />
</div>
<style>

View File

@@ -46,6 +46,7 @@
if (command.getSubCommands) {
parentCommand = command;
domInput.focus();
filter = '';
selectedIndex = 0;
} else {
$visibleCommandPalette = false;

View File

@@ -35,6 +35,7 @@ export const currentTheme = writableWithStorage('theme-light', 'currentTheme');
export const activeTabId = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)?.tabid);
export const visibleToolbar = writableWithStorage(1, 'visibleToolbar');
export const leftPanelWidth = writable(300);
export const currentDropDownMenu = writable(null);
subscribeCssVariable(selectedWidget, x => (x ? 1 : 0), '--dim-visible-left-panel');
subscribeCssVariable(visibleToolbar, x => (x ? 1 : 0), '--dim-visible-toolbar');

View File

@@ -0,0 +1,19 @@
import _ from 'lodash';
import { currentDropDownMenu } from '../stores';
export default function contextMenu(node, items) {
const handleContextMenu = e => {
e.preventDefault();
const left = e.pageX;
const top = e.pageY;
currentDropDownMenu.set({ left, top, items: _.isFunction(items) ? items() : items });
};
node.addEventListener('contextmenu', handleContextMenu);
return {
destroy() {
node.removeEventListener('contextmenu', handleContextMenu);
},
};
}

View File

@@ -25,6 +25,7 @@
import { currentDatabase, openedTabs } from '../stores';
import { setSelectedTab } from '../utility/common';
import contextMenu from '../utility/contextMenu';
$: currentDbKey =
$currentDatabase && $currentDatabase.name && $currentDatabase.connection
@@ -100,6 +101,13 @@
closeTab(tabid);
}
};
const tabContextMenu = tabid => () => [
{
text: 'Close',
onClick: () => closeTab(tabid),
},
];
</script>
{#each dbKeys as dbKey}
@@ -115,6 +123,7 @@
class:selected={tab.selected}
on:click={e => handleTabClick(e, tab.tabid)}
on:mouseup={e => handleMouseUp(e, tab.tabid)}
use:contextMenu={tabContextMenu(tab.tabid)}
>
<FontIcon icon={tab.busy ? 'icon loading' : tab.icon} />
<span class="file-name">