@pzerelles/headlessui-svelte 2.1.2-next.4 → 2.1.2-next.41

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 (252) hide show
  1. package/dist/button/Button.svelte +15 -18
  2. package/dist/button/Button.svelte.d.ts +8 -36
  3. package/dist/button/index.d.ts +1 -1
  4. package/dist/button/index.js +1 -1
  5. package/dist/checkbox/Checkbox.svelte +30 -26
  6. package/dist/checkbox/Checkbox.svelte.d.ts +17 -38
  7. package/dist/checkbox/index.d.ts +1 -1
  8. package/dist/checkbox/index.js +1 -1
  9. package/dist/close-button/CloseButton.svelte +4 -7
  10. package/dist/close-button/CloseButton.svelte.d.ts +3 -46
  11. package/dist/close-button/index.d.ts +1 -0
  12. package/dist/close-button/index.js +1 -0
  13. package/dist/data-interactive/DataInteractive.svelte +6 -22
  14. package/dist/data-interactive/DataInteractive.svelte.d.ts +9 -34
  15. package/dist/data-interactive/index.d.ts +1 -1
  16. package/dist/data-interactive/index.js +1 -1
  17. package/dist/description/Description.svelte +28 -23
  18. package/dist/description/Description.svelte.d.ts +9 -30
  19. package/dist/description/context.svelte.js +14 -16
  20. package/dist/description/index.d.ts +1 -1
  21. package/dist/dialog/Dialog.svelte +315 -31
  22. package/dist/dialog/Dialog.svelte.d.ts +7 -45
  23. package/dist/dialog/DialogBackdrop.svelte +11 -14
  24. package/dist/dialog/DialogBackdrop.svelte.d.ts +8 -33
  25. package/dist/dialog/DialogPanel.svelte +23 -19
  26. package/dist/dialog/DialogPanel.svelte.d.ts +8 -34
  27. package/dist/dialog/DialogTitle.svelte +17 -8
  28. package/dist/dialog/DialogTitle.svelte.d.ts +9 -30
  29. package/dist/dialog/context.svelte.js +2 -2
  30. package/dist/dialog/index.d.ts +4 -4
  31. package/dist/dialog/index.js +4 -4
  32. package/dist/field/Field.svelte +27 -26
  33. package/dist/field/Field.svelte.d.ts +7 -34
  34. package/dist/field/index.d.ts +1 -1
  35. package/dist/fieldset/Fieldset.svelte +14 -20
  36. package/dist/fieldset/Fieldset.svelte.d.ts +8 -35
  37. package/dist/fieldset/index.d.ts +1 -1
  38. package/dist/focus-trap/FocusTrap.svelte +30 -54
  39. package/dist/focus-trap/FocusTrap.svelte.d.ts +10 -52
  40. package/dist/focus-trap/FocusTrapFeatures.d.ts +14 -0
  41. package/dist/focus-trap/FocusTrapFeatures.js +15 -0
  42. package/dist/hooks/use-controllable.svelte.js +2 -1
  43. package/dist/hooks/use-did-element-move.svelte.js +5 -10
  44. package/dist/hooks/use-disabled.d.ts +6 -1
  45. package/dist/hooks/use-disabled.js +10 -5
  46. package/dist/hooks/use-event-listener.svelte.d.ts +1 -1
  47. package/dist/hooks/use-event-listener.svelte.js +3 -1
  48. package/dist/hooks/use-inert-others.svelte.js +10 -10
  49. package/dist/hooks/use-resolve-button-type.svelte.js +0 -1
  50. package/dist/hooks/use-root-containers.svelte.d.ts +2 -2
  51. package/dist/hooks/use-root-containers.svelte.js +5 -5
  52. package/dist/hooks/use-tab-direction.svelte.js +1 -1
  53. package/dist/index.d.ts +5 -2
  54. package/dist/index.js +5 -2
  55. package/dist/input/Input.svelte +28 -21
  56. package/dist/input/Input.svelte.d.ts +16 -33
  57. package/dist/input/index.d.ts +1 -1
  58. package/dist/input/index.js +1 -1
  59. package/dist/internal/FloatingProvider.svelte +17 -0
  60. package/dist/internal/FloatingProvider.svelte.d.ts +8 -0
  61. package/dist/internal/FocusSentinel.svelte +33 -32
  62. package/dist/internal/FocusSentinel.svelte.d.ts +4 -18
  63. package/dist/internal/ForcePortalRoot.svelte.d.ts +4 -18
  64. package/dist/internal/FormFields.svelte +18 -13
  65. package/dist/internal/FormFields.svelte.d.ts +4 -18
  66. package/dist/internal/FormFieldsProvider.svelte +17 -0
  67. package/dist/internal/FormFieldsProvider.svelte.d.ts +7 -0
  68. package/dist/internal/FormResolver.svelte +6 -2
  69. package/dist/internal/FormResolver.svelte.d.ts +4 -18
  70. package/dist/internal/Hidden.svelte +10 -10
  71. package/dist/internal/Hidden.svelte.d.ts +6 -33
  72. package/dist/internal/MainTreeProvider.svelte +1 -1
  73. package/dist/internal/MainTreeProvider.svelte.d.ts +4 -18
  74. package/dist/internal/Portal.svelte.d.ts +4 -18
  75. package/dist/internal/floating-provider.svelte.d.ts +3 -0
  76. package/dist/internal/floating-provider.svelte.js +206 -0
  77. package/dist/internal/floating.svelte.d.ts +46 -22
  78. package/dist/internal/floating.svelte.js +90 -272
  79. package/dist/internal/form-fields.svelte.d.ts +10 -0
  80. package/dist/internal/form-fields.svelte.js +23 -0
  81. package/dist/label/Label.svelte +17 -13
  82. package/dist/label/Label.svelte.d.ts +8 -33
  83. package/dist/label/context.svelte.js +1 -1
  84. package/dist/label/index.d.ts +1 -1
  85. package/dist/legend/Legend.svelte +21 -15
  86. package/dist/legend/Legend.svelte.d.ts +9 -34
  87. package/dist/listbox/Listbox.svelte +79 -163
  88. package/dist/listbox/Listbox.svelte.d.ts +16 -101
  89. package/dist/listbox/ListboxButton.svelte +24 -29
  90. package/dist/listbox/ListboxButton.svelte.d.ts +8 -38
  91. package/dist/listbox/ListboxOption.svelte +33 -27
  92. package/dist/listbox/ListboxOption.svelte.d.ts +16 -32
  93. package/dist/listbox/ListboxOptions.svelte +126 -73
  94. package/dist/listbox/ListboxOptions.svelte.d.ts +8 -43
  95. package/dist/listbox/ListboxSelectedOption.svelte +24 -26
  96. package/dist/listbox/ListboxSelectedOption.svelte.d.ts +14 -39
  97. package/dist/listbox/context.svelte.d.ts +76 -0
  98. package/dist/listbox/context.svelte.js +36 -0
  99. package/dist/listbox/index.d.ts +5 -5
  100. package/dist/listbox/index.js +4 -4
  101. package/dist/menu/Menu.svelte +22 -266
  102. package/dist/menu/Menu.svelte.d.ts +7 -37
  103. package/dist/menu/MenuButton.svelte +22 -24
  104. package/dist/menu/MenuButton.svelte.d.ts +8 -39
  105. package/dist/menu/MenuHeading.svelte +12 -16
  106. package/dist/menu/MenuHeading.svelte.d.ts +7 -36
  107. package/dist/menu/MenuItem.svelte +18 -23
  108. package/dist/menu/MenuItem.svelte.d.ts +9 -39
  109. package/dist/menu/MenuItems.svelte +33 -34
  110. package/dist/menu/MenuItems.svelte.d.ts +8 -43
  111. package/dist/menu/MenuSection.svelte +9 -12
  112. package/dist/menu/MenuSection.svelte.d.ts +7 -33
  113. package/dist/menu/MenuSeparator.svelte +9 -12
  114. package/dist/menu/MenuSeparator.svelte.d.ts +7 -33
  115. package/dist/menu/context.svelte.d.ts +2 -1
  116. package/dist/menu/context.svelte.js +212 -2
  117. package/dist/menu/index.d.ts +7 -7
  118. package/dist/menu/index.js +3 -3
  119. package/dist/popover/Popover.svelte +225 -0
  120. package/dist/popover/Popover.svelte.d.ts +15 -0
  121. package/dist/popover/PopoverBackdrop.svelte +83 -0
  122. package/dist/popover/PopoverBackdrop.svelte.d.ts +17 -0
  123. package/dist/popover/PopoverButton.svelte +324 -0
  124. package/dist/popover/PopoverButton.svelte.d.ts +21 -0
  125. package/dist/popover/PopoverGroup.svelte +66 -0
  126. package/dist/popover/PopoverGroup.svelte.d.ts +9 -0
  127. package/dist/popover/PopoverPanel.svelte +359 -0
  128. package/dist/popover/PopoverPanel.svelte.d.ts +22 -0
  129. package/dist/popover/context.svelte.d.ts +51 -0
  130. package/dist/popover/context.svelte.js +108 -0
  131. package/dist/popover/index.d.ts +5 -0
  132. package/dist/popover/index.js +5 -0
  133. package/dist/portal/InternalPortal.svelte +17 -17
  134. package/dist/portal/InternalPortal.svelte.d.ts +6 -33
  135. package/dist/portal/Portal.svelte +7 -6
  136. package/dist/portal/Portal.svelte.d.ts +3 -22
  137. package/dist/portal/PortalGroup.svelte +6 -14
  138. package/dist/portal/PortalGroup.svelte.d.ts +5 -34
  139. package/dist/radio-group/Radio.svelte +135 -0
  140. package/dist/radio-group/Radio.svelte.d.ts +35 -0
  141. package/dist/radio-group/RadioGroup.svelte +223 -0
  142. package/dist/radio-group/RadioGroup.svelte.d.ts +34 -0
  143. package/dist/radio-group/RadioOption.svelte +138 -0
  144. package/dist/radio-group/RadioOption.svelte.d.ts +37 -0
  145. package/dist/radio-group/contest.svelte.d.ts +30 -0
  146. package/dist/radio-group/contest.svelte.js +40 -0
  147. package/dist/radio-group/index.d.ts +3 -0
  148. package/dist/radio-group/index.js +3 -0
  149. package/dist/select/Select.svelte +112 -0
  150. package/dist/select/Select.svelte.d.ts +21 -0
  151. package/dist/select/index.d.ts +1 -0
  152. package/dist/select/index.js +1 -0
  153. package/dist/switch/Switch.svelte +27 -28
  154. package/dist/switch/Switch.svelte.d.ts +9 -42
  155. package/dist/switch/SwitchGroup.svelte +5 -5
  156. package/dist/switch/SwitchGroup.svelte.d.ts +8 -30
  157. package/dist/switch/index.d.ts +1 -1
  158. package/dist/switch/index.js +1 -1
  159. package/dist/tabs/Tab.svelte +26 -29
  160. package/dist/tabs/Tab.svelte.d.ts +8 -36
  161. package/dist/tabs/TabGroup.svelte +42 -264
  162. package/dist/tabs/TabGroup.svelte.d.ts +7 -57
  163. package/dist/tabs/TabList.svelte +13 -16
  164. package/dist/tabs/TabList.svelte.d.ts +8 -31
  165. package/dist/tabs/TabPanel.svelte +19 -19
  166. package/dist/tabs/TabPanel.svelte.d.ts +8 -38
  167. package/dist/tabs/TabPanels.svelte +11 -9
  168. package/dist/tabs/TabPanels.svelte.d.ts +8 -30
  169. package/dist/tabs/context.svelte.d.ts +31 -0
  170. package/dist/tabs/context.svelte.js +134 -0
  171. package/dist/tabs/index.d.ts +5 -5
  172. package/dist/tabs/index.js +4 -4
  173. package/dist/textarea/Textarea.svelte +23 -19
  174. package/dist/textarea/Textarea.svelte.d.ts +18 -30
  175. package/dist/textarea/index.d.ts +1 -1
  176. package/dist/textarea/index.js +1 -1
  177. package/dist/transition/InternalTransitionChild.svelte +19 -12
  178. package/dist/transition/InternalTransitionChild.svelte.d.ts +4 -35
  179. package/dist/transition/Transition.svelte +16 -17
  180. package/dist/transition/Transition.svelte.d.ts +8 -38
  181. package/dist/transition/TransitionChild.svelte +13 -12
  182. package/dist/transition/TransitionChild.svelte.d.ts +11 -38
  183. package/dist/transition/context.svelte.js +9 -9
  184. package/dist/transition/index.d.ts +2 -2
  185. package/dist/transition/index.js +2 -2
  186. package/dist/utils/DisabledProvider.svelte +10 -0
  187. package/dist/utils/DisabledProvider.svelte.d.ts +8 -0
  188. package/dist/utils/ElementOrComponent.svelte +57 -14
  189. package/dist/utils/ElementOrComponent.svelte.d.ts +19 -29
  190. package/dist/utils/StableCollection.svelte.d.ts +4 -18
  191. package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +32 -0
  192. package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte.d.ts +8 -0
  193. package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +94 -0
  194. package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte.d.ts +26 -0
  195. package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.d.ts +6 -0
  196. package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.js +158 -0
  197. package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.d.ts +11 -0
  198. package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.js +53 -0
  199. package/dist/utils/floating-ui/svelte/hooks/useId.svelte.d.ts +9 -0
  200. package/dist/utils/floating-ui/svelte/hooks/useId.svelte.js +28 -0
  201. package/dist/utils/floating-ui/svelte/hooks/useInteractions.svelte.d.ts +23 -0
  202. package/dist/utils/floating-ui/svelte/hooks/useInteractions.svelte.js +72 -0
  203. package/dist/utils/floating-ui/svelte/index.d.ts +5 -0
  204. package/dist/utils/floating-ui/svelte/index.js +5 -0
  205. package/dist/utils/floating-ui/svelte/inner.svelte.d.ts +83 -0
  206. package/dist/utils/floating-ui/svelte/inner.svelte.js +178 -0
  207. package/dist/utils/floating-ui/svelte/types.d.ts +114 -0
  208. package/dist/utils/floating-ui/svelte/utils/createPubSub.d.ts +5 -0
  209. package/dist/utils/floating-ui/svelte/utils/createPubSub.js +14 -0
  210. package/dist/utils/floating-ui/svelte/utils/getFloatingFocusElement.d.ts +2 -0
  211. package/dist/utils/floating-ui/svelte/utils/getFloatingFocusElement.js +13 -0
  212. package/dist/utils/floating-ui/svelte/utils/log.d.ts +2 -0
  213. package/dist/utils/floating-ui/svelte/utils/log.js +19 -0
  214. package/dist/utils/floating-ui/svelte/utils.d.ts +19 -0
  215. package/dist/utils/floating-ui/svelte/utils.js +136 -0
  216. package/dist/utils/floating-ui/svelte-dom/arrow.d.ts +22 -0
  217. package/dist/utils/floating-ui/svelte-dom/arrow.js +29 -0
  218. package/dist/utils/floating-ui/svelte-dom/index.d.ts +2 -0
  219. package/dist/utils/floating-ui/svelte-dom/index.js +2 -0
  220. package/dist/utils/floating-ui/svelte-dom/types.d.ts +80 -0
  221. package/dist/utils/floating-ui/svelte-dom/types.js +3 -0
  222. package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.d.ts +6 -0
  223. package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.js +182 -0
  224. package/dist/utils/floating-ui/svelte-dom/utils/deepEqual.d.ts +1 -0
  225. package/dist/utils/floating-ui/svelte-dom/utils/deepEqual.js +50 -0
  226. package/dist/utils/floating-ui/svelte-dom/utils/getDPR.d.ts +1 -0
  227. package/dist/utils/floating-ui/svelte-dom/utils/getDPR.js +7 -0
  228. package/dist/utils/floating-ui/svelte-dom/utils/roundByDPR.d.ts +1 -0
  229. package/dist/utils/floating-ui/svelte-dom/utils/roundByDPR.js +5 -0
  230. package/dist/utils/floating-ui/svelte-dom/utils/useLatestRef.d.ts +4 -0
  231. package/dist/utils/floating-ui/svelte-dom/utils/useLatestRef.js +7 -0
  232. package/dist/utils/id.d.ts +1 -1
  233. package/dist/utils/id.js +1 -1
  234. package/dist/utils/index.d.ts +3 -0
  235. package/dist/utils/index.js +3 -0
  236. package/dist/utils/state.js +4 -4
  237. package/dist/utils/style.d.ts +2 -0
  238. package/dist/utils/style.js +6 -0
  239. package/dist/utils/types.d.ts +12 -18
  240. package/package.json +33 -32
  241. package/dist/combobox/Combobox.svelte +0 -53
  242. package/dist/combobox/Combobox.svelte.d.ts +0 -50
  243. package/dist/dialog/InternalDialog.svelte +0 -294
  244. package/dist/dialog/InternalDialog.svelte.d.ts +0 -42
  245. package/dist/internal/HoistFormFields.svelte +0 -14
  246. package/dist/internal/HoistFormFields.svelte.d.ts +0 -21
  247. package/dist/internal/id.d.ts +0 -8
  248. package/dist/internal/id.js +0 -11
  249. package/dist/utils/Generic.svelte +0 -56
  250. package/dist/utils/Generic.svelte.d.ts +0 -35
  251. package/dist/utils/alternative-types.d.ts +0 -21
  252. /package/dist/utils/{alternative-types.js → floating-ui/svelte/types.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  <script lang="ts" module>
2
- import type { ElementType, Props } from "../utils/types.js"
2
+ import type { Props } from "../utils/types.js"
3
3
  import { mergeProps, RenderFeatures, type PropsForFeatures } from "../utils/render.js"
4
4
  import {
5
5
  useFloatingPanel,
@@ -9,7 +9,8 @@
9
9
  } from "../internal/floating.svelte.js"
10
10
 
11
11
  const DEFAULT_OPTIONS_TAG = "div" as const
12
- type OptionsRenderPropArg = {
12
+
13
+ export type OptionsRenderPropArg = {
13
14
  open: boolean
14
15
  }
15
16
  type OptionsPropsWeControl =
@@ -22,23 +23,19 @@
22
23
 
23
24
  let OptionsRenderFeatures = RenderFeatures.RenderStrategy | RenderFeatures.Static
24
25
 
25
- export type ListboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> = Props<
26
- TTag,
27
- OptionsRenderPropArg,
28
- OptionsPropsWeControl,
29
- {
30
- id?: string
31
- anchor?: AnchorPropsWithSelection
32
- portal?: boolean
33
- modal?: boolean
34
- transition?: boolean
35
- } & PropsForFeatures<typeof OptionsRenderFeatures>
36
- >
37
-
38
- export type ListboxOptionsChildren = Snippet<[OptionsRenderPropArg]>
26
+ export type ListboxOptionsOwnProps = {
27
+ element?: HTMLElement
28
+ id?: string
29
+ anchor?: AnchorPropsWithSelection
30
+ portal?: boolean
31
+ modal?: boolean
32
+ transition?: boolean
33
+ } & PropsForFeatures<typeof OptionsRenderFeatures>
34
+
35
+ export type ListboxOptionsProps = Props<typeof DEFAULT_OPTIONS_TAG, OptionsRenderPropArg, ListboxOptionsOwnProps>
39
36
  </script>
40
37
 
41
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG">
38
+ <script lang="ts">
42
39
  import { useId } from "../hooks/use-id.js"
43
40
  import { ListboxStates, useActions, useData, ValueMode, type ListboxDataContext } from "./Listbox.svelte"
44
41
  import { getOwnerDocument } from "../utils/owner.js"
@@ -55,25 +52,27 @@
55
52
  import { focusFrom, Focus as FocusManagementFocus } from "../utils/focus-management.js"
56
53
  import { useElementSize } from "../hooks/use-element-size.svelte.js"
57
54
  import { setContext, type Snippet } from "svelte"
58
- import Hidden from "../internal/Hidden.svelte"
59
55
  import Portal from "../portal/Portal.svelte"
60
- import { stateFromSlot } from "../utils/state.js"
61
56
  import ElementOrComponent from "../utils/ElementOrComponent.svelte"
62
57
 
63
58
  const internalId = useId()
64
59
  let {
65
- as = DEFAULT_OPTIONS_TAG as TTag,
66
- ref = $bindable(),
60
+ element = $bindable(),
67
61
  id = `headlessui-listbox-options-${internalId}`,
68
62
  anchor: rawAnchor,
69
63
  portal = false,
70
64
  modal = true,
71
65
  transition = false,
72
- static: isStatic = false,
73
- unmount = true,
74
66
  ...theirProps
75
- }: { as?: TTag } & ListboxOptionsProps<TTag> = $props()
76
- const anchor = $derived(useResolvedAnchor(rawAnchor))
67
+ }: ListboxOptionsProps = $props()
68
+ const resolvedAnchor = useResolvedAnchor({
69
+ get anchor() {
70
+ return rawAnchor
71
+ },
72
+ })
73
+ const { anchor } = $derived(resolvedAnchor)
74
+
75
+ let localOptionsElement = $state<HTMLElement | null>()
77
76
 
78
77
  // Always enable `portal` functionality, when `anchor` is enabled
79
78
  $effect(() => {
@@ -85,7 +84,7 @@
85
84
  const data = useData("ListboxOptions")
86
85
  const actions = useActions("ListboxOptions")
87
86
 
88
- const ownerDocument = $derived(getOwnerDocument(data.optionsRef.current))
87
+ const ownerDocument = $derived(getOwnerDocument(data.optionsElement))
89
88
 
90
89
  const usesOpenClosedState = useOpenClosed()
91
90
  const show = $derived(
@@ -98,7 +97,7 @@
98
97
  return transition
99
98
  },
100
99
  get element() {
101
- return ref
100
+ return localOptionsElement
102
101
  },
103
102
  get show() {
104
103
  return show
@@ -112,7 +111,7 @@
112
111
  return visible
113
112
  },
114
113
  get ref() {
115
- return data.buttonRef.current
114
+ return data.buttonElement
116
115
  },
117
116
  get ondisappear() {
118
117
  return actions.closeListbox
@@ -138,7 +137,7 @@
138
137
  },
139
138
  elements: {
140
139
  get allowed() {
141
- return [data.buttonRef.current, data.optionsRef.current]
140
+ return [data.buttonElement, data.optionsElement]
142
141
  },
143
142
  },
144
143
  })
@@ -158,7 +157,7 @@
158
157
  return didElementMoveEnabled
159
158
  },
