@geoffcox/sterling-svelte 2.0.1 → 2.0.3

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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/Button.svelte +18 -14
  3. package/dist/Button.svelte.d.ts +0 -1
  4. package/dist/Callout.svelte +162 -96
  5. package/dist/Callout.svelte.d.ts +1 -2
  6. package/dist/Checkbox.svelte +34 -15
  7. package/dist/Checkbox.svelte.d.ts +0 -1
  8. package/dist/Dialog.svelte +121 -71
  9. package/dist/Dialog.svelte.d.ts +1 -1
  10. package/dist/Dropdown.svelte +106 -56
  11. package/dist/Dropdown.svelte.d.ts +8 -3
  12. package/dist/Input.svelte +54 -29
  13. package/dist/Input.svelte.d.ts +1 -2
  14. package/dist/Label.svelte +99 -55
  15. package/dist/Label.svelte.d.ts +4 -4
  16. package/dist/Link.svelte +20 -14
  17. package/dist/Link.svelte.d.ts +0 -1
  18. package/dist/List.svelte +181 -126
  19. package/dist/List.svelte.d.ts +0 -1
  20. package/dist/ListItem.svelte +36 -21
  21. package/dist/ListItem.svelte.d.ts +0 -1
  22. package/dist/Menu.svelte +67 -45
  23. package/dist/Menu.svelte.d.ts +0 -1
  24. package/dist/MenuBar.svelte +96 -65
  25. package/dist/MenuBar.svelte.d.ts +0 -1
  26. package/dist/MenuButton.svelte +102 -62
  27. package/dist/MenuButton.svelte.d.ts +1 -1
  28. package/dist/MenuItem.svelte +332 -243
  29. package/dist/MenuItem.svelte.d.ts +3 -3
  30. package/dist/MenuSeparator.svelte +7 -7
  31. package/dist/MenuSeparator.svelte.d.ts +0 -1
  32. package/dist/Pagination.svelte +267 -0
  33. package/dist/Pagination.svelte.d.ts +4 -0
  34. package/dist/Pagination.types.d.ts +24 -0
  35. package/dist/Pagination.types.js +1 -0
  36. package/dist/Popover.svelte +114 -60
  37. package/dist/Popover.svelte.d.ts +1 -2
  38. package/dist/Portal.types.d.ts +1 -4
  39. package/dist/Progress.svelte +40 -15
  40. package/dist/Progress.svelte.d.ts +0 -1
  41. package/dist/Radio.svelte +37 -25
  42. package/dist/Radio.svelte.d.ts +0 -1
  43. package/dist/Select.svelte +191 -125
  44. package/dist/Select.svelte.d.ts +8 -2
  45. package/dist/Slider.svelte +120 -71
  46. package/dist/Slider.svelte.d.ts +0 -1
  47. package/dist/Switch.svelte +51 -20
  48. package/dist/Switch.svelte.d.ts +1 -1
  49. package/dist/Tab.svelte +39 -24
  50. package/dist/Tab.svelte.d.ts +0 -1
  51. package/dist/TabList.svelte +176 -125
  52. package/dist/TabList.svelte.d.ts +0 -1
  53. package/dist/TextArea.svelte +83 -41
  54. package/dist/TextArea.svelte.d.ts +2 -3
  55. package/dist/Tooltip.svelte +68 -36
  56. package/dist/Tree.svelte +52 -24
  57. package/dist/Tree.svelte.d.ts +0 -1
  58. package/dist/TreeChevron.svelte +24 -12
  59. package/dist/TreeChevron.svelte.d.ts +0 -1
  60. package/dist/TreeItem.svelte +292 -225
  61. package/dist/TreeItem.svelte.d.ts +1 -1
  62. package/dist/actions/extraClass.d.ts +1 -0
  63. package/dist/actions/extraClass.js +1 -0
  64. package/dist/idGenerator.d.ts +1 -0
  65. package/dist/idGenerator.js +1 -0
  66. package/dist/index.d.ts +3 -2
  67. package/dist/index.js +3 -2
  68. package/dist/mediaQueries/prefersColorSchemeDark.d.ts +0 -1
  69. package/dist/mediaQueries/prefersReducedMotion.d.ts +0 -1
  70. package/dist/mediaQueries/usingKeyboard.d.ts +0 -1
  71. package/package.json +21 -22
