@geoffcox/sterling-svelte 0.0.31 → 1.0.0

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 (215) hide show
  1. package/@types/clickOutside.d.ts +11 -7
  2. package/Button.svelte +11 -183
  3. package/Button.svelte.d.ts +2 -6
  4. package/Callout.svelte +107 -146
  5. package/Callout.svelte.d.ts +1 -1
  6. package/Checkbox.svelte +15 -177
  7. package/Checkbox.svelte.d.ts +2 -2
  8. package/ColorPicker.svelte +204 -223
  9. package/ColorPicker.svelte.d.ts +1 -2
  10. package/Dialog.svelte +91 -187
  11. package/Dialog.svelte.d.ts +3 -1
  12. package/Dropdown.svelte +52 -220
  13. package/Dropdown.svelte.d.ts +4 -8
  14. package/HexColorSliders.svelte +77 -145
  15. package/HexColorSliders.svelte.d.ts +28 -1
  16. package/HslColorSliders.svelte +99 -179
  17. package/HslColorSliders.svelte.d.ts +28 -1
  18. package/Input.svelte +27 -136
  19. package/Input.svelte.d.ts +2 -3
  20. package/Label.constants.d.ts +1 -0
  21. package/Label.constants.js +1 -0
  22. package/Label.svelte +96 -169
  23. package/Label.svelte.d.ts +6 -1
  24. package/Label.types.d.ts +3 -1
  25. package/Link.svelte +9 -106
  26. package/Link.svelte.d.ts +0 -1
  27. package/List.svelte +142 -230
  28. package/List.svelte.d.ts +2 -3
  29. package/List.types.d.ts +6 -1
  30. package/ListItem.svelte +25 -94
  31. package/ListItem.svelte.d.ts +2 -0
  32. package/Menu.svelte +48 -65
  33. package/Menu.svelte.d.ts +4 -1
  34. package/MenuBar.svelte +84 -86
  35. package/MenuBar.svelte.d.ts +4 -1
  36. package/MenuButton.svelte +66 -73
  37. package/MenuButton.svelte.d.ts +7 -3
  38. package/MenuItem.svelte +256 -288
  39. package/MenuItem.svelte.d.ts +2 -2
  40. package/MenuItemDisplay.svelte +12 -116
  41. package/MenuItemDisplay.svelte.d.ts +21 -7
  42. package/MenuSeparator.svelte +6 -45
  43. package/MenuSeparator.svelte.d.ts +8 -78
  44. package/Popover.constants.d.ts +1 -1
  45. package/Popover.constants.js +1 -1
  46. package/Popover.svelte +66 -80
  47. package/Popover.svelte.d.ts +5 -1
  48. package/Progress.svelte +28 -126
  49. package/Progress.svelte.d.ts +4 -3
  50. package/Radio.svelte +49 -192
  51. package/Radio.svelte.d.ts +2 -2
  52. package/RgbColorSliders.svelte +48 -137
  53. package/RgbColorSliders.svelte.d.ts +5 -5
  54. package/Select.svelte +122 -250
  55. package/Select.svelte.d.ts +6 -2
  56. package/Slider.svelte +90 -259
  57. package/Slider.svelte.d.ts +1 -2
  58. package/Switch.svelte +24 -259
  59. package/Switch.svelte.d.ts +3 -1
  60. package/Tab.svelte +27 -175
  61. package/Tab.svelte.d.ts +6 -4
  62. package/TabList.svelte +146 -171
  63. package/TabList.svelte.d.ts +3 -2
  64. package/TabList.types.d.ts +6 -1
  65. package/TextArea.svelte +32 -129
  66. package/TextArea.svelte.d.ts +1 -1
  67. package/Tooltip.svelte +46 -47
  68. package/Tooltip.svelte.d.ts +8 -3
  69. package/Tree.constants.d.ts +0 -1
  70. package/Tree.constants.js +0 -1
  71. package/Tree.svelte +35 -119
  72. package/Tree.svelte.d.ts +4 -4
  73. package/Tree.types.d.ts +1 -3
  74. package/TreeChevron.svelte +18 -98
  75. package/TreeChevron.svelte.d.ts +1 -0
  76. package/TreeItem.constants.d.ts +1 -0
  77. package/TreeItem.constants.js +1 -0
  78. package/TreeItem.svelte +251 -211
  79. package/TreeItem.svelte.d.ts +7 -3
  80. package/TreeItem.types.d.ts +1 -1
  81. package/TreeItemDisplay.svelte +20 -104
  82. package/TreeItemDisplay.svelte.d.ts +2 -2
  83. package/actions/applyLightDarkMode.d.ts +10 -0
  84. package/actions/applyLightDarkMode.js +36 -0
  85. package/actions/forwardEvents.js +3 -3
  86. package/css/Button.base.css +74 -0
  87. package/css/Button.colorful.css +17 -0
  88. package/css/Button.css +7 -0
  89. package/css/Button.secondary.colorful.css +15 -0
  90. package/css/Button.secondary.css +11 -0
  91. package/css/Button.shapes.css +14 -0
  92. package/css/Button.tool.colorful.css +13 -0
  93. package/css/Button.tool.css +18 -0
  94. package/css/Callout.base.css +43 -0
  95. package/css/Callout.colorful.css +5 -0
  96. package/css/Callout.css +2 -0
  97. package/css/Checkbox.base.css +145 -0
  98. package/css/Checkbox.colorful.css +17 -0
  99. package/css/Checkbox.css +2 -0
  100. package/css/ColorPicker.base.css +23 -0
  101. package/css/ColorPicker.css +1 -0
  102. package/css/Dialog.base.css +116 -0
  103. package/css/Dialog.css +1 -0
  104. package/css/Dropdown.base.css +147 -0
  105. package/css/Dropdown.colorful.css +23 -0
  106. package/css/Dropdown.css +2 -0
  107. package/css/HexColorSliders.base.css +106 -0
  108. package/css/HexColorSliders.css +1 -0
  109. package/css/HslColorSliders.base.css +124 -0
  110. package/css/HslColorSliders.css +1 -0
  111. package/css/Input.base.css +100 -0
  112. package/css/Input.colorful.css +22 -0
  113. package/css/Input.composed.css +8 -0
  114. package/css/Input.css +3 -0
  115. package/css/Label.base.css +119 -0
  116. package/css/Label.boxed.colorful.css +21 -0
  117. package/css/Label.boxed.css +31 -0
  118. package/css/Label.colorful.css +3 -0
  119. package/css/Label.css +4 -0
  120. package/css/Link.base.css +52 -0
  121. package/css/Link.colorful.css +15 -0
  122. package/css/Link.css +6 -0
  123. package/css/Link.ghost.colorful.css +7 -0
  124. package/css/Link.ghost.css +11 -0
  125. package/css/Link.undecorated.colorful.css +6 -0
  126. package/css/Link.undecorated.css +6 -0
  127. package/css/List.base.css +98 -0
  128. package/css/List.css +1 -0
  129. package/css/ListItem.base.css +59 -0
  130. package/css/ListItem.css +1 -0
  131. package/css/Menu.base.css +21 -0
  132. package/css/Menu.css +1 -0
  133. package/css/MenuBar.base.css +9 -0
  134. package/css/MenuBar.css +1 -0
  135. package/css/MenuButton.base.css +13 -0
  136. package/css/MenuButton.css +1 -0
  137. package/css/MenuItem.base.css +48 -0
  138. package/css/MenuItem.css +1 -0
  139. package/css/MenuItemDisplay.base.css +104 -0
  140. package/css/MenuItemDisplay.css +1 -0
  141. package/css/MenuSeparator.base.css +5 -0
  142. package/css/MenuSeparator.css +1 -0
  143. package/css/Popover copy.css +21 -0
  144. package/css/Popover.css +21 -0
  145. package/css/Progress.base.css +99 -0
  146. package/css/Progress.css +1 -0
  147. package/css/Radio.base.css +135 -0
  148. package/css/Radio.colorful.css +18 -0
  149. package/css/Radio.css +2 -0
  150. package/css/RgbColorSliders.base.css +94 -0
  151. package/css/RgbColorSliders.css +1 -0
  152. package/css/Select.base.css +127 -0
  153. package/css/Select.colorful.css +24 -0
  154. package/css/Select.composed.css +12 -0
  155. package/css/Select.css +3 -0
  156. package/css/Slider.base.css +182 -0
  157. package/css/Slider.colorful.css +11 -0
  158. package/css/Slider.composed.css +8 -0
  159. package/css/Slider.css +3 -0
  160. package/css/Switch.base.css +193 -0
  161. package/css/Switch.colorful.css +39 -0
  162. package/css/Switch.css +2 -0
  163. package/css/Tab.base.css +135 -0
  164. package/css/Tab.colorful.css +13 -0
  165. package/css/Tab.css +2 -0
  166. package/css/TabList.base.css +34 -0
  167. package/css/TabList.css +1 -0
  168. package/css/TextArea.base.css +85 -0
  169. package/css/TextArea.colorful.css +17 -0
  170. package/css/TextArea.composed.css +8 -0
  171. package/css/TextArea.css +3 -0
  172. package/css/Tooltip.base.css +6 -0
  173. package/css/Tooltip.css +1 -0
  174. package/css/Tree.base.css +74 -0
  175. package/css/Tree.composed.css +8 -0
  176. package/css/Tree.css +2 -0
  177. package/css/TreeChevron.base.css +86 -0
  178. package/css/TreeChevron.css +1 -0
  179. package/css/TreeItem.base.css +3 -0
  180. package/css/TreeItem.css +1 -0
  181. package/css/TreeItemDisplay.base.css +74 -0
  182. package/css/TreeItemDisplay.colorful.css +9 -0
  183. package/css/TreeItemDisplay.css +1 -0
  184. package/css/dark-mode.css +134 -0
  185. package/css/light-mode.css +134 -0
  186. package/css/sterling.css +37 -0
  187. package/index.d.ts +9 -13
  188. package/index.js +8 -12
  189. package/mediaQueries/prefersColorSchemeDark.d.ts +2 -0
  190. package/mediaQueries/prefersColorSchemeDark.js +10 -0
  191. package/{stores → mediaQueries}/prefersReducedMotion.d.ts +1 -0
  192. package/{stores → mediaQueries}/usingKeyboard.d.ts +1 -0
  193. package/package.json +121 -13
  194. package/Link.constants.d.ts +0 -1
  195. package/Link.constants.js +0 -1
  196. package/Link.types.d.ts +0 -4
  197. package/Link.types.js +0 -1
  198. package/theme/applyDarkTheme.d.ts +0 -7
  199. package/theme/applyDarkTheme.js +0 -11
  200. package/theme/applyLightTheme.d.ts +0 -7
  201. package/theme/applyLightTheme.js +0 -11
  202. package/theme/applyTheme.d.ts +0 -7
  203. package/theme/applyTheme.js +0 -20
  204. package/theme/colors.d.ts +0 -54
  205. package/theme/colors.js +0 -82
  206. package/theme/darkTheme.d.ts +0 -2
  207. package/theme/darkTheme.js +0 -142
  208. package/theme/lightTheme.d.ts +0 -2
  209. package/theme/lightTheme.js +0 -119
  210. package/theme/toggleDarkTheme.d.ts +0 -18
  211. package/theme/toggleDarkTheme.js +0 -53
  212. package/theme/types.d.ts +0 -21
  213. package/theme/types.js +0 -1
  214. /package/{stores → mediaQueries}/prefersReducedMotion.js +0 -0
  215. /package/{stores → mediaQueries}/usingKeyboard.js +0 -0