160
159
  get element() {
161
- return data.buttonRef.current
160
+ return data.buttonElement
162
161
  },
163
162
  })
164
163
 
@@ -181,9 +180,9 @@
181
180
  },
182
181
  })
183
182
 
184
- const isSelected = (compareValue: unknown) => data.compare(frozenValue, compareValue)
183
+ const isSelected = (compareValue: unknown) => data.compare(frozenValue.data, compareValue)
185
184
 
186
- const selectedOptionIndex = () => {
185
+ const selectedOptionIndex = $derived.by(() => {
187
186
  if (anchor == null) return null
188
187
  if (!anchor?.to?.includes("selection")) return null
189
188
 
@@ -193,13 +192,13 @@
193
192
  // Ensure that if no data is selected, we default to the first item.
194
193
  if (idx === -1) idx = 0
195
194
  return idx
196
- }
195
+ })
197
196
 
198
197
  const anchorOptions = $derived.by(() => {
199
198
  if (anchor == null) return undefined
200
199
  if (selectedOptionIndex === null) return { ...anchor, inner: undefined }
201
200
 
202
- let elements = Array.from(data.listRef.current.values())
201
+ let elements = Array.from(data.listElements.values())
203
202
 
204
203
  return {
205
204
  ...anchor,
@@ -215,24 +214,24 @@
215
214
  return anchorOptions ?? null
216
215
  },
217
216
  })
