@geoffcox/sterling-svelte 0.0.16 → 0.0.18
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.
- package/{buttons/Button.svelte → Button.svelte} +27 -27
- package/{inputs/Checkbox.svelte → Checkbox.svelte} +26 -21
- package/{inputs/Checkbox.svelte.d.ts → Checkbox.svelte.d.ts} +2 -1
- package/{surfaces/Dialog.svelte → Dialog.svelte} +34 -21
- package/Field.svelte +257 -0
- package/Field.svelte.d.ts +63 -0
- package/Field.types.d.ts +1 -0
- package/Input.svelte +115 -0
- package/{inputs/Input.svelte.d.ts → Input.svelte.d.ts} +8 -3
- package/Label.svelte +51 -0
- package/Label.svelte.d.ts +41 -0
- package/List.constants.d.ts +1 -0
- package/List.constants.js +1 -0
- package/List.svelte +293 -0
- package/List.svelte.d.ts +63 -0
- package/List.types.d.ts +6 -0
- package/ListItem.svelte +89 -0
- package/ListItem.svelte.d.ts +51 -0
- package/{containers/Menu.svelte → Menu.svelte} +42 -27
- package/{containers/MenuBar.svelte → MenuBar.svelte} +13 -13
- package/{buttons/MenuButton.svelte → MenuButton.svelte} +17 -17
- package/{buttons/MenuButton.svelte.d.ts → MenuButton.svelte.d.ts} +1 -1
- package/{containers/MenuItem.svelte → MenuItem.svelte} +42 -54
- package/{containers/MenuItem.svelte.d.ts → MenuItem.svelte.d.ts} +2 -2
- package/{containers/MenuSeparator.svelte → MenuSeparator.svelte} +2 -2
- package/Menus.types.d.ts +22 -0
- package/{containers/Menus.utils.d.ts → Menus.utils.d.ts} +2 -2
- package/{containers/Menus.utils.js → Menus.utils.js} +6 -6
- package/{display/Progress.svelte → Progress.svelte} +28 -52
- package/{display/Progress.svelte.d.ts → Progress.svelte.d.ts} +1 -3
- package/Progress.types.d.ts +1 -0
- package/{inputs/Radio.svelte → Radio.svelte} +34 -29
- package/{inputs/Radio.svelte.d.ts → Radio.svelte.d.ts} +7 -2
- package/{inputs/Select.svelte → Select.svelte} +112 -130
- package/Select.svelte.d.ts +53 -0
- package/{inputs/Slider.svelte → Slider.svelte} +90 -86
- package/Slider.svelte.d.ts +51 -0
- package/{inputs/Switch.svelte → Switch.svelte} +43 -41
- package/Tab.svelte +181 -0
- package/{containers/Tab.svelte.d.ts → Tab.svelte.d.ts} +12 -15
- package/TabList.svelte +247 -0
- package/{containers/TabList.svelte.d.ts → TabList.svelte.d.ts} +21 -21
- package/TabList.types.d.ts +7 -0
- package/TextArea.svelte +113 -0
- package/{inputs/TextArea.svelte.d.ts → TextArea.svelte.d.ts} +3 -6
- package/TextArea.types.js +1 -0
- package/Tooltip.svelte +182 -0
- package/Tooltip.svelte.d.ts +24 -0
- package/Tooltip.types.d.ts +3 -0
- package/Tooltip.types.js +1 -0
- package/Tree.constants.d.ts +2 -0
- package/Tree.constants.js +2 -0
- package/Tree.svelte +114 -0
- package/Tree.svelte.d.ts +24 -0
- package/Tree.types.d.ts +28 -0
- package/Tree.types.js +1 -0
- package/{containers/TreeChevron.svelte → TreeChevron.svelte} +3 -3
- package/TreeItem.svelte +276 -0
- package/TreeItem.svelte.d.ts +65 -0
- package/{containers/TreeItem.svelte → TreeItemDisplay.svelte} +18 -18
- package/{containers/TreeItem.svelte.d.ts → TreeItemDisplay.svelte.d.ts} +11 -14
- package/{forwardEvents.js → actions/forwardEvents.js} +0 -2
- package/index.d.ts +44 -31
- package/index.js +40 -25
- package/package.json +45 -41
- package/theme/darkTheme.js +73 -74
- package/theme/lightTheme.js +76 -77
- package/containers/List.svelte +0 -249
- package/containers/List.svelte.d.ts +0 -68
- package/containers/ListItem.svelte +0 -48
- package/containers/ListItem.svelte.d.ts +0 -26
- package/containers/Menus.types.d.ts +0 -22
- package/containers/Tab.svelte +0 -327
- package/containers/TabList.svelte +0 -126
- package/containers/Tabs.types.d.ts +0 -12
- package/containers/Tree.constants.d.ts +0 -2
- package/containers/Tree.constants.js +0 -2
- package/containers/Tree.svelte +0 -222
- package/containers/Tree.svelte.d.ts +0 -50
- package/containers/Tree.types.d.ts +0 -47
- package/containers/TreeNode.svelte +0 -266
- package/containers/TreeNode.svelte.d.ts +0 -43
- package/display/Label.svelte +0 -27
- package/display/Label.svelte.d.ts +0 -20
- package/display/Progress.types.d.ts +0 -1
- package/inputs/Input.svelte +0 -129
- package/inputs/Select.svelte.d.ts +0 -62
- package/inputs/Slider.svelte.d.ts +0 -28
- package/inputs/TextArea.svelte +0 -154
- package/surfaces/CloseX.svelte +0 -5
- package/surfaces/CloseX.svelte.d.ts +0 -23
- package/surfaces/Portal.svelte +0 -14
- package/surfaces/Portal.svelte.d.ts +0 -21
- /package/{buttons/Button.svelte.d.ts → Button.svelte.d.ts} +0 -0
- /package/{buttons/Button.types.d.ts → Button.types.d.ts} +0 -0
- /package/{buttons/Button.types.js → Button.types.js} +0 -0
- /package/{surfaces/Dialog.svelte.d.ts → Dialog.svelte.d.ts} +0 -0
- /package/{containers/Menus.types.js → Field.types.js} +0 -0
- /package/{containers/Tabs.types.js → List.types.js} +0 -0
- /package/{containers/Menu.svelte.d.ts → Menu.svelte.d.ts} +0 -0
- /package/{containers/MenuBar.svelte.d.ts → MenuBar.svelte.d.ts} +0 -0
- /package/{containers/MenuItemDisplay.svelte → MenuItemDisplay.svelte} +0 -0
- /package/{containers/MenuItemDisplay.svelte.d.ts → MenuItemDisplay.svelte.d.ts} +0 -0
- /package/{containers/MenuSeparator.svelte.d.ts → MenuSeparator.svelte.d.ts} +0 -0
- /package/{containers/Menus.constants.d.ts → Menus.constants.d.ts} +0 -0
- /package/{containers/Menus.constants.js → Menus.constants.js} +0 -0
- /package/{containers/Tree.types.js → Menus.types.js} +0 -0
- /package/{display/Progress.types.js → Progress.types.js} +0 -0
- /package/{inputs/Switch.svelte.d.ts → Switch.svelte.d.ts} +0 -0
- /package/{containers/Tabs.constants.d.ts → TabList.constants.d.ts} +0 -0
- /package/{containers/Tabs.constants.js → TabList.constants.js} +0 -0
- /package/{inputs/TextArea.types.js → TabList.types.js} +0 -0
- /package/{inputs/TextArea.types.d.ts → TextArea.types.d.ts} +0 -0
- /package/{containers/TreeChevron.svelte.d.ts → TreeChevron.svelte.d.ts} +0 -0
- /package/{clickOutside.d.ts → actions/clickOutside.d.ts} +0 -0
- /package/{clickOutside.js → actions/clickOutside.js} +0 -0
- /package/{forwardEvents.d.ts → actions/forwardEvents.d.ts} +0 -0
- /package/{portal.d.ts → actions/portal.d.ts} +0 -0
- /package/{portal.js → actions/portal.js} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
[x: string]: any;
|
|
5
|
+
disabled?: boolean | undefined;
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
events: {
|
|
9
|
+
blur: FocusEvent;
|
|
10
|
+
click: MouseEvent;
|
|
11
|
+
dblclick: MouseEvent;
|
|
12
|
+
focus: FocusEvent;
|
|
13
|
+
focusin: FocusEvent;
|
|
14
|
+
focusout: FocusEvent;
|
|
15
|
+
keydown: KeyboardEvent;
|
|
16
|
+
keypress: KeyboardEvent;
|
|
17
|
+
keyup: KeyboardEvent;
|
|
18
|
+
mousedown: MouseEvent;
|
|
19
|
+
mouseenter: MouseEvent;
|
|
20
|
+
mouseleave: MouseEvent;
|
|
21
|
+
mousemove: MouseEvent;
|
|
22
|
+
mouseover: MouseEvent;
|
|
23
|
+
mouseout: MouseEvent;
|
|
24
|
+
mouseup: MouseEvent;
|
|
25
|
+
pointercancel: PointerEvent;
|
|
26
|
+
pointerdown: PointerEvent;
|
|
27
|
+
pointerenter: PointerEvent;
|
|
28
|
+
pointerleave: PointerEvent;
|
|
29
|
+
pointermove: PointerEvent;
|
|
30
|
+
pointerover: PointerEvent;
|
|
31
|
+
pointerout: PointerEvent;
|
|
32
|
+
pointerup: PointerEvent;
|
|
33
|
+
wheel: WheelEvent;
|
|
34
|
+
} & {
|
|
35
|
+
[evt: string]: CustomEvent<any>;
|
|
36
|
+
};
|
|
37
|
+
slots: {
|
|
38
|
+
default: {
|
|
39
|
+
disabled: boolean;
|
|
40
|
+
horizontal: import("svelte/store").Readable<boolean>;
|
|
41
|
+
selected: boolean;
|
|
42
|
+
value: string;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export type ListItemProps = typeof __propDef.props;
|
|
47
|
+
export type ListItemEvents = typeof __propDef.events;
|
|
48
|
+
export type ListItemSlots = typeof __propDef.slots;
|
|
49
|
+
export default class ListItem extends SvelteComponentTyped<ListItemProps, ListItemEvents, ListItemSlots> {
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<script>import { getContext } from "svelte";
|
|
1
|
+
<script>import { getContext, onMount } from "svelte";
|
|
2
2
|
import { autoUpdate, computePosition, flip, offset, shift } from "@floating-ui/dom";
|
|
3
|
-
import { portal } from "
|
|
3
|
+
import { portal } from "./actions/portal";
|
|
4
4
|
import { menuItemContextKey } from "./Menus.constants";
|
|
5
5
|
export let reference;
|
|
6
6
|
export let open = false;
|
|
7
7
|
let menuRef;
|
|
8
8
|
let menuPosition = { x: 0, y: 0 };
|
|
9
|
-
const {
|
|
9
|
+
const { rootValue, depth = 0 } = getContext(menuItemContextKey) || {};
|
|
10
10
|
const ensurePortalHost = () => {
|
|
11
11
|
let host = document.querySelector("#SterlingMenuPortal");
|
|
12
12
|
if (!host) {
|
|
@@ -18,8 +18,16 @@ const ensurePortalHost = () => {
|
|
|
18
18
|
return host;
|
|
19
19
|
};
|
|
20
20
|
const portalTarget = ensurePortalHost();
|
|
21
|
+
let bodyHeight = 0;
|
|
22
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
23
|
+
bodyHeight = entries[0].target.clientHeight;
|
|
24
|
+
});
|
|
21
25
|
const menuPlacement = depth > 1 ? "right-start" : "bottom-start";
|
|
22
|
-
const middleware = [
|
|
26
|
+
const middleware = [
|
|
27
|
+
offset({ mainAxis: -2 }),
|
|
28
|
+
flip(),
|
|
29
|
+
shift({ padding: 0, mainAxis: true, crossAxis: true })
|
|
30
|
+
];
|
|
23
31
|
const computeMenuPosition = async () => {
|
|
24
32
|
if (reference && menuRef) {
|
|
25
33
|
menuPosition = await computePosition(reference, menuRef, {
|
|
@@ -39,40 +47,49 @@ const autoUpdateMenuPosition = () => {
|
|
|
39
47
|
}
|
|
40
48
|
};
|
|
41
49
|
$:
|
|
42
|
-
|
|
50
|
+
menuRef, reference, autoUpdateMenuPosition();
|
|
51
|
+
$:
|
|
52
|
+
open, bodyHeight, computeMenuPosition();
|
|
53
|
+
onMount(() => {
|
|
54
|
+
resizeObserver.observe(document.body);
|
|
55
|
+
return () => {
|
|
56
|
+
resizeObserver.unobserve(document.body);
|
|
57
|
+
};
|
|
58
|
+
});
|
|
43
59
|
</script>
|
|
44
60
|
|
|
45
61
|
{#if open}
|
|
46
|
-
<div
|
|
62
|
+
<div
|
|
63
|
+
class="sterling-menu-portal"
|
|
64
|
+
data-root-value={rootValue}
|
|
65
|
+
use:portal={{ target: portalTarget }}
|
|
66
|
+
>
|
|
47
67
|
<div
|
|
48
68
|
bind:this={menuRef}
|
|
49
|
-
class="menu"
|
|
69
|
+
class="sterling-menu"
|
|
70
|
+
role="menu"
|
|
50
71
|
class:open
|
|
51
72
|
{...$$restProps}
|
|
52
73
|
style="left:{menuPosition.x}px; top:{menuPosition.y}px"
|
|
53
74
|
>
|
|
54
|
-
|
|
55
|
-
<!-- TODO: Remove this extra children div. Probably not needed -->
|
|
56
|
-
<div class="children" role="menu">
|
|
57
|
-
<slot />
|
|
58
|
-
</div>
|
|
59
|
-
{/if}
|
|
75
|
+
<slot />
|
|
60
76
|
</div>
|
|
61
77
|
</div>
|
|
62
78
|
{/if}
|
|
63
79
|
|
|
64
80
|
<style>
|
|
65
|
-
.portal {
|
|
81
|
+
.sterling-menu-portal {
|
|
66
82
|
position: relative;
|
|
67
83
|
overflow: visible;
|
|
84
|
+
background: rgba(255, 0, 0, 0.1);
|
|
68
85
|
}
|
|
69
86
|
|
|
70
|
-
.menu {
|
|
71
|
-
background-color: var(--Common__background-color);
|
|
72
|
-
border-color: var(--Common__border-color);
|
|
73
|
-
border-radius: var(--Common__border-radius);
|
|
74
|
-
border-style: var(--Common__border-style);
|
|
75
|
-
border-width: var(--Common__border-width);
|
|
87
|
+
.sterling-menu {
|
|
88
|
+
background-color: var(--stsv-Common__background-color);
|
|
89
|
+
border-color: var(--stsv-Common__border-color);
|
|
90
|
+
border-radius: var(--stsv-Common__border-radius);
|
|
91
|
+
border-style: var(--stsv-Common__border-style);
|
|
92
|
+
border-width: var(--stsv-Common__border-width);
|
|
76
93
|
box-sizing: border-box;
|
|
77
94
|
position: absolute;
|
|
78
95
|
box-shadow: rgba(0, 0, 0, 0.4) 2px 2px 4px -1px;
|
|
@@ -82,19 +99,17 @@ $:
|
|
|
82
99
|
z-index: 1;
|
|
83
100
|
top: 0;
|
|
84
101
|
left: 0;
|
|
85
|
-
}
|
|
86
102
|
|
|
87
|
-
.menu.open {
|
|
88
103
|
display: grid;
|
|
89
104
|
grid-template-columns: 1fr;
|
|
90
|
-
grid-template-rows:
|
|
105
|
+
grid-template-rows: auto;
|
|
106
|
+
row-gap: calc(2 * var(--stsv-Common__outline-width));
|
|
107
|
+
padding: 0.25em;
|
|
91
108
|
}
|
|
92
109
|
|
|
93
|
-
.
|
|
110
|
+
.sterling-menu.open {
|
|
94
111
|
display: grid;
|
|
95
112
|
grid-template-columns: 1fr;
|
|
96
|
-
grid-template-rows:
|
|
97
|
-
row-gap: calc(2 * var(--Common__outline-width));
|
|
98
|
-
padding: 0.25em;
|
|
113
|
+
grid-template-rows: 1fr;
|
|
99
114
|
}
|
|
100
115
|
</style>
|
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
import { menuBarContextKey, menuItemContextKey } from "./Menus.constants";
|
|
3
3
|
import { writable } from "svelte/store";
|
|
4
4
|
const dispatch = createEventDispatcher();
|
|
5
|
-
const raiseClose = (
|
|
6
|
-
dispatch("close", {
|
|
5
|
+
const raiseClose = (value) => {
|
|
6
|
+
dispatch("close", { value });
|
|
7
7
|
};
|
|
8
|
-
const raiseOpen = (
|
|
9
|
-
dispatch("open", {
|
|
8
|
+
const raiseOpen = (value) => {
|
|
9
|
+
dispatch("open", { value });
|
|
10
10
|
};
|
|
11
|
-
const raiseSelect = (
|
|
12
|
-
dispatch("select", {
|
|
11
|
+
const raiseSelect = (value) => {
|
|
12
|
+
dispatch("select", { value });
|
|
13
13
|
};
|
|
14
14
|
const children = writable([]);
|
|
15
|
-
const openPreviousChild = (
|
|
16
|
-
const index = $children?.findIndex((menuItem) => menuItem.
|
|
15
|
+
const openPreviousChild = (currentValue) => {
|
|
16
|
+
const index = $children?.findIndex((menuItem) => menuItem.value === currentValue);
|
|
17
17
|
if (index !== -1) {
|
|
18
18
|
const focusIndex = index === 0 ? $children.length - 1 : index - 1;
|
|
19
19
|
$children[focusIndex].focus();
|
|
20
20
|
$children[focusIndex].open();
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
const openNextChild = (
|
|
24
|
-
const index = $children?.findIndex((menuItem) => menuItem.
|
|
23
|
+
const openNextChild = (currentValue) => {
|
|
24
|
+
const index = $children?.findIndex((menuItem) => menuItem.value === currentValue);
|
|
25
25
|
if (index !== -1) {
|
|
26
26
|
const focusIndex = (index + 1) % $children.length;
|
|
27
27
|
$children[focusIndex].focus();
|
|
28
28
|
$children[focusIndex].open();
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
-
const focusChild = (
|
|
32
|
-
const focusIndex = $children?.findIndex((menuItem) => menuItem.
|
|
31
|
+
const focusChild = (value) => {
|
|
32
|
+
const focusIndex = $children?.findIndex((menuItem) => menuItem.value === value);
|
|
33
33
|
if (focusIndex !== -1) {
|
|
34
34
|
$children[focusIndex].focus();
|
|
35
35
|
}
|
|
@@ -39,7 +39,7 @@ setContext(menuItemContextKey, {
|
|
|
39
39
|
children.set([...$children, menuItem]);
|
|
40
40
|
},
|
|
41
41
|
unregister: (menuItem) => {
|
|
42
|
-
children.set($children.filter((x) => x.
|
|
42
|
+
children.set($children.filter((x) => x.value !== menuItem.value));
|
|
43
43
|
},
|
|
44
44
|
closeMenu: (recursive) => {
|
|
45
45
|
},
|
|
@@ -2,29 +2,29 @@
|
|
|
2
2
|
import { createEventDispatcher, getContext, setContext } from "svelte";
|
|
3
3
|
import { writable } from "svelte/store";
|
|
4
4
|
import Button from "./Button.svelte";
|
|
5
|
-
import Menu from "
|
|
6
|
-
import { menuItemContextKey } from "
|
|
7
|
-
import { focusFirstChild, focusNextChild, focusPreviousChild } from "
|
|
8
|
-
export let menuItemId;
|
|
5
|
+
import Menu from "./Menu.svelte";
|
|
6
|
+
import { menuItemContextKey } from "./Menus.constants";
|
|
7
|
+
import { focusFirstChild, focusNextChild, focusPreviousChild } from "./Menus.utils";
|
|
9
8
|
export let open = false;
|
|
10
9
|
export let shape = "rounded";
|
|
10
|
+
export let value;
|
|
11
11
|
export let variant = "regular";
|
|
12
12
|
const instanceId = uuid();
|
|
13
13
|
let reference;
|
|
14
14
|
$:
|
|
15
|
-
menuId = `${
|
|
15
|
+
menuId = `${value}-menu-${instanceId}`;
|
|
16
16
|
$:
|
|
17
17
|
hasChildren = $$slots.items;
|
|
18
18
|
const children = writable([]);
|
|
19
19
|
const dispatch = createEventDispatcher();
|
|
20
|
-
const raiseClose = (
|
|
21
|
-
dispatch("close", {
|
|
20
|
+
const raiseClose = (value2) => {
|
|
21
|
+
dispatch("close", { value: value2 });
|
|
22
22
|
};
|
|
23
|
-
const raiseOpen = (
|
|
24
|
-
dispatch("open", {
|
|
23
|
+
const raiseOpen = (value2) => {
|
|
24
|
+
dispatch("open", { value: value2 });
|
|
25
25
|
};
|
|
26
|
-
const raiseSelect = (
|
|
27
|
-
dispatch("select", {
|
|
26
|
+
const raiseSelect = (value2) => {
|
|
27
|
+
dispatch("select", { value: value2 });
|
|
28
28
|
};
|
|
29
29
|
const onClick = () => {
|
|
30
30
|
open = !open;
|
|
@@ -33,19 +33,19 @@ const onClick = () => {
|
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
setContext(menuItemContextKey, {
|
|
36
|
-
|
|
36
|
+
rootValue: value,
|
|
37
37
|
depth: 1,
|
|
38
38
|
register: (menuItem) => {
|
|
39
39
|
children.set([...$children, menuItem]);
|
|
40
40
|
},
|
|
41
41
|
unregister: (menuItem) => {
|
|
42
|
-
children.set($children.filter((x) => x.
|
|
42
|
+
children.set($children.filter((x) => x.value !== menuItem.value));
|
|
43
43
|
},
|
|
44
44
|
closeMenu: (recursive) => {
|
|
45
45
|
open = false;
|
|
46
46
|
},
|
|
47
|
-
focusPrevious: (
|
|
48
|
-
focusNext: (
|
|
47
|
+
focusPrevious: (currentValue) => focusPreviousChild($children, currentValue),
|
|
48
|
+
focusNext: (currentValue) => focusNextChild($children, currentValue),
|
|
49
49
|
onOpen: raiseOpen,
|
|
50
50
|
onClose: raiseClose,
|
|
51
51
|
onSelect: raiseSelect
|
|
@@ -61,8 +61,8 @@ setContext(menuItemContextKey, {
|
|
|
61
61
|
aria-expanded={open}
|
|
62
62
|
aria-haspopup={hasChildren}
|
|
63
63
|
aria-owns={menuId}
|
|
64
|
-
data-
|
|
65
|
-
data-root-
|
|
64
|
+
data-value={value}
|
|
65
|
+
data-root-value={value}
|
|
66
66
|
{variant}
|
|
67
67
|
{shape}
|
|
68
68
|
on:blur
|
|
@@ -3,9 +3,9 @@ import type { ButtonShape, ButtonVariant } from './Button.types';
|
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
5
|
[x: string]: any;
|
|
6
|
-
menuItemId: string;
|
|
7
6
|
open?: boolean | undefined;
|
|
8
7
|
shape?: ButtonShape | undefined;
|
|
8
|
+
value: string;
|
|
9
9
|
variant?: ButtonVariant | undefined;
|
|
10
10
|
};
|
|
11
11
|
events: {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
import { getContext, onMount, setContext } from "svelte";
|
|
4
4
|
import { writable } from "svelte/store";
|
|
5
|
-
import { clickOutside } from "
|
|
5
|
+
import { clickOutside } from "./actions/clickOutside";
|
|
6
6
|
import { afterUpdate, createEventDispatcher } from "svelte/internal";
|
|
7
7
|
import MenuItemDisplay from "./MenuItemDisplay.svelte";
|
|
8
8
|
import { menuBarContextKey, menuItemContextKey } from "./Menus.constants";
|
|
@@ -17,11 +17,11 @@ export let checked = false;
|
|
|
17
17
|
export let composed = false;
|
|
18
18
|
export let disabled = false;
|
|
19
19
|
export let open = false;
|
|
20
|
-
export let
|
|
20
|
+
export let value;
|
|
21
21
|
export let role = "menuitem";
|
|
22
22
|
export let text = void 0;
|
|
23
23
|
const {
|
|
24
|
-
|
|
24
|
+
rootValue = value,
|
|
25
25
|
depth = 0,
|
|
26
26
|
register = void 0,
|
|
27
27
|
unregister = void 0,
|
|
@@ -32,24 +32,12 @@ const {
|
|
|
32
32
|
onClose = void 0,
|
|
33
33
|
onSelect = void 0
|
|
34
34
|
} = getContext(menuItemContextKey) || {};
|
|
35
|
-
console.log({
|
|
36
|
-
rootMenuItemId,
|
|
37
|
-
depth,
|
|
38
|
-
register,
|
|
39
|
-
unregister,
|
|
40
|
-
closeMenu,
|
|
41
|
-
focusPrevious,
|
|
42
|
-
focusNext,
|
|
43
|
-
onOpen,
|
|
44
|
-
onClose,
|
|
45
|
-
onSelect
|
|
46
|
-
});
|
|
47
35
|
const { openPreviousMenu = void 0, openNextMenu = void 0 } = getContext(menuBarContextKey) || {};
|
|
48
36
|
const instanceId = uuid();
|
|
49
37
|
$:
|
|
50
|
-
displayId = `${
|
|
38
|
+
displayId = `${value}-display-${instanceId}`;
|
|
51
39
|
$:
|
|
52
|
-
menuId = `${
|
|
40
|
+
menuId = `${value}-menu-${instanceId}`;
|
|
53
41
|
let menuItemRef;
|
|
54
42
|
const children = writable([]);
|
|
55
43
|
let mounted = false;
|
|
@@ -57,28 +45,28 @@ let prevOpen = open;
|
|
|
57
45
|
$:
|
|
58
46
|
hasChildren = $$slots.default;
|
|
59
47
|
const dispatch = createEventDispatcher();
|
|
60
|
-
const raiseClose = (
|
|
61
|
-
dispatch("close", {
|
|
62
|
-
onClose?.(
|
|
48
|
+
const raiseClose = (value2) => {
|
|
49
|
+
dispatch("close", { value: value2 });
|
|
50
|
+
onClose?.(value2);
|
|
63
51
|
};
|
|
64
|
-
const raiseOpen = (
|
|
65
|
-
dispatch("open", {
|
|
66
|
-
onOpen?.(
|
|
52
|
+
const raiseOpen = (value2) => {
|
|
53
|
+
dispatch("open", { value: value2 });
|
|
54
|
+
onOpen?.(value2);
|
|
67
55
|
};
|
|
68
56
|
$: {
|
|
69
57
|
if (hasChildren && open !== prevOpen) {
|
|
70
|
-
open ? raiseOpen(
|
|
58
|
+
open ? raiseOpen(value) : raiseClose(value);
|
|
71
59
|
}
|
|
72
60
|
prevOpen = open;
|
|
73
61
|
}
|
|
74
|
-
const raiseSelect = (
|
|
75
|
-
dispatch("select", {
|
|
76
|
-
onSelect?.(
|
|
62
|
+
const raiseSelect = (value2) => {
|
|
63
|
+
dispatch("select", { value: value2 });
|
|
64
|
+
onSelect?.(value2);
|
|
77
65
|
};
|
|
78
66
|
let keyborg = createKeyborg(window);
|
|
79
67
|
let usingKeyboard = keyborg.isNavigatingWithKeyboard();
|
|
80
|
-
const keyborgHandler = (
|
|
81
|
-
usingKeyboard =
|
|
68
|
+
const keyborgHandler = (value2) => {
|
|
69
|
+
usingKeyboard = value2;
|
|
82
70
|
};
|
|
83
71
|
const autoFocusFirstChild = (open2, insideMenu) => {
|
|
84
72
|
if (open2 && insideMenu) {
|
|
@@ -91,7 +79,7 @@ onMount(() => {
|
|
|
91
79
|
mounted = true;
|
|
92
80
|
keyborg.subscribe(keyborgHandler);
|
|
93
81
|
const menuItemSelf = {
|
|
94
|
-
|
|
82
|
+
value,
|
|
95
83
|
open: () => {
|
|
96
84
|
open = true;
|
|
97
85
|
},
|
|
@@ -121,7 +109,7 @@ const onKeyDown = (event) => {
|
|
|
121
109
|
event.preventDefault();
|
|
122
110
|
return false;
|
|
123
111
|
} else if (depth > 0) {
|
|
124
|
-
focusNext?.(
|
|
112
|
+
focusNext?.(value);
|
|
125
113
|
event.preventDefault();
|
|
126
114
|
return false;
|
|
127
115
|
}
|
|
@@ -130,7 +118,7 @@ const onKeyDown = (event) => {
|
|
|
130
118
|
if (depth < 2) {
|
|
131
119
|
open = false;
|
|
132
120
|
closeMenu?.(true);
|
|
133
|
-
openPreviousMenu?.(
|
|
121
|
+
openPreviousMenu?.(rootValue);
|
|
134
122
|
} else {
|
|
135
123
|
closeMenu?.();
|
|
136
124
|
}
|
|
@@ -143,7 +131,7 @@ const onKeyDown = (event) => {
|
|
|
143
131
|
} else {
|
|
144
132
|
open = false;
|
|
145
133
|
closeMenu?.(true);
|
|
146
|
-
openNextMenu?.(
|
|
134
|
+
openNextMenu?.(rootValue);
|
|
147
135
|
}
|
|
148
136
|
event.preventDefault();
|
|
149
137
|
return false;
|
|
@@ -154,7 +142,7 @@ const onKeyDown = (event) => {
|
|
|
154
142
|
event.preventDefault();
|
|
155
143
|
return false;
|
|
156
144
|
} else if (depth > 0) {
|
|
157
|
-
focusPrevious?.(
|
|
145
|
+
focusPrevious?.(value);
|
|
158
146
|
event.preventDefault();
|
|
159
147
|
return false;
|
|
160
148
|
}
|
|
@@ -179,7 +167,7 @@ const onMenuItemClick = (event) => {
|
|
|
179
167
|
event.stopPropagation();
|
|
180
168
|
return false;
|
|
181
169
|
} else {
|
|
182
|
-
raiseSelect(
|
|
170
|
+
raiseSelect(value);
|
|
183
171
|
closeMenu?.(true);
|
|
184
172
|
}
|
|
185
173
|
}
|
|
@@ -190,7 +178,7 @@ const onClickOutside = (event) => {
|
|
|
190
178
|
} = event;
|
|
191
179
|
let element = mouseEvent.target;
|
|
192
180
|
while (element) {
|
|
193
|
-
if (element.getAttribute("data-root-
|
|
181
|
+
if (element.getAttribute("data-root-value") === rootValue) {
|
|
194
182
|
return;
|
|
195
183
|
}
|
|
196
184
|
element = element.parentElement;
|
|
@@ -198,13 +186,13 @@ const onClickOutside = (event) => {
|
|
|
198
186
|
closeMenu?.(true);
|
|
199
187
|
};
|
|
200
188
|
setContext(menuItemContextKey, {
|
|
201
|
-
|
|
189
|
+
rootValue,
|
|
202
190
|
depth: depth + 1,
|
|
203
191
|
register: (menuItem) => {
|
|
204
192
|
children.set([...$children, menuItem]);
|
|
205
193
|
},
|
|
206
194
|
unregister: (menuItem) => {
|
|
207
|
-
children.set($children.filter((x) => x.
|
|
195
|
+
children.set($children.filter((x) => x.value !== menuItem.value));
|
|
208
196
|
},
|
|
209
197
|
closeMenu: (recursive) => {
|
|
210
198
|
open = false;
|
|
@@ -215,8 +203,8 @@ setContext(menuItemContextKey, {
|
|
|
215
203
|
menuItemRef?.focus();
|
|
216
204
|
}
|
|
217
205
|
},
|
|
218
|
-
focusPrevious: (
|
|
219
|
-
focusNext: (
|
|
206
|
+
focusPrevious: (currentValue) => focusPreviousChild($children, currentValue),
|
|
207
|
+
focusNext: (currentValue) => focusNextChild($children, currentValue),
|
|
220
208
|
onOpen: raiseOpen,
|
|
221
209
|
onClose: raiseClose,
|
|
222
210
|
onSelect: raiseSelect
|
|
@@ -234,8 +222,8 @@ setContext(menuItemContextKey, {
|
|
|
234
222
|
class:composed
|
|
235
223
|
class:disabled
|
|
236
224
|
class:using-keyboard={usingKeyboard}
|
|
237
|
-
data-
|
|
238
|
-
data-root-
|
|
225
|
+
data-value={value}
|
|
226
|
+
data-root-value={rootValue}
|
|
239
227
|
{role}
|
|
240
228
|
tabindex={0}
|
|
241
229
|
type="button"
|
|
@@ -272,7 +260,7 @@ setContext(menuItemContextKey, {
|
|
|
272
260
|
{...$$restProps}
|
|
273
261
|
>
|
|
274
262
|
<div class="item" id={displayId}>
|
|
275
|
-
<slot name="item" {checked} {disabled} {hasChildren} {depth} {
|
|
263
|
+
<slot name="item" {checked} {disabled} {hasChildren} {depth} {value} {open} {role} {text}>
|
|
276
264
|
<MenuItemDisplay {checked} hasChildren={depth > 0 && hasChildren} menuItemRole={role}
|
|
277
265
|
>{text}</MenuItemDisplay
|
|
278
266
|
>
|
|
@@ -289,11 +277,11 @@ setContext(menuItemContextKey, {
|
|
|
289
277
|
.sterling-menu-item {
|
|
290
278
|
background-color: transparent;
|
|
291
279
|
border-color: transparent;
|
|
292
|
-
border-radius: var(--Button__border-radius);
|
|
280
|
+
border-radius: var(--stsv-Button__border-radius);
|
|
293
281
|
border-style: none;
|
|
294
282
|
border-width: 0;
|
|
295
283
|
box-sizing: border-box;
|
|
296
|
-
color: var(--Common__color);
|
|
284
|
+
color: var(--stsv-Common__color);
|
|
297
285
|
cursor: pointer;
|
|
298
286
|
font: inherit;
|
|
299
287
|
margin: 0;
|
|
@@ -309,8 +297,8 @@ setContext(menuItemContextKey, {
|
|
|
309
297
|
}
|
|
310
298
|
|
|
311
299
|
.sterling-menu-item:hover {
|
|
312
|
-
background-color: var(--Button__background-color--hover);
|
|
313
|
-
color: var(--Button__color--hover);
|
|
300
|
+
background-color: var(--stsv-Button__background-color--hover);
|
|
301
|
+
color: var(--stsv-Button__color--hover);
|
|
314
302
|
}
|
|
315
303
|
|
|
316
304
|
.sterling-menu-item:focus {
|
|
@@ -318,19 +306,19 @@ setContext(menuItemContextKey, {
|
|
|
318
306
|
}
|
|
319
307
|
|
|
320
308
|
.sterling-menu-item.using-keyboard:focus {
|
|
321
|
-
border-color: var(--Button__border-color--focus);
|
|
322
|
-
outline-color: var(--Common__outline-color);
|
|
323
|
-
outline-offset: var(--Common__outline-offset);
|
|
324
|
-
outline-style: var(--Common__outline-style);
|
|
325
|
-
outline-width: var(--Common__outline-width);
|
|
309
|
+
border-color: var(--stsv-Button__border-color--focus);
|
|
310
|
+
outline-color: var(--stsv-Common__outline-color);
|
|
311
|
+
outline-offset: var(--stsv-Common__outline-offset);
|
|
312
|
+
outline-style: var(--stsv-Common__outline-style);
|
|
313
|
+
outline-width: var(--stsv-Common__outline-width);
|
|
326
314
|
}
|
|
327
315
|
|
|
328
316
|
.sterling-menu-item:focus {
|
|
329
|
-
background-color: var(--Input__background-color--selected);
|
|
317
|
+
background-color: var(--stsv-Input__background-color--selected);
|
|
330
318
|
}
|
|
331
319
|
|
|
332
320
|
.sterling-menu-item.disabled {
|
|
333
|
-
color: var(--
|
|
321
|
+
color: var(--stsv-Common__color--disabled);
|
|
334
322
|
}
|
|
335
323
|
|
|
336
324
|
.sterling-menu-item.composed,
|
|
@@ -6,7 +6,7 @@ declare const __propDef: {
|
|
|
6
6
|
composed?: boolean | undefined;
|
|
7
7
|
disabled?: boolean | undefined;
|
|
8
8
|
open?: boolean | undefined;
|
|
9
|
-
|
|
9
|
+
value: string;
|
|
10
10
|
role?: "menuitem" | "menuitemcheckbox" | "menuitemradio" | undefined;
|
|
11
11
|
text?: string | undefined;
|
|
12
12
|
};
|
|
@@ -45,7 +45,7 @@ declare const __propDef: {
|
|
|
45
45
|
disabled: boolean;
|
|
46
46
|
hasChildren: boolean;
|
|
47
47
|
depth: number;
|
|
48
|
-
|
|
48
|
+
value: string;
|
|
49
49
|
open: boolean;
|
|
50
50
|
role: "menuitem" | "menuitemcheckbox" | "menuitemradio";
|
|
51
51
|
text: string | undefined;
|
|
@@ -35,8 +35,8 @@ A styled line to visually separate menu items in a menu.
|
|
|
35
35
|
|
|
36
36
|
<style>
|
|
37
37
|
.sterling-menu-item-separator {
|
|
38
|
-
height: var(--Common__border-width);
|
|
39
|
-
background-color: var(--Common__border-color);
|
|
38
|
+
height: var(--stsv-Common__border-width);
|
|
39
|
+
background-color: var(--stsv-Common__border-color);
|
|
40
40
|
margin: 0.1em 0;
|
|
41
41
|
}
|
|
42
42
|
</style>
|
package/Menus.types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type MenuItemRegistration = {
|
|
2
|
+
value: string;
|
|
3
|
+
open: () => void;
|
|
4
|
+
close: () => void;
|
|
5
|
+
focus: () => void;
|
|
6
|
+
};
|
|
7
|
+
export type MenuBarContext = {
|
|
8
|
+
openPreviousMenu?: (currentValue: string) => void;
|
|
9
|
+
openNextMenu?: (currentValue: string) => void;
|
|
10
|
+
};
|
|
11
|
+
export type MenuItemContext = {
|
|
12
|
+
rootValue?: string;
|
|
13
|
+
depth?: number;
|
|
14
|
+
register?: (menuItem: MenuItemRegistration) => void;
|
|
15
|
+
unregister?: (menuItem: MenuItemRegistration) => void;
|
|
16
|
+
focusPrevious?: (currentValue: string) => void;
|
|
17
|
+
focusNext?: (currentValue: string) => void;
|
|
18
|
+
closeMenu?: (recursive?: boolean) => void;
|
|
19
|
+
onOpen?: (value: string) => void;
|
|
20
|
+
onClose?: (value: string) => void;
|
|
21
|
+
onSelect?: (value: string) => void;
|
|
22
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MenuItemRegistration } from './Menus.types';
|
|
2
|
-
export declare const focusPreviousChild: (children: MenuItemRegistration[],
|
|
3
|
-
export declare const focusNextChild: (children: MenuItemRegistration[],
|
|
2
|
+
export declare const focusPreviousChild: (children: MenuItemRegistration[], currentValue: string) => void;
|
|
3
|
+
export declare const focusNextChild: (children: MenuItemRegistration[], currentValue: string) => void;
|
|
4
4
|
export declare const focusFirstChild: (children: MenuItemRegistration[]) => void;
|
|
5
5
|
export declare const focusLastChild: (children: MenuItemRegistration[]) => void;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
export const focusPreviousChild = (children,
|
|
2
|
-
const index = children?.findIndex((menuItem) => menuItem.
|
|
1
|
+
export const focusPreviousChild = (children, currentValue) => {
|
|
2
|
+
const index = children?.findIndex((menuItem) => menuItem.value === currentValue);
|
|
3
3
|
if (index !== -1) {
|
|
4
4
|
const focusIndex = index === 0 ? children.length - 1 : index - 1;
|
|
5
5
|
children[focusIndex].focus();
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
|
-
export const focusNextChild = (children,
|
|
9
|
-
const index = children?.findIndex((menuItem) => menuItem.
|
|
8
|
+
export const focusNextChild = (children, currentValue) => {
|
|
9
|
+
const index = children?.findIndex((menuItem) => menuItem.value === currentValue);
|
|
10
10
|
if (index !== -1) {
|
|
11
11
|
const focusIndex = (index + 1) % children.length;
|
|
12
12
|
children[focusIndex].focus();
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
15
|
export const focusFirstChild = (children) => {
|
|
16
|
-
children[0]?.focus();
|
|
16
|
+
children?.[0]?.focus();
|
|
17
17
|
};
|
|
18
18
|
export const focusLastChild = (children) => {
|
|
19
|
-
children[children.length - 1]?.focus();
|
|
19
|
+
children?.[children.length - 1]?.focus();
|
|
20
20
|
};
|