@pzerelles/headlessui-svelte 2.1.2-next.23 → 2.1.2-next.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/button/Button.svelte +84 -54
- package/dist/button/Button.svelte.d.ts +7 -5
- package/dist/checkbox/Checkbox.svelte +173 -120
- package/dist/checkbox/Checkbox.svelte.d.ts +7 -5
- package/dist/close-button/CloseButton.svelte +12 -6
- package/dist/close-button/CloseButton.svelte.d.ts +13 -11
- package/dist/combobox/Combobox.svelte +50 -3
- package/dist/data-interactive/DataInteractive.svelte +55 -29
- package/dist/data-interactive/DataInteractive.svelte.d.ts +7 -6
- package/dist/description/Description.svelte +31 -21
- package/dist/description/Description.svelte.d.ts +7 -5
- package/dist/dialog/Dialog.svelte +358 -38
- package/dist/dialog/Dialog.svelte.d.ts +10 -8
- package/dist/dialog/DialogBackdrop.svelte +30 -13
- package/dist/dialog/DialogBackdrop.svelte.d.ts +7 -5
- package/dist/dialog/DialogPanel.svelte +49 -26
- package/dist/dialog/DialogPanel.svelte.d.ts +7 -5
- package/dist/dialog/DialogTitle.svelte +38 -23
- package/dist/dialog/DialogTitle.svelte.d.ts +7 -5
- package/dist/field/Field.svelte +50 -28
- package/dist/field/Field.svelte.d.ts +7 -5
- package/dist/fieldset/Fieldset.svelte +50 -29
- package/dist/fieldset/Fieldset.svelte.d.ts +7 -5
- package/dist/focus-trap/FocusTrap.svelte +419 -283
- package/dist/focus-trap/FocusTrap.svelte.d.ts +7 -5
- package/dist/input/Input.svelte +84 -53
- package/dist/input/Input.svelte.d.ts +7 -5
- package/dist/internal/FloatingProvider.svelte +14 -9
- package/dist/internal/FocusSentinel.svelte +16 -8
- package/dist/internal/ForcePortalRoot.svelte +7 -3
- package/dist/internal/FormFields.svelte +47 -34
- package/dist/internal/FormFieldsProvider.svelte +9 -5
- package/dist/internal/FormResolver.svelte +20 -15
- package/dist/internal/Hidden.svelte +50 -29
- package/dist/internal/Hidden.svelte.d.ts +7 -5
- package/dist/internal/MainTreeProvider.svelte +89 -36
- package/dist/internal/Portal.svelte +18 -14
- package/dist/internal/floating-provider.svelte.js +1 -1
- package/dist/internal/floating.svelte.d.ts +5 -5
- package/dist/internal/floating.svelte.js +17 -17
- package/dist/label/Label.svelte +93 -58
- package/dist/label/Label.svelte.d.ts +7 -5
- package/dist/legend/Legend.svelte +12 -3
- package/dist/listbox/Listbox.svelte +525 -387
- package/dist/listbox/Listbox.svelte.d.ts +7 -6
- package/dist/listbox/ListboxButton.svelte +173 -127
- package/dist/listbox/ListboxButton.svelte.d.ts +7 -6
- package/dist/listbox/ListboxOption.svelte +170 -129
- package/dist/listbox/ListboxOption.svelte.d.ts +7 -6
- package/dist/listbox/ListboxOptions.svelte +400 -304
- package/dist/listbox/ListboxOptions.svelte.d.ts +7 -6
- package/dist/listbox/ListboxSelectedOption.svelte +38 -15
- package/dist/listbox/ListboxSelectedOption.svelte.d.ts +7 -5
- package/dist/listbox/index.d.ts +4 -4
- package/dist/listbox/index.js +1 -1
- package/dist/menu/Menu.svelte +78 -51
- package/dist/menu/Menu.svelte.d.ts +7 -6
- package/dist/menu/MenuButton.svelte +157 -117
- package/dist/menu/MenuButton.svelte.d.ts +7 -6
- package/dist/menu/MenuHeading.svelte +32 -14
- package/dist/menu/MenuHeading.svelte.d.ts +7 -6
- package/dist/menu/MenuItem.svelte +142 -107
- package/dist/menu/MenuItem.svelte.d.ts +8 -10
- package/dist/menu/MenuItems.svelte +301 -229
- package/dist/menu/MenuItems.svelte.d.ts +7 -6
- package/dist/menu/MenuSection.svelte +24 -9
- package/dist/menu/MenuSection.svelte.d.ts +7 -6
- package/dist/menu/MenuSeparator.svelte +17 -4
- package/dist/menu/MenuSeparator.svelte.d.ts +7 -7
- package/dist/menu/index.d.ts +7 -7
- package/dist/popover/Popover.svelte +216 -150
- package/dist/popover/Popover.svelte.d.ts +7 -5
- package/dist/popover/PopoverBackdrop.svelte +67 -41
- package/dist/popover/PopoverBackdrop.svelte.d.ts +7 -5
- package/dist/popover/PopoverButton.svelte +292 -212
- package/dist/popover/PopoverButton.svelte.d.ts +7 -5
- package/dist/popover/PopoverGroup.svelte +62 -35
- package/dist/popover/PopoverGroup.svelte.d.ts +7 -5
- package/dist/popover/PopoverPanel.svelte +311 -229
- package/dist/popover/PopoverPanel.svelte.d.ts +7 -5
- package/dist/portal/InternalPortal.svelte +141 -85
- package/dist/portal/InternalPortal.svelte.d.ts +7 -5
- package/dist/portal/Portal.svelte +5 -2
- package/dist/portal/PortalGroup.svelte +30 -9
- package/dist/portal/PortalGroup.svelte.d.ts +7 -5
- package/dist/select/Select.svelte +98 -68
- package/dist/select/Select.svelte.d.ts +7 -5
- package/dist/switch/Switch.svelte +179 -132
- package/dist/switch/Switch.svelte.d.ts +7 -5
- package/dist/switch/SwitchGroup.svelte +44 -31
- package/dist/switch/SwitchGroup.svelte.d.ts +7 -5
- package/dist/tabs/Tab.svelte +194 -143
- package/dist/tabs/Tab.svelte.d.ts +7 -5
- package/dist/tabs/TabGroup.svelte +81 -214
- package/dist/tabs/TabGroup.svelte.d.ts +7 -25
- package/dist/tabs/TabList.svelte +31 -11
- package/dist/tabs/TabList.svelte.d.ts +7 -5
- package/dist/tabs/TabPanel.svelte +67 -43
- package/dist/tabs/TabPanel.svelte.d.ts +7 -5
- package/dist/tabs/TabPanels.svelte +18 -7
- package/dist/tabs/TabPanels.svelte.d.ts +7 -5
- package/dist/tabs/context.svelte.d.ts +31 -0
- package/dist/tabs/context.svelte.js +134 -0
- package/dist/textarea/Textarea.svelte +84 -53
- package/dist/textarea/Textarea.svelte.d.ts +7 -5
- package/dist/transition/InternalTransitionChild.svelte +259 -170
- package/dist/transition/InternalTransitionChild.svelte.d.ts +7 -5
- package/dist/transition/Transition.svelte +96 -66
- package/dist/transition/Transition.svelte.d.ts +7 -5
- package/dist/transition/TransitionChild.svelte +31 -11
- package/dist/transition/TransitionChild.svelte.d.ts +7 -5
- package/dist/utils/ElementOrComponent.svelte +43 -23
- package/dist/utils/ElementOrComponent.svelte.d.ts +10 -5
- package/dist/utils/Generic.svelte +36 -22
- package/dist/utils/Generic.svelte.d.ts +12 -10
- package/dist/utils/StableCollection.svelte +54 -36
- package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +27 -12
- package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +88 -44
- package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.js +7 -7
- package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.js +1 -1
- package/dist/utils/floating-ui/svelte/types.d.ts +4 -4
- package/dist/utils/floating-ui/svelte-dom/types.d.ts +2 -2
- package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.js +6 -6
- package/dist/utils/types.d.ts +9 -12
- package/package.json +6 -6
- package/dist/dialog/InternalDialog.svelte +0 -233
- package/dist/dialog/InternalDialog.svelte.d.ts +0 -42
|
@@ -14,17 +14,18 @@ export type ListboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTION
|
|
|
14
14
|
modal?: boolean;
|
|
15
15
|
transition?: boolean;
|
|
16
16
|
} & PropsForFeatures<typeof OptionsRenderFeatures>>;
|
|
17
|
-
export type ListboxOptionsChildren = Snippet<[OptionsRenderPropArg]>;
|
|
18
17
|
import { type Snippet } from "svelte";
|
|
19
18
|
declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> {
|
|
20
19
|
props(): {
|
|
21
20
|
as?: TTag | undefined;
|
|
22
|
-
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("as" | "children" | "
|
|
23
|
-
children?: Snippet<[
|
|
21
|
+
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("slot" | "as" | "children" | "class" | "ref") | "anchor" | "unmount" | "static" | "id" | "transition" | OptionsPropsWeControl | "portal" | "modal"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
|
|
22
|
+
children?: Snippet<[{
|
|
23
|
+
slot: OptionsRenderPropArg;
|
|
24
|
+
props: Record<string, any>;
|
|
25
|
+
}]> | undefined;
|
|
26
|
+
class?: string | ((bag: OptionsRenderPropArg) => string) | null | undefined;
|
|
24
27
|
ref?: HTMLElement;
|
|
25
|
-
} &
|
|
26
|
-
class?: import("../utils/types.js").PropsOf<TTag>["class"] | ((bag: OptionsRenderPropArg) => string) | undefined;
|
|
27
|
-
} : {}) & {
|
|
28
|
+
} & {
|
|
28
29
|
id?: string;
|
|
29
30
|
anchor?: AnchorPropsWithSelection;
|
|
30
31
|
portal?: boolean;
|
|
@@ -1,20 +1,43 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { ElementType, Props } from "../utils/types.js"
|
|
3
|
+
import type { Snippet } from "svelte"
|
|
4
|
+
|
|
5
|
+
const DEFAULT_SELECTED_OPTION_TAG = "svelte:fragment"
|
|
6
|
+
type SelectedOptionRenderPropArg = {}
|
|
7
|
+
type SelectedOptionPropsWeControl = never
|
|
8
|
+
|
|
9
|
+
export type ListboxSelectedOptionProps<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> = Props<
|
|
10
|
+
TTag,
|
|
11
|
+
SelectedOptionRenderPropArg,
|
|
12
|
+
SelectedOptionPropsWeControl,
|
|
13
|
+
{
|
|
14
|
+
options: Snippet
|
|
15
|
+
placeholder?: Snippet
|
|
16
|
+
}
|
|
17
|
+
>
|
|
2
18
|
</script>
|
|
3
19
|
|
|
4
|
-
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG">
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
17
|
-
|
|
20
|
+
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG">
|
|
21
|
+
import { useData, ValueMode } from "./Listbox.svelte"
|
|
22
|
+
import { setContext } from "svelte"
|
|
23
|
+
import ElementOrComponent from "../utils/ElementOrComponent.svelte"
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
ref = $bindable(),
|
|
27
|
+
options,
|
|
28
|
+
placeholder,
|
|
29
|
+
...theirProps
|
|
30
|
+
}: { as?: TTag } & ListboxSelectedOptionProps<TTag> = $props()
|
|
31
|
+
|
|
32
|
+
const data = useData("ListboxSelectedOption")
|
|
33
|
+
|
|
34
|
+
const shouldShowPlaceholder = $derived(
|
|
35
|
+
data.value === undefined ||
|
|
36
|
+
data.value === null ||
|
|
37
|
+
(data.mode === ValueMode.Multi && Array.isArray(data.value) && data.value.length === 0)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
setContext("SelectedOptionContext", true)
|
|
18
41
|
</script>
|
|
19
42
|
|
|
20
43
|
{#snippet children()}
|
|
@@ -10,12 +10,14 @@ export type ListboxSelectedOptionProps<TTag extends ElementType = typeof DEFAULT
|
|
|
10
10
|
declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> {
|
|
11
11
|
props(): {
|
|
12
12
|
as?: TTag | undefined;
|
|
13
|
-
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("as" | "children" | "
|
|
14
|
-
children?: Snippet<[
|
|
13
|
+
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("slot" | "as" | "children" | "class" | "ref") | "placeholder" | "options"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
|
|
14
|
+
children?: Snippet<[{
|
|
15
|
+
slot: SelectedOptionRenderPropArg;
|
|
16
|
+
props: Record<string, any>;
|
|
17
|
+
}]> | undefined;
|
|
18
|
+
class?: string | ((bag: SelectedOptionRenderPropArg) => string) | null | undefined;
|
|
15
19
|
ref?: HTMLElement;
|
|
16
|
-
} &
|
|
17
|
-
class?: import("../utils/types.js").PropsOf<TTag>["class"] | ((bag: SelectedOptionRenderPropArg) => string) | undefined;
|
|
18
|
-
} : {}) & {
|
|
20
|
+
} & {
|
|
19
21
|
options: Snippet;
|
|
20
22
|
placeholder?: Snippet;
|
|
21
23
|
};
|
package/dist/listbox/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { default as Listbox, type ListboxProps
|
|
2
|
-
export { default as ListboxButton, type ListboxButtonProps
|
|
3
|
-
export { default as ListboxOption, type ListboxOptionProps
|
|
4
|
-
export { default as ListboxOptions, type ListboxOptionsProps
|
|
1
|
+
export { default as Listbox, type ListboxProps } from "./Listbox.svelte";
|
|
2
|
+
export { default as ListboxButton, type ListboxButtonProps } from "./ListboxButton.svelte";
|
|
3
|
+
export { default as ListboxOption, type ListboxOptionProps } from "./ListboxOption.svelte";
|
|
4
|
+
export { default as ListboxOptions, type ListboxOptionsProps } from "./ListboxOptions.svelte";
|
|
5
5
|
export { default as ListboxSelectedOption, type ListboxSelectedOptionProps } from "./ListboxSelectedOption.svelte";
|
package/dist/listbox/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as Listbox } from "./Listbox.svelte";
|
|
2
2
|
export { default as ListboxButton } from "./ListboxButton.svelte";
|
|
3
3
|
export { default as ListboxOption } from "./ListboxOption.svelte";
|
|
4
|
-
export { default as ListboxOptions
|
|
4
|
+
export { default as ListboxOptions } from "./ListboxOptions.svelte";
|
|
5
5
|
export { default as ListboxSelectedOption } from "./ListboxSelectedOption.svelte";
|
package/dist/menu/Menu.svelte
CHANGED
|
@@ -1,57 +1,84 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { useOutsideClick } from "../hooks/use-outside-click.svelte.js"
|
|
3
|
+
import { useFloatingProvider } from "../internal/floating.svelte.js"
|
|
4
|
+
import { createOpenClosedContext, State } from "../internal/open-closed.js"
|
|
5
|
+
import ElementOrComponent from "../utils/ElementOrComponent.svelte"
|
|
6
|
+
import { FocusableMode, isFocusableElement } from "../utils/focus-management.js"
|
|
7
|
+
import { match } from "../utils/match.js"
|
|
8
|
+
import type { ElementType, Props } from "../utils/types.js"
|
|
9
|
+
import type { Snippet } from "svelte"
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
menuState: __demoMode ? MenuStates.Open : MenuStates.Closed,
|
|
15
|
-
buttonElement: null,
|
|
16
|
-
itemsElement: null,
|
|
17
|
-
items: [],
|
|
18
|
-
searchQuery: "",
|
|
19
|
-
activeItemIndex: null,
|
|
20
|
-
activationTrigger: ActivationTrigger.Other
|
|
21
|
-
});
|
|
22
|
-
const { menuState, itemsElement, buttonElement } = $derived(context);
|
|
23
|
-
const outsideClickEnabled = $derived(menuState === MenuStates.Open);
|
|
24
|
-
useOutsideClick({
|
|
25
|
-
get enabled() {
|
|
26
|
-
return outsideClickEnabled;
|
|
27
|
-
},
|
|
28
|
-
get containers() {
|
|
29
|
-
return [buttonElement, itemsElement];
|
|
30
|
-
},
|
|
31
|
-
cb: (event, target) => {
|
|
32
|
-
context.closeMenu();
|
|
33
|
-
if (!isFocusableElement(target, FocusableMode.Loose)) {
|
|
34
|
-
event.preventDefault();
|
|
35
|
-
buttonElement?.focus();
|
|
36
|
-
}
|
|
11
|
+
let DEFAULT_MENU_TAG = "svelte:fragment"
|
|
12
|
+
type MenuRenderPropArg = {
|
|
13
|
+
open: boolean
|
|
14
|
+
close: () => void
|
|
37
15
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
16
|
+
type MenuPropsWeControl = never
|
|
17
|
+
|
|
18
|
+
export type MenuProps<TTag extends ElementType = typeof DEFAULT_MENU_TAG> = Props<
|
|
19
|
+
TTag,
|
|
20
|
+
MenuRenderPropArg,
|
|
21
|
+
MenuPropsWeControl,
|
|
22
|
+
{
|
|
23
|
+
__demoMode?: boolean
|
|
24
|
+
}
|
|
25
|
+
>
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_MENU_TAG">
|
|
29
|
+
import { ActivationTrigger, createMenuContext, MenuStates, type StateDefinition } from "./context.svelte.js"
|
|
30
|
+
|
|
31
|
+
let { ref = $bindable(), __demoMode = false, ...theirProps }: { as?: TTag } & MenuProps<TTag> = $props()
|
|
32
|
+
|
|
33
|
+
const context = createMenuContext({
|
|
34
|
+
__demoMode,
|
|
35
|
+
menuState: __demoMode ? MenuStates.Open : MenuStates.Closed,
|
|
36
|
+
buttonElement: null,
|
|
37
|
+
itemsElement: null,
|
|
38
|
+
items: [],
|
|
39
|
+
searchQuery: "",
|
|
40
|
+
activeItemIndex: null,
|
|
41
|
+
activationTrigger: ActivationTrigger.Other,
|
|
42
|
+
} as StateDefinition)
|
|
43
|
+
const { menuState, itemsElement, buttonElement } = $derived(context)
|
|
44
|
+
|
|
45
|
+
// Handle outside click
|
|
46
|
+
const outsideClickEnabled = $derived(menuState === MenuStates.Open)
|
|
47
|
+
useOutsideClick({
|
|
48
|
+
get enabled() {
|
|
49
|
+
return outsideClickEnabled
|
|
50
|
+
},
|
|
51
|
+
get containers() {
|
|
52
|
+
return [buttonElement, itemsElement]
|
|
53
|
+
},
|
|
54
|
+
cb: (event, target) => {
|
|
55
|
+
context.closeMenu()
|
|
56
|
+
|
|
57
|
+
if (!isFocusableElement(target, FocusableMode.Loose)) {
|
|
58
|
+
event.preventDefault()
|
|
59
|
+
buttonElement?.focus()
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const slot = $derived({
|
|
65
|
+
open: context.menuState === MenuStates.Open,
|
|
66
|
+
close: context.closeMenu,
|
|
67
|
+
} satisfies MenuRenderPropArg)
|
|
68
|
+
|
|
69
|
+
useFloatingProvider()
|
|
70
|
+
|
|
71
|
+
const openClosed = $derived(
|
|
72
|
+
match(menuState, {
|
|
73
|
+
[MenuStates.Open]: State.Open,
|
|
74
|
+
[MenuStates.Closed]: State.Closed,
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
createOpenClosedContext({
|
|
78
|
+
get value() {
|
|
79
|
+
return openClosed
|
|
80
|
+
},
|
|
48
81
|
})
|
|
49
|
-
);
|
|
50
|
-
createOpenClosedContext({
|
|
51
|
-
get value() {
|
|
52
|
-
return openClosed;
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
82
|
</script>
|
|
56
83
|
|
|
57
84
|
<ElementOrComponent {theirProps} {slot} defaultTag={DEFAULT_MENU_TAG} name="Menu" bind:ref />
|
|
@@ -9,16 +9,17 @@ type MenuPropsWeControl = never;
|
|
|
9
9
|
export type MenuProps<TTag extends ElementType = typeof DEFAULT_MENU_TAG> = Props<TTag, MenuRenderPropArg, MenuPropsWeControl, {
|
|
10
10
|
__demoMode?: boolean;
|
|
11
11
|
}>;
|
|
12
|
-
export type MenuChildren<T> = Snippet<[MenuRenderPropArg]>;
|
|
13
12
|
declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_MENU_TAG> {
|
|
14
13
|
props(): {
|
|
15
14
|
as?: TTag | undefined;
|
|
16
|
-
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("as" | "children" | "
|
|
17
|
-
children?: Snippet<[
|
|
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?: Snippet<[{
|
|
17
|
+
slot: MenuRenderPropArg;
|
|
18
|
+
props: Record<string, any>;
|
|
19
|
+
}]> | undefined;
|
|
20
|
+
class?: string | ((bag: MenuRenderPropArg) => string) | null | undefined;
|
|
18
21
|
ref?: HTMLElement;
|
|
19
|
-
} &
|
|
20
|
-
class?: import("../utils/types.js").PropsOf<TTag>["class"] | ((bag: MenuRenderPropArg) => string) | undefined;
|
|
21
|
-
} : {}) & {
|
|
22
|
+
} & {
|
|
22
23
|
__demoMode?: boolean;
|
|
23
24
|
};
|
|
24
25
|
events(): {} & {
|
|
@@ -1,129 +1,169 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { tick, type Snippet } from "svelte"
|
|
3
|
+
import type { Props, ElementType } from "../utils/types.js"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { MenuStates, useMenuContext } from "./context.svelte.js";
|
|
14
|
-
import { untrack } from "svelte";
|
|
15
|
-
import ElementOrComponent from "../utils/ElementOrComponent.svelte";
|
|
16
|
-
const internalId = useId();
|
|
17
|
-
let {
|
|
18
|
-
ref = $bindable(),
|
|
19
|
-
id = `headlessui-menu-button-${internalId}`,
|
|
20
|
-
disabled = false,
|
|
21
|
-
autofocus = false,
|
|
22
|
-
...theirProps
|
|
23
|
-
} = $props();
|
|
24
|
-
const _state = useMenuContext("MenuButton");
|
|
25
|
-
const floatingReference = useFloatingReference();
|
|
26
|
-
const { setReference } = $derived(floatingReference);
|
|
27
|
-
const { getReferenceProps: getFloatingReferenceProps } = useFloatingReferenceProps();
|
|
28
|
-
$effect(() => {
|
|
29
|
-
untrack(() => _state.setButtonElement(ref ? ref : null));
|
|
30
|
-
setReference(ref);
|
|
31
|
-
});
|
|
32
|
-
const handleKeyDown = async (event) => {
|
|
33
|
-
switch (event.key) {
|
|
34
|
-
case " ":
|
|
35
|
-
case "Enter":
|
|
36
|
-
case "ArrowDown":
|
|
37
|
-
event.preventDefault();
|
|
38
|
-
event.stopPropagation();
|
|
39
|
-
_state.openMenu();
|
|
40
|
-
await tick();
|
|
41
|
-
_state.goToItem({ focus: Focus.First });
|
|
42
|
-
break;
|
|
43
|
-
case "ArrowUp":
|
|
44
|
-
event.preventDefault();
|
|
45
|
-
event.stopPropagation();
|
|
46
|
-
_state.openMenu();
|
|
47
|
-
await tick();
|
|
48
|
-
_state.goToItem({ focus: Focus.Last });
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
const handleKeyUp = (event) => {
|
|
53
|
-
switch (event.key) {
|
|
54
|
-
case " ":
|
|
55
|
-
event.preventDefault();
|
|
56
|
-
break;
|
|
5
|
+
const DEFAULT_BUTTON_TAG = "button" as const
|
|
6
|
+
type ButtonRenderPropArg = {
|
|
7
|
+
open: boolean
|
|
8
|
+
active: boolean
|
|
9
|
+
hover: boolean
|
|
10
|
+
focus: boolean
|
|
11
|
+
disabled: boolean
|
|
12
|
+
autofocus: boolean
|
|
57
13
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
};
|
|
70
|
-
const { isFocusVisible: focus, focusProps } = $derived(
|
|
71
|
-
useFocusRing({
|
|
72
|
-
get autofocus() {
|
|
73
|
-
return autofocus;
|
|
14
|
+
type ButtonPropsWeControl = "aria-controls" | "aria-expanded" | "aria-haspopup"
|
|
15
|
+
|
|
16
|
+
export type MenuButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG> = Props<
|
|
17
|
+
TTag,
|
|
18
|
+
ButtonRenderPropArg,
|
|
19
|
+
ButtonPropsWeControl,
|
|
20
|
+
{
|
|
21
|
+
id?: string
|
|
22
|
+
disabled?: boolean
|
|
23
|
+
autofocus?: boolean
|
|
24
|
+
type?: string
|
|
74
25
|
}
|
|
26
|
+
>
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_BUTTON_TAG">
|
|
30
|
+
import { useId } from "../hooks/use-id.js"
|
|
31
|
+
import { Focus } from "../utils/calculate-active-index.js"
|
|
32
|
+
import { useFocusRing } from "../hooks/use-focus-ring.svelte.js"
|
|
33
|
+
import { useActivePress } from "../hooks/use-active-press.svelte.js"
|
|
34
|
+
import { useResolveButtonType } from "../hooks/use-resolve-button-type.svelte.js"
|
|
35
|
+
import { useFloatingReference, useFloatingReferenceProps } from "../internal/floating.svelte.js"
|
|
36
|
+
import { useHover } from "../hooks/use-hover.svelte.js"
|
|
37
|
+
import { mergeProps } from "../utils/render.js"
|
|
38
|
+
import { MenuStates, useMenuContext } from "./context.svelte.js"
|
|
39
|
+
import { untrack } from "svelte"
|
|
40
|
+
import ElementOrComponent from "../utils/ElementOrComponent.svelte"
|
|
41
|
+
|
|
42
|
+
const internalId = useId()
|
|
43
|
+
let {
|
|
44
|
+
ref = $bindable(),
|
|
45
|
+
id = `headlessui-menu-button-${internalId}`,
|
|
46
|
+
disabled = false,
|
|
47
|
+
autofocus = false,
|
|
48
|
+
...theirProps
|
|
49
|
+
}: { as?: TTag } & MenuButtonProps<TTag> = $props()
|
|
50
|
+
const _state = useMenuContext("MenuButton")
|
|
51
|
+
const floatingReference = useFloatingReference()
|
|
52
|
+
const { setReference } = $derived(floatingReference)
|
|
53
|
+
const { getReferenceProps: getFloatingReferenceProps } = useFloatingReferenceProps()
|
|
54
|
+
$effect(() => {
|
|
55
|
+
untrack(() => _state.setButtonElement(ref ? (ref as HTMLButtonElement) : null))
|
|
56
|
+
setReference(ref)
|
|
75
57
|
})
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
58
|
+
|
|
59
|
+
const handleKeyDown = async (event: KeyboardEvent) => {
|
|
60
|
+
switch (event.key) {
|
|
61
|
+
// Ref: https://www.w3.org/WAI/ARIA/apg/patterns/menubutton/#keyboard-interaction-13
|
|
62
|
+
|
|
63
|
+
case " ":
|
|
64
|
+
case "Enter":
|
|
65
|
+
case "ArrowDown":
|
|
66
|
+
event.preventDefault()
|
|
67
|
+
event.stopPropagation()
|
|
68
|
+
_state.openMenu()
|
|
69
|
+
await tick()
|
|
70
|
+
_state.goToItem({ focus: Focus.First })
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
case "ArrowUp":
|
|
74
|
+
event.preventDefault()
|
|
75
|
+
event.stopPropagation()
|
|
76
|
+
_state.openMenu()
|
|
77
|
+
await tick()
|
|
78
|
+
_state.goToItem({ focus: Focus.Last })
|
|
79
|
+
break
|
|
81
80
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const handleKeyUp = (event: KeyboardEvent) => {
|
|
84
|
+
switch (event.key) {
|
|
85
|
+
case " ":
|
|
86
|
+
// Required for firefox, event.preventDefault() in handleKeyDown for
|
|
87
|
+
// the Space key doesn't cancel the handleKeyUp, which in turn
|
|
88
|
+
// triggers a *click*.
|
|
89
|
+
event.preventDefault()
|
|
90
|
+
break
|
|
88
91
|
}
|
|
89
|
-
})
|
|
90
|
-
);
|
|
91
|
-
const slot = $derived({
|
|
92
|
-
open: _state.menuState === MenuStates.Open,
|
|
93
|
-
active: active || _state.menuState === MenuStates.Open,
|
|
94
|
-
disabled,
|
|
95
|
-
hover,
|
|
96
|
-
focus,
|
|
97
|
-
autofocus: autofocus ?? false
|
|
98
|
-
});
|
|
99
|
-
const buttonType = useResolveButtonType({
|
|
100
|
-
get props() {
|
|
101
|
-
return { type: theirProps.type, as: theirProps.as };
|
|
102
|
-
},
|
|
103
|
-
get ref() {
|
|
104
|
-
return { current: _state.buttonElement };
|
|
105
92
|
}
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
93
|
+
|
|
94
|
+
const handleClick = async (event: MouseEvent) => {
|
|
95
|
+
//if (isDisabledReactIssue7711(event.currentTarget)) return event.preventDefault()
|
|
96
|
+
if (disabled) return
|
|
97
|
+
if (_state.menuState === MenuStates.Open) {
|
|
98
|
+
_state.closeMenu()
|
|
99
|
+
await tick()
|
|
100
|
+
_state.buttonElement?.focus({ preventScroll: true })
|
|
101
|
+
} else {
|
|
102
|
+
event.preventDefault()
|
|
103
|
+
_state.openMenu()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const { isFocusVisible: focus, focusProps } = $derived(
|
|
108
|
+
useFocusRing({
|
|
109
|
+
get autofocus() {
|
|
110
|
+
return autofocus
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
)
|
|
114
|
+
const { isHovered: hover, hoverProps } = $derived(
|
|
115
|
+
useHover({
|
|
116
|
+
get disabled() {
|
|
117
|
+
return disabled
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
)
|
|
121
|
+
const { pressed: active, pressProps } = $derived(
|
|
122
|
+
useActivePress({
|
|
123
|
+
get disabled() {
|
|
124
|
+
return disabled
|
|
125
|
+
},
|
|
126
|
+
})
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
const slot = $derived({
|
|
130
|
+
open: _state.menuState === MenuStates.Open,
|
|
131
|
+
active: active || _state.menuState === MenuStates.Open,
|
|
132
|
+
disabled,
|
|
133
|
+
hover,
|
|
134
|
+
focus,
|
|
135
|
+
autofocus: autofocus ?? false,
|
|
136
|
+
} satisfies ButtonRenderPropArg)
|
|
137
|
+
|
|
138
|
+
const buttonType = useResolveButtonType({
|
|
139
|
+
get props() {
|
|
140
|
+
return { type: theirProps.type, as: theirProps.as }
|
|
121
141
|
},
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
get ref() {
|
|
143
|
+
return { current: _state.buttonElement }
|
|
144
|
+
},
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const ourProps = $derived(
|
|
148
|
+
mergeProps(
|
|
149
|
+
{
|
|
150
|
+
...getFloatingReferenceProps(),
|
|
151
|
+
id,
|
|
152
|
+
type: buttonType.type,
|
|
153
|
+
"aria-haspopup": "menu",
|
|
154
|
+
"aria-controls": _state.itemsElement?.id,
|
|
155
|
+
"aria-expanded": _state.menuState === MenuStates.Open,
|
|
156
|
+
disabled: disabled || undefined,
|
|
157
|
+
autofocus,
|
|
158
|
+
onkeydown: handleKeyDown,
|
|
159
|
+
onkeyup: handleKeyUp,
|
|
160
|
+
onclick: handleClick,
|
|
161
|
+
},
|
|
162
|
+
focusProps,
|
|
163
|
+
hoverProps,
|
|
164
|
+
pressProps
|
|
165
|
+
)
|
|
125
166
|
)
|
|
126
|
-
);
|
|
127
167
|
</script>
|
|
128
168
|
|
|
129
169
|
<ElementOrComponent {ourProps} {theirProps} {slot} defaultTag={DEFAULT_BUTTON_TAG} name="MenuButton" bind:ref />
|
|
@@ -16,16 +16,17 @@ export type MenuButtonProps<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG
|
|
|
16
16
|
autofocus?: boolean;
|
|
17
17
|
type?: string;
|
|
18
18
|
}>;
|
|
19
|
-
export type MenuButtonChildren = Snippet<[ButtonRenderPropArg]>;
|
|
20
19
|
declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_BUTTON_TAG> {
|
|
21
20
|
props(): {
|
|
22
21
|
as?: TTag | undefined;
|
|
23
|
-
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("as" | "children" | "
|
|
24
|
-
children?: Snippet<[
|
|
22
|
+
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("slot" | "as" | "children" | "class" | "ref") | "disabled" | "autofocus" | "type" | "id" | ButtonPropsWeControl> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
|
|
23
|
+
children?: Snippet<[{
|
|
24
|
+
slot: ButtonRenderPropArg;
|
|
25
|
+
props: Record<string, any>;
|
|
26
|
+
}]> | undefined;
|
|
27
|
+
class?: string | ((bag: ButtonRenderPropArg) => string) | null | undefined;
|
|
25
28
|
ref?: HTMLElement;
|
|
26
|
-
} &
|
|
27
|
-
class?: import("../utils/types.js").PropsOf<TTag>["class"] | ((bag: ButtonRenderPropArg) => string) | undefined;
|
|
28
|
-
} : {}) & {
|
|
29
|
+
} & {
|
|
29
30
|
id?: string;
|
|
30
31
|
disabled?: boolean;
|
|
31
32
|
autofocus?: boolean;
|
|
@@ -1,19 +1,37 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { onMount, type Snippet } from "svelte"
|
|
3
|
+
import type { ElementType, Props } from "../utils/types.js"
|
|
4
|
+
|
|
5
|
+
const DEFAULT_HEADING_TAG = "header" as const
|
|
6
|
+
type HeadingRenderPropArg = {}
|
|
7
|
+
type HeadingPropsWeControl = "role"
|
|
8
|
+
|
|
9
|
+
export type MenuHeadingProps<TTag extends ElementType = typeof DEFAULT_HEADING_TAG> = Props<
|
|
10
|
+
TTag,
|
|
11
|
+
HeadingRenderPropArg,
|
|
12
|
+
HeadingPropsWeControl,
|
|
13
|
+
{
|
|
14
|
+
id?: string
|
|
15
|
+
}
|
|
16
|
+
>
|
|
3
17
|
</script>
|
|
4
18
|
|
|
5
|
-
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_HEADING_TAG">
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
<script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_HEADING_TAG">
|
|
20
|
+
import { useId } from "../hooks/use-id.js"
|
|
21
|
+
import { useLabelContext } from "../label/context.svelte.js"
|
|
22
|
+
import ElementOrComponent from "../utils/ElementOrComponent.svelte"
|
|
23
|
+
|
|
24
|
+
const internalId = useId()
|
|
25
|
+
let {
|
|
26
|
+
ref = $bindable(),
|
|
27
|
+
id = `headlessui-menu-heading-${internalId}`,
|
|
28
|
+
...theirProps
|
|
29
|
+
}: { as?: TTag } & MenuHeadingProps<TTag> = $props()
|
|
30
|
+
|
|
31
|
+
const context = useLabelContext()
|
|
32
|
+
onMount(() => context.register(id))
|
|
33
|
+
|
|
34
|
+
const ourProps = $derived({ id, role: "presentation", ...context.props })
|
|
17
35
|
</script>
|
|
18
36
|
|
|
19
37
|
<ElementOrComponent {ourProps} {theirProps} defaultTag={DEFAULT_HEADING_TAG} name="MenuItem" bind:ref />
|