218
- const { setFloating, style } = $derived(floatingPanel)
217
+ const { setFloating, styles } = $derived(floatingPanel)
219
218
  const getFloatingPanelProps = useFloatingPanelProps()
220
219
 
221
220
  $effect(() => {
222
- data.optionsRef.current = ref || null
223
- if (anchor) setFloating(ref)
221
+ localOptionsElement = element
222
+ data.optionsElement = element ?? null
223
+ if (anchor) setFloating(element ?? null)
224
224
  })
225
225
 
226
226
  const searchDisposables = useDisposables()
227
227
 
228
- const { listboxState, optionsRef } = $derived(data)
228
+ const { listboxState, optionsElement } = $derived(data)
229
229
  $effect(() => {
230
- let container = optionsRef.current
231
- if (!container) return
230
+ if (!optionsElement) return
232
231
  if (listboxState !== ListboxStates.Open) return
233
- if (container === getOwnerDocument(container)?.activeElement) return
232
+ if (optionsElement === getOwnerDocument(optionsElement)?.activeElement) return
234
233
 
235
- container?.focus({ preventScroll: true })
234
+ optionsElement?.focus({ preventScroll: true })
236
235
  })
237
236
 
238
237
  const handleKeyDown = (event: KeyboardEvent) => {
@@ -258,7 +257,7 @@
258
257
  }
