@geoffcox/sterling-svelte 1.0.12 → 2.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 (325) hide show
  1. package/.DS_Store +0 -0
  2. package/Button.svelte +25 -0
  3. package/Button.svelte.d.ts +9 -0
  4. package/{dist/Callout.svelte → Callout.svelte} +47 -72
  5. package/Callout.svelte.d.ts +15 -0
  6. package/Callout.types.d.ts +11 -0
  7. package/Checkbox.svelte +43 -0
  8. package/Checkbox.svelte.d.ts +10 -0
  9. package/{dist/Dialog.svelte → Dialog.svelte} +30 -38
  10. package/Dialog.svelte.d.ts +14 -0
  11. package/{dist/Dropdown.svelte → Dropdown.svelte} +39 -71
  12. package/Dropdown.svelte.d.ts +18 -0
  13. package/Input.svelte +55 -0
  14. package/Input.svelte.d.ts +12 -0
  15. package/Label.svelte +91 -0
  16. package/Label.svelte.d.ts +17 -0
  17. package/Link.svelte +25 -0
  18. package/Link.svelte.d.ts +12 -0
  19. package/{dist/List.svelte → List.svelte} +35 -85
  20. package/List.svelte.d.ts +20 -0
  21. package/List.types.d.ts +5 -0
  22. package/ListItem.svelte +49 -0
  23. package/ListItem.svelte.d.ts +13 -0
  24. package/{dist/Menu.svelte → Menu.svelte} +18 -45
  25. package/Menu.svelte.d.ts +13 -0
  26. package/{dist/MenuBar.svelte → MenuBar.svelte} +36 -78
  27. package/MenuBar.svelte.d.ts +13 -0
  28. package/MenuButton.svelte +116 -0
  29. package/MenuButton.svelte.d.ts +20 -0
  30. package/{dist/MenuItem.svelte → MenuItem.svelte} +107 -151
  31. package/MenuItem.svelte.d.ts +22 -0
  32. package/{dist/MenuItem.types.d.ts → MenuItem.types.d.ts} +1 -9
  33. package/MenuSeparator.svelte +11 -0
  34. package/MenuSeparator.svelte.d.ts +6 -0
  35. package/{dist/Popover.svelte → Popover.svelte} +45 -64
  36. package/Popover.svelte.d.ts +15 -0
  37. package/Progress.constants.d.ts +1 -0
  38. package/Progress.constants.js +1 -0
  39. package/Progress.svelte +36 -0
  40. package/Progress.svelte.d.ts +12 -0
  41. package/Progress.types.d.ts +4 -0
  42. package/Radio.svelte +53 -0
  43. package/Radio.svelte.d.ts +13 -0
  44. package/{dist/Select.svelte → Select.svelte} +55 -94
  45. package/Select.svelte.d.ts +20 -0
  46. package/Slider.svelte +133 -0
  47. package/Slider.svelte.d.ts +19 -0
  48. package/Switch.svelte +61 -0
  49. package/Switch.svelte.d.ts +21 -0
  50. package/Tab.svelte +51 -0
  51. package/Tab.svelte.d.ts +12 -0
  52. package/{dist/TabList.svelte → TabList.svelte} +50 -76
  53. package/TabList.svelte.d.ts +18 -0
  54. package/TabList.types.d.ts +5 -0
  55. package/{dist/TextArea.svelte → TextArea.svelte} +17 -59
  56. package/TextArea.svelte.d.ts +19 -0
  57. package/Tooltip.svelte +63 -0
  58. package/Tooltip.svelte.d.ts +10 -0
  59. package/Tree.svelte +53 -0
  60. package/Tree.svelte.d.ts +15 -0
  61. package/Tree.types.d.ts +5 -0
  62. package/TreeChevron.svelte +27 -0
  63. package/TreeChevron.svelte.d.ts +9 -0
  64. package/{dist/TreeItem.svelte → TreeItem.svelte} +105 -159
  65. package/TreeItem.svelte.d.ts +22 -0
  66. package/TreeItem.types.d.ts +4 -0
  67. package/{dist/actions → actions}/clickOutside.d.ts +1 -0
  68. package/{dist/actions → actions}/clickOutside.js +1 -0
  69. package/actions/extraClass.d.ts +8 -0
  70. package/actions/extraClass.js +14 -0
  71. package/{dist/index.d.ts → index.d.ts} +4 -12
  72. package/{dist/index.js → index.js} +3 -9
  73. package/package.json +26 -28
  74. package/README.md +0 -18
  75. package/dist/Button.constants.d.ts +0 -2
  76. package/dist/Button.constants.js +0 -2
  77. package/dist/Button.svelte +0 -63
  78. package/dist/Button.svelte.d.ts +0 -65
  79. package/dist/Button.types.d.ts +0 -6
  80. package/dist/Callout.svelte.d.ts +0 -56
  81. package/dist/Checkbox.svelte +0 -79
  82. package/dist/Checkbox.svelte.d.ts +0 -63
  83. package/dist/ColorPicker.constants.d.ts +0 -1
  84. package/dist/ColorPicker.constants.js +0 -1
  85. package/dist/ColorPicker.svelte +0 -287
  86. package/dist/ColorPicker.svelte.d.ts +0 -52
  87. package/dist/ColorPicker.types.d.ts +0 -4
  88. package/dist/ColorPicker.types.js +0 -1
  89. package/dist/Dialog.svelte.d.ts +0 -37
  90. package/dist/Dropdown.svelte.d.ts +0 -77
  91. package/dist/HexColorSliders.svelte +0 -103
  92. package/dist/HexColorSliders.svelte.d.ts +0 -51
  93. package/dist/HslColorSliders.svelte +0 -128
  94. package/dist/HslColorSliders.svelte.d.ts +0 -51
  95. package/dist/Input.svelte +0 -89
  96. package/dist/Input.svelte.d.ts +0 -74
  97. package/dist/Label.svelte +0 -197
  98. package/dist/Label.svelte.d.ts +0 -82
  99. package/dist/Label.types.d.ts +0 -6
  100. package/dist/Label.types.js +0 -1
  101. package/dist/Link.svelte +0 -57
  102. package/dist/Link.svelte.d.ts +0 -65
  103. package/dist/List.svelte.d.ts +0 -75
  104. package/dist/List.types.d.ts +0 -13
  105. package/dist/ListItem.svelte +0 -78
  106. package/dist/ListItem.svelte.d.ts +0 -67
  107. package/dist/Menu.svelte.d.ts +0 -63
  108. package/dist/MenuBar.svelte.d.ts +0 -58
  109. package/dist/MenuButton.svelte +0 -145
  110. package/dist/MenuButton.svelte.d.ts +0 -71
  111. package/dist/MenuItem.svelte.d.ts +0 -83
  112. package/dist/MenuItemDisplay.svelte +0 -32
  113. package/dist/MenuItemDisplay.svelte.d.ts +0 -39
  114. package/dist/MenuSeparator.svelte +0 -9
  115. package/dist/MenuSeparator.svelte.d.ts +0 -20
  116. package/dist/Popover.svelte.d.ts +0 -59
  117. package/dist/Progress.constants.d.ts +0 -1
  118. package/dist/Progress.constants.js +0 -1
  119. package/dist/Progress.svelte +0 -83
  120. package/dist/Progress.svelte.d.ts +0 -61
  121. package/dist/Progress.types.d.ts +0 -4
  122. package/dist/Radio.svelte +0 -126
  123. package/dist/Radio.svelte.d.ts +0 -65
  124. package/dist/RgbColorSliders.svelte +0 -93
  125. package/dist/RgbColorSliders.svelte.d.ts +0 -24
  126. package/dist/Select.svelte.d.ts +0 -83
  127. package/dist/Slider.svelte +0 -190
  128. package/dist/Slider.svelte.d.ts +0 -66
  129. package/dist/Switch.svelte +0 -110
  130. package/dist/Switch.svelte.d.ts +0 -74
  131. package/dist/Tab.svelte +0 -94
  132. package/dist/Tab.svelte.d.ts +0 -71
  133. package/dist/TabList.svelte.d.ts +0 -70
  134. package/dist/TabList.types.d.ts +0 -13
  135. package/dist/TextArea.svelte.d.ts +0 -69
  136. package/dist/Tooltip.svelte +0 -106
  137. package/dist/Tooltip.svelte.d.ts +0 -70
  138. package/dist/Tree.svelte +0 -104
  139. package/dist/Tree.svelte.d.ts +0 -67
  140. package/dist/Tree.types.d.ts +0 -13
  141. package/dist/TreeChevron.svelte +0 -66
  142. package/dist/TreeChevron.svelte.d.ts +0 -53
  143. package/dist/TreeItem.svelte.d.ts +0 -101
  144. package/dist/TreeItem.types.d.ts +0 -14
  145. package/dist/TreeItemDisplay.svelte +0 -74
  146. package/dist/TreeItemDisplay.svelte.d.ts +0 -73
  147. package/dist/css/Button.base.css +0 -54
  148. package/dist/css/Button.colorful.css +0 -17
  149. package/dist/css/Button.css +0 -8
  150. package/dist/css/Button.disabled.css +0 -22
  151. package/dist/css/Button.secondary.colorful.css +0 -15
  152. package/dist/css/Button.secondary.css +0 -11
  153. package/dist/css/Button.shapes.css +0 -14
  154. package/dist/css/Button.tool.colorful.css +0 -13
  155. package/dist/css/Button.tool.css +0 -18
  156. package/dist/css/Callout.base.css +0 -55
  157. package/dist/css/Callout.colorful.css +0 -5
  158. package/dist/css/Callout.css +0 -2
  159. package/dist/css/Checkbox.base.css +0 -121
  160. package/dist/css/Checkbox.colorful.css +0 -17
  161. package/dist/css/Checkbox.css +0 -3
  162. package/dist/css/Checkbox.disabled.css +0 -28
  163. package/dist/css/ColorPicker.base.css +0 -23
  164. package/dist/css/ColorPicker.css +0 -1
  165. package/dist/css/Dialog.base.css +0 -114
  166. package/dist/css/Dialog.css +0 -1
  167. package/dist/css/Dropdown.base.css +0 -105
  168. package/dist/css/Dropdown.colorful.css +0 -23
  169. package/dist/css/Dropdown.composed.css +0 -11
  170. package/dist/css/Dropdown.css +0 -4
  171. package/dist/css/Dropdown.disabled.css +0 -32
  172. package/dist/css/HexColorSliders.base.css +0 -87
  173. package/dist/css/HexColorSliders.css +0 -1
  174. package/dist/css/HslColorSliders.base.css +0 -105
  175. package/dist/css/HslColorSliders.css +0 -1
  176. package/dist/css/Input.base.css +0 -72
  177. package/dist/css/Input.colorful.css +0 -22
  178. package/dist/css/Input.composed.css +0 -12
  179. package/dist/css/Input.css +0 -4
  180. package/dist/css/Input.disabled.css +0 -24
  181. package/dist/css/Label.base.css +0 -114
  182. package/dist/css/Label.boxed.colorful.css +0 -21
  183. package/dist/css/Label.boxed.css +0 -31
  184. package/dist/css/Label.colorful.css +0 -3
  185. package/dist/css/Label.css +0 -5
  186. package/dist/css/Label.disabled.css +0 -9
  187. package/dist/css/Link.base.css +0 -43
  188. package/dist/css/Link.colorful.css +0 -15
  189. package/dist/css/Link.css +0 -11
  190. package/dist/css/Link.disabled.css +0 -10
  191. package/dist/css/Link.ghost.colorful.css +0 -7
  192. package/dist/css/Link.ghost.css +0 -11
  193. package/dist/css/Link.text-underline.css +0 -8
  194. package/dist/css/Link.text-underline.ghost.css +0 -13
  195. package/dist/css/Link.undecorated.colorful.css +0 -8
  196. package/dist/css/Link.undecorated.css +0 -8
  197. package/dist/css/Link.undecorated.ghost.css +0 -8
  198. package/dist/css/Link.undecorated.underline.css +0 -8
  199. package/dist/css/List.base.css +0 -84
  200. package/dist/css/List.composed.css +0 -8
  201. package/dist/css/List.css +0 -3
  202. package/dist/css/List.disabled.css +0 -7
  203. package/dist/css/ListItem.base.css +0 -33
  204. package/dist/css/ListItem.css +0 -2
  205. package/dist/css/ListItem.disabled.css +0 -28
  206. package/dist/css/Menu.base.css +0 -21
  207. package/dist/css/Menu.css +0 -1
  208. package/dist/css/MenuBar.base.css +0 -9
  209. package/dist/css/MenuBar.css +0 -1
  210. package/dist/css/MenuButton.base.css +0 -13
  211. package/dist/css/MenuButton.css +0 -1
  212. package/dist/css/MenuItem.base.css +0 -48
  213. package/dist/css/MenuItem.css +0 -1
  214. package/dist/css/MenuItemDisplay.base.css +0 -79
  215. package/dist/css/MenuItemDisplay.css +0 -2
  216. package/dist/css/MenuItemDisplay.disabled.css +0 -28
  217. package/dist/css/MenuSeparator.base.css +0 -5
  218. package/dist/css/MenuSeparator.css +0 -1
  219. package/dist/css/Popover.css +0 -21
  220. package/dist/css/Progress.base.css +0 -85
  221. package/dist/css/Progress.css +0 -2
  222. package/dist/css/Progress.disabled.css +0 -17
  223. package/dist/css/Radio.base.css +0 -109
  224. package/dist/css/Radio.colorful.css +0 -18
  225. package/dist/css/Radio.css +0 -3
  226. package/dist/css/Radio.disabled.css +0 -28
  227. package/dist/css/RgbColorSliders.base.css +0 -94
  228. package/dist/css/RgbColorSliders.css +0 -1
  229. package/dist/css/Select.base.css +0 -101
  230. package/dist/css/Select.colorful.css +0 -24
  231. package/dist/css/Select.composed.css +0 -12
  232. package/dist/css/Select.css +0 -4
  233. package/dist/css/Select.disabled.css +0 -28
  234. package/dist/css/Slider.base.css +0 -152
  235. package/dist/css/Slider.colorful.css +0 -11
  236. package/dist/css/Slider.composed.css +0 -8
  237. package/dist/css/Slider.css +0 -4
  238. package/dist/css/Slider.disabled.css +0 -30
  239. package/dist/css/Switch.base.css +0 -175
  240. package/dist/css/Switch.colorful.css +0 -45
  241. package/dist/css/Switch.css +0 -3
  242. package/dist/css/Switch.disabled.css +0 -30
  243. package/dist/css/Tab.base.css +0 -96
  244. package/dist/css/Tab.colorful.css +0 -13
  245. package/dist/css/Tab.css +0 -3
  246. package/dist/css/Tab.disabled.css +0 -36
  247. package/dist/css/TabList.base.css +0 -34
  248. package/dist/css/TabList.css +0 -1
  249. package/dist/css/TextArea.base.css +0 -62
  250. package/dist/css/TextArea.colorful.css +0 -17
  251. package/dist/css/TextArea.composed.css +0 -8
  252. package/dist/css/TextArea.css +0 -4
  253. package/dist/css/TextArea.disabled.css +0 -28
  254. package/dist/css/Tooltip.base.css +0 -6
  255. package/dist/css/Tooltip.css +0 -1
  256. package/dist/css/Tree.base.css +0 -49
  257. package/dist/css/Tree.composed.css +0 -8
  258. package/dist/css/Tree.css +0 -3
  259. package/dist/css/Tree.disabled.css +0 -27
  260. package/dist/css/TreeChevron.base.css +0 -86
  261. package/dist/css/TreeChevron.css +0 -1
  262. package/dist/css/TreeItem.base.css +0 -3
  263. package/dist/css/TreeItem.css +0 -1
  264. package/dist/css/TreeItemDisplay.base.css +0 -48
  265. package/dist/css/TreeItemDisplay.colorful.css +0 -9
  266. package/dist/css/TreeItemDisplay.css +0 -3
  267. package/dist/css/TreeItemDisplay.disabled.css +0 -28
  268. package/dist/css/dark-mode.css +0 -134
  269. package/dist/css/light-mode.css +0 -134
  270. package/dist/css/sterling.css +0 -37
  271. package/dist/package.json +0 -108
  272. /package/{dist/@types → @types}/clickOutside.d.ts +0 -0
  273. /package/{dist/Button.types.js → Callout.types.js} +0 -0
  274. /package/{dist/Label.constants.d.ts → Label.constants.d.ts} +0 -0
  275. /package/{dist/Label.constants.js → Label.constants.js} +0 -0
  276. /package/{dist/List.constants.d.ts → List.constants.d.ts} +0 -0
  277. /package/{dist/List.constants.js → List.constants.js} +0 -0
  278. /package/{dist/List.types.js → List.types.js} +0 -0
  279. /package/{dist/MenuBar.constants.d.ts → MenuBar.constants.d.ts} +0 -0
  280. /package/{dist/MenuBar.constants.js → MenuBar.constants.js} +0 -0
  281. /package/{dist/MenuBar.types.d.ts → MenuBar.types.d.ts} +0 -0
  282. /package/{dist/MenuBar.types.js → MenuBar.types.js} +0 -0
  283. /package/{dist/MenuItem.constants.d.ts → MenuItem.constants.d.ts} +0 -0
  284. /package/{dist/MenuItem.constants.js → MenuItem.constants.js} +0 -0
  285. /package/{dist/MenuItem.types.js → MenuItem.types.js} +0 -0
  286. /package/{dist/MenuItem.utils.d.ts → MenuItem.utils.d.ts} +0 -0
  287. /package/{dist/MenuItem.utils.js → MenuItem.utils.js} +0 -0
  288. /package/{dist/Popover.constants.d.ts → Popover.constants.d.ts} +0 -0
  289. /package/{dist/Popover.constants.js → Popover.constants.js} +0 -0
  290. /package/{dist/Popover.types.d.ts → Popover.types.d.ts} +0 -0
  291. /package/{dist/Popover.types.js → Popover.types.js} +0 -0
  292. /package/{dist/Portal.constants.d.ts → Portal.constants.d.ts} +0 -0
  293. /package/{dist/Portal.constants.js → Portal.constants.js} +0 -0
  294. /package/{dist/Portal.types.d.ts → Portal.types.d.ts} +0 -0
  295. /package/{dist/Portal.types.js → Portal.types.js} +0 -0
  296. /package/{dist/Progress.types.js → Progress.types.js} +0 -0
  297. /package/{dist/TabList.constants.d.ts → TabList.constants.d.ts} +0 -0
  298. /package/{dist/TabList.constants.js → TabList.constants.js} +0 -0
  299. /package/{dist/TabList.types.js → TabList.types.js} +0 -0
  300. /package/{dist/TextArea.constants.d.ts → TextArea.constants.d.ts} +0 -0
  301. /package/{dist/TextArea.constants.js → TextArea.constants.js} +0 -0
  302. /package/{dist/TextArea.types.d.ts → TextArea.types.d.ts} +0 -0
  303. /package/{dist/TextArea.types.js → TextArea.types.js} +0 -0
  304. /package/{dist/Tree.constants.d.ts → Tree.constants.d.ts} +0 -0
  305. /package/{dist/Tree.constants.js → Tree.constants.js} +0 -0
  306. /package/{dist/Tree.types.js → Tree.types.js} +0 -0
  307. /package/{dist/TreeItem.constants.d.ts → TreeItem.constants.d.ts} +0 -0
  308. /package/{dist/TreeItem.constants.js → TreeItem.constants.js} +0 -0
  309. /package/{dist/TreeItem.types.js → TreeItem.types.js} +0 -0
  310. /package/{dist/actions → actions}/applyLightDarkMode.d.ts +0 -0
  311. /package/{dist/actions → actions}/applyLightDarkMode.js +0 -0
  312. /package/{dist/actions → actions}/forwardEvents.d.ts +0 -0
  313. /package/{dist/actions → actions}/forwardEvents.js +0 -0
  314. /package/{dist/actions → actions}/portal.d.ts +0 -0
  315. /package/{dist/actions → actions}/portal.js +0 -0
  316. /package/{dist/actions → actions}/trapKeyboardFocus.d.ts +0 -0
  317. /package/{dist/actions → actions}/trapKeyboardFocus.js +0 -0
  318. /package/{dist/idGenerator.d.ts → idGenerator.d.ts} +0 -0
  319. /package/{dist/idGenerator.js → idGenerator.js} +0 -0
  320. /package/{dist/mediaQueries → mediaQueries}/prefersColorSchemeDark.d.ts +0 -0
  321. /package/{dist/mediaQueries → mediaQueries}/prefersColorSchemeDark.js +0 -0
  322. /package/{dist/mediaQueries → mediaQueries}/prefersReducedMotion.d.ts +0 -0
  323. /package/{dist/mediaQueries → mediaQueries}/prefersReducedMotion.js +0 -0
  324. /package/{dist/mediaQueries → mediaQueries}/usingKeyboard.d.ts +0 -0
  325. /package/{dist/mediaQueries → mediaQueries}/usingKeyboard.js +0 -0
