@pzerelles/headlessui-svelte 2.0.0-next.1 → 2.1.2-next.2

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 (275) hide show
  1. package/dist/button/Button.svelte +61 -0
  2. package/dist/button/Button.svelte.d.ts +47 -0
  3. package/dist/button/index.d.ts +1 -0
  4. package/dist/button/index.js +1 -0
  5. package/dist/checkbox/Checkbox.svelte +93 -61
  6. package/dist/checkbox/Checkbox.svelte.d.ts +45 -29
  7. package/dist/close-button/CloseButton.svelte +11 -0
  8. package/dist/close-button/CloseButton.svelte.d.ts +48 -0
  9. package/dist/close-button/index.d.ts +1 -0
  10. package/dist/close-button/index.js +1 -0
  11. package/dist/combobox/Combobox.svelte +6 -0
  12. package/dist/combobox/Combobox.svelte.d.ts +50 -0
  13. package/dist/data-interactive/DataInteractive.svelte +41 -0
  14. package/dist/data-interactive/DataInteractive.svelte.d.ts +39 -0
  15. package/dist/data-interactive/index.d.ts +1 -0
  16. package/dist/data-interactive/index.js +1 -0
  17. package/dist/description/Description.svelte +16 -41
  18. package/dist/description/Description.svelte.d.ts +15 -23
  19. package/dist/description/context.svelte.d.ts +17 -0
  20. package/dist/description/context.svelte.js +51 -0
  21. package/dist/dialog/Dialog.svelte +51 -0
  22. package/dist/dialog/Dialog.svelte.d.ts +60 -0
  23. package/dist/dialog/DialogBackdrop.svelte +39 -0
  24. package/dist/dialog/DialogBackdrop.svelte.d.ts +38 -0
  25. package/dist/dialog/DialogPanel.svelte +46 -0
  26. package/dist/dialog/DialogPanel.svelte.d.ts +40 -0
  27. package/dist/dialog/DialogTitle.svelte +29 -0
  28. package/dist/dialog/DialogTitle.svelte.d.ts +34 -0
  29. package/dist/dialog/InternalDialog.svelte +233 -0
  30. package/dist/dialog/InternalDialog.svelte.d.ts +42 -0
  31. package/dist/dialog/context.svelte.d.ts +15 -0
  32. package/dist/dialog/context.svelte.js +16 -0
  33. package/dist/dialog/index.d.ts +4 -0
  34. package/dist/dialog/index.js +4 -0
  35. package/dist/field/Field.svelte +14 -16
  36. package/dist/field/Field.svelte.d.ts +21 -17
  37. package/dist/fieldset/Fieldset.svelte +19 -17
  38. package/dist/fieldset/Fieldset.svelte.d.ts +21 -17
  39. package/dist/focus-trap/FocusTrap.svelte +332 -0
  40. package/dist/focus-trap/FocusTrap.svelte.d.ts +58 -0
  41. package/dist/hooks/document-overflow/adjust-scrollbar-padding.d.ts +2 -0
  42. package/dist/hooks/document-overflow/adjust-scrollbar-padding.js +18 -0
  43. package/dist/hooks/document-overflow/handle-ios-locking.d.ts +6 -0
  44. package/dist/hooks/document-overflow/handle-ios-locking.js +134 -0
  45. package/dist/hooks/document-overflow/overflow-store.d.ts +19 -0
  46. package/dist/hooks/document-overflow/overflow-store.js +76 -0
  47. package/dist/hooks/document-overflow/prevent-scroll.d.ts +2 -0
  48. package/dist/hooks/document-overflow/prevent-scroll.js +7 -0
  49. package/dist/hooks/document-overflow/use-document-overflow.svelte.d.ts +7 -0
  50. package/dist/hooks/document-overflow/use-document-overflow.svelte.js +27 -0
  51. package/dist/hooks/use-active-press.svelte.d.ts +14 -0
  52. package/dist/{actions/activePress.svelte.js → hooks/use-active-press.svelte.js} +33 -39
  53. package/dist/hooks/use-by-comparator.d.ts +2 -0
  54. package/dist/hooks/use-by-comparator.js +15 -0
  55. package/dist/hooks/use-controllable.svelte.d.ts +6 -0
  56. package/dist/hooks/use-controllable.svelte.js +34 -0
  57. package/dist/hooks/use-did-element-move.svelte.d.ts +6 -0
  58. package/dist/hooks/use-did-element-move.svelte.js +27 -0
  59. package/dist/hooks/use-disabled.d.ts +3 -0
  60. package/dist/hooks/use-disabled.js +9 -0
  61. package/dist/hooks/use-element-size.svelte.d.ts +7 -0
  62. package/dist/hooks/use-element-size.svelte.js +36 -0
  63. package/dist/hooks/use-escape.svelte.d.ts +5 -0
  64. package/dist/hooks/use-escape.svelte.js +26 -0
  65. package/dist/hooks/use-event-listener.svelte.d.ts +6 -0
  66. package/dist/hooks/use-event-listener.svelte.js +12 -0
  67. package/dist/hooks/use-flags.svelte.d.ts +8 -0
  68. package/dist/hooks/use-flags.svelte.js +18 -0
  69. package/dist/hooks/use-focus-ring.svelte.d.ts +10 -0
  70. package/dist/hooks/use-focus-ring.svelte.js +24 -0
  71. package/dist/hooks/use-hover.svelte.d.ts +26 -0
  72. package/dist/hooks/use-hover.svelte.js +124 -0
  73. package/dist/hooks/use-id.d.ts +1 -0
  74. package/dist/hooks/use-id.js +1 -0
  75. package/dist/hooks/use-inert-others.svelte.d.ts +32 -0
  76. package/dist/hooks/use-inert-others.svelte.js +114 -0
  77. package/dist/hooks/use-is-mounted.svelte.d.ts +3 -0
  78. package/dist/hooks/use-is-mounted.svelte.js +14 -0
  79. package/dist/hooks/use-is-top-layer.svelte.d.ts +29 -0
  80. package/dist/hooks/use-is-top-layer.svelte.js +82 -0
  81. package/dist/hooks/use-is-touch-device.svelte.d.ts +3 -0
  82. package/dist/hooks/use-is-touch-device.svelte.js +20 -0
  83. package/dist/hooks/use-on-disappear.svelte.d.ts +12 -0
  84. package/dist/hooks/use-on-disappear.svelte.js +38 -0
  85. package/dist/hooks/use-outside-click.svelte.d.ts +10 -0
  86. package/dist/hooks/use-outside-click.svelte.js +150 -0
  87. package/dist/hooks/use-reducer.d.ts +4 -0
  88. package/dist/hooks/use-reducer.js +11 -0
  89. package/dist/hooks/use-resolve-button-type.svelte.d.ts +10 -0
  90. package/dist/hooks/use-resolve-button-type.svelte.js +19 -0
  91. package/dist/hooks/use-root-containers.svelte.d.ts +9 -0
  92. package/dist/hooks/use-root-containers.svelte.js +50 -0
  93. package/dist/hooks/use-scroll-lock.svelte.d.ts +5 -0
  94. package/dist/hooks/use-scroll-lock.svelte.js +24 -0
  95. package/dist/hooks/use-sync-refs.d.ts +7 -0
  96. package/dist/hooks/use-sync-refs.js +22 -0
  97. package/dist/hooks/use-tab-direction.svelte.d.ts +7 -0
  98. package/dist/hooks/use-tab-direction.svelte.js +25 -0
  99. package/dist/hooks/use-text-value.svelte.d.ts +3 -0
  100. package/dist/hooks/use-text-value.svelte.js +20 -0
  101. package/dist/hooks/use-tracked-pointer.d.ts +4 -0
  102. package/dist/hooks/use-tracked-pointer.js +26 -0
  103. package/dist/hooks/use-transition.svelte.d.ts +20 -0
  104. package/dist/hooks/use-transition.svelte.js +253 -0
  105. package/dist/hooks/use-tree-walker.svelte.d.ts +8 -0
  106. package/dist/hooks/use-tree-walker.svelte.js +19 -0
  107. package/dist/hooks/use-watch.svelte.d.ts +4 -0
  108. package/dist/hooks/use-watch.svelte.js +16 -0
  109. package/dist/hooks/use-window-event.svelte.d.ts +6 -0
  110. package/dist/hooks/use-window-event.svelte.js +12 -0
  111. package/dist/index.d.ts +13 -0
  112. package/dist/index.js +13 -0
  113. package/dist/input/Input.svelte +59 -0
  114. package/dist/input/Input.svelte.d.ts +52 -0
  115. package/dist/input/index.d.ts +1 -0
  116. package/dist/input/index.js +1 -0
  117. package/dist/internal/FocusSentinel.svelte +45 -0
  118. package/dist/internal/FocusSentinel.svelte.d.ts +20 -0
  119. package/dist/internal/ForcePortalRoot.svelte +6 -0
  120. package/dist/internal/ForcePortalRoot.svelte.d.ts +22 -0
  121. package/dist/internal/FormFields.svelte +2 -4
  122. package/dist/internal/FormFields.svelte.d.ts +9 -7
  123. package/dist/internal/FormResolver.svelte +11 -16
  124. package/dist/internal/FormResolver.svelte.d.ts +6 -4
  125. package/dist/internal/Hidden.svelte +5 -9
  126. package/dist/internal/Hidden.svelte.d.ts +35 -19
  127. package/dist/internal/HoistFormFields.svelte.d.ts +5 -2
  128. package/dist/internal/MainTreeProvider.svelte +45 -0
  129. package/dist/internal/MainTreeProvider.svelte.d.ts +31 -0
  130. package/dist/internal/Portal.svelte.d.ts +5 -2
  131. package/dist/internal/close-provider.d.ts +7 -0
  132. package/dist/internal/close-provider.js +7 -0
  133. package/dist/internal/floating.svelte.d.ts +62 -0
  134. package/dist/internal/floating.svelte.js +488 -0
  135. package/dist/internal/frozen.svelte.d.ts +6 -0
  136. package/dist/internal/frozen.svelte.js +18 -0
  137. package/dist/internal/id.d.ts +8 -0
  138. package/dist/internal/id.js +11 -0
  139. package/dist/internal/open-closed.d.ts +14 -0
  140. package/dist/internal/open-closed.js +17 -0
  141. package/dist/internal/portal-force-root.svelte.d.ts +6 -0
  142. package/dist/internal/portal-force-root.svelte.js +11 -0
  143. package/dist/label/Label.svelte +17 -45
  144. package/dist/label/Label.svelte.d.ts +19 -23
  145. package/dist/label/context.svelte.d.ts +17 -0
  146. package/dist/label/context.svelte.js +56 -0
  147. package/dist/legend/Legend.svelte +4 -3
  148. package/dist/legend/Legend.svelte.d.ts +33 -16
  149. package/dist/listbox/Listbox.svelte +448 -0
  150. package/dist/listbox/Listbox.svelte.d.ts +126 -0
  151. package/dist/listbox/ListboxButton.svelte +139 -0
  152. package/dist/listbox/ListboxButton.svelte.d.ts +52 -0
  153. package/dist/listbox/ListboxOption.svelte +136 -0
  154. package/dist/listbox/ListboxOption.svelte.d.ts +50 -0
  155. package/dist/listbox/ListboxOptions.svelte +269 -0
  156. package/dist/listbox/ListboxOptions.svelte.d.ts +55 -0
  157. package/dist/listbox/ListboxSelectedOption.svelte +35 -0
  158. package/dist/listbox/ListboxSelectedOption.svelte.d.ts +40 -0
  159. package/dist/listbox/index.d.ts +5 -0
  160. package/dist/listbox/index.js +5 -0
  161. package/dist/menu/Menu.svelte +235 -0
  162. package/dist/menu/Menu.svelte.d.ts +42 -0
  163. package/dist/menu/MenuButton.svelte +127 -0
  164. package/dist/menu/MenuButton.svelte.d.ts +52 -0
  165. package/dist/menu/MenuHeading.svelte +19 -0
  166. package/dist/menu/MenuHeading.svelte.d.ts +39 -0
  167. package/dist/menu/MenuItem.svelte +114 -0
  168. package/dist/menu/MenuItem.svelte.d.ts +49 -0
  169. package/dist/menu/MenuItems.svelte +244 -0
  170. package/dist/menu/MenuItems.svelte.d.ts +55 -0
  171. package/dist/menu/MenuSection.svelte +14 -0
  172. package/dist/menu/MenuSection.svelte.d.ts +35 -0
  173. package/dist/menu/MenuSeparator.svelte +9 -0
  174. package/dist/menu/MenuSeparator.svelte.d.ts +35 -0
  175. package/dist/menu/context.svelte.d.ts +47 -0
  176. package/dist/menu/context.svelte.js +21 -0
  177. package/dist/menu/index.d.ts +7 -0
  178. package/dist/menu/index.js +7 -0
  179. package/dist/portal/InternalPortal.svelte +97 -0
  180. package/dist/portal/InternalPortal.svelte.d.ts +43 -0
  181. package/dist/portal/Portal.svelte +7 -0
  182. package/dist/portal/Portal.svelte.d.ts +23 -0
  183. package/dist/portal/PortalGroup.svelte +14 -0
  184. package/dist/portal/PortalGroup.svelte.d.ts +40 -0
  185. package/dist/switch/Switch.svelte +143 -0
  186. package/dist/switch/Switch.svelte.d.ts +61 -0
  187. package/dist/switch/SwitchGroup.svelte +37 -0
  188. package/dist/switch/SwitchGroup.svelte.d.ts +34 -0
  189. package/dist/switch/index.d.ts +2 -0
  190. package/dist/switch/index.js +2 -0
  191. package/dist/tabs/Tab.svelte +156 -0
  192. package/dist/tabs/Tab.svelte.d.ts +48 -0
  193. package/dist/tabs/TabGroup.svelte +241 -0
  194. package/dist/tabs/TabGroup.svelte.d.ts +67 -0
  195. package/dist/tabs/TabList.svelte +16 -0
  196. package/dist/tabs/TabList.svelte.d.ts +35 -0
  197. package/dist/tabs/TabPanel.svelte +61 -0
  198. package/dist/tabs/TabPanel.svelte.d.ts +47 -0
  199. package/dist/tabs/TabPanels.svelte +12 -0
  200. package/dist/tabs/TabPanels.svelte.d.ts +34 -0
  201. package/dist/tabs/index.d.ts +5 -0
  202. package/dist/tabs/index.js +5 -0
  203. package/dist/test-utils/accessability-assertions.d.ts +271 -0
  204. package/dist/test-utils/accessability-assertions.js +1572 -0
  205. package/dist/test-utils/fake-pointer.d.ts +24 -0
  206. package/dist/test-utils/fake-pointer.js +48 -0
  207. package/dist/test-utils/interactions.d.ts +61 -0
  208. package/dist/test-utils/interactions.js +453 -0
  209. package/dist/test-utils/suppress-console-logs.d.ts +7 -0
  210. package/dist/test-utils/suppress-console-logs.js +17 -0
  211. package/dist/transition/InternalTransitionChild.svelte +178 -0
  212. package/dist/transition/InternalTransitionChild.svelte.d.ts +55 -0
  213. package/dist/transition/Transition.svelte +89 -0
  214. package/dist/transition/Transition.svelte.d.ts +42 -0
  215. package/dist/transition/TransitionChild.svelte +16 -0
  216. package/dist/transition/TransitionChild.svelte.d.ts +44 -0
  217. package/dist/transition/context.svelte.d.ts +64 -0
  218. package/dist/transition/context.svelte.js +120 -0
  219. package/dist/transition/index.d.ts +2 -0
  220. package/dist/transition/index.js +2 -0
  221. package/dist/utils/ElementOrComponent.svelte +26 -0
  222. package/dist/utils/ElementOrComponent.svelte.d.ts +56 -0
  223. package/dist/utils/Generic.svelte +44 -0
  224. package/dist/utils/Generic.svelte.d.ts +35 -0
  225. package/dist/utils/StableCollection.svelte +43 -0
  226. package/dist/utils/StableCollection.svelte.d.ts +22 -0
  227. package/dist/utils/active-element-history.d.ts +1 -0
  228. package/dist/utils/active-element-history.js +35 -0
  229. package/dist/utils/alternative-types.d.ts +21 -0
  230. package/dist/utils/alternative-types.js +1 -0
  231. package/dist/utils/calculate-active-index.d.ts +25 -0
  232. package/dist/utils/calculate-active-index.js +74 -0
  233. package/dist/utils/class-names.d.ts +1 -0
  234. package/dist/utils/class-names.js +10 -0
  235. package/dist/utils/default-map.d.ts +5 -0
  236. package/dist/utils/default-map.js +15 -0
  237. package/dist/utils/disposables.d.ts +14 -12
  238. package/dist/utils/disposables.js +13 -10
  239. package/dist/utils/dom.d.ts +0 -2
  240. package/dist/utils/dom.js +2 -4
  241. package/dist/utils/env.d.ts +17 -0
  242. package/dist/utils/env.js +39 -0
  243. package/dist/utils/focus-management.d.ts +45 -0
  244. package/dist/utils/focus-management.js +242 -0
  245. package/dist/utils/focusVisible.svelte.d.ts +3 -3
  246. package/dist/utils/focusVisible.svelte.js +52 -41
  247. package/dist/utils/get-text-value.d.ts +1 -0
  248. package/dist/utils/get-text-value.js +71 -0
  249. package/dist/utils/id.d.ts +1 -1
  250. package/dist/utils/match.d.ts +1 -0
  251. package/dist/utils/match.js +13 -0
  252. package/dist/utils/on-document-ready.d.ts +1 -0
  253. package/dist/utils/on-document-ready.js +12 -0
  254. package/dist/utils/once.d.ts +1 -0
  255. package/dist/utils/once.js +9 -0
  256. package/dist/utils/owner.d.ts +1 -0
  257. package/dist/utils/owner.js +8 -0
  258. package/dist/utils/platform.d.ts +2 -0
  259. package/dist/utils/platform.js +17 -0
  260. package/dist/utils/ref.svelte.d.ts +4 -0
  261. package/dist/utils/ref.svelte.js +4 -0
  262. package/dist/utils/render.d.ts +34 -0
  263. package/dist/utils/render.js +119 -0
  264. package/dist/utils/state.d.ts +7 -1
  265. package/dist/utils/state.js +10 -6
  266. package/dist/utils/store.d.ts +11 -0
  267. package/dist/utils/store.js +20 -0
  268. package/dist/utils/types.d.ts +24 -0
  269. package/dist/utils/types.js +1 -0
  270. package/package.json +33 -25
  271. package/dist/actions/activePress.svelte.d.ts +0 -8
  272. package/dist/actions/focusRing.svelte.d.ts +0 -9
  273. package/dist/actions/focusRing.svelte.js +0 -34
  274. package/dist/utils/disabled.d.ts +0 -3
  275. package/dist/utils/disabled.js +0 -2