259
258
  if (data.mode === ValueMode.Single) {
260
259
  actions.closeListbox()
261
- data.buttonRef.current?.focus({ preventScroll: true })
260
+ data.buttonElement?.focus({ preventScroll: true })
262
261
  }
263
262
  break
264
263
 
@@ -288,14 +287,14 @@
288
287
  event.preventDefault()
289
288
  event.stopPropagation()
290
289
  actions.closeListbox()
291
- data.buttonRef.current?.focus({ preventScroll: true })
290
+ data.buttonElement?.focus({ preventScroll: true })
292
291
  return
293
292
 
294
293
  case "Tab":
295
294
  event.preventDefault()
296
295
  event.stopPropagation()
297
296
  actions.closeListbox()
298
- focusFrom(data.buttonRef.current!, event.shiftKey ? FocusManagementFocus.Previous : FocusManagementFocus.Next)
297
+ focusFrom(data.buttonElement, event.shiftKey ? FocusManagementFocus.Previous : FocusManagementFocus.Next)
299
298
  break
300
299
 
301
300
  default:
@@ -307,59 +306,113 @@
307
306
  }
308
307
  }
309
308
 
310
- const labelledby = $derived(data.buttonRef.current?.id)
309
+ const labelledby = $derived(data.buttonElement?.id)
311
310
  const slot = $derived({
312
311
  open: data.listboxState === ListboxStates.Open,
313
312
  } satisfies OptionsRenderPropArg)
