@pzerelles/headlessui-svelte 2.1.2-next.29 → 2.1.2-next.30

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 (67) hide show
  1. package/dist/button/Button.svelte +54 -84
  2. package/dist/checkbox/Checkbox.svelte +120 -173
  3. package/dist/checkbox/Checkbox.svelte.d.ts +1 -1
  4. package/dist/close-button/CloseButton.svelte +6 -12
  5. package/dist/combobox/Combobox.svelte +3 -50
  6. package/dist/data-interactive/DataInteractive.svelte +29 -55
  7. package/dist/description/Description.svelte +21 -31
  8. package/dist/dialog/Dialog.svelte +228 -320
  9. package/dist/dialog/DialogBackdrop.svelte +12 -29
  10. package/dist/dialog/DialogPanel.svelte +25 -48
  11. package/dist/dialog/DialogTitle.svelte +23 -38
  12. package/dist/field/Field.svelte +25 -47
  13. package/dist/fieldset/Fieldset.svelte +29 -50
  14. package/dist/focus-trap/FocusTrap.svelte +283 -419
  15. package/dist/input/Input.svelte +53 -84
  16. package/dist/internal/FloatingProvider.svelte +9 -14
  17. package/dist/internal/FocusSentinel.svelte +8 -16
  18. package/dist/internal/ForcePortalRoot.svelte +3 -7
  19. package/dist/internal/FormFields.svelte +34 -47
  20. package/dist/internal/FormFieldsProvider.svelte +5 -9
  21. package/dist/internal/FormResolver.svelte +15 -20
  22. package/dist/internal/Hidden.svelte +29 -50
  23. package/dist/internal/MainTreeProvider.svelte +36 -89
  24. package/dist/internal/Portal.svelte +14 -18
  25. package/dist/label/Label.svelte +58 -93
  26. package/dist/legend/Legend.svelte +3 -12
  27. package/dist/listbox/Listbox.svelte +387 -525
  28. package/dist/listbox/Listbox.svelte.d.ts +1 -1
  29. package/dist/listbox/ListboxButton.svelte +127 -173
  30. package/dist/listbox/ListboxOption.svelte +129 -170
  31. package/dist/listbox/ListboxOptions.svelte +304 -400
  32. package/dist/listbox/ListboxSelectedOption.svelte +15 -38
  33. package/dist/menu/Menu.svelte +51 -78
  34. package/dist/menu/MenuButton.svelte +117 -157
  35. package/dist/menu/MenuHeading.svelte +14 -32
  36. package/dist/menu/MenuItem.svelte +107 -142
  37. package/dist/menu/MenuItems.svelte +229 -301
  38. package/dist/menu/MenuSection.svelte +9 -24
  39. package/dist/menu/MenuSeparator.svelte +4 -17
  40. package/dist/popover/Popover.svelte +150 -216
  41. package/dist/popover/PopoverBackdrop.svelte +41 -67
  42. package/dist/popover/PopoverButton.svelte +212 -292
  43. package/dist/popover/PopoverGroup.svelte +35 -62
  44. package/dist/popover/PopoverPanel.svelte +229 -311
  45. package/dist/portal/InternalPortal.svelte +85 -141
  46. package/dist/portal/Portal.svelte +2 -5
  47. package/dist/portal/PortalGroup.svelte +9 -30
  48. package/dist/select/Select.svelte +68 -98
  49. package/dist/switch/Switch.svelte +132 -179
  50. package/dist/switch/SwitchGroup.svelte +31 -44
  51. package/dist/tabs/Tab.svelte +142 -194
  52. package/dist/tabs/TabGroup.svelte +56 -86
  53. package/dist/tabs/TabGroup.svelte.d.ts +1 -1
  54. package/dist/tabs/TabList.svelte +11 -31
  55. package/dist/tabs/TabPanel.svelte +42 -67
  56. package/dist/tabs/TabPanels.svelte +7 -18
  57. package/dist/textarea/Textarea.svelte +53 -84
  58. package/dist/transition/InternalTransitionChild.svelte +170 -259
  59. package/dist/transition/Transition.svelte +66 -96
  60. package/dist/transition/TransitionChild.svelte +11 -31
  61. package/dist/utils/DisabledProvider.svelte +3 -7
  62. package/dist/utils/ElementOrComponent.svelte +23 -43
  63. package/dist/utils/Generic.svelte +16 -27
  64. package/dist/utils/StableCollection.svelte +36 -54
  65. package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +12 -27
  66. package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +44 -88
  67. package/package.json +4 -4
