Init
This commit is contained in:
commit
0ad405c26e
78 changed files with 9127 additions and 0 deletions
38
src/lib/state/menu.svelte.ts
Normal file
38
src/lib/state/menu.svelte.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// A single app-wide context menu.
|
||||
|
||||
import type { Component } from 'svelte';
|
||||
|
||||
export type MenuItem =
|
||||
| { label: string; icon?: Component; action: () => void; danger?: boolean; disabled?: boolean; hint?: string }
|
||||
| 'separator';
|
||||
|
||||
class Menu {
|
||||
open = $state(false);
|
||||
x = $state(0);
|
||||
y = $state(0);
|
||||
items = $state.raw<MenuItem[]>([]);
|
||||
/** Grow upward from (x, y) — for menus opened from the bottom toolbar. */
|
||||
above = $state(false);
|
||||
|
||||
show(x: number, y: number, items: MenuItem[]) {
|
||||
this.above = false;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.items = items;
|
||||
this.open = true;
|
||||
}
|
||||
|
||||
/** Open below/beside an anchor element. */
|
||||
showAt(el: Element, items: MenuItem[], placement: 'below' | 'above' = 'below') {
|
||||
const r = el.getBoundingClientRect();
|
||||
this.show(r.left, placement === 'below' ? r.bottom + 4 : r.top - 4, items);
|
||||
this.above = placement === 'above';
|
||||
}
|
||||
|
||||
close() {
|
||||
this.open = false;
|
||||
this.above = false;
|
||||
}
|
||||
}
|
||||
|
||||
export const menu = new Menu();
|
||||
Loading…
Add table
Add a link
Reference in a new issue