314
313
 
315
314
  const buttonSize = useElementSize({
316
315
  get element() {
317
- return data.buttonRef.current
316
+ return data.buttonElement
318
317
  },
319
318
  unit: true,
320
319
  })
321
320
 
322
- const ourProps = $derived(
323
- mergeProps(anchor ? getFloatingPanelProps() : {}, {
321
+ $effect(() => {
322
+ transitionData
323
+ })
324
+
325
+ const ourProps = $derived({
326
+ ...mergeProps(anchor ? getFloatingPanelProps() : {}, {
324
327
  id,
325
328
  "aria-activedescendant": data.activeOptionIndex === null ? undefined : data.options[data.activeOptionIndex]?.id,
326
329
  "aria-multiselectable": data.mode === ValueMode.Multi ? true : undefined,
327
330
  "aria-labelledby": labelledby,
328
331
  "aria-orientation": data.orientation,
329
- onkeydown: handleKeyDown,
330
332
  role: "listbox",
331
333
  // When the `Listbox` is closed, it should not be focusable. This allows us
332
334
  // to skip focusing the `ListboxOptions` when pressing the tab key on an
333
335
  // open `Listbox`, and go to the next focusable element.
334
- tabIndex: data.listboxState === ListboxStates.Open ? 0 : undefined,
335
- style: [theirProps.style, style, `--button-width: ${buttonSize.width}`].filter(Boolean).join("; "),
336
- ...transitionDataAttributes(transitionData),
337
- ...stateFromSlot(slot),
338
- })
339
- )
336
+ tabindex: data.listboxState === ListboxStates.Open ? 0 : undefined,
337
+ style: [theirProps.style, styles, `--button-width: ${buttonSize.width}`].filter(Boolean).join("; "),
338
+ }),
339
+ ...transitionDataAttributes(transitionData),
340
+ })
340
341
 
341
- const derivedData: ListboxDataContext = {
342
+ const derivedData: ListboxDataContext = $derived({
342
343
  ...data,
343
344
  get isSelected() {
344
345
  return data.mode === ValueMode.Multi ? data.isSelected : isSelected
345
346
  },
346
- }
347
+ })
347
348
 
