@pzerelles/headlessui-svelte 2.1.2-next.6 → 2.1.2-next.8

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 (57) hide show
  1. package/dist/button/Button.svelte +54 -84
  2. package/dist/checkbox/Checkbox.svelte +120 -174
  3. package/dist/close-button/CloseButton.svelte +6 -12
  4. package/dist/combobox/Combobox.svelte +3 -50
  5. package/dist/data-interactive/DataInteractive.svelte +29 -57
  6. package/dist/description/Description.svelte +21 -32
  7. package/dist/dialog/Dialog.svelte +34 -69
  8. package/dist/dialog/DialogBackdrop.svelte +12 -29
  9. package/dist/dialog/DialogPanel.svelte +26 -49
  10. package/dist/dialog/DialogTitle.svelte +23 -38
  11. package/dist/dialog/InternalDialog.svelte +202 -263
  12. package/dist/field/Field.svelte +26 -49
  13. package/dist/fieldset/Fieldset.svelte +29 -50
  14. package/dist/focus-trap/FocusTrap.svelte +283 -419
  15. package/dist/input/Input.svelte +53 -85
  16. package/dist/input/Input.svelte.d.ts +4 -6
  17. package/dist/internal/FocusSentinel.svelte +8 -16
  18. package/dist/internal/ForcePortalRoot.svelte +3 -7
  19. package/dist/internal/FormFields.svelte +20 -31
  20. package/dist/internal/FormResolver.svelte +15 -20
  21. package/dist/internal/Hidden.svelte +23 -44
  22. package/dist/internal/HoistFormFields.svelte +4 -7
  23. package/dist/internal/MainTreeProvider.svelte +36 -89
  24. package/dist/internal/Portal.svelte +14 -18
  25. package/dist/label/Label.svelte +57 -91
  26. package/dist/legend/Legend.svelte +3 -18
  27. package/dist/listbox/Listbox.svelte +396 -588
  28. package/dist/listbox/ListboxButton.svelte +127 -176
  29. package/dist/listbox/ListboxOption.svelte +125 -166
  30. package/dist/listbox/ListboxOptions.svelte +244 -340
  31. package/dist/listbox/ListboxSelectedOption.svelte +15 -38
  32. package/dist/menu/Menu.svelte +218 -307
  33. package/dist/menu/MenuButton.svelte +115 -157
  34. package/dist/menu/MenuHeading.svelte +14 -34
  35. package/dist/menu/MenuItem.svelte +107 -145
  36. package/dist/menu/MenuItems.svelte +224 -298
  37. package/dist/menu/MenuSection.svelte +9 -26
  38. package/dist/menu/MenuSeparator.svelte +4 -20
  39. package/dist/portal/InternalPortal.svelte +85 -141
  40. package/dist/portal/Portal.svelte +2 -5
  41. package/dist/portal/PortalGroup.svelte +9 -30
  42. package/dist/switch/Switch.svelte +132 -179
  43. package/dist/switch/SwitchGroup.svelte +31 -44
  44. package/dist/tabs/Tab.svelte +143 -195
  45. package/dist/tabs/TabGroup.svelte +205 -292
  46. package/dist/tabs/TabList.svelte +11 -31
  47. package/dist/tabs/TabPanel.svelte +43 -68
  48. package/dist/tabs/TabPanels.svelte +7 -18
  49. package/dist/textarea/Textarea.svelte +53 -83
  50. package/dist/textarea/Textarea.svelte.d.ts +14 -11
  51. package/dist/transition/InternalTransitionChild.svelte +170 -259
  52. package/dist/transition/Transition.svelte +66 -96
  53. package/dist/transition/TransitionChild.svelte +11 -31
  54. package/dist/utils/ElementOrComponent.svelte +23 -44
  55. package/dist/utils/Generic.svelte +17 -29
  56. package/dist/utils/StableCollection.svelte +36 -54
  57. package/package.json +1 -1
