@geoffcox/sterling-svelte 1.0.12 → 2.0.1

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 (219) hide show
  1. package/dist/Button.svelte +8 -46
  2. package/dist/Button.svelte.d.ts +9 -65
  3. package/dist/Callout.svelte +47 -72
  4. package/dist/Callout.svelte.d.ts +14 -55
  5. package/dist/Callout.types.d.ts +11 -0
  6. package/dist/Checkbox.svelte +12 -48
  7. package/dist/Checkbox.svelte.d.ts +9 -62
  8. package/dist/Dialog.svelte +30 -38
  9. package/dist/Dialog.svelte.d.ts +13 -36
  10. package/dist/Dropdown.svelte +39 -71
  11. package/dist/Dropdown.svelte.d.ts +17 -76
  12. package/dist/Input.svelte +16 -50
  13. package/dist/Input.svelte.d.ts +12 -74
  14. package/dist/Label.svelte +55 -161
  15. package/dist/Label.svelte.d.ts +16 -81
  16. package/dist/Link.svelte +9 -41
  17. package/dist/Link.svelte.d.ts +11 -64
  18. package/dist/List.svelte +35 -85
  19. package/dist/List.svelte.d.ts +19 -74
  20. package/dist/List.types.d.ts +3 -11
  21. package/dist/ListItem.svelte +27 -56
  22. package/dist/ListItem.svelte.d.ts +12 -66
  23. package/dist/Menu.svelte +18 -45
  24. package/dist/Menu.svelte.d.ts +13 -63
  25. package/dist/MenuBar.svelte +36 -78
  26. package/dist/MenuBar.svelte.d.ts +12 -57
  27. package/dist/MenuButton.svelte +56 -85
  28. package/dist/MenuButton.svelte.d.ts +19 -70
  29. package/dist/MenuItem.svelte +107 -151
  30. package/dist/MenuItem.svelte.d.ts +21 -82
  31. package/dist/MenuItem.types.d.ts +1 -9
  32. package/dist/MenuSeparator.svelte +9 -7
  33. package/dist/MenuSeparator.svelte.d.ts +6 -20
  34. package/dist/Popover.svelte +45 -64
  35. package/dist/Popover.svelte.d.ts +14 -58
  36. package/dist/Progress.constants.d.ts +1 -1
  37. package/dist/Progress.constants.js +1 -1
  38. package/dist/Progress.svelte +24 -71
  39. package/dist/Progress.svelte.d.ts +11 -60
  40. package/dist/Progress.types.d.ts +3 -3
  41. package/dist/Radio.svelte +19 -92
  42. package/dist/Radio.svelte.d.ts +11 -63
  43. package/dist/Select.svelte +55 -94
  44. package/dist/Select.svelte.d.ts +19 -82
  45. package/dist/Slider.svelte +41 -98
  46. package/dist/Slider.svelte.d.ts +18 -65
  47. package/dist/Switch.svelte +29 -78
  48. package/dist/Switch.svelte.d.ts +20 -73
  49. package/dist/Tab.svelte +23 -66
  50. package/dist/Tab.svelte.d.ts +11 -70
  51. package/dist/TabList.svelte +50 -76
  52. package/dist/TabList.svelte.d.ts +17 -69
  53. package/dist/TabList.types.d.ts +3 -11
  54. package/dist/TextArea.svelte +17 -59
  55. package/dist/TextArea.svelte.d.ts +18 -68
  56. package/dist/Tooltip.svelte +23 -66
  57. package/dist/Tooltip.svelte.d.ts +9 -69
  58. package/dist/Tree.svelte +32 -83
  59. package/dist/Tree.svelte.d.ts +14 -66
  60. package/dist/Tree.types.d.ts +3 -11
  61. package/dist/TreeChevron.svelte +10 -49
  62. package/dist/TreeChevron.svelte.d.ts +8 -52
  63. package/dist/TreeItem.svelte +105 -159
  64. package/dist/TreeItem.svelte.d.ts +21 -100
  65. package/dist/TreeItem.types.d.ts +2 -12
  66. package/dist/actions/clickOutside.d.ts +1 -0
  67. package/dist/actions/clickOutside.js +1 -0
  68. package/dist/actions/extraClass.d.ts +8 -0
  69. package/dist/actions/extraClass.js +14 -0
  70. package/dist/index.d.ts +4 -12
  71. package/dist/index.js +3 -9
  72. package/package.json +20 -22
  73. package/dist/Button.constants.d.ts +0 -2
  74. package/dist/Button.constants.js +0 -2
  75. package/dist/Button.types.d.ts +0 -6
  76. package/dist/ColorPicker.constants.d.ts +0 -1
  77. package/dist/ColorPicker.constants.js +0 -1
  78. package/dist/ColorPicker.svelte +0 -287
  79. package/dist/ColorPicker.svelte.d.ts +0 -52
  80. package/dist/ColorPicker.types.d.ts +0 -4
  81. package/dist/ColorPicker.types.js +0 -1
  82. package/dist/HexColorSliders.svelte +0 -103
  83. package/dist/HexColorSliders.svelte.d.ts +0 -51
  84. package/dist/HslColorSliders.svelte +0 -128
  85. package/dist/HslColorSliders.svelte.d.ts +0 -51
  86. package/dist/Label.types.d.ts +0 -6
  87. package/dist/Label.types.js +0 -1
  88. package/dist/MenuItemDisplay.svelte +0 -32
  89. package/dist/MenuItemDisplay.svelte.d.ts +0 -39
  90. package/dist/RgbColorSliders.svelte +0 -93
  91. package/dist/RgbColorSliders.svelte.d.ts +0 -24
  92. package/dist/TreeItemDisplay.svelte +0 -74
  93. package/dist/TreeItemDisplay.svelte.d.ts +0 -73
  94. package/dist/css/Button.base.css +0 -54
  95. package/dist/css/Button.colorful.css +0 -17
  96. package/dist/css/Button.css +0 -8
  97. package/dist/css/Button.disabled.css +0 -22
  98. package/dist/css/Button.secondary.colorful.css +0 -15
  99. package/dist/css/Button.secondary.css +0 -11
  100. package/dist/css/Button.shapes.css +0 -14
  101. package/dist/css/Button.tool.colorful.css +0 -13
  102. package/dist/css/Button.tool.css +0 -18
  103. package/dist/css/Callout.base.css +0 -55
  104. package/dist/css/Callout.colorful.css +0 -5
  105. package/dist/css/Callout.css +0 -2
  106. package/dist/css/Checkbox.base.css +0 -121
  107. package/dist/css/Checkbox.colorful.css +0 -17
  108. package/dist/css/Checkbox.css +0 -3
  109. package/dist/css/Checkbox.disabled.css +0 -28
  110. package/dist/css/ColorPicker.base.css +0 -23
  111. package/dist/css/ColorPicker.css +0 -1
  112. package/dist/css/Dialog.base.css +0 -114
  113. package/dist/css/Dialog.css +0 -1
  114. package/dist/css/Dropdown.base.css +0 -105
  115. package/dist/css/Dropdown.colorful.css +0 -23
  116. package/dist/css/Dropdown.composed.css +0 -11
  117. package/dist/css/Dropdown.css +0 -4
  118. package/dist/css/Dropdown.disabled.css +0 -32
  119. package/dist/css/HexColorSliders.base.css +0 -87
  120. package/dist/css/HexColorSliders.css +0 -1
  121. package/dist/css/HslColorSliders.base.css +0 -105
  122. package/dist/css/HslColorSliders.css +0 -1
  123. package/dist/css/Input.base.css +0 -72
  124. package/dist/css/Input.colorful.css +0 -22
  125. package/dist/css/Input.composed.css +0 -12
  126. package/dist/css/Input.css +0 -4
  127. package/dist/css/Input.disabled.css +0 -24
  128. package/dist/css/Label.base.css +0 -114
  129. package/dist/css/Label.boxed.colorful.css +0 -21
  130. package/dist/css/Label.boxed.css +0 -31
  131. package/dist/css/Label.colorful.css +0 -3
  132. package/dist/css/Label.css +0 -5
  133. package/dist/css/Label.disabled.css +0 -9
  134. package/dist/css/Link.base.css +0 -43
  135. package/dist/css/Link.colorful.css +0 -15
  136. package/dist/css/Link.css +0 -11
  137. package/dist/css/Link.disabled.css +0 -10
  138. package/dist/css/Link.ghost.colorful.css +0 -7
  139. package/dist/css/Link.ghost.css +0 -11
  140. package/dist/css/Link.text-underline.css +0 -8
  141. package/dist/css/Link.text-underline.ghost.css +0 -13
  142. package/dist/css/Link.undecorated.colorful.css +0 -8
  143. package/dist/css/Link.undecorated.css +0 -8
  144. package/dist/css/Link.undecorated.ghost.css +0 -8
  145. package/dist/css/Link.undecorated.underline.css +0 -8
  146. package/dist/css/List.base.css +0 -84
  147. package/dist/css/List.composed.css +0 -8
  148. package/dist/css/List.css +0 -3
  149. package/dist/css/List.disabled.css +0 -7
  150. package/dist/css/ListItem.base.css +0 -33
  151. package/dist/css/ListItem.css +0 -2
  152. package/dist/css/ListItem.disabled.css +0 -28
  153. package/dist/css/Menu.base.css +0 -21
  154. package/dist/css/Menu.css +0 -1
  155. package/dist/css/MenuBar.base.css +0 -9
  156. package/dist/css/MenuBar.css +0 -1
  157. package/dist/css/MenuButton.base.css +0 -13
  158. package/dist/css/MenuButton.css +0 -1
  159. package/dist/css/MenuItem.base.css +0 -48
  160. package/dist/css/MenuItem.css +0 -1
  161. package/dist/css/MenuItemDisplay.base.css +0 -79
  162. package/dist/css/MenuItemDisplay.css +0 -2
  163. package/dist/css/MenuItemDisplay.disabled.css +0 -28
  164. package/dist/css/MenuSeparator.base.css +0 -5
  165. package/dist/css/MenuSeparator.css +0 -1
  166. package/dist/css/Popover.css +0 -21
  167. package/dist/css/Progress.base.css +0 -85
  168. package/dist/css/Progress.css +0 -2
  169. package/dist/css/Progress.disabled.css +0 -17
  170. package/dist/css/Radio.base.css +0 -109
  171. package/dist/css/Radio.colorful.css +0 -18
  172. package/dist/css/Radio.css +0 -3
  173. package/dist/css/Radio.disabled.css +0 -28
  174. package/dist/css/RgbColorSliders.base.css +0 -94
  175. package/dist/css/RgbColorSliders.css +0 -1
  176. package/dist/css/Select.base.css +0 -101
  177. package/dist/css/Select.colorful.css +0 -24
  178. package/dist/css/Select.composed.css +0 -12
  179. package/dist/css/Select.css +0 -4
  180. package/dist/css/Select.disabled.css +0 -28
  181. package/dist/css/Slider.base.css +0 -152
  182. package/dist/css/Slider.colorful.css +0 -11
  183. package/dist/css/Slider.composed.css +0 -8
  184. package/dist/css/Slider.css +0 -4
  185. package/dist/css/Slider.disabled.css +0 -30
  186. package/dist/css/Switch.base.css +0 -175
  187. package/dist/css/Switch.colorful.css +0 -45
  188. package/dist/css/Switch.css +0 -3
  189. package/dist/css/Switch.disabled.css +0 -30
  190. package/dist/css/Tab.base.css +0 -96
  191. package/dist/css/Tab.colorful.css +0 -13
  192. package/dist/css/Tab.css +0 -3
  193. package/dist/css/Tab.disabled.css +0 -36
  194. package/dist/css/TabList.base.css +0 -34
  195. package/dist/css/TabList.css +0 -1
  196. package/dist/css/TextArea.base.css +0 -62
  197. package/dist/css/TextArea.colorful.css +0 -17
  198. package/dist/css/TextArea.composed.css +0 -8
  199. package/dist/css/TextArea.css +0 -4
  200. package/dist/css/TextArea.disabled.css +0 -28
  201. package/dist/css/Tooltip.base.css +0 -6
  202. package/dist/css/Tooltip.css +0 -1
  203. package/dist/css/Tree.base.css +0 -49
  204. package/dist/css/Tree.composed.css +0 -8
  205. package/dist/css/Tree.css +0 -3
  206. package/dist/css/Tree.disabled.css +0 -27
  207. package/dist/css/TreeChevron.base.css +0 -86
  208. package/dist/css/TreeChevron.css +0 -1
  209. package/dist/css/TreeItem.base.css +0 -3
  210. package/dist/css/TreeItem.css +0 -1
  211. package/dist/css/TreeItemDisplay.base.css +0 -48
  212. package/dist/css/TreeItemDisplay.colorful.css +0 -9
  213. package/dist/css/TreeItemDisplay.css +0 -3
  214. package/dist/css/TreeItemDisplay.disabled.css +0 -28
  215. package/dist/css/dark-mode.css +0 -134
  216. package/dist/css/light-mode.css +0 -134
  217. package/dist/css/sterling.css +0 -37
  218. package/dist/package.json +0 -108
  219. /package/dist/{Button.types.js → Callout.types.js} +0 -0