@@ -1,36 +1,26 @@
1
- <script lang="ts" module>
2
- import type { ElementType, Props, PropsOf } from "../utils/types.js"
3
-
4
- let DEFAULT_DESCRIPTION_TAG = "p" as const
5
-
6
- export type DescriptionProps<TTag extends ElementType = typeof DEFAULT_DESCRIPTION_TAG> = Props<TTag>
1
+ <script lang="ts" module>let DEFAULT_DESCRIPTION_TAG = "p";
7
2
  </script>
8
3
 
9
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_DESCRIPTION_TAG">
10
- import { useId } from "../hooks/use-id.js"
11
- import { useDisabled } from "../hooks/use-disabled.js"
12
- import { useDescriptionContext } from "./context.svelte.js"
13
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
14
- import { untrack } from "svelte"
15
-
16
- const internalId = useId()
17
- const providedDisabled = useDisabled()
18
-
19
- let {
20
- ref = $bindable(),
21
- id = `headlessui-description-${internalId}` as PropsOf<TTag>["id"],
22
- ...theirProps
23
- }: { as?: TTag } & DescriptionProps<TTag> = $props()
24
-
25
- const { register } = useDescriptionContext()
26
- $effect(() => {
27
- id
28
- return untrack(() => register(id))
29
- })
30
-
31
- const disabled = $derived(providedDisabled.current || false)
32
- const slot = $derived({ disabled })
33
- const ourProps = $derived({ id })
4
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_DESCRIPTION_TAG">import { useId } from "../hooks/use-id.js";
5
+ import { useDisabled } from "../hooks/use-disabled.js";
6
+ import { useDescriptionContext } from "./context.svelte.js";
7
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
8
+ import { untrack } from "svelte";
9
+ const internalId = useId();
10
+ const providedDisabled = useDisabled();
11
+ let {
12
+ ref = $bindable(),
13
+ id = `headlessui-description-${internalId}`,
14
+ ...theirProps
15
+ } = $props();
16
+ const { register } = useDescriptionContext();
17
+ $effect(() => {
18
+ id;
19
+ return untrack(() => register(id));
20
+ });
21
+ const disabled = $derived(providedDisabled.current || false);
22
+ const slot = $derived({ disabled });
23
+ const ourProps = $derived({ id });
34
24
  </script>
35
25
 
36
26
  <ElementOrComponent
@@ -1,331 +1,239 @@
1
- <script lang="ts" module>
2
- import type { ElementType, Props } from "../utils/types.js"
3
- import { RenderFeatures, type PropsForFeatures } from "../utils/render.js"
4
-
5
- export const DEFAULT_DIALOG_TAG = "div" as const
6
- export type DialogRenderPropArg = {
7
- open: boolean
8
- }
9
- type DialogPropsWeControl = "aria-describedby" | "aria-labelledby" | "aria-modal"
10
-
11
- export const DialogRenderFeatures = RenderFeatures.RenderStrategy | RenderFeatures.Static
12
-
13
- export type DialogProps<TTag extends ElementType = typeof DEFAULT_DIALOG_TAG> = Props<
14
- TTag,
15
- DialogRenderPropArg,
16
- DialogPropsWeControl,
17
- PropsForFeatures<typeof DialogRenderFeatures> & {
18
- as?: TTag
19
- id?: string
20
- open?: boolean
21
- onclose(value: boolean): void
22
- initialFocus?: HTMLElement
23
- role?: "dialog" | "alertdialog"
24
- autofocus?: boolean
25
- transition?: boolean
26
- __demoMode?: boolean
27
- }
28
- >
1
+ <script lang="ts" module>import { RenderFeatures } from "../utils/render.js";
2
+ export const DEFAULT_DIALOG_TAG = "div";
3
+ export const DialogRenderFeatures = RenderFeatures.RenderStrategy | RenderFeatures.Static;
29
4
  </script>
30
5
 
