@pzerelles/headlessui-svelte 2.1.2-next.31 → 2.1.2-next.33

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 (123) hide show
  1. package/dist/button/Button.svelte +84 -55
  2. package/dist/button/Button.svelte.d.ts +4 -32
  3. package/dist/checkbox/Checkbox.svelte +177 -121
  4. package/dist/checkbox/Checkbox.svelte.d.ts +14 -32
  5. package/dist/close-button/CloseButton.svelte +10 -7
  6. package/dist/close-button/CloseButton.svelte.d.ts +2 -44
  7. package/dist/data-interactive/DataInteractive.svelte +49 -37
  8. package/dist/data-interactive/DataInteractive.svelte.d.ts +7 -30
  9. package/dist/description/Description.svelte +35 -22
  10. package/dist/description/Description.svelte.d.ts +7 -28
  11. package/dist/dialog/Dialog.svelte +326 -232
  12. package/dist/dialog/Dialog.svelte.d.ts +4 -42
  13. package/dist/dialog/DialogBackdrop.svelte +33 -16
  14. package/dist/dialog/DialogBackdrop.svelte.d.ts +4 -29
  15. package/dist/dialog/DialogPanel.svelte +60 -29
  16. package/dist/dialog/DialogPanel.svelte.d.ts +4 -30
  17. package/dist/dialog/DialogTitle.svelte +51 -24
  18. package/dist/dialog/DialogTitle.svelte.d.ts +6 -27
  19. package/dist/field/Field.svelte +44 -28
  20. package/dist/field/Field.svelte.d.ts +4 -30
  21. package/dist/fieldset/Fieldset.svelte +48 -30
  22. package/dist/fieldset/Fieldset.svelte.d.ts +5 -31
  23. package/dist/focus-trap/FocusTrap.svelte +430 -298
  24. package/dist/focus-trap/FocusTrap.svelte.d.ts +5 -34
  25. package/dist/hooks/use-inert-others.svelte.js +10 -10
  26. package/dist/hooks/use-resolve-button-type.svelte.js +0 -1
  27. package/dist/input/Input.svelte +95 -54
  28. package/dist/input/Input.svelte.d.ts +13 -27
  29. package/dist/internal/FloatingProvider.svelte +14 -9
  30. package/dist/internal/FocusSentinel.svelte +49 -40
  31. package/dist/internal/ForcePortalRoot.svelte +7 -3
  32. package/dist/internal/FormFields.svelte +47 -34
  33. package/dist/internal/FormFieldsProvider.svelte +9 -5
  34. package/dist/internal/FormResolver.svelte +25 -16
  35. package/dist/internal/Hidden.svelte +45 -38
  36. package/dist/internal/Hidden.svelte.d.ts +4 -30
  37. package/dist/internal/MainTreeProvider.svelte +90 -37
  38. package/dist/internal/Portal.svelte +18 -14
  39. package/dist/label/Label.svelte +100 -59
  40. package/dist/label/Label.svelte.d.ts +7 -32
  41. package/dist/legend/Legend.svelte +27 -4
  42. package/dist/legend/Legend.svelte.d.ts +4 -3
  43. package/dist/listbox/Listbox.svelte +518 -391
  44. package/dist/listbox/Listbox.svelte.d.ts +11 -35
  45. package/dist/listbox/ListboxButton.svelte +175 -128
  46. package/dist/listbox/ListboxButton.svelte.d.ts +5 -32
  47. package/dist/listbox/ListboxOption.svelte +171 -130
  48. package/dist/listbox/ListboxOption.svelte.d.ts +12 -26
  49. package/dist/listbox/ListboxOptions.svelte +403 -305
  50. package/dist/listbox/ListboxOptions.svelte.d.ts +4 -38
  51. package/dist/listbox/ListboxSelectedOption.svelte +40 -19
  52. package/dist/listbox/ListboxSelectedOption.svelte.d.ts +8 -33
  53. package/dist/menu/Menu.svelte +76 -52
  54. package/dist/menu/Menu.svelte.d.ts +3 -31
  55. package/dist/menu/MenuButton.svelte +158 -118
  56. package/dist/menu/MenuButton.svelte.d.ts +4 -34
  57. package/dist/menu/MenuHeading.svelte +34 -15
  58. package/dist/menu/MenuHeading.svelte.d.ts +4 -31
  59. package/dist/menu/MenuItem.svelte +143 -108
  60. package/dist/menu/MenuItem.svelte.d.ts +5 -32
  61. package/dist/menu/MenuItems.svelte +301 -230
  62. package/dist/menu/MenuItems.svelte.d.ts +4 -38
  63. package/dist/menu/MenuSection.svelte +26 -10
  64. package/dist/menu/MenuSection.svelte.d.ts +5 -29
  65. package/dist/menu/MenuSeparator.svelte +20 -5
  66. package/dist/menu/MenuSeparator.svelte.d.ts +5 -28
  67. package/dist/popover/Popover.svelte +217 -151
  68. package/dist/popover/Popover.svelte.d.ts +4 -30
  69. package/dist/popover/PopoverBackdrop.svelte +71 -42
  70. package/dist/popover/PopoverBackdrop.svelte.d.ts +6 -34
  71. package/dist/popover/PopoverButton.svelte +302 -222
  72. package/dist/popover/PopoverButton.svelte.d.ts +6 -29
  73. package/dist/popover/PopoverGroup.svelte +64 -36
  74. package/dist/popover/PopoverGroup.svelte.d.ts +5 -28
  75. package/dist/popover/PopoverPanel.svelte +335 -248
  76. package/dist/popover/PopoverPanel.svelte.d.ts +5 -36
  77. package/dist/popover/index.d.ts +1 -1
  78. package/dist/portal/InternalPortal.svelte +143 -86
  79. package/dist/portal/InternalPortal.svelte.d.ts +4 -30
  80. package/dist/portal/Portal.svelte +8 -4
  81. package/dist/portal/Portal.svelte.d.ts +2 -18
  82. package/dist/portal/PortalGroup.svelte +23 -10
  83. package/dist/portal/PortalGroup.svelte.d.ts +3 -31
  84. package/dist/select/Select.svelte +100 -69
  85. package/dist/select/Select.svelte.d.ts +5 -32
  86. package/dist/switch/Switch.svelte +181 -133
  87. package/dist/switch/Switch.svelte.d.ts +5 -38
  88. package/dist/switch/SwitchGroup.svelte +45 -32
  89. package/dist/switch/SwitchGroup.svelte.d.ts +7 -28
  90. package/dist/tabs/Tab.svelte +195 -143
  91. package/dist/tabs/Tab.svelte.d.ts +4 -32
  92. package/dist/tabs/TabGroup.svelte +87 -57
  93. package/dist/tabs/TabGroup.svelte.d.ts +4 -34
  94. package/dist/tabs/TabList.svelte +31 -12
  95. package/dist/tabs/TabList.svelte.d.ts +5 -28
  96. package/dist/tabs/TabPanel.svelte +69 -44
  97. package/dist/tabs/TabPanel.svelte.d.ts +4 -34
  98. package/dist/tabs/TabPanels.svelte +19 -8
  99. package/dist/tabs/TabPanels.svelte.d.ts +5 -27
  100. package/dist/textarea/Textarea.svelte +87 -54
  101. package/dist/textarea/Textarea.svelte.d.ts +13 -27
  102. package/dist/transition/InternalTransitionChild.svelte +267 -171
  103. package/dist/transition/InternalTransitionChild.svelte.d.ts +3 -33
  104. package/dist/transition/Transition.svelte +88 -67
  105. package/dist/transition/Transition.svelte.d.ts +3 -36
  106. package/dist/transition/TransitionChild.svelte +31 -12
  107. package/dist/transition/TransitionChild.svelte.d.ts +8 -35
  108. package/dist/transition/context.svelte.js +7 -7
  109. package/dist/utils/DisabledProvider.svelte +7 -3
  110. package/dist/utils/ElementOrComponent.svelte +88 -24
  111. package/dist/utils/ElementOrComponent.svelte.d.ts +32 -27
  112. package/dist/utils/StableCollection.svelte +54 -36
  113. package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +27 -12
  114. package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +88 -44
  115. package/dist/utils/state.js +4 -4
  116. package/dist/utils/types.d.ts +14 -12
  117. package/package.json +12 -12
  118. package/dist/combobox/Combobox.svelte +0 -6
  119. package/dist/combobox/Combobox.svelte.d.ts +0 -50
  120. package/dist/utils/Generic.svelte +0 -46
  121. package/dist/utils/Generic.svelte.d.ts +0 -32
  122. package/dist/utils/alternative-types.d.ts +0 -20
  123. package/dist/utils/alternative-types.js +0 -1