@@ -1,46 +1,24 @@
1
- <script>import { getContext, afterUpdate, createEventDispatcher, onMount, setContext, tick } from 'svelte';
2
- import { writable } from 'svelte/store';
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { getContext, setContext, tick } from 'svelte';
3
4
  import { idGenerator } from './idGenerator';
4
5
  import Menu from './Menu.svelte';
5
6
  import { MENU_BAR_CONTEXT_KEY } from './MenuBar.constants';
6
7
  import { MENU_ITEM_CONTEXT_KEY } from './MenuItem.constants';
7
8
  import { isElementEnabledMenuItem } from './MenuItem.utils';
8
- import MenuItemDisplay from './MenuItemDisplay.svelte';
9
9
  import Popover from './Popover.svelte';
10
10
  import { usingKeyboard } from './mediaQueries/usingKeyboard';
11
- // ----- Props ----- //
12
- /**
13
- * When true, the menu item is checked.
14
- * Use with role='menuitemcheckbox' or role='menuitemradio'.
15
- */
16
- export let checked = false;
17
- /** When true, the menu item is disabled. */
18
- export let disabled = false;
19
- /** The role of the menu item. */
20
- export let role = 'menuitem';
21
- /** The text of the menu item. Not used when the item slot is filled.*/
22
- export let text = undefined;
23
- /** The value uniquely identifying this menu item within the menu hierarchy. */
24
- export let value;
25
- /** Additional class names to apply. */
26
- export let variant = '';
27
- /** Additional class names to apply to the sub Menu*/
28
- export let menuVariant = '';
29
- // ----- Get Context ----- //
30
- const { isMenuBarItem, openValues = writable([]), rootValue = value, depth = 0, closeContainingMenu = undefined, onOpen = undefined, onClose = undefined, onSelect = undefined } = getContext(MENU_ITEM_CONTEXT_KEY) || {};
31
- const { openPreviousMenuBarItem = undefined, openNextMenuBarItem = undefined } = getContext(MENU_BAR_CONTEXT_KEY) || {};
32
- // ----- State ----- //
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) || {};
33
14
  const instanceId = idGenerator.nextId('MenuItem');
