@geoffcox/sterling-svelte 0.0.14 → 0.0.16

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.
Files changed (46) hide show
  1. package/@types/clickOutside.d.ts +9 -3
  2. package/buttons/Button.svelte +1 -1
  3. package/buttons/Button.svelte.d.ts +4 -1
  4. package/buttons/MenuButton.svelte +102 -0
  5. package/buttons/MenuButton.svelte.d.ts +54 -0
  6. package/clickOutside.js +3 -1
  7. package/containers/List.svelte +1 -1
  8. package/containers/Menu.svelte +100 -0
  9. package/containers/Menu.svelte.d.ts +20 -0
  10. package/containers/MenuBar.svelte +97 -0
  11. package/containers/MenuBar.svelte.d.ts +43 -0
  12. package/containers/MenuItem.svelte +350 -0
  13. package/containers/MenuItem.svelte.d.ts +61 -0
  14. package/containers/MenuItemDisplay.svelte +97 -0
  15. package/containers/MenuItemDisplay.svelte.d.ts +21 -0
  16. package/containers/MenuSeparator.svelte +42 -0
  17. package/containers/MenuSeparator.svelte.d.ts +76 -0
  18. package/containers/Menus.constants.d.ts +2 -0
  19. package/containers/Menus.constants.js +2 -0
  20. package/containers/Menus.types.d.ts +22 -0
  21. package/containers/Menus.types.js +1 -0
  22. package/containers/Menus.utils.d.ts +5 -0
  23. package/containers/Menus.utils.js +20 -0
  24. package/containers/Tab.svelte +327 -0
  25. package/containers/Tab.svelte.d.ts +55 -0
  26. package/containers/TabList.svelte +126 -0
  27. package/containers/TabList.svelte.d.ts +56 -0
  28. package/containers/Tabs.constants.d.ts +1 -0
  29. package/containers/Tabs.constants.js +1 -0
  30. package/containers/Tabs.types.d.ts +12 -0
  31. package/containers/Tabs.types.js +1 -0
  32. package/containers/TreeNode.svelte +0 -1
  33. package/forwardEvents.d.ts +12 -0
  34. package/forwardEvents.js +34 -0
  35. package/index.d.ts +12 -2
  36. package/index.js +9 -1
  37. package/inputs/Checkbox.svelte +2 -2
  38. package/inputs/Checkbox.svelte.d.ts +4 -1
  39. package/inputs/Input.svelte +1 -1
  40. package/inputs/Select.svelte +5 -5
  41. package/inputs/TextArea.svelte +2 -2
  42. package/package.json +18 -1
  43. package/portal.d.ts +8 -0
  44. package/portal.js +19 -0
  45. package/surfaces/Portal.svelte +14 -0
  46. package/surfaces/Portal.svelte.d.ts +21 -0
