@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,9 +1,24 @@
1
- <script lang="ts" module>const DEFAULT_SEPARATOR_TAG = "div";
1
+ <script lang="ts" module>
2
+ import type { Props } from "../utils/types.js"
3
+
4
+ const DEFAULT_SEPARATOR_TAG = "div" as const
5
+ type SeparatorRenderPropArg = {}
6
+ type SeparatorPropsWeControl = "role"
7
+
8
+ export type MenuSeparatorProps = Props<
9
+ typeof DEFAULT_SEPARATOR_TAG,
10
+ SeparatorRenderPropArg,
11
+ {
12
+ element?: HTMLElement
13
+ }
14
+ >
2
15
  </script>
3
16
 
4
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_SEPARATOR_TAG">import ElementOrComponent from "../utils/ElementOrComponent.svelte";
5
- let { ref = $bindable(), ...theirProps } = $props();
6
- const ourProps = { role: "separator" };
17
+ <script lang="ts">
18
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
19
+
20
+ let { element = $bindable(), ...theirProps }: MenuSeparatorProps = $props()
21
+ const ourProps = { role: "separator" }
7
22
  </script>
8
23
 
9
- <ElementOrComponent {ourProps} {theirProps} defaultTag={DEFAULT_SEPARATOR_TAG} name="MenuSeparator" bind:ref />
24
+ <ElementOrComponent {ourProps} {theirProps} defaultTag={DEFAULT_SEPARATOR_TAG} name="MenuSeparator" bind:element />
@@ -1,31 +1,8 @@
1
- import type { ElementType, Props } from "../utils/types.js";
1
+ import type { Props } from "../utils/types.js";
2
2
  declare const DEFAULT_SEPARATOR_TAG: "div";
3
3
  type SeparatorRenderPropArg = {};
4
- type SeparatorPropsWeControl = "role";
5
- export type MenuSeparatorProps<TTag extends ElementType = typeof DEFAULT_SEPARATOR_TAG> = Props<TTag, SeparatorRenderPropArg, SeparatorPropsWeControl>;
6
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_SEPARATOR_TAG> {
7
- props(): {
8
- as?: TTag | undefined;
9
- } & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("slot" | "as" | "children" | "class" | "ref") | "role"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
10
- children?: import("svelte").Snippet<[{
11
- slot: SeparatorRenderPropArg;
12
- props: Record<string, any>;
13
- }]> | undefined;
14
- class?: string | ((bag: SeparatorRenderPropArg) => string) | null | undefined;
15
- ref?: HTMLElement;
16
- };
17
- events(): {};
18
- slots(): {};
19
- bindings(): "ref";
20
- exports(): {};
21
- }
22
- interface $$IsomorphicComponent {
23
- new <TTag extends ElementType = typeof DEFAULT_SEPARATOR_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']>> & {
24
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
25
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
26
- <TTag extends ElementType = typeof DEFAULT_SEPARATOR_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
27
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
28
- }
29
- declare const MenuSeparator: $$IsomorphicComponent;
30
- type MenuSeparator<TTag extends ElementType = typeof DEFAULT_SEPARATOR_TAG> = InstanceType<typeof MenuSeparator<TTag>>;
4
+ export type MenuSeparatorProps = Props<typeof DEFAULT_SEPARATOR_TAG, SeparatorRenderPropArg, {
5
+ element?: HTMLElement;
6
+ }>;
7
+ declare const MenuSeparator: import("svelte").Component<MenuSeparatorProps, {}, "element">;
31
8
  export default MenuSeparator;
@@ -1,161 +1,227 @@
1
- <script lang="ts" module>export const DEFAULT_POPOVER_TAG = "div";
2
- </script>
1
+ <script lang="ts" module>
2
+ import type { Props } from "../utils/types.js"
3
3
 