@@ -1,169 +1,127 @@
1
- <script lang="ts" module>
2
- import { tick, type Snippet } from "svelte"
3
- import type { Props, ElementType } from "../utils/types.js"
1
+ <script lang="ts" module>import { tick } from "svelte";
2
+ const DEFAULT_BUTTON_TAG = "button";
3
+ </script>
4
4
 
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
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 { useFloating } 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 { setReference, getReferenceProps: getFloatingReferenceProps } = useFloating();
26
+ $effect(() => {
27
+ untrack(() => _state.setButtonElement(ref ? ref : null));
28
+ setReference(ref);
29
+ });
30
+ const handleKeyDown = async (event) => {
31
+ switch (event.key) {
32
+ case " ":
33
+ case "Enter":
34
+ case "ArrowDown":
35
+ event.preventDefault();
36
+ event.stopPropagation();
37
+ _state.openMenu();
38
+ await tick();
39
+ _state.goToItem({ focus: Focus.First });
40
+ break;
41
+ case "ArrowUp":
42
+ event.preventDefault();
43
+ event.stopPropagation();
44
+ _state.openMenu();
45
+ await tick();
46
+ _state.goToItem({ focus: Focus.Last });
47
+ break;
13
48
  }
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
49
+ };
50
+ const handleKeyUp = (event) => {
51
+ switch (event.key) {
52
+ case " ":
53
+ event.preventDefault();
54
+ break;
55
+ }
56
+ };
57
+ const handleClick = async (event) => {
58
+ if (disabled) return;
59
+ if (_state.menuState === MenuStates.Open) {
60
+ _state.closeMenu();
61
+ await tick();
62
+ _state.buttonElement?.focus({ preventScroll: true });
63
+ } else {
64
+ event.preventDefault();
65
+ _state.openMenu();
66
+ }
67
+ };
68
+ const { isFocusVisible: focus, focusProps } = $derived(
69
+ useFocusRing({
70
+ get autofocus() {
71
+ return autofocus;
25
72
  }
26
- >
27
-
28
- export type MenuButtonChildren = Snippet<[ButtonRenderPropArg]>
29
- </script>
30
-
31
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_BUTTON_TAG">
32
- import { useId } from "../hooks/use-id.js"
33
- import { Focus } from "../utils/calculate-active-index.js"
34
- import { useFocusRing } from "../hooks/use-focus-ring.svelte.js"
35
- import { useActivePress } from "../hooks/use-active-press.svelte.js"
36
- import { useResolveButtonType } from "../hooks/use-resolve-button-type.svelte.js"
37
- import { useFloating } from "../internal/floating.svelte.js"
38
- import { useHover } from "../hooks/use-hover.svelte.js"
39
- import { mergeProps } from "../utils/render.js"
40
- import { MenuStates, useMenuContext } from "./context.svelte.js"
41
- import { untrack } from "svelte"
42
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
43
-
44
- const internalId = useId()
45
- let {
46
- ref = $bindable(),
47
- id = `headlessui-menu-button-${internalId}`,
48
- disabled = false,
49
- autofocus = false,
50
- ...theirProps
51
- }: { as?: TTag } & MenuButtonProps<TTag> = $props()
52
- const _state = useMenuContext("MenuButton")
53
- const { setReference, getReferenceProps: getFloatingReferenceProps } = useFloating()
54
- $effect(() => {
55
- untrack(() => _state.setButtonElement(ref ? (ref as HTMLButtonElement) : null))
56
- setReference(ref)
57
73
  })
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
80
- }
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
74
+ );
75
+ const { isHovered: hover, hoverProps } = $derived(
76
+ useHover({
77
+ get disabled() {
78
+ return disabled;
91
79
  }
92
- }
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()
80
+ })
81
+ );
82
+ const { pressed: active, pressProps } = $derived(
83
+ useActivePress({
84
+ get disabled() {
85
+ return disabled;
104
86
  }
87
+ })
88
+ );
89
+ const slot = $derived({
90
+ open: _state.menuState === MenuStates.Open,
91
+ active: active || _state.menuState === MenuStates.Open,
92
+ disabled,
93
+ hover,
94
+ focus,
95
+ autofocus: autofocus ?? false
96
+ });
97
+ const buttonType = useResolveButtonType({
98
+ get props() {
99
+ return { type: theirProps.type, as: theirProps.as };
100
+ },
101
+ get ref() {
102
+ return { current: _state.buttonElement };
105
103
  }
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 }
141
- },
142
- get ref() {
143
- return { current: _state.buttonElement }
104
+ });
105
+ const ourProps = $derived(
106
+ mergeProps(
107
+ {
108
+ ...getFloatingReferenceProps(),
109
+ id,
110
+ type: buttonType.type,
111
+ "aria-haspopup": "menu",
112
+ "aria-controls": _state.itemsElement?.id,
113
+ "aria-expanded": _state.menuState === MenuStates.Open,
114
+ disabled: disabled || void 0,
115
+ autofocus,
116
+ onkeydown: handleKeyDown,
117
+ onkeyup: handleKeyUp,
118
+ onclick: handleClick
144
119
  },
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
- )
120
+ focusProps,
121
+ hoverProps,
122
+ pressProps
166
123
  )