package/Input.svelte ADDED
@@ -0,0 +1,55 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { idGenerator } from './idGenerator';
4
+ import { usingKeyboard } from './mediaQueries/usingKeyboard';
5
+ let { id, children, class: _class, disabled = false, value = $bindable(undefined), ...rest } = $props();
6
+ let inputRef;
7
+ $effect(() => {
8
+ if (children && id === undefined) {
9
+ id = idGenerator.nextId('Input');
10
+ }
11
+ });
12
+ export const blur = () => {
13
+ inputRef?.blur();
14
+ };
15
+ export const click = () => {
16
+ inputRef?.click();
17
+ };
18
+ export const focus = (options) => {
19
+ inputRef?.focus();
20
+ };
21
+ export const select = () => {
22
+ inputRef?.select();
23
+ };
24
+ export const setSelectionRange = (start, end, direction) => {
25
+ inputRef?.setSelectionRange(start, end, direction);
26
+ };
27
+ export const setRangeText = (replacement, start, end, selectionMode) => {
28
+ if (start && end) {
29
+ inputRef?.setRangeText(replacement, start, end, selectionMode);
30
+ }
31
+ else {
32
+ inputRef?.setRangeText(replacement);
33
+ }
34
+ };
35
+ </script>
36
+
37
+ {#if children}
38
+ <label class={['sterling-input-label', _class].filter(Boolean).join(' ')} class:disabled for={id}>
39
+ {@render children()}
40
+ </label>
41
+ {/if}
42
+ <div
43
+ class={['sterling-input', _class].filter(Boolean).join(' ')}
44
+ class:disabled
45
+ class:using-keyboard={$usingKeyboard}
46
+ >
47
+ <input
48
+ bind:this={inputRef}
49
+ class:using-keyboard={$usingKeyboard}
50
+ {disabled}
51
+ {id}
52
+ bind:value
53
+ {...rest}
54
+ />
55
+ </div>
@@ -0,0 +1,12 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ declare const Input: import("svelte").Component<HTMLInputAttributes, {
4
+ blur: () => void;
5
+ click: () => void;
6
+ focus: (options?: FocusOptions) => void;
7
+ select: () => void;
8
+ setSelectionRange: (start: number | null, end: number | null, direction?: 'forward' | 'backward' | 'none') => void;
9
+ setRangeText: (replacement: string, start?: number, end?: number, selectionMode?: SelectionMode) => void;
10
+ }, "value">;
11
+ type Input = ReturnType<typeof Input>;
12
+ export default Input;
package/Label.svelte ADDED
@@ -0,0 +1,91 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import {} from 'svelte';
4
+ import Tooltip from './Tooltip.svelte';
5
+ import { usingKeyboard } from './mediaQueries/usingKeyboard';
6
+ let { children, class: _class, for: _for, forwardClick = false, message, required, requiredIndicator = '*', requiredReason, text, ...rest } = $props();
7
+ // ----- State ----- //
8
+ let labelRef = $state(null);
9
+ let targetRef = $state(null);
10
+ let requiredRef = $state(null);
11
+ const findTarget = () => {
12
+ let candidate = null;
13
+ if (_for) {
14
+ candidate = labelRef?.querySelector(`[id="${_for}"]`) || null;
15
+ }
16
+ if (!candidate) {
17
+ candidate =
18
+ labelRef?.querySelector('a[href], ' +
19
+ 'audio[controls], ' +
20
+ 'button, ' +
21
+ 'details, ' +
22
+ 'div[contenteditable], ' +
23
+ 'form, ' +
24
+ 'input, ' +
25
+ 'select, ' +
26
+ 'textarea, ' +
27
+ 'video[controls], ' +
28
+ '[tabindex]:not([tabindex="-1"])') || null;
29
+ }
30
+ targetRef = candidate;
31
+ };
32
+ // ----- Methods ----- //
33
+ export const click = () => {
34
+ labelRef?.click();
35
+ };
36
+ export const blur = () => {
37
+ labelRef?.blur();
38
+ };
39
+ export const focus = (options) => {
40
+ labelRef?.focus(options);
41
+ };
42
+ // ----- Event Handlers ----- //
43
+ const onClick = (event) => {
44
+ if (forwardClick) {
45
+ targetRef?.click();
46
+ }
47
+ rest.onclick?.(event);
48
+ };
49
+ </script>
50
+
51
+ {#snippet snippetOrText(item?: string | Snippet, _class?: string)}
52
+ {#if item}
53
+ {#if typeof item === 'string'}
54
+ <div class={_class}>{item}</div>
55
+ {:else}
56
+ <div class={_class}>
57
+ {@render item()}
58
+ </div>
59
+ {/if}
60
+ {/if}
61
+ {/snippet}
62
+
63
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
64
+ <label
65
+ bind:this={labelRef}
66
+ class={['sterling-label', _class].filter(Boolean).join(' ')}
67
+ class:using-keyboard={$usingKeyboard}
68
+ for={_for}
69
+ {...rest}
70
+ onclick={onClick}
71
+ >
72
+ {@render snippetOrText(text, 'text')}
73
+ {#if children}
74
+ <div class="content">
75
+ {@render children()}
76
+ </div>
77
+ {/if}
78
+ {@render snippetOrText(message, 'message')}
79
+ <div class="required" bind:this={requiredRef}>
80
+ {#if required && requiredReason}
81
+ <Tooltip>
82
+ {@render snippetOrText(requiredIndicator, 'required')}
83
+ {#snippet tip()}
84
+ {@render snippetOrText(requiredReason, 'required-reason')}
85
+ {/snippet}
86
+ </Tooltip>
87
+ {:else if required}
88
+ {@render snippetOrText(requiredIndicator, 'required')}
89
+ {/if}
90
+ </div>
91
+ </label>
@@ -0,0 +1,17 @@
1
+ import { type Snippet } from 'svelte';
2
+ import type { HTMLLabelAttributes } from 'svelte/elements';
3
+ type Props = HTMLLabelAttributes & {
4
+ forwardClick?: boolean | null;
5
+ message?: string | Snippet;
6
+ required?: boolean | null;
7
+ requiredIndicator?: string | Snippet;
8
+ requiredReason?: string | Snippet;
9
+ text?: string | Snippet;
10
+ };
11
+ declare const Label: import("svelte").Component<Props, {
12
+ click: () => void;
13
+ blur: () => void;
14
+ focus: (options?: FocusOptions) => void;
15
+ }, "">;
16
+ type Label = ReturnType<typeof Label>;
17
+ export default Label;
package/Link.svelte ADDED
@@ -0,0 +1,25 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">let { children, class: _class, disabled, ...rest } = $props();
4
+ let linkRef;
5
+ export const blur = () => {
6
+ linkRef?.blur();
7
+ };
8
+ export const click = () => {
9
+ linkRef?.click();
10
+ };
11
+ export const focus = (options) => {
12
+ linkRef?.focus();
13
+ };
14
+ </script>
15
+
16
+ <a
17
+ bind:this={linkRef}
18
+ class={['sterling-link', _class].filter(Boolean).join(' ')}
19
+ class:disabled
20
+ {...rest}
21
+ >
22
+ {#if children}
23
+ {@render children()}
24
+ {/if}
25
+ </a>
@@ -0,0 +1,12 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLAnchorAttributes } from 'svelte/elements';
3
+ type Props = HTMLAnchorAttributes & {
4
+ disabled?: boolean | null;
5
+ };
6
+ declare const Link: import("svelte").Component<Props, {
7
+ blur: () => void;
8
+ click: () => void;
9
+ focus: (options?: FocusOptions) => void;
10
+ }, "">;
11
+ type Link = ReturnType<typeof Link>;
12
+ export default Link;
@@ -1,43 +1,26 @@
1
- <script>import { createEventDispatcher, setContext } from 'svelte';
2
- import { writable } from 'svelte/store';
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { setContext } from 'svelte';
3
4
  import { LIST_CONTEXT_KEY } from './List.constants';
4
5
  import { usingKeyboard } from './mediaQueries/usingKeyboard';
5
- // ----- Props ----- //
6
- /** If the list and all its items are disabled. */
7
- export let disabled = false;
8
- /** When true, items are arranged horizontally. */
9
- export let horizontal = false;
10
- /** The value of the currently selected item. */
11
- export let selectedValue = undefined;
12
- /** Additional class names to apply. */
13
- export let variant = '';
14
- // ----- State ----- //
6
+ let { children, class: _class, disabled = false, horizontal = false, selectedValue = $bindable(), onSelect, ...rest } = $props();
15
7
  let listRef;
16
8
  let lastSelectedItemRef;
17
- const disabledStore = writable(disabled);
18
- const horizontalStore = writable(horizontal);
19
- const selectedValueStore = writable(selectedValue);
20
- $: {
21
- disabledStore.set(disabled);
22
- }
23
- $: {
24
- horizontalStore.set(horizontal);
25
- }
26
- $: {
27
- selectedValueStore.set(selectedValue);
28
- }
29
- $: {
30
- selectedValue = $selectedValueStore;
31
- }
32
- // ----- Events ----- //
33
- const dispatch = createEventDispatcher();
34
- const raiseSelect = (value) => {
35
- dispatch('select', { value });
36
- };
37
- $: {
38
- raiseSelect(selectedValue);
39
- }
40
- // ----- Methods ----- //
9
+ let listContext = $state({
10
+ disabled,
11
+ selectedValue,
12
+ horizontal
13
+ });
14
+ $effect(() => {
15
+ listContext.disabled = disabled;
16
+ });
17
+ $effect(() => {
18
+ listContext.horizontal = horizontal;
19
+ });
20
+ $effect(() => {
21
+ listContext.selectedValue = selectedValue;
22
+ });
23
+ setContext(LIST_CONTEXT_KEY, listContext);
41
24
  export const blur = () => {
42
25
  listRef?.blur();
43
26
  };
@@ -51,8 +34,9 @@ export const scrollToSelectedItem = () => {
51
34
  const element = getSelectedItemElement();
52
35
  element?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
53
36
  };
54
- // ----- Focus ----- //
55
- // ----- Selection ----- //
37
+ $effect(() => {
38
+ onSelect?.(selectedValue);
39
+ });
56
40
  const isElementListItem = (candidate) => {
57
41
  return (candidate &&
58
42
  candidate.getAttribute('data-value') !== null &&
@@ -70,7 +54,7 @@ const getSelectedItemElement = () => {
70
54
  }
71
55
  };
72
56
  const selectItem = (value, element) => {
73
- selectedValueStore.set(value);
57
+ selectedValue = value;
74
58
  lastSelectedItemRef = element;
75
59
  element.scrollIntoView({ block: 'nearest', inline: 'nearest' });
76
60
  };
@@ -124,7 +108,6 @@ export const selectLastItem = () => {
124
108
  }
125
109
  return false;
126
110
  };
127
- // ----- Event Handlers ----- //
128
111
  const onClick = (event) => {
129
112
  if (!disabled) {
130
113
  let candidate = event.target;
@@ -137,6 +120,7 @@ const onClick = (event) => {
137
120
  selectItem(candidateValue, candidate);
138
121
  }
139
122
  }
123
+ rest.onclick?.(event);
140
124
  };
141
125
  const onKeydown = (event) => {
142
126
  if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
@@ -189,65 +173,31 @@ const onKeydown = (event) => {
189
173
  return false;
190
174
  }
191
175
  }
176
+ rest.onkeydown?.(event);
192
177
  };
193
- // ----- Set Context ----- //
194
- setContext(LIST_CONTEXT_KEY, {
195
- disabled: disabledStore,
196
- selectedValue: selectedValueStore,
197
- horizontal: horizontalStore
198
- });
199
178
  </script>
200
179
 
201
- <!--
202
- @component
203
- A list of items where a single item can be selected.
204
- -->
205
- <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
206
- <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
207
- <!-- svelte-ignore a11y-role-supports-aria-props -->
180
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
181
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
182
+ <!-- svelte-ignore a11y_role_supports_aria_props -->
208
183
  <div
209
184
  aria-activedescendant={selectedValue}
210
185
  aria-disabled={disabled}
211
186
  aria-orientation={horizontal ? 'horizontal' : 'vertical'}
212
187
  bind:this={listRef}
213
- class={`sterling-list ${variant}`}
188
+ class={['sterling-list', _class].filter(Boolean).join(' ')}
214
189
  class:disabled
215
190
  class:horizontal
216
191
  class:using-keyboard={$usingKeyboard}
217
192
  role="list"
218
193
  tabindex={0}
219
- on:blur
220
- on:click
221
- on:click={onClick}
222
- on:copy
223
- on:cut
224
- on:dblclick
225
- on:dragend
226
- on:dragenter
227
- on:dragleave
228
- on:dragover
229
- on:dragstart
230
- on:drop
231
- on:focus
232
- on:focusin
233
- on:focusout
234
- on:keydown
235
- on:keydown={onKeydown}
236
- on:keypress
237
- on:keyup
238
- on:mousedown
239
- on:mouseenter
240
- on:mouseleave
241
- on:mousemove
242
- on:mouseover
243
- on:mouseout
244
- on:mouseup
245
- on:scroll
246
- on:wheel|passive
247
- on:paste
248
- {...$$restProps}
194
+ {...rest}
195
+ onclick={onClick}
196
+ onkeydown={onKeydown}
249
197
  >
250
198
  <div class="container">
251
- <slot {disabled} {horizontal} {selectedValue} {variant} />
199
+ {#if children}
200
+ {@render children()}
201
+ {/if}
252
202
  </div>
253
203
  </div>
@@ -0,0 +1,20 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement> & {
4
+ disabled?: boolean | null;
5
+ horizontal?: boolean | null;
6
+ selectedValue?: string;
7
+ onSelect?: (value?: string) => void;
8
+ };
9
+ declare const List: import("svelte").Component<Props, {
10
+ blur: () => void;
11
+ click: () => void;
12
+ focus: (options?: FocusOptions) => void;
13
+ scrollToSelectedItem: () => void;
14
+ selectFirstItem: () => boolean;
15
+ selectPreviousItem: () => boolean;
16
+ selectNextItem: () => boolean;
17
+ selectLastItem: () => boolean;
18
+ }, "selectedValue">;
19
+ type List = ReturnType<typeof List>;
20
+ export default List;
@@ -0,0 +1,5 @@
1
+ export type ListContext = {
2
+ disabled?: boolean | null | undefined;
3
+ selectedValue?: string;
4
+ horizontal?: boolean | null | undefined;
5
+ };
@@ -0,0 +1,49 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { getContext } from 'svelte';
4
+ import { LIST_CONTEXT_KEY } from './List.constants';
5
+ let { children, class: _class, disabled, value, ...rest } = $props();
6
+ const listContext = getContext(LIST_CONTEXT_KEY);
7
+ let selected = $state(listContext.selectedValue === value);
8
+ // Using $derived would be preferred, but this helps avoid
9
+ // updates to every list item when selectedValue changes.
10
+ $effect(() => {
11
+ if (listContext.selectedValue === value && !selected) {
12
+ selected = true;
13
+ }
14
+ else if (listContext.selectedValue !== value && selected) {
15
+ selected = false;
16
+ }
17
+ });
18
+ let itemRef;
19
+ export const click = () => {
20
+ itemRef?.click();
21
+ };
22
+ export const blur = () => {
23
+ itemRef?.blur();
24
+ };
25
+ export const focus = (options) => {
26
+ itemRef?.focus(options);
27
+ };
28
+ </script>
29
+
30
+ <!-- svelte-ignore a11y_role_supports_aria_props -->
31
+ <div
32
+ aria-selected={selected}
33
+ bind:this={itemRef}
34
+ class={['sterling-list-item', _class].filter(Boolean).join(' ')}
35
+ class:disabled={disabled || listContext.disabled}
36
+ class:horizontal={listContext.horizontal}
37
+ class:item-disabled={disabled}
38
+ class:list-disabled={listContext.disabled}
39
+ class:selected
40
+ data-value={value}
41
+ role="listitem"
42
+ {...rest}
43
+ >
44
+ {#if children}
45
+ {@render children()}
46
+ {:else}
47
+ {value}
48
+ {/if}
49
+ </div>
@@ -0,0 +1,13 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement> & {
4
+ disabled?: boolean | null;
5
+ value?: string;
6
+ };
7
+ declare const ListItem: import("svelte").Component<Props, {
8
+ click: () => void;
9
+ blur: () => void;
10
+ focus: (options?: FocusOptions) => void;
11
+ }, "">;
12
+ type ListItem = ReturnType<typeof ListItem>;
13
+ export default ListItem;
@@ -1,30 +1,27 @@
1
- <script>import { getContext } from 'svelte';
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { getContext } from 'svelte';
2
4
  import { slide } from 'svelte/transition';
3
5
  import { MENU_ITEM_CONTEXT_KEY } from './MenuItem.constants';
4
6
  import { isElementEnabledMenuItem, isElementMenuItem } from './MenuItem.utils';
5
7
  import { prefersReducedMotion } from './mediaQueries/prefersReducedMotion';
6
- // ----- Props ----- //
7
- /** Additional class names to apply. */
8
- export let variant = '';
9
- // ----- State ----- //
8
+ let { children, class: _class, ...rest } = $props();
10
9
  let menuRef;
11
10
  let menuItemsRef;
12
- // ----- Media Queries ----- //
13
- const slidNoOp = (node, params) => {
11
+ const noSlide = (node, params) => {
14
12
  return { delay: 0, duration: 0 };
15
13
  };
16
- $: slideMotion = !$prefersReducedMotion ? slide : slidNoOp;
17
- // ----- Get Context ----- //
18
- const { rootValue } = getContext(MENU_ITEM_CONTEXT_KEY) || {};
19
- // ----- Methods ----- //
20
- export const blur = () => {
21
- menuRef?.blur();
14
+ let slideMotion = $derived(!$prefersReducedMotion ? slide : noSlide);
15
+ const { rootValue = undefined } = getContext(MENU_ITEM_CONTEXT_KEY);
16
+ const isElementInThisMenu = (candidate) => {
17
+ return candidate && candidate.closest('[role="menu"]') === menuRef;
22
18
  };
19
+ //#region focus
23
20
  export const focus = (options) => {
24
21
  menuRef?.focus(options);
25
22
  };
26
- const isElementInThisMenu = (candidate) => {
27
- return candidate && candidate.closest('[role="menu"]') === menuRef;
23
+ export const blur = () => {
24
+ menuRef?.blur();
28
25
  };
29
26
  export const focusFirstMenuItem = () => {
30
27
  let candidate = menuItemsRef?.firstElementChild;
@@ -64,47 +61,23 @@ export const focusLastMenuItem = () => {
64
61
  candidate?.focus({ preventScroll: true });
65
62
  return !!candidate;
66
63
  };
64
+ //#endregion
67
65
  </script>
68
66
 
69
67
  <div
70
68
  bind:this={menuRef}
71
- class={`sterling-menu ${variant}`}
69
+ class={['sterling-menu', _class].filter(Boolean).join(' ')}
72
70
  role="menu"
73
71
  class:open
74
72
  data-root-value={rootValue}
75
73
  tabindex="-1"
76
74
  in:slideMotion|global={{ duration: 300 }}
77
75
  out:slideMotion|global={{ duration: 100 }}
78
- on:blur
79
- on:click
80
- on:copy
81
- on:cut
82
- on:dblclick
83
- on:dragend
84
- on:dragenter
85
- on:dragleave
86
- on:dragover
87
- on:dragstart
88
- on:drop
89
- on:focus
90
- on:focusin
91
- on:focusout
92
- on:keydown
93
- on:keypress
94
- on:keyup
95
- on:mousedown
96
- on:mouseenter
97
- on:mouseleave
98
- on:mousemove
99
- on:mouseover
100
- on:mouseout
101
- on:mouseup
102
- on:scroll
103
- on:wheel|passive
104
- on:paste
105
- {...$$restProps}
76
+ {...rest}
106
77
  >
107
78
  <div bind:this={menuItemsRef} class="menu-items">
108
- <slot {variant} />
79
+ {#if children}
80
+ {@render children()}
81
+ {/if}
109
82
  </div>
110
83
  </div>
@@ -0,0 +1,13 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement>;
4
+ declare const Menu: import("svelte").Component<Props, {
5
+ focus: (options?: FocusOptions) => void;
6
+ blur: () => void;
7
+ focusFirstMenuItem: () => boolean;
8
+ focusPreviousMenuItem: () => boolean;
9
+ focusNextMenuItem: () => boolean;
10
+ focusLastMenuItem: () => boolean;
11
+ }, "">;
12
+ type Menu = ReturnType<typeof Menu>;
13
+ export default Menu;