package/MenuItem.svelte CHANGED
@@ -1,253 +1,297 @@
1
- <script>import {
2
- getContext,
3
- afterUpdate,
4
- createEventDispatcher,
5
- onMount,
6
- setContext,
7
- tick
8
- } from "svelte";
9
- import { writable } from "svelte/store";
10
- import { idGenerator } from "./idGenerator";
11
- import Menu from "./Menu.svelte";
12
- import { MENU_BAR_CONTEXT_KEY } from "./MenuBar.constants";
13
- import { MENU_ITEM_CONTEXT_KEY } from "./MenuItem.constants";
14
- import { isElementEnabledMenuItem } from "./MenuItem.utils";
15
- import MenuItemDisplay from "./MenuItemDisplay.svelte";
16
- import Popover from "./Popover.svelte";
17
- import { usingKeyboard } from "./stores/usingKeyboard";
1
+ <script>import { getContext, afterUpdate, createEventDispatcher, onMount, setContext, tick } from 'svelte';
2
+ import { writable } from 'svelte/store';
3
+ import { idGenerator } from './idGenerator';
4
+ import Menu from './Menu.svelte';
5
+ import { MENU_BAR_CONTEXT_KEY } from './MenuBar.constants';
6
+ import { MENU_ITEM_CONTEXT_KEY } from './MenuItem.constants';
7
+ import { isElementEnabledMenuItem } from './MenuItem.utils';
8
+ import MenuItemDisplay from './MenuItemDisplay.svelte';
9
+ import Popover from './Popover.svelte';
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
+ */
18
16
  export let checked = false;