@@ -0,0 +1,27 @@
1
+ import { overflows } from "./overflow-store.js";
2
+ export function useDocumentOverflowLockedEffect(options) {
3
+ const { shouldBeLocked, doc, meta = () => ({ containers: [] }) } = $derived(options);
4
+ let store = $state(overflows.getSnapshot());
5
+ $effect(() => {
6
+ const unsubscribe = overflows.subscribe(() => {
7
+ store = overflows.getSnapshot();
8
+ });
9
+ return unsubscribe;
10
+ });
11
+ const entry = $derived(doc ? store.get(doc) : undefined);
12
+ const locked = $derived(entry ? entry.count > 0 : false);
13
+ $effect(() => {
14
+ if (!doc || !shouldBeLocked) {
15
+ return;
16
+ }
17
+ // Prevent the document from scrolling
18
+ overflows.dispatch("PUSH", doc, meta);
19
+ // Allow document to scroll
20
+ return () => overflows.dispatch("POP", doc, meta);
21
+ });
22
+ return {
23
+ get locked() {
24
+ return locked;
25
+ },
26
+ };
27
+ }
@@ -0,0 +1,14 @@
1
+ export declare const useActivePress: (options: {
2
+ disabled?: boolean;
3
+ }) => {
4
+ readonly pressed: boolean;
5
+ readonly pressProps: {
6
+ onpointerdown?: undefined;
7
+ onpointerup?: undefined;
8
+ onclick?: undefined;
9
+ } | {
10
+ onpointerdown: (event: PointerEvent) => void;
11
+ onpointerup: () => void;
12
+ onclick: () => void;
13
+ };
14
+ };
@@ -1,9 +1,9 @@
1
1
  import { disposables } from "../utils/disposables.js";