348
- setContext("ListboxDataContext", derivedData)
349
+ setContext("ListboxDataContext", {
350
+ get value() {
351
+ return data.value
352
+ },
353
+ get disabled() {
354
+ return data.disabled
355
+ },
356
+ get invalid() {
357
+ return data.invalid
358
+ },
359
+ get mode() {
360
+ return data.mode
361
+ },
362
+ get orientation() {
363
+ return data.orientation
364
+ },
365
+ get activeOptionIndex() {
366
+ return data.activeOptionIndex
367
+ },
368
+ get closeOnSelect() {
369
+ return data.closeOnSelect
370
+ },
371
+ get compare() {
372
+ return data.compare
373
+ },
374
+ get isSelected() {
375
+ return data.mode === ValueMode.Multi ? data.isSelected : isSelected
376
+ },
377
+ get optionsProps() {
378
+ return data.optionsProps
379
+ },
380
+ get listElements() {
381
+ return data.listElements
382
+ },
383
+ get buttonElement() {
384
+ return data.buttonElement
385
+ },
386
+ get optionsElement() {
387
+ return data.optionsElement
388
+ },
389
+ get listboxState() {
390
+ return data.listboxState
391
+ },
392
+ get options() {
393
+ return data.options
394
+ },
395
+ get searchQuery() {
396
+ return data.searchQuery
397
+ },
398
+ get activationTrigger() {
399
+ return data.activationTrigger
400
+ },
401
+ get __demoMode() {
402
+ return data.__demoMode
403
+ },
404
+ })
349
405
  </script>
350
406
 