124
+ );
167
125
  </script>
168
126
 
169
127
  <ElementOrComponent {ourProps} {theirProps} {slot} defaultTag={DEFAULT_BUTTON_TAG} name="MenuButton" bind:ref />
@@ -1,39 +1,19 @@
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
- >
17
-
18
- export type MenuHeadingChildren = Snippet<[HeadingRenderPropArg]>
1
+ <script lang="ts" module>import { onMount } from "svelte";
2
+ const DEFAULT_HEADING_TAG = "header";
19
3
  </script>
20
4
 
21
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_HEADING_TAG">
22
- import { useId } from "../hooks/use-id.js"
23
- import { useLabelContext } from "../label/context.svelte.js"
24
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
25
-
26
- const internalId = useId()
27
- let {
28
- ref = $bindable(),
29
- id = `headlessui-menu-heading-${internalId}`,
30
- ...theirProps
31
- }: { as?: TTag } & MenuHeadingProps<TTag> = $props()
32
-
33
- const context = useLabelContext()
34
- onMount(() => context.register(id))
35
-
36
- const ourProps = $derived({ id, role: "presentation", ...context.props })
5
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_HEADING_TAG">import { useId } from "../hooks/use-id.js";
6
+ import { useLabelContext } from "../label/context.svelte.js";
7
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
8
+ const internalId = useId();
9
+ let {
10
+ ref = $bindable(),
11
+ id = `headlessui-menu-heading-${internalId}`,
12
+ ...theirProps
13
+ } = $props();
14
+ const context = useLabelContext();
15
+ onMount(() => context.register(id));
16
+ const ourProps = $derived({ id, role: "presentation", ...context.props });
37
17
  </script>
38
18
 
39
19
  <ElementOrComponent {ourProps} {theirProps} defaultTag={DEFAULT_HEADING_TAG} name="MenuItem" bind:ref />
@@ -1,152 +1,114 @@
1
- <script lang="ts" module>
2
- import type { Props, ElementType, Children } from "../utils/types.js"
3
- import { onMount, type Snippet } from "svelte"
4
-
5
- const DEFAULT_ITEM_TAG = "svelte:fragment" as const
6
- type ItemRenderPropArg = {
7
- /** @deprecated use `focus` instead */
8
- active: boolean
9
- focus: boolean
10
- disabled: boolean
11
- close: () => void
12
- props?: Record<string, any>
13
- }
14
- type ItemPropsWeControl = "aria-describedby" | "aria-disabled" | "aria-labelledby" | "role" | "tabIndex"
15
-
16
- export type MenuItemProps<TTag extends ElementType = typeof DEFAULT_ITEM_TAG> = Props<
17
- TTag,
18
- ItemRenderPropArg,
19
- ItemPropsWeControl | "children",
20
- {
21
- id?: string
22
- disabled?: boolean
23
- children: Children<ItemRenderPropArg>
24
- }
25
- >
26
-
27
- export type MenuItemChildren = Children<ItemRenderPropArg>
1
+ <script lang="ts" module>import { onMount } from "svelte";
2
+ const DEFAULT_ITEM_TAG = "svelte:fragment";
28
3
  </script>
29
4
 
