@geoffcox/sterling-svelte 1.0.11 → 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 (306) 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} +61 -78
  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/Dropdown.svelte +109 -0
  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 +0 -138
  91. package/dist/Dropdown.svelte.d.ts +0 -77
  92. package/dist/HexColorSliders.svelte +0 -103
  93. package/dist/HexColorSliders.svelte.d.ts +0 -51
  94. package/dist/HslColorSliders.svelte +0 -128
  95. package/dist/HslColorSliders.svelte.d.ts +0 -51
  96. package/dist/Input.svelte +0 -89
  97. package/dist/Input.svelte.d.ts +0 -74
  98. package/dist/Label.svelte +0 -197
  99. package/dist/Label.svelte.d.ts +0 -82
  100. package/dist/Label.types.d.ts +0 -6
  101. package/dist/Label.types.js +0 -1
  102. package/dist/Link.svelte +0 -57
  103. package/dist/Link.svelte.d.ts +0 -65
  104. package/dist/List.svelte.d.ts +0 -75
  105. package/dist/List.types.d.ts +0 -13
  106. package/dist/ListItem.svelte +0 -78
  107. package/dist/ListItem.svelte.d.ts +0 -67
  108. package/dist/Menu.svelte.d.ts +0 -63
  109. package/dist/MenuBar.svelte.d.ts +0 -58
  110. package/dist/MenuButton.svelte +0 -145
  111. package/dist/MenuButton.svelte.d.ts +0 -71
  112. package/dist/MenuItem.svelte.d.ts +0 -83
  113. package/dist/MenuItemDisplay.svelte +0 -32
  114. package/dist/MenuItemDisplay.svelte.d.ts +0 -39
  115. package/dist/MenuSeparator.svelte +0 -9
  116. package/dist/MenuSeparator.svelte.d.ts +0 -20
  117. package/dist/Popover.svelte.d.ts +0 -59
  118. package/dist/Progress.constants.d.ts +0 -1
  119. package/dist/Progress.constants.js +0 -1
  120. package/dist/Progress.svelte +0 -83
  121. package/dist/Progress.svelte.d.ts +0 -61
  122. package/dist/Progress.types.d.ts +0 -4
  123. package/dist/Radio.svelte +0 -126
  124. package/dist/Radio.svelte.d.ts +0 -65
  125. package/dist/RgbColorSliders.svelte +0 -93
  126. package/dist/RgbColorSliders.svelte.d.ts +0 -24
  127. package/dist/Select.svelte.d.ts +0 -83
  128. package/dist/Slider.svelte +0 -190
  129. package/dist/Slider.svelte.d.ts +0 -66
  130. package/dist/Switch.svelte +0 -110
  131. package/dist/Switch.svelte.d.ts +0 -74
  132. package/dist/Tab.svelte +0 -94
  133. package/dist/Tab.svelte.d.ts +0 -71
  134. package/dist/TabList.svelte.d.ts +0 -70
  135. package/dist/TabList.types.d.ts +0 -13
  136. package/dist/TextArea.svelte.d.ts +0 -69
  137. package/dist/Tooltip.svelte +0 -106
  138. package/dist/Tooltip.svelte.d.ts +0 -70
  139. package/dist/Tree.svelte +0 -104
  140. package/dist/Tree.svelte.d.ts +0 -67
  141. package/dist/Tree.types.d.ts +0 -13
  142. package/dist/TreeChevron.svelte +0 -66
  143. package/dist/TreeChevron.svelte.d.ts +0 -53
  144. package/dist/TreeItem.svelte.d.ts +0 -101
  145. package/dist/TreeItem.types.d.ts +0 -14
  146. package/dist/TreeItemDisplay.svelte +0 -74
  147. package/dist/TreeItemDisplay.svelte.d.ts +0 -73
  148. package/dist/css/Button.base.css +0 -74
  149. package/dist/css/Button.colorful.css +0 -17
  150. package/dist/css/Button.css +0 -7
  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 -43
  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 -145
  160. package/dist/css/Checkbox.colorful.css +0 -17
  161. package/dist/css/Checkbox.css +0 -2
  162. package/dist/css/ColorPicker.base.css +0 -23
  163. package/dist/css/ColorPicker.css +0 -1
  164. package/dist/css/Dialog.base.css +0 -114
  165. package/dist/css/Dialog.css +0 -1
  166. package/dist/css/Dropdown.base.css +0 -147
  167. package/dist/css/Dropdown.colorful.css +0 -23
  168. package/dist/css/Dropdown.css +0 -2
  169. package/dist/css/HexColorSliders.base.css +0 -106
  170. package/dist/css/HexColorSliders.css +0 -1
  171. package/dist/css/HslColorSliders.base.css +0 -124
  172. package/dist/css/HslColorSliders.css +0 -1
  173. package/dist/css/Input.base.css +0 -103
  174. package/dist/css/Input.colorful.css +0 -22
  175. package/dist/css/Input.composed.css +0 -8
  176. package/dist/css/Input.css +0 -3
  177. package/dist/css/Label.base.css +0 -118
  178. package/dist/css/Label.boxed.colorful.css +0 -21
  179. package/dist/css/Label.boxed.css +0 -31
  180. package/dist/css/Label.colorful.css +0 -3
  181. package/dist/css/Label.css +0 -4
  182. package/dist/css/Link.base.css +0 -54
  183. package/dist/css/Link.colorful.css +0 -15
  184. package/dist/css/Link.css +0 -10
  185. package/dist/css/Link.ghost.colorful.css +0 -7
  186. package/dist/css/Link.ghost.css +0 -11
  187. package/dist/css/Link.text-underline.css +0 -8
  188. package/dist/css/Link.text-underline.ghost.css +0 -13
  189. package/dist/css/Link.undecorated.colorful.css +0 -8
  190. package/dist/css/Link.undecorated.css +0 -8
  191. package/dist/css/Link.undecorated.ghost.css +0 -8
  192. package/dist/css/Link.undecorated.underline.css +0 -8
  193. package/dist/css/List.base.css +0 -98
  194. package/dist/css/List.css +0 -1
  195. package/dist/css/ListItem.base.css +0 -59
  196. package/dist/css/ListItem.css +0 -1
  197. package/dist/css/Menu.base.css +0 -21
  198. package/dist/css/Menu.css +0 -1
  199. package/dist/css/MenuBar.base.css +0 -9
  200. package/dist/css/MenuBar.css +0 -1
  201. package/dist/css/MenuButton.base.css +0 -13
  202. package/dist/css/MenuButton.css +0 -1
  203. package/dist/css/MenuItem.base.css +0 -48
  204. package/dist/css/MenuItem.css +0 -1
  205. package/dist/css/MenuItemDisplay.base.css +0 -108
  206. package/dist/css/MenuItemDisplay.css +0 -1
  207. package/dist/css/MenuSeparator.base.css +0 -5
  208. package/dist/css/MenuSeparator.css +0 -1
  209. package/dist/css/Popover.css +0 -21
  210. package/dist/css/Progress.base.css +0 -99
  211. package/dist/css/Progress.css +0 -1
  212. package/dist/css/Radio.base.css +0 -135
  213. package/dist/css/Radio.colorful.css +0 -18
  214. package/dist/css/Radio.css +0 -2
  215. package/dist/css/RgbColorSliders.base.css +0 -94
  216. package/dist/css/RgbColorSliders.css +0 -1
  217. package/dist/css/Select.base.css +0 -127
  218. package/dist/css/Select.colorful.css +0 -24
  219. package/dist/css/Select.composed.css +0 -12
  220. package/dist/css/Select.css +0 -3
  221. package/dist/css/Slider.base.css +0 -192
  222. package/dist/css/Slider.colorful.css +0 -11
  223. package/dist/css/Slider.composed.css +0 -8
  224. package/dist/css/Slider.css +0 -3
  225. package/dist/css/Switch.base.css +0 -206
  226. package/dist/css/Switch.colorful.css +0 -45
  227. package/dist/css/Switch.css +0 -2
  228. package/dist/css/Tab.base.css +0 -132
  229. package/dist/css/Tab.colorful.css +0 -13
  230. package/dist/css/Tab.css +0 -2
  231. package/dist/css/TabList.base.css +0 -34
  232. package/dist/css/TabList.css +0 -1
  233. package/dist/css/TextArea.base.css +0 -85
  234. package/dist/css/TextArea.colorful.css +0 -17
  235. package/dist/css/TextArea.composed.css +0 -8
  236. package/dist/css/TextArea.css +0 -3
  237. package/dist/css/Tooltip.base.css +0 -6
  238. package/dist/css/Tooltip.css +0 -1
  239. package/dist/css/Tree.base.css +0 -74
  240. package/dist/css/Tree.composed.css +0 -8
  241. package/dist/css/Tree.css +0 -2
  242. package/dist/css/TreeChevron.base.css +0 -86
  243. package/dist/css/TreeChevron.css +0 -1
  244. package/dist/css/TreeItem.base.css +0 -3
  245. package/dist/css/TreeItem.css +0 -1
  246. package/dist/css/TreeItemDisplay.base.css +0 -74
  247. package/dist/css/TreeItemDisplay.colorful.css +0 -9
  248. package/dist/css/TreeItemDisplay.css +0 -1
  249. package/dist/css/dark-mode.css +0 -134
  250. package/dist/css/light-mode.css +0 -134
  251. package/dist/css/sterling.css +0 -37
  252. package/dist/package.json +0 -108
  253. /package/{dist/@types → @types}/clickOutside.d.ts +0 -0
  254. /package/{dist/Button.types.js → Callout.types.js} +0 -0
  255. /package/{dist/Label.constants.d.ts → Label.constants.d.ts} +0 -0
  256. /package/{dist/Label.constants.js → Label.constants.js} +0 -0
  257. /package/{dist/List.constants.d.ts → List.constants.d.ts} +0 -0
  258. /package/{dist/List.constants.js → List.constants.js} +0 -0
  259. /package/{dist/List.types.js → List.types.js} +0 -0
  260. /package/{dist/MenuBar.constants.d.ts → MenuBar.constants.d.ts} +0 -0
  261. /package/{dist/MenuBar.constants.js → MenuBar.constants.js} +0 -0
  262. /package/{dist/MenuBar.types.d.ts → MenuBar.types.d.ts} +0 -0
  263. /package/{dist/MenuBar.types.js → MenuBar.types.js} +0 -0
  264. /package/{dist/MenuItem.constants.d.ts → MenuItem.constants.d.ts} +0 -0
  265. /package/{dist/MenuItem.constants.js → MenuItem.constants.js} +0 -0
  266. /package/{dist/MenuItem.types.js → MenuItem.types.js} +0 -0
  267. /package/{dist/MenuItem.utils.d.ts → MenuItem.utils.d.ts} +0 -0
  268. /package/{dist/MenuItem.utils.js → MenuItem.utils.js} +0 -0
  269. /package/{dist/Popover.constants.d.ts → Popover.constants.d.ts} +0 -0
  270. /package/{dist/Popover.constants.js → Popover.constants.js} +0 -0
  271. /package/{dist/Popover.types.d.ts → Popover.types.d.ts} +0 -0
  272. /package/{dist/Popover.types.js → Popover.types.js} +0 -0
  273. /package/{dist/Portal.constants.d.ts → Portal.constants.d.ts} +0 -0
  274. /package/{dist/Portal.constants.js → Portal.constants.js} +0 -0
  275. /package/{dist/Portal.types.d.ts → Portal.types.d.ts} +0 -0
  276. /package/{dist/Portal.types.js → Portal.types.js} +0 -0
  277. /package/{dist/Progress.types.js → Progress.types.js} +0 -0
  278. /package/{dist/TabList.constants.d.ts → TabList.constants.d.ts} +0 -0
  279. /package/{dist/TabList.constants.js → TabList.constants.js} +0 -0
  280. /package/{dist/TabList.types.js → TabList.types.js} +0 -0
  281. /package/{dist/TextArea.constants.d.ts → TextArea.constants.d.ts} +0 -0
  282. /package/{dist/TextArea.constants.js → TextArea.constants.js} +0 -0
  283. /package/{dist/TextArea.types.d.ts → TextArea.types.d.ts} +0 -0
  284. /package/{dist/TextArea.types.js → TextArea.types.js} +0 -0
  285. /package/{dist/Tree.constants.d.ts → Tree.constants.d.ts} +0 -0
  286. /package/{dist/Tree.constants.js → Tree.constants.js} +0 -0
  287. /package/{dist/Tree.types.js → Tree.types.js} +0 -0
  288. /package/{dist/TreeItem.constants.d.ts → TreeItem.constants.d.ts} +0 -0
  289. /package/{dist/TreeItem.constants.js → TreeItem.constants.js} +0 -0
  290. /package/{dist/TreeItem.types.js → TreeItem.types.js} +0 -0
  291. /package/{dist/actions → actions}/applyLightDarkMode.d.ts +0 -0
  292. /package/{dist/actions → actions}/applyLightDarkMode.js +0 -0
  293. /package/{dist/actions → actions}/forwardEvents.d.ts +0 -0
  294. /package/{dist/actions → actions}/forwardEvents.js +0 -0
  295. /package/{dist/actions → actions}/portal.d.ts +0 -0
  296. /package/{dist/actions → actions}/portal.js +0 -0
  297. /package/{dist/actions → actions}/trapKeyboardFocus.d.ts +0 -0
  298. /package/{dist/actions → actions}/trapKeyboardFocus.js +0 -0
  299. /package/{dist/idGenerator.d.ts → idGenerator.d.ts} +0 -0
  300. /package/{dist/idGenerator.js → idGenerator.js} +0 -0
  301. /package/{dist/mediaQueries → mediaQueries}/prefersColorSchemeDark.d.ts +0 -0
  302. /package/{dist/mediaQueries → mediaQueries}/prefersColorSchemeDark.js +0 -0
  303. /package/{dist/mediaQueries → mediaQueries}/prefersReducedMotion.d.ts +0 -0
  304. /package/{dist/mediaQueries → mediaQueries}/prefersReducedMotion.js +0 -0
  305. /package/{dist/mediaQueries → mediaQueries}/usingKeyboard.d.ts +0 -0
  306. /package/{dist/mediaQueries → mediaQueries}/usingKeyboard.js +0 -0