4
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_POPOVER_TAG">import { getOwnerDocument } from "../utils/owner.js";
5
- import { setContext, untrack } from "svelte";
6
- import {
7
- createPopoverContext,
8
- PopoverStates,
9
- usePopoverGroupContext
10
- } from "./context.svelte.js";
11
- import { FocusableMode, getFocusableElements, isFocusableElement } from "../utils/focus-management.js";
12
- import { useNestedPortals } from "../portal/InternalPortal.svelte";
13
- import MainTreeProvider, { useMainTreeNode } from "../internal/MainTreeProvider.svelte";
14
- import { useRootContainers } from "../hooks/use-root-containers.svelte.js";
15
- import { useEventListener } from "../hooks/use-event-listener.svelte.js";
16
- import { useOutsideClick } from "../hooks/use-outside-click.svelte.js";
17
- import { useFloatingProvider } from "../internal/floating-provider.svelte.js";
18
- import { createCloseContext } from "../internal/close-provider.js";
19
- import { createOpenClosedContext, State } from "../internal/open-closed.js";
20
- import ElementOrComponent from "../utils/ElementOrComponent.svelte";
21
- let { ref = $bindable(), __demoMode = false, ...theirProps } = $props();
22
- let buttons = $state([]);
23
- const context = createPopoverContext({
24
- __demoMode,
25
- popoverState: __demoMode ? PopoverStates.Open : PopoverStates.Closed,
26
- buttons
27
- });
28
- const {
29
- popoverState,
30
- button,
31
- buttonId,
32
- panel,
33
- panelId,
34
- beforePanelSentinel,
35
- afterPanelSentinel,
36
- afterButtonSentinel
37
- } = $derived(context);
38
- const ownerDocument = $derived(getOwnerDocument(ref ?? button));
39
- const isPortalled = $derived.by(() => {
40
- if (!button) return false;
41
- if (!panel) return false;
42
- return untrack(() => {
43
- for (let root2 of document.querySelectorAll("body > *")) {
44
- if (Number(root2?.contains(button)) ^ Number(root2?.contains(panel))) {
45
- return true;
46
- }
47
- }
48
- let elements = getFocusableElements();
49
- let buttonIdx = elements.indexOf(button);
50
- let beforeIdx = (buttonIdx + elements.length - 1) % elements.length;
51
- let afterIdx = (buttonIdx + 1) % elements.length;
52
- let beforeElement = elements[beforeIdx];
53
- let afterElement = elements[afterIdx];
54
- if (!panel.contains(beforeElement) && !panel.contains(afterElement)) {
55
- return true;
56
- }
57
- return false;
58
- });
59
- });
60
- const registerBag = $derived({
61
- buttonId,
62
- panelId,
63
- close: () => context.closePopover()
64
- });
65
- const groupContext = usePopoverGroupContext();
66
- const registerPopover = $derived(groupContext?.registerPopover);
67
- const isFocusWithinPopoverGroup = () => {
68
- return groupContext?.isFocusWithinPopoverGroup() ?? (ownerDocument?.activeElement && (button?.contains(ownerDocument.activeElement) || panel?.contains(ownerDocument.activeElement)));
69
- };
70
- $effect(() => registerPopover?.(registerBag));
71
- const nestedPortals = useNestedPortals();
72
- const { portals } = $derived(nestedPortals);
73
- const mainTreeNode = useMainTreeNode({
74
- get fallbackMainTreeNode() {
75
- return button;
76
- }
77
- });
78
- const root = useRootContainers({
79
- get mainTreeNode() {
80
- return mainTreeNode.node;
81
- },
82
- get portals() {
83
- return portals;
84
- },
85
- get defaultContainers() {
86
- return [button, panel];
4
+ export const DEFAULT_POPOVER_TAG = "div" as const
5
+ type PopoverRenderPropArg = {
6
+ open: boolean
7
+ close(focusableElement?: HTMLElement | MouseEvent<HTMLElement>): void
87
8
  }
88
- });
89
- useEventListener({
90
- get element() {
91
- return ownerDocument?.defaultView;
92
- },
93
- type: "focus",
94
- listener: (event) => {
95
- if (event.target === window) return;
96
- if (!(event.target instanceof HTMLElement)) return;
97
- if (popoverState !== PopoverStates.Open) return;
98
- if (isFocusWithinPopoverGroup()) return;
99
- if (!button) return;
100
- if (!panel) return;
101
- if (root.contains(event.target)) return;
102
- if (beforePanelSentinel?.contains?.(event.target)) return;
103
- if (afterPanelSentinel?.contains?.(event.target)) return;
104
- if (afterButtonSentinel?.contains?.(event.target)) return;
105
- context.closePopover();
106
- },
107
- options: true
108
- });
109
- const outsideClickEnabled = $derived(popoverState === PopoverStates.Open);
110
- useOutsideClick({
111
- get enabled() {
112
- return outsideClickEnabled;
113
- },
114
- get containers() {
115
- return root.resolvedContainers;
116
- },
117
- cb: (event, target) => {
118
- context.closePopover();
119
- if (!isFocusableElement(target, FocusableMode.Loose)) {
120
- event.preventDefault();
121
- button?.focus();
9
+ type PopoverPropsWeControl = never
10
+
11
+ export type PopoverProps = Props<
12
+ typeof DEFAULT_POPOVER_TAG,
13
+ PopoverRenderPropArg,
14
+ {
15
+ element?: HTMLElement
16
+ __demoMode?: boolean
122
17
  }
18
+ >
19
+ </script>
20
+
21
+ <script lang="ts">
22
+ import { getOwnerDocument } from "../utils/owner.js"
23
+
24
+ import { setContext, untrack } from "svelte"
25
+ import {
26
+ createPopoverContext,
27
+ PopoverStates,
28
+ usePopoverGroupContext,
29
+ type MouseEvent,
30
+ type PopoverAPIContext,
31
+ type PopoverPanelContext,
32
+ } from "./context.svelte.js"
33
+ import { FocusableMode, getFocusableElements, isFocusableElement } from "../utils/focus-management.js"
34
+ import { useNestedPortals } from "../portal/InternalPortal.svelte"
35
+ import MainTreeProvider, { useMainTreeNode } from "../internal/MainTreeProvider.svelte"
36
+ import { useRootContainers } from "../hooks/use-root-containers.svelte.js"
37
+ import { useEventListener } from "../hooks/use-event-listener.svelte.js"
38
+ import { useOutsideClick } from "../hooks/use-outside-click.svelte.js"
39
+ import { useFloatingProvider } from "../internal/floating-provider.svelte.js"
40
+ import { createCloseContext } from "../internal/close-provider.js"
41
+ import { createOpenClosedContext, State } from "../internal/open-closed.js"
42
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
43
+
44
+ let { element = $bindable(), __demoMode = false, ...theirProps }: PopoverProps = $props()
45
+
46
+ let buttons = $state([])
47
+ const context = createPopoverContext({
48
+ __demoMode,
49
+ popoverState: __demoMode ? PopoverStates.Open : PopoverStates.Closed,
50
+ buttons,
51
+ })
52
+ const {
53
+ popoverState,
54
+ button,
55
+ buttonId,
56
+ panel,
57
+ panelId,
58
+ beforePanelSentinel,
59
+ afterPanelSentinel,
60
+ afterButtonSentinel,
61
+ } = $derived(context)
62
+
63
+ const ownerDocument = $derived(getOwnerDocument(element ?? button))
64
+
65
+ const isPortalled = $derived.by(() => {
66
+ if (!button) return false
67
+ if (!panel) return false
68
+
69
+ return untrack(() => {
70
+ // We are part of a different "root" tree, so therefore we can consider it portalled. This is a
71
+ // heuristic because 3rd party tools could use some form of portal, typically rendered at the
72
+ // end of the body but we don't have an actual reference to that.
73
+ for (let root of document.querySelectorAll("body > *")) {
74
+ if (Number(root?.contains(button)) ^ Number(root?.contains(panel))) {
75
+ return true
76
+ }
77
+ }
78
+
79
+ // Use another heuristic to try and calculate whether or not the focusable
80
+ // elements are near each other (aka, following the default focus/tab order
81
+ // from the browser). If they are then it doesn't really matter if they are
82
+ // portalled or not because we can follow the default tab order. But if they
83
+ // are not, then we can consider it being portalled so that we can ensure
84
+ // that tab and shift+tab (hopefully) go to the correct spot.
85
+ let elements = getFocusableElements()
86
+ let buttonIdx = elements.indexOf(button)
87
+
88
+ let beforeIdx = (buttonIdx + elements.length - 1) % elements.length
89
+ let afterIdx = (buttonIdx + 1) % elements.length
90
+
91
+ let beforeElement = elements[beforeIdx]
92
+ let afterElement = elements[afterIdx]
93
+
94
+ if (!panel.contains(beforeElement) && !panel.contains(afterElement)) {
95
+ return true
96
+ }
97
+
98
+ // It may or may not be portalled, but we don't really know.
99
+ return false
100
+ })
101
+ })
102
+
103
+ const registerBag = $derived({
104
+ buttonId,
105
+ panelId,
106
+ close: () => context.closePopover(),
107
+ })
108
+
109
+ const groupContext = usePopoverGroupContext()
110
+ const registerPopover = $derived(groupContext?.registerPopover)
111
+ const isFocusWithinPopoverGroup = () => {
112
+ return (
113
+ groupContext?.isFocusWithinPopoverGroup() ??
114
+ (ownerDocument?.activeElement &&
115
+ (button?.contains(ownerDocument.activeElement) || panel?.contains(ownerDocument.activeElement)))
116
+ )
123
117
  }
124
- });
125
- const close = (focusableElement) => {
126
- context.closePopover();
127
- const restoreElement = (() => {
128
- if (!focusableElement) return button;
129
- if (focusableElement instanceof HTMLElement) return focusableElement;
130
- return button;
131
- })();
132
- restoreElement?.focus();
133
- };
134
- const api = {
135
- close,
136
- get isPortalled() {
137
- return isPortalled;
138
- }
139
- };
140
- setContext("PopoverAPIContext", api);
141
- const slot = $derived({
142
- open: popoverState === PopoverStates.Open,
143
- close
144
- });
145
- useFloatingProvider();
146
- setContext("PopoverPanelContext", void 0);
147
- createCloseContext({
148
- get close() {
149
- return close;
118
+
119
+ $effect(() => registerPopover?.(registerBag))
120
+
121
+ const nestedPortals = useNestedPortals()
122
+ const { portals } = $derived(nestedPortals)
123
+ const mainTreeNode = useMainTreeNode({
124
+ get fallbackMainTreeNode() {
125
+ return button
126
+ },
127
+ })
128
+ const root = useRootContainers({
129
+ get mainTreeNode() {
130
+ return mainTreeNode.node
131
+ },
132
+ get portals() {
133
+ return portals
134
+ },
135
+ get defaultContainers() {
136
+ return [button, panel]
137
+ },
138
+ })
139
+
140
+ // Handle focus out
141
+ useEventListener({
142
+ get element() {
143
+ return ownerDocument?.defaultView
144
+ },
145
+ type: "focus",
146
+ listener: (event) => {
147
+ if (event.target === window) return
148
+ if (!(event.target instanceof HTMLElement)) return
149
+ if (popoverState !== PopoverStates.Open) return
150
+ if (isFocusWithinPopoverGroup()) return
151
+ if (!button) return
152
+ if (!panel) return
153
+ if (root.contains(event.target)) return
154
+ if (beforePanelSentinel?.contains?.(event.target)) return
155
+ if (afterPanelSentinel?.contains?.(event.target)) return
156
+ if (afterButtonSentinel?.contains?.(event.target)) return
157
+
158
+ context.closePopover()
159
+ },
160
+ options: true,
161
+ })
162
+
163
+ // Handle outside click
164
+ const outsideClickEnabled = $derived(popoverState === PopoverStates.Open)
165
+ useOutsideClick({
166
+ get enabled() {
167
+ return outsideClickEnabled
168
+ },
169
+ get containers() {
170
+ return root.resolvedContainers
171
+ },
172
+ cb: (event, target) => {
173
+ context.closePopover()
174
+
175
+ if (!isFocusableElement(target, FocusableMode.Loose)) {
176
+ event.preventDefault()
177
+ button?.focus()
178
+ }
179
+ },
180
+ })
181
+
182
+ const close = (focusableElement?: HTMLElement | MouseEvent<HTMLElement>) => {
183
+ context.closePopover()
184
+
185
+ const restoreElement = (() => {
186
+ if (!focusableElement) return button
187
+ if (focusableElement instanceof HTMLElement) return focusableElement
188
+
189
+ return button
190
+ })()
191
+
192
+ restoreElement?.focus()
150
193
  }
151
- });
152
- createOpenClosedContext({
153
- get value() {
154
- return context.popoverState === PopoverStates.Open ? State.Open : State.Closed;
194
+
195
+ const api: PopoverAPIContext = {
196
+ close,
197
+ get isPortalled() {
198
+ return isPortalled
199
+ },
155
200
  }
156
- });
201
+ setContext("PopoverAPIContext", api)
202
+
203
+ const slot = $derived({
204
+ open: popoverState === PopoverStates.Open,
205
+ close,
206
+ } satisfies PopoverRenderPropArg)
207
+
208
+ useFloatingProvider()
209
+
210
+ setContext<PopoverPanelContext | undefined>("PopoverPanelContext", undefined)
211
+
212
+ createCloseContext({
213
+ get close() {
214
+ return close
215
+ },
216
+ })
217
+
218
+ createOpenClosedContext({
219
+ get value() {
220
+ return context.popoverState === PopoverStates.Open ? State.Open : State.Closed
221
+ },
222
+ })
157
223
  </script>
158
224
 
159
225
  <MainTreeProvider node={mainTreeNode.node}>
160
- <ElementOrComponent {theirProps} slots={slot} defaultTag={DEFAULT_POPOVER_TAG} name="Popover" bind:ref />
226
+ <ElementOrComponent {theirProps} slots={slot} defaultTag={DEFAULT_POPOVER_TAG} name="Popover" bind:element />
161
227
  </MainTreeProvider>
@@ -1,39 +1,13 @@
1
- import type { ElementType, Props } from "../utils/types.js";
1
+ import type { Props } from "../utils/types.js";
2
2
  export declare const DEFAULT_POPOVER_TAG: "div";
3
3
  type PopoverRenderPropArg = {
4
4
  open: boolean;
5
5
  close(focusableElement?: HTMLElement | MouseEvent<HTMLElement>): void;
6
6
  };
7
- type PopoverPropsWeControl = never;
8
- export type PopoverProps<TTag extends ElementType = typeof DEFAULT_POPOVER_TAG> = Props<TTag, PopoverRenderPropArg, PopoverPropsWeControl, {
7
+ export type PopoverProps = Props<typeof DEFAULT_POPOVER_TAG, PopoverRenderPropArg, {
8
+ element?: HTMLElement;
9
9
  __demoMode?: boolean;
10
10
  }>;
11
11
  import { type MouseEvent } from "./context.svelte.js";
12
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_POPOVER_TAG> {
13
- props(): {
14
- as?: TTag | undefined;
15
- } & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("slot" | "as" | "children" | "class" | "ref") | "__demoMode"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
16
- children?: import("svelte").Snippet<[{
17
- slot: PopoverRenderPropArg;
18
- props: Record<string, any>;
19
- }]> | undefined;
20
- class?: string | ((bag: PopoverRenderPropArg) => string) | null | undefined;
21
- ref?: HTMLElement;
22
- } & {
23
- __demoMode?: boolean;
24
- };
25
- events(): {};
26
- slots(): {};
27
- bindings(): "ref";
28
- exports(): {};
29
- }
30
- interface $$IsomorphicComponent {
31
- new <TTag extends ElementType = typeof DEFAULT_POPOVER_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']>> & {
32
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
33
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
34
- <TTag extends ElementType = typeof DEFAULT_POPOVER_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
35
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
36
- }
37
- declare const Popover: $$IsomorphicComponent;
38
- type Popover<TTag extends ElementType = typeof DEFAULT_POPOVER_TAG> = InstanceType<typeof Popover<TTag>>;
12
+ declare const Popover: import("svelte").Component<PopoverProps, {}, "element">;
39
13
  export default Popover;
@@ -1,47 +1,76 @@
1
- <script lang="ts" module>import { RenderFeatures } from "../utils/render.js";
2
- let DEFAULT_BACKDROP_TAG = "div";
3
- const BackdropRenderFeatures = RenderFeatures.RenderStrategy | RenderFeatures.Static;
1
+ <script lang="ts" module>
2
+ import type { Props } from "../utils/types.js"
3
+ import { RenderFeatures, type PropsForFeatures } from "../utils/render.js"
4
+
5
+ let DEFAULT_BACKDROP_TAG = "div" as const
6
+ type BackdropRenderPropArg = {
7
+ open: boolean
8
+ }
9
+ type BackdropPropsWeControl = "aria-hidden"
10
+
11
+ const BackdropRenderFeatures = RenderFeatures.RenderStrategy | RenderFeatures.Static
12
+
13
+ export type PopoverBackdropProps = Props<
14
+ typeof DEFAULT_BACKDROP_TAG,
15
+ BackdropRenderPropArg,
16
+ {
17
+ element?: HTMLElement
18
+ id?: string
19
+ transition?: boolean
20
+ } & PropsForFeatures<typeof BackdropRenderFeatures>
21
+ >
22
+
23
+ export type PopoverOverlayProps = PopoverBackdropProps
4
24
  </script>
5
25
 
6
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG">import ElementOrComponent from "../utils/ElementOrComponent.svelte";
7
- import { useId } from "../hooks/use-id.js";
8
- import { PopoverStates, usePopoverContext } from "./context.svelte.js";
9
- import { State, useOpenClosed } from "../internal/open-closed.js";
10
- import { transitionDataAttributes, useTransition } from "../hooks/use-transition.svelte.js";
11
- const internalId = useId();
12
- let {
13
- ref = $bindable(),
14
- id = `headlessui-popover-backdrop-${internalId}`,
15
- transition = false,
16
- ...theirProps
17
- } = $props();
18
- const context = usePopoverContext("PopoverBackdrop");
19
- const { popoverState } = $derived(context);
20
- const usesOpenClosedState = useOpenClosed();
21
- const _transition = useTransition({
22
- get enabled() {
23
- return transition;
24
- },
25
- get element() {
26
- return ref;
27
- },
28
- get show() {
29
- return usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Open) === State.Open : popoverState === PopoverStates.Open;
26
+ <script lang="ts">
27
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
28
+ import { useId } from "../hooks/use-id.js"
29
+ import { PopoverStates, usePopoverContext } from "./context.svelte.js"
30
+ import { State, useOpenClosed } from "../internal/open-closed.js"
31
+ import { transitionDataAttributes, useTransition } from "../hooks/use-transition.svelte.js"
32
+
33
+ const internalId = useId()
34
+ let {
35
+ element = $bindable(),
36
+ id = `headlessui-popover-backdrop-${internalId}`,
37
+ transition = false,
38
+ ...theirProps
39
+ }: PopoverBackdropProps = $props()
40
+ const context = usePopoverContext("PopoverBackdrop")
41
+ const { popoverState } = $derived(context)
42
+
43
+ const usesOpenClosedState = useOpenClosed()
44
+ const _transition = useTransition({
45
+ get enabled() {
46
+ return transition
47
+ },
48
+ get element() {
49
+ return element
50
+ },
51
+ get show() {
52
+ return usesOpenClosedState !== null
53
+ ? (usesOpenClosedState.value & State.Open) === State.Open
54
+ : popoverState === PopoverStates.Open
55
+ },
56
+ })
57
+ const { visible, data: transitionData } = $derived(_transition)
58
+
59
+ const handleClick = (event: MouseEvent) => {
60
+ //if (isDisabledReactIssue7711(event.currentTarget)) return event.preventDefault()
61
+ context.closePopover()
30
62
  }
31
- });
32
- const { visible, data: transitionData } = $derived(_transition);
33
- const handleClick = (event) => {
34
- context.closePopover();
35
- };
36
- const slot = $derived({
37
- open: popoverState === PopoverStates.Open
38
- });
39
- const ourProps = $derived({
40
- id,
41
- "aria-hidden": true,
42
- onclick: handleClick,
43
- ...transitionDataAttributes(transitionData)
44
- });
63
+
64
+ const slot = $derived({
65
+ open: popoverState === PopoverStates.Open,
66
+ } satisfies BackdropRenderPropArg)
67
+
68
+ const ourProps = $derived({
69
+ id,
70
+ "aria-hidden": true,
71
+ onclick: handleClick,
72
+ ...transitionDataAttributes(transitionData),
73
+ })
45
74
  </script>
46
75
 
47
76
  <ElementOrComponent
@@ -52,5 +81,5 @@ const ourProps = $derived({
52
81
  features={BackdropRenderFeatures}
53
82
  name="PopoverBackdrop"
54
83
  {visible}
55
- bind:ref
84
+ bind:element
56
85
  />
@@ -1,43 +1,15 @@
1
- import type { ElementType, Props, PropsOf } from "../utils/types.js";
1
+ import type { Props } from "../utils/types.js";
2
2
  import { type PropsForFeatures } from "../utils/render.js";
3
3
  declare let DEFAULT_BACKDROP_TAG: "div";
4
4
  type BackdropRenderPropArg = {
5
5
  open: boolean;
6
6
  };
7
- type BackdropPropsWeControl = "aria-hidden";
8
7
  declare const BackdropRenderFeatures: number;
9
- export type PopoverBackdropProps<TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG> = Props<TTag, BackdropRenderPropArg, BackdropPropsWeControl, {
8
+ export type PopoverBackdropProps = Props<typeof DEFAULT_BACKDROP_TAG, BackdropRenderPropArg, {
9
+ element?: HTMLElement;
10
+ id?: string;
10
11
  transition?: boolean;
11
12
  } & PropsForFeatures<typeof BackdropRenderFeatures>>;
12
- export type PopoverOverlayProps<TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG> = PopoverBackdropProps<TTag>;
13
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG> {
14
- props(): {
15
- as?: TTag | undefined;
16
- } & (Exclude<keyof PropsOf<TTag>, ("slot" | "as" | "children" | "class" | "ref") | "unmount" | "static" | "aria-hidden" | "transition"> extends infer T extends keyof PropsOf<TTag> ? { [P in T]: PropsOf<TTag>[P]; } : never) & {
17
- children?: import("svelte").Snippet<[{
18
- slot: BackdropRenderPropArg;
19
- props: Record<string, any>;
20
- }]> | undefined;
21
- class?: string | ((bag: BackdropRenderPropArg) => string) | null | undefined;
22
- ref?: HTMLElement;
23
- } & {
24
- transition?: boolean;
25
- } & {
26
- static?: boolean | undefined;
27
- unmount?: boolean | undefined;
28
- };
29
- events(): {};
30
- slots(): {};
31
- bindings(): "ref";
32
- exports(): {};
33
- }
34
- interface $$IsomorphicComponent {
35
- new <TTag extends ElementType = typeof DEFAULT_BACKDROP_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']>> & {
36
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
37
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
38
- <TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
39
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
40
- }
41
- declare const PopoverBackdrop: $$IsomorphicComponent;
42
- type PopoverBackdrop<TTag extends ElementType = typeof DEFAULT_BACKDROP_TAG> = InstanceType<typeof PopoverBackdrop<TTag>>;
13
+ export type PopoverOverlayProps = PopoverBackdropProps;
14
+ declare const PopoverBackdrop: import("svelte").Component<PopoverBackdropProps, {}, "element">;
43
15
  export default PopoverBackdrop;