1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-07-18 22:04:05 +00:00

Context menu + database dropping

This commit is contained in:
2023-01-14 20:38:39 +01:00
parent 5a558577ea
commit b7365b739c
10 changed files with 182 additions and 19 deletions

View File

@ -0,0 +1,58 @@
<script>
import { createEventDispatcher } from 'svelte';
export let items = undefined;
export let position = undefined;
const dispatch = createEventDispatcher();
function close() {
dispatch('close');
}
</script>
{#if items && position}
<div class="backdrop" on:pointerdown={close}></div>
<ul class="contextmenu" role="" style:left="{position[0]}px" style:top="{position[1]}px">
{#each items as item}
{#if item.separator}
<hr />
{:else}
<li>
<button class="item" on:click={item.fn}>
{item.label}
</button>
</li>
{/if}
{/each}
</ul>
{/if}
<style>
.backdrop {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.contextmenu {
position: fixed;
background-color: rgba(230, 230, 230, 0.7);
backdrop-filter: blur(30px);
border-radius: 10px;
padding: 5px;
box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.2);
}
button {
padding: 5px;
border-radius: 5px;
}
button:hover {
background-color: #00008b;
color: #fff;
}
</style>

View File

@ -1,9 +1,11 @@
<script>
import { contextMenu } from '../stores';
import { createEventDispatcher } from 'svelte';
import Icon from './icon.svelte';
export let columns = [];
export let items = [];
export let actions = [];
export let key = 'id';
export let activeKey = '';
export let activeChildKey = '';
@ -12,7 +14,7 @@
export let contained = false;
const dispatch = createEventDispatcher();
const childrenOpen = {};
let childrenOpen = {};
$: _items = objectToArray(items).map(item => {
item.children = objectToArray(item.children);
@ -43,12 +45,32 @@
dispatch('selectChild', childKey);
}
function toggleChildren(itemKey) {
function toggleChildren(itemKey, closeAll) {
childrenOpen[itemKey] = !childrenOpen[itemKey];
if (closeAll) {
childrenOpen = {};
dispatch('closeAll');
}
}
function showContextMenu(evt, item) {
select(item[key]);
contextMenu.show(evt, item.menu);
}
</script>
<div class:grid={level === 0} class:subgrid={level > 0} class:contained>
{#if actions?.length}
<div class="actions">
{#each actions as action}
<button class="btn" on:click={action.fn}>
{#if action.icon}<Icon name={action.icon} />{/if}
{action.label || ''}
</button>
{/each}
</div>
{/if}
<table>
{#if showHeaders && columns.some(col => col.title)}
<thead>
@ -63,10 +85,15 @@
<tbody>
{#each _items as item (item[key])}
<tr on:click={() => select(item[key])} class:selected={activeKey === item[key] && !activeChildKey}>
<tr
on:click={() => select(item[key])}
on:dblclick={() => toggleChildren(item[key])}
on:contextmenu|preventDefault={evt => showContextMenu(evt, item)}
class:selected={activeKey === item[key] && !activeChildKey}
>
<td class="has-toggle">
{#if item.children?.length}
<button class="toggle" on:click={() => toggleChildren(item[key])}>
<button class="toggle" on:click={evt => toggleChildren(item[key], evt.shiftKey)}>
<Icon name={childrenOpen[item[key]] ? 'chev-d' : 'chev-r'} />
</button>
{/if}
@ -94,6 +121,7 @@
items={item.children}
level={level + 1}
on:select={e => selectChild(item[key], e.detail)}
on:closeAll={() => (childrenOpen = {})}
/>
</td>
</tr>
@ -116,6 +144,15 @@
width: 100%;
}
.actions {
margin-bottom: 0.5rem;
padding: 0.5rem;
border-bottom: 1px solid #ccc;
}
.actions button {
margin-right: 0.2rem;
}
table {
border-collapse: collapse;
width: 100%;

View File

@ -1,5 +1,5 @@
<script>
export let name;
export let name = '';
</script>
{#if name === 'radio'}
@ -14,6 +14,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-database"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"></path><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path></svg>
{:else if name === 'x'}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
{:else if name === '+'}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
{:else if name === '-'}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-minus"><line x1="5" y1="12" x2="19" y2="12"></line></svg>
{:else if name === 'reload'}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-refresh-cw"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>
{/if}