@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.
- package/dist/button/Button.svelte +84 -55
- package/dist/button/Button.svelte.d.ts +4 -32
- package/dist/checkbox/Checkbox.svelte +177 -121
- package/dist/checkbox/Checkbox.svelte.d.ts +14 -32
- package/dist/close-button/CloseButton.svelte +10 -7
- package/dist/close-button/CloseButton.svelte.d.ts +2 -44
- package/dist/data-interactive/DataInteractive.svelte +49 -37
- package/dist/data-interactive/DataInteractive.svelte.d.ts +7 -30
- package/dist/description/Description.svelte +35 -22
- package/dist/description/Description.svelte.d.ts +7 -28
- package/dist/dialog/Dialog.svelte +326 -232
- package/dist/dialog/Dialog.svelte.d.ts +4 -42
- package/dist/dialog/DialogBackdrop.svelte +33 -16
- package/dist/dialog/DialogBackdrop.svelte.d.ts +4 -29
- package/dist/dialog/DialogPanel.svelte +60 -29
- package/dist/dialog/DialogPanel.svelte.d.ts +4 -30
- package/dist/dialog/DialogTitle.svelte +51 -24
- package/dist/dialog/DialogTitle.svelte.d.ts +6 -27
- package/dist/field/Field.svelte +44 -28
- package/dist/field/Field.svelte.d.ts +4 -30
- package/dist/fieldset/Fieldset.svelte +48 -30
- package/dist/fieldset/Fieldset.svelte.d.ts +5 -31
- package/dist/focus-trap/FocusTrap.svelte +430 -298
- package/dist/focus-trap/FocusTrap.svelte.d.ts +5 -34
- package/dist/hooks/use-inert-others.svelte.js +10 -10
- package/dist/hooks/use-resolve-button-type.svelte.js +0 -1
- package/dist/input/Input.svelte +95 -54
- package/dist/input/Input.svelte.d.ts +13 -27
- package/dist/internal/FloatingProvider.svelte +14 -9
- package/dist/internal/FocusSentinel.svelte +49 -40
- 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 +25 -16
- package/dist/internal/Hidden.svelte +45 -38
- package/dist/internal/Hidden.svelte.d.ts +4 -30
- package/dist/internal/MainTreeProvider.svelte +90 -37
- package/dist/internal/Portal.svelte +18 -14
- package/dist/label/Label.svelte +100 -59
- package/dist/label/Label.svelte.d.ts +7 -32
- package/dist/legend/Legend.svelte +27 -4
- package/dist/legend/Legend.svelte.d.ts +4 -3
- package/dist/listbox/Listbox.svelte +518 -391
- package/dist/listbox/Listbox.svelte.d.ts +11 -35
- package/dist/listbox/ListboxButton.svelte +175 -128
- package/dist/listbox/ListboxButton.svelte.d.ts +5 -32
- package/dist/listbox/ListboxOption.svelte +171 -130
- package/dist/listbox/ListboxOption.svelte.d.ts +12 -26
- package/dist/listbox/ListboxOptions.svelte +403 -305
- package/dist/listbox/ListboxOptions.svelte.d.ts +4 -38
- package/dist/listbox/ListboxSelectedOption.svelte +40 -19
- package/dist/listbox/ListboxSelectedOption.svelte.d.ts +8 -33
- package/dist/menu/Menu.svelte +76 -52
- package/dist/menu/Menu.svelte.d.ts +3 -31
- package/dist/menu/MenuButton.svelte +158 -118
- package/dist/menu/MenuButton.svelte.d.ts +4 -34
- package/dist/menu/MenuHeading.svelte +34 -15
- package/dist/menu/MenuHeading.svelte.d.ts +4 -31
- package/dist/menu/MenuItem.svelte +143 -108
- package/dist/menu/MenuItem.svelte.d.ts +5 -32
- package/dist/menu/MenuItems.svelte +301 -230
- package/dist/menu/MenuItems.svelte.d.ts +4 -38
- package/dist/menu/MenuSection.svelte +26 -10
- package/dist/menu/MenuSection.svelte.d.ts +5 -29
- package/dist/menu/MenuSeparator.svelte +20 -5
- package/dist/menu/MenuSeparator.svelte.d.ts +5 -28
- package/dist/popover/Popover.svelte +217 -151
- package/dist/popover/Popover.svelte.d.ts +4 -30
- package/dist/popover/PopoverBackdrop.svelte +71 -42
- package/dist/popover/PopoverBackdrop.svelte.d.ts +6 -34
- package/dist/popover/PopoverButton.svelte +302 -222
- package/dist/popover/PopoverButton.svelte.d.ts +6 -29
- package/dist/popover/PopoverGroup.svelte +64 -36
- package/dist/popover/PopoverGroup.svelte.d.ts +5 -28
- package/dist/popover/PopoverPanel.svelte +335 -248
- package/dist/popover/PopoverPanel.svelte.d.ts +5 -36
- package/dist/popover/index.d.ts +1 -1
- package/dist/portal/InternalPortal.svelte +143 -86
- package/dist/portal/InternalPortal.svelte.d.ts +4 -30
- package/dist/portal/Portal.svelte +8 -4
- package/dist/portal/Portal.svelte.d.ts +2 -18
- package/dist/portal/PortalGroup.svelte +23 -10
- package/dist/portal/PortalGroup.svelte.d.ts +3 -31
- package/dist/select/Select.svelte +100 -69
- package/dist/select/Select.svelte.d.ts +5 -32
- package/dist/switch/Switch.svelte +181 -133
- package/dist/switch/Switch.svelte.d.ts +5 -38
- package/dist/switch/SwitchGroup.svelte +45 -32
- package/dist/switch/SwitchGroup.svelte.d.ts +7 -28
- package/dist/tabs/Tab.svelte +195 -143
- package/dist/tabs/Tab.svelte.d.ts +4 -32
- package/dist/tabs/TabGroup.svelte +87 -57
- package/dist/tabs/TabGroup.svelte.d.ts +4 -34
- package/dist/tabs/TabList.svelte +31 -12
- package/dist/tabs/TabList.svelte.d.ts +5 -28
- package/dist/tabs/TabPanel.svelte +69 -44
- package/dist/tabs/TabPanel.svelte.d.ts +4 -34
- package/dist/tabs/TabPanels.svelte +19 -8
- package/dist/tabs/TabPanels.svelte.d.ts +5 -27
- package/dist/textarea/Textarea.svelte +87 -54
- package/dist/textarea/Textarea.svelte.d.ts +13 -27
- package/dist/transition/InternalTransitionChild.svelte +267 -171
- package/dist/transition/InternalTransitionChild.svelte.d.ts +3 -33
- package/dist/transition/Transition.svelte +88 -67
- package/dist/transition/Transition.svelte.d.ts +3 -36
- package/dist/transition/TransitionChild.svelte +31 -12
- package/dist/transition/TransitionChild.svelte.d.ts +8 -35
- package/dist/transition/context.svelte.js +7 -7
- package/dist/utils/DisabledProvider.svelte +7 -3
- package/dist/utils/ElementOrComponent.svelte +88 -24
- package/dist/utils/ElementOrComponent.svelte.d.ts +32 -27
- 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/state.js +4 -4
- package/dist/utils/types.d.ts +14 -12
- package/package.json +12 -12
- package/dist/combobox/Combobox.svelte +0 -6
- package/dist/combobox/Combobox.svelte.d.ts +0 -50
- package/dist/utils/Generic.svelte +0 -46
- package/dist/utils/Generic.svelte.d.ts +0 -32
- package/dist/utils/alternative-types.d.ts +0 -20
- package/dist/utils/alternative-types.js +0 -1
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
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"
|
|
5
|
-
|
|
6
|
-
|
|
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:
|
|
24
|
+
<ElementOrComponent {ourProps} {theirProps} defaultTag={DEFAULT_SEPARATOR_TAG} name="MenuSeparator" bind:element />
|
|
@@ -1,31 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Props } from "../utils/types.js";
|
|
2
2
|
declare const DEFAULT_SEPARATOR_TAG: "div";
|
|
3
3
|
type SeparatorRenderPropArg = {};
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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>
|
|
2
|
-
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Props } from "../utils/types.js"
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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:
|
|
226
|
+
<ElementOrComponent {theirProps} slots={slot} defaultTag={DEFAULT_POPOVER_TAG} name="Popover" bind:element />
|
|
161
227
|
</MainTreeProvider>
|
|
@@ -1,39 +1,13 @@
|
|
|
1
|
-
import type {
|
|
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
|
|
8
|
-
|
|
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
|
|
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>
|
|
2
|
-
|
|
3
|
-
|
|
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"
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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:
|
|
84
|
+
bind:element
|
|
56
85
|
/>
|
|
@@ -1,43 +1,15 @@
|
|
|
1
|
-
import type {
|
|
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
|
|
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
|
|
13
|
-
declare
|
|
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;
|