351
- <Portal enabled={portal ? isStatic || visible : false}>
352
- {#if !panelEnabled && unmount && !isStatic}
353
- <Hidden as="span" bind:ref aria-hidden="true" {...ourProps} />
354
- {:else}
355
- <ElementOrComponent
356
- {ourProps}
357
- {theirProps}
358
- slots={slot}
359
- defaultTag={DEFAULT_OPTIONS_TAG}
360
- features={OptionsRenderFeatures}
361
- name="MenuItems"
362
- bind:ref
363
- />
364
- {/if}
407
+ <Portal enabled={portal ? theirProps.static || visible : false}>
408
+ <ElementOrComponent
409
+ {ourProps}
410
+ {theirProps}
411
+ slots={slot}
412
+ defaultTag={DEFAULT_OPTIONS_TAG}
413
+ features={OptionsRenderFeatures}
414
+ visible={panelEnabled}
415
+ name="ListboxOptions"
416
+ bind:element
417
+ />
365
418
  </Portal>
@@ -1,55 +1,20 @@
1
- import type { ElementType, Props } from "../utils/types.js";
1
+ import type { Props } from "../utils/types.js";
2
2
  import { type PropsForFeatures } from "../utils/render.js";
3
3
  import { type AnchorPropsWithSelection } from "../internal/floating.svelte.js";
4
4
  declare const DEFAULT_OPTIONS_TAG: "div";
5
- type OptionsRenderPropArg = {
5
+ export type OptionsRenderPropArg = {
6
6
  open: boolean;
7
7
  };
8
- type OptionsPropsWeControl = "aria-activedescendant" | "aria-labelledby" | "aria-multiselectable" | "aria-orientation" | "role" | "tabIndex";
9
8
  declare let OptionsRenderFeatures: number;
10
- export type ListboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> = Props<TTag, OptionsRenderPropArg, OptionsPropsWeControl, {
9
+ export type ListboxOptionsOwnProps = {
10
+ element?: HTMLElement;
11
11
  id?: string;
12
12
  anchor?: AnchorPropsWithSelection;
13
13
  portal?: boolean;
14
14
  modal?: boolean;
15
15
  transition?: boolean;
16
- } & PropsForFeatures<typeof OptionsRenderFeatures>>;
17
- export type ListboxOptionsChildren = Snippet<[OptionsRenderPropArg]>;
18
- import { type Snippet } from "svelte";
19
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> {
20
- props(): {
21
- as?: TTag | undefined;
22
- } & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("as" | "children" | "refName" | "class") | "anchor" | "unmount" | "static" | "id" | "transition" | OptionsPropsWeControl | "portal" | "modal"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
23
- children?: import("../utils/types.js").Children<OptionsRenderPropArg> | undefined;
24
- ref?: HTMLElement;
25
- } & (true extends (import("../utils/types.js").PropsOf<TTag> extends infer T_1 ? T_1 extends import("../utils/types.js").PropsOf<TTag> ? T_1 extends never ? never : "class" extends infer T_2 ? T_2 extends "class" ? T_2 extends keyof T_1 ? true : never : never : never : never : never) ? {
26
- class?: import("../utils/types.js").PropsOf<TTag>["class"] | ((bag: OptionsRenderPropArg) => string) | undefined;
27
- } : {}) & {
28
- id?: string;
29
- anchor?: AnchorPropsWithSelection;
30
- portal?: boolean;
31
- modal?: boolean;
32
- transition?: boolean;
33
- } & {
34
- static?: boolean | undefined;
35
- unmount?: boolean | undefined;
36
- };
37
- events(): {} & {
38
- [evt: string]: CustomEvent<any>;
39
- };
40
- slots(): {};
41
- bindings(): "ref";
42
- exports(): {};
43
- }
44
- interface $$IsomorphicComponent {
45
- new <TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag>['props']>, ReturnType<__sveltets_Render<TTag>['events']>, ReturnType<__sveltets_Render<TTag>['slots']>> & {
46
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
47
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
48
- <TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {
49
- $$events?: ReturnType<__sveltets_Render<TTag>['events']>;
50
- }): ReturnType<__sveltets_Render<TTag>['exports']>;
51
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
52
- }
53
- declare const ListboxOptions: $$IsomorphicComponent;
54
- type ListboxOptions<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> = InstanceType<typeof ListboxOptions<TTag>>;
16
+ } & PropsForFeatures<typeof OptionsRenderFeatures>;
17
+ export type ListboxOptionsProps = Props<typeof DEFAULT_OPTIONS_TAG, OptionsRenderPropArg, ListboxOptionsOwnProps>;
18
+ declare const ListboxOptions: import("svelte").Component<ListboxOptionsProps, {}, "element">;
19
+ type ListboxOptions = ReturnType<typeof ListboxOptions>;
55
20
  export default ListboxOptions;
@@ -1,33 +1,32 @@
1
1
  <script lang="ts" module>
2
- import type { ElementType, Props } from "../utils/types.js"
3
- import type { Component } from "svelte"
2
+ import type { Props } from "../utils/types.js"
3
+ import type { Snippet } from "svelte"
4
4
 
5
- const DEFAULT_SELECTED_OPTION_TAG = "svelte:fragment"
6
- type SelectedOptionRenderPropArg = {}
5
+ const DEFAULT_SELECTED_OPTION_TAG = "span"
6
+ export type SelectedOptionRenderPropArg = {
7
+ option: Snippet
8
+ }
7
9
  type SelectedOptionPropsWeControl = never
8
10
 
9
- export type ListboxSelectedOptionProps<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> = Props<
10
- TTag,
11
+ export type ListboxSelectedOptionOwnProps = {
12
+ element?: HTMLElement
13
+ options: Snippet
14
+ placeholder?: Snippet
15
+ }
16
+
17
+ export type ListboxSelectedOptionProps = Props<
18
+ typeof DEFAULT_SELECTED_OPTION_TAG,
11
19
  SelectedOptionRenderPropArg,
12
- SelectedOptionPropsWeControl,
13
- {
14
- options: Component<any, any>
15
- placeholder?: Component<any, any>
16
- }
20
+ ListboxSelectedOptionOwnProps
17
21
  >
18
22
  </script>
19
23
 
20
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG">
24
+ <script lang="ts">
21
25
  import { useData, ValueMode } from "./Listbox.svelte"
22
26
  import { setContext } from "svelte"
23
27
  import ElementOrComponent from "../utils/ElementOrComponent.svelte"
24
28
 
25
- let {
26
- ref = $bindable(),
27
- options,
28
- placeholder,
29
- ...theirProps
30
- }: { as?: TTag } & ListboxSelectedOptionProps<TTag> = $props()
29
+ let { element = $bindable(), options, placeholder, ...theirProps }: ListboxSelectedOptionProps = $props()
31
30
 
32
31
  const data = useData("ListboxSelectedOption")
33
32
 
@@ -40,19 +39,18 @@
40
39
  setContext("SelectedOptionContext", true)
41
40
  </script>
42
41
 
43
- {#snippet children()}
42
+ {#snippet option()}
44
43
  {#if placeholder && shouldShowPlaceholder}
45
- {@const Component = placeholder}
46
- <Component />
44
+ {@render placeholder()}
47
45
  {:else}
48
- {@const Component = options}
49
- <Component />
46
+ {@render options()}
50
47
  {/if}
51
48
  {/snippet}
52
49
 
53
50
  <ElementOrComponent
54
- theirProps={{ ...theirProps, children }}
51
+ theirProps={{ ...theirProps, ...(theirProps.asChild ? {} : { children: option }) }}
52
+ slot={{ option }}
55
53
  defaultTag={DEFAULT_SELECTED_OPTION_TAG}
56
54
  name="ListboxSelectedOption"
57
- bind:ref
58
- ></ElementOrComponent>
55
+ bind:element
56
+ />
@@ -1,40 +1,15 @@
1
- import type { ElementType, Props } from "../utils/types.js";
2
- import type { Component } from "svelte";
3
- declare const DEFAULT_SELECTED_OPTION_TAG = "svelte:fragment";
4
- type SelectedOptionRenderPropArg = {};
5
- type SelectedOptionPropsWeControl = never;
6
- export type ListboxSelectedOptionProps<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> = Props<TTag, SelectedOptionRenderPropArg, SelectedOptionPropsWeControl, {
7
- options: Component<any, any>;
8
- placeholder?: Component<any, any>;
9
- }>;
10
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> {
11
- props(): {
12
- as?: TTag | undefined;
13
- } & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("as" | "children" | "refName" | "class") | "placeholder" | "options"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
14
- children?: import("../utils/types.js").Children<SelectedOptionRenderPropArg> | undefined;
15
- ref?: HTMLElement;
16
- } & (true extends (import("../utils/types.js").PropsOf<TTag> extends infer T_1 ? T_1 extends import("../utils/types.js").PropsOf<TTag> ? T_1 extends never ? never : "class" extends infer T_2 ? T_2 extends "class" ? T_2 extends keyof T_1 ? true : never : never : never : never : never) ? {
17
- class?: import("../utils/types.js").PropsOf<TTag>["class"] | ((bag: SelectedOptionRenderPropArg) => string) | undefined;
18
- } : {}) & {
19
- options: Component<any, any>;
20
- placeholder?: Component<any, any>;
21
- };
22
- events(): {} & {
23
- [evt: string]: CustomEvent<any>;
24
- };
25
- slots(): {};
26
- bindings(): "ref";
27
- exports(): {};
28
- }
29
- interface $$IsomorphicComponent {
30
- new <TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag>['props']>, ReturnType<__sveltets_Render<TTag>['events']>, ReturnType<__sveltets_Render<TTag>['slots']>> & {
31
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
32
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
33
- <TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {
34
- $$events?: ReturnType<__sveltets_Render<TTag>['events']>;
35
- }): ReturnType<__sveltets_Render<TTag>['exports']>;
36
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
37
- }
38
- declare const ListboxSelectedOption: $$IsomorphicComponent;
39
- type ListboxSelectedOption<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> = InstanceType<typeof ListboxSelectedOption<TTag>>;
1
+ import type { Props } from "../utils/types.js";
2
+ import type { Snippet } from "svelte";
3
+ declare const DEFAULT_SELECTED_OPTION_TAG = "span";
4
+ export type SelectedOptionRenderPropArg = {
5
+ option: Snippet;
6
+ };
7
+ export type ListboxSelectedOptionOwnProps = {
8
+ element?: HTMLElement;
9
+ options: Snippet;
10
+ placeholder?: Snippet;
11
+ };
12
+ export type ListboxSelectedOptionProps = Props<typeof DEFAULT_SELECTED_OPTION_TAG, SelectedOptionRenderPropArg, ListboxSelectedOptionOwnProps>;
13
+ declare const ListboxSelectedOption: import("svelte").Component<ListboxSelectedOptionProps, {}, "element">;
14
+ type ListboxSelectedOption = ReturnType<typeof ListboxSelectedOption>;
40
15
  export default ListboxSelectedOption;
@@ -0,0 +1,76 @@
1
+ import type { Focus } from "../utils/calculate-active-index.js";
2
+ import type { MutableRefObject } from "../utils/ref.svelte.js";
3
+ import type { SvelteMap } from "svelte/reactivity";
4
+ export declare enum ListboxStates {
5
+ Open = 0,
6
+ Closed = 1
7
+ }
8
+ export declare enum ValueMode {
9
+ Single = 0,
10
+ Multi = 1
11
+ }
12
+ export declare enum ActivationTrigger {
13
+ Pointer = 0,
14
+ Other = 1
15
+ }
16
+ export type ListboxOptionDataRef<T> = MutableRefObject<{
17
+ textValue?: string;
18
+ disabled: boolean;
19
+ value: T;
20
+ domRef: MutableRefObject<HTMLElement | null>;
21
+ }>;
22
+ export interface StateDefinition<T> {
23
+ listboxState: ListboxStates;
24
+ options: {
25
+ id: string;
26
+ dataRef: ListboxOptionDataRef<T>;
27
+ }[];
28
+ searchQuery: string;
29
+ activeOptionIndex: number | null;
30
+ activationTrigger: ActivationTrigger;
31
+ __demoMode: boolean;
32
+ }
33
+ export interface StateActions<T> {
34
+ openListbox(): void;
35
+ closeListbox(): void;
36
+ registerOption(id: string, dataRef: ListboxOptionDataRef<T>): void;
37
+ unregisterOption(id: string): void;
38
+ goToOption(action: {
39
+ focus: Focus.Specific;
40
+ id: string;
41
+ trigger?: ActivationTrigger;
42
+ } | {
43
+ focus: Exclude<Focus, Focus.Specific>;
44
+ trigger?: ActivationTrigger;
45
+ }): void;
46
+ search(query: string): void;
47
+ clearSearch(): void;
48
+ }
49
+ export type ListboxActionsContext<T = unknown> = {
50
+ registerOption(id: string, dataRef: ListboxOptionDataRef<T>): () => void;
51
+ goToOption(focus: Focus.Specific, id: string, trigger?: ActivationTrigger): void;
52
+ goToOption(focus: Focus, id?: string, trigger?: ActivationTrigger): void;
53
+ selectOption(id: string): void;
54
+ selectActiveOption(): void;
55
+ onChange(value: T): void;
56
+ } & Pick<StateActions<T>, "openListbox" | "closeListbox" | "search" | "clearSearch">;
57
+ export declare function useActions<T>(component: string): ListboxActionsContext<T>;
58
+ export type ListboxDataContext<T = unknown> = {
59
+ value: T;
60
+ disabled: boolean;
61
+ invalid: boolean;
62
+ mode: ValueMode;
63
+ orientation: "horizontal" | "vertical";
64
+ activeOptionIndex: number | null;
65
+ closeOnSelect?: boolean;
66
+ compare(a: T, z: T): boolean;
67
+ isSelected(value: T): boolean;
68
+ optionsProps: {
69
+ static: boolean;
70
+ hold: boolean;
71
+ };
72
+ listElements: SvelteMap<string, HTMLElement | null>;
73
+ buttonElement: HTMLElement | null;
74
+ optionsElement: HTMLElement | null;
75
+ } & StateDefinition<T>;
76
+ export declare function useData<T>(component: string): ListboxDataContext<T>;
@@ -0,0 +1,36 @@
1
+ import { getContext } from "svelte";
2
+ export var ListboxStates;
3
+ (function (ListboxStates) {
4
+ ListboxStates[ListboxStates["Open"] = 0] = "Open";
5
+ ListboxStates[ListboxStates["Closed"] = 1] = "Closed";
6
+ })(ListboxStates || (ListboxStates = {}));
7
+ export var ValueMode;
8
+ (function (ValueMode) {
9
+ ValueMode[ValueMode["Single"] = 0] = "Single";
10
+ ValueMode[ValueMode["Multi"] = 1] = "Multi";
11
+ })(ValueMode || (ValueMode = {}));
12
+ export var ActivationTrigger;
13
+ (function (ActivationTrigger) {
14
+ ActivationTrigger[ActivationTrigger["Pointer"] = 0] = "Pointer";
15
+ ActivationTrigger[ActivationTrigger["Other"] = 1] = "Other";
16
+ })(ActivationTrigger || (ActivationTrigger = {}));
17
+ export function useActions(component) {
18
+ const context = getContext("ListboxActionsContext");
19
+ if (!context) {
20
+ const err = new Error(`<${component} /> is missing a parent <Listbox /> component.`);
21
+ if (Error.captureStackTrace)
22
+ Error.captureStackTrace(err, useActions);
23
+ throw err;
24
+ }
25
+ return context;
26
+ }
27
+ export function useData(component) {
28
+ const context = getContext("ListboxDataContext");
29
+ if (!context) {
30
+ const err = new Error(`<${component} /> is missing a parent <Listbox /> component.`);
31
+ if (Error.captureStackTrace)
32
+ Error.captureStackTrace(err, useData);
33
+ throw err;
34
+ }
35
+ return context;
36
+ }