19
- export let colorful = false;
20
- export let composed = false;
17
+ /** When true, the menu item is disabled. */
21
18
  export let disabled = false;
22
- export let role = "menuitem";
23
- export let text = void 0;
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
24
  export let value;
25
- const {
26
- isMenuBarItem,
27
- openValues = writable([]),
28
- rootValue = value,
29
- depth = 0,
30
- closeContainingMenu = void 0,
31
- onOpen = void 0,
32
- onClose = void 0,
33
- onSelect = void 0
34
- } = getContext(MENU_ITEM_CONTEXT_KEY) || {};
35
- const { openPreviousMenuBarItem = void 0, openNextMenuBarItem = void 0 } = getContext(MENU_BAR_CONTEXT_KEY) || {};
36
- const instanceId = idGenerator.nextId("MenuItem");
37
- $:
38
- displayId = `${value}-display-${instanceId}`;
39
- $:
40
- open = $openValues.includes(value);
41
- $:
42
- menuId = `${value}-menu-${instanceId}`;
25
+ /** Additional class names to apply. */
26
+ export let variant = '';
27
+ // ----- Get Context ----- //
28
+ const { isMenuBarItem, openValues = writable([]), rootValue = value, depth = 0, closeContainingMenu = undefined, onOpen = undefined, onClose = undefined, onSelect = undefined } = getContext(MENU_ITEM_CONTEXT_KEY) || {};
29
+ const { openPreviousMenuBarItem = undefined, openNextMenuBarItem = undefined } = getContext(MENU_BAR_CONTEXT_KEY) || {};
30
+ // ----- State ----- //
31
+ const instanceId = idGenerator.nextId('MenuItem');
32
+ $: displayId = `${value}-display-${instanceId}`;
33
+ $: open = $openValues.includes(value);
34
+ $: menuId = `${value}-menu-${instanceId}`;
43
35
  let menuItemRef;