2
- import { getOwnerDocument } from "../utils/dom.js";
2
+ import { getOwnerDocument } from "../utils/owner.js";
3
3
  function pointerRectFromPointerEvent(event) {
4
4
  // Center of the pointer geometry
5
- let offsetX = event.width / 2;
6
- let offsetY = event.height / 2;
5
+ const offsetX = event.width / 2;
6
+ const offsetY = event.height / 2;
7
7
  return {
8
8
  top: event.clientY - offsetY,
9
9
  right: event.clientX + offsetX,
@@ -23,27 +23,28 @@ function areRectsOverlapping(a, b) {
23
23
  }
24
24
  return true;
25
25
  }
26
- export const createActivePress = ({ disabled }) => {
26
+ export const useActivePress = (options) => {
27
+ const { disabled } = $derived(options);
27
28
  let currentTarget = $state(null);
28
29
  let pressed = $state(false);
29
- const activePressAction = (node) => {
30
- const d = disposables();
31
- const reset = () => {
32
- currentTarget = null;
33
- pressed = false;
34
- d.dispose();
35
- };
36
- const handlePointerDown = (event) => {
37
- d.dispose(); // Cancel any scheduled tasks
38
- if (currentTarget !== null)
39
- return;
40
- // Keep track of the current element
41
- currentTarget = event.currentTarget;
42
- // We are definitely pressing the element now
43
- pressed = true;
44
- // Setup global handlers to catch events on elements that are not the current element
45
- {
46
- let owner = getOwnerDocument(event.currentTarget);
30
+ const d = disposables();
31
+ const reset = () => {
32
+ currentTarget = null;
33
+ pressed = false;
34
+ d.dispose();
35
+ };
36
+ const handlePointerDown = (event) => {
37
+ d.dispose(); // Cancel any scheduled tasks
38
+ if (currentTarget !== null)
39
+ return;
40
+ // Keep track of the current element
41
+ currentTarget = event.currentTarget;
42
+ // We are definitely pressing the element now
43
+ pressed = true;
44
+ // Setup global handlers to catch events on elements that are not the current element
45
+ {
46
+ const owner = getOwnerDocument(event.currentTarget);
47
+ if (owner) {
47
48
  // `pointerup` on any element means that we are no longer pressing the current element
48
49
  d.addEventListener(owner, "pointerup", reset, false);
49
50
  // `pointerleave` isn't called consistently (if at all) on iOS Safari, so we use `pointermove` instead
@@ -51,34 +52,27 @@ export const createActivePress = ({ disabled }) => {
51
52
  // so that we can tell if the pointer is still over the element or not.
52
53
  d.addEventListener(owner, "pointermove", (event) => {
53
54
  if (currentTarget) {
54
- let pointerRect = pointerRectFromPointerEvent(event);
55
+ const pointerRect = pointerRectFromPointerEvent(event);
55
56
  pressed = areRectsOverlapping(pointerRect, currentTarget.getBoundingClientRect());
56
57
  }
57
58
  }, false);
58
59
  // Whenever the browser decides to fire a `pointercancel` event, we should abort
59
60
  d.addEventListener(owner, "pointercancel", reset, false);
60
61
  }
61
- };
62
- if (!disabled) {
63
- node.addEventListener("pointerdown", handlePointerDown);
64
- node.addEventListener("pointerup", reset);
65
- node.addEventListener("click", reset);
66
62
  }
67
- return {
68
- destroy: () => {
69
- if (!disabled) {
70
- node.removeEventListener("pointerdown", handlePointerDown);
71
- node.removeEventListener("pointerup", reset);
72
- node.removeEventListener("click", reset);
73
- }
74
- d.dispose();
75
- },
76
- };
77
63
  };
78
64
  return {
79
- activePressAction,
80
65
  get pressed() {
81
66
  return pressed;
82
67
  },
68
+ get pressProps() {
69
+ return disabled
70
+ ? {}
71
+ : {
72
+ onpointerdown: handlePointerDown,
73
+ onpointerup: reset,
74
+ onclick: reset,
75
+ };
76
+ },
83
77
  };
84
78
  };
@@ -0,0 +1,2 @@
1
+ export type ByComparator<T> = (NonNullable<T> extends never ? string : keyof NonNullable<T> & string) | ((a: T, z: T) => boolean);
2
+ export declare function useByComparator<T>(by?: ByComparator<T>): (a: T, z: T) => boolean;
@@ -0,0 +1,15 @@
1
+ function defaultBy(a, z) {
2
+ if (a !== null && z !== null && typeof a === "object" && typeof z === "object" && "id" in a && "id" in z) {
3
+ return a.id === z.id;
4
+ }
5
+ return a === z;
6
+ }
7
+ export function useByComparator(by = defaultBy) {
8
+ return (a, z) => {
9
+ if (typeof by === "string") {
10
+ const property = by;
11
+ return a?.[property] === z?.[property];
12
+ }
13
+ return by(a, z);
14
+ };
15
+ }
@@ -0,0 +1,6 @@
1
+ export declare function useControllable<T>(input: {
2
+ controlledValue: T | undefined;
3
+ }, onchange?: (value: T) => void, defaultValue?: T): {
4
+ readonly value: NonNullable<T>;
5
+ onchange: (value: T) => void;
6
+ };
@@ -0,0 +1,34 @@
1
+ export function useControllable(input, onchange, defaultValue) {
2
+ let internalValue = $state(defaultValue);
3
+ const isControlled = $derived(input.controlledValue !== undefined);
4
+ let wasControlled = isControlled;
5
+ let didWarnOnUncontrolledToControlled = false;
6
+ let didWarnOnControlledToUncontrolled = false;
7
+ $effect(() => {
8
+ if (isControlled && !wasControlled && !didWarnOnUncontrolledToControlled) {
9
+ didWarnOnUncontrolledToControlled = true;
10
+ wasControlled = isControlled;
11
+ console.error("A component is changing from uncontrolled to controlled. This may be caused by the value changing from undefined to a defined value, which should not happen.");
12
+ }
13
+ else if (!isControlled && wasControlled && !didWarnOnControlledToUncontrolled) {
14
+ didWarnOnControlledToUncontrolled = true;
15
+ wasControlled = isControlled;
16
+ console.error("A component is changing from controlled to uncontrolled. This may be caused by the value changing from a defined value to undefined, which should not happen.");
17
+ }
18
+ });
19
+ const value = $derived(isControlled ? input.controlledValue : internalValue);
20
+ return {
21
+ get value() {
22
+ return value;
23
+ },
24
+ onchange: (value) => {
25
+ if (isControlled && onchange) {
26
+ onchange?.(value);
27
+ }
28
+ else {
29
+ internalValue = value;
30
+ input.controlledValue = value;
31
+ }
32
+ },
33
+ };
34
+ }
@@ -0,0 +1,6 @@
1
+ export declare function useDidElementMove(options: {
2
+ enabled: boolean;
3
+ element: HTMLElement | null;
4
+ }): {
5
+ readonly value: boolean;
6
+ };
@@ -0,0 +1,27 @@
1
+ export function useDidElementMove(options) {
2
+ const { enabled, element } = $derived(options);
3
+ let elementPosition = $state({ left: 0, top: 0 });
4
+ $effect(() => {
5
+ if (!element)
6
+ return;
7
+ let DOMRect = element.getBoundingClientRect();
8
+ if (DOMRect)
9
+ elementPosition = DOMRect;
10
+ });
11
+ const value = $derived.by(() => {
12
+ if (element == null)
13
+ return false;
14
+ if (!enabled)
15
+ return false;
16
+ if (element === document.activeElement)
17
+ return false;
18
+ let buttonRect = element.getBoundingClientRect();
19
+ let didElementMove = buttonRect.top !== elementPosition.top || buttonRect.left !== elementPosition.left;
20
+ return didElementMove;
21
+ });
22
+ return {
23
+ get value() {
24
+ return value;
25
+ },
26
+ };
27
+ }
@@ -0,0 +1,3 @@
1
+ export declare const useDisabled: () => {
2
+ readonly value: boolean;
3
+ };
@@ -0,0 +1,9 @@
1
+ import { getContext } from "svelte";
2
+ export const useDisabled = () => {
3
+ const context = getContext("DisabledContext");
4
+ return {
5
+ get value() {
6
+ return context?.value ?? false;
7
+ },
8
+ };
9
+ };
@@ -0,0 +1,7 @@
1
+ export declare function useElementSize(options: {
2
+ element: HTMLElement | null;
3
+ unit: boolean;
4
+ }): {
5
+ readonly width: string | number;
6
+ readonly height: string | number;
7
+ };
@@ -0,0 +1,36 @@
1
+ function computeSize(element) {
2
+ if (element === null)
3
+ return { width: 0, height: 0 };
4
+ const { width, height } = element.getBoundingClientRect();
5
+ return { width, height };
6
+ }
7
+ export function useElementSize(options) {
8
+ const { element, unit = false } = $derived(options);
9
+ // When the element changes during a re-render, we want to make sure we
10
+ // compute the correct size as soon as possible. However, once the element is
11
+ // stable, we also want to watch for changes to the element. The `identity`
12
+ // state can be used to recompute the size.
13
+ let size = $state(computeSize(element));
14
+ const observeSize = (element) => {
15
+ if (!element)
16
+ return;
17
+ const observer = new ResizeObserver(() => {
18
+ const { width, height } = computeSize(element);
19
+ if (width !== size.width || height !== size.height)
20
+ size = { width, height };
21
+ });
22
+ observer.observe(element);
23
+ return () => {
24
+ observer.disconnect();
25
+ };
26
+ };
27
+ $effect(() => observeSize(element));
28
+ return {
29
+ get width() {
30
+ return unit ? `${size.width}px` : size.width;
31
+ },
32
+ get height() {
33
+ return unit ? `${size.height}px` : size.height;
34
+ },
35
+ };
36
+ }
@@ -0,0 +1,5 @@
1
+ export declare function useEscape(options: {
2
+ enabled: boolean;
3
+ view: typeof document.defaultView | null;
4
+ cb: (event: KeyboardEvent) => void;
5
+ }): void;
@@ -0,0 +1,26 @@
1
+ import { useEventListener } from "./use-event-listener.svelte.js";
2
+ import { useIsTopLayer } from "./use-is-top-layer.svelte.js";
3
+ export function useEscape(options) {
4
+ const { enabled, view = typeof document !== "undefined" ? document.defaultView : null, cb } = $derived(options);
5
+ let isTopLayer = useIsTopLayer({
6
+ get enabled() {
7
+ return enabled;
8
+ },
9
+ scope: "escape",
10
+ });
11
+ useEventListener({
12
+ get element() {
13
+ return view;
14
+ },
15
+ type: "keydown",
16
+ listener: (event) => {
17
+ if (!isTopLayer.value)
18
+ return;
19
+ if (event.defaultPrevented)
20
+ return;
21
+ if (event.key !== "Escape")
22
+ return;
23
+ cb(event);
24
+ },
25
+ });
26
+ }
@@ -0,0 +1,6 @@
1
+ export declare function useEventListener<TType extends keyof WindowEventMap>(params: {
2
+ element: HTMLElement | Document | Window | EventTarget | null | undefined;
3
+ type: TType;
4
+ listener: (event: WindowEventMap[TType]) => any;
5
+ options?: boolean | AddEventListenerOptions;
6
+ }): void;
@@ -0,0 +1,12 @@
1
+ export function useEventListener(params) {
2
+ let { element = window, type, listener, options } = $derived(params);
3
+ $effect(() => {
4
+ if (!element)
5
+ return;
6
+ function handler(event) {
7
+ listener(event);
8
+ }
9
+ element.addEventListener(type, handler, options);
10
+ return () => element.removeEventListener(type, handler, options);
11
+ });
12
+ }
@@ -0,0 +1,8 @@
1
+ export declare function useFlags(initialFlags?: number): {
2
+ readonly flags: number;
3
+ setFlag: (flag: number) => number;
4
+ addFlag: (flag: number) => number;
5
+ hasFlag: (flag: number) => boolean;
6
+ removeFlag: (flag: number) => number;
7
+ toggleFlag: (flag: number) => number;
8
+ };
@@ -0,0 +1,18 @@
1
+ export function useFlags(initialFlags = 0) {
2
+ let flags = $state(initialFlags);
3
+ let setFlag = (flag) => (flags = flag);
4
+ let addFlag = (flag) => (flags = flags | flag);
5
+ let hasFlag = (flag) => (flags & flag) === flag;
6
+ let removeFlag = (flag) => (flags = flags & ~flag);
7
+ let toggleFlag = (flag) => (flags = flags ^ flag);
8
+ return {
9
+ get flags() {
10
+ return flags;
11
+ },
12
+ setFlag,
13
+ addFlag,
14
+ hasFlag,
15
+ removeFlag,
16
+ toggleFlag,
17
+ };
18
+ }
@@ -0,0 +1,10 @@
1
+ export declare const useFocusRing: (options?: {
2
+ autofocus?: boolean;
3
+ within?: boolean;
4
+ }) => {
5
+ readonly isFocusVisible: boolean;
6
+ focusProps: {
7
+ onfocus: () => void;
8
+ onblur: () => void;
9
+ };
10
+ };
@@ -0,0 +1,24 @@
1
+ import { isFocusVisible, useFocusVisibleListener } from "../utils/focusVisible.svelte.js";
2
+ export const useFocusRing = (options = {}) => {
3
+ const { autofocus, within } = $derived(options);
4
+ let focused = $state(false);
5
+ let _isFocusVisible = $state(autofocus || isFocusVisible());
6
+ useFocusVisibleListener((isFocusVisible) => {
7
+ _isFocusVisible = isFocusVisible;
8
+ });
9
+ return {
10
+ get isFocusVisible() {
11
+ return _isFocusVisible && focused;
12
+ },
13
+ focusProps: {
14
+ onfocus: () => {
15
+ if (!within)
16
+ focused = true;
17
+ },
18
+ onblur: () => {
19
+ if (!within)
20
+ focused = false;
21
+ },
22
+ },
23
+ };
24
+ };
@@ -0,0 +1,26 @@
1
+ export interface HoverEvent {
2
+ /** The type of hover event being fired. */
3
+ type: "hoverstart" | "hoverend";
4
+ /** The pointer type that triggered the hover event. */
5
+ pointerType: "mouse" | "pen";
6
+ /** The target element of the hover event. */
7
+ target: Element;
8
+ }
9
+ export declare const useHover: (options?: {
10
+ disabled?: boolean;
11
+ }) => {
12
+ readonly isHovered: boolean;
13
+ hoverProps: {
14
+ onpointerenter: (e: PointerEvent) => void;
15
+ onpointerleave: (e: PointerEvent) => void;
16
+ onmouseenter?: undefined;
17
+ onmouseleave?: undefined;
18
+ ontouchstart?: undefined;
19
+ } | {
20
+ onmouseenter: (e: MouseEvent) => void;
21
+ onmouseleave: (e: MouseEvent) => void;
22
+ ontouchstart: () => void;
23
+ onpointerenter?: undefined;
24
+ onpointerleave?: undefined;
25
+ };
26
+ };
@@ -0,0 +1,124 @@
1
+ // let { isHovered: hover, hoverProps } = useHover({ isDisabled: disabled })
2
+ import { disposables } from "../utils/disposables.js";
3
+ let globalIgnoreEmulatedMouseEvents = false;
4
+ let hoverCount = 0;
5
+ const d = disposables();
6
+ function setGlobalIgnoreEmulatedMouseEvents() {
7
+ globalIgnoreEmulatedMouseEvents = true;
8
+ // Clear globalIgnoreEmulatedMouseEvents after a short timeout. iOS fires onPointerEnter
9
+ // with pointerType="mouse" immediately after onPointerUp and before onFocus. On other
10
+ // devices that don't have this quirk, we don't want to ignore a mouse hover sometime in
11
+ // the distant future because a user previously touched the element.
12
+ setTimeout(() => { });
13
+ }
14
+ function handleGlobalPointerEvent(e) {
15
+ if (e.pointerType === "touch") {
16
+ setGlobalIgnoreEmulatedMouseEvents();
17
+ }
18
+ }
19
+ function isHoverPointerType(pointerType) {
20
+ return pointerType === "mouse" || pointerType === "pen" || pointerType === "touch";
21
+ }
22
+ function setupGlobalTouchEvents() {
23
+ if (typeof document === "undefined" || !document)
24
+ return;
25
+ if (hoverCount === 0) {
26
+ if (typeof PointerEvent !== "undefined") {
27
+ d.addEventListener(document, "pointerup", handleGlobalPointerEvent);
28
+ }
29
+ else {
30
+ d.addEventListener(document, "touchend", setGlobalIgnoreEmulatedMouseEvents);
31
+ }
32
+ }
33
+ hoverCount++;
34
+ return () => {
35
+ hoverCount--;
36
+ if (hoverCount === 0)
37
+ d.dispose();
38
+ };
39
+ }
40
+ export const useHover = (options = {}) => {
41
+ const { disabled } = $derived(options);
42
+ const _state = $state({
43
+ isHovered: false,
44
+ ignoreEmulatedMouseEvents: false,
45
+ pointerType: "",
46
+ target: null,
47
+ });
48
+ $effect(() => setupGlobalTouchEvents());
49
+ $effect(() => {
50
+ if (disabled) {
51
+ _state.pointerType = "";
52
+ _state.target = null;
53
+ _state.isHovered = false;
54
+ }
55
+ });
56
+ function triggerHoverStart(originalEvent, pointerType) {
57
+ _state.pointerType = pointerType ?? undefined;
58
+ const target = originalEvent.currentTarget;
59
+ if (!(target instanceof HTMLElement || target instanceof SVGElement))
60
+ return;
61
+ if (disabled || pointerType === "touch" || _state.isHovered || !target.contains(originalEvent.target)) {
62
+ return;
63
+ }
64
+ _state.isHovered = true;
65
+ _state.target = target;
66
+ }
67
+ function triggerHoverEnd(originalEvent, pointerType) {
68
+ _state.pointerType = "";
69
+ _state.target = null;
70
+ const currentTarget = originalEvent.currentTarget;
71
+ if (pointerType === "touch" || !_state.isHovered || !(currentTarget instanceof HTMLElement))
72
+ return;
73
+ _state.isHovered = false;
74
+ }
75
+ function handlePointerEnter(e) {
76
+ const pointerType = e.pointerType;
77
+ if (!isHoverPointerType(pointerType))
78
+ return;
79
+ if (globalIgnoreEmulatedMouseEvents && e.pointerType === "mouse")
80
+ return;
81
+ triggerHoverStart(e, pointerType);
82
+ }
83
+ function handlePointerLeave(e) {
84
+ const pointerType = e.pointerType;
85
+ const currentTarget = e.currentTarget;
86
+ if (disabled ||
87
+ !(currentTarget instanceof HTMLElement) ||
88
+ !currentTarget.contains(e.target) ||
89
+ !isHoverPointerType(pointerType)) {
90
+ return;
91
+ }
92
+ triggerHoverEnd(e, pointerType);
93
+ }
94
+ function handleTouchStart() {
95
+ _state.ignoreEmulatedMouseEvents = true;
96
+ }
97
+ function handleMouseEnter(e) {
98
+ if (!_state.ignoreEmulatedMouseEvents && !globalIgnoreEmulatedMouseEvents) {
99
+ triggerHoverStart(e, "mouse");
100
+ }
101
+ _state.ignoreEmulatedMouseEvents = false;
102
+ }
103
+ function handleMouseLeave(e) {
104
+ const currentTarget = e.currentTarget;
105
+ if (disabled || !(currentTarget instanceof HTMLElement) || !currentTarget.contains(e.target))
106
+ return;
107
+ triggerHoverEnd(e, "mouse");
108
+ }
109
+ return {
110
+ get isHovered() {
111
+ return _state.isHovered;
112
+ },
113
+ hoverProps: typeof PointerEvent !== "undefined"
114
+ ? {
115
+ onpointerenter: handlePointerEnter,
116
+ onpointerleave: handlePointerLeave,
117
+ }
118
+ : {
119
+ onmouseenter: handleMouseEnter,
120
+ onmouseleave: handleMouseLeave,
121
+ ontouchstart: handleTouchStart,
122
+ },
123
+ };
124
+ };
@@ -0,0 +1 @@
1
+ export { htmlid as useId } from "../utils/id.js";
@@ -0,0 +1 @@
1
+ export { htmlid as useId } from "../utils/id.js";
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Mark all elements on the page as inert, except for the ones that are allowed.
3
+ *
4
+ * We move up the tree from the allowed elements, and mark all their siblings as
5
+ * inert. If any of the children happens to be a parent of one of the elements,
6
+ * then that child will not be marked as inert.
7
+ *
8
+ * E.g.:
9
+ *
10
+ * ```html
11
+ * <body> <!-- Stop at body -->
12
+ * <header></header> <!-- Inert, sibling of parent -->
13
+ * <main> <!-- Not inert, parent of allowed element -->
14
+ * <div>Sidebar</div> <!-- Inert, sibling of parent -->
15
+ * <div> <!-- Not inert, parent of allowed element -->
16
+ * <listbox> <!-- Not inert, parent of allowed element -->
17
+ * <button></button> <!-- Not inert, allowed element -->
18
+ * <options></options> <!-- Not inert, allowed element -->
19
+ * </listbox>
20
+ * </div>
21
+ * </main>
22
+ * <footer></footer> <!-- Inert, sibling of parent -->
23
+ * </body>
24
+ * ```
25
+ */
26
+ export declare function useInertOthers(options: {
27
+ enabled: boolean;
28
+ elements?: {
29
+ allowed?: (HTMLElement | null)[];
30
+ disallowed?: (HTMLElement | null)[];
31
+ };
32
+ }): void;