@@ -1,42 +1,49 @@
1
- <script lang="ts" module>import ElementOrComponent from "../utils/ElementOrComponent.svelte";
2
- import { HiddenFeatures } from "./HiddenFeatures.js";
3
- export * from "./HiddenFeatures.js";
4
- const DEFAULT_VISUALLY_HIDDEN_TAG = "span";
1
+ <script lang="ts" module>
2
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
3
+ import type { Props } from "../utils/types.js"
4
+ import { HiddenFeatures } from "./HiddenFeatures.js"
5
+ import type { SvelteHTMLElements } from "svelte/elements"
6
+
7
+ export * from "./HiddenFeatures.js"
8
+
9
+ const DEFAULT_VISUALLY_HIDDEN_TAG = "span" as const
10
+
11
+ type HiddenRenderPropArg = {}
12
+ type HiddenPropsWeControl = never
13
+ export type HiddenProps = Props<
14
+ typeof DEFAULT_VISUALLY_HIDDEN_TAG,
15
+ HiddenRenderPropArg,
16
+ { element?: HTMLElement; features?: HiddenFeatures }
17
+ >
5
18
  </script>
6
19
 
7
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDDEN_TAG">let {
8
- ref = $bindable(),
9
- value,
10
- checked,
11
- features = HiddenFeatures.None,
12
- ...theirProps
13
- } = $props();
14
- let ourProps = {
15
- "aria-hidden": (features & HiddenFeatures.Focusable) === HiddenFeatures.Focusable ? true : theirProps["aria-hidden"] ?? void 0,
16
- hidden: (features & HiddenFeatures.Hidden) === HiddenFeatures.Hidden ? true : void 0,
17
- style: [
18
- "position: fixed",
19
- "top: 1px",
20
- "left: 1px",
21
- "width: 1px",
22
- "height: 0",
23
- "padding: 0",
24
- "margin: -1px",
25
- "overflow: hidden",
26
- "clip: rect(0, 0, 0, 0)",
27
- "whiteSpace: nowrap",
28
- "borderWidth: 0",
29
- ...(features & HiddenFeatures.Hidden) === HiddenFeatures.Hidden && !((features & HiddenFeatures.Focusable) === HiddenFeatures.Focusable) ? ["display: none"] : []
30
- ].join("; ")
31
- };
20
+ <script lang="ts">
21
+ let { element = $bindable(), features = HiddenFeatures.None, ...theirProps }: HiddenProps = $props()
22
+
23
+ let ourProps = {
24
+ "aria-hidden":
25
+ (features & HiddenFeatures.Focusable) === HiddenFeatures.Focusable
26
+ ? true
27
+ : (theirProps["aria-hidden"] ?? undefined),
28
+ hidden: (features & HiddenFeatures.Hidden) === HiddenFeatures.Hidden ? true : undefined,
29
+ style: [
30
+ "position: fixed",
31
+ "top: 1px",
32
+ "left: 1px",
33
+ "width: 1px",
34
+ "height: 0",
35
+ "padding: 0",
36
+ "margin: -1px",
37
+ "overflow: hidden",
38
+ "clip: rect(0, 0, 0, 0)",
39
+ "whiteSpace: nowrap",
40
+ "borderWidth: 0",
41
+ ...((features & HiddenFeatures.Hidden) === HiddenFeatures.Hidden &&
42
+ !((features & HiddenFeatures.Focusable) === HiddenFeatures.Focusable)
43
+ ? ["display: none"]
44
+ : []),
45
+ ].join("; "),
46
+ }
32
47
  </script>