30
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_ITEM_TAG">
31
- import { useId } from "../hooks/use-id.js"
32
- import { ActivationTrigger, MenuStates, useMenuContext, type MenuItemDataRef } from "./context.svelte.js"
33
- import { disposables } from "../utils/disposables.js"
34
- import { useTextValue } from "../hooks/use-text-value.svelte.js"
35
- import { restoreFocusIfNecessary } from "../utils/focus-management.js"
36
- import { Focus } from "../utils/calculate-active-index.js"
37
- import { useTrackedPointer } from "../hooks/use-tracked-pointer.js"
38
- import { useLabels } from "../label/context.svelte.js"
39
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
40
- import { mergeProps } from "../utils/render.js"
41
- import { useDescriptions } from "../description/context.svelte.js"
42
-
43
- const internalId = useId()
44
- let {
45
- ref = $bindable(),
46
- id = `headlessui-menu-item-${internalId}`,
47
- disabled = false,
48
- ...theirProps
49
- }: { as?: TTag } & MenuItemProps<TTag> = $props()
50
- const _state = useMenuContext("MenuItem")
51
- const active = $derived(_state.activeItemIndex !== null ? _state.items[_state.activeItemIndex].id === id : false)
52
-
53
- $effect(() => {
54
- /* We also want to trigger this when the position of the active item changes so that we can re-trigger the scrollIntoView */
55
- _state.activeItemIndex
56
- if (_state.__demoMode) return
57
- if (_state.menuState !== MenuStates.Open) return
58
- if (!active) return
59
- if (_state.activationTrigger === ActivationTrigger.Pointer) return
60
- return disposables().requestAnimationFrame(() => {
61
- ;(ref as HTMLElement)?.scrollIntoView?.({ block: "nearest" })
62
- })
63
- })
64
-
65
- const getTextValue = useTextValue({
66
- get element() {
67
- return ref || null
68
- },
69
- })
70
-
71
- const bag: MenuItemDataRef["current"] = $derived({
72
- disabled,
73
- domRef: { current: ref || null },
74
- get textValue() {
75
- return getTextValue()
76
- },
77
- })
78
-
79
- onMount(() => {
80
- _state.registerItem(id, {
81
- get current() {
82
- return bag
83
- },
84
- })
85
- return () => _state.unregisterItem(id)
86
- })
87
-
88
- const handleClick = (event: MouseEvent) => {
89
- if (disabled) return event.preventDefault()
90
- _state.closeMenu()
91
- restoreFocusIfNecessary(_state.buttonElement)
92
- }
93
-
94
- const handleFocus = () => {
95
- if (disabled) return _state.goToItem({ focus: Focus.Nothing })
96
- _state.goToItem({ focus: Focus.Specific, id })
5
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_ITEM_TAG">import { useId } from "../hooks/use-id.js";
6
+ import { ActivationTrigger, MenuStates, useMenuContext } from "./context.svelte.js";
7
+ import { disposables } from "../utils/disposables.js";
8
+ import { useTextValue } from "../hooks/use-text-value.svelte.js";
9
+ import { restoreFocusIfNecessary } from "../utils/focus-management.js";
10
+ import { Focus } from "../utils/calculate-active-index.js";
11
+ import { useTrackedPointer } from "../hooks/use-tracked-pointer.js";
12
+ import { useLabels } from "../label/context.svelte.js";
13
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
14
+ import { mergeProps } from "../utils/render.js";
15
+ import { useDescriptions } from "../description/context.svelte.js";
16
+ const internalId = useId();
17
+ let {
18
+ ref = $bindable(),
19
+ id = `headlessui-menu-item-${internalId}`,
20
+ disabled = false,
21
+ ...theirProps
22
+ } = $props();
23
+ const _state = useMenuContext("MenuItem");
24
+ const active = $derived(_state.activeItemIndex !== null ? _state.items[_state.activeItemIndex].id === id : false);
25
+ $effect(() => {
26
+ _state.activeItemIndex;
27
+ if (_state.__demoMode) return;
28
+ if (_state.menuState !== MenuStates.Open) return;
29
+ if (!active) return;
30
+ if (_state.activationTrigger === ActivationTrigger.Pointer) return;
31
+ return disposables().requestAnimationFrame(() => {
32
+ ;
33
+ ref?.scrollIntoView?.({ block: "nearest" });
34
+ });
35
+ });
36
+ const getTextValue = useTextValue({
37
+ get element() {
38
+ return ref || null;
97
39
  }
98
-
99
- const pointer = useTrackedPointer()
100
-
101
- const handleEnter = (evt: PointerEvent) => {
102
- pointer.update(evt)
103
- if (disabled) return
104
- if (active) return
105
- _state.goToItem({ focus: Focus.Specific, id, trigger: ActivationTrigger.Pointer })
106
- }
107
-
108
- const handleMove = (evt: PointerEvent) => {
109
- if (!pointer.wasMoved(evt)) return
110
- if (disabled) return
111
- if (active) return
112
- _state.goToItem({ focus: Focus.Specific, id, trigger: ActivationTrigger.Pointer })
40
+ });
41
+ const bag = $derived({
42
+ disabled,
43
+ domRef: { current: ref || null },
44
+ get textValue() {
45
+ return getTextValue();
113
46
  }
114
-
115
- const handleLeave = (evt: PointerEvent) => {
116
- if (!pointer.wasMoved(evt)) return
117
- if (disabled) return
118
- if (!active) return
119
- _state.goToItem({ focus: Focus.Nothing })
120
- }
121
-
122
- const labelledby = useLabels()
123
- const describedby = useDescriptions()
124
-
125
- const slot = $derived({
126
- active,
127
- focus: active,
128
- disabled,
129
- close: _state.closeMenu,
130
- } satisfies ItemRenderPropArg)
131
- const ourProps = $derived(
132
- mergeProps({
133
- id,
134
- role: "menuitem",
135
- tabindex: disabled === true ? undefined : -1,
136
- "aria-disabled": disabled === true ? true : undefined,
137
- "aria-labelledby": labelledby.value,
138
- "aria-describedby": describedby.value,
139
- disabled: undefined, // Never forward the `disabled` prop
140
- onclick: handleClick,
141
- onfocus: handleFocus,
142
- onpointerenter: handleEnter,
143
- onmouseenter: handleEnter,
144
- onpointermove: handleMove,
145
- onmousemove: handleMove,
146
- onpointerleave: handleLeave,
147
- onmouseleave: handleLeave,
148
- })
149
- )
47
+ });
48
+ onMount(() => {
49
+ _state.registerItem(id, {
50
+ get current() {
51
+ return bag;
52
+ }
53
+ });
54
+ return () => _state.unregisterItem(id);
55
+ });
56
+ const handleClick = (event) => {
57
+ if (disabled) return event.preventDefault();
58
+ _state.closeMenu();
59
+ restoreFocusIfNecessary(_state.buttonElement);
60
+ };
61
+ const handleFocus = () => {
62
+ if (disabled) return _state.goToItem({ focus: Focus.Nothing });
63
+ _state.goToItem({ focus: Focus.Specific, id });
64
+ };
65
+ const pointer = useTrackedPointer();
66
+ const handleEnter = (evt) => {
67
+ pointer.update(evt);
68
+ if (disabled) return;
69
+ if (active) return;
70
+ _state.goToItem({ focus: Focus.Specific, id, trigger: ActivationTrigger.Pointer });
71
+ };
72
+ const handleMove = (evt) => {
73
+ if (!pointer.wasMoved(evt)) return;
74
+ if (disabled) return;
75
+ if (active) return;
76
+ _state.goToItem({ focus: Focus.Specific, id, trigger: ActivationTrigger.Pointer });
77
+ };
78
+ const handleLeave = (evt) => {
79
+ if (!pointer.wasMoved(evt)) return;
80
+ if (disabled) return;
81
+ if (!active) return;
82
+ _state.goToItem({ focus: Focus.Nothing });
83
+ };
84
+ const labelledby = useLabels();
85
+ const describedby = useDescriptions();
86
+ const slot = $derived({
87
+ active,
88
+ focus: active,
89
+ disabled,
90
+ close: _state.closeMenu
91
+ });
92
+ const ourProps = $derived(
93
+ mergeProps({
94
+ id,
95
+ role: "menuitem",
96
+ tabindex: disabled === true ? void 0 : -1,
97
+ "aria-disabled": disabled === true ? true : void 0,
98
+ "aria-labelledby": labelledby.value,
99
+ "aria-describedby": describedby.value,
100
+ disabled: void 0,
101
+ // Never forward the `disabled` prop
102
+ onclick: handleClick,
103
+ onfocus: handleFocus,
104
+ onpointerenter: handleEnter,
105
+ onmouseenter: handleEnter,
106
+ onpointermove: handleMove,
107
+ onmousemove: handleMove,
108
+ onpointerleave: handleLeave,
109
+ onmouseleave: handleLeave
110
+ })
111
+ );
150
112
  </script>
151
113
 
152
114
  <ElementOrComponent {ourProps} {theirProps} {slot} defaultTag={DEFAULT_ITEM_TAG} name="MenuItem" bind:ref />