@pzerelles/headlessui-svelte 2.1.2-next.3 → 2.1.2-next.31
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 +1 -1
- package/dist/button/Button.svelte.d.ts +9 -11
- package/dist/checkbox/Checkbox.svelte +4 -4
- package/dist/checkbox/Checkbox.svelte.d.ts +10 -14
- package/dist/close-button/CloseButton.svelte.d.ts +16 -18
- package/dist/data-interactive/DataInteractive.svelte.d.ts +8 -11
- package/dist/description/Description.svelte +19 -14
- package/dist/description/Description.svelte.d.ts +9 -11
- package/dist/description/context.svelte.js +14 -16
- package/dist/dialog/Dialog.svelte +245 -17
- package/dist/dialog/Dialog.svelte.d.ts +12 -14
- package/dist/dialog/DialogBackdrop.svelte +1 -1
- package/dist/dialog/DialogBackdrop.svelte.d.ts +9 -11
- package/dist/dialog/DialogPanel.svelte +1 -2
- package/dist/dialog/DialogPanel.svelte.d.ts +9 -11
- package/dist/dialog/DialogTitle.svelte.d.ts +8 -10
- package/dist/dialog/context.svelte.js +1 -1
- package/dist/field/Field.svelte +24 -12
- package/dist/field/Field.svelte.d.ts +9 -11
- package/dist/fieldset/Fieldset.svelte +1 -1
- package/dist/fieldset/Fieldset.svelte.d.ts +9 -11
- package/dist/focus-trap/FocusTrap.svelte +7 -14
- package/dist/focus-trap/FocusTrap.svelte.d.ts +11 -25
- package/dist/focus-trap/FocusTrapFeatures.d.ts +14 -0
- package/dist/focus-trap/FocusTrapFeatures.js +15 -0
- package/dist/hooks/use-controllable.svelte.js +2 -1
- package/dist/hooks/use-did-element-move.svelte.js +5 -10
- package/dist/hooks/use-disabled.d.ts +6 -1
- package/dist/hooks/use-disabled.js +10 -5
- package/dist/hooks/use-event-listener.svelte.d.ts +1 -1
- package/dist/hooks/use-event-listener.svelte.js +3 -1
- package/dist/hooks/use-root-containers.svelte.d.ts +2 -2
- package/dist/hooks/use-root-containers.svelte.js +5 -5
- package/dist/hooks/use-tab-direction.svelte.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/input/Input.svelte +3 -3
- package/dist/input/Input.svelte.d.ts +10 -14
- package/dist/internal/FloatingProvider.svelte +12 -0
- package/dist/internal/FloatingProvider.svelte.d.ts +6 -0
- package/dist/internal/FocusSentinel.svelte.d.ts +2 -18
- package/dist/internal/ForcePortalRoot.svelte.d.ts +2 -18
- package/dist/internal/FormFields.svelte +22 -19
- package/dist/internal/FormFields.svelte.d.ts +2 -18
- package/dist/internal/FormFieldsProvider.svelte +13 -0
- package/dist/internal/FormFieldsProvider.svelte.d.ts +5 -0
- package/dist/internal/FormResolver.svelte.d.ts +2 -18
- package/dist/internal/Hidden.svelte +18 -8
- package/dist/internal/Hidden.svelte.d.ts +11 -16
- package/dist/internal/HiddenFeatures.d.ts +5 -0
- package/dist/internal/HiddenFeatures.js +9 -0
- package/dist/internal/MainTreeProvider.svelte.d.ts +2 -18
- package/dist/internal/Portal.svelte.d.ts +2 -18
- package/dist/internal/floating-provider.svelte.d.ts +3 -0
- package/dist/internal/floating-provider.svelte.js +206 -0
- package/dist/internal/floating.svelte.d.ts +46 -22
- package/dist/internal/floating.svelte.js +90 -272
- package/dist/internal/form-fields.svelte.d.ts +10 -0
- package/dist/internal/form-fields.svelte.js +23 -0
- package/dist/label/Label.svelte +6 -5
- package/dist/label/Label.svelte.d.ts +9 -11
- package/dist/label/context.svelte.js +1 -1
- package/dist/legend/Legend.svelte +2 -2
- package/dist/legend/Legend.svelte.d.ts +4 -32
- package/dist/listbox/Listbox.svelte +47 -68
- package/dist/listbox/Listbox.svelte.d.ts +18 -80
- package/dist/listbox/ListboxButton.svelte +10 -10
- package/dist/listbox/ListboxButton.svelte.d.ts +10 -15
- package/dist/listbox/ListboxOption.svelte +10 -6
- package/dist/listbox/ListboxOption.svelte.d.ts +9 -12
- package/dist/listbox/ListboxOptions.svelte +108 -54
- package/dist/listbox/ListboxOptions.svelte.d.ts +9 -12
- package/dist/listbox/ListboxSelectedOption.svelte +2 -4
- package/dist/listbox/ListboxSelectedOption.svelte.d.ts +14 -16
- package/dist/listbox/context.svelte.d.ts +76 -0
- package/dist/listbox/context.svelte.js +36 -0
- package/dist/listbox/index.d.ts +4 -4
- package/dist/listbox/index.js +1 -1
- package/dist/menu/Menu.svelte +13 -191
- package/dist/menu/Menu.svelte.d.ts +9 -13
- package/dist/menu/MenuButton.svelte +4 -2
- package/dist/menu/MenuButton.svelte.d.ts +9 -12
- package/dist/menu/MenuHeading.svelte.d.ts +9 -12
- package/dist/menu/MenuItem.svelte.d.ts +11 -16
- package/dist/menu/MenuItems.svelte +15 -11
- package/dist/menu/MenuItems.svelte.d.ts +9 -12
- package/dist/menu/MenuSection.svelte.d.ts +8 -11
- package/dist/menu/MenuSeparator.svelte.d.ts +8 -12
- package/dist/menu/context.svelte.d.ts +2 -1
- package/dist/menu/context.svelte.js +212 -2
- package/dist/menu/index.d.ts +7 -7
- package/dist/popover/Popover.svelte +161 -0
- package/dist/popover/Popover.svelte.d.ts +39 -0
- package/dist/popover/PopoverBackdrop.svelte +56 -0
- package/dist/popover/PopoverBackdrop.svelte.d.ts +43 -0
- package/dist/popover/PopoverButton.svelte +246 -0
- package/dist/popover/PopoverButton.svelte.d.ts +42 -0
- package/dist/popover/PopoverGroup.svelte +43 -0
- package/dist/popover/PopoverGroup.svelte.d.ts +31 -0
- package/dist/popover/PopoverPanel.svelte +274 -0
- package/dist/popover/PopoverPanel.svelte.d.ts +51 -0
- package/dist/popover/context.svelte.d.ts +51 -0
- package/dist/popover/context.svelte.js +108 -0
- package/dist/popover/index.d.ts +5 -0
- package/dist/popover/index.js +5 -0
- package/dist/portal/InternalPortal.svelte.d.ts +9 -11
- package/dist/portal/Portal.svelte.d.ts +2 -6
- package/dist/portal/PortalGroup.svelte.d.ts +9 -11
- package/dist/select/Select.svelte +74 -0
- package/dist/select/Select.svelte.d.ts +46 -0
- package/dist/select/index.d.ts +1 -0
- package/dist/select/index.js +1 -0
- package/dist/switch/Switch.svelte +30 -20
- package/dist/switch/Switch.svelte.d.ts +10 -12
- package/dist/switch/SwitchGroup.svelte.d.ts +8 -10
- package/dist/tabs/Tab.svelte +8 -9
- package/dist/tabs/Tab.svelte.d.ts +9 -11
- package/dist/tabs/TabGroup.svelte +27 -190
- package/dist/tabs/TabGroup.svelte.d.ts +9 -31
- package/dist/tabs/TabList.svelte +4 -4
- package/dist/tabs/TabList.svelte.d.ts +8 -10
- package/dist/tabs/TabPanel.svelte +4 -5
- package/dist/tabs/TabPanel.svelte.d.ts +9 -11
- package/dist/tabs/TabPanels.svelte +3 -3
- package/dist/tabs/TabPanels.svelte.d.ts +8 -10
- package/dist/tabs/context.svelte.d.ts +31 -0
- package/dist/tabs/context.svelte.js +134 -0
- package/dist/textarea/Textarea.svelte +4 -4
- package/dist/textarea/Textarea.svelte.d.ts +21 -20
- package/dist/transition/InternalTransitionChild.svelte.d.ts +9 -11
- package/dist/transition/Transition.svelte.d.ts +9 -11
- package/dist/transition/TransitionChild.svelte.d.ts +9 -11
- package/dist/transition/context.svelte.js +2 -2
- package/dist/utils/DisabledProvider.svelte +6 -0
- package/dist/utils/DisabledProvider.svelte.d.ts +6 -0
- package/dist/utils/ElementOrComponent.svelte +2 -2
- package/dist/utils/ElementOrComponent.svelte.d.ts +12 -11
- package/dist/utils/Generic.svelte +10 -8
- package/dist/utils/Generic.svelte.d.ts +12 -15
- package/dist/utils/StableCollection.svelte.d.ts +2 -18
- package/dist/utils/alternative-types.d.ts +1 -2
- package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +17 -0
- package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte.d.ts +7 -0
- package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +50 -0
- package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte.d.ts +25 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.d.ts +6 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.js +158 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.d.ts +11 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.js +53 -0
- package/dist/utils/floating-ui/svelte/hooks/useId.svelte.d.ts +9 -0
- package/dist/utils/floating-ui/svelte/hooks/useId.svelte.js +28 -0
- package/dist/utils/floating-ui/svelte/hooks/useInteractions.svelte.d.ts +23 -0
- package/dist/utils/floating-ui/svelte/hooks/useInteractions.svelte.js +72 -0
- package/dist/utils/floating-ui/svelte/index.d.ts +5 -0
- package/dist/utils/floating-ui/svelte/index.js +5 -0
- package/dist/utils/floating-ui/svelte/inner.svelte.d.ts +83 -0
- package/dist/utils/floating-ui/svelte/inner.svelte.js +178 -0
- package/dist/utils/floating-ui/svelte/types.d.ts +114 -0
- package/dist/utils/floating-ui/svelte/types.js +1 -0
- package/dist/utils/floating-ui/svelte/utils/createPubSub.d.ts +5 -0
- package/dist/utils/floating-ui/svelte/utils/createPubSub.js +14 -0
- package/dist/utils/floating-ui/svelte/utils/getFloatingFocusElement.d.ts +2 -0
- package/dist/utils/floating-ui/svelte/utils/getFloatingFocusElement.js +13 -0
- package/dist/utils/floating-ui/svelte/utils/log.d.ts +2 -0
- package/dist/utils/floating-ui/svelte/utils/log.js +19 -0
- package/dist/utils/floating-ui/svelte/utils.d.ts +19 -0
- package/dist/utils/floating-ui/svelte/utils.js +136 -0
- package/dist/utils/floating-ui/svelte-dom/arrow.d.ts +22 -0
- package/dist/utils/floating-ui/svelte-dom/arrow.js +29 -0
- package/dist/utils/floating-ui/svelte-dom/index.d.ts +2 -0
- package/dist/utils/floating-ui/svelte-dom/index.js +2 -0
- package/dist/utils/floating-ui/svelte-dom/types.d.ts +80 -0
- package/dist/utils/floating-ui/svelte-dom/types.js +3 -0
- package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.d.ts +6 -0
- package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.js +182 -0
- package/dist/utils/floating-ui/svelte-dom/utils/deepEqual.d.ts +1 -0
- package/dist/utils/floating-ui/svelte-dom/utils/deepEqual.js +50 -0
- package/dist/utils/floating-ui/svelte-dom/utils/getDPR.d.ts +1 -0
- package/dist/utils/floating-ui/svelte-dom/utils/getDPR.js +7 -0
- package/dist/utils/floating-ui/svelte-dom/utils/roundByDPR.d.ts +1 -0
- package/dist/utils/floating-ui/svelte-dom/utils/roundByDPR.js +5 -0
- package/dist/utils/floating-ui/svelte-dom/utils/useLatestRef.d.ts +4 -0
- package/dist/utils/floating-ui/svelte-dom/utils/useLatestRef.js +7 -0
- package/dist/utils/id.d.ts +1 -1
- package/dist/utils/id.js +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/style.d.ts +2 -0
- package/dist/utils/style.js +6 -0
- package/dist/utils/types.d.ts +9 -13
- package/package.json +27 -26
- package/dist/dialog/InternalDialog.svelte +0 -233
- package/dist/dialog/InternalDialog.svelte.d.ts +0 -42
- package/dist/internal/HoistFormFields.svelte +0 -11
- package/dist/internal/HoistFormFields.svelte.d.ts +0 -21
- package/dist/internal/id.d.ts +0 -8
- package/dist/internal/id.js +0 -11
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { computePosition } from "@floating-ui/dom";
|
|
2
|
+
import { deepEqual } from "./utils/deepEqual.js";
|
|
3
|
+
import { getDPR } from "./utils/getDPR.js";
|
|
4
|
+
import { roundByDPR } from "./utils/roundByDPR.js";
|
|
5
|
+
import { useLatestRef } from "./utils/useLatestRef.js";
|
|
6
|
+
import { tick, untrack } from "svelte";
|
|
7
|
+
import { stylePropsToString } from "../../style.js";
|
|
8
|
+
/**
|
|
9
|
+
* Provides data to position a floating element.
|
|
10
|
+
* @see https://floating-ui.com/docs/useFloating
|
|
11
|
+
*/
|
|
12
|
+
export function useFloating(options = {}) {
|
|
13
|
+
const { placement = "bottom", strategy = "absolute", middleware = [], platform, elements: externalElements = {}, transform = true, whileElementsMounted, open, } = $derived(options);
|
|
14
|
+
const { reference: externalReference, floating: externalFloating } = $derived(externalElements);
|
|
15
|
+
let data = $state({
|
|
16
|
+
x: 0,
|
|
17
|
+
y: 0,
|
|
18
|
+
strategy,
|
|
19
|
+
placement,
|
|
20
|
+
middlewareData: {},
|
|
21
|
+
isPositioned: false,
|
|
22
|
+
});
|
|
23
|
+
const setData = (value) => (data = value);
|
|
24
|
+
let latestMiddleware = $state(middleware);
|
|
25
|
+
$effect(() => {
|
|
26
|
+
if (!deepEqual(latestMiddleware, middleware)) {
|
|
27
|
+
latestMiddleware = middleware;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
let _reference = $state(null);
|
|
31
|
+
let _floating = $state(null);
|
|
32
|
+
const setReference = (node) => {
|
|
33
|
+
if ((node ?? null) !== referenceRef.current) {
|
|
34
|
+
referenceRef.current = node ?? null;
|
|
35
|
+
_reference = node ?? null;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const setFloating = (node) => {
|
|
39
|
+
if ((node ?? null) !== floatingRef.current) {
|
|
40
|
+
floatingRef.current = node ?? null;
|
|
41
|
+
_floating = node ?? null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const referenceEl = $derived((externalReference || _reference));
|
|
45
|
+
const floatingEl = $derived(externalFloating || _floating);
|
|
46
|
+
const referenceRef = $state({ current: null });
|
|
47
|
+
const floatingRef = $state({ current: null });
|
|
48
|
+
const dataRef = $state({ current: data });
|
|
49
|
+
const hasWhileElementsMounted = whileElementsMounted != null;
|
|
50
|
+
const whileElementsMountedRef = useLatestRef({
|
|
51
|
+
get value() {
|
|
52
|
+
return whileElementsMounted;
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const platformRef = useLatestRef({
|
|
56
|
+
get value() {
|
|
57
|
+
return platform;
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const openRef = useLatestRef({
|
|
61
|
+
get value() {
|
|
62
|
+
return open;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
const update = () => {
|
|
66
|
+
if (!referenceRef.current || !floatingRef.current) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const config = {
|
|
70
|
+
placement,
|
|
71
|
+
strategy,
|
|
72
|
+
middleware: latestMiddleware,
|
|
73
|
+
};
|
|
74
|
+
if (platformRef.current) {
|
|
75
|
+
config.platform = platformRef.current;
|
|
76
|
+
}
|
|
77
|
+
computePosition(referenceRef.current, floatingRef.current, config).then(async (data) => {
|
|
78
|
+
const fullData = {
|
|
79
|
+
...data,
|
|
80
|
+
// The floating element's position may be recomputed while it's closed
|
|
81
|
+
// but still mounted (such as when transitioning out). To ensure
|
|
82
|
+
// `isPositioned` will be `false` initially on the next open, avoid
|
|
83
|
+
// setting it to `true` when `open === false` (must be specified).
|
|
84
|
+
isPositioned: openRef.current !== false,
|
|
85
|
+
};
|
|
86
|
+
if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
|
|
87
|
+
dataRef.current = fullData;
|
|
88
|
+
setData(fullData);
|
|
89
|
+
await tick();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
$effect(() => {
|
|
94
|
+
open;
|
|
95
|
+
untrack(() => {
|
|
96
|
+
if (open === false && dataRef.current.isPositioned) {
|
|
97
|
+
dataRef.current.isPositioned = false;
|
|
98
|
+
data.isPositioned = false;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
const isMountedRef = $state({ current: false });
|
|
103
|
+
$effect(() => {
|
|
104
|
+
isMountedRef.current = true;
|
|
105
|
+
return () => {
|
|
106
|
+
isMountedRef.current = false;
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
$effect(() => {
|
|
110
|
+
if (referenceEl)
|
|
111
|
+
referenceRef.current = referenceEl;
|
|
112
|
+
if (floatingEl)
|
|
113
|
+
floatingRef.current = floatingEl;
|
|
114
|
+
if (referenceEl && floatingEl) {
|
|
115
|
+
if (whileElementsMountedRef.current) {
|
|
116
|
+
return whileElementsMountedRef.current(referenceEl, floatingEl, update);
|
|
117
|
+
}
|
|
118
|
+
update();
|
|
119
|
+
}
|
|
120
|
+
}); //, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted])
|
|
121
|
+
const refs = $derived({
|
|
122
|
+
reference: referenceRef,
|
|
123
|
+
floating: floatingRef,
|
|
124
|
+
setReference,
|
|
125
|
+
setFloating,
|
|
126
|
+
});
|
|
127
|
+
const elements = $derived({ reference: referenceEl, floating: floatingEl });
|
|
128
|
+
const floatingStyles = $derived.by(() => {
|
|
129
|
+
const initialStyles = {
|
|
130
|
+
position: strategy,
|
|
131
|
+
left: 0,
|
|
132
|
+
top: 0,
|
|
133
|
+
};
|
|
134
|
+
if (!elements.floating) {
|
|
135
|
+
return stylePropsToString(initialStyles);
|
|
136
|
+
}
|
|
137
|
+
const x = roundByDPR(elements.floating, data.x);
|
|
138
|
+
const y = roundByDPR(elements.floating, data.y);
|
|
139
|
+
if (transform) {
|
|
140
|
+
return stylePropsToString({
|
|
141
|
+
...initialStyles,
|
|
142
|
+
transform: `translate(${x}px, ${y}px)`,
|
|
143
|
+
...(getDPR(elements.floating) >= 1.5 && { "will-change": "transform" }),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return stylePropsToString({
|
|
147
|
+
position: strategy,
|
|
148
|
+
left: x,
|
|
149
|
+
top: y,
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
get placement() {
|
|
154
|
+
return data.placement;
|
|
155
|
+
},
|
|
156
|
+
get strategy() {
|
|
157
|
+
return data.strategy;
|
|
158
|
+
},
|
|
159
|
+
get middlewareData() {
|
|
160
|
+
return data.middlewareData;
|
|
161
|
+
},
|
|
162
|
+
get x() {
|
|
163
|
+
return data.x;
|
|
164
|
+
},
|
|
165
|
+
get y() {
|
|
166
|
+
return data.y;
|
|
167
|
+
},
|
|
168
|
+
get isPositioned() {
|
|
169
|
+
return data.isPositioned;
|
|
170
|
+
},
|
|
171
|
+
update,
|
|
172
|
+
get refs() {
|
|
173
|
+
return refs;
|
|
174
|
+
},
|
|
175
|
+
get elements() {
|
|
176
|
+
return elements;
|
|
177
|
+
},
|
|
178
|
+
get floatingStyles() {
|
|
179
|
+
return floatingStyles;
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deepEqual(a: any, b: any): boolean;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Fork of `fast-deep-equal` that only does the comparisons we need and compares
|
|
2
|
+
// functions
|
|
3
|
+
export function deepEqual(a, b) {
|
|
4
|
+
if (a === b) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
if (typeof a !== typeof b) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if (typeof a === "function" && a.toString() === b.toString()) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
let length;
|
|
14
|
+
let i;
|
|
15
|
+
let keys;
|
|
16
|
+
if (a && b && typeof a === "object") {
|
|
17
|
+
if (Array.isArray(a)) {
|
|
18
|
+
length = a.length;
|
|
19
|
+
if (length !== b.length)
|
|
20
|
+
return false;
|
|
21
|
+
for (i = length; i-- !== 0;) {
|
|
22
|
+
if (!deepEqual(a[i], b[i])) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
keys = Object.keys(a);
|
|
29
|
+
length = keys.length;
|
|
30
|
+
if (length !== Object.keys(b).length) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
for (i = length; i-- !== 0;) {
|
|
34
|
+
if (!{}.hasOwnProperty.call(b, keys[i])) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (i = length; i-- !== 0;) {
|
|
39
|
+
const key = keys[i];
|
|
40
|
+
if (key === "_owner" && a.$$typeof) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (!deepEqual(a[key], b[key])) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return a !== a && b !== b;
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getDPR(element: Element): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function roundByDPR(element: Element, value: number): number;
|
package/dist/utils/id.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const alphaid: (size?: number) => string;
|
|
2
2
|
export declare const htmlid: (size?: number) => string;
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const useProvidedId: () => string | undefined;
|
|
4
4
|
export declare const createIdContext: (id: string) => string | undefined;
|
package/dist/utils/id.js
CHANGED
|
@@ -2,5 +2,5 @@ import { nanoid, customAlphabet } from "nanoid";
|
|
|
2
2
|
import { getContext, setContext } from "svelte";
|
|
3
3
|
export const alphaid = customAlphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
|
|
4
4
|
export const htmlid = (size = 10) => alphaid(1) + nanoid(size - 1);
|
|
5
|
-
export const
|
|
5
|
+
export const useProvidedId = () => getContext("Id");
|
|
6
6
|
export const createIdContext = (id) => setContext("Id", id);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const camelToKebab = (s) => s.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
2
|
+
export const stylePropsToString = (props) => {
|
|
3
|
+
return Object.entries(props)
|
|
4
|
+
.map(([key, value]) => `${camelToKebab(key)}: ${typeof value === "number" ? `${value}px` : value}`)
|
|
5
|
+
.join(";");
|
|
6
|
+
};
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
import type { Snippet } from "svelte";
|
|
2
2
|
import type { SvelteHTMLElements } from "svelte/elements";
|
|
3
|
-
export
|
|
4
|
-
"svelte:fragment": {};
|
|
5
|
-
}
|
|
6
|
-
export type ElementType = keyof SvelteHTMLProps;
|
|
3
|
+
export type ElementType = keyof SvelteHTMLElements;
|
|
7
4
|
export type Expand<T> = T extends infer O ? {
|
|
8
5
|
[K in keyof O]: O[K];
|
|
9
6
|
} : never;
|
|
10
|
-
export type PropsOf<TTag extends ElementType> =
|
|
11
|
-
|
|
12
|
-
type PropsWeControl = "as" | "children" | "refName" | "class";
|
|
7
|
+
export type PropsOf<TTag extends ElementType> = SvelteHTMLElements[TTag];
|
|
8
|
+
type PropsWeControl = "as" | "children" | "class" | "ref" | "slot";
|
|
13
9
|
type CleanProps<TTag extends ElementType, TOmittableProps extends PropertyKey = never> = Omit<PropsOf<TTag>, TOmittableProps | PropsWeControl>;
|
|
14
10
|
type OurProps<TSlot> = {
|
|
15
|
-
children?:
|
|
11
|
+
children?: Snippet<[{
|
|
12
|
+
slot: TSlot;
|
|
13
|
+
props: Record<string, any>;
|
|
14
|
+
}]>;
|
|
15
|
+
class?: string | null | ((bag: TSlot) => string);
|
|
16
16
|
ref?: HTMLElement;
|
|
17
17
|
};
|
|
18
|
-
type
|
|
19
|
-
type ClassNameOverride<TTag extends ElementType, TSlot = {}> = true extends HasProperty<PropsOf<TTag>, "class"> ? {
|
|
20
|
-
class?: PropsOf<TTag>["class"] | ((bag: TSlot) => string);
|
|
21
|
-
} : {};
|
|
22
|
-
export type Props<TTag extends ElementType, TSlot = {}, TOmittableProps extends PropertyKey = never, Overrides = {}> = CleanProps<TTag, TOmittableProps | keyof Overrides> & OurProps<TSlot> & ClassNameOverride<TTag, TSlot> & Overrides;
|
|
18
|
+
export type Props<TTag extends ElementType, TSlot = {}, TOmittableProps extends PropertyKey = never, Overrides = {}> = CleanProps<TTag, TOmittableProps | keyof Overrides> & OurProps<TSlot> & Overrides;
|
|
23
19
|
export type EnsureArray<T> = T extends any[] ? T : Expand<T>[];
|
|
24
20
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pzerelles/headlessui-svelte",
|
|
3
|
-
"version": "2.1.2-next.
|
|
3
|
+
"version": "2.1.2-next.31",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -13,46 +13,47 @@
|
|
|
13
13
|
"!dist/**/*.spec.*"
|
|
14
14
|
],
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"svelte": "^5.0.0-next.
|
|
16
|
+
"svelte": "^5.0.0-next.244"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@changesets/cli": "^2.27.
|
|
19
|
+
"@changesets/cli": "^2.27.8",
|
|
20
20
|
"@changesets/types": "^6.0.0",
|
|
21
|
-
"@playwright/test": "^1.
|
|
21
|
+
"@playwright/test": "^1.47.2",
|
|
22
22
|
"@pzerelles/heroicons-svelte": "^2.1.5",
|
|
23
|
-
"@sveltejs/adapter-auto": "^3.2.
|
|
24
|
-
"@sveltejs/kit": "^2.
|
|
25
|
-
"@sveltejs/package": "^2.3.
|
|
26
|
-
"@sveltejs/vite-plugin-svelte": "
|
|
23
|
+
"@sveltejs/adapter-auto": "^3.2.5",
|
|
24
|
+
"@sveltejs/kit": "^2.6.1",
|
|
25
|
+
"@sveltejs/package": "^2.3.5",
|
|
26
|
+
"@sveltejs/vite-plugin-svelte": "4.0.0-next.7",
|
|
27
27
|
"@testing-library/jest-dom": "^6.5.0",
|
|
28
28
|
"@testing-library/svelte": "^5.2.1",
|
|
29
|
-
"@types/eslint": "^
|
|
30
|
-
"@types/node": "^20.16.
|
|
29
|
+
"@types/eslint": "^9.6.1",
|
|
30
|
+
"@types/node": "^20.16.10",
|
|
31
31
|
"autoprefixer": "^10.4.20",
|
|
32
|
-
"
|
|
33
|
-
"eslint": "^9.9.1",
|
|
32
|
+
"eslint": "^9.11.1",
|
|
34
33
|
"eslint-config-prettier": "^9.1.0",
|
|
35
|
-
"eslint-plugin-svelte": "^2.
|
|
34
|
+
"eslint-plugin-svelte": "^2.44.1",
|
|
36
35
|
"globals": "^15.9.0",
|
|
37
36
|
"jsdom": "^24.1.3",
|
|
38
37
|
"outdent": "^0.8.0",
|
|
39
|
-
"postcss": "^8.4.
|
|
38
|
+
"postcss": "^8.4.47",
|
|
40
39
|
"prettier": "^3.3.3",
|
|
41
|
-
"prettier-plugin-svelte": "^3.2.
|
|
42
|
-
"prettier-plugin-tailwindcss": "^0.
|
|
43
|
-
"publint": "^0.
|
|
44
|
-
"svelte": "5.0.0-next.
|
|
45
|
-
"svelte-check": "^
|
|
46
|
-
"tailwindcss": "^3.4.
|
|
40
|
+
"prettier-plugin-svelte": "^3.2.7",
|
|
41
|
+
"prettier-plugin-tailwindcss": "^0.6.8",
|
|
42
|
+
"publint": "^0.2.11",
|
|
43
|
+
"svelte": "5.0.0-next.260",
|
|
44
|
+
"svelte-check": "^4.0.4",
|
|
45
|
+
"tailwindcss": "^3.4.13",
|
|
47
46
|
"tslib": "^2.7.0",
|
|
48
|
-
"typescript": "^5.
|
|
49
|
-
"typescript-eslint": "8.
|
|
50
|
-
"vite": "^5.4.
|
|
51
|
-
"vitest": "^2.
|
|
47
|
+
"typescript": "^5.6.2",
|
|
48
|
+
"typescript-eslint": "^8.7.0",
|
|
49
|
+
"vite": "^5.4.8",
|
|
50
|
+
"vitest": "^2.1.1"
|
|
52
51
|
},
|
|
53
52
|
"dependencies": {
|
|
54
|
-
"@floating-ui/core": "^1.6.
|
|
55
|
-
"@floating-ui/dom": "^1.6.
|
|
53
|
+
"@floating-ui/core": "^1.6.8",
|
|
54
|
+
"@floating-ui/dom": "^1.6.11",
|
|
55
|
+
"@floating-ui/utils": "^0.2.8",
|
|
56
|
+
"clsx": "^2.1.1",
|
|
56
57
|
"esm-env": "^1.0.0",
|
|
57
58
|
"nanoid": "^5.0.7"
|
|
58
59
|
},
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_DIALOG_TAG">import { useId } from "../hooks/use-id.js";
|
|
2
|
-
import { useMainTreeNode, useRootContainers } from "../hooks/use-root-containers.svelte.js";
|
|
3
|
-
import { clearOpenClosedContext, State, useOpenClosed } from "../internal/open-closed.js";
|
|
4
|
-
import { useNestedPortals } from "../portal/InternalPortal.svelte";
|
|
5
|
-
import { getOwnerDocument } from "../utils/owner.js";
|
|
6
|
-
import { DEFAULT_DIALOG_TAG, DialogRenderFeatures } from "./Dialog.svelte";
|
|
7
|
-
import { useInertOthers } from "../hooks/use-inert-others.svelte.js";
|
|
8
|
-
import { useOutsideClick } from "../hooks/use-outside-click.svelte.js";
|
|
9
|
-
import { useEscape } from "../hooks/use-escape.svelte.js";
|
|
10
|
-
import { useScrollLock } from "../hooks/use-scroll-lock.svelte.js";
|
|
11
|
-
import { useOnDisappear } from "../hooks/use-on-disappear.svelte.js";
|
|
12
|
-
import { setContext } from "svelte";
|
|
13
|
-
import { useIsTouchDevice } from "../hooks/use-is-touch-device.svelte.js";
|
|
14
|
-
import FocusTrap, { FocusTrapFeatures } from "../focus-trap/FocusTrap.svelte";
|
|
15
|
-
import Portal from "../portal/Portal.svelte";
|
|
16
|
-
import PortalGroup from "../portal/PortalGroup.svelte";
|
|
17
|
-
import ForcePortalRoot from "../internal/ForcePortalRoot.svelte";
|
|
18
|
-
import { createCloseContext } from "../internal/close-provider.js";
|
|
19
|
-
import ElementOrComponent from "../utils/ElementOrComponent.svelte";
|
|
20
|
-
import { DialogStates } from "./context.svelte.js";
|
|
21
|
-
import { useDescriptions } from "../description/context.svelte.js";
|
|
22
|
-
const internalId = useId();
|
|
23
|
-
let {
|
|
24
|
-
ref = $bindable(),
|
|
25
|
-
id = `headlessui-dialog-${internalId}`,
|
|
26
|
-
open: theirOpen,
|
|
27
|
-
onclose,
|
|
28
|
-
initialFocus,
|
|
29
|
-
role: theirRole = "dialog",
|
|
30
|
-
autofocus = true,
|
|
31
|
-
__demoMode = false,
|
|
32
|
-
unmount = false,
|
|
33
|
-
...theirProps
|
|
34
|
-
} = $props();
|
|
35
|
-
let didWarnOnRole = $state(false);
|
|
36
|
-
const role = $derived.by(() => {
|
|
37
|
-
if (theirRole === "dialog" || theirRole === "alertdialog") {
|
|
38
|
-
return theirRole;
|
|
39
|
-
}
|
|
40
|
-
if (!didWarnOnRole) {
|
|
41
|
-
didWarnOnRole = true;
|
|
42
|
-
console.warn(
|
|
43
|
-
`Invalid role [${theirRole}] passed to <Dialog />. Only \`dialog\` and and \`alertdialog\` are supported. Using \`dialog\` instead.`
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
return "dialog";
|
|
47
|
-
});
|
|
48
|
-
const usesOpenClosedState = useOpenClosed();
|
|
49
|
-
const open = $derived(
|
|
50
|
-
theirOpen === void 0 && usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Open) === State.Open : theirOpen
|
|
51
|
-
);
|
|
52
|
-
const ownerDocument = $derived(getOwnerDocument(ref));
|
|
53
|
-
const dialogState = $derived(open ? DialogStates.Open : DialogStates.Closed);
|
|
54
|
-
let _state = $state({
|
|
55
|
-
titleId: null,
|
|
56
|
-
panelRef: null
|
|
57
|
-
});
|
|
58
|
-
const close = $derived(() => onclose(false));
|
|
59
|
-
const setTitleId = (id2) => _state.titleId = id2;
|
|
60
|
-
const enabled = $derived(dialogState === DialogStates.Open);
|
|
61
|
-
const nestedPortals = useNestedPortals();
|
|
62
|
-
const { portals } = $derived(nestedPortals);
|
|
63
|
-
const defaultContainer = {
|
|
64
|
-
get current() {
|
|
65
|
-
return _state.panelRef ?? ref;
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
const mainTreeNode = useMainTreeNode();
|
|
69
|
-
let { resolvedContainers: resolvedRootContainers } = $derived(
|
|
70
|
-
useRootContainers({
|
|
71
|
-
get mainTreeNode() {
|
|
72
|
-
return mainTreeNode.node;
|
|
73
|
-
},
|
|
74
|
-
get portals() {
|
|
75
|
-
return portals;
|
|
76
|
-
},
|
|
77
|
-
get defaultContainers() {
|
|
78
|
-
return defaultContainer.current ? [defaultContainer.current] : [];
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
);
|
|
82
|
-
const isClosing = $derived(
|
|
83
|
-
usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Closing) === State.Closing : false
|
|
84
|
-
);
|
|
85
|
-
const inertOthersEnabled = $derived(__demoMode ? false : isClosing ? false : enabled);
|
|
86
|
-
useInertOthers({
|
|
87
|
-
get enabled() {
|
|
88
|
-
return inertOthersEnabled;
|
|
89
|
-
},
|
|
90
|
-
elements: {
|
|
91
|
-
get allowed() {
|
|
92
|
-
return [
|
|
93
|
-
// Allow the headlessui-portal of the Dialog to be interactive. This
|
|
94
|
-
// contains the current dialog and the necessary focus guard elements.
|
|
95
|
-
ref?.closest("[data-headlessui-portal]") ?? null
|
|
96
|
-
];
|
|
97
|
-
},
|
|
98
|
-
get disallowed() {
|
|
99
|
-
return [
|
|
100
|
-
// Disallow the "main" tree root node
|
|
101
|
-
mainTreeNode.node?.closest("body > *:not(#headlessui-portal-root)") ?? null
|
|
102
|
-
];
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
useOutsideClick({
|
|
107
|
-
get enabled() {
|
|
108
|
-
return enabled;
|
|
109
|
-
},
|
|
110
|
-
get containers() {
|
|
111
|
-
return resolvedRootContainers;
|
|
112
|
-
},
|
|
113
|
-
cb(event) {
|
|
114
|
-
event.preventDefault();
|
|
115
|
-
close();
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
useEscape({
|
|
119
|
-
get enabled() {
|
|
120
|
-
return enabled;
|
|
121
|
-
},
|
|
122
|
-
get view() {
|
|
123
|
-
return ownerDocument?.defaultView ?? null;
|
|
124
|
-
},
|
|
125
|
-
cb(event) {
|
|
126
|
-
event.preventDefault();
|
|
127
|
-
event.stopPropagation();
|
|
128
|
-
if (document.activeElement && "blur" in document.activeElement && typeof document.activeElement.blur === "function") {
|
|
129
|
-
document.activeElement.blur();
|
|
130
|
-
}
|
|
131
|
-
close();
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
const scrollLockEnabled = $derived(__demoMode ? false : isClosing ? false : enabled);
|
|
135
|
-
useScrollLock({
|
|
136
|
-
get enabled() {
|
|
137
|
-
return scrollLockEnabled;
|
|
138
|
-
},
|
|
139
|
-
get ownerDocument() {
|
|
140
|
-
return ownerDocument;
|
|
141
|
-
},
|
|
142
|
-
resolveAllowedContainers() {
|
|
143
|
-
return resolvedRootContainers;
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
useOnDisappear({
|
|
147
|
-
get enabled() {
|
|
148
|
-
return enabled;
|
|
149
|
-
},
|
|
150
|
-
get ref() {
|
|
151
|
-
return ref;
|
|
152
|
-
},
|
|
153
|
-
get ondisappear() {
|
|
154
|
-
return close;
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
const describedby = useDescriptions();
|
|
158
|
-
setContext("DialogContext", {
|
|
159
|
-
get titleId() {
|
|
160
|
-
return _state.titleId;
|
|
161
|
-
},
|
|
162
|
-
get panelRef() {
|
|
163
|
-
return _state.panelRef;
|
|
164
|
-
},
|
|
165
|
-
get dialogState() {
|
|
166
|
-
return dialogState;
|
|
167
|
-
},
|
|
168
|
-
get close() {
|
|
169
|
-
return close;
|
|
170
|
-
},
|
|
171
|
-
get unmount() {
|
|
172
|
-
return unmount;
|
|
173
|
-
},
|
|
174
|
-
setTitleId
|
|
175
|
-
});
|
|
176
|
-
const slot = $derived({ open: dialogState === DialogStates.Open });
|
|
177
|
-
const ourProps = $derived({
|
|
178
|
-
id,
|
|
179
|
-
role,
|
|
180
|
-
tabIndex: -1,
|
|
181
|
-
"aria-modal": __demoMode ? void 0 : dialogState === DialogStates.Open ? true : void 0,
|
|
182
|
-
"aria-labelledby": _state.titleId,
|
|
183
|
-
"aria-describedby": describedby.value,
|
|
184
|
-
unmount
|
|
185
|
-
});
|
|
186
|
-
const shouldMoveFocusInside = !useIsTouchDevice().value;
|
|
187
|
-
const focusTrapFeatures = $derived.by(() => {
|
|
188
|
-
let focusTrapFeatures2 = FocusTrapFeatures.None;
|
|
189
|
-
if (enabled && !__demoMode) {
|
|
190
|
-
focusTrapFeatures2 |= FocusTrapFeatures.RestoreFocus;
|
|
191
|
-
focusTrapFeatures2 |= FocusTrapFeatures.TabLock;
|
|
192
|
-
if (autofocus) {
|
|
193
|
-
focusTrapFeatures2 |= FocusTrapFeatures.AutoFocus;
|
|
194
|
-
}
|
|
195
|
-
if (shouldMoveFocusInside) {
|
|
196
|
-
focusTrapFeatures2 |= FocusTrapFeatures.InitialFocus;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return focusTrapFeatures2;
|
|
200
|
-
});
|
|
201
|
-
clearOpenClosedContext();
|
|
202
|
-
createCloseContext({
|
|
203
|
-
get close() {
|
|
204
|
-
return close;
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
</script>
|
|
208
|
-
|
|
209
|
-
<ForcePortalRoot force={true}>
|
|
210
|
-
<Portal>
|
|
211
|
-
<PortalGroup target={ref ?? null}>
|
|
212
|
-
<ForcePortalRoot force={false}>
|
|
213
|
-
<FocusTrap
|
|
214
|
-
{initialFocus}
|
|
215
|
-
initialFocusFallback={ref}
|
|
216
|
-
containers={resolvedRootContainers}
|
|
217
|
-
features={focusTrapFeatures}
|
|
218
|
-
>
|
|
219
|
-
<ElementOrComponent
|
|
220
|
-
{ourProps}
|
|
221
|
-
{theirProps}
|
|
222
|
-
slots={slot}
|
|
223
|
-
defaultTag={DEFAULT_DIALOG_TAG}
|
|
224
|
-
features={DialogRenderFeatures}
|
|
225
|
-
visible={dialogState === DialogStates.Open}
|
|
226
|
-
name="Dialog"
|
|
227
|
-
bind:ref
|
|
228
|
-
/>
|
|
229
|
-
</FocusTrap>
|
|
230
|
-
</ForcePortalRoot>
|
|
231
|
-
</PortalGroup>
|
|
232
|
-
</Portal>
|
|
233
|
-
</ForcePortalRoot>
|