33
48
 
34
- <ElementOrComponent
35
- {ourProps}
36
- {theirProps}
37
- defaultTag={DEFAULT_VISUALLY_HIDDEN_TAG}
38
- name="Hidden"
39
- bind:ref
40
- {value}
41
- {checked}
42
- />
49
+ <ElementOrComponent {ourProps} {theirProps} defaultTag={DEFAULT_VISUALLY_HIDDEN_TAG} name="Hidden" bind:element />
@@ -1,37 +1,11 @@
1
- import type { ElementType, Props } from "../utils/types.js";
1
+ import type { Props } from "../utils/types.js";
2
2
  import { HiddenFeatures } from "./HiddenFeatures.js";
3
3
  export * from "./HiddenFeatures.js";
4
4
  declare const DEFAULT_VISUALLY_HIDDEN_TAG: "span";
5
5
  type HiddenRenderPropArg = {};
6
- type HiddenPropsWeControl = never;
7
- export type HiddenProps<TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDDEN_TAG> = Props<TTag, HiddenRenderPropArg, HiddenPropsWeControl, {
6
+ export type HiddenProps = Props<typeof DEFAULT_VISUALLY_HIDDEN_TAG, HiddenRenderPropArg, {
7
+ element?: HTMLElement;
8
8
  features?: HiddenFeatures;
9
9
  }>;
10
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDDEN_TAG> {
11
- props(): {
12
- as?: TTag | undefined;
13
- } & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("slot" | "as" | "children" | "class" | "ref") | "features"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
14
- children?: import("svelte").Snippet<[{
15
- slot: HiddenRenderPropArg;
16
- props: Record<string, any>;
17
- }]> | undefined;
18
- class?: string | ((bag: HiddenRenderPropArg) => string) | null | undefined;
19
- ref?: HTMLElement;
20
- } & {
21
- features?: HiddenFeatures;
22
- };
23
- events(): {};
24
- slots(): {};
25
- bindings(): "ref";
26
- exports(): {};
27
- }
28
- interface $$IsomorphicComponent {
29
- new <TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDDEN_TAG>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag>['props']>, ReturnType<__sveltets_Render<TTag>['events']>, ReturnType<__sveltets_Render<TTag>['slots']>> & {
30
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
31
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
32
- <TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDDEN_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
33
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
34
- }
35
- declare const Hidden: $$IsomorphicComponent;
36
- type Hidden<TTag extends ElementType = typeof DEFAULT_VISUALLY_HIDDEN_TAG> = InstanceType<typeof Hidden<TTag>>;
10
+ declare const Hidden: import("svelte").Component<HiddenProps, {}, "element">;
37
11
  export default Hidden;
@@ -1,45 +1,98 @@
1
- <script lang="ts" module>import { getContext, onMount } from "svelte";
2
- export function useMainTreeNode(options = {}) {
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
- <script lang="ts">import { setContext } from "svelte";
13
- import Hidden, { HiddenFeatures } from "./Hidden.svelte";
14
- import { getOwnerDocument } from "../utils/owner.js";
15
- let { node, children } = $props();
16
- let mainTreeNode = $state(null);
17
- const resolvedMainTreeNode = useMainTreeNode({
18
- get fallbackMainTreeNode() {
19
- return node ?? mainTreeNode;
20
- }
21
- });
22
- setContext("MainTreeContext", {
23
- get node() {
24
- return resolvedMainTreeNode.node;
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
- let el = $state();
28
- onMount(() => {
29
- if (!el) return;
30
- for (let container of getOwnerDocument(el)?.querySelectorAll("html > *, body > *") ?? []) {
31
- if (container === document.body) continue;
32
- if (container === document.head) continue;
33
- if (!(container instanceof HTMLElement)) continue;
34
- if (container?.contains(el)) {
35
- mainTreeNode = container;
36
- break;
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}
43
96
  {#if resolvedMainTreeNode === null}
44
- <Hidden features={HiddenFeatures.Hidden} bind:ref={el} />
97
+ <Hidden features={HiddenFeatures.Hidden} bind:element={el} />
45
98
  {/if}
@@ -1,17 +1,21 @@
1
- <script lang="ts">import { onDestroy, onMount } from "svelte";
2
- let { target, children } = $props();
3
- let ref = $state();
4
- onMount(() => {
5
- target.appendChild(ref);
6
- });
7
- onDestroy(() => {
8
- const _ref = ref;
9
- setTimeout(() => {
10
- if (_ref?.parentNode) {
11
- _ref.parentNode?.removeChild(_ref);
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>
@@ -1,66 +1,107 @@
1
- <script lang="ts" module>let DEFAULT_LABEL_TAG = "label";
1
+ <script lang="ts" module>
2
+ import type { Props } from "../utils/types.js"
3
+
4
+ const DEFAULT_LABEL_TAG = "label" as const
5
+
6
+ export type LabelProps = Props<
7
+ typeof DEFAULT_LABEL_TAG,
8
+ {},
9
+ {
10
+ element?: HTMLElement
11
+ id?: string
12
+ passive?: boolean
13
+ htmlFor?: string
14
+ }
15
+ >
2
16
  </script>
3
17
 
4
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_LABEL_TAG">import { onMount } from "svelte";
5
- import { useProvidedId, htmlid } from "../utils/id.js";
6
- import { useDisabled } from "../hooks/use-disabled.js";
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();
28
- }
29
- console.log("click", providedHtmlFor);
30
- if (current instanceof HTMLLabelElement) {
31
- let target = document.getElementById(current.getAttribute("for") ?? "");
32
- if (target) {
33
- let actuallyDisabled = target.getAttribute("disabled");
34
- if (actuallyDisabled === "true" || actuallyDisabled === "") {
35
- return;
36
- }
37
- let ariaDisabled = target.getAttribute("aria-disabled");
38
- if (ariaDisabled === "true" || ariaDisabled === "") {
39
- return;
40
- }
41
- if (target instanceof HTMLInputElement && (target.type === "radio" || target.type === "checkbox") || target.role === "radio" || target.role === "checkbox" || target.role === "switch") {
42
- target.click();
18
+ <script lang="ts">
19
+ import { onMount } from "svelte"
20
+ import { useProvidedId, htmlid } from "../utils/id.js"
21
+ import { useDisabled } from "../hooks/use-disabled.js"
22
+ import { stateFromSlot } from "../utils/state.js"
23
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
24
+ import { useLabelContext } from "./context.svelte.js"
25
+
26
+ const internalId = htmlid()
27
+ const context = useLabelContext()
28
+ const providedHtmlFor = useProvidedId()
29
+ const providedDisabled = useDisabled()
30
+
31
+ let {
32
+ element = $bindable(),
33
+ id = `headlessui-label-${internalId}`,
34
+ htmlFor = providedHtmlFor,
35
+ passive = false,
36
+ ...theirOriginalProps
37
+ }: LabelProps = $props()
38
+
39
+ onMount(() => {
40
+ context.register(id)
41
+ })
42
+
43
+ let handleClick = (e: MouseEvent) => {
44
+ let current = e.currentTarget
45
+
46
+ // Labels connected to 'real' controls will already click the element. But we don't know that
47
+ // ahead of time. This will prevent the default click, such that only a single click happens
48
+ // instead of two. Otherwise this results in a visual no-op.
49
+ if (current instanceof HTMLLabelElement) {
50
+ e.preventDefault()
51
+ }
52
+
53
+ console.log("click", providedHtmlFor)
54
+
55
+ if (current instanceof HTMLLabelElement) {
56
+ let target = document.getElementById(current.getAttribute("for") ?? "")
57
+ if (target) {
58
+ // Bail if the target element is disabled
59
+ let actuallyDisabled = target.getAttribute("disabled")
60
+ if (actuallyDisabled === "true" || actuallyDisabled === "") {
61
+ return
62
+ }
63
+
64
+ let ariaDisabled = target.getAttribute("aria-disabled")
65
+ if (ariaDisabled === "true" || ariaDisabled === "") {
66
+ return
67
+ }
68
+
69
+ // Ensure we click the element this label is bound to. This is necessary for elements that
70
+ // immediately require state changes, e.g.: Radio & Checkbox inputs need to be checked (or
71
+ // unchecked).
72
+ if (
73
+ (target instanceof HTMLInputElement && (target.type === "radio" || target.type === "checkbox")) ||
74
+ target.role === "radio" ||
75
+ target.role === "checkbox" ||
76
+ target.role === "switch"
77
+ ) {
78
+ target.click()
79
+ }
80
+
81
+ // Move focus to the element, this allows you to start using keyboard shortcuts since the
82
+ // bound element is now focused.
83
+ target.focus({ preventScroll: true })
43
84
  }
44
- target.focus({ preventScroll: true });
45
85
  }
46
86
  }
47
- };
48
- const disabled = $derived(providedDisabled.current ?? false);
49
- const slot = $derived({ disabled });
50
- const ourProps = $derived({
51
- id,
52
- for: passive ? void 0 : htmlFor,
53
- onclick: passive ? void 0 : handleClick,
54
- ...stateFromSlot(slot)
55
- });
56
- const theirProps = $derived.by(() => {
57
- if (passive) {
58
- const { onclick: _, ...props } = theirOriginalProps;
59
- return props;
60
- } else {
61
- return theirOriginalProps;
62
- }
63
- });
87
+
88
+ const disabled = $derived(providedDisabled.current ?? false)
89
+ const slot = $derived({ disabled })
90
+ const ourProps = $derived({
91
+ id,
92
+ for: passive ? undefined : htmlFor,
93
+ onclick: passive ? undefined : handleClick,
94
+ ...stateFromSlot(slot),
95
+ })
96
+
97
+ const theirProps = $derived.by(() => {
98
+ if (passive) {
99
+ const { onclick: _, ...props } = theirOriginalProps
100
+ return props
101
+ } else {
102
+ return theirOriginalProps
103
+ }
104
+ })
64
105
  </script>
65
106
 
66
107
  <ElementOrComponent
@@ -68,5 +109,5 @@ const theirProps = $derived.by(() => {
68
109
  {theirProps}
69
110
  defaultTag={htmlFor ? DEFAULT_LABEL_TAG : "div"}
70
111
  name={context.name || "Label"}
71
- bind:ref
112
+ bind:element
72
113
  />
@@ -1,35 +1,10 @@
1
- import type { ElementType, Props, PropsOf } from "../utils/types.js";
2
- declare let DEFAULT_LABEL_TAG: "label";
3
- export type LabelProps<TTag extends ElementType = typeof DEFAULT_LABEL_TAG> = Props<TTag> & {
1
+ import type { Props } from "../utils/types.js";
2
+ declare const DEFAULT_LABEL_TAG: "label";
3
+ export type LabelProps = Props<typeof DEFAULT_LABEL_TAG, {}, {
4
+ element?: HTMLElement;
5
+ id?: string;
4
6
  passive?: boolean;
5
7
  htmlFor?: string;
6
- };
7
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_LABEL_TAG> {
8
- props(): {
9
- as?: TTag | undefined;
10
- } & (Exclude<keyof PropsOf<TTag>, "slot" | "as" | "children" | "class" | "ref"> 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;
15
- class?: string | ((bag: {}) => string) | null | undefined;
16
- ref?: HTMLElement;
17
- } & {
18
- passive?: boolean;
19
- htmlFor?: string;
20
- };
21
- events(): {};
22
- slots(): {};
23
- bindings(): "ref";
24
- exports(): {};
25
- }
26
- interface $$IsomorphicComponent {
27
- new <TTag extends ElementType = typeof DEFAULT_LABEL_TAG>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag>['props']>, ReturnType<__sveltets_Render<TTag>['events']>, ReturnType<__sveltets_Render<TTag>['slots']>> & {
28
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
29
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
30
- <TTag extends ElementType = typeof DEFAULT_LABEL_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
31
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
32
- }
33
- declare const Label: $$IsomorphicComponent;
34
- type Label<TTag extends ElementType = typeof DEFAULT_LABEL_TAG> = InstanceType<typeof Label<TTag>>;
8
+ }>;
9
+ declare const Label: import("svelte").Component<LabelProps, {}, "element">;
35
10
  export default Label;
@@ -1,8 +1,31 @@
1
- <script lang="ts" module>import { Label } from "../index.js";
2
- const DEFAULT_LEGEND_TAG = "div";
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
+ export type LegendProps = Props<
8
+ typeof DEFAULT_LEGEND_TAG,
9
+ {},
10
+ {
11
+ element?: HTMLElement
12
+ class?: string
13
+ }
14
+ >
3
15
  </script>
4
16
 
5
- <script lang="ts">let { ...props } = $props();
17
+ <script lang="ts">
18
+ let { asChild, children: theirChildren, ...props }: LegendProps = $props()
6
19
  </script>
7
20
 
8
- <Label as="div" {...props} />
21
+ <Label asChild>
22
+ {#snippet children({ props: childProps })}
23
+ {#if asChild}
24
+ {@render theirChildren?.({ props: { ...props, ...childProps } })}
25
+ {:else}
26
+ <div {...props} {...childProps}>
27
+ {@render theirChildren?.({ props: {} })}
28
+ </div>
29
+ {/if}
30
+ {/snippet}
31
+ </Label>
@@ -1,7 +1,8 @@
1
1
  import type { Props } from "../utils/types.js";
2
2
  declare const DEFAULT_LEGEND_TAG: "div";
3
- type LegendRenderPropArg = {};
4
- type LegendPropsWeControl = never;
5
- export type LegendProps = Props<typeof DEFAULT_LEGEND_TAG, LegendRenderPropArg, LegendPropsWeControl, {}>;
3
+ export type LegendProps = Props<typeof DEFAULT_LEGEND_TAG, {}, {
4
+ element?: HTMLElement;
5
+ class?: string;
6
+ }>;
6
7
  declare const Legend: import("svelte").Component<LegendProps, {}, "">;
7
8
  export default Legend;