@pzerelles/headlessui-svelte 2.1.2-next.22 → 2.1.2-next.24
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 +84 -54
- package/dist/button/Button.svelte.d.ts +7 -4
- package/dist/checkbox/Checkbox.svelte +173 -120
- package/dist/checkbox/Checkbox.svelte.d.ts +7 -4
- package/dist/close-button/CloseButton.svelte +12 -6
- package/dist/close-button/CloseButton.svelte.d.ts +13 -10
- package/dist/combobox/Combobox.svelte +50 -3
- package/dist/data-interactive/DataInteractive.svelte +55 -29
- package/dist/data-interactive/DataInteractive.svelte.d.ts +7 -5
- package/dist/description/Description.svelte +39 -24
- package/dist/description/Description.svelte.d.ts +8 -5
- package/dist/description/context.svelte.js +13 -15
- package/dist/dialog/Dialog.svelte +358 -38
- package/dist/dialog/Dialog.svelte.d.ts +10 -7
- package/dist/dialog/DialogBackdrop.svelte +30 -13
- package/dist/dialog/DialogBackdrop.svelte.d.ts +7 -4
- package/dist/dialog/DialogPanel.svelte +49 -26
- package/dist/dialog/DialogPanel.svelte.d.ts +7 -4
- package/dist/dialog/DialogTitle.svelte +38 -23
- package/dist/dialog/DialogTitle.svelte.d.ts +7 -4
- package/dist/field/Field.svelte +50 -34
- package/dist/field/Field.svelte.d.ts +7 -4
- package/dist/fieldset/Fieldset.svelte +50 -29
- package/dist/fieldset/Fieldset.svelte.d.ts +7 -4
- package/dist/focus-trap/FocusTrap.svelte +419 -283
- package/dist/focus-trap/FocusTrap.svelte.d.ts +7 -4
- package/dist/hooks/use-disabled.d.ts +4 -1
- package/dist/hooks/use-disabled.js +10 -5
- package/dist/input/Input.svelte +84 -53
- package/dist/input/Input.svelte.d.ts +7 -4
- package/dist/internal/FloatingProvider.svelte +14 -9
- package/dist/internal/FocusSentinel.svelte +16 -8
- package/dist/internal/ForcePortalRoot.svelte +7 -3
- package/dist/internal/FormFields.svelte +47 -34
- package/dist/internal/FormFieldsProvider.svelte +9 -5
- package/dist/internal/FormResolver.svelte +20 -15
- package/dist/internal/Hidden.svelte +50 -29
- package/dist/internal/Hidden.svelte.d.ts +7 -4
- package/dist/internal/MainTreeProvider.svelte +89 -36
- package/dist/internal/Portal.svelte +18 -14
- package/dist/internal/floating-provider.svelte.js +1 -1
- package/dist/internal/floating.svelte.d.ts +5 -5
- package/dist/internal/floating.svelte.js +17 -17
- package/dist/label/Label.svelte +93 -58
- package/dist/label/Label.svelte.d.ts +7 -4
- package/dist/legend/Legend.svelte +12 -3
- package/dist/listbox/Listbox.svelte +525 -387
- package/dist/listbox/Listbox.svelte.d.ts +7 -5
- package/dist/listbox/ListboxButton.svelte +173 -127
- package/dist/listbox/ListboxButton.svelte.d.ts +7 -5
- package/dist/listbox/ListboxOption.svelte +170 -129
- package/dist/listbox/ListboxOption.svelte.d.ts +7 -5
- package/dist/listbox/ListboxOptions.svelte +400 -304
- package/dist/listbox/ListboxOptions.svelte.d.ts +7 -5
- package/dist/listbox/ListboxSelectedOption.svelte +38 -15
- package/dist/listbox/ListboxSelectedOption.svelte.d.ts +7 -4
- package/dist/listbox/index.d.ts +4 -4
- package/dist/listbox/index.js +1 -1
- package/dist/menu/Menu.svelte +78 -57
- package/dist/menu/Menu.svelte.d.ts +7 -5
- package/dist/menu/MenuButton.svelte +157 -117
- package/dist/menu/MenuButton.svelte.d.ts +7 -5
- package/dist/menu/MenuHeading.svelte +32 -14
- package/dist/menu/MenuHeading.svelte.d.ts +7 -5
- package/dist/menu/MenuItem.svelte +142 -107
- package/dist/menu/MenuItem.svelte.d.ts +8 -8
- package/dist/menu/MenuItems.svelte +301 -229
- package/dist/menu/MenuItems.svelte.d.ts +7 -5
- package/dist/menu/MenuSection.svelte +24 -9
- package/dist/menu/MenuSection.svelte.d.ts +7 -5
- package/dist/menu/MenuSeparator.svelte +17 -4
- package/dist/menu/MenuSeparator.svelte.d.ts +7 -6
- package/dist/menu/context.svelte.d.ts +1 -29
- package/dist/menu/context.svelte.js +29 -27
- package/dist/menu/index.d.ts +7 -7
- package/dist/popover/Popover.svelte +216 -150
- package/dist/popover/Popover.svelte.d.ts +7 -4
- package/dist/popover/PopoverBackdrop.svelte +67 -41
- package/dist/popover/PopoverBackdrop.svelte.d.ts +7 -4
- package/dist/popover/PopoverButton.svelte +292 -212
- package/dist/popover/PopoverButton.svelte.d.ts +7 -4
- package/dist/popover/PopoverGroup.svelte +62 -35
- package/dist/popover/PopoverGroup.svelte.d.ts +7 -4
- package/dist/popover/PopoverPanel.svelte +311 -229
- package/dist/popover/PopoverPanel.svelte.d.ts +7 -4
- package/dist/portal/InternalPortal.svelte +141 -85
- package/dist/portal/InternalPortal.svelte.d.ts +7 -4
- package/dist/portal/Portal.svelte +5 -2
- package/dist/portal/PortalGroup.svelte +30 -9
- package/dist/portal/PortalGroup.svelte.d.ts +7 -4
- package/dist/select/Select.svelte +98 -68
- package/dist/select/Select.svelte.d.ts +7 -4
- package/dist/switch/Switch.svelte +179 -132
- package/dist/switch/Switch.svelte.d.ts +7 -4
- package/dist/switch/SwitchGroup.svelte +44 -31
- package/dist/switch/SwitchGroup.svelte.d.ts +7 -4
- package/dist/tabs/Tab.svelte +194 -143
- package/dist/tabs/Tab.svelte.d.ts +7 -4
- package/dist/tabs/TabGroup.svelte +81 -214
- package/dist/tabs/TabGroup.svelte.d.ts +7 -24
- package/dist/tabs/TabList.svelte +31 -11
- package/dist/tabs/TabList.svelte.d.ts +7 -4
- package/dist/tabs/TabPanel.svelte +67 -43
- package/dist/tabs/TabPanel.svelte.d.ts +7 -4
- package/dist/tabs/TabPanels.svelte +18 -7
- package/dist/tabs/TabPanels.svelte.d.ts +7 -4
- package/dist/tabs/context.svelte.d.ts +31 -0
- package/dist/tabs/context.svelte.js +134 -0
- package/dist/textarea/Textarea.svelte +84 -53
- package/dist/textarea/Textarea.svelte.d.ts +7 -4
- package/dist/transition/InternalTransitionChild.svelte +259 -170
- package/dist/transition/InternalTransitionChild.svelte.d.ts +7 -4
- package/dist/transition/Transition.svelte +96 -66
- package/dist/transition/Transition.svelte.d.ts +7 -4
- package/dist/transition/TransitionChild.svelte +31 -11
- package/dist/transition/TransitionChild.svelte.d.ts +7 -4
- package/dist/utils/ElementOrComponent.svelte +43 -23
- package/dist/utils/ElementOrComponent.svelte.d.ts +10 -4
- package/dist/utils/Generic.svelte +36 -22
- package/dist/utils/Generic.svelte.d.ts +7 -4
- package/dist/utils/StableCollection.svelte +54 -36
- package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +27 -12
- package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +88 -44
- package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.js +7 -7
- package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.js +1 -1
- package/dist/utils/floating-ui/svelte/types.d.ts +4 -4
- package/dist/utils/floating-ui/svelte-dom/types.d.ts +2 -2
- package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.js +6 -6
- package/dist/utils/types.d.ts +11 -4
- package/package.json +2 -2
- package/dist/dialog/InternalDialog.svelte +0 -233
- package/dist/dialog/InternalDialog.svelte.d.ts +0 -42
|
@@ -1,42 +1,95 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
|
|
3
|
-
const { fallbackMainTreeNode = null } = $derived(options);
|
|
4
|
-
return getContext("MainTreeContext") ?? {
|
|
5
|
-
get node() {
|
|
6
|
-
return fallbackMainTreeNode;
|
|
7
|
-
}
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
</script>
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { getContext, onMount } from "svelte"
|
|
11
3
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
4
|
+
type MainTreeContext = { node: HTMLElement | null }
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Get the main tree node from context or fallback to the optionally provided node.
|
|
8
|
+
*/
|
|
9
|
+
export function useMainTreeNode(options: { fallbackMainTreeNode?: HTMLElement | null } = {}) {
|
|
10
|
+
const { fallbackMainTreeNode = null } = $derived(options)
|
|
11
|
+
|
|
12
|
+
// Prefer the main tree node from context, but fallback to the provided node.
|
|
13
|
+
return (
|
|
14
|
+
getContext<MainTreeContext>("MainTreeContext") ?? {
|
|
15
|
+
get node() {
|
|
16
|
+
return fallbackMainTreeNode
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
)
|
|
25
20
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import { setContext, type Snippet } from "svelte"
|
|
25
|
+
import Hidden, { HiddenFeatures } from "./Hidden.svelte"
|
|
26
|
+
import { getOwnerDocument } from "../utils/owner.js"
|
|
27
|
+
/**
|
|
28
|
+
* A provider for the main tree node.
|
|
29
|
+
*
|
|
30
|
+
* When a component is rendered in a `Portal`, it is no longer part of the main
|
|
31
|
+
* tree. This provider helps to find the main tree node and pass it along to the
|
|
32
|
+
* components that need it.
|
|
33
|
+
*
|
|
34
|
+
* The main tree node is used for features such as outside click behavior, where
|
|
35
|
+
* we allow clicks in 3rd party containers, but not in the parent of the "main
|
|
36
|
+
* tree".
|
|
37
|
+
*
|
|
38
|
+
* In case of a `Popover`, we can use the `PopoverButton` as a marker in the
|
|
39
|
+
* "main tree", the `PopoverPanel` can't be used because it could be rendered in
|
|
40
|
+
* a `Portal` (e.g. when using the `anchor` props).
|
|
41
|
+
*
|
|
42
|
+
* However, we can't use the `PopoverButton` when it's nested inside of another
|
|
43
|
+
* `Popover`'s `PopoverPanel` component if the parent `PopoverPanel` is
|
|
44
|
+
* rendered in a `Portal`.
|
|
45
|
+
*
|
|
46
|
+
* This is where the `MainTreeProvider` comes in. It will find the "main tree"
|
|
47
|
+
* node and pass it on. The top-level `PopoverButton` will be used as a marker
|
|
48
|
+
* in the "main tree" and nested `Popover` will use this button as well.
|
|
49
|
+
*/
|
|
50
|
+
let { node, children }: { children: Snippet; node?: HTMLElement | null } = $props()
|
|
51
|
+
|
|
52
|
+
let mainTreeNode = $state<HTMLElement | null>(null)
|
|
53
|
+
|
|
54
|
+
// 1. Prefer the main tree node from context
|
|
55
|
+
// 2. Prefer the provided node
|
|
56
|
+
// 3. Create a new node at this point, and find the main tree node
|
|
57
|
+
const resolvedMainTreeNode = useMainTreeNode({
|
|
58
|
+
get fallbackMainTreeNode() {
|
|
59
|
+
return node ?? mainTreeNode
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
setContext("MainTreeContext", {
|
|
64
|
+
get node() {
|
|
65
|
+
return resolvedMainTreeNode.node
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* If no main tree node is found at this point, then we briefly render an
|
|
71
|
+
* element to find the main tree node and pass it along.
|
|
72
|
+
*/
|
|
73
|
+
let el = $state<HTMLElement>()
|
|
74
|
+
onMount(() => {
|
|
75
|
+
if (!el) return
|
|
76
|
+
|
|
77
|
+
// We will only render this when no `mainTreeNode` is found. This
|
|
78
|
+
// means that if we render this element and use it as the
|
|
79
|
+
// `mainTreeNode` that we will be unmounting it later.
|
|
80
|
+
//
|
|
81
|
+
// However, we can resolve the actual root container of the main
|
|
82
|
+
// tree node and use that instead.
|
|
83
|
+
for (let container of getOwnerDocument(el)?.querySelectorAll("html > *, body > *") ?? []) {
|
|
84
|
+
if (container === document.body) continue // Skip `<body>`
|
|
85
|
+
if (container === document.head) continue // Skip `<head>`
|
|
86
|
+
if (!(container instanceof HTMLElement)) continue // Skip non-HTMLElements
|
|
87
|
+
if (container?.contains(el)) {
|
|
88
|
+
mainTreeNode = container
|
|
89
|
+
break
|
|
90
|
+
}
|
|
37
91
|
}
|
|
38
|
-
}
|
|
39
|
-
});
|
|
92
|
+
})
|
|
40
93
|
</script>
|
|
41
94
|
|
|
42
95
|
{#if children}{@render children()}{/if}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onDestroy, onMount, type Snippet } from "svelte"
|
|
3
|
+
|
|
4
|
+
let { target, children }: { target: HTMLElement; children: Snippet } = $props()
|
|
5
|
+
let ref = $state<HTMLDivElement>()
|
|
6
|
+
|
|
7
|
+
onMount(() => {
|
|
8
|
+
target.appendChild(ref!)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
onDestroy(() => {
|
|
12
|
+
const _ref = ref
|
|
13
|
+
setTimeout(() => {
|
|
14
|
+
if (_ref?.parentNode) {
|
|
15
|
+
_ref.parentNode?.removeChild(_ref)
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
})
|
|
15
19
|
</script>
|
|
16
20
|
|
|
17
21
|
<div bind:this={ref}>{@render children()}</div>
|
|
@@ -10,7 +10,7 @@ export const useFloatingProvider = (options = { enabled: true }) => {
|
|
|
10
10
|
const setInnerOffset = (offset) => (innerOffset = typeof offset === "function" ? offset(innerOffset) : offset);
|
|
11
11
|
const overflowRef = $state({ current: null });
|
|
12
12
|
let floatingEl = $state(null);
|
|
13
|
-
const setFloatingElement = (element) => (floatingEl = element);
|
|
13
|
+
const setFloatingElement = (element) => (floatingEl = element ?? null);
|
|
14
14
|
useFixScrollingPixel({
|
|
15
15
|
get element() {
|
|
16
16
|
return floatingEl;
|
|
@@ -37,9 +37,9 @@ export type InternalFloatingPanelProps = Partial<{
|
|
|
37
37
|
};
|
|
38
38
|
}>;
|
|
39
39
|
export type FloatingContext = {
|
|
40
|
-
styles?: UseFloatingReturn
|
|
41
|
-
setReference: UseFloatingReturn
|
|
42
|
-
setFloating: UseFloatingReturn
|
|
40
|
+
styles?: UseFloatingReturn["floatingStyles"];
|
|
41
|
+
setReference: UseFloatingReturn["refs"]["setReference"];
|
|
42
|
+
setFloating: UseFloatingReturn["refs"]["setFloating"];
|
|
43
43
|
getReferenceProps: ReturnType<typeof useInteractions>["getReferenceProps"];
|
|
44
44
|
getFloatingProps: ReturnType<typeof useInteractions>["getFloatingProps"];
|
|
45
45
|
slot: Partial<{
|
|
@@ -55,7 +55,7 @@ export declare function useResolvedAnchor<T extends AnchorProps | AnchorPropsWit
|
|
|
55
55
|
anchor: Exclude<T, boolean | string> | null;
|
|
56
56
|
};
|
|
57
57
|
export declare function useFloatingReference(): {
|
|
58
|
-
readonly setReference: ((node: import("../utils/floating-ui/svelte-dom/types.js").ReferenceType | null) => void) & ((node:
|
|
58
|
+
readonly setReference: ((node: import("../utils/floating-ui/svelte-dom/types.js").ReferenceType | null | undefined) => void) & ((node: import("../utils/floating-ui/svelte/types.js").ReferenceType | null | undefined) => void);
|
|
59
59
|
};
|
|
60
60
|
export declare function useFloatingReferenceProps(): {
|
|
61
61
|
readonly getReferenceProps: (userProps?: import("svelte/elements.js").HTMLAttributes<Element>) => Record<string, unknown>;
|
|
@@ -66,7 +66,7 @@ export declare function useFloatingPanelProps(): (userProps?: import("svelte/ele
|
|
|
66
66
|
export declare function useFloatingPanel(options?: {
|
|
67
67
|
placement: (AnchorPropsWithSelection & InternalFloatingPanelProps) | null;
|
|
68
68
|
}): {
|
|
69
|
-
readonly setFloating: ((node: HTMLElement | null) => void) & ((node: HTMLElement | null) => void);
|
|
69
|
+
readonly setFloating: ((node: HTMLElement | null | undefined) => void) & ((node: HTMLElement | null | undefined) => void);
|
|
70
70
|
readonly styles: string | undefined;
|
|
71
71
|
};
|
|
72
72
|
export declare function useFixScrollingPixel(options: {
|
|
@@ -76,17 +76,17 @@ export function useFloatingPanel(options = { placement: null }) {
|
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
export function useFixScrollingPixel(options) {
|
|
79
|
-
const { element } = $derived(options);
|
|
80
79
|
$effect(() => {
|
|
80
|
+
const element = options.element;
|
|
81
81
|
if (!element)
|
|
82
82
|
return;
|
|
83
83
|
untrack(() => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
const observer = new MutationObserver(() => {
|
|
85
|
+
const maxHeight = window.getComputedStyle(element).maxHeight;
|
|
86
|
+
const maxHeightFloat = parseFloat(maxHeight);
|
|
87
87
|
if (isNaN(maxHeightFloat))
|
|
88
88
|
return;
|
|
89
|
-
|
|
89
|
+
const maxHeightInt = parseInt(maxHeight);
|
|
90
90
|
if (isNaN(maxHeightInt))
|
|
91
91
|
return;
|
|
92
92
|
if (maxHeightFloat !== maxHeightInt) {
|
|
@@ -149,7 +149,7 @@ export function useResolvedConfig(options) {
|
|
|
149
149
|
}
|
|
150
150
|
function useResolvePxValue(options) {
|
|
151
151
|
const { input, element, defaultValue } = $derived(options);
|
|
152
|
-
|
|
152
|
+
const d = useDisposables();
|
|
153
153
|
const computeValue = (value, element) => {
|
|
154
154
|
// Nullish
|
|
155
155
|
if (value == null)
|
|
@@ -165,7 +165,7 @@ function useResolvePxValue(options) {
|
|
|
165
165
|
return [
|
|
166
166
|
result,
|
|
167
167
|
(setValue) => {
|
|
168
|
-
|
|
168
|
+
const variables = resolveVariables(value);
|
|
169
169
|
// TODO: Improve this part and make it work
|
|
170
170
|
//
|
|
171
171
|
// Observe variables themselves. Currently the browser doesn't support this, but the
|
|
@@ -197,7 +197,7 @@ function useResolvePxValue(options) {
|
|
|
197
197
|
// }
|
|
198
198
|
// Works as a fallback, but not very performant because we are polling the value.
|
|
199
199
|
{
|
|
200
|
-
|
|
200
|
+
const history = variables.map((variable) => window.getComputedStyle(element).getPropertyValue(variable));
|
|
201
201
|
d.requestAnimationFrame(function check() {
|
|
202
202
|
d.nextFrame(check);
|
|
203
203
|
// Fast path, detect if the value of the CSS Variable has changed before completely
|
|
@@ -206,8 +206,8 @@ function useResolvePxValue(options) {
|
|
|
206
206
|
//
|
|
207
207
|
// This is a lot of work, so we want to avoid it if possible.
|
|
208
208
|
let changed = false;
|
|
209
|
-
for (
|
|
210
|
-
|
|
209
|
+
for (const [idx, variable] of variables.entries()) {
|
|
210
|
+
const value = window.getComputedStyle(element).getPropertyValue(variable);
|
|
211
211
|
if (history[idx] !== value) {
|
|
212
212
|
history[idx] = value;
|
|
213
213
|
changed = true;
|
|
@@ -217,7 +217,7 @@ function useResolvePxValue(options) {
|
|
|
217
217
|
// Nothing changed, no need to perform the expensive computation.
|
|
218
218
|
if (!changed)
|
|
219
219
|
return;
|
|
220
|
-
|
|
220
|
+
const newResult = resolveCSSVariablePxValue(value, element);
|
|
221
221
|
if (result !== newResult) {
|
|
222
222
|
setValue(newResult);
|
|
223
223
|
result = newResult;
|
|
@@ -250,14 +250,14 @@ function useResolvePxValue(options) {
|
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
252
|
function resolveVariables(value) {
|
|
253
|
-
|
|
253
|
+
const matches = /var\((.*)\)/.exec(value);
|
|
254
254
|
if (matches) {
|
|
255
|
-
|
|
255
|
+
const idx = matches[1].indexOf(",");
|
|
256
256
|
if (idx === -1) {
|
|
257
257
|
return [matches[1]];
|
|
258
258
|
}
|
|
259
|
-
|
|
260
|
-
|
|
259
|
+
const variable = matches[1].slice(0, idx).trim();
|
|
260
|
+
const fallback = matches[1].slice(idx + 1).trim();
|
|
261
261
|
if (fallback) {
|
|
262
262
|
return [variable, ...resolveVariables(fallback)];
|
|
263
263
|
}
|
|
@@ -291,7 +291,7 @@ function resolveCSSVariablePxValue(input, element) {
|
|
|
291
291
|
// ```
|
|
292
292
|
//
|
|
293
293
|
// Then this will result to resolved value of `2rem`, instead of `1rem`
|
|
294
|
-
|
|
294
|
+
const tmpEl = document.createElement("div");
|
|
295
295
|
element.appendChild(tmpEl);
|
|
296
296
|
// Set the value to `0px` otherwise if an invalid value is provided later the browser will read
|
|
297
297
|
// out the default value.
|
|
@@ -301,7 +301,7 @@ function resolveCSSVariablePxValue(input, element) {
|
|
|
301
301
|
// Set the new value, if this is invalid the previous value will be used.
|
|
302
302
|
tmpEl.style.setProperty("margin-top", input, "important");
|
|
303
303
|
// Reading the `margin-top` will already be in pixels (e.g.: 123px).
|
|
304
|
-
|
|
304
|
+
const pxValue = parseFloat(window.getComputedStyle(tmpEl).marginTop) || 0;
|
|
305
305
|
element.removeChild(tmpEl);
|
|
306
306
|
return pxValue;
|
|
307
307
|
}
|
package/dist/label/Label.svelte
CHANGED
|
@@ -1,66 +1,101 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { ElementType, Props, PropsOf } from "../utils/types.js"
|
|
3
|
+
|
|
4
|
+
let DEFAULT_LABEL_TAG = "label" as const
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { stateFromSlot } from "../utils/state.js";
|
|
8
|
-
import ElementOrComponent from "../utils/ElementOrComponent.svelte";
|
|
9
|
-
import { useLabelContext } from "./context.svelte.js";
|
|
10
|
-
const internalId = htmlid();
|
|
11
|
-
const context = useLabelContext();
|
|
12
|
-
const providedHtmlFor = useProvidedId();
|
|
13
|
-
const providedDisabled = useDisabled();
|
|
14
|
-
let {
|
|
15
|
-
ref = $bindable(),
|
|
16
|
-
id = `headlessui-label-${internalId}`,
|
|
17
|
-
htmlFor = providedHtmlFor,
|
|
18
|
-
passive = false,
|
|
19
|
-
...theirOriginalProps
|
|
20
|
-
} = $props();
|
|
21
|
-
onMount(() => {
|
|
22
|
-
context.register(id);
|
|
23
|
-
});
|
|
24
|
-
let handleClick = (e) => {
|
|
25
|
-
let current = e.currentTarget;
|
|
26
|
-
if (current instanceof HTMLLabelElement) {
|
|
27
|
-
e.preventDefault();
|
|
6
|
+
export type LabelProps<TTag extends ElementType = typeof DEFAULT_LABEL_TAG> = Props<TTag> & {
|
|
7
|
+
passive?: boolean
|
|
8
|
+
htmlFor?: string
|
|
28
9
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_LABEL_TAG">
|
|
13
|
+
import { onMount } from "svelte"
|
|
14
|
+
import { useProvidedId, htmlid } from "../utils/id.js"
|
|
15
|
+
import { useDisabled } from "../hooks/use-disabled.js"
|
|
16
|
+
import { stateFromSlot } from "../utils/state.js"
|
|
17
|
+
import ElementOrComponent from "../utils/ElementOrComponent.svelte"
|
|
18
|
+
import { useLabelContext } from "./context.svelte.js"
|
|
19
|
+
|
|
20
|
+
const internalId = htmlid()
|
|
21
|
+
const context = useLabelContext()
|
|
22
|
+
const providedHtmlFor = useProvidedId()
|
|
23
|
+
const providedDisabled = useDisabled()
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
ref = $bindable(),
|
|
27
|
+
id = `headlessui-label-${internalId}` as PropsOf<TTag>["id"],
|
|
28
|
+
htmlFor = providedHtmlFor,
|
|
29
|
+
passive = false,
|
|
30
|
+
...theirOriginalProps
|
|
31
|
+
}: { as?: TTag } & LabelProps<TTag> = $props()
|
|
32
|
+
|
|
33
|
+
onMount(() => {
|
|
34
|
+
context.register(id)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
let handleClick = (e: MouseEvent) => {
|
|
38
|
+
let current = e.currentTarget
|
|
39
|
+
|
|
40
|
+
// Labels connected to 'real' controls will already click the element. But we don't know that
|
|
41
|
+
// ahead of time. This will prevent the default click, such that only a single click happens
|
|
42
|
+
// instead of two. Otherwise this results in a visual no-op.
|
|
43
|
+
if (current instanceof HTMLLabelElement) {
|
|
44
|
+
e.preventDefault()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log("click", providedHtmlFor)
|
|
48
|
+
|
|
49
|
+
if (current instanceof HTMLLabelElement) {
|
|
50
|
+
let target = document.getElementById(current.getAttribute("for") ?? "")
|
|
51
|
+
if (target) {
|
|
52
|
+
// Bail if the target element is disabled
|
|
53
|
+
let actuallyDisabled = target.getAttribute("disabled")
|
|
54
|
+
if (actuallyDisabled === "true" || actuallyDisabled === "") {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let ariaDisabled = target.getAttribute("aria-disabled")
|
|
59
|
+
if (ariaDisabled === "true" || ariaDisabled === "") {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Ensure we click the element this label is bound to. This is necessary for elements that
|
|
64
|
+
// immediately require state changes, e.g.: Radio & Checkbox inputs need to be checked (or
|
|
65
|
+
// unchecked).
|
|
66
|
+
if (
|
|
67
|
+
(target instanceof HTMLInputElement && (target.type === "radio" || target.type === "checkbox")) ||
|
|
68
|
+
target.role === "radio" ||
|
|
69
|
+
target.role === "checkbox" ||
|
|
70
|
+
target.role === "switch"
|
|
71
|
+
) {
|
|
72
|
+
target.click()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Move focus to the element, this allows you to start using keyboard shortcuts since the
|
|
76
|
+
// bound element is now focused.
|
|
77
|
+
target.focus({ preventScroll: true })
|
|
43
78
|
}
|
|
44
|
-
target.focus({ preventScroll: true });
|
|
45
79
|
}
|
|
46
80
|
}
|
|
47
|
-
|
|
48
|
-
const disabled = $derived(providedDisabled.
|
|
49
|
-
const slot = $derived({ disabled })
|
|
50
|
-
const ourProps = $derived({
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
81
|
+
|
|
82
|
+
const disabled = $derived(providedDisabled.current ?? false)
|
|
83
|
+
const slot = $derived({ disabled })
|
|
84
|
+
const ourProps = $derived({
|
|
85
|
+
id,
|
|
86
|
+
for: passive ? undefined : htmlFor,
|
|
87
|
+
onclick: passive ? undefined : handleClick,
|
|
88
|
+
...stateFromSlot(slot),
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
const theirProps = $derived.by(() => {
|
|
92
|
+
if (passive) {
|
|
93
|
+
const { onclick: _, ...props } = theirOriginalProps
|
|
94
|
+
return props
|
|
95
|
+
} else {
|
|
96
|
+
return theirOriginalProps
|
|
97
|
+
}
|
|
98
|
+
})
|
|
64
99
|
</script>
|
|
65
100
|
|
|
66
101
|
<ElementOrComponent
|
|
@@ -7,11 +7,14 @@ export type LabelProps<TTag extends ElementType = typeof DEFAULT_LABEL_TAG> = Pr
|
|
|
7
7
|
declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_LABEL_TAG> {
|
|
8
8
|
props(): {
|
|
9
9
|
as?: TTag | undefined;
|
|
10
|
-
} & (Exclude<keyof PropsOf<TTag>, "as" | "children" | "
|
|
11
|
-
children?: import("svelte").Snippet<[{
|
|
10
|
+
} & (Exclude<keyof PropsOf<TTag>, "as" | "children" | "class"> extends infer T extends keyof PropsOf<TTag> ? { [P in T]: PropsOf<TTag>[P]; } : never) & {
|
|
11
|
+
children?: import("svelte").Snippet<[{
|
|
12
|
+
slot: {};
|
|
13
|
+
props: Record<string, any>;
|
|
14
|
+
}]> | undefined;
|
|
12
15
|
ref?: HTMLElement;
|
|
13
|
-
} & (true extends (
|
|
14
|
-
class?:
|
|
16
|
+
} & (true extends (import("svelte/elements.js").SvelteHTMLElements[TTag] extends infer T_1 ? T_1 extends import("svelte/elements.js").SvelteHTMLElements[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?: string | ((bag: {}) => string) | null | undefined;
|
|
15
18
|
} : {}) & {
|
|
16
19
|
passive?: boolean;
|
|
17
20
|
htmlFor?: string;
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { Label } from "../index.js"
|
|
3
|
+
import type { Props } from "../utils/types.js"
|
|
4
|
+
|
|
5
|
+
const DEFAULT_LEGEND_TAG = "div" as const
|
|
6
|
+
|
|
7
|
+
type LegendRenderPropArg = {}
|
|
8
|
+
type LegendPropsWeControl = never
|
|
9
|
+
|
|
10
|
+
export type LegendProps = Props<typeof DEFAULT_LEGEND_TAG, LegendRenderPropArg, LegendPropsWeControl, {}>
|
|
3
11
|
</script>
|
|
4
12
|
|
|
5
|
-
<script lang="ts">
|
|
13
|
+
<script lang="ts">
|
|
14
|
+
let { ...props }: LegendProps = $props()
|
|
6
15
|
</script>
|
|
7
16
|
|
|
8
17
|
<Label as="div" {...props} />
|