@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.
- package/dist/button/Button.svelte +54 -84
- package/dist/checkbox/Checkbox.svelte +120 -173
- package/dist/checkbox/Checkbox.svelte.d.ts +1 -1
- package/dist/close-button/CloseButton.svelte +6 -12
- package/dist/combobox/Combobox.svelte +3 -50
- package/dist/data-interactive/DataInteractive.svelte +29 -55
- package/dist/description/Description.svelte +21 -31
- package/dist/dialog/Dialog.svelte +228 -320
- package/dist/dialog/DialogBackdrop.svelte +12 -29
- package/dist/dialog/DialogPanel.svelte +25 -48
- package/dist/dialog/DialogTitle.svelte +23 -38
- package/dist/field/Field.svelte +25 -47
- package/dist/fieldset/Fieldset.svelte +29 -50
- package/dist/focus-trap/FocusTrap.svelte +283 -419
- package/dist/input/Input.svelte +53 -84
- package/dist/internal/FloatingProvider.svelte +9 -14
- package/dist/internal/FocusSentinel.svelte +8 -16
- package/dist/internal/ForcePortalRoot.svelte +3 -7
- package/dist/internal/FormFields.svelte +34 -47
- package/dist/internal/FormFieldsProvider.svelte +5 -9
- package/dist/internal/FormResolver.svelte +15 -20
- package/dist/internal/Hidden.svelte +29 -50
- package/dist/internal/MainTreeProvider.svelte +36 -89
- package/dist/internal/Portal.svelte +14 -18
- package/dist/label/Label.svelte +58 -93
- package/dist/legend/Legend.svelte +3 -12
- package/dist/listbox/Listbox.svelte +387 -525
- package/dist/listbox/Listbox.svelte.d.ts +1 -1
- package/dist/listbox/ListboxButton.svelte +127 -173
- package/dist/listbox/ListboxOption.svelte +129 -170
- package/dist/listbox/ListboxOptions.svelte +304 -400
- package/dist/listbox/ListboxSelectedOption.svelte +15 -38
- package/dist/menu/Menu.svelte +51 -78
- package/dist/menu/MenuButton.svelte +117 -157
- package/dist/menu/MenuHeading.svelte +14 -32
- package/dist/menu/MenuItem.svelte +107 -142
- package/dist/menu/MenuItems.svelte +229 -301
- package/dist/menu/MenuSection.svelte +9 -24
- package/dist/menu/MenuSeparator.svelte +4 -17
- package/dist/popover/Popover.svelte +150 -216
- package/dist/popover/PopoverBackdrop.svelte +41 -67
- package/dist/popover/PopoverButton.svelte +212 -292
- package/dist/popover/PopoverGroup.svelte +35 -62
- package/dist/popover/PopoverPanel.svelte +229 -311
- package/dist/portal/InternalPortal.svelte +85 -141
- package/dist/portal/Portal.svelte +2 -5
- package/dist/portal/PortalGroup.svelte +9 -30
- package/dist/select/Select.svelte +68 -98
- package/dist/switch/Switch.svelte +132 -179
- package/dist/switch/SwitchGroup.svelte +31 -44
- package/dist/tabs/Tab.svelte +142 -194
- package/dist/tabs/TabGroup.svelte +56 -86
- package/dist/tabs/TabGroup.svelte.d.ts +1 -1
- package/dist/tabs/TabList.svelte +11 -31
- package/dist/tabs/TabPanel.svelte +42 -67
- package/dist/tabs/TabPanels.svelte +7 -18
- package/dist/textarea/Textarea.svelte +53 -84
- package/dist/transition/InternalTransitionChild.svelte +170 -259
- package/dist/transition/Transition.svelte +66 -96
- package/dist/transition/TransitionChild.svelte +11 -31
- package/dist/utils/DisabledProvider.svelte +3 -7
- package/dist/utils/ElementOrComponent.svelte +23 -43
- package/dist/utils/Generic.svelte +16 -27
- package/dist/utils/StableCollection.svelte +36 -54
- package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +12 -27
- package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +44 -88
- 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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
3
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
|
286
|
-
return
|
|
104
|
+
get portals() {
|
|
105
|
+
return portals;
|
|
287
106
|
},
|
|
288
|
-
|
|
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
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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}
|