@@ -1,274 +1,351 @@
1
1
  <svelte:options runes={true} />
2
2
 
3
- <script lang="ts">import { getContext, setContext, tick } from 'svelte';
4
- import { idGenerator } from './idGenerator';
5
- import Menu from './Menu.svelte';
6
- import { MENU_BAR_CONTEXT_KEY } from './MenuBar.constants';
7
- import { MENU_ITEM_CONTEXT_KEY } from './MenuItem.constants';
8
- import { isElementEnabledMenuItem } from './MenuItem.utils';
9
- import Popover from './Popover.svelte';
10
- import { usingKeyboard } from './mediaQueries/usingKeyboard';
11
- let { checked, children, class: _class, disabled, item, menuClass, onClose, onOpen, onSelect, role = 'menuitem', text, shortcut, value, ...rest } = $props();
12
- const menuItemContext = getContext(MENU_ITEM_CONTEXT_KEY) || {};
13
- const menuBarContext = getContext(MENU_BAR_CONTEXT_KEY) || {};
14
- const instanceId = idGenerator.nextId('MenuItem');
15
- let displayId = $derived(`${value}-display-${instanceId}`);
16
- let open = $derived(menuItemContext.openValues?.includes(value));
17
- let prevOpen = $state(menuItemContext.openValues?.includes(value));
18
- let menuId = $derived(`${value}-menu-${instanceId}`);
19
- let menuItemRef = $state();
20
- let menuRef = $state();
21
- //#region methods
22
- export const blur = () => {
3
+ <script lang="ts">
4
+ import { getContext, setContext, tick, type Snippet } from 'svelte';
5
+ import type {
6
+ HTMLButtonAttributes,
7
+ KeyboardEventHandler,
8
+ MouseEventHandler
9
+ } from 'svelte/elements';
10
+ import Menu from './Menu.svelte';
11
+ import { MENU_BAR_CONTEXT_KEY } from './MenuBar.constants';
12
+ import type { MenuBarContext } from './MenuBar.types';
13
+ import { MENU_ITEM_CONTEXT_KEY } from './MenuItem.constants';
14
+ import type { MenuItemContext, MenuItemRole } from './MenuItem.types';
15
+ import { isElementEnabledMenuItem } from './MenuItem.utils';
16
+ import Popover from './Popover.svelte';
17
+ import { usingKeyboard } from './mediaQueries/usingKeyboard';
18
+
19
+ const uuid = $props.id();
20
+
21
+ type Props = HTMLButtonAttributes & {
22
+ checked?: boolean | null;
23
+ item?: Snippet;
24
+ menuClass?: string;
25
+ onClose?: (value: string) => void;
26
+ onOpen?: (value: string) => void;
27
+ onSelect?: (value: string) => void;
28
+ role?: MenuItemRole;
29
+ shortcut?: string | Snippet;
30
+ text?: string | Snippet;
31
+ value: string;
32
+ };
33
+
34
+ let {
35
+ checked,
36
+ children,
37
+ class: _class,
38
+ disabled,
39
+ item,
40
+ menuClass,
41
+ onClose,
42
+ onOpen,
43
+ onSelect,
44
+ role = 'menuitem',
45
+ text,
46
+ shortcut,
47
+ value,
48
+ ...rest
49
+ }: Props = $props();
50
+
51
+ const menuItemContext = getContext<MenuItemContext>(MENU_ITEM_CONTEXT_KEY) || {};
52
+
53
+ const menuBarContext = getContext<MenuBarContext>(MENU_BAR_CONTEXT_KEY) || {};
54
+
55
+ const instanceId = `MenuItem-${uuid}`;
56
+
57
+ let displayId = $derived(`${value}-display-${instanceId}`);
58
+ let open = $derived(menuItemContext.openValues?.includes(value));
59
+ let prevOpen = $state(menuItemContext.openValues?.includes(value));
60
+ let menuId = $derived(`${value}-menu-${instanceId}`);
61
+
62
+ let menuItemRef: HTMLButtonElement | undefined = $state();
63
+ let menuRef: Menu | undefined = $state();
64
+
65
+ //#region methods
66
+
67
+ export const blur = () => {
23
68
  menuItemRef?.blur();
24
- };
25
- export const click = () => {
69
+ };
70
+
71
+ export const click = () => {
26
72
  menuItemRef?.click();
27
- };
28
- export const focus = (options) => {
73
+ };
74
+
75
+ export const focus = (options?: FocusOptions) => {
29
76
  menuItemRef?.focus(options);
30
- };
31
- //#endregion
32
- //#region events
33
- const raiseClose = (value) => {
77
+ };
78
+
79
+ //#endregion
80
+
81
+ //#region events
82
+
83
+ const raiseClose = (value: string) => {
34
84
  onClose?.(value);
35
85
  menuItemContext.onClose?.(value);
36
- };
37
- const raiseOpen = (value) => {
86
+ };
87
+
88
+ const raiseOpen = (value: string) => {
38
89
  onOpen?.(value);
39
90
  menuItemContext.onOpen?.(value);
40
- };
41
- const raiseSelect = (value) => {
91
+ };
92
+
93
+ const raiseSelect = (value: string) => {
42
94
  onSelect?.(value);
43
95
  menuItemContext.onSelect?.(value);
44
- };
45
- $effect(() => {
96
+ };
97
+
98
+ $effect(() => {
46
99
  if (open !== prevOpen) {
47
- open ? raiseOpen(value) : raiseClose(value);
100
+ open ? raiseOpen(value) : raiseClose(value);
48
101
  }
49
102
  prevOpen = open;
50
- });
51
- //#endregion
52
- //#region focus
53
- const focusPreviousMenuItem = () => {
54
- let candidate = menuItemRef?.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
103
+ });
104
+
105
+ //#endregion
106
+
107
+ //#region focus
108
+
109
+ const focusPreviousMenuItem = () => {
110
+ let candidate =
111
+ menuItemRef?.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
55
112
  while (candidate && !isElementEnabledMenuItem(candidate)) {
56
- candidate = candidate.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
57
- if (candidate === menuItemRef) {
58
- return false;
59
- }
113
+ candidate = candidate.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
114
+
115
+ if (candidate === menuItemRef) {
116
+ return false;
117
+ }
60
118
  }
61
- candidate?.focus();
119
+ (candidate as HTMLElement)?.focus();
62
120
  return !!candidate;
63
- };
64
- const focusNextMenuItem = () => {
65
- let candidate = menuItemRef?.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
121
+ };
122
+
123
+ const focusNextMenuItem = () => {
124
+ let candidate =
125
+ menuItemRef?.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
66
126
  while (candidate && !isElementEnabledMenuItem(candidate)) {
67
- candidate = candidate.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
68
- if (candidate === menuItemRef) {
69
- return false;
70
- }
127
+ candidate = candidate.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
128
+
129
+ if (candidate === menuItemRef) {
130
+ return false;
131
+ }
71
132
  }
72
- candidate?.focus();
133
+ (candidate as HTMLElement)?.focus();
73
134
  return !!candidate;
74
- };
75
- //#endregion
76
- //#region open/close
77
- // opens the menu for this menu item
78
- const openMenu = () => {
135
+ };
136
+
137
+ //#endregion
138
+
139
+ //#region open/close
140
+
141
+ // opens the menu for this menu item
142
+ const openMenu = () => {
79
143
  if (!menuItemContext.openValues.includes(value)) {
80
- // slice to depth to close any sibling menus that are open
81
- menuItemContext.openValues = [
82
- ...menuItemContext.openValues.slice(0, menuItemContext.depth),
83
- value
84
- ];
144
+ // slice to depth to close any sibling menus that are open
145
+ menuItemContext.openValues = [
146
+ ...menuItemContext.openValues.slice(0, menuItemContext.depth),
147
+ value
148
+ ];
85
149
  }
86
- };
87
- // closes the menu for this menu item
88
- const closeMenu = async () => {
150
+ };
151
+
152
+ // closes the menu for this menu item
153
+ const closeMenu = async () => {
89
154
  const index = menuItemContext.openValues.indexOf(value);
90
155
  if (index !== -1) {
91
- menuItemContext.openValues = [...menuItemContext.openValues.slice(0, index)];
92
- await tick();
93
- menuItemRef?.focus();
156
+ menuItemContext.openValues = [...menuItemContext.openValues.slice(0, index)];
157
+ await tick();
158
+ menuItemRef?.focus();
94
159
  }
95
- };
96
- const closeAllMenus = () => {
160
+ };
161
+
162
+ const closeAllMenus = () => {
97
163
  menuItemContext.openValues = [];
98
- };
99
- //#endregion
100
- //#region event handlers
101
- const onKeyDown = async (event) => {
164
+ };
165
+
166
+ //#endregion
167
+
168
+ //#region event handlers
169
+
170
+ const onKeyDown: KeyboardEventHandler<HTMLButtonElement> = async (event) => {
102
171
  if (!disabled && !event.altKey && !event.ctrlKey && !event.shiftKey) {
103
- switch (event.key) {
104
- case 'ArrowDown':
105
- // ARIA menubar/menuitem:
106
- // If the currently focused menuitem has a submenu,
107
- // opens the submenu and places focus on the first item in the submenu.
108
- if (menuItemContext.isMenuBarItem && children) {
109
- openMenu();
110
- setTimeout(async () => {
111
- await tick();
112
- menuRef?.focusFirstMenuItem();
113
- }, 10);
114
- event.preventDefault();
115
- event.stopPropagation();
116
- return false;
117
- }
118
- if (!menuItemContext.isMenuBarItem) {
119
- // ARIA menuitem:
120
- // Moves focus to the next item, optionally wrapping from the last to the first.
121
- focusNextMenuItem();
122
- event.preventDefault();
123
- event.stopPropagation();
124
- return false;
125
- }
126
- break;
127
- case 'ArrowLeft':
128
- // ARIA menubar/menuitem:
129
- // Moves focus to the previous item, optionally wrapping from the first to the last.
130
- if (menuItemContext.isMenuBarItem) {
131
- focusPreviousMenuItem();
132
- event.preventDefault();
133
- event.stopPropagation();
134
- return false;
135
- }
136
- // ARIA menuitem:
137
- // When focus is in a submenu of an item in a menu,
138
- // closes the submenu and returns focus to the parent menuitem.
139
- if (menuItemContext.depth && menuItemContext.depth > 1) {
140
- menuItemContext.closeContainingMenu?.();
141
- event.preventDefault();
142
- event.stopPropagation();
143
- return false;
144
- }
145
- // ARIA menubar/menuitem:
146
- // When focus is in a submenu of an item in a menubar,
147
- // closes the submenu,
148
- // moves focus to the previous item in the menubar,
149
- // and,
150
- // if focus is now on a menuitem with a submenu,
151
- // either opens the submenu of that menuitem without moving focus into the submenu,
152
- // or opens the submenu of that menuitem and places focus on the first item in the submenu.
153
- menuBarContext.openPreviousMenuBarItem?.();
154
- event.preventDefault();
155
- event.stopPropagation();
156
- return false;
157
- case 'ArrowRight':
158
- // ARIA menubar:
159
- // Moves focus to the next item, optionally wrapping from the last to the first.
160
- if (menuItemContext.isMenuBarItem) {
161
- focusNextMenuItem();
162
- event.preventDefault();
163
- event.stopPropagation();
164
- return false;
165
- }
166
- // ARIA menuitem:
167
- // When focus is in a menu and on a menuitem that has a submenu,
168
- // opens the submenu and places focus on its first item
169
- if (children) {
170
- openMenu();
171
- setTimeout(async () => {
172
- await tick();
173
- menuRef?.focusFirstMenuItem();
174
- }, 10);
175
- event.preventDefault();
176
- event.stopPropagation();
177
- return false;
178
- }
179
- // ARIA menubar/menuitem:
180
- // When focus is in a menu and on an item that does not have a submenu,
181
- // closes the submenu and any parent menus,
182
- // moves focus to the next item in the menubar,
183
- // and,
184
- // if focus is now on a menuitem with a submenu,
185
- // either opens the submenu of that menuitem without moving focus into the submenu,
186
- // or opens the submenu of that menuitem and places focus on the first item in the submenu.
187
- if (menuBarContext.openNextMenuBarItem) {
188
- menuBarContext.openNextMenuBarItem();
189
- event.preventDefault();
190
- event.stopPropagation();
191
- return false;
192
- }
193
- break;
194
- case 'ArrowUp':
195
- // ARIA menubar/menuitem:
196
- // If the currently focused menuitem has a submenu,
197
- // opens the submenu and places focus on the last item in the submenu.
198
- if (menuItemContext.isMenuBarItem && children) {
199
- openMenu();
200
- setTimeout(async () => {
201
- await tick();
202
- menuRef?.focusLastMenuItem();
203
- }, 10);
204
- event.preventDefault();
205
- event.stopPropagation();
206
- return false;
207
- }
208
- // ARIA menuitem:
209
- // Moves focus to the previous item, optionally wrapping from the first to the last.
210
- if (!menuItemContext.isMenuBarItem) {
211
- focusPreviousMenuItem();
212
- event.preventDefault();
213
- event.stopPropagation();
214
- return false;
215
- }
216
- break;
217
- case 'Escape':
218
- // ARIA menuitem:
219
- // Close the menu that contains focus and return focus to the element or context,
220
- // e.g., menu button or parent menuitem, from which the menu was opened.
221
- // open = false;
222
- closeAllMenus();
223
- event.preventDefault();
224
- event.stopPropagation();
225
- return false;
226
- }
227
- }
228
- rest.onkeydown?.(event);
229
- };
230
- const onMouseEnter = (event) => {
231
- menuItemRef?.focus();
232
- rest.onmouseenter?.(event);
233
- };
234
- const onClick = (event) => {
235
- if (!disabled) {
236
- if (children) {
237
- if (!menuItemContext.openValues.includes(value)) {
238
- openMenu();
239
- if ($usingKeyboard) {
240
- setTimeout(async () => {
241
- await tick();
242
- menuRef?.focusFirstMenuItem();
243
- }, 10);
244
- }
245
- }
246
- else {
247
- closeMenu();
248
- }
172
+ switch (event.key) {
173
+ case 'ArrowDown':
174
+ // ARIA menubar/menuitem:
175
+ // If the currently focused menuitem has a submenu,
176
+ // opens the submenu and places focus on the first item in the submenu.
177
+ if (menuItemContext.isMenuBarItem && children) {
178
+ openMenu();
179
+ setTimeout(async () => {
180
+ await tick();
181
+ menuRef?.focusFirstMenuItem();
182
+ }, 10);
249
183
  event.preventDefault();
250
184
  event.stopPropagation();
251
185
  return false;
252
- }
253
- else {
254
- raiseSelect(value);
255
- closeAllMenus();
186
+ }
187
+
188
+ if (!menuItemContext.isMenuBarItem) {
189
+ // ARIA menuitem:
190
+ // Moves focus to the next item, optionally wrapping from the last to the first.
191
+ focusNextMenuItem();
192
+ event.preventDefault();
193
+ event.stopPropagation();
194
+ return false;
195
+ }
196
+ break;
197
+ case 'ArrowLeft':
198
+ // ARIA menubar/menuitem:
199
+ // Moves focus to the previous item, optionally wrapping from the first to the last.
200
+ if (menuItemContext.isMenuBarItem) {
201
+ focusPreviousMenuItem();
202
+ event.preventDefault();
203
+ event.stopPropagation();
204
+ return false;
205
+ }
206
+
207
+ // ARIA menuitem:
208
+ // When focus is in a submenu of an item in a menu,
209
+ // closes the submenu and returns focus to the parent menuitem.
210
+ if (menuItemContext.depth && menuItemContext.depth > 1) {
211
+ menuItemContext.closeContainingMenu?.();
212
+ event.preventDefault();
213
+ event.stopPropagation();
214
+ return false;
215
+ }
216
+
217
+ // ARIA menubar/menuitem:
218
+ // When focus is in a submenu of an item in a menubar,
219
+ // closes the submenu,
220
+ // moves focus to the previous item in the menubar,
221
+ // and,
222
+ // if focus is now on a menuitem with a submenu,
223
+ // either opens the submenu of that menuitem without moving focus into the submenu,
224
+ // or opens the submenu of that menuitem and places focus on the first item in the submenu.
225
+ menuBarContext.openPreviousMenuBarItem?.();
226
+ event.preventDefault();
227
+ event.stopPropagation();
228
+ return false;
229
+ case 'ArrowRight':
230
+ // ARIA menubar:
231
+ // Moves focus to the next item, optionally wrapping from the last to the first.
232
+ if (menuItemContext.isMenuBarItem) {
233
+ focusNextMenuItem();
234
+ event.preventDefault();
235
+ event.stopPropagation();
236
+ return false;
237
+ }
238
+
239
+ // ARIA menuitem:
240
+ // When focus is in a menu and on a menuitem that has a submenu,
241
+ // opens the submenu and places focus on its first item
242
+ if (children) {
243
+ openMenu();
244
+ setTimeout(async () => {
245
+ await tick();
246
+ menuRef?.focusFirstMenuItem();
247
+ }, 10);
248
+ event.preventDefault();
249
+ event.stopPropagation();
250
+ return false;
251
+ }
252
+
253
+ // ARIA menubar/menuitem:
254
+ // When focus is in a menu and on an item that does not have a submenu,
255
+ // closes the submenu and any parent menus,
256
+ // moves focus to the next item in the menubar,
257
+ // and,
258
+ // if focus is now on a menuitem with a submenu,
259
+ // either opens the submenu of that menuitem without moving focus into the submenu,
260
+ // or opens the submenu of that menuitem and places focus on the first item in the submenu.
261
+ if (menuBarContext.openNextMenuBarItem) {
262
+ menuBarContext.openNextMenuBarItem();
256
263
  event.preventDefault();
257
264
  event.stopPropagation();
258
265
  return false;
266
+ }
267
+ break;
268
+ case 'ArrowUp':
269
+ // ARIA menubar/menuitem:
270
+ // If the currently focused menuitem has a submenu,
271
+ // opens the submenu and places focus on the last item in the submenu.
272
+ if (menuItemContext.isMenuBarItem && children) {
273
+ openMenu();
274
+ setTimeout(async () => {
275
+ await tick();
276
+ menuRef?.focusLastMenuItem();
277
+ }, 10);
278
+ event.preventDefault();
279
+ event.stopPropagation();
280
+ return false;
281
+ }
282
+
283
+ // ARIA menuitem:
284
+ // Moves focus to the previous item, optionally wrapping from the first to the last.
285
+ if (!menuItemContext.isMenuBarItem) {
286
+ focusPreviousMenuItem();
287
+ event.preventDefault();
288
+ event.stopPropagation();
289
+ return false;
290
+ }
291
+ break;
292
+ case 'Escape':
293
+ // ARIA menuitem:
294
+ // Close the menu that contains focus and return focus to the element or context,
295
+ // e.g., menu button or parent menuitem, from which the menu was opened.
296
+ // open = false;
297
+ closeAllMenus();
298
+ event.preventDefault();
299
+ event.stopPropagation();
300
+ return false;
301
+ }
302
+ }
303
+ rest.onkeydown?.(event);
304
+ };
305
+
306
+ const onMouseEnter: MouseEventHandler<HTMLButtonElement> = (event) => {
307
+ menuItemRef?.focus();
308
+ rest.onmouseenter?.(event);
309
+ };
310
+
311
+ const onClick: MouseEventHandler<HTMLButtonElement> = (event) => {
312
+ if (!disabled) {
313
+ if (children) {
314
+ if (!menuItemContext.openValues.includes(value)) {
315
+ openMenu();
316
+ if ($usingKeyboard) {
317
+ setTimeout(async () => {
318
+ await tick();
319
+ menuRef?.focusFirstMenuItem();
320
+ }, 10);
321
+ }
322
+ } else {
323
+ closeMenu();
259
324
  }
325
+ event.preventDefault();
326
+ event.stopPropagation();
327
+ return false;
328
+ } else {
329
+ raiseSelect(value);
330
+ closeAllMenus();
331
+ event.preventDefault();
332
+ event.stopPropagation();
333
+ return false;
334
+ }
260
335
  }
261
336
  rest.onclick?.(event);
262
- };
263
- //#endregion
264
- //#region set context
265
- let menuItemChildContext = {
337
+ };
338
+
339
+ //#endregion
340
+
341
+ //#region set context
342
+ let menuItemChildContext: MenuItemContext = {
266
343
  isMenuBarItem: false,
267
344
  get openValues() {
268
- return menuItemContext.openValues;
345
+ return menuItemContext.openValues;
269
346
  },
270
- set openValues(value) {
271
- menuItemContext.openValues = value;
347
+ set openValues(value: string[]) {
348
+ menuItemContext.openValues = value;
272
349
  },
273
350
  rootValue: menuItemContext.rootValue || value,
274
351
  depth: menuItemContext.depth ? menuItemContext.depth + 1 : 1,
@@ -276,13 +353,15 @@ let menuItemChildContext = {
276
353
  onOpen: raiseOpen,
277
354
  onClose: raiseClose,
278
355
  onSelect: raiseSelect
279
- };
280
- setContext(MENU_ITEM_CONTEXT_KEY, menuItemChildContext);
281
- //#endregion
356
+ };
357
+
358
+ setContext<MenuItemContext>(MENU_ITEM_CONTEXT_KEY, menuItemChildContext);
359
+
360
+ //#endregion
282
361
  </script>
283
362
 
284
363
  {#snippet renderDefaultItem()}
285
- <div class="sterling-menu-item-display" class:disabled>
364
+ <div class="default-item sterling-menu-item-display" class:disabled>
286
365
  <div
287
366
  class="check"
288
367
  class:checkmark={role === 'menuitemcheckbox'}
@@ -290,13 +369,23 @@ setContext(MENU_ITEM_CONTEXT_KEY, menuItemChildContext);
290
369
  class:checked
291
370
  ></div>
292
371
  <div class="content">
293
- {text}
372
+ {#if text}
373
+ {#if typeof text === 'string'}
374
+ {text}
375
+ {:else}
376
+ {@render text()}
377
+ {/if}
378
+ {/if}
379
+ </div>
380
+ <div class="shortcut">
381
+ {#if shortcut}
382
+ {#if typeof shortcut === 'string'}
383
+ {shortcut}
384
+ {:else}
385
+ {@render shortcut()}
386
+ {/if}
387
+ {/if}
294
388
  </div>
295
- {#if shortcut}
296
- <div class="shortcut">
297
- {shortcut}
298
- </div>
299
- {/if}
300
389
  <div class="chevron" class:has-children={!menuItemContext.isMenuBarItem && !!children}></div>
301
390
  </div>
302
391
  {/snippet}
@@ -308,7 +397,7 @@ setContext(MENU_ITEM_CONTEXT_KEY, menuItemChildContext);
308
397
  aria-expanded={open}
309
398
  aria-haspopup={!!children}
310
399
  aria-owns={menuId}
311
- class={['sterling-menu-item', _class].filter(Boolean).join(' ')}
400
+ class={['sterling-menu-item', _class]}
312
401
  class:using-keyboard={usingKeyboard}
313
402
  data-value={value}
314
403
  data-root-value={menuItemContext.rootValue}
@@ -1,6 +1,6 @@
1
- import type { MenuItemRole } from './MenuItem.types';
2
1
  import { type Snippet } from 'svelte';
3
2
  import type { HTMLButtonAttributes } from 'svelte/elements';
3
+ import type { MenuItemRole } from './MenuItem.types';
4
4
  type Props = HTMLButtonAttributes & {
5
5
  checked?: boolean | null;
6
6
  item?: Snippet;
@@ -9,8 +9,8 @@ type Props = HTMLButtonAttributes & {
9
9
  onOpen?: (value: string) => void;
10
10
  onSelect?: (value: string) => void;
11
11
  role?: MenuItemRole;
12
- shortcut?: string;
13
- text?: string;
12
+ shortcut?: string | Snippet;
13
+ text?: string | Snippet;
14
14
  value: string;
15
15
  };
16
16
  declare const MenuItem: import("svelte").Component<Props, {
@@ -1,11 +1,11 @@
1
1
  <svelte:options runes={true} />
2
2
 
3
- <script lang="ts">let { class: _class, ...rest } = $props();
4
- export {};
3
+ <script lang="ts">
4
+ import type { HTMLAttributes } from 'svelte/elements';
5
+
6
+ type Props = HTMLAttributes<HTMLDivElement>;
7
+
8
+ let { class: _class, ...rest }: Props = $props();
5
9
  </script>
6
10
 
7
- <div
8
- class={['sterling-menu-separator', _class].filter(Boolean).join(' ')}
9
- role="separator"
10
- {...rest}
11
- ></div>
11
+ <div class={['sterling-menu-separator', _class]} role="separator" {...rest}></div>
@@ -1,4 +1,3 @@
1
- /// <reference types="svelte" />
2
1
  import type { HTMLAttributes } from 'svelte/elements';
3
2
  type Props = HTMLAttributes<HTMLDivElement>;
4
3
  declare const MenuSeparator: import("svelte").Component<Props, {}, "">;