@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
@@ -0,0 +1,36 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">let { class: _class, disabled = false, max = 100, percent = $bindable(0), //readonly
4
+ value = $bindable(0), vertical, ...rest } = $props();
5
+ //----- State ----- //
6
+ let clientHeight = $state(0);
7
+ let clientWidth = $state(0);
8
+ let clampMax = $derived(Math.max(1, max));
9
+ let clampValue = $derived(Math.max(0, Math.min(value, clampMax)));
10
+ let ratio = $derived(clampValue / clampMax);
11
+ $effect(() => {
12
+ percent = Math.round(ratio * 100);
13
+ });
14
+ let percentHeight = $derived(clientHeight * ratio);
15
+ let percentWidth = $derived(clientWidth * ratio);
16
+ let indicatorStyle = $derived(vertical ? `height: ${percentHeight}px` : `width: ${percentWidth}px`);
17
+ export {};
18
+ </script>
19
+
20
+ <!-- svelte-ignore a11y_role_supports_aria_props -->
21
+ <div
22
+ aria-orientation={vertical ? 'vertical' : 'horizontal'}
23
+ class={['sterling-progress', _class].filter(Boolean).join(' ')}
24
+ class:disabled
25
+ class:horizontal={!vertical}
26
+ class:vertical
27
+ data-progress-percent={percent}
28
+ data-progress-max={max}
29
+ data-progress-value={value}
30
+ role="progressbar"
31
+ {...rest}
32
+ >
33
+ <div class="container" bind:clientWidth bind:clientHeight>
34
+ <div class="indicator" style={indicatorStyle}></div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,12 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement> & {
4
+ disabled?: boolean | null;
5
+ max?: number;
6
+ percent?: number;
7
+ value?: number;
8
+ vertical?: boolean | null;
9
+ };
10
+ declare const Progress: import("svelte").Component<Props, {}, "value" | "percent">;
11
+ type Progress = ReturnType<typeof Progress>;
12
+ export default Progress;
@@ -0,0 +1,4 @@
1
+ import type { PROGRESS_ORIENTATIONS } from './Progress.constants';
2
+ type ProgressOrientationTuple = typeof PROGRESS_ORIENTATIONS;
3
+ export type ProgressOrientation = ProgressOrientationTuple[number];
4
+ export {};
package/Radio.svelte ADDED
@@ -0,0 +1,53 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { idGenerator } from './idGenerator';
4
+ import { usingKeyboard } from './mediaQueries/usingKeyboard';
5
+ let { id, children, checked = $bindable(false), class: _class, disabled = false, group = $bindable(), ...rest } = $props();
6
+ let inputRef;
7
+ $effect(() => {
8
+ if (children && id === undefined) {
9
+ id = idGenerator.nextId('Radio');
10
+ }
11
+ });
12
+ // ----- Methods ----- //
13
+ export const blur = () => {
14
+ inputRef?.blur();
15
+ };
16
+ export const click = () => {
17
+ inputRef?.click();
18
+ };
19
+ export const focus = (options) => {
20
+ inputRef?.focus(options);
21
+ };
22
+ // ----- Event Handlers ----- //
23
+ const onChange = (e) => {
24
+ console.log('onChange', e);
25
+ // if ((e.currentTarget && e.currentTarget.checked) || (e.target && e.target.checked)) {
26
+ // group = value;
27
+ // }
28
+ };
29
+ $effect(() => {
30
+ console.log(id, '-checked', checked);
31
+ });
32
+ </script>
33
+
34
+ <!--
35
+ @component
36
+ A styled HTML input type=radio element with optional label.
37
+ -->
38
+ <div
39
+ class={`sterling-radio ${_class}`}
40
+ class:checked
41
+ class:disabled
42
+ class:using-keyboard={$usingKeyboard}
43
+ >
44
+ <div class="container">
45
+ <input bind:this={inputRef} checked {disabled} bind:group {id} type="radio" {...rest} />
46
+ <div class="indicator"></div>
47
+ </div>
48
+ {#if children}
49
+ <label for={id}>
50
+ {@render children()}
51
+ </label>
52
+ {/if}
53
+ </div>
@@ -0,0 +1,13 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ type Props = HTMLInputAttributes & {
4
+ group?: any | null;
5
+ };
6
+ /** A styled HTML input type=radio element with optional label. */
7
+ declare const Radio: import("svelte").Component<Props, {
8
+ blur: () => void;
9
+ click: () => void;
10
+ focus: (options?: FocusOptions) => void;
11
+ }, "group" | "checked">;
12
+ type Radio = ReturnType<typeof Radio>;
13
+ export default Radio;
@@ -1,49 +1,32 @@
1
- <script>import { createEventDispatcher, tick } from 'svelte';
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { tick } from 'svelte';
2
4
  import { clickOutside } from './actions/clickOutside';
3
5
  import { idGenerator } from './idGenerator';
4
6
  import List from './List.svelte';
5
7
  import Popover from './Popover.svelte';
8
+ let { buttonSnippet, children, class: _class, disabled = false, open = $bindable(false), onSelect, onPending, selectedValue = $bindable(), listClass, valueSnippet, ...rest } = $props();
6
9
  const popupId = idGenerator.nextId('Select-popup');
7
- // ----- Props ----- //
8
- export let disabled = false;
9
- /** When true, the select's dropdown is open. */
10
- export let open = false;
11
- /** The value of the selected item.*/
12
- export let selectedValue = undefined;
13
- /** Additional class names to apply. */
14
- export let variant = '';
15
- /** Additional class names to apply to the List*/
16
- export let listVariant = '';
17
10
  // ----- State ----- //
18
- // Tracks the previous open state
19
- let prevOpen = false;
20
11
  // Tracks the pending selected index
21
- let pendingSelectedValue = selectedValue;
22
- let selectRef;
12
+ let pendingSelectedValue = $state(selectedValue);
13
+ // svelte-ignore non_reactive_update
14
+ let selectRef = $state(undefined);
23
15
  let listRef;
24
- // ----- Events ----- //
25
- const dispatch = createEventDispatcher();
26
- const raiseSelect = (value) => {
27
- dispatch('select', { value });
28
- };
29
- const raisePending = (value) => {
30
- dispatch('pending', { value });
31
- };
32
16
  // ----- Reactions ----- //
33
- $: {
17
+ $effect(() => {
34
18
  pendingSelectedValue = selectedValue;
35
- }
36
- $: {
37
- raiseSelect(selectedValue);
38
- }
39
- $: {
19
+ });
20
+ $effect(() => {
21
+ onSelect?.(selectedValue);
22
+ });
23
+ $effect(() => {
40
24
  if (open) {
41
- raisePending(pendingSelectedValue);
25
+ onPending?.(pendingSelectedValue);
42
26
  }
43
- }
44
- $: {
45
- if (open && !prevOpen) {
46
- prevOpen = true;
27
+ });
28
+ $effect(() => {
29
+ if (open) {
47
30
  tick().then(() => {
48
31
  setTimeout(() => {
49
32
  listRef?.focus();
@@ -51,11 +34,12 @@ $: {
51
34
  }, 10);
52
35
  });
53
36
  }
54
- else if (prevOpen) {
55
- prevOpen = false;
37
+ });
38
+ $effect(() => {
39
+ if (!open) {
56
40
  tick().then(() => selectRef?.focus());
57
41
  }
58
- }
42
+ });
59
43
  // ----- Methods ----- //
60
44
  export const blur = () => {
61
45
  selectRef?.blur();
@@ -78,6 +62,7 @@ const onSelectClick = (event) => {
78
62
  event.preventDefault();
79
63
  event.stopPropagation();
80
64
  }
65
+ rest.onclick?.(event);
81
66
  };
82
67
  const onSelectKeydown = (event) => {
83
68
  if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
@@ -95,10 +80,10 @@ const onSelectKeydown = (event) => {
95
80
  case 'ArrowUp':
96
81
  {
97
82
  if (selectedValue) {
98
- listRef.selectPreviousItem();
83
+ listRef?.selectPreviousItem();
99
84
  }
100
85
  else {
101
- listRef.selectLastItem();
86
+ listRef?.selectLastItem();
102
87
  }
103
88
  event.preventDefault();
104
89
  event.stopPropagation();
@@ -108,10 +93,10 @@ const onSelectKeydown = (event) => {
108
93
  case 'ArrowDown':
109
94
  {
110
95
  if (selectedValue) {
111
- listRef.selectNextItem();
96
+ listRef?.selectNextItem();
112
97
  }
113
98
  else {
114
- listRef.selectFirstItem();
99
+ listRef?.selectFirstItem();
115
100
  }
116
101
  event.preventDefault();
117
102
  event.stopPropagation();
@@ -120,6 +105,7 @@ const onSelectKeydown = (event) => {
120
105
  break;
121
106
  }
122
107
  }
108
+ rest.onkeydown?.(event);
123
109
  };
124
110
  const onListKeydown = (event) => {
125
111
  if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
@@ -151,8 +137,8 @@ const onListClick = (event) => {
151
137
  event.stopPropagation();
152
138
  return false;
153
139
  };
154
- const onListSelect = (event) => {
155
- pendingSelectedValue = event.detail.value;
140
+ const onListSelect = (value) => {
141
+ pendingSelectedValue = value;
156
142
  if (!open) {
157
143
  selectedValue = pendingSelectedValue;
158
144
  }
@@ -164,71 +150,46 @@ const onListSelect = (event) => {
164
150
  aria-controls={popupId}
165
151
  aria-haspopup="listbox"
166
152
  aria-expanded={open}
167
- class={`sterling-select ${variant}`}
153
+ class={['sterling-select', _class].filter(Boolean).join(' ')}
168
154
  class:disabled
169
155
  role="combobox"
170
156
  tabindex="0"
171
- use:clickOutside
172
- on:blur
173
- on:click
174
- on:copy
175
- on:cut
176
- on:dblclick
177
- on:dragend
178
- on:dragenter
179
- on:dragleave
180
- on:dragover
181
- on:dragstart
182
- on:drop
183
- on:focus
184
- on:focusin
185
- on:focusout
186
- on:keydown
187
- on:keypress
188
- on:keyup
189
- on:mousedown
190
- on:mouseenter
191
- on:mouseleave
192
- on:mousemove
193
- on:mouseover
194
- on:mouseout
195
- on:mouseup
196
- on:wheel|passive
197
- on:paste
198
- on:click={onSelectClick}
199
- on:click_outside={() => (open = false)}
200
- on:keydown={onSelectKeydown}
201
- {...$$restProps}
157
+ use:clickOutside={{ onclickoutside: () => (open = false) }}
158
+ {...rest}
159
+ onclick={onSelectClick}
160
+ onkeydown={onSelectKeydown}
202
161
  >
203
162
  <div class="value">
204
- <slot name="value" {disabled} {open} {selectedValue} {variant}>
205
- {#if selectedValue}
206
- {selectedValue}
207
- {:else}
208
- <span>&nbsp;</span>
209
- {/if}
210
- </slot>
163
+ {#if valueSnippet}
164
+ {@render valueSnippet(selectedValue)}
165
+ {:else if selectedValue}
166
+ {selectedValue}
167
+ {:else}
168
+ <span>&nbsp;</span>
169
+ {/if}
211
170
  </div>
212
171
  <div class="button">
213
- <slot name="button" {disabled} {open} {selectedValue} {variant}>
214
- <slot name="icon" {disabled} {open} {selectedValue} {variant}>
215
- <div class="chevron" />
216
- </slot>
217
- </slot>
172
+ {#if buttonSnippet}
173
+ {@render buttonSnippet()}
174
+ {:else}
175
+ <div class="chevron"></div>
176
+ {/if}
218
177
  </div>
219
178
  <Popover reference={selectRef} bind:open id={popupId} conditionalRender={false}>
220
- <div class={`sterling-select-popup-content ${variant}`}>
179
+ <div class={['sterling-select-popup-content', _class].filter(Boolean).join(' ')}>
221
180
  <List
222
181
  bind:this={listRef}
223
182
  {disabled}
224
183
  selectedValue={pendingSelectedValue}
225
- on:click={onListClick}
226
- on:keydown={onListKeydown}
227
- on:select={onListSelect}
228
- tabIndex={open ? 0 : -1}
229
- variant={`composed ${listVariant}`}
184
+ onclick={onListClick}
185
+ onkeydown={onListKeydown}
186
+ onSelect={onListSelect}
187
+ tabindex={open ? 0 : -1}
188
+ class={`composed ${listClass}`}
230
189
  >
231
- <slot {variant} {listVariant} />
190
+ {#if children}
191
+ {@render children()}
192
+ {/if}
232
193
  </List>
233
194
  </div>
234
195
  </Popover>
@@ -0,0 +1,20 @@
1
+ import { type Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement> & {
4
+ buttonSnippet?: Snippet;
5
+ disabled?: boolean | null;
6
+ listClass?: string;
7
+ onPending?: (value?: string) => void;
8
+ onSelect?: (value?: string) => void;
9
+ open?: boolean | null;
10
+ selectedValue?: string;
11
+ valueSnippet?: Snippet<[string | undefined]>;
12
+ };
13
+ declare const Select: import("svelte").Component<Props, {
14
+ blur: () => void;
15
+ click: () => void;
16
+ focus: (options?: FocusOptions) => void;
17
+ scrollToSelectedItem: () => void;
18
+ }, "open" | "selectedValue">;
19
+ type Select = ReturnType<typeof Select>;
20
+ export default Select;
package/Slider.svelte ADDED
@@ -0,0 +1,133 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { round } from 'lodash-es';
4
+ let { class: _class, disabled, min = 0, max = 100, onChange, precision = 0, step = 1, value = $bindable(0), vertical, ...rest } = $props();
5
+ let sliderRef;
6
+ export const blur = () => {
7
+ sliderRef?.blur();
8
+ };
9
+ export const click = () => {
10
+ sliderRef?.click();
11
+ };
12
+ export const focus = (options) => {
13
+ sliderRef?.focus();
14
+ };
15
+ let ratio = $derived((value - min) / (max - min));
16
+ const setValue = (newValue) => {
17
+ const clamped = Math.max(min, Math.min(max, newValue));
18
+ value = precision !== undefined ? round(clamped, precision) : clamped;
19
+ };
20
+ // ensure min <= max
21
+ $effect(() => {
22
+ if (min > max) {
23
+ min = max;
24
+ }
25
+ });
26
+ $effect(() => {
27
+ const clamped = Math.max(min, Math.min(max, value));
28
+ const newValue = precision !== undefined ? round(clamped, precision) : clamped;
29
+ if (value !== newValue) {
30
+ value = newValue;
31
+ }
32
+ });
33
+ const setValueByOffset = (offset) => {
34
+ if (sliderSize > 0) {
35
+ const positionRatio = Math.max(0, Math.min(1, offset / sliderSize));
36
+ const newValue = min + positionRatio * (max - min);
37
+ setValue(newValue);
38
+ }
39
+ };
40
+ // Raise change event when value changes
41
+ $effect(() => {
42
+ onChange?.(value);
43
+ });
44
+ // ----- Size tracking ----- //
45
+ let sliderWidth = $state(0);
46
+ let sliderHeight = $state(0);
47
+ let sliderSize = $derived(vertical ? sliderHeight : sliderWidth);
48
+ let valueOffset = $derived(sliderSize * ratio);
49
+ // ----- Event handlers ----- //
50
+ const onPointerDown = (event) => {
51
+ if (!disabled) {
52
+ event.currentTarget.setPointerCapture(event.pointerId);
53
+ if (vertical) {
54
+ setValueByOffset(sliderRef.getBoundingClientRect().bottom - event.y);
55
+ }
56
+ else {
57
+ setValueByOffset(event.x - sliderRef.getBoundingClientRect().left);
58
+ }
59
+ }
60
+ rest?.onpointerdown?.(event);
61
+ };
62
+ const onPointerMove = (event) => {
63
+ if (!disabled && event.currentTarget.hasPointerCapture(event.pointerId)) {
64
+ if (vertical) {
65
+ setValueByOffset(sliderRef.getBoundingClientRect().bottom - event.y);
66
+ }
67
+ else {
68
+ setValueByOffset(event.x - sliderRef.getBoundingClientRect().left);
69
+ }
70
+ }
71
+ rest?.onpointermove?.(event);
72
+ };
73
+ const onPointerUp = (event) => {
74
+ if (!disabled) {
75
+ event.currentTarget.releasePointerCapture(event.pointerId);
76
+ }
77
+ rest?.onpointerup?.(event);
78
+ };
79
+ const onKeyDown = (event) => {
80
+ if (!disabled && !event.ctrlKey && !event.shiftKey && !event.altKey) {
81
+ switch (event.code) {
82
+ case 'ArrowDown':
83
+ case 'ArrowLeft':
84
+ setValue(value - step);
85
+ event.preventDefault();
86
+ event.stopPropagation();
87
+ return;
88
+ case 'ArrowRight':
89
+ case 'ArrowUp':
90
+ setValue(value + step);
91
+ event.preventDefault();
92
+ event.stopPropagation();
93
+ return;
94
+ }
95
+ }
96
+ rest?.onkeydown?.(event);
97
+ };
98
+ </script>
99
+
100
+ <div
101
+ aria-disabled={disabled}
102
+ aria-valuemin={min}
103
+ aria-valuenow={value}
104
+ aria-valuemax={max}
105
+ class={`sterling-slider ${_class}`}
106
+ class:disabled
107
+ class:horizontal={!vertical}
108
+ class:vertical
109
+ role="slider"
110
+ tabindex={!disabled ? 0 : undefined}
111
+ {...rest}
112
+ onkeydown={onKeyDown}
113
+ onpointerdown={onPointerDown}
114
+ onpointermove={onPointerMove}
115
+ onpointerup={onPointerUp}
116
+ >
117
+ <div
118
+ class="container"
119
+ bind:this={sliderRef}
120
+ bind:clientWidth={sliderWidth}
121
+ bind:clientHeight={sliderHeight}
122
+ >
123
+ <div class="track"></div>
124
+ <div
125
+ class="fill"
126
+ style={vertical ? `height: ${valueOffset}px` : `width: ${valueOffset}px`}
127
+ ></div>
128
+ <div
129
+ class="thumb"
130
+ style={vertical ? `bottom: ${valueOffset}px` : `left: ${valueOffset}px`}
131
+ ></div>
132
+ </div>
133
+ </div>
@@ -0,0 +1,19 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement> & {
4
+ disabled?: boolean | null;
5
+ min?: number;
6
+ max?: number;
7
+ precision?: number;
8
+ step?: number;
9
+ value?: number;
10
+ vertical?: boolean | null;
11
+ onChange?: (value: number) => void;
12
+ };
13
+ declare const Slider: import("svelte").Component<Props, {
14
+ blur: () => void;
15
+ click: () => void;
16
+ focus: (options?: FocusOptions) => void;
17
+ }, "value">;
18
+ type Slider = ReturnType<typeof Slider>;
19
+ export default Slider;
package/Switch.svelte ADDED
@@ -0,0 +1,61 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { idGenerator } from './idGenerator';
4
+ import { usingKeyboard } from './mediaQueries/usingKeyboard';
5
+ let { checked = $bindable(false), class: _class, disabled, id, offLabel, onLabel, vertical, ...rest } = $props();
6
+ const inputId = id || idGenerator.nextId('Switch');
7
+ let inputRef;
8
+ let switchWidth = $state(0);
9
+ let switchHeight = $state(0);
10
+ let thumbWidth = $state(0);
11
+ let thumbHeight = $state(0);
12
+ let switchSize = $derived(vertical ? switchHeight : switchWidth);
13
+ let thumbSize = $derived(vertical ? thumbHeight : thumbWidth);
14
+ let ratio = $derived(vertical ? (checked ? 0 : 1) : checked ? 1 : 0);
15
+ let valueOffset = $derived((switchSize - thumbSize) * ratio);
16
+ export const blur = () => {
17
+ inputRef?.blur();
18
+ };
19
+ export const click = () => {
20
+ inputRef?.click();
21
+ };
22
+ export const focus = (options) => {
23
+ inputRef?.focus(options);
24
+ };
25
+ </script>
26
+
27
+ <div
28
+ class={`sterling-switch ${_class}`}
29
+ class:checked
30
+ class:disabled
31
+ class:vertical
32
+ class:using-keyboard={$usingKeyboard}
33
+ >
34
+ <input bind:this={inputRef} bind:checked {disabled} id={inputId} type="checkbox" {...rest} />
35
+ {#if offLabel}
36
+ <div class="off-label">
37
+ {#if typeof offLabel === 'string'}
38
+ {offLabel}
39
+ {:else}
40
+ {@render offLabel({ checked, disabled, inputId })}
41
+ {/if}
42
+ </div>
43
+ {/if}
44
+ <div class="toggle" bind:offsetWidth={switchWidth} bind:offsetHeight={switchHeight}>
45
+ <div
46
+ class="thumb"
47
+ bind:offsetWidth={thumbWidth}
48
+ bind:offsetHeight={thumbHeight}
49
+ style={`--thumb-offset: ${valueOffset}px`}
50
+ ></div>
51
+ </div>
52
+ {#if onLabel}
53
+ <div class="on-label">
54
+ {#if typeof onLabel === 'string'}
55
+ {onLabel}
56
+ {:else}
57
+ {@render onLabel({ checked, disabled, inputId })}
58
+ {/if}
59
+ </div>
60
+ {/if}
61
+ </div>
@@ -0,0 +1,21 @@
1
+ import type { HTMLInputAttributes } from 'svelte/elements';
2
+ import type { Snippet } from 'svelte';
3
+ type LabelSnippet = Snippet<[
4
+ {
5
+ checked: boolean | null | undefined;
6
+ disabled: boolean | null | undefined;
7
+ inputId: string;
8
+ }
9
+ ]>;
10
+ type Props = HTMLInputAttributes & {
11
+ offLabel?: string | LabelSnippet;
12
+ onLabel?: string | LabelSnippet;
13
+ vertical?: boolean | null | undefined;
14
+ };
15
+ declare const Switch: import("svelte").Component<Props, {
16
+ blur: () => void;
17
+ click: () => void;
18
+ focus: (options?: FocusOptions) => void;
19
+ }, "checked">;
20
+ type Switch = ReturnType<typeof Switch>;
21
+ export default Switch;
package/Tab.svelte ADDED
@@ -0,0 +1,51 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { getContext } from 'svelte';
4
+ import { TAB_LIST_CONTEXT_KEY } from './TabList.constants';
5
+ import { usingKeyboard } from './mediaQueries/usingKeyboard';
6
+ let { children, class: _class, disabled = false, value, ...rest } = $props();
7
+ let tabRef;
8
+ const tabListContext = getContext(TAB_LIST_CONTEXT_KEY);
9
+ let selected = $state(tabListContext.selectedValue === value);
10
+ let _disabled = $derived(tabListContext.disabled || disabled);
11
+ // Using $derived would be preferred, but this helps avoid
12
+ // updates to every tab when selectedValue changes.
13
+ // let selected = $derived(tabContext.selectedValue === value);
14
+ $effect(() => {
15
+ if (tabListContext.selectedValue === value && !selected) {
16
+ selected = true;
17
+ }
18
+ else if (tabListContext.selectedValue !== value && selected) {
19
+ selected = false;
20
+ }
21
+ });
22
+ export const click = () => {
23
+ tabRef?.click();
24
+ };
25
+ export const blur = () => {
26
+ tabRef?.blur();
27
+ };
28
+ export const focus = (options) => {
29
+ tabRef?.focus(options);
30
+ };
31
+ </script>
32
+
33
+ <button
34
+ bind:this={tabRef}
35
+ aria-selected={selected}
36
+ class={`sterling-tab ${_class}`}
37
+ class:selected
38
+ class:using-keyboard={$usingKeyboard}
39
+ class:vertical={tabListContext.vertical}
40
+ data-value={value}
41
+ disabled={_disabled}
42
+ role="tab"
43
+ type="button"
44
+ tabIndex={selected ? 0 : -1}
45
+ {...rest}
46
+ >
47
+ <div class="content">
48
+ {@render children?.()}
49
+ </div>
50
+ <div class="indicator"></div>
51
+ </button>
@@ -0,0 +1,12 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLButtonAttributes } from 'svelte/elements';
3
+ type Props = HTMLButtonAttributes & {
4
+ value: string;
5
+ };
6
+ declare const Tab: import("svelte").Component<Props, {
7
+ click: () => void;
8
+ blur: () => void;
9
+ focus: (options?: FocusOptions) => void;
10
+ }, "">;
11
+ type Tab = ReturnType<typeof Tab>;
12
+ export default Tab;