package/.DS_Store ADDED
Binary file
package/Button.svelte ADDED
@@ -0,0 +1,25 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">let { children, class: _class, ...rest } = $props();
4
+ let buttonRef;
5
+ export const click = () => {
6
+ buttonRef?.click();
7
+ };
8
+ export const blur = () => {
9
+ buttonRef?.blur();
10
+ };
11
+ export const focus = (options) => {
12
+ buttonRef?.focus(options);
13
+ };
14
+ </script>
15
+
16
+ <button
17
+ bind:this={buttonRef}
18
+ class={['sterling-button', _class].filter(Boolean).join(' ')}
19
+ type="button"
20
+ {...rest}
21
+ >
22
+ {#if children}
23
+ {@render children()}
24
+ {/if}
25
+ </button>
@@ -0,0 +1,9 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLButtonAttributes } from 'svelte/elements';
3
+ declare const Button: import("svelte").Component<HTMLButtonAttributes, {
4
+ click: () => void;
5
+ blur: () => void;
6
+ focus: (options?: FocusOptions) => void;
7
+ }, "">;
8
+ type Button = ReturnType<typeof Button>;
9
+ export default Button;
@@ -1,37 +1,21 @@
1
- <script>import { getContext, onMount, tick } from 'svelte';
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { getContext, tick } from 'svelte';
2
4
  import { arrow, autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
3
5
  import { portal } from './actions/portal';
4
6
  import { fade } from 'svelte/transition';
5
7
  import { prefersReducedMotion } from './mediaQueries/prefersReducedMotion';
6
8
  import { STERLING_PORTAL_HOST_ID, STERLING_PORTAL_CONTEXT_ID } from './Portal.constants';
7
- // ----- Props ----- //
8
- /** Conditionally renders content based on open. */
9
- export let conditionalRender = true;
10
- /** The offset along the side of the reference element. */
11
- export let crossAxisOffset = 0;
12
- /** The offset towards or away from the side of the reference element. */
13
- export let mainAxisOffset = 0;
14
- /** When true, the callout is open and visible. */
15
- export let open = false;
16
- /** How the callout should be positioned relative to the reference element. */
17
- export let placement = 'top-start';
18
- /** The host container for the callout. */
19
- export let portalHost = undefined;
20
- /** The reference to the element anchoring the position of the callout. */
21
- export let reference;
22
- /** Additional class names to apply. */
23
- export let variant = '';
24
- // ----- State ----- //
25
- let popupRef;
26
- let arrowRef;
27
- let popupPosition = { x: 0, y: 0 };
28
- $: floatingUIPlacement = placement;
29
- let bodyHeight = 0;
9
+ let { children, conditionalRender = $bindable(true), crossAxisOffset = $bindable(0), mainAxisOffset = $bindable(0), open = $bindable(false), placement = $bindable('top-start'), portalHost, reference, class: _class, ...rest } = $props();
10
+ let popupRef = $state(undefined);
11
+ let arrowRef = $state(undefined);
12
+ let popupPosition = $state({ x: 0, y: 0 });
13
+ let floatingUIPlacement = $derived(placement);
14
+ let bodyHeight = $state(0);
30
15
  let resizeObserver = undefined;
31
16
  const { portalHost: contextPortalHost } = getContext(STERLING_PORTAL_CONTEXT_ID) || {
32
17
  portalHost: undefined
33
18
  };
34
- // ----- Portal Host ----- //
35
19
  const ensurePortalHost = async () => {
36
20
  await tick();
37
21
  // use the host set from context, usually set from a Dialog
@@ -49,18 +33,18 @@ const ensurePortalHost = async () => {
49
33
  }
50
34
  portalHost = host;
51
35
  };
52
- // ----- Position ----- //
53
- $: middleware = [
36
+ let middleware = $derived([
54
37
  offset({ mainAxis: mainAxisOffset, crossAxis: crossAxisOffset }),
55
38
  flip(),
56
- arrow({ element: arrowRef, padding: 8 })
57
- ];
39
+ arrowRef && arrow({ element: arrowRef, padding: 8 })
40
+ ]);
58
41
  const computeCalloutPosition = async () => {
59
42
  if (reference && popupRef) {
60
43
  popupPosition = await computePosition(reference, popupRef, {
61
44
  placement: floatingUIPlacement,
62
45
  middleware
63
46
  });
47
+ console.log('popupPosition', popupPosition);
64
48
  }
65
49
  else {
66
50
  popupPosition = { x: 0, y: 0 };
@@ -70,12 +54,23 @@ const computeCalloutPosition = async () => {
70
54
  let cleanupAutoUpdate = () => { };
71
55
  const autoUpdateCalloutPosition = () => {
72
56
  cleanupAutoUpdate();
57
+ cleanupAutoUpdate = () => { };
73
58
  if (reference && popupRef) {
74
59
  cleanupAutoUpdate = autoUpdate(reference, popupRef, computeCalloutPosition);
75
60
  }
76
61
  };
77
- $: popupRef, reference, autoUpdateCalloutPosition();
78
- $: open, bodyHeight, middleware, placement, computeCalloutPosition();
62
+ $effect(() => {
63
+ autoUpdateCalloutPosition();
64
+ return () => {
65
+ cleanupAutoUpdate();
66
+ cleanupAutoUpdate = () => { };
67
+ };
68
+ });
69
+ $effect(() => {
70
+ bodyHeight;
71
+ reference;
72
+ computeCalloutPosition();
73
+ });
79
74
  // ----- Arrow ----- //
80
75
  const getArrowPlacementStyle = (position) => {
81
76
  if (position?.placement && arrowRef) {
@@ -83,9 +78,7 @@ const getArrowPlacementStyle = (position) => {
83
78
  case 'top':
84
79
  case 'top-start':
85
80
  case 'top-end':
86
- return (`bottom: -${arrowRef.offsetWidth}px;` +
87
- `filter: drop-shadow(-1px -2px 1px rgba(0,0,0,0.2));` +
88
- `transform:translate(0, -50%) rotate(135deg);`);
81
+ return (`bottom: -${arrowRef.offsetWidth}px;` + `transform:translate(0, -50%) rotate(135deg);`);
89
82
  case 'right':
90
83
  case 'right-start':
91
84
  case 'right-end':
@@ -97,9 +90,7 @@ const getArrowPlacementStyle = (position) => {
97
90
  case 'left':
98
91
  case 'left-start':
99
92
  case 'left-end':
100
- return (`right: -${arrowRef.offsetWidth}px;` +
101
- `filter: drop-shadow(2px 2px 1px rgba(0,0,0,0.2));` +
102
- `transform:translate(-50%, 0) rotate(45deg);`);
93
+ return (`right: -${arrowRef.offsetWidth}px;` + `transform:translate(-50%, 0) rotate(45deg);`);
103
94
  }
104
95
  }
105
96
  return '';
@@ -116,14 +107,20 @@ const getArrowOffsetStyle = (position) => {
116
107
  }
117
108
  return '';
118
109
  };
119
- $: arrowStyle = getArrowPlacementStyle(popupPosition) + getArrowOffsetStyle(popupPosition);
110
+ let arrowStyle = $derived(getArrowPlacementStyle(popupPosition) + getArrowOffsetStyle(popupPosition));
120
111
  // ----- Animation ----- //
121
112
  const fadeNoOp = (node, params) => {
122
113
  return { delay: 0, duration: 0 };
123
114
  };
124
- $: fadeMotion = !$prefersReducedMotion ? fade : fadeNoOp;
115
+ let fadeMotion = $derived(!$prefersReducedMotion ? fade : fadeNoOp);
125
116
  // ----- EventHandlers ----- //
126
- onMount(() => {
117
+ const onKeydown = (event) => {
118
+ if (event.key === 'Escape') {
119
+ open = false;
120
+ }
121
+ rest.onkeydown?.(event);
122
+ };
123
+ $effect(() => {
127
124
  ensurePortalHost();
128
125
  resizeObserver = new ResizeObserver((entries) => {
129
126
  bodyHeight = entries[0].target.clientHeight;
@@ -136,11 +133,6 @@ onMount(() => {
136
133
  resizeObserver = undefined;
137
134
  };
138
135
  });
139
- const onKeydown = (event) => {
140
- if (event.key === 'Escape') {
141
- open = false;
142
- }
143
- };
144
136
  ensurePortalHost();
145
137
  </script>
146
138
 
@@ -150,45 +142,36 @@ ensurePortalHost();
150
142
  class="sterling-callout-portal"
151
143
  transition:fadeMotion|global={{ duration: 250 }}
152
144
  >
153
- <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
145
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
154
146
  <div
155
147
  bind:this={popupRef}
156
- class={`sterling-callout ${variant}`}
148
+ class={['sterling-callout', _class].filter(Boolean).join(' ')}
157
149
  class:open
150
+ class:top={popupPosition.placement === 'top'}
151
+ class:top-start={popupPosition.placement === 'top-start'}
152
+ class:top-end={popupPosition.placement === 'top-end'}
153
+ class:right={popupPosition.placement === 'right'}
154
+ class:right-start={popupPosition.placement === 'right-start'}
155
+ class:right-end={popupPosition.placement === 'right-end'}
156
+ class:bottom={popupPosition.placement === 'bottom'}
157
+ class:bottom-start={popupPosition.placement === 'bottom-start'}
158
+ class:bottom-end={popupPosition.placement === 'bottom-end'}
159
+ class:left={popupPosition.placement === 'left'}
160
+ class:left-start={popupPosition.placement === 'left-start'}
161
+ class:left-end={popupPosition.placement === 'left-end'}
158
162
  role="tooltip"
159
- on:blur
160
- on:click
161
- on:copy
162
- on:cut
163
- on:dblclick
164
- on:dragend
165
- on:dragenter
166
- on:dragleave
167
- on:dragover
168
- on:dragstart
169
- on:drop
170
- on:focus
171
- on:focusin
172
- on:focusout
173
- on:keydown
174
- on:keypress
175
- on:keyup
176
- on:mousedown
177
- on:mouseenter
178
- on:mouseleave
179
- on:mousemove
180
- on:mouseover
181
- on:mouseout
182
- on:mouseup
183
- on:scroll
184
- on:wheel|passive
185
- on:paste
186
- on:keydown={onKeydown}
187
- {...$$restProps}
163
+ {...rest}
164
+ onkeydown={onKeydown}
188
165
  style="left:{popupPosition.x}px; top:{popupPosition.y}px"
189
166
  >
190
- <slot />
191
- <div class="arrow" bind:this={arrowRef} style={arrowStyle} />
167
+ {#if children}
168
+ {#if typeof children === 'string'}
169
+ <div class="callout-text">{children}</div>
170
+ {:else}
171
+ {@render children()}
172
+ {/if}
173
+ {/if}
174
+ <div class="arrow" bind:this={arrowRef} style={arrowStyle}></div>
192
175
  </div>
193
176
  </div>
194
177
  {/if}
@@ -0,0 +1,15 @@
1
+ /// <reference types="svelte" />
2
+ import type { PopoverPlacement } from './Popover.types';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ type Props = HTMLAttributes<HTMLDivElement> & {
5
+ conditionalRender?: boolean | null;
6
+ crossAxisOffset?: number;
7
+ mainAxisOffset?: number;
8
+ open?: boolean | null;
9
+ placement?: PopoverPlacement;
10
+ portalHost?: HTMLElement;
11
+ reference?: HTMLElement | null;
12
+ };
13
+ declare const Callout: import("svelte").Component<Props, {}, "conditionalRender" | "crossAxisOffset" | "mainAxisOffset" | "open" | "placement">;
14
+ type Callout = ReturnType<typeof Callout>;
15
+ export default Callout;
@@ -0,0 +1,11 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import type { PopoverPlacement } from './Popover.types';
3
+ export type CalloutProps = HTMLAttributes<HTMLDivElement> & {
4
+ conditionalRender?: boolean | null;
5
+ crossAxisOffset?: number;
6
+ mainAxisOffset?: number;
7
+ open?: boolean | null;
8
+ placement?: PopoverPlacement;
9
+ portalHost?: HTMLElement;
10
+ reference?: HTMLElement | null;
11
+ };
@@ -0,0 +1,43 @@
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 = $bindable(false), ...rest } = $props();
6
+ let inputRef;
7
+ $effect(() => {
8
+ if (children && id === undefined) {
9
+ id = idGenerator.nextId('Checkbox');
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
+ </script>
23
+
24
+ <!--
25
+ @component
26
+ A styled HTML input type=checkbox element.
27
+ -->
28
+ <div
29
+ class={['sterling-checkbox', _class].filter(Boolean).join(' ')}
30
+ class:checked
31
+ class:disabled
32
+ class:using-keyboard={$usingKeyboard}
33
+ >
34
+ <div class="container">
35
+ <input bind:this={inputRef} bind:checked {disabled} {id} type="checkbox" {...rest} />
36
+ <div class="indicator"></div>
37
+ </div>
38
+ {#if children}
39
+ <label for={id}>
40
+ {@render children()}
41
+ </label>
42
+ {/if}
43
+ </div>
@@ -0,0 +1,10 @@
1
+ /// <reference types="svelte" />
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ /** A styled HTML input type=checkbox element. */
4
+ declare const Checkbox: import("svelte").Component<HTMLInputAttributes, {
5
+ blur: () => void;
6
+ click: () => void;
7
+ focus: (options?: FocusOptions) => void;
8
+ }, "disabled" | "checked">;
9
+ type Checkbox = ReturnType<typeof Checkbox>;
10
+ export default Checkbox;
@@ -1,25 +1,15 @@
1
- <script>import { onMount, setContext, tick } from 'svelte';
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import { onMount, setContext, tick } from 'svelte';
2
4
  import Button from './Button.svelte';
3
5
  import { STERLING_PORTAL_CONTEXT_ID } from './Portal.constants';
4
6
  import { writable } from 'svelte/store';
5
7
  const dialogFadeDuration = 250;
6
- // ----- Props ----- //
7
- /** When true, clicking outside the dialog causes the dialog close. */
8
- export let backdropCloses = false;
9
- /** When true, the dialog is open; otherwise the dialog is closed. */
10
- export let open = false;
11
- /**
12
- * The return value from the dialog:
13
- * - an empty string indicates cancellation
14
- * - a value indicates form submission.
15
- */
16
- export let returnValue = '';
17
- /** Additional class names to apply. */
18
- export let variant = '';
19
- // ----- State ----- //
8
+ let { backdropCloses = false, open = $bindable(false), body, class: _class, content, footer, header, returnValue = $bindable(''), headerTitle, ...rest } = $props();
20
9
  let dialogRef;
21
10
  let contentRef;
22
11
  let formRef;
12
+ // svelte-ignore non_reactive_update
23
13
  let closing = false;
24
14
  const portalHostStore = writable(undefined);
25
15
  // ----- Context ----- //
@@ -101,9 +91,9 @@ const onSubmit = (event) => {
101
91
  return false;
102
92
  }
103
93
  };
104
- $: {
94
+ $effect(() => {
105
95
  updateDialog(open);
106
- }
96
+ });
107
97
  onMount(() => {
108
98
  updateDialog(open);
109
99
  // Use the dialog for any element portals
@@ -116,44 +106,46 @@ onMount(() => {
116
106
  });
117
107
  </script>
118
108
 
119
- <!-- @component
120
- A styled &lt;dialog&gt; element
121
-
122
- - Slots for typical dialog content.
123
- - Props and events to make using &lt;dialog&gt; easier
124
- -->
125
109
  <dialog
126
110
  bind:this={dialogRef}
127
- class={`sterling-dialog ${variant}`}
111
+ class={`sterling-dialog ${_class}`}
128
112
  class:open
129
113
  class:closing
130
- on:close
131
- on:cancel
132
- {...$$restProps}
114
+ {...rest}
133
115
  >
134
- <form method="dialog" bind:this={formRef} on:submit={onSubmit}>
116
+ <form method="dialog" bind:this={formRef} onsubmit={onSubmit}>
135
117
  <div class="content" bind:this={contentRef}>
136
- <slot name="content">
118
+ {#if content}
119
+ {@render content()}
120
+ {:else}
137
121
  <div class="header">
138
- <slot name="header">
122
+ {#if header}
123
+ {@render header()}
124
+ {:else}
139
125
  <div class="title">
140
- <slot name="title" />
126
+ {#if headerTitle}
127
+ {#if typeof headerTitle === 'string'}
128
+ {headerTitle}
129
+ {:else}
130
+ {@render headerTitle()}
131
+ {/if}
132
+ {/if}
141
133
  </div>
142
134
  <div class="close">
143
- <Button variant={`circular tool ${variant}`} on:click={() => closeDialog()}>
144
- <div class="close-x" />
135
+ <Button class={`circular tool`} onclick={() => closeDialog()}>
136
+ <div class="close-x"></div>
145
137
  </Button>
146
138
  </div>
147
- </slot>
139
+ {/if}
148
140
  </div>
149
141
  <div class="body">
150
- <slot name="body" />
142
+ {@render body?.()}
151
143
  </div>
152
- <div class="separator" />
144
+ <div class="separator"></div>
153
145
  <div class="footer">
154
- <slot name="footer" />
146
+ {@render footer?.()}
155
147
  </div>
156
- </slot>
148
+ {/if}
157
149
  </div>
158
150
  </form>
159
151
  </dialog>
@@ -0,0 +1,14 @@
1
+ import type { HTMLDialogAttributes } from 'svelte/elements';
2
+ import { type Snippet } from 'svelte';
3
+ type Props = HTMLDialogAttributes & {
4
+ backdropCloses?: boolean | null | undefined;
5
+ body?: Snippet;
6
+ content?: Snippet;
7
+ footer?: Snippet;
8
+ header?: Snippet;
9
+ returnValue?: string;
10
+ headerTitle?: string | Snippet;
11
+ };
12
+ declare const Dialog: import("svelte").Component<Props, {}, "open" | "returnValue">;
13
+ type Dialog = ReturnType<typeof Dialog>;
14
+ export default Dialog;
@@ -0,0 +1,109 @@
1
+ <svelte:options runes={true} />
2
+
3
+ <script lang="ts">import {} from 'svelte';
4
+ import Popover from './Popover.svelte';
5
+ import { clickOutside } from './actions/clickOutside';
6
+ import { idGenerator } from './idGenerator';
7
+ import { prefersReducedMotion } from './mediaQueries/prefersReducedMotion';
8
+ import { slide } from 'svelte/transition';
9
+ import { usingKeyboard } from './mediaQueries/usingKeyboard';
10
+ const popupId = idGenerator.nextId('Dropdown-popup');
11
+ let { class: _class, children, disabled = false, open = $bindable(false), onOpen, stayOpenOnClickAway = false, button, buttonIcon, value, ...rest } = $props();
12
+ // svelte-ignore non_reactive_update
13
+ let dropdownRef = $state(undefined);
14
+ // svelte-ignore non_reactive_update
15
+ let popupContentRef = $state(undefined);
16
+ // ----- Reactions ----- //
17
+ $effect(() => {
18
+ onOpen?.(open);
19
+ });
20
+ // ----- Methods ----- //
21
+ export const click = () => {
22
+ dropdownRef?.click();
23
+ };
24
+ export const blur = () => {
25
+ dropdownRef?.blur();
26
+ };
27
+ export const focus = (options) => {
28
+ dropdownRef?.focus(options);
29
+ };
30
+ const onClick = (event) => {
31
+ if (!disabled) {
32
+ open = !open;
33
+ event.preventDefault();
34
+ event.stopPropagation();
35
+ }
36
+ rest.onclick?.(event);
37
+ };
38
+ const onKeydown = (event) => {
39
+ if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
40
+ switch (event.key) {
41
+ case ' ':
42
+ open = !open;
43
+ event.preventDefault();
44
+ event.stopPropagation();
45
+ case 'Escape':
46
+ open = false;
47
+ event.preventDefault();
48
+ event.stopPropagation();
49
+ }
50
+ }
51
+ rest.onkeydown?.(event);
52
+ };
53
+ const onClickOutside = (event) => {
54
+ if (!stayOpenOnClickAway) {
55
+ open = false;
56
+ }
57
+ };
58
+ // ----- Animation ----- //
59
+ const slideNoOp = (node, params) => {
60
+ return { delay: 0, duration: 0 };
61
+ };
62
+ let slideMotion = $derived(!$prefersReducedMotion ? slide : slideNoOp);
63
+ </script>
64
+
65
+ <div
66
+ bind:this={dropdownRef}
67
+ aria-controls={popupId}
68
+ aria-haspopup={true}
69
+ aria-expanded={open}
70
+ class={`sterling-dropdown ${_class}`}
71
+ class:disabled
72
+ class:open
73
+ class:using-keyboard={$usingKeyboard}
74
+ role="combobox"
75
+ tabindex="0"
76
+ use:clickOutside={{ ignoreOthers: [popupContentRef!], onclickoutside: onClickOutside }}
77
+ {...rest}
78
+ onclick={onClick}
79
+ onkeydown={onKeydown}
80
+ >
81
+ <div class="value">
82
+ {#if value}
83
+ {#if typeof value === 'string'}
84
+ {value}
85
+ {:else}
86
+ {@render value()}
87
+ {/if}
88
+ {/if}
89
+ </div>
90
+ <div class="button">
91
+ {#if button}
92
+ {@render button()}
93
+ {:else if buttonIcon}
94
+ {@render buttonIcon()}
95
+ {:else}
96
+ <div class="chevron"></div>
97
+ {/if}
98
+ </div>
99
+
100
+ <Popover reference={dropdownRef} open={!disabled && open} placement="bottom-start">
101
+ <div
102
+ class={`sterling-dropdown-popup-content ${_class}`}
103
+ transition:slideMotion|global={{ duration: 200 }}
104
+ bind:this={popupContentRef}
105
+ >
106
+ {@render children?.()}
107
+ </div>
108
+ </Popover>
109
+ </div>
@@ -0,0 +1,18 @@
1
+ import { type Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement> & {
4
+ disabled?: boolean | null | undefined;
5
+ open?: boolean | null | undefined;
6
+ stayOpenOnClickAway?: boolean | null | undefined;
7
+ onOpen?: (open: boolean | null | undefined) => void;
8
+ button?: Snippet;
9
+ buttonIcon?: Snippet;
10
+ value?: string | Snippet;
11
+ };
12
+ declare const Dropdown: import("svelte").Component<Props, {
13
+ click: () => void;
14
+ blur: () => void;
15
+ focus: (options?: FocusOptions) => void;
16
+ }, "open">;
17
+ type Dropdown = ReturnType<typeof Dropdown>;
18
+ export default Dropdown;
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;