svseeds 0.4.9 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
|
|
35
35
|
const preset = "svs-combo-box";
|
|
36
36
|
const NA = -1;
|
|
37
|
-
const optionStyle = "cursor: default; user-select: none;";
|
|
38
37
|
|
|
39
38
|
import { type Snippet } from "svelte";
|
|
40
39
|
import { type Action } from "svelte/action";
|
|
@@ -56,7 +55,7 @@
|
|
|
56
55
|
let listElem: HTMLUListElement | undefined = $state();
|
|
57
56
|
|
|
58
57
|
// *** Bind Handlers *** //
|
|
59
|
-
let listboxStyle = $derived(`position:absolute;visibility: ${expanded ? "visible" : "hidden"};${overflow.x ? "right:0%;" : ""}${overflow.y ? "bottom:100%;" : ""}`);
|
|
58
|
+
let listboxStyle = $derived(`position:absolute;cursor:default;user-select:none;visibility: ${expanded ? "visible" : "hidden"};${overflow.x ? "right:0%;" : ""}${overflow.y ? "bottom:100%;" : ""}`);
|
|
60
59
|
let opts = $derived([...options.keys()]);
|
|
61
60
|
let maxlen = $derived(opts.reduce((max, x) => Math.max(max, [...x].length), 0));
|
|
62
61
|
|
|
@@ -133,7 +132,7 @@
|
|
|
133
132
|
<input bind:value bind:this={element} class={cls(PARTS.MAIN, variant)} type="text" role="combobox" aria-haspopup="listbox" aria-autocomplete="none" aria-controls={idList} aria-expanded={expanded} onfocus={() => open()} onblur={close} {onkeydown} {oninput} {...attrs} />
|
|
134
133
|
{/if}
|
|
135
134
|
{#if extra}
|
|
136
|
-
<div class={cls(PARTS.EXTRA, variant)} style="position:absolute;
|
|
135
|
+
<div class={cls(PARTS.EXTRA, variant)} style="position:absolute;top:50%;right:0%;transform:translateY(-50%);pointer-events:none;">
|
|
137
136
|
{@render extra(expanded, variant)}
|
|
138
137
|
</div>
|
|
139
138
|
{/if}
|
|
@@ -142,7 +141,7 @@
|
|
|
142
141
|
{@const isSelected = i === selected}
|
|
143
142
|
{@const labelStatus = isSelected ? VARIANT.ACTIVE : variant}
|
|
144
143
|
{@const onpointerenter = () => selected = i}
|
|
145
|
-
<li class={cls(PARTS.LABEL, labelStatus)} aria-selected={isSelected} role="option"
|
|
144
|
+
<li class={cls(PARTS.LABEL, labelStatus)} aria-selected={isSelected} role="option" onpointerdown={apply} {onpointerenter}>
|
|
146
145
|
{opt}
|
|
147
146
|
</li>
|
|
148
147
|
{/each}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
children: Snippet<[string]>; // Snippet<[variant]>
|
|
7
7
|
open?: boolean; // bindable (false); to observe state, not to control
|
|
8
8
|
lock?: boolean; // bindable (false)
|
|
9
|
+
target?: HTMLElement;
|
|
9
10
|
element?: HTMLElement; // bindable
|
|
10
11
|
styling?: SVSClass;
|
|
11
12
|
variant?: string; // bindable (VARIANT.NEUTRAL)
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
children: Snippet<[string]>; // Snippet<[variant]>
|
|
18
19
|
open?: boolean; // bindable (false); to observe state, not to control
|
|
19
20
|
lock?: boolean; // bindable (false)
|
|
21
|
+
target?: HTMLElement;
|
|
20
22
|
element?: HTMLElement; // bindable
|
|
21
23
|
styling?: SVSClass;
|
|
22
24
|
variant?: string; // bindable (VARIANT.NEUTRAL)
|
|
@@ -26,39 +28,47 @@
|
|
|
26
28
|
|
|
27
29
|
const preset = "svs-context-menu";
|
|
28
30
|
|
|
29
|
-
import { type Snippet } from "svelte";
|
|
31
|
+
import { type Snippet, onDestroy } from "svelte";
|
|
32
|
+
import { on } from "svelte/events";
|
|
30
33
|
import { type SVSClass, VARIANT, PARTS, fnClass } from "./core";
|
|
31
34
|
</script>
|
|
32
35
|
|
|
33
36
|
<!---------------------------------------->
|
|
34
37
|
|
|
35
38
|
<script lang="ts">
|
|
36
|
-
let { children, open = $bindable(false), lock = $bindable(false), element = $bindable(), styling, variant = $bindable("") }: ContextMenuProps = $props();
|
|
39
|
+
let { children, open = $bindable(false), lock = $bindable(false), target, element = $bindable(), styling, variant = $bindable("") }: ContextMenuProps = $props();
|
|
37
40
|
|
|
38
41
|
// *** Initialize *** //
|
|
39
42
|
if (!variant) variant = VARIANT.NEUTRAL;
|
|
40
43
|
const cls = fnClass(preset, styling);
|
|
41
44
|
let position = $state({ x: 0, y: 0 });
|
|
45
|
+
let listeners: (() => void)[] = [];
|
|
46
|
+
$effect(() => {
|
|
47
|
+
listeners.push(on(target ?? document, "contextmenu", show));
|
|
48
|
+
if (target) listeners.push(on(document, "contextmenu", hide));
|
|
49
|
+
});
|
|
50
|
+
onDestroy(() => listeners.forEach((x) => x()));
|
|
42
51
|
|
|
43
52
|
// *** Bind Handlers *** //
|
|
44
|
-
let
|
|
45
|
-
let dynStyle = $derived(`position: fixed; left:${position.x}px; top:${position.y}px; ${visibility}`);
|
|
53
|
+
let dynStyle = $derived(`position:fixed;left:${position.x}px;top:${position.y}px;${open ? "visibility:visible;" : "visibility:hidden;z-index:-9999;"}`);
|
|
46
54
|
|
|
47
55
|
// *** Event Handlers *** //
|
|
48
|
-
function show(ev:
|
|
56
|
+
function show(ev: Event) {
|
|
49
57
|
if (lock) return;
|
|
50
58
|
ev.preventDefault();
|
|
59
|
+
ev.stopPropagation();
|
|
51
60
|
|
|
61
|
+
const [x, y] = [(ev as MouseEvent).clientX, (ev as MouseEvent).clientY];
|
|
52
62
|
const menu = { width: element?.offsetWidth ?? 0, height: element?.offsetHeight ?? 0 };
|
|
53
|
-
position.x = window.innerWidth-
|
|
54
|
-
position.y = window.innerHeight-
|
|
63
|
+
position.x = window.innerWidth-x < menu.width ? x-menu.width : x;
|
|
64
|
+
position.y = window.innerHeight-y < menu.height ? (y < menu.height ? y : y-menu.height) : y;
|
|
55
65
|
open = true;
|
|
56
66
|
}
|
|
57
67
|
function hide() { if (!lock) open = false; }
|
|
58
68
|
</script>
|
|
59
69
|
|
|
60
70
|
<!---------------------------------------->
|
|
61
|
-
<svelte:document
|
|
71
|
+
<svelte:document onclick={hide} />
|
|
62
72
|
|
|
63
73
|
<nav class={cls(PARTS.WHOLE, variant)} style={dynStyle} bind:this={element}>
|
|
64
74
|
{@render children(variant)}
|
|
@@ -2,6 +2,7 @@ export interface ContextMenuProps {
|
|
|
2
2
|
children: Snippet<[string]>;
|
|
3
3
|
open?: boolean;
|
|
4
4
|
lock?: boolean;
|
|
5
|
+
target?: HTMLElement;
|
|
5
6
|
element?: HTMLElement;
|
|
6
7
|
styling?: SVSClass;
|
|
7
8
|
variant?: string;
|
|
@@ -17,6 +18,7 @@ import { type SVSClass } from "./core";
|
|
|
17
18
|
* children: Snippet<[string]>; // Snippet<[variant]>
|
|
18
19
|
* open?: boolean; // bindable (false); to observe state, not to control
|
|
19
20
|
* lock?: boolean; // bindable (false)
|
|
21
|
+
* target?: HTMLElement;
|
|
20
22
|
* element?: HTMLElement; // bindable
|
|
21
23
|
* styling?: SVSClass;
|
|
22
24
|
* variant?: string; // bindable (VARIANT.NEUTRAL)
|