@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,52 +1,18 @@
1
- import type { ElementType, Props } from "../utils/types.js";
1
+ import type { Props } from "../utils/types.js";
2
2
  import { type PropsForFeatures } from "../utils/render.js";
3
3
  import { type AnchorPropsWithSelection } from "../internal/floating.svelte.js";
4
4
  declare const DEFAULT_OPTIONS_TAG: "div";
5
5
  type OptionsRenderPropArg = {
6
6
  open: boolean;
7
7
  };
8
- type OptionsPropsWeControl = "aria-activedescendant" | "aria-labelledby" | "aria-multiselectable" | "aria-orientation" | "role" | "tabIndex";
9
8
  declare let OptionsRenderFeatures: number;
10
- export type ListboxOptionsProps<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> = Props<TTag, OptionsRenderPropArg, OptionsPropsWeControl, {
9
+ export type ListboxOptionsProps = Props<typeof DEFAULT_OPTIONS_TAG, OptionsRenderPropArg, {
10
+ element?: HTMLElement;
11
11
  id?: string;
12
12
  anchor?: AnchorPropsWithSelection;
13
13
  portal?: boolean;
14
14
  modal?: boolean;
15
15
  transition?: boolean;
16
16
  } & PropsForFeatures<typeof OptionsRenderFeatures>>;
17
- import { type Snippet } from "svelte";
18
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> {
19
- props(): {
20
- as?: TTag | undefined;
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;
27
- ref?: HTMLElement;
28
- } & {
29
- id?: string;
30
- anchor?: AnchorPropsWithSelection;
31
- portal?: boolean;
32
- modal?: boolean;
33
- transition?: boolean;
34
- } & {
35
- static?: boolean | undefined;
36
- unmount?: boolean | undefined;
37
- };
38
- events(): {};
39
- slots(): {};
40
- bindings(): "ref";
41
- exports(): {};
42
- }
43
- interface $$IsomorphicComponent {
44
- new <TTag extends ElementType = typeof DEFAULT_OPTIONS_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']>> & {
45
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
46
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
47
- <TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
48
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
49
- }
50
- declare const ListboxOptions: $$IsomorphicComponent;
51
- type ListboxOptions<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG> = InstanceType<typeof ListboxOptions<TTag>>;
17
+ declare const ListboxOptions: import("svelte").Component<ListboxOptionsProps, {}, "element">;
52
18
  export default ListboxOptions;
@@ -1,23 +1,43 @@
1
- <script lang="ts" module>const DEFAULT_SELECTED_OPTION_TAG = "svelte:fragment";
1
+ <script lang="ts" module>
2
+ import type { Props } from "../utils/types.js"
3
+ import type { Snippet } from "svelte"
4
+
5
+ const DEFAULT_SELECTED_OPTION_TAG = "span"
6
+ type SelectedOptionRenderPropArg = {
7
+ option: Snippet
8
+ }
9
+ type SelectedOptionPropsWeControl = never
10
+
11
+ export type ListboxSelectedOptionProps = Props<
12
+ typeof DEFAULT_SELECTED_OPTION_TAG,
13
+ SelectedOptionRenderPropArg,
14
+ {
15
+ element?: HTMLElement
16
+ options: Snippet
17
+ placeholder?: Snippet
18
+ }
19
+ >
2
20
  </script>
3
21
 
4
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG">import { useData, ValueMode } from "./Listbox.svelte";
5
- import { setContext } from "svelte";
6
- import ElementOrComponent from "../utils/ElementOrComponent.svelte";
7
- let {
8
- ref = $bindable(),
9
- options,
10
- placeholder,
11
- ...theirProps
12
- } = $props();
13
- const data = useData("ListboxSelectedOption");
14
- const shouldShowPlaceholder = $derived(
15
- data.value === void 0 || data.value === null || data.mode === ValueMode.Multi && Array.isArray(data.value) && data.value.length === 0
16
- );
17
- setContext("SelectedOptionContext", true);
22
+ <script lang="ts">
23
+ import { useData, ValueMode } from "./Listbox.svelte"
24
+ import { setContext } from "svelte"
25
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
26
+
27
+ let { element = $bindable(), options, placeholder, ...theirProps }: ListboxSelectedOptionProps = $props()
28
+
29
+ const data = useData("ListboxSelectedOption")
30
+
31
+ const shouldShowPlaceholder = $derived(
32
+ data.value === undefined ||
33
+ data.value === null ||
34
+ (data.mode === ValueMode.Multi && Array.isArray(data.value) && data.value.length === 0)
35
+ )
36
+
37
+ setContext("SelectedOptionContext", true)
18
38
  </script>
19
39
 
20
- {#snippet children()}
40
+ {#snippet option()}
21
41
  {#if placeholder && shouldShowPlaceholder}
22
42
  {@render placeholder()}
23
43
  {:else}
@@ -26,8 +46,9 @@ setContext("SelectedOptionContext", true);
26
46
  {/snippet}
27
47
 
28
48
  <ElementOrComponent
29
- theirProps={{ ...theirProps, children }}
49
+ theirProps={{ ...theirProps, ...(theirProps.asChild ? {} : { children: option }) }}
50
+ slot={{ option }}
30
51
  defaultTag={DEFAULT_SELECTED_OPTION_TAG}
31
52
  name="ListboxSelectedOption"
32
- bind:ref
33
- ></ElementOrComponent>
53
+ bind:element
54
+ />
@@ -1,38 +1,13 @@
1
- import type { ElementType, Props } from "../utils/types.js";
1
+ import type { Props } from "../utils/types.js";
2
2
  import type { Snippet } from "svelte";
3
- declare const DEFAULT_SELECTED_OPTION_TAG = "svelte:fragment";
4
- type SelectedOptionRenderPropArg = {};
5
- type SelectedOptionPropsWeControl = never;
6
- export type ListboxSelectedOptionProps<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> = Props<TTag, SelectedOptionRenderPropArg, SelectedOptionPropsWeControl, {
3
+ declare const DEFAULT_SELECTED_OPTION_TAG = "span";
4
+ type SelectedOptionRenderPropArg = {
5
+ option: Snippet;
6
+ };
7
+ export type ListboxSelectedOptionProps = Props<typeof DEFAULT_SELECTED_OPTION_TAG, SelectedOptionRenderPropArg, {
8
+ element?: HTMLElement;
7
9
  options: Snippet;
8
10
  placeholder?: Snippet;
9
11
  }>;
10
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> {
11
- props(): {
12
- as?: TTag | undefined;
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;
19
- ref?: HTMLElement;
20
- } & {
21
- options: Snippet;
22
- placeholder?: Snippet;
23
- };
24
- events(): {};
25
- slots(): {};
26
- bindings(): "ref";
27
- exports(): {};
28
- }
29
- interface $$IsomorphicComponent {
30
- new <TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_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']>> & {
31
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
32
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
33
- <TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
34
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
35
- }
36
- declare const ListboxSelectedOption: $$IsomorphicComponent;
37
- type ListboxSelectedOption<TTag extends ElementType = typeof DEFAULT_SELECTED_OPTION_TAG> = InstanceType<typeof ListboxSelectedOption<TTag>>;
12
+ declare const ListboxSelectedOption: import("svelte").Component<ListboxSelectedOptionProps, {}, "element">;
38
13
  export default ListboxSelectedOption;
@@ -1,57 +1,81 @@
1
- <script lang="ts" module>let DEFAULT_MENU_TAG = "svelte:fragment";
2
- </script>
1
+ <script lang="ts" module>
2
+ import type { PropsAsChild } from "../utils/types.js"
3
3
 
4
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_MENU_TAG">import { ActivationTrigger, createMenuContext, MenuStates } from "./context.svelte.js";
5
- import { useOutsideClick } from "../hooks/use-outside-click.svelte.js";
6
- import { useFloatingProvider } from "../internal/floating-provider.svelte.js";
7
- import { createOpenClosedContext, State } from "../internal/open-closed.js";
8
- import ElementOrComponent from "../utils/ElementOrComponent.svelte";
9
- import { FocusableMode, isFocusableElement } from "../utils/focus-management.js";
10
- import { match } from "../utils/match.js";
11
- let { ref = $bindable(), __demoMode = false, ...theirProps } = $props();
12
- const context = createMenuContext({
13
- __demoMode,
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
- }
4
+ let DEFAULT_MENU_TAG = "svelte:fragment"
5
+ type MenuRenderPropArg = {
6
+ open: boolean
7
+ close: () => void
37
8
  }
38
- });
39
- const slot = $derived({
40
- open: context.menuState === MenuStates.Open,
41
- close: context.closeMenu
42
- });
43
- useFloatingProvider();
44
- const openClosed = $derived(
45
- match(menuState, {
46
- [MenuStates.Open]: State.Open,
47
- [MenuStates.Closed]: State.Closed
9
+ type MenuPropsWeControl = never
10
+
11
+ export type MenuProps = PropsAsChild<
12
+ MenuRenderPropArg,
13
+ {
14
+ __demoMode?: boolean
15
+ }
16
+ >
17
+ </script>
18
+
19
+ <script lang="ts">
20
+ import { ActivationTrigger, createMenuContext, MenuStates, type StateDefinition } from "./context.svelte.js"
21
+ import { useOutsideClick } from "../hooks/use-outside-click.svelte.js"
22
+ import { useFloatingProvider } from "../internal/floating-provider.svelte.js"
23
+ import { createOpenClosedContext, State } from "../internal/open-closed.js"
24
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
25
+ import { FocusableMode, isFocusableElement } from "../utils/focus-management.js"
26
+ import { match } from "../utils/match.js"
27
+
28
+ let { __demoMode = false, ...theirProps }: MenuProps = $props()
29
+
30
+ const context = createMenuContext({
31
+ __demoMode,
32
+ menuState: __demoMode ? MenuStates.Open : MenuStates.Closed,
33
+ buttonElement: null,
34
+ itemsElement: null,
35
+ items: [],
36
+ searchQuery: "",
37
+ activeItemIndex: null,
38
+ activationTrigger: ActivationTrigger.Other,
39
+ } as StateDefinition)
40
+ const { menuState, itemsElement, buttonElement } = $derived(context)
41
+
42
+ // Handle outside click
43
+ const outsideClickEnabled = $derived(menuState === MenuStates.Open)
44
+ useOutsideClick({
45
+ get enabled() {
46
+ return outsideClickEnabled
47
+ },
48
+ get containers() {
49
+ return [buttonElement, itemsElement]
50
+ },
51
+ cb: (event, target) => {
52
+ context.closeMenu()
53
+
54
+ if (!isFocusableElement(target, FocusableMode.Loose)) {
55
+ event.preventDefault()
56
+ buttonElement?.focus()
57
+ }
58
+ },
59
+ })
60
+
61
+ const slot = $derived({
62
+ open: context.menuState === MenuStates.Open,
63
+ close: context.closeMenu,
64
+ } satisfies MenuRenderPropArg)
65
+
66
+ useFloatingProvider()
67
+
68
+ const openClosed = $derived(
69
+ match(menuState, {
70
+ [MenuStates.Open]: State.Open,
71
+ [MenuStates.Closed]: State.Closed,
72
+ })
73
+ )
74
+ createOpenClosedContext({
75
+ get value() {
76
+ return openClosed
77
+ },
48
78
  })
49
- );
50
- createOpenClosedContext({
51
- get value() {
52
- return openClosed;
53
- }
54
- });
55
79
  </script>
56
80
 
57
- <ElementOrComponent {theirProps} {slot} defaultTag={DEFAULT_MENU_TAG} name="Menu" bind:ref />
81
+ <ElementOrComponent {theirProps} {slot} name="Menu" />
@@ -1,38 +1,10 @@
1
- import type { ElementType, Props } from "../utils/types.js";
2
- declare let DEFAULT_MENU_TAG: string;
1
+ import type { PropsAsChild } from "../utils/types.js";
3
2
  type MenuRenderPropArg = {
4
3
  open: boolean;
5
4
  close: () => void;
6
5
  };
7
- type MenuPropsWeControl = never;
8
- export type MenuProps<TTag extends ElementType = typeof DEFAULT_MENU_TAG> = Props<TTag, MenuRenderPropArg, MenuPropsWeControl, {
6
+ export type MenuProps = PropsAsChild<MenuRenderPropArg, {
9
7
  __demoMode?: boolean;
10
8
  }>;
11
- declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_MENU_TAG> {
12
- props(): {
13
- as?: TTag | undefined;
14
- } & (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) & {
15
- children?: import("svelte").Snippet<[{
16
- slot: MenuRenderPropArg;
17
- props: Record<string, any>;
18
- }]> | undefined;
19
- class?: string | ((bag: MenuRenderPropArg) => string) | null | undefined;
20
- ref?: HTMLElement;
21
- } & {
22
- __demoMode?: boolean;
23
- };
24
- events(): {};
25
- slots(): {};
26
- bindings(): "ref";
27
- exports(): {};
28
- }
29
- interface $$IsomorphicComponent {
30
- new <TTag extends ElementType = typeof DEFAULT_MENU_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']>> & {
31
- $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
32
- } & ReturnType<__sveltets_Render<TTag>['exports']>;
33
- <TTag extends ElementType = typeof DEFAULT_MENU_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {}): ReturnType<__sveltets_Render<TTag>['exports']>;
34
- z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
35
- }
36
- declare const Menu: $$IsomorphicComponent;
37
- type Menu<TTag extends ElementType = typeof DEFAULT_MENU_TAG> = InstanceType<typeof Menu<TTag>>;
9
+ declare const Menu: import("svelte").Component<MenuProps, {}, "">;
38
10
  export default Menu;
@@ -1,129 +1,169 @@
1
- <script lang="ts" module>import { tick } from "svelte";
2
- const DEFAULT_BUTTON_TAG = "button";
3
- </script>
1
+ <script lang="ts" module>
2
+ import { tick } from "svelte"
3
+ import type { Props } from "../utils/types.js"
4
4
 
5
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_BUTTON_TAG">import { useId } from "../hooks/use-id.js";
6
- import { Focus } from "../utils/calculate-active-index.js";
7
- import { useFocusRing } from "../hooks/use-focus-ring.svelte.js";
8
- import { useActivePress } from "../hooks/use-active-press.svelte.js";
9
- import { useResolveButtonType } from "../hooks/use-resolve-button-type.svelte.js";
10
- import { useFloatingReference, useFloatingReferenceProps } from "../internal/floating.svelte.js";
11
- import { useHover } from "../hooks/use-hover.svelte.js";
12
- import { mergeProps } from "../utils/render.js";
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
- const handleClick = async (event) => {
60
- if (disabled) return;
61
- if (_state.menuState === MenuStates.Open) {
62
- _state.closeMenu();
63
- await tick();
64
- _state.buttonElement?.focus({ preventScroll: true });
65
- } else {
66
- event.preventDefault();
67
- _state.openMenu();
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 = Props<
17
+ typeof DEFAULT_BUTTON_TAG,
18
+ ButtonRenderPropArg,
19
+ {
20
+ element?: HTMLElement
21
+ id?: string
22
+ disabled?: boolean
23
+ autofocus?: boolean
24
+ type?: string
74
25
  }
26
+ >
27
+ </script>
28
+
29
+ <script lang="ts">
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
+ element = $bindable(),
45
+ id = `headlessui-menu-button-${internalId}`,
46
+ disabled = false,
47
+ autofocus = false,
48
+ ...theirProps
49
+ }: MenuButtonProps = $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(element ? (element as HTMLButtonElement) : null))
56
+ setReference(element)
75
57
  })
76
- );
77
- const { isHovered: hover, hoverProps } = $derived(
78
- useHover({
79
- get disabled() {
80
- return disabled;
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 { pressed: active, pressProps } = $derived(
85
- useActivePress({
86
- get disabled() {
87
- return disabled;
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 ourProps = $derived(
108
- mergeProps(
109
- {
110
- ...getFloatingReferenceProps(),
111
- id,
112
- type: buttonType.type,
113
- "aria-haspopup": "menu",
114
- "aria-controls": _state.itemsElement?.id,
115
- "aria-expanded": _state.menuState === MenuStates.Open,
116
- disabled: disabled || void 0,
117
- autofocus,
118
- onkeydown: handleKeyDown,
119
- onkeyup: handleKeyUp,
120
- onclick: handleClick
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: DEFAULT_BUTTON_TAG }
121
141
  },
122
- focusProps,
123
- hoverProps,
124
- pressProps
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
- <ElementOrComponent {ourProps} {theirProps} {slot} defaultTag={DEFAULT_BUTTON_TAG} name="MenuButton" bind:ref />
169
+ <ElementOrComponent {ourProps} {theirProps} {slot} defaultTag={DEFAULT_BUTTON_TAG} name="MenuButton" bind:element />