34
- $: displayId = `${value}-display-${instanceId}`;
35
- $: open = $openValues.includes(value);
36
- $: menuId = `${value}-menu-${instanceId}`;
37
- let menuItemRef;
38
- let menuRef;
39
- const children = writable([]);
40
- let mounted = false;
41
- let prevOpen = open;
42
- $: hasChildren = $$slots.default;
43
- // ----- Methods ----- //
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
44
22
  export const blur = () => {
45
23
  menuItemRef?.blur();
46
24
  };
@@ -50,30 +28,28 @@ export const click = () => {
50
28
  export const focus = (options) => {
51
29
  menuItemRef?.focus(options);
52
30
  };
53
- // ----- Events ----- //
54
- const dispatch = createEventDispatcher();
31
+ //#endregion
32
+ //#region events
55
33
  const raiseClose = (value) => {
56
- dispatch('close', { value });
57
34
  onClose?.(value);
35
+ menuItemContext.onClose?.(value);
58
36
  };
59
37
  const raiseOpen = (value) => {
60
- dispatch('open', { value });
61
38
  onOpen?.(value);
39
+ menuItemContext.onOpen?.(value);
62
40
  };
63
- $: {
64
- if (hasChildren && open !== prevOpen) {
65
- open ? raiseOpen(value) : raiseClose(value);
66
- }
67
- prevOpen = open;
68
- }
69
- // dispatches the event and bubbles it up the context
70
- // so that container components can subscribe to select
71
- // events for children.
72
41
  const raiseSelect = (value) => {
73
- dispatch('select', { value });
74
42
  onSelect?.(value);
43
+ menuItemContext.onSelect?.(value);
75
44
  };
76
- // ----- Focus ----- //
45
+ $effect(() => {
46
+ if (open !== prevOpen) {
47
+ open ? raiseOpen(value) : raiseClose(value);
48
+ }
49
+ prevOpen = open;
50
+ });
51
+ //#endregion
52
+ //#region focus
77
53
  const focusPreviousMenuItem = () => {
78
54
  let candidate = menuItemRef?.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
79
55
  while (candidate && !isElementEnabledMenuItem(candidate)) {
@@ -96,33 +72,32 @@ const focusNextMenuItem = () => {
96
72
  candidate?.focus();
97
73
  return !!candidate;
98
74
  };
99
- // ----- Open/Close ----- //
75
+ //#endregion
76
+ //#region open/close
100
77
  // opens the menu for this menu item
101
78
  const openMenu = () => {
102
- if (!$openValues.includes(value)) {
79
+ if (!menuItemContext.openValues.includes(value)) {
103
80
  // slice to depth to close any sibling menus that are open
104
- openValues.set([...$openValues.slice(0, depth), value]);
81
+ menuItemContext.openValues = [
82
+ ...menuItemContext.openValues.slice(0, menuItemContext.depth),
83
+ value
84
+ ];
105
85
  }
106
86
  };
107
87
  // closes the menu for this menu item
108
88
  const closeMenu = async () => {
109
- const index = $openValues.indexOf(value);
89
+ const index = menuItemContext.openValues.indexOf(value);
110
90
  if (index !== -1) {
111
- openValues.set([...$openValues.slice(0, index)]);
91
+ menuItemContext.openValues = [...menuItemContext.openValues.slice(0, index)];
112
92
  await tick();
113
93
  menuItemRef?.focus();
114
94
  }
115
95
  };
116
96
  const closeAllMenus = () => {
117
- openValues.set([]);
97
+ menuItemContext.openValues = [];
118
98
  };
119
- // ----- Event Handlers ----- //
120
- onMount(() => {
121
- mounted = true;
122
- });
123
- afterUpdate(() => {
124
- prevOpen = open;
125
- });
99
+ //#endregion
100
+ //#region event handlers
126
101
  const onKeyDown = async (event) => {
127
102
  if (!disabled && !event.altKey && !event.ctrlKey && !event.shiftKey) {
128
103
  switch (event.key) {
@@ -130,7 +105,7 @@ const onKeyDown = async (event) => {
130
105
  // ARIA menubar/menuitem:
131
106
  // If the currently focused menuitem has a submenu,
132
107
  // opens the submenu and places focus on the first item in the submenu.
133
- if (isMenuBarItem && hasChildren) {
108
+ if (menuItemContext.isMenuBarItem && children) {
134
109
  openMenu();
135
110
  setTimeout(async () => {
136
111
  await tick();
@@ -140,7 +115,7 @@ const onKeyDown = async (event) => {
140
115
  event.stopPropagation();
141
116
  return false;
142
117
  }
143
- if (!isMenuBarItem) {
118
+ if (!menuItemContext.isMenuBarItem) {
144
119
  // ARIA menuitem:
145
120
  // Moves focus to the next item, optionally wrapping from the last to the first.
146
121
  focusNextMenuItem();
@@ -152,7 +127,7 @@ const onKeyDown = async (event) => {
152
127
  case 'ArrowLeft':
153
128
  // ARIA menubar/menuitem:
154
129
  // Moves focus to the previous item, optionally wrapping from the first to the last.
155
- if (isMenuBarItem) {
130
+ if (menuItemContext.isMenuBarItem) {
156
131
  focusPreviousMenuItem();
157
132
  event.preventDefault();
158
133
  event.stopPropagation();
@@ -161,8 +136,8 @@ const onKeyDown = async (event) => {
161
136
  // ARIA menuitem:
162
137
  // When focus is in a submenu of an item in a menu,
163
138
  // closes the submenu and returns focus to the parent menuitem.
164
- if (depth > 1) {
165
- closeContainingMenu?.();
139
+ if (menuItemContext.depth && menuItemContext.depth > 1) {
140
+ menuItemContext.closeContainingMenu?.();
166
141
  event.preventDefault();
167
142
  event.stopPropagation();
168
143
  return false;
@@ -175,14 +150,14 @@ const onKeyDown = async (event) => {
175
150
  // if focus is now on a menuitem with a submenu,
176
151
  // either opens the submenu of that menuitem without moving focus into the submenu,
177
152
  // or opens the submenu of that menuitem and places focus on the first item in the submenu.
178
- openPreviousMenuBarItem?.();
153
+ menuBarContext.openPreviousMenuBarItem?.();
179
154
  event.preventDefault();
180
155
  event.stopPropagation();
181
156
  return false;
182
157
  case 'ArrowRight':
183
158
  // ARIA menubar:
184
159
  // Moves focus to the next item, optionally wrapping from the last to the first.
185
- if (isMenuBarItem) {
160
+ if (menuItemContext.isMenuBarItem) {
186
161
  focusNextMenuItem();
187
162
  event.preventDefault();
188
163
  event.stopPropagation();
@@ -191,7 +166,7 @@ const onKeyDown = async (event) => {
191
166
  // ARIA menuitem:
192
167
  // When focus is in a menu and on a menuitem that has a submenu,
193
168
  // opens the submenu and places focus on its first item
194
- if (hasChildren) {
169
+ if (children) {
195
170
  openMenu();
196
171
  setTimeout(async () => {
197
172
  await tick();
@@ -209,8 +184,8 @@ const onKeyDown = async (event) => {
209
184
  // if focus is now on a menuitem with a submenu,
210
185
  // either opens the submenu of that menuitem without moving focus into the submenu,
211
186
  // or opens the submenu of that menuitem and places focus on the first item in the submenu.
212
- if (openNextMenuBarItem) {
213
- openNextMenuBarItem();
187
+ if (menuBarContext.openNextMenuBarItem) {
188
+ menuBarContext.openNextMenuBarItem();
214
189
  event.preventDefault();
215
190
  event.stopPropagation();
216
191
  return false;
@@ -220,7 +195,7 @@ const onKeyDown = async (event) => {
220
195
  // ARIA menubar/menuitem:
221
196
  // If the currently focused menuitem has a submenu,
222
197
  // opens the submenu and places focus on the last item in the submenu.
223
- if (isMenuBarItem && hasChildren) {
198
+ if (menuItemContext.isMenuBarItem && children) {
224
199
  openMenu();
225
200
  setTimeout(async () => {
226
201
  await tick();
@@ -232,7 +207,7 @@ const onKeyDown = async (event) => {
232
207
  }
233
208
  // ARIA menuitem:
234
209
  // Moves focus to the previous item, optionally wrapping from the first to the last.
235
- if (!isMenuBarItem) {
210
+ if (!menuItemContext.isMenuBarItem) {
236
211
  focusPreviousMenuItem();
237
212
  event.preventDefault();
238
213
  event.stopPropagation();
@@ -243,21 +218,23 @@ const onKeyDown = async (event) => {
243
218
  // ARIA menuitem:
244
219
  // Close the menu that contains focus and return focus to the element or context,
245
220
  // e.g., menu button or parent menuitem, from which the menu was opened.
246
- open = false;
221
+ // open = false;
247
222
  closeAllMenus();
248
223
  event.preventDefault();
249
224
  event.stopPropagation();
250
225
  return false;
251
226
  }
252
227
  }
228
+ rest.onkeydown?.(event);
253
229
  };
254
230
  const onMouseEnter = (event) => {
255
231
  menuItemRef?.focus();
232
+ rest.onmouseenter?.(event);
256
233
  };
257
234
  const onClick = (event) => {
258
235
  if (!disabled) {
259
- if (hasChildren) {
260
- if (!$openValues.includes(value)) {
236
+ if (children) {
237
+ if (!menuItemContext.openValues.includes(value)) {
261
238
  openMenu();
262
239
  if ($usingKeyboard) {
263
240
  setTimeout(async () => {
@@ -281,105 +258,84 @@ const onClick = (event) => {
281
258
  return false;
282
259
  }
283
260
  }
261
+ rest.onclick?.(event);
284
262
  };
285
- // ----- Set Context ----- //
286
- setContext(MENU_ITEM_CONTEXT_KEY, {
263
+ //#endregion
264
+ //#region set context
265
+ let menuItemChildContext = {
287
266
  isMenuBarItem: false,
288
- openValues,
289
- rootValue,
290
- depth: depth + 1,
291
- closeContainingMenu: () => {
292
- closeMenu();
267
+ get openValues() {
268
+ return menuItemContext.openValues;
293
269
  },
270
+ set openValues(value) {
271
+ menuItemContext.openValues = value;
272
+ },
273
+ rootValue: menuItemContext.rootValue || value,
274
+ depth: menuItemContext.depth ? menuItemContext.depth + 1 : 1,
275
+ closeContainingMenu: closeMenu,
294
276
  onOpen: raiseOpen,
295
277
  onClose: raiseClose,
296
278
  onSelect: raiseSelect
297
- });
279
+ };
280
+ setContext(MENU_ITEM_CONTEXT_KEY, menuItemChildContext);
281
+ //#endregion
298
282
  </script>
299
283
 
284
+ {#snippet renderDefaultItem()}
285
+ <div class="sterling-menu-item-display" class:disabled>
286
+ <div
287
+ class="check"
288
+ class:checkmark={role === 'menuitemcheckbox'}
289
+ class:bullet={role === 'menuitemradio'}
290
+ class:checked
291
+ ></div>
292
+ <div class="content">
293
+ {text}
294
+ </div>
295
+ {#if shortcut}
296
+ <div class="shortcut">
297
+ {shortcut}
298
+ </div>
299
+ {/if}
300
+ <div class="chevron" class:has-children={!menuItemContext.isMenuBarItem && !!children}></div>
301
+ </div>
302
+ {/snippet}
303
+
300
304
  <button
305
+ bind:this={menuItemRef}
301
306
  aria-controls={menuId}
302
307
  aria-disabled={disabled}
303
308
  aria-expanded={open}
304
- aria-haspopup={hasChildren}
309
+ aria-haspopup={!!children}
305
310
  aria-owns={menuId}
306
- bind:this={menuItemRef}
307
- class={`sterling-menu-item ${variant}`}
311
+ class={['sterling-menu-item', _class].filter(Boolean).join(' ')}
308
312
  class:using-keyboard={usingKeyboard}
309
313
  data-value={value}
310
- data-root-value={rootValue}
314
+ data-root-value={menuItemContext.rootValue}
311
315
  {disabled}
312
316
  {role}
313
317
  tabindex={0}
314
318
  type="button"
315
- on:blur
316
- on:click
317
- on:dblclick
318
- on:dragend
319
- on:dragenter
320
- on:dragleave
321
- on:dragover
322
- on:dragstart
323
- on:drop
324
- on:focus
325
- on:focusin
326
- on:focusout
327
- on:keydown
328
- on:keypress
329
- on:keyup
330
- on:mousedown
331
- on:mouseenter
332
- on:mouseleave
333
- on:mousemove
334
- on:mouseover
335
- on:mouseout
336
- on:mouseup
337
- on:pointercancel
338
- on:pointerdown
339
- on:pointerenter
340
- on:pointerleave
341
- on:pointermove
342
- on:pointerover
343
- on:pointerout
344
- on:pointerup
345
- on:wheel|passive
346
- on:click={onClick}
347
- on:keydown={onKeyDown}
348
- on:mouseenter={onMouseEnter}
349
- {...$$restProps}
319
+ {...rest}
320
+ onclick={onClick}
321
+ onkeydown={onKeyDown}
322
+ onmouseenter={onMouseEnter}
350
323
  >
351
324
  <div class="item" id={displayId}>
352
- <slot
353
- name="item"
354
- {checked}
355
- {depth}
356
- {disabled}
357
- {hasChildren}
358
- {isMenuBarItem}
359
- {open}
360
- {role}
361
- {text}
362
- {value}
363
- {variant}
364
- >
365
- <MenuItemDisplay
366
- {checked}
367
- {disabled}
368
- {hasChildren}
369
- {isMenuBarItem}
370
- menuItemRole={role}
371
- {variant}>{text}</MenuItemDisplay
372
- >
373
- </slot>
325
+ {#if item}
326
+ {@render item()}
327
+ {:else}
328
+ {@render renderDefaultItem()}
329
+ {/if}
374
330
  </div>
375
- {#if menuItemRef && open && hasChildren}
331
+ {#if menuItemRef && open && children}
376
332
  <Popover
377
333
  reference={menuItemRef}
378
- placement={isMenuBarItem ? 'bottom-start' : 'right-start'}
334
+ placement={menuItemContext.isMenuBarItem ? 'bottom-start' : 'right-start'}
379
335
  {open}
380
336
  >
381
- <Menu bind:this={menuRef} id={menuId} variant={menuVariant}>
382
- <slot {depth} {disabled} />
337
+ <Menu bind:this={menuRef} id={menuId} class={menuClass}>
338
+ {@render children()}
383
339
  </Menu>
384
340
  </Popover>
385
341
  {/if}
@@ -1,83 +1,22 @@
1
- import { SvelteComponent } from "svelte";
2
- declare const __propDef: {
3
- props: {
4
- [x: string]: any;
5
- checked?: boolean | undefined;
6
- disabled?: boolean | undefined;
7
- role?: "menuitem" | "menuitemcheckbox" | "menuitemradio" | undefined;
8
- text?: string | undefined;
9
- value: string;
10
- variant?: string | undefined;
11
- menuVariant?: string | undefined;
12
- blur?: (() => void) | undefined;
13
- click?: (() => void) | undefined;
14
- focus?: ((options?: FocusOptions) => void) | undefined;
15
- };
16
- events: {
17
- blur: FocusEvent;
18
- click: MouseEvent;
19
- dblclick: MouseEvent;
20
- dragend: DragEvent;
21
- dragenter: DragEvent;
22
- dragleave: DragEvent;
23
- dragover: DragEvent;
24
- dragstart: DragEvent;
25
- drop: DragEvent;
26
- focus: FocusEvent;
27
- focusin: FocusEvent;
28
- focusout: FocusEvent;
29
- keydown: KeyboardEvent;
30
- keypress: KeyboardEvent;
31
- keyup: KeyboardEvent;
32
- mousedown: MouseEvent;
33
- mouseenter: MouseEvent;
34
- mouseleave: MouseEvent;
35
- mousemove: MouseEvent;
36
- mouseover: MouseEvent;
37
- mouseout: MouseEvent;
38
- mouseup: MouseEvent;
39
- pointercancel: PointerEvent;
40
- pointerdown: PointerEvent;
41
- pointerenter: PointerEvent;
42
- pointerleave: PointerEvent;
43
- pointermove: PointerEvent;
44
- pointerover: PointerEvent;
45
- pointerout: PointerEvent;
46
- pointerup: PointerEvent;
47
- wheel: WheelEvent;
48
- close: CustomEvent<any>;
49
- open: CustomEvent<any>;
50
- select: CustomEvent<any>;
51
- } & {
52
- [evt: string]: CustomEvent<any>;
53
- };
54
- slots: {
55
- item: {
56
- checked: boolean;
57
- depth: number;
58
- disabled: boolean;
59
- hasChildren: boolean;
60
- isMenuBarItem: boolean | undefined;
61
- open: boolean;
62
- role: "menuitem" | "menuitemcheckbox" | "menuitemradio";
63
- text: string | undefined;
64
- value: string;
65
- variant: string;
66
- };
67
- default: {
68
- depth: number;
69
- disabled: boolean;
70
- };
71
- };
72
- exports?: undefined;
73
- bindings?: undefined;
1
+ import type { MenuItemRole } from './MenuItem.types';
2
+ import { type Snippet } from 'svelte';
3
+ import type { HTMLButtonAttributes } from 'svelte/elements';
4
+ type Props = HTMLButtonAttributes & {
5
+ checked?: boolean | null;
6
+ item?: Snippet;
7
+ menuClass?: string;
8
+ onClose?: (value: string) => void;
9
+ onOpen?: (value: string) => void;
10
+ onSelect?: (value: string) => void;
11
+ role?: MenuItemRole;
12
+ shortcut?: string;
13
+ text?: string;
14
+ value: string;
74
15
  };
75
- export type MenuItemProps = typeof __propDef.props;
76
- export type MenuItemEvents = typeof __propDef.events;
77
- export type MenuItemSlots = typeof __propDef.slots;
78
- export default class MenuItem extends SvelteComponent<MenuItemProps, MenuItemEvents, MenuItemSlots> {
79
- get blur(): () => void;
80
- get click(): () => void;
81
- get focus(): (options?: FocusOptions | undefined) => void;
82
- }
83
- export {};
16
+ declare const MenuItem: import("svelte").Component<Props, {
17
+ blur: () => void;
18
+ click: () => void;
19
+ focus: (options?: FocusOptions) => void;
20
+ }, "">;
21
+ type MenuItem = ReturnType<typeof MenuItem>;
22
+ export default MenuItem;
@@ -1,5 +1,3 @@
1
- /// <reference types="svelte" />
2
- import type { Writable } from 'svelte/store';
3
1
  import type { MENU_ITEM_ROLES } from './MenuItem.constants';
4
2
  type MenuItemRoleTuple = typeof MENU_ITEM_ROLES;
5
3
  export type MenuItemRole = MenuItemRoleTuple[number];
@@ -10,14 +8,8 @@ export type MenuItemRegistration = {
10
8
  focus: () => void;
11
9
  };
12
10
  export type MenuItemContext = {
13
- /**
14
- * If the menu item is a top-level item in a menu bar
15
- */
16
11
  isMenuBarItem?: boolean;
17
- /**
18
- * The menu item values for the chain of open menus.
19
- */
20
- openValues: Writable<string[]>;
12
+ openValues: string[];
21
13
  rootValue?: string;
22
14
  depth?: number;
23
15
  closeContainingMenu?: () => void;
@@ -1,9 +1,11 @@
1
- <script>/** Additional class names to apply. */
2
- export let variant = '';
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">let { class: _class, ...rest } = $props();
4
+ export {};
3
5
  </script>
4
6
 
5
- <!--
6
- @component
7
- A styled line to visually separate groups of menu items in a menu.
8
- -->
9
- <div class={`sterling-menu-separator ${variant}`} role="separator" {...$$restProps} />
7
+ <div
8
+ class={['sterling-menu-separator', _class].filter(Boolean).join(' ')}
9
+ role="separator"
10
+ {...rest}
11
+ ></div>
@@ -1,20 +1,6 @@
1
- import { SvelteComponent } from "svelte";
2
- declare const __propDef: {
3
- props: {
4
- [x: string]: any;
5
- variant?: string | undefined;
6
- };
7
- events: {
8
- [evt: string]: CustomEvent<any>;
9
- };
10
- slots: {};
11
- exports?: undefined;
12
- bindings?: undefined;
13
- };
14
- export type MenuSeparatorProps = typeof __propDef.props;
15
- export type MenuSeparatorEvents = typeof __propDef.events;
16
- export type MenuSeparatorSlots = typeof __propDef.slots;
17
- /** A styled line to visually separate groups of menu items in a menu. */
18
- export default class MenuSeparator extends SvelteComponent<MenuSeparatorProps, MenuSeparatorEvents, MenuSeparatorSlots> {
19
- }
20
- export {};
1
+ /// <reference types="svelte" />
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement>;
4
+ declare const MenuSeparator: import("svelte").Component<Props, {}, "">;
5
+ type MenuSeparator = ReturnType<typeof MenuSeparator>;
6
+ export default MenuSeparator;