31
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_DIALOG_TAG">
32
- import { useId } from "../hooks/use-id.js"
33
- import { useMainTreeNode, useRootContainers } from "../hooks/use-root-containers.svelte.js"
34
- import { clearOpenClosedContext, State, useOpenClosed } from "../internal/open-closed.js"
35
- import { useNestedPortals } from "../portal/InternalPortal.svelte"
36
- import { getOwnerDocument } from "../utils/owner.js"
37
- import { useInertOthers } from "../hooks/use-inert-others.svelte.js"
38
- import { useOutsideClick } from "../hooks/use-outside-click.svelte.js"
39
- import { useEscape } from "../hooks/use-escape.svelte.js"
40
- import { useScrollLock } from "../hooks/use-scroll-lock.svelte.js"
41
- import { useOnDisappear } from "../hooks/use-on-disappear.svelte.js"
42
- import { setContext } from "svelte"
43
- import { useIsTouchDevice } from "../hooks/use-is-touch-device.svelte.js"
44
- import FocusTrap, { FocusTrapFeatures } from "../focus-trap/FocusTrap.svelte"
45
- import Portal from "../portal/Portal.svelte"
46
- import PortalGroup from "../portal/PortalGroup.svelte"
47
- import ForcePortalRoot from "../internal/ForcePortalRoot.svelte"
48
- import { createCloseContext } from "../internal/close-provider.js"
49
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
50
- import { DialogStates, type DialogContext, type StateDefinition } from "./context.svelte.js"
51
- import { useDescriptions } from "../description/context.svelte.js"
52
- import MainTreeProvider from "../internal/MainTreeProvider.svelte"
53
- import Transition from "../transition/Transition.svelte"
54
-
55
- const internalId = useId()
56
- let {
57
- ref = $bindable(),
58
- id = `headlessui-dialog-${internalId}`,
59
- open: theirOpen,
60
- onclose,
61
- initialFocus,
62
- role: theirRole = "dialog",
63
- autofocus = true,
64
- __demoMode = false,
65
- unmount = false,
66
- transition = false,
67
- ...theirProps
68
- }: { as?: TTag } & DialogProps<TTag> = $props()
69
-
70
- // Validations
71
- const usesOpenClosedState = useOpenClosed()
72
- const hasOpen = $derived(theirOpen !== undefined || usesOpenClosedState)
73
- const hasOnClose = $derived(theirProps.hasOwnProperty("onclose"))
74
-
75
- $effect(() => {
76
- if (!hasOpen && !hasOnClose) {
77
- throw new Error(`You have to provide an \`open\` and an \`onclose\` prop to the \`Dialog\` component.`)
78
- }
79
-
80
- if (!hasOpen) {
81
- throw new Error(`You provided an \`onclose\` prop to the \`Dialog\`, but forgot an \`open\` prop.`)
82
- }
83
-
84
- if (!hasOnClose) {
85
- throw new Error(`You provided an \`open\` prop to the \`Dialog\`, but forgot an \`onclose\` prop.`)
86
- }
87
-
88
- if (!usesOpenClosedState && typeof open !== "boolean") {
89
- throw new Error(
90
- `You provided an \`open\` prop to the \`Dialog\`, but the value is not a boolean. Received: ${open}`
91
- )
92
- }
93
-
94
- if (typeof theirProps.onclose !== "function") {
95
- throw new Error(
96
- `You provided an \`onclose\` prop to the \`Dialog\`, but the value is not a function. Received: ${theirProps.onclose}`
97
- )
98
- }
99
- })
100
-
101
- let didWarnOnRole = $state(false)
102
-
103
- const role = $derived.by(() => {
104
- if (theirRole === "dialog" || theirRole === "alertdialog") {
105
- return theirRole
106
- }
107
-
108
- if (!didWarnOnRole) {
109
- didWarnOnRole = true
110
- console.warn(
111
- `Invalid role [${theirRole}] passed to <Dialog />. Only \`dialog\` and and \`alertdialog\` are supported. Using \`dialog\` instead.`
112
- )
113
- }
114
-
115
- return "dialog"
116
- })
117
-
118
- // Update the `open` prop based on the open closed state
119
- const open = $derived(
120
- theirOpen === undefined && usesOpenClosedState !== null
121
- ? (usesOpenClosedState.value & State.Open) === State.Open
122
- : theirOpen
123
- )
124
-
125
- const ownerDocument = $derived(getOwnerDocument(ref))
126
-
127
- const dialogState = $derived(open ? DialogStates.Open : DialogStates.Closed)
128
-
129
- let _state = $state({
130
- titleId: null,
131
- panelRef: null,
132
- } as StateDefinition)
133
-
134
- const close = $derived(() => onclose(false))
135
-
136
- const setTitleId = (id: string | null) => (_state.titleId = id)
137
-
138
- const enabled = $derived(dialogState === DialogStates.Open)
139
- const nestedPortals = useNestedPortals()
140
- const { portals } = $derived(nestedPortals)
141
-
142
- // We use this because reading these values during initial render(s)
143
- // can result in `null` rather then the actual elements
144
- // This doesn't happen when using certain components like a
145
- // `<Dialog.Title>` because they cause the parent to re-render
146
- const defaultContainer: { readonly current: HTMLElement | undefined } = {
147
- get current() {
148
- return _state.panelRef ?? ref
149
- },
6
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_DIALOG_TAG">import { useId } from "../hooks/use-id.js";
7
+ import { useMainTreeNode, useRootContainers } from "../hooks/use-root-containers.svelte.js";
8
+ import { clearOpenClosedContext, State, useOpenClosed } from "../internal/open-closed.js";
9
+ import { useNestedPortals } from "../portal/InternalPortal.svelte";
10
+ import { getOwnerDocument } from "../utils/owner.js";
11
+ import { useInertOthers } from "../hooks/use-inert-others.svelte.js";
12
+ import { useOutsideClick } from "../hooks/use-outside-click.svelte.js";
13
+ import { useEscape } from "../hooks/use-escape.svelte.js";
14
+ import { useScrollLock } from "../hooks/use-scroll-lock.svelte.js";
15
+ import { useOnDisappear } from "../hooks/use-on-disappear.svelte.js";
16
+ import { setContext } from "svelte";
17
+ import { useIsTouchDevice } from "../hooks/use-is-touch-device.svelte.js";
18
+ import FocusTrap, { FocusTrapFeatures } from "../focus-trap/FocusTrap.svelte";
19
+ import Portal from "../portal/Portal.svelte";
20
+ import PortalGroup from "../portal/PortalGroup.svelte";
21
+ import ForcePortalRoot from "../internal/ForcePortalRoot.svelte";
22
+ import { createCloseContext } from "../internal/close-provider.js";
23
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
24
+ import { DialogStates } from "./context.svelte.js";
25
+ import { useDescriptions } from "../description/context.svelte.js";
26
+ import MainTreeProvider from "../internal/MainTreeProvider.svelte";
27
+ import Transition from "../transition/Transition.svelte";
28
+ const internalId = useId();
29
+ let {
30
+ ref = $bindable(),
31
+ id = `headlessui-dialog-${internalId}`,
32
+ open: theirOpen,
33
+ onclose,
34
+ initialFocus,
35
+ role: theirRole = "dialog",
36
+ autofocus = true,
37
+ __demoMode = false,
38
+ unmount = false,
39
+ transition = false,
40
+ ...theirProps
41
+ } = $props();
42
+ const usesOpenClosedState = useOpenClosed();
43
+ const hasOpen = $derived(theirOpen !== void 0 || usesOpenClosedState);
44
+ const hasOnClose = $derived(theirProps.hasOwnProperty("onclose"));
45
+ $effect(() => {
46
+ if (!hasOpen && !hasOnClose) {
47
+ throw new Error(`You have to provide an \`open\` and an \`onclose\` prop to the \`Dialog\` component.`);
150
48
  }
151
-
152
- const mainTreeNode = useMainTreeNode()
153
- let { resolvedContainers: resolvedRootContainers } = $derived(
154
- useRootContainers({
155
- get mainTreeNode() {
156
- return mainTreeNode.node
157
- },
158
- get portals() {
159
- return portals
160
- },
161
- get defaultContainers() {
162
- return defaultContainer.current ? [defaultContainer.current] : []
163
- },
164
- })
165
- )
166
-
167
- // When the `Dialog` is wrapped in a `Transition` (or another Headless UI component that exposes
168
- // the OpenClosed state) then we get some information via context about its state. When the
169
- // `Transition` is about to close, then the `State.Closing` state will be exposed. This allows us
170
- // to enable/disable certain functionality in the `Dialog` upfront instead of waiting until the
171
- // `Transition` is done transitioning.
172
- const isClosing = $derived(
173
- usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Closing) === State.Closing : false
174
- )
175
-
176
- // Ensure other elements can't be interacted with
177
- const inertOthersEnabled = $derived(__demoMode ? false : isClosing ? false : enabled)
178
- useInertOthers({
179
- get enabled() {
180
- return inertOthersEnabled
181
- },
182
- elements: {
183
- get allowed() {
184
- return [
185
- // Allow the headlessui-portal of the Dialog to be interactive. This
186
- // contains the current dialog and the necessary focus guard elements.
187
- ref?.closest<HTMLElement>("[data-headlessui-portal]") ?? null,
188
- ]
189
- },
190
- get disallowed() {
191
- return [
192
- // Disallow the "main" tree root node
193
- mainTreeNode.node?.closest<HTMLElement>("body > *:not(#headlessui-portal-root)") ?? null,
194
- ]
195
- },
196
- },
197
- })
198
-
199
- // Close Dialog on outside click
200
- useOutsideClick({
201
- get enabled() {
202
- return enabled
203
- },
204
- get containers() {
205
- return resolvedRootContainers
206
- },
207
- cb(event) {
208
- event.preventDefault()
209
- close()
210
- },
211
- })
212
-
213
- // Handle `Escape` to close
214
- useEscape({
215
- get enabled() {
216
- return enabled
217
- },
218
- get view() {
219
- return ownerDocument?.defaultView ?? null
220
- },
221
- cb(event) {
222
- event.preventDefault()
223
- event.stopPropagation()
224
-
225
- // Ensure that we blur the current activeElement to prevent maintaining
226
- // focus and potentially scrolling the page to the end (because the Dialog
227
- // is rendered in a Portal at the end of the document.body and the browser
228
- // tries to keep the focused element in view)
229
- //
230
- // Typically only happens in Safari.
231
- if (
232
- document.activeElement &&
233
- "blur" in document.activeElement &&
234
- typeof document.activeElement.blur === "function"
235
- ) {
236
- document.activeElement.blur()
237
- }
238
-
239
- close()
240
- },
241
- })
242
-
243
- // Scroll lock
244
- const scrollLockEnabled = $derived(__demoMode ? false : isClosing ? false : enabled)
245
- useScrollLock({
246
- get enabled() {
247
- return scrollLockEnabled
248
- },
249
- get ownerDocument() {
250
- return ownerDocument
251
- },
252
- resolveAllowedContainers() {
253
- return resolvedRootContainers
254
- },
255
- })
256
-
257
- // Ensure we close the dialog as soon as the dialog itself becomes hidden
258
- useOnDisappear({
259
- get enabled() {
260
- return enabled
261
- },
262
- get ref() {
263
- return ref
264
- },
265
- get ondisappear() {
266
- return close
267
- },
268
- })
269
-
270
- const describedby = useDescriptions()
271
-
272
- setContext<DialogContext>("DialogContext", {
273
- get titleId() {
274
- return _state.titleId
275
- },
276
- get panelRef() {
277
- return _state.panelRef
278
- },
279
- get dialogState() {
280
- return dialogState
281
- },
282
- get close() {
283
- return close
49
+ if (!hasOpen) {
50
+ throw new Error(`You provided an \`onclose\` prop to the \`Dialog\`, but forgot an \`open\` prop.`);
51
+ }
52
+ if (!hasOnClose) {
53
+ throw new Error(`You provided an \`open\` prop to the \`Dialog\`, but forgot an \`onclose\` prop.`);
54
+ }
55
+ if (!usesOpenClosedState && typeof open !== "boolean") {
56
+ throw new Error(
57
+ `You provided an \`open\` prop to the \`Dialog\`, but the value is not a boolean. Received: ${open}`
58
+ );
59
+ }
60
+ if (typeof theirProps.onclose !== "function") {
61
+ throw new Error(
62
+ `You provided an \`onclose\` prop to the \`Dialog\`, but the value is not a function. Received: ${theirProps.onclose}`
63
+ );
64
+ }
65
+ });
66
+ let didWarnOnRole = $state(false);
67
+ const role = $derived.by(() => {
68
+ if (theirRole === "dialog" || theirRole === "alertdialog") {
69
+ return theirRole;
70
+ }
71
+ if (!didWarnOnRole) {
72
+ didWarnOnRole = true;
73
+ console.warn(
74
+ `Invalid role [${theirRole}] passed to <Dialog />. Only \`dialog\` and and \`alertdialog\` are supported. Using \`dialog\` instead.`
75
+ );
76
+ }
77
+ return "dialog";
78
+ });
79
+ const open = $derived(
80
+ theirOpen === void 0 && usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Open) === State.Open : theirOpen
81
+ );
82
+ const ownerDocument = $derived(getOwnerDocument(ref));
83
+ const dialogState = $derived(open ? DialogStates.Open : DialogStates.Closed);
84
+ let _state = $state({
85
+ titleId: null,
86
+ panelRef: null
87
+ });
88
+ const close = $derived(() => onclose(false));
89
+ const setTitleId = (id2) => _state.titleId = id2;
90
+ const enabled = $derived(dialogState === DialogStates.Open);
91
+ const nestedPortals = useNestedPortals();
92
+ const { portals } = $derived(nestedPortals);
93
+ const defaultContainer = {
94
+ get current() {
95
+ return _state.panelRef ?? ref;
96
+ }
97
+ };
98
+ const mainTreeNode = useMainTreeNode();
99
+ let { resolvedContainers: resolvedRootContainers } = $derived(
100
+ useRootContainers({
101
+ get mainTreeNode() {
102
+ return mainTreeNode.node;
284
103
  },
285
- get unmount() {
286
- return unmount
104
+ get portals() {
105
+ return portals;
287
106
  },
288
- setTitleId,
289
- })
290
-
291
- const slot = $derived({ open: dialogState === DialogStates.Open } satisfies DialogRenderPropArg)
292
-
293
- const ourProps = $derived({
294
- id,
295
- role,
296
- tabIndex: -1,
297
- "aria-modal": __demoMode ? undefined : dialogState === DialogStates.Open ? true : undefined,
298
- "aria-labelledby": _state.titleId,
299
- "aria-describedby": describedby.value,
300
- unmount,
301
- })
302
-
303
- const shouldMoveFocusInside = !useIsTouchDevice().value
304
- const focusTrapFeatures = $derived.by(() => {
305
- let focusTrapFeatures = FocusTrapFeatures.None
306
-
307
- if (enabled && !__demoMode) {
308
- focusTrapFeatures |= FocusTrapFeatures.RestoreFocus
309
- focusTrapFeatures |= FocusTrapFeatures.TabLock
310
-
311
- if (autofocus) {
312
- focusTrapFeatures |= FocusTrapFeatures.AutoFocus
313
- }
314
-
315
- if (shouldMoveFocusInside) {
316
- focusTrapFeatures |= FocusTrapFeatures.InitialFocus
317
- }
107
+ get defaultContainers() {
108
+ return defaultContainer.current ? [defaultContainer.current] : [];
318
109
  }
319
-
320
- return focusTrapFeatures
321
110
  })
322
-
323
- clearOpenClosedContext()
324
- createCloseContext({
325
- get close() {
326
- return close
111
+ );
112
+ const isClosing = $derived(
113
+ usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Closing) === State.Closing : false
114
+ );
115
+ const inertOthersEnabled = $derived(__demoMode ? false : isClosing ? false : enabled);
116
+ useInertOthers({
117
+ get enabled() {
118
+ return inertOthersEnabled;
119
+ },
120
+ elements: {
121
+ get allowed() {
122
+ return [
123
+ // Allow the headlessui-portal of the Dialog to be interactive. This
124
+ // contains the current dialog and the necessary focus guard elements.
125
+ ref?.closest("[data-headlessui-portal]") ?? null
126
+ ];
327
127
  },
328
- })
128
+ get disallowed() {
129
+ return [
130
+ // Disallow the "main" tree root node
131
+ mainTreeNode.node?.closest("body > *:not(#headlessui-portal-root)") ?? null
132
+ ];
133
+ }
134
+ }
135
+ });
136
+ useOutsideClick({
137
+ get enabled() {
138
+ return enabled;
139
+ },
140
+ get containers() {
141
+ return resolvedRootContainers;
142
+ },
143
+ cb(event) {
144
+ event.preventDefault();
145
+ close();
146
+ }
147
+ });
148
+ useEscape({
149
+ get enabled() {
150
+ return enabled;
151
+ },
152
+ get view() {
153
+ return ownerDocument?.defaultView ?? null;
154
+ },
155
+ cb(event) {
156
+ event.preventDefault();
157
+ event.stopPropagation();
158
+ if (document.activeElement && "blur" in document.activeElement && typeof document.activeElement.blur === "function") {
159
+ document.activeElement.blur();
160
+ }
161
+ close();
162
+ }
163
+ });
164
+ const scrollLockEnabled = $derived(__demoMode ? false : isClosing ? false : enabled);
165
+ useScrollLock({
166
+ get enabled() {
167
+ return scrollLockEnabled;
168
+ },
169
+ get ownerDocument() {
170
+ return ownerDocument;
171
+ },
172
+ resolveAllowedContainers() {
173
+ return resolvedRootContainers;
174
+ }
175
+ });
176
+ useOnDisappear({
177
+ get enabled() {
178
+ return enabled;
179
+ },
180
+ get ref() {
181
+ return ref;
182
+ },
183
+ get ondisappear() {
184
+ return close;
185
+ }
186
+ });
187
+ const describedby = useDescriptions();
188
+ setContext("DialogContext", {
189
+ get titleId() {
190
+ return _state.titleId;
191
+ },
192
+ get panelRef() {
193
+ return _state.panelRef;
194
+ },
195
+ get dialogState() {
196
+ return dialogState;
197
+ },
198
+ get close() {
199
+ return close;
200
+ },
201
+ get unmount() {
202
+ return unmount;
203
+ },
204
+ setTitleId
205
+ });
206
+ const slot = $derived({ open: dialogState === DialogStates.Open });
207
+ const ourProps = $derived({
208
+ id,
209
+ role,
210
+ tabIndex: -1,
211
+ "aria-modal": __demoMode ? void 0 : dialogState === DialogStates.Open ? true : void 0,
212
+ "aria-labelledby": _state.titleId,
213
+ "aria-describedby": describedby.value,
214
+ unmount
215
+ });
216
+ const shouldMoveFocusInside = !useIsTouchDevice().value;
217
+ const focusTrapFeatures = $derived.by(() => {
218
+ let focusTrapFeatures2 = FocusTrapFeatures.None;
219
+ if (enabled && !__demoMode) {
220
+ focusTrapFeatures2 |= FocusTrapFeatures.RestoreFocus;
221
+ focusTrapFeatures2 |= FocusTrapFeatures.TabLock;
222
+ if (autofocus) {
223
+ focusTrapFeatures2 |= FocusTrapFeatures.AutoFocus;
224
+ }
225
+ if (shouldMoveFocusInside) {
226
+ focusTrapFeatures2 |= FocusTrapFeatures.InitialFocus;
227
+ }
228
+ }
229
+ return focusTrapFeatures2;
230
+ });
231
+ clearOpenClosedContext();
232
+ createCloseContext({
233
+ get close() {
234
+ return close;
235
+ }
236
+ });
329
237
  </script>
330
238
 
331
239
  {#snippet internal(transitionProps?: Record<string, any>)}
@@ -1,34 +1,17 @@
1
- <script lang="ts" module>
2
- import type { ElementType, Props } from "../utils/types.js"
3
-
4
- let DEFAULT_BACKDROP_TAG = "div" as const
5
- type BackdropRenderPropArg = {
6
- open: boolean
7
- }
8
-
9
- export type DialogBackdropProps<TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG> = Props<
10
- TTag,
11
- BackdropRenderPropArg,
12
- never,
13
- { transition?: boolean }
14
- >
1
+ <script lang="ts" module>let DEFAULT_BACKDROP_TAG = "div";
15
2
  </script>
16
3
 
17
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG">
18
- import { DialogStates, useDialogContext } from "./context.svelte.js"
19
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
20
- import { mergeProps } from "../utils/render.js"
21
- import TransitionChild from "../transition/TransitionChild.svelte"
22
-
23
- let { ref = $bindable(), transition = false, ...theirProps }: { as?: TTag } & DialogBackdropProps<TTag> = $props()
24
- const _state = useDialogContext("Dialog.Panel")
25
- const { dialogState, unmount } = $derived(_state)
26
-
27
- const slot = $derived({ open: dialogState === DialogStates.Open } satisfies BackdropRenderPropArg)
28
-
29
- const ourProps = mergeProps({
30
- "aria-hidden": true,
31
- })
4
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG">import { DialogStates, useDialogContext } from "./context.svelte.js";
5
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
6
+ import { mergeProps } from "../utils/render.js";
7
+ import TransitionChild from "../transition/TransitionChild.svelte";
8
+ let { ref = $bindable(), transition = false, ...theirProps } = $props();
9
+ const _state = useDialogContext("Dialog.Panel");
10
+ const { dialogState, unmount } = $derived(_state);
11
+ const slot = $derived({ open: dialogState === DialogStates.Open });
12
+ const ourProps = mergeProps({
13
+ "aria-hidden": true
14
+ });
32
15
  </script>
33
16
 
34
17
  {#if transition}