44
36
  let menuRef;
45
37
  const children = writable([]);
46
38
  let mounted = false;
47
39
  let prevOpen = open;
48
- $:
49
- hasChildren = $$slots.default;
40
+ $: hasChildren = $$slots.default;
41
+ // ----- Methods ----- //
50
42
  export const blur = () => {
51
- menuItemRef?.blur();
43
+ menuItemRef?.blur();
52
44
  };
53
45
  export const click = () => {
54
- menuItemRef?.click();
46
+ menuItemRef?.click();
55
47
  };
56
48
  export const focus = (options) => {
57
- menuItemRef?.focus(options);
49
+ menuItemRef?.focus(options);
58
50
  };
51
+ // ----- Events ----- //
59
52
  const dispatch = createEventDispatcher();
60
- const raiseClose = (value2) => {
61
- dispatch("close", { value: value2 });
62
- onClose?.(value2);
53
+ const raiseClose = (value) => {
54
+ dispatch('close', { value });
55
+ onClose?.(value);
63
56
  };
64
- const raiseOpen = (value2) => {
65
- dispatch("open", { value: value2 });
66
- onOpen?.(value2);
57
+ const raiseOpen = (value) => {
58
+ dispatch('open', { value });
59
+ onOpen?.(value);
67
60
  };
68
61
  $: {
69
- if (hasChildren && open !== prevOpen) {
70
- open ? raiseOpen(value) : raiseClose(value);
71
- }
72
- prevOpen = open;
62
+ if (hasChildren && open !== prevOpen) {
63
+ open ? raiseOpen(value) : raiseClose(value);
64
+ }
65
+ prevOpen = open;
73
66
  }
74
- const raiseSelect = (value2) => {
75
- dispatch("select", { value: value2 });
76
- onSelect?.(value2);
67
+ // dispatches the event and bubbles it up the context
68
+ // so that container components can subscribe to select
69
+ // events for children.
70
+ const raiseSelect = (value) => {
71
+ dispatch('select', { value });
72
+ onSelect?.(value);
77
73
  };
74
+ // ----- Focus ----- //
78
75
  const focusPreviousMenuItem = () => {
79
- let candidate = menuItemRef?.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
80
- while (candidate && !isElementEnabledMenuItem(candidate)) {
81
- candidate = candidate.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
82
- if (candidate === menuItemRef) {
83
- return false;
76
+ let candidate = menuItemRef?.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
77
+ while (candidate && !isElementEnabledMenuItem(candidate)) {
78
+ candidate = candidate.previousElementSibling || menuItemRef?.parentElement?.lastElementChild;
79
+ if (candidate === menuItemRef) {
80
+ return false;
81
+ }
84
82
  }
85
- }
86
- candidate?.focus();
87
- return !!candidate;
83
+ candidate?.focus();
84
+ return !!candidate;
88
85
  };
89
86
  const focusNextMenuItem = () => {
90
- let candidate = menuItemRef?.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
91
- while (candidate && !isElementEnabledMenuItem(candidate)) {
92
- candidate = candidate.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
93
- if (candidate === menuItemRef) {
94
- return false;
87
+ let candidate = menuItemRef?.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
88
+ while (candidate && !isElementEnabledMenuItem(candidate)) {
89
+ candidate = candidate.nextElementSibling || menuItemRef?.parentElement?.firstElementChild;
90
+ if (candidate === menuItemRef) {
91
+ return false;
92
+ }
95
93
  }
96
- }
97
- candidate?.focus();
98
- return !!candidate;
94
+ candidate?.focus();
95
+ return !!candidate;
99
96
  };
97
+ // ----- Open/Close ----- //
98
+ // opens the menu for this menu item
100
99
  const openMenu = () => {
101
- if (!$openValues.includes(value)) {
102
- openValues.set([...$openValues.slice(0, depth), value]);
103
- }
100
+ if (!$openValues.includes(value)) {
101
+ // slice to depth to close any sibling menus that are open
102
+ openValues.set([...$openValues.slice(0, depth), value]);
103
+ }
104
104
  };
105
+ // closes the menu for this menu item
105
106
  const closeMenu = async () => {
106
- const index = $openValues.indexOf(value);
107
- if (index !== -1) {
108
- openValues.set([...$openValues.slice(0, index)]);
109
- await tick();
110
- menuItemRef?.focus();
111
- }
107
+ const index = $openValues.indexOf(value);
108
+ if (index !== -1) {
109
+ openValues.set([...$openValues.slice(0, index)]);
110
+ await tick();
111
+ menuItemRef?.focus();
112
+ }
112
113
  };
113
114
  const closeAllMenus = () => {
114
- openValues.set([]);
115
+ openValues.set([]);
115
116
  };
117
+ // ----- Event Handlers ----- //
116
118
  onMount(() => {
117
- mounted = true;
119
+ mounted = true;
118
120
  });
119
121
  afterUpdate(() => {
120
- prevOpen = open;
122
+ prevOpen = open;
121
123
  });
122
124
  const onKeyDown = async (event) => {
123
- if (!disabled && !event.altKey && !event.ctrlKey && !event.shiftKey) {
124
- switch (event.key) {
125
- case "ArrowDown":
126
- if (isMenuBarItem && hasChildren) {
127
- openMenu();
128
- setTimeout(async () => {
129
- await tick();
130
- menuRef?.focusFirstMenuItem();
131
- }, 10);
132
- event.preventDefault();
133
- event.stopPropagation();
134
- return false;
135
- }
136
- if (!isMenuBarItem) {
137
- focusNextMenuItem();
138
- event.preventDefault();
139
- event.stopPropagation();
140
- return false;
141
- }
142
- break;
143
- case "ArrowLeft":
144
- if (isMenuBarItem) {
145
- focusPreviousMenuItem();
146
- event.preventDefault();
147
- event.stopPropagation();
148
- return false;
149
- }
150
- if (depth > 1) {
151
- closeContainingMenu?.();
152
- event.preventDefault();
153
- event.stopPropagation();
154
- return false;
125
+ if (!disabled && !event.altKey && !event.ctrlKey && !event.shiftKey) {
126
+ switch (event.key) {
127
+ case 'ArrowDown':
128
+ // ARIA menubar/menuitem:
129
+ // If the currently focused menuitem has a submenu,
130
+ // opens the submenu and places focus on the first item in the submenu.
131
+ if (isMenuBarItem && hasChildren) {
132
+ openMenu();
133
+ setTimeout(async () => {
134
+ await tick();
135
+ menuRef?.focusFirstMenuItem();
136
+ }, 10);
137
+ event.preventDefault();
138
+ event.stopPropagation();
139
+ return false;
140
+ }
141
+ if (!isMenuBarItem) {
142
+ // ARIA menuitem:
143
+ // Moves focus to the next item, optionally wrapping from the last to the first.
144
+ focusNextMenuItem();
145
+ event.preventDefault();
146
+ event.stopPropagation();
147
+ return false;
148
+ }
149
+ break;
150
+ case 'ArrowLeft':
151
+ // ARIA menubar/menuitem:
152
+ // Moves focus to the previous item, optionally wrapping from the first to the last.
153
+ if (isMenuBarItem) {
154
+ focusPreviousMenuItem();
155
+ event.preventDefault();
156
+ event.stopPropagation();
157
+ return false;
158
+ }
159
+ // ARIA menuitem:
160
+ // When focus is in a submenu of an item in a menu,
161
+ // closes the submenu and returns focus to the parent menuitem.
162
+ if (depth > 1) {
163
+ closeContainingMenu?.();
164
+ event.preventDefault();
165
+ event.stopPropagation();
166
+ return false;
167
+ }
168
+ // ARIA menubar/menuitem:
169
+ // When focus is in a submenu of an item in a menubar,
170
+ // closes the submenu,
171
+ // moves focus to the previous item in the menubar,
172
+ // and,
173
+ // if focus is now on a menuitem with a submenu,
174
+ // either opens the submenu of that menuitem without moving focus into the submenu,
175
+ // or opens the submenu of that menuitem and places focus on the first item in the submenu.
176
+ openPreviousMenuBarItem?.();
177
+ event.preventDefault();
178
+ event.stopPropagation();
179
+ return false;
180
+ case 'ArrowRight':
181
+ // ARIA menubar:
182
+ // Moves focus to the next item, optionally wrapping from the last to the first.
183
+ if (isMenuBarItem) {
184
+ focusNextMenuItem();
185
+ event.preventDefault();
186
+ event.stopPropagation();
187
+ return false;
188
+ }
189
+ // ARIA menuitem:
190
+ // When focus is in a menu and on a menuitem that has a submenu,
191
+ // opens the submenu and places focus on its first item
192
+ if (hasChildren) {
193
+ openMenu();
194
+ setTimeout(async () => {
195
+ await tick();
196
+ menuRef?.focusFirstMenuItem();
197
+ }, 10);
198
+ event.preventDefault();
199
+ event.stopPropagation();
200
+ return false;
201
+ }
202
+ // ARIA menubar/menuitem:
203
+ // When focus is in a menu and on an item that does not have a submenu,
204
+ // closes the submenu and any parent menus,
205
+ // moves focus to the next item in the menubar,
206
+ // and,
207
+ // if focus is now on a menuitem with a submenu,
208
+ // either opens the submenu of that menuitem without moving focus into the submenu,
209
+ // or opens the submenu of that menuitem and places focus on the first item in the submenu.
210
+ if (openNextMenuBarItem) {
211
+ openNextMenuBarItem();
212
+ event.preventDefault();
213
+ event.stopPropagation();
214
+ return false;
215
+ }
216
+ break;
217
+ case 'ArrowUp':
218
+ // ARIA menubar/menuitem:
219
+ // If the currently focused menuitem has a submenu,
220
+ // opens the submenu and places focus on the last item in the submenu.
221
+ if (isMenuBarItem && hasChildren) {
222
+ openMenu();
223
+ setTimeout(async () => {
224
+ await tick();
225
+ menuRef?.focusLastMenuItem();
226
+ }, 10);
227
+ event.preventDefault();
228
+ event.stopPropagation();
229
+ return false;
230
+ }
231
+ // ARIA menuitem:
232
+ // Moves focus to the previous item, optionally wrapping from the first to the last.
233
+ if (!isMenuBarItem) {
234
+ focusPreviousMenuItem();
235
+ event.preventDefault();
236
+ event.stopPropagation();
237
+ return false;
238
+ }
239
+ break;
240
+ case 'Escape':
241
+ // ARIA menuitem:
242
+ // Close the menu that contains focus and return focus to the element or context,
243
+ // e.g., menu button or parent menuitem, from which the menu was opened.
244
+ open = false;
245
+ closeAllMenus();
246
+ event.preventDefault();
247
+ event.stopPropagation();
248
+ return false;
155
249
  }
156
- openPreviousMenuBarItem?.();
157
- event.preventDefault();
158
- event.stopPropagation();
159
- return false;
160
- case "ArrowRight":
161
- if (isMenuBarItem) {
162
- focusNextMenuItem();
163
- event.preventDefault();
164
- event.stopPropagation();
165
- return false;
166
- }
167
- if (hasChildren) {
168
- openMenu();
169
- setTimeout(async () => {
170
- await tick();
171
- menuRef?.focusFirstMenuItem();
172
- }, 10);
173
- event.preventDefault();
174
- event.stopPropagation();
175
- return false;
176
- }
177
- if (openNextMenuBarItem) {
178
- openNextMenuBarItem();
179
- event.preventDefault();
180
- event.stopPropagation();
181
- return false;
182
- }
183
- break;
184
- case "ArrowUp":
185
- if (isMenuBarItem && hasChildren) {
186
- openMenu();
187
- setTimeout(async () => {
188
- await tick();
189
- menuRef?.focusLastMenuItem();
190
- }, 10);
191
- event.preventDefault();
192
- event.stopPropagation();
193
- return false;
194
- }
195
- if (!isMenuBarItem) {
196
- focusPreviousMenuItem();
197
- event.preventDefault();
198
- event.stopPropagation();
199
- return false;
200
- }
201
- break;
202
- case "Escape":
203
- open = false;
204
- closeAllMenus();
205
- event.preventDefault();
206
- event.stopPropagation();
207
- return false;
208
250
  }
209
- }
210
251
  };
211
252
  const onMouseEnter = (event) => {
212
- menuItemRef?.focus();
253
+ menuItemRef?.focus();
213
254
  };
214
255
  const onClick = (event) => {
215
- if (!disabled) {
216
- if (hasChildren) {
217
- if (!$openValues.includes(value)) {
218
- openMenu();
219
- if ($usingKeyboard) {
220
- setTimeout(async () => {
221
- await tick();
222
- menuRef?.focusFirstMenuItem();
223
- }, 10);
256
+ if (!disabled) {
257
+ if (hasChildren) {
258
+ if (!$openValues.includes(value)) {
259
+ openMenu();
260
+ if ($usingKeyboard) {
261
+ setTimeout(async () => {
262
+ await tick();
263
+ menuRef?.focusFirstMenuItem();
264
+ }, 10);
265
+ }
266
+ }
267
+ else {
268
+ closeMenu();
269
+ }
270
+ event.preventDefault();
271
+ event.stopPropagation();
272
+ return false;
273
+ }
274
+ else {
275
+ raiseSelect(value);
276
+ closeAllMenus();
277
+ event.preventDefault();
278
+ event.stopPropagation();
279
+ return false;
224
280
  }
225
- } else {
226
- closeMenu();
227
- }
228
- event.preventDefault();
229
- event.stopPropagation();
230
- return false;
231
- } else {
232
- raiseSelect(value);
233
- closeAllMenus();
234
- event.preventDefault();
235
- event.stopPropagation();
236
- return false;
237
281
  }
238
- }
239
282
  };
283
+ // ----- Set Context ----- //
240
284
  setContext(MENU_ITEM_CONTEXT_KEY, {
241
- isMenuBarItem: false,
242
- openValues,
243
- rootValue,
244
- depth: depth + 1,
245
- closeContainingMenu: () => {
246
- closeMenu();
247
- },
248
- onOpen: raiseOpen,
249
- onClose: raiseClose,
250
- onSelect: raiseSelect
285
+ isMenuBarItem: false,
286
+ openValues,
287
+ rootValue,
288
+ depth: depth + 1,
289
+ closeContainingMenu: () => {
290
+ closeMenu();
291
+ },
292
+ onOpen: raiseOpen,
293
+ onClose: raiseClose,
294
+ onSelect: raiseSelect
251
295
  });
252
296
  </script>
253
297
 
@@ -258,9 +302,7 @@ setContext(MENU_ITEM_CONTEXT_KEY, {
258
302
  aria-haspopup={hasChildren}
259
303
  aria-owns={menuId}
260
304
  bind:this={menuItemRef}
261
- class="sterling-menu-item"
262
- class:colorful
263
- class:composed
305
+ class={`sterling-menu-item ${variant}`}
264
306
  class:using-keyboard={usingKeyboard}
265
307
  data-value={value}
266
308
  data-root-value={rootValue}
@@ -316,9 +358,15 @@ setContext(MENU_ITEM_CONTEXT_KEY, {
316
358
  {role}
317
359
  {text}
318
360
  {value}
361
+ {variant}
319
362
  >
320
- <MenuItemDisplay {checked} {disabled} {hasChildren} {isMenuBarItem} menuItemRole={role}
321
- >{text}</MenuItemDisplay
363
+ <MenuItemDisplay
364
+ {checked}
365
+ {disabled}
366
+ {hasChildren}
367
+ {isMenuBarItem}
368
+ menuItemRole={role}
369
+ {variant}>{text}</MenuItemDisplay
322
370
  >
323
371
  </slot>
324
372
  </div>
@@ -334,83 +382,3 @@ setContext(MENU_ITEM_CONTEXT_KEY, {
334
382
  </Popover>
335
383
  {/if}
336
384
  </button>
337
-
338
- <style>
339
- .sterling-menu-item {
340
- background-color: transparent;
341
- border-color: transparent;
342
- border-radius: var(--stsv-button__border-radius);
343
- border-style: none;
344
- border-width: 0;
345
- box-sizing: border-box;
346
- color: var(--stsv-common__color);
347
- cursor: pointer;
348
- font: inherit;
349
- margin: 0;
350
- padding: 0;
351
- position: relative;
352
- outline: none;
353
- overflow: hidden;
354
- text-decoration: none;
355
- text-overflow: ellipsis;
356
- transition: background-color 250ms, color 250ms, border-color 250ms;
357
- white-space: nowrap;
358
- user-select: none;
359
- }
360
-
361
- .sterling-menu-item:hover {
362
- background-color: var(--stsv-button__background-color--hover);
363
- color: var(--stsv-button__color--hover);
364
- }
365
-
366
- .sterling-menu-item:focus {
367
- outline: none;
368
- }
369
-
370
- .sterling-menu-item.using-keyboard:focus {
371
- border-color: var(--stsv-button__border-color--focus);
372
- outline-color: var(--stsv-common__outline-color);
373
- outline-offset: var(--stsv-common__outline-offset);
374
- outline-style: var(--stsv-common__outline-style);
375
- outline-width: var(--stsv-common__outline-width);
376
- }
377
-
378
- .sterling-menu-item:focus {
379
- background-color: var(--stsv-input__background-color--selected);
380
- }
381
-
382
- /** ----- colorful ----- */
383
-
384
- .sterling-menu-item.colorful {
385
- color: var(--stsv-common--colorful__color);
386
- }
387
-
388
- .sterling-menu-item.colorful:hover {
389
- background-color: var(--stsv-button--colorful__background-color--hover);
390
- color: var(--stsv-button--colorful__color--hover);
391
- }
392
-
393
- .sterling-menu-item.colorful.using-keyboard:focus {
394
- border-color: var(--stsv-button--colorful__border-color--focus);
395
- }
396
-
397
- .sterling-menu-item.colorful:focus {
398
- background-color: var(--stsv-button--colorful__background-color--focus);
399
- color: var(--stsv-button--colorful__color--focus);
400
- }
401
-
402
- .sterling-menu-item.composed,
403
- .sterling-menu-item.composed:focus,
404
- .sterling-menu-item.composed:hover {
405
- border-width: 0;
406
- border-color: transparent;
407
- outline: none;
408
- background-color: transparent;
409
- }
410
-
411
- @media (prefers-reduced-motion) {
412
- .sterling-menu-item {
413
- transition: none;
414
- }
415
- }
416
- </style>
@@ -3,12 +3,11 @@ declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
5
  checked?: boolean | undefined;
6
- colorful?: boolean | undefined;
7
- composed?: boolean | undefined;
8
6
  disabled?: boolean | undefined;
9
7
  role?: "menuitem" | "menuitemcheckbox" | "menuitemradio" | undefined;
10
8
  text?: string | undefined;
11
9
  value: string;
10
+ variant?: string | undefined;
12
11
  blur?: (() => void) | undefined;
13
12
  click?: (() => void) | undefined;
14
13
  focus?: ((options?: FocusOptions) => void) | undefined;
@@ -62,6 +61,7 @@ declare const __propDef: {
62
61
  role: "menuitem" | "menuitemcheckbox" | "menuitemradio";
63
62
  text: string | undefined;
64
63
  value: string;
64
+ variant: string;
65
65
  };
66
66
  default: {
67
67
  depth: number;