@@ -0,0 +1,350 @@
1
+ <script>import { createKeyborg } from "keyborg";
2
+ import { v4 as uuid } from "uuid";
3
+ import { getContext, onMount, setContext } from "svelte";
4
+ import { writable } from "svelte/store";
5
+ import { clickOutside } from "../clickOutside";
6
+ import { afterUpdate, createEventDispatcher } from "svelte/internal";
7
+ import MenuItemDisplay from "./MenuItemDisplay.svelte";
8
+ import { menuBarContextKey, menuItemContextKey } from "./Menus.constants";
9
+ import Menu from "./Menu.svelte";
10
+ import {
11
+ focusFirstChild,
12
+ focusLastChild,
13
+ focusNextChild,
14
+ focusPreviousChild
15
+ } from "./Menus.utils";
16
+ export let checked = false;
17
+ export let composed = false;
18
+ export let disabled = false;
19
+ export let open = false;
20
+ export let menuItemId;
21
+ export let role = "menuitem";
22
+ export let text = void 0;
23
+ const {
24
+ rootMenuItemId = menuItemId,
25
+ depth = 0,
26
+ register = void 0,
27
+ unregister = void 0,
28
+ closeMenu = void 0,
29
+ focusPrevious = void 0,
30
+ focusNext = void 0,
31
+ onOpen = void 0,
32
+ onClose = void 0,
33
+ onSelect = void 0
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
+ const { openPreviousMenu = void 0, openNextMenu = void 0 } = getContext(menuBarContextKey) || {};
48
+ const instanceId = uuid();
49
+ $:
50
+ displayId = `${menuItemId}-display-${instanceId}`;
51
+ $:
52
+ menuId = `${menuItemId}-menu-${instanceId}`;
53
+ let menuItemRef;
54
+ const children = writable([]);
55
+ let mounted = false;
56
+ let prevOpen = open;
57
+ $:
58
+ hasChildren = $$slots.default;
59
+ const dispatch = createEventDispatcher();
60
+ const raiseClose = (menuItemId2) => {
61
+ dispatch("close", { menuItemId: menuItemId2 });
62
+ onClose?.(menuItemId2);
63
+ };
64
+ const raiseOpen = (menuItemId2) => {
65
+ dispatch("open", { menuItemId: menuItemId2 });
66
+ onOpen?.(menuItemId2);
67
+ };
68
+ $: {
69
+ if (hasChildren && open !== prevOpen) {
70
+ open ? raiseOpen(menuItemId) : raiseClose(menuItemId);
71
+ }
72
+ prevOpen = open;
73
+ }
74
+ const raiseSelect = (menuItemId2) => {
75
+ dispatch("select", { menuItemId: menuItemId2 });
76
+ onSelect?.(menuItemId2);
77
+ };
78
+ let keyborg = createKeyborg(window);
79
+ let usingKeyboard = keyborg.isNavigatingWithKeyboard();
80
+ const keyborgHandler = (value) => {
81
+ usingKeyboard = value;
82
+ };
83
+ const autoFocusFirstChild = (open2, insideMenu) => {
84
+ if (open2 && insideMenu) {
85
+ setTimeout(() => focusFirstChild($children), 10);
86
+ }
87
+ };
88
+ $:
89
+ autoFocusFirstChild(open, depth > 0);
90
+ onMount(() => {
91
+ mounted = true;
92
+ keyborg.subscribe(keyborgHandler);
93
+ const menuItemSelf = {
94
+ id: menuItemId,
95
+ open: () => {
96
+ open = true;
97
+ },
98
+ close: () => {
99
+ open = false;
100
+ },
101
+ focus: () => {
102
+ menuItemRef?.focus();
103
+ }
104
+ };
105
+ register?.(menuItemSelf);
106
+ return () => {
107
+ keyborg.unsubscribe(keyborgHandler);
108
+ unregister?.(menuItemSelf);
109
+ };
110
+ });
111
+ afterUpdate(() => {
112
+ prevOpen = open;
113
+ });
114
+ const onKeyDown = (event) => {
115
+ if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
116
+ switch (event.key) {
117
+ case "ArrowDown":
118
+ if (depth === 0 && hasChildren) {
119
+ open = true;
120
+ setTimeout(() => focusFirstChild($children), 10);
121
+ event.preventDefault();
122
+ return false;
123
+ } else if (depth > 0) {
124
+ focusNext?.(menuItemId);
125
+ event.preventDefault();
126
+ return false;
127
+ }
128
+ break;
129
+ case "ArrowLeft":
130
+ if (depth < 2) {
131
+ open = false;
132
+ closeMenu?.(true);
133
+ openPreviousMenu?.(rootMenuItemId);
134
+ } else {
135
+ closeMenu?.();
136
+ }
137
+ event.preventDefault();
138
+ return false;
139
+ case "ArrowRight":
140
+ if (depth > 0 && hasChildren) {
141
+ open = true;
142
+ setTimeout(focusFirstChild, 10);
143
+ } else {
144
+ open = false;
145
+ closeMenu?.(true);
146
+ openNextMenu?.(rootMenuItemId);
147
+ }
148
+ event.preventDefault();
149
+ return false;
150
+ case "ArrowUp":
151
+ if (depth === 0 && hasChildren) {
152
+ open = true;
153
+ setTimeout(() => focusLastChild($children), 10);
154
+ event.preventDefault();
155
+ return false;
156
+ } else if (depth > 0) {
157
+ focusPrevious?.(menuItemId);
158
+ event.preventDefault();
159
+ return false;
160
+ }
161
+ case "Escape":
162
+ open = false;
163
+ closeMenu?.(true);
164
+ event.preventDefault();
165
+ return false;
166
+ }
167
+ }
168
+ };
169
+ const onMouseEnter = (event) => {
170
+ setTimeout(() => {
171
+ menuItemRef?.focus();
172
+ }, 10);
173
+ };
174
+ const onMenuItemClick = (event) => {
175
+ if (!disabled) {
176
+ if (hasChildren) {
177
+ open = !open;
178
+ event.preventDefault();
179
+ event.stopPropagation();
180
+ return false;
181
+ } else {
182
+ raiseSelect(menuItemId);
183
+ closeMenu?.(true);
184
+ }
185
+ }
186
+ };
187
+ const onClickOutside = (event) => {
188
+ const {
189
+ detail: { mouseEvent }
190
+ } = event;
191
+ let element = mouseEvent.target;
192
+ while (element) {
193
+ if (element.getAttribute("data-root-menu-item-id") === rootMenuItemId) {
194
+ return;
195
+ }
196
+ element = element.parentElement;
197
+ }
198
+ closeMenu?.(true);
199
+ };
200
+ setContext(menuItemContextKey, {
201
+ rootMenuItemId,
202
+ depth: depth + 1,
203
+ register: (menuItem) => {
204
+ children.set([...$children, menuItem]);
205
+ },
206
+ unregister: (menuItem) => {
207
+ children.set($children.filter((x) => x.id !== menuItem.id));
208
+ },
209
+ closeMenu: (recursive) => {
210
+ open = false;
211
+ if (recursive) {
212
+ closeMenu?.(recursive);
213
+ }
214
+ if (!recursive || depth === 0) {
215
+ menuItemRef?.focus();
216
+ }
217
+ },
218
+ focusPrevious: (fromMenuItemId) => focusPreviousChild($children, fromMenuItemId),
219
+ focusNext: (fromMenuItemId) => focusNextChild($children, fromMenuItemId),
220
+ onOpen: raiseOpen,
221
+ onClose: raiseClose,
222
+ onSelect: raiseSelect
223
+ });
224
+ </script>
225
+
226
+ <button
227
+ aria-controls={menuId}
228
+ aria-disabled={disabled}
229
+ aria-expanded={open}
230
+ aria-haspopup={hasChildren}
231
+ aria-owns={menuId}
232
+ bind:this={menuItemRef}
233
+ class="sterling-menu-item"
234
+ class:composed
235
+ class:disabled
236
+ class:using-keyboard={usingKeyboard}
237
+ data-menu-item-id={menuItemId}
238
+ data-root-menu-item-id={rootMenuItemId}
239
+ {role}
240
+ tabindex={0}
241
+ type="button"
242
+ use:clickOutside
243
+ on:blur
244
+ on:click
245
+ on:dblclick
246
+ on:focus
247
+ on:focusin
248
+ on:focusout
249
+ on:keydown
250
+ on:keypress
251
+ on:keyup
252
+ on:mousedown
253
+ on:mouseenter
254
+ on:mouseleave
255
+ on:mousemove
256
+ on:mouseover
257
+ on:mouseout
258
+ on:mouseup
259
+ on:pointercancel
260
+ on:pointerdown
261
+ on:pointerenter
262
+ on:pointerleave
263
+ on:pointermove
264
+ on:pointerover
265
+ on:pointerout
266
+ on:pointerup
267
+ on:wheel
268
+ on:click={onMenuItemClick}
269
+ on:click_outside={onClickOutside}
270
+ on:keydown={onKeyDown}
271
+ on:mouseenter={onMouseEnter}
272
+ {...$$restProps}
273
+ >
274
+ <div class="item" id={displayId}>
275
+ <slot name="item" {checked} {disabled} {hasChildren} {depth} {menuItemId} {open} {role} {text}>
276
+ <MenuItemDisplay {checked} hasChildren={depth > 0 && hasChildren} menuItemRole={role}
277
+ >{text}</MenuItemDisplay
278
+ >
279
+ </slot>
280
+ </div>
281
+ {#if menuItemRef && open && $$slots.default}
282
+ <Menu id={menuId} {open} reference={menuItemRef}>
283
+ <slot />
284
+ </Menu>
285
+ {/if}
286
+ </button>
287
+
288
+ <style>
289
+ .sterling-menu-item {
290
+ background-color: transparent;
291
+ border-color: transparent;
292
+ border-radius: var(--Button__border-radius);
293
+ border-style: none;
294
+ border-width: 0;
295
+ box-sizing: border-box;
296
+ color: var(--Common__color);
297
+ cursor: pointer;
298
+ font: inherit;
299
+ margin: 0;
300
+ padding: 0;
301
+ position: relative;
302
+ outline: none;
303
+ overflow: hidden;
304
+ text-decoration: none;
305
+ text-overflow: ellipsis;
306
+ transition: background-color 250ms, color 250ms, border-color 250ms;
307
+ white-space: nowrap;
308
+ user-select: none;
309
+ }
310
+
311
+ .sterling-menu-item:hover {
312
+ background-color: var(--Button__background-color--hover);
313
+ color: var(--Button__color--hover);
314
+ }
315
+
316
+ .sterling-menu-item:focus {
317
+ outline: none;
318
+ }
319
+
320
+ .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);
326
+ }
327
+
328
+ .sterling-menu-item:focus {
329
+ background-color: var(--Input__background-color--selected);
330
+ }
331
+
332
+ .sterling-menu-item.disabled {
333
+ color: var(--Input__color--disabled);
334
+ }
335
+
336
+ .sterling-menu-item.composed,
337
+ .sterling-menu-item.composed:focus,
338
+ .sterling-menu-item.composed:hover {
339
+ border-width: 0;
340
+ border-color: transparent;
341
+ outline: none;
342
+ background-color: transparent;
343
+ }
344
+
345
+ @media (prefers-reduced-motion) {
346
+ .sterling-menu-item {
347
+ transition: none;
348
+ }
349
+ }
350
+ </style>
@@ -0,0 +1,61 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ [x: string]: any;
5
+ checked?: boolean | undefined;
6
+ composed?: boolean | undefined;
7
+ disabled?: boolean | undefined;
8
+ open?: boolean | undefined;
9
+ menuItemId: string;
10
+ role?: "menuitem" | "menuitemcheckbox" | "menuitemradio" | undefined;
11
+ text?: string | undefined;
12
+ };
13
+ events: {
14
+ blur: FocusEvent;
15
+ click: MouseEvent;
16
+ dblclick: MouseEvent;
17
+ focus: FocusEvent;
18
+ focusin: FocusEvent;
19
+ focusout: FocusEvent;
20
+ keydown: KeyboardEvent;
21
+ keypress: KeyboardEvent;
22
+ keyup: KeyboardEvent;
23
+ mousedown: MouseEvent;
24
+ mouseenter: MouseEvent;
25
+ mouseleave: MouseEvent;
26
+ mousemove: MouseEvent;
27
+ mouseover: MouseEvent;
28
+ mouseout: MouseEvent;
29
+ mouseup: MouseEvent;
30
+ pointercancel: PointerEvent;
31
+ pointerdown: PointerEvent;
32
+ pointerenter: PointerEvent;
33
+ pointerleave: PointerEvent;
34
+ pointermove: PointerEvent;
35
+ pointerover: PointerEvent;
36
+ pointerout: PointerEvent;
37
+ pointerup: PointerEvent;
38
+ wheel: WheelEvent;
39
+ } & {
40
+ [evt: string]: CustomEvent<any>;
41
+ };
42
+ slots: {
43
+ item: {
44
+ checked: boolean;
45
+ disabled: boolean;
46
+ hasChildren: boolean;
47
+ depth: number;
48
+ menuItemId: string;
49
+ open: boolean;
50
+ role: "menuitem" | "menuitemcheckbox" | "menuitemradio";
51
+ text: string | undefined;
52
+ };
53
+ default: {};
54
+ };
55
+ };
56
+ export type MenuItemProps = typeof __propDef.props;
57
+ export type MenuItemEvents = typeof __propDef.events;
58
+ export type MenuItemSlots = typeof __propDef.slots;
59
+ export default class MenuItem extends SvelteComponentTyped<MenuItemProps, MenuItemEvents, MenuItemSlots> {
60
+ }
61
+ export {};
@@ -0,0 +1,97 @@
1
+ <script>export let checked = false;
2
+ export let hasChildren = false;
3
+ export let menuItemRole = "menuitem";
4
+ </script>
5
+
6
+ <div class="menu-item-display">
7
+ <div
8
+ class="check"
9
+ class:checkmark={menuItemRole === 'menuitemcheckbox'}
10
+ class:bullet={menuItemRole === 'menuitemradio'}
11
+ class:checked
12
+ />
13
+ <div class="content">
14
+ <slot />
15
+ </div>
16
+ {#if $$slots.shortcut}
17
+ <div class="shortcut">
18
+ <slot name="shortcut" />
19
+ </div>
20
+ {:else}
21
+ <div class="chevron" class:has-children={hasChildren} />
22
+ {/if}
23
+ </div>
24
+
25
+ <style>
26
+ .menu-item-display {
27
+ align-items: center;
28
+ justify-items: flex-start;
29
+ display: grid;
30
+ grid-template-columns: 1em 1fr 1em;
31
+ column-gap: 0.5em;
32
+ padding: 0.25em;
33
+ }
34
+
35
+ .check {
36
+ box-sizing: border-box;
37
+ pointer-events: none;
38
+ width: 20px;
39
+ height: 20px;
40
+ position: relative;
41
+ transition: background-color 250ms, color 250ms, border-color 250ms;
42
+ }
43
+
44
+ .check.checkmark.checked::after {
45
+ border-color: currentColor;
46
+ border-style: solid;
47
+ border-width: 0 0.2em 0.2em 0;
48
+ box-sizing: border-box;
49
+ content: '';
50
+ height: 0.8em;
51
+ left: 45%;
52
+ position: absolute;
53
+ top: 45%;
54
+ transform: translate(-50%, -50%) rotate(45deg);
55
+ transform-origin: center;
56
+ transition: border-color 250ms;
57
+ width: 0.4em;
58
+ }
59
+
60
+ .check.bullet.checked::after {
61
+ background-color: currentColor;
62
+ border-radius: 10000px;
63
+ content: '';
64
+ height: 0.5em;
65
+ left: 45%;
66
+ position: absolute;
67
+ top: 50%;
68
+ transform: translate(-50%, -50%);
69
+ transition: background-color 250ms;
70
+ width: 0.5em;
71
+ }
72
+
73
+ .content {
74
+ padding-top: 0.25em;
75
+ }
76
+
77
+ .chevron {
78
+ position: relative;
79
+ border: none;
80
+ background: none;
81
+ height: 1em;
82
+ width: 1em;
83
+ transform-origin: 50% 50%;
84
+ }
85
+
86
+ .chevron.has-children::after {
87
+ position: absolute;
88
+ content: '';
89
+ top: 50%;
90
+ left: 50%;
91
+ width: 7px;
92
+ height: 7px;
93
+ border-right: 3px solid currentColor;
94
+ border-top: 3px solid currentColor;
95
+ transform: translate(-50%, -50%) rotate(45deg);
96
+ }
97
+ </style>
@@ -0,0 +1,21 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ checked?: boolean | undefined;
5
+ hasChildren?: boolean | undefined;
6
+ menuItemRole?: "menuitem" | "menuitemcheckbox" | "menuitemradio" | undefined;
7
+ };
8
+ events: {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {
12
+ default: {};
13
+ shortcut: {};
14
+ };
15
+ };
16
+ export type MenuItemDisplayProps = typeof __propDef.props;
17
+ export type MenuItemDisplayEvents = typeof __propDef.events;
18
+ export type MenuItemDisplaySlots = typeof __propDef.slots;
19
+ export default class MenuItemDisplay extends SvelteComponentTyped<MenuItemDisplayProps, MenuItemDisplayEvents, MenuItemDisplaySlots> {
20
+ }
21
+ export {};
@@ -0,0 +1,42 @@
1
+ <!--
2
+ @component
3
+ A styled line to visually separate menu items in a menu.
4
+ -->
5
+ <div
6
+ class="sterling-menu-item-separator"
7
+ role="separator"
8
+ on:blur
9
+ on:click
10
+ on:dblclick
11
+ on:focus
12
+ on:focusin
13
+ on:focusout
14
+ on:keydown
15
+ on:keypress
16
+ on:keyup
17
+ on:mousedown
18
+ on:mouseenter
19
+ on:mouseleave
20
+ on:mousemove
21
+ on:mouseover
22
+ on:mouseout
23
+ on:mouseup
24
+ on:pointercancel
25
+ on:pointerdown
26
+ on:pointerenter
27
+ on:pointerleave
28
+ on:pointermove
29
+ on:pointerover
30
+ on:pointerout
31
+ on:pointerup
32
+ on:wheel
33
+ {...$$restProps}
34
+ />
35
+
36
+ <style>
37
+ .sterling-menu-item-separator {
38
+ height: var(--Common__border-width);
39
+ background-color: var(--Common__border-color);
40
+ margin: 0.1em 0;
41
+ }
42
+ </style>
@@ -0,0 +1,76 @@
1
+ /** @typedef {typeof __propDef.props} MenuSeparatorProps */
2
+ /** @typedef {typeof __propDef.events} MenuSeparatorEvents */
3
+ /** @typedef {typeof __propDef.slots} MenuSeparatorSlots */
4
+ /** A styled line to visually separate menu items in a menu. */
5
+ export default class MenuSeparator extends SvelteComponentTyped<{
6
+ [x: string]: never;
7
+ }, {
8
+ blur: FocusEvent;
9
+ click: MouseEvent;
10
+ dblclick: MouseEvent;
11
+ focus: FocusEvent;
12
+ focusin: FocusEvent;
13
+ focusout: FocusEvent;
14
+ keydown: KeyboardEvent;
15
+ keypress: KeyboardEvent;
16
+ keyup: KeyboardEvent;
17
+ mousedown: MouseEvent;
18
+ mouseenter: MouseEvent;
19
+ mouseleave: MouseEvent;
20
+ mousemove: MouseEvent;
21
+ mouseover: MouseEvent;
22
+ mouseout: MouseEvent;
23
+ mouseup: MouseEvent;
24
+ pointercancel: PointerEvent;
25
+ pointerdown: PointerEvent;
26
+ pointerenter: PointerEvent;
27
+ pointerleave: PointerEvent;
28
+ pointermove: PointerEvent;
29
+ pointerover: PointerEvent;
30
+ pointerout: PointerEvent;
31
+ pointerup: PointerEvent;
32
+ wheel: WheelEvent;
33
+ } & {
34
+ [evt: string]: CustomEvent<any>;
35
+ }, {}> {
36
+ }
37
+ export type MenuSeparatorProps = typeof __propDef.props;
38
+ export type MenuSeparatorEvents = typeof __propDef.events;
39
+ export type MenuSeparatorSlots = typeof __propDef.slots;
40
+ import { SvelteComponentTyped } from "svelte";
41
+ declare const __propDef: {
42
+ props: {
43
+ [x: string]: never;
44
+ };
45
+ events: {
46
+ blur: FocusEvent;
47
+ click: MouseEvent;
48
+ dblclick: MouseEvent;
49
+ focus: FocusEvent;
50
+ focusin: FocusEvent;
51
+ focusout: FocusEvent;
52
+ keydown: KeyboardEvent;
53
+ keypress: KeyboardEvent;
54
+ keyup: KeyboardEvent;
55
+ mousedown: MouseEvent;
56
+ mouseenter: MouseEvent;
57
+ mouseleave: MouseEvent;
58
+ mousemove: MouseEvent;
59
+ mouseover: MouseEvent;
60
+ mouseout: MouseEvent;
61
+ mouseup: MouseEvent;
62
+ pointercancel: PointerEvent;
63
+ pointerdown: PointerEvent;
64
+ pointerenter: PointerEvent;
65
+ pointerleave: PointerEvent;
66
+ pointermove: PointerEvent;
67
+ pointerover: PointerEvent;
68
+ pointerout: PointerEvent;
69
+ pointerup: PointerEvent;
70
+ wheel: WheelEvent;
71
+ } & {
72
+ [evt: string]: CustomEvent<any>;
73
+ };
74
+ slots: {};
75
+ };
76
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare const menuBarContextKey = "sterlingMenuBar";
2
+ export declare const menuItemContextKey = "sterlingMenuItem";
@@ -0,0 +1,2 @@
1
+ export const menuBarContextKey = 'sterlingMenuBar';
2
+ export const menuItemContextKey = 'sterlingMenuItem';
@@ -0,0 +1,22 @@
1
+ export type MenuItemRegistration = {
2
+ id: string;
3
+ open: () => void;
4
+ close: () => void;
5
+ focus: () => void;
6
+ };
7
+ export type MenuBarContext = {
8
+ openPreviousMenu?: (fromMenuItemId: string) => void;
9
+ openNextMenu?: (fromMenuItemId: string) => void;
10
+ };
11
+ export type MenuItemContext = {
12
+ rootMenuItemId?: string;
13
+ depth?: number;
14
+ register?: (menuItem: MenuItemRegistration) => void;
15
+ unregister?: (menuItem: MenuItemRegistration) => void;
16
+ focusPrevious?: (fromMenuItemId: string) => void;
17
+ focusNext?: (fromMenuItemId: string) => void;
18
+ closeMenu?: (recursive?: boolean) => void;
19
+ onOpen?: (menuItemId: string) => void;
20
+ onClose?: (menuItemId: string) => void;
21
+ onSelect?: (menuItemId: string) => void;
22
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { MenuItemRegistration } from './Menus.types';
2
+ export declare const focusPreviousChild: (children: MenuItemRegistration[], fromMenuItemId: string) => void;
3
+ export declare const focusNextChild: (children: MenuItemRegistration[], fromMenuItemId: string) => void;
4
+ export declare const focusFirstChild: (children: MenuItemRegistration[]) => void;
5
+ export declare const focusLastChild: (children: MenuItemRegistration[]) => void;
@@ -0,0 +1,20 @@
1
+ export const focusPreviousChild = (children, fromMenuItemId) => {
2
+ const index = children?.findIndex((menuItem) => menuItem.id === fromMenuItemId);
3
+ if (index !== -1) {
4
+ const focusIndex = index === 0 ? children.length - 1 : index - 1;
5
+ children[focusIndex].focus();
6
+ }
7
+ };
8
+ export const focusNextChild = (children, fromMenuItemId) => {
9
+ const index = children?.findIndex((menuItem) => menuItem.id === fromMenuItemId);
10
+ if (index !== -1) {
11
+ const focusIndex = (index + 1) % children.length;
12
+ children[focusIndex].focus();
13
+ }
14
+ };
15
+ export const focusFirstChild = (children) => {
16
+ children[0]?.focus();
17
+ };
18
+ export const focusLastChild = (children) => {
19
+ children[children.length - 1]?.focus();
20
+ };