@yamada-ui/menu 1.3.20-next-20241113111348 → 1.3.20-next-20241114172614

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.
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
  import {
3
3
  MenuIcon
4
- } from "./chunk-7FDQPFQM.mjs";
4
+ } from "./chunk-X5YYJEDZ.mjs";
5
5
  import {
6
6
  useMenu,
7
7
  useUpstreamMenuItem
@@ -37,10 +37,12 @@ var MenuButton = forwardRef(
37
37
  id != null ? id : id = uuid;
38
38
  const onKeyDown = useCallback(
39
39
  (ev) => {
40
+ if (ev.key === " ") ev.key = ev.code;
40
41
  const actions = {
41
42
  ArrowDown: funcAll(onOpen, onFocusFirstItem),
42
43
  ArrowUp: funcAll(onOpen, onFocusLastItem),
43
- Enter: funcAll(onOpen, onFocusFirstItem)
44
+ Enter: funcAll(onOpen, onFocusFirstItem),
45
+ Space: funcAll(onOpen, onFocusFirstItem)
44
46
  };
45
47
  const action = actions[ev.key];
46
48
  if (!action) return;
@@ -51,9 +53,12 @@ var MenuButton = forwardRef(
51
53
  );
52
54
  const onItemKeyDown = useCallback(
53
55
  (ev) => {
56
+ if (ev.key === " ") ev.key = ev.code;
54
57
  const actions = {
55
58
  ArrowLeft: isOpen ? funcAll(onUpstreamRestoreFocus, onClose) : void 0,
56
- ArrowRight: !isOpen ? funcAll(onOpen, onFocusFirstItem) : void 0
59
+ ArrowRight: !isOpen ? funcAll(onOpen, onFocusFirstItem) : void 0,
60
+ Enter: !isOpen ? funcAll(onOpen, onFocusFirstItem) : void 0,
61
+ Space: !isOpen ? funcAll(onOpen, onFocusFirstItem) : void 0
57
62
  };
58
63
  const action = actions[ev.key];
59
64
  if (!action) return;
@@ -70,7 +75,6 @@ var MenuButton = forwardRef(
70
75
  id,
71
76
  ref: mergeRefs(buttonRef, ref),
72
77
  className: cx("ui-menu", className),
73
- "aria-expanded": isOpen,
74
78
  "aria-haspopup": "menu",
75
79
  ...rest,
76
80
  "data-active": dataAttr(isOpen),
@@ -117,4 +121,4 @@ export {
117
121
  MenuButton,
118
122
  MenuItemButton
119
123
  };
120
- //# sourceMappingURL=chunk-TDS7X2BY.mjs.map
124
+ //# sourceMappingURL=chunk-72J22E3I.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu-button.tsx"],"sourcesContent":["import type { CSSUIObject, HTMLUIProps } from \"@yamada-ui/core\"\nimport type { KeyboardEvent, ReactNode } from \"react\"\nimport type { MenuIconProps } from \"./menu-item\"\nimport { forwardRef, ui } from \"@yamada-ui/core\"\nimport { ChevronIcon } from \"@yamada-ui/icon\"\nimport { PopoverTrigger } from \"@yamada-ui/popover\"\nimport {\n assignRef,\n cx,\n dataAttr,\n funcAll,\n handlerAll,\n mergeRefs,\n} from \"@yamada-ui/utils\"\nimport { useCallback, useId, useMemo } from \"react\"\nimport { useMenu, useUpstreamMenuItem } from \"./menu-context\"\nimport { MenuIcon } from \"./menu-item\"\n\nexport interface MenuButtonProps extends HTMLUIProps<\"button\"> {}\n\nexport const MenuButton = forwardRef<MenuButtonProps, \"button\">(\n ({ id, as, className, children, ...rest }, ref) => {\n const { onKeyDownRef, onUpstreamRestoreFocus } = useUpstreamMenuItem() ?? {}\n const {\n buttonRef,\n isOpen,\n onClose,\n onFocusFirstItem,\n onFocusLastItem,\n onOpen,\n } = useMenu()\n const uuid = useId()\n\n id ??= uuid\n\n const onKeyDown = useCallback(\n (ev: KeyboardEvent) => {\n if (ev.key === \" \") ev.key = ev.code\n\n const actions: { [key: string]: Function } = {\n ArrowDown: funcAll(onOpen, onFocusFirstItem),\n ArrowUp: funcAll(onOpen, onFocusLastItem),\n Enter: funcAll(onOpen, onFocusFirstItem),\n Space: funcAll(onOpen, onFocusFirstItem),\n }\n\n const action = actions[ev.key]\n\n if (!action) return\n\n ev.preventDefault()\n\n action()\n },\n [onFocusFirstItem, onFocusLastItem, onOpen],\n )\n\n const onItemKeyDown = useCallback(\n (ev: KeyboardEvent<HTMLDivElement>) => {\n if (ev.key === \" \") ev.key = ev.code\n\n const actions: { [key: string]: Function | undefined } = {\n ArrowLeft: isOpen\n ? funcAll(onUpstreamRestoreFocus, onClose)\n : undefined,\n ArrowRight: !isOpen ? funcAll(onOpen, onFocusFirstItem) : undefined,\n Enter: !isOpen ? funcAll(onOpen, onFocusFirstItem) : undefined,\n Space: !isOpen ? funcAll(onOpen, onFocusFirstItem) : undefined,\n }\n\n const action = actions[ev.key]\n\n if (!action) return\n\n ev.preventDefault()\n\n action()\n },\n [isOpen, onOpen, onFocusFirstItem, onUpstreamRestoreFocus, onClose],\n )\n\n assignRef(onKeyDownRef, onItemKeyDown)\n\n const Component = useMemo(() => (as ? ui(as) : Button), [as])\n\n return (\n <PopoverTrigger>\n <Component\n id={id}\n ref={mergeRefs(buttonRef, ref)}\n className={cx(\"ui-menu\", className)}\n aria-haspopup=\"menu\"\n {...rest}\n data-active={dataAttr(isOpen)}\n onKeyDown={handlerAll(rest.onKeyDown, onKeyDown)}\n >\n {children}\n </Component>\n </PopoverTrigger>\n )\n },\n)\n\nMenuButton.displayName = \"MenuButton\"\nMenuButton.__ui__ = \"MenuButton\"\n\nconst Button = forwardRef<MenuButtonProps, \"button\">((rest, ref) => {\n const { styles } = useMenu()\n\n const css: CSSUIObject = {\n alignItems: \"center\",\n appearance: \"none\",\n display: \"inline-flex\",\n outline: 0,\n ...styles.button,\n }\n\n return <ui.button ref={ref} __css={css} {...rest} />\n})\n\nexport interface MenuItemButtonProps extends MenuButtonProps {\n icon?: ReactNode\n iconProps?: MenuIconProps\n innerProps?: HTMLUIProps<\"span\">\n}\n\nexport const MenuItemButton = forwardRef<MenuItemButtonProps, \"button\">(\n ({ className, children, icon, iconProps, innerProps, ...rest }, ref) => {\n return (\n <MenuButton\n ref={ref}\n className={cx(\"ui-menu__item-button\", className)}\n flex=\"1\"\n {...rest}\n >\n <ui.span as=\"span\" flex=\"1\" {...innerProps}>\n {children}\n </ui.span>\n\n <MenuIcon {...iconProps}>\n {icon ?? <ChevronIcon fontSize=\"1.5em\" transform=\"rotate(-90deg)\" />}\n </MenuIcon>\n </MenuButton>\n )\n },\n)\n\nMenuItemButton.displayName = \"MenuItemButton\"\nMenuItemButton.__ui__ = \"MenuItemButton\"\n"],"mappings":"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","names":[]}
@@ -8,11 +8,11 @@ import {
8
8
  import { forwardRef, ui } from "@yamada-ui/core";
9
9
  import { PopoverContent } from "@yamada-ui/popover";
10
10
  import { cx, handlerAll, mergeRefs } from "@yamada-ui/utils";
11
- import { useCallback } from "react";
11
+ import { useCallback, useId } from "react";
12
12
  import { jsx } from "react/jsx-runtime";
13
13
  var MenuList = forwardRef(
14
- ({ className, children, contentProps, ...rest }, ref) => {
15
- var _a;
14
+ ({ id, className, children, contentProps, ...rest }, ref) => {
15
+ var _a, _b;
16
16
  const {
17
17
  buttonRef,
18
18
  focusedIndex,
@@ -21,7 +21,10 @@ var MenuList = forwardRef(
21
21
  styles,
22
22
  onClose
23
23
  } = useMenu();
24
+ const uuid = useId();
25
+ id != null ? id : id = uuid;
24
26
  const descendants = useMenuDescendantsContext();
27
+ const activedescendantId = (_a = descendants.value(focusedIndex)) == null ? void 0 : _a.node.id;
25
28
  const onNext = useCallback(() => {
26
29
  const next = descendants.enabledNextValue(focusedIndex);
27
30
  if (next) setFocusedIndex(next.index);
@@ -46,7 +49,7 @@ var MenuList = forwardRef(
46
49
  End: onLast,
47
50
  Escape: onClose,
48
51
  Home: onFirst,
49
- Tab: (ev2) => ev2.preventDefault()
52
+ Tab: onClose
50
53
  };
51
54
  const action = actions[ev.key];
52
55
  if (!action) return;
@@ -58,8 +61,12 @@ var MenuList = forwardRef(
58
61
  return /* @__PURE__ */ jsx(
59
62
  PopoverContent,
60
63
  {
64
+ id,
61
65
  as: "div",
62
66
  className: "ui-menu__content",
67
+ "aria-activedescendant": activedescendantId,
68
+ "aria-labelledby": (_b = buttonRef.current) == null ? void 0 : _b.id,
69
+ role: "menu",
63
70
  __css: { ...styles.content },
64
71
  ...contentProps,
65
72
  onKeyDown: handlerAll(contentProps == null ? void 0 : contentProps.onKeyDown, onKeyDown),
@@ -68,8 +75,6 @@ var MenuList = forwardRef(
68
75
  {
69
76
  ref: mergeRefs(menuRef, ref),
70
77
  className: cx("ui-menu__list", className),
71
- "aria-labelledby": (_a = buttonRef.current) == null ? void 0 : _a.id,
72
- role: "menu",
73
78
  tabIndex: -1,
74
79
  __css: { ...styles.list },
75
80
  ...rest,
@@ -86,4 +91,4 @@ MenuList.__ui__ = "MenuList";
86
91
  export {
87
92
  MenuList
88
93
  };
89
- //# sourceMappingURL=chunk-GWDM6IJK.mjs.map
94
+ //# sourceMappingURL=chunk-N7KSYRKD.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu-list.tsx"],"sourcesContent":["import type { HTMLUIProps } from \"@yamada-ui/core\"\nimport type { MotionPropsWithoutChildren } from \"@yamada-ui/motion\"\nimport type { KeyboardEvent, KeyboardEventHandler } from \"react\"\nimport { forwardRef, ui } from \"@yamada-ui/core\"\nimport { PopoverContent } from \"@yamada-ui/popover\"\nimport { cx, handlerAll, mergeRefs } from \"@yamada-ui/utils\"\nimport { useCallback, useId } from \"react\"\nimport { useMenu, useMenuDescendantsContext } from \"./menu-context\"\n\nexport interface MenuListProps extends HTMLUIProps<\"ul\"> {\n contentProps?: MotionPropsWithoutChildren\n}\n\nexport const MenuList = forwardRef<MenuListProps, \"ul\">(\n ({ id, className, children, contentProps, ...rest }, ref) => {\n const {\n buttonRef,\n focusedIndex,\n menuRef,\n setFocusedIndex,\n styles,\n onClose,\n } = useMenu()\n const uuid = useId()\n id ??= uuid\n\n const descendants = useMenuDescendantsContext()\n\n const activedescendantId = descendants.value(focusedIndex)?.node.id\n\n const onNext = useCallback(() => {\n const next = descendants.enabledNextValue(focusedIndex)\n\n if (next) setFocusedIndex(next.index)\n }, [descendants, focusedIndex, setFocusedIndex])\n\n const onPrev = useCallback(() => {\n const prev = descendants.enabledPrevValue(focusedIndex)\n\n if (prev) setFocusedIndex(prev.index)\n }, [descendants, focusedIndex, setFocusedIndex])\n\n const onFirst = useCallback(() => {\n const first = descendants.enabledFirstValue()\n\n if (first) setFocusedIndex(first.index)\n }, [descendants, setFocusedIndex])\n\n const onLast = useCallback(() => {\n const last = descendants.enabledLastValue()\n\n if (last) setFocusedIndex(last.index)\n }, [descendants, setFocusedIndex])\n\n const onKeyDown = useCallback(\n (ev: KeyboardEvent) => {\n const actions: { [key: string]: KeyboardEventHandler } = {\n ArrowDown: focusedIndex === -1 ? onFirst : onNext,\n ArrowUp: focusedIndex === -1 ? onLast : onPrev,\n End: onLast,\n Escape: onClose,\n Home: onFirst,\n Tab: onClose,\n }\n\n const action = actions[ev.key]\n\n if (!action) return\n\n ev.preventDefault()\n action(ev)\n },\n [focusedIndex, onClose, onFirst, onLast, onNext, onPrev],\n )\n\n return (\n <PopoverContent\n id={id}\n as=\"div\"\n className=\"ui-menu__content\"\n aria-activedescendant={activedescendantId}\n aria-labelledby={buttonRef.current?.id}\n role=\"menu\"\n __css={{ ...styles.content }}\n {...contentProps}\n onKeyDown={handlerAll(contentProps?.onKeyDown, onKeyDown)}\n >\n <ui.div\n ref={mergeRefs(menuRef, ref)}\n className={cx(\"ui-menu__list\", className)}\n tabIndex={-1}\n __css={{ ...styles.list }}\n {...rest}\n >\n {children}\n </ui.div>\n </PopoverContent>\n )\n },\n)\n\nMenuList.displayName = \"MenuList\"\nMenuList.__ui__ = \"MenuList\"\n"],"mappings":";;;;;;;AAGA,SAAS,YAAY,UAAU;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,IAAI,YAAY,iBAAiB;AAC1C,SAAS,aAAa,aAAa;AAiF3B;AA1ED,IAAM,WAAW;AAAA,EACtB,CAAC,EAAE,IAAI,WAAW,UAAU,cAAc,GAAG,KAAK,GAAG,QAAQ;AAd/D;AAeI,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,QAAQ;AACZ,UAAM,OAAO,MAAM;AACnB,2BAAO;AAEP,UAAM,cAAc,0BAA0B;AAE9C,UAAM,sBAAqB,iBAAY,MAAM,YAAY,MAA9B,mBAAiC,KAAK;AAEjE,UAAM,SAAS,YAAY,MAAM;AAC/B,YAAM,OAAO,YAAY,iBAAiB,YAAY;AAEtD,UAAI,KAAM,iBAAgB,KAAK,KAAK;AAAA,IACtC,GAAG,CAAC,aAAa,cAAc,eAAe,CAAC;AAE/C,UAAM,SAAS,YAAY,MAAM;AAC/B,YAAM,OAAO,YAAY,iBAAiB,YAAY;AAEtD,UAAI,KAAM,iBAAgB,KAAK,KAAK;AAAA,IACtC,GAAG,CAAC,aAAa,cAAc,eAAe,CAAC;AAE/C,UAAM,UAAU,YAAY,MAAM;AAChC,YAAM,QAAQ,YAAY,kBAAkB;AAE5C,UAAI,MAAO,iBAAgB,MAAM,KAAK;AAAA,IACxC,GAAG,CAAC,aAAa,eAAe,CAAC;AAEjC,UAAM,SAAS,YAAY,MAAM;AAC/B,YAAM,OAAO,YAAY,iBAAiB;AAE1C,UAAI,KAAM,iBAAgB,KAAK,KAAK;AAAA,IACtC,GAAG,CAAC,aAAa,eAAe,CAAC;AAEjC,UAAM,YAAY;AAAA,MAChB,CAAC,OAAsB;AACrB,cAAM,UAAmD;AAAA,UACvD,WAAW,iBAAiB,KAAK,UAAU;AAAA,UAC3C,SAAS,iBAAiB,KAAK,SAAS;AAAA,UACxC,KAAK;AAAA,UACL,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,KAAK;AAAA,QACP;AAEA,cAAM,SAAS,QAAQ,GAAG,GAAG;AAE7B,YAAI,CAAC,OAAQ;AAEb,WAAG,eAAe;AAClB,eAAO,EAAE;AAAA,MACX;AAAA,MACA,CAAC,cAAc,SAAS,SAAS,QAAQ,QAAQ,MAAM;AAAA,IACzD;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAG;AAAA,QACH,WAAU;AAAA,QACV,yBAAuB;AAAA,QACvB,oBAAiB,eAAU,YAAV,mBAAmB;AAAA,QACpC,MAAK;AAAA,QACL,OAAO,EAAE,GAAG,OAAO,QAAQ;AAAA,QAC1B,GAAG;AAAA,QACJ,WAAW,WAAW,6CAAc,WAAW,SAAS;AAAA,QAExD;AAAA,UAAC,GAAG;AAAA,UAAH;AAAA,YACC,KAAK,UAAU,SAAS,GAAG;AAAA,YAC3B,WAAW,GAAG,iBAAiB,SAAS;AAAA,YACxC,UAAU;AAAA,YACV,OAAO,EAAE,GAAG,OAAO,KAAK;AAAA,YACvB,GAAG;AAAA,YAEH;AAAA;AAAA,QACH;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AACvB,SAAS,SAAS;","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-SWY6VV4V.mjs";
5
5
  import {
6
6
  MenuOptionItem
7
- } from "./chunk-7FDQPFQM.mjs";
7
+ } from "./chunk-X5YYJEDZ.mjs";
8
8
 
9
9
  // src/menu-option-group.tsx
10
10
  import { useControllableState } from "@yamada-ui/use-controllable-state";
@@ -66,4 +66,4 @@ MenuOptionGroup.__ui__ = "MenuOptionGroup";
66
66
  export {
67
67
  MenuOptionGroup
68
68
  };
69
- //# sourceMappingURL=chunk-3NSBHYCK.mjs.map
69
+ //# sourceMappingURL=chunk-VPMWBZWN.mjs.map
@@ -10,8 +10,8 @@ import {
10
10
  import { forwardRef, ui } from "@yamada-ui/core";
11
11
  import { useClickable } from "@yamada-ui/use-clickable";
12
12
  import {
13
- ariaAttr,
14
13
  cx,
14
+ dataAttr,
15
15
  funcAll,
16
16
  handlerAll,
17
17
  isActiveElement,
@@ -19,7 +19,7 @@ import {
19
19
  mergeRefs,
20
20
  useUpdateEffect
21
21
  } from "@yamada-ui/utils";
22
- import { useCallback, useRef, useState } from "react";
22
+ import { useCallback, useId, useRef, useState } from "react";
23
23
  import { jsx, jsxs } from "react/jsx-runtime";
24
24
  var isTargetMenuItem = (target) => {
25
25
  var _a;
@@ -27,6 +27,7 @@ var isTargetMenuItem = (target) => {
27
27
  };
28
28
  var MenuItem = forwardRef(
29
29
  ({
30
+ id,
30
31
  className,
31
32
  children,
32
33
  closeOnSelect: customCloseOnSelect,
@@ -36,7 +37,7 @@ var MenuItem = forwardRef(
36
37
  isFocusable,
37
38
  ...props
38
39
  }, ref) => {
39
- var _a;
40
+ var _a, _b;
40
41
  const {
41
42
  closeOnSelect,
42
43
  focusedIndex,
@@ -50,14 +51,18 @@ var MenuItem = forwardRef(
50
51
  onUpstreamClose
51
52
  } = useMenu();
52
53
  const { onUpstreamRestoreFocus } = (_a = useUpstreamMenuItem()) != null ? _a : {};
53
- const trulyDisabled = isDisabled && !isFocusable;
54
+ const [isDownstreamOpen, setDownstreamOpen] = useState(false);
55
+ const uuid = useId();
54
56
  const itemRef = useRef(null);
55
57
  const hasDownstreamRef = useRef(false);
56
58
  const onKeyDownRef = useRef(
57
59
  () => void 0
58
60
  );
61
+ id != null ? id : id = uuid;
62
+ const trulyDisabled = isDisabled && !isFocusable;
63
+ const type = (_b = itemRef.current) == null ? void 0 : _b.getAttribute("type");
64
+ const role = !!type ? type === "checkbox" ? "menuitemcheckbox" : "menuitemradio" : "menuitem";
59
65
  const { index, register } = useMenuDescendant({ disabled: trulyDisabled });
60
- const [isDownstreamOpen, setDownstreamOpen] = useState(false);
61
66
  const isFocused = index === focusedIndex;
62
67
  const onMouseOver = useCallback(() => {
63
68
  if (isDisabled) return;
@@ -88,8 +93,10 @@ var MenuItem = forwardRef(
88
93
  }, [setFocusedIndex, index]);
89
94
  const onKeyDown = useCallback(
90
95
  (ev) => {
96
+ if (ev.key === " ") ev.key = ev.code;
91
97
  const actions = {
92
- ArrowLeft: isNested ? funcAll(onUpstreamRestoreFocus, onClose) : void 0
98
+ ArrowLeft: isNested ? funcAll(onUpstreamRestoreFocus, onClose) : void 0,
99
+ Space: !hasDownstreamRef.current ? funcAll(onUpstreamClose, onClose) : void 0
93
100
  };
94
101
  const action = actions[ev.key];
95
102
  if (!action) return;
@@ -97,9 +104,10 @@ var MenuItem = forwardRef(
97
104
  ev.stopPropagation();
98
105
  action();
99
106
  },
100
- [onUpstreamRestoreFocus, onClose, isNested]
107
+ [isNested, onUpstreamRestoreFocus, onClose, onUpstreamClose]
101
108
  );
102
109
  const rest = useClickable({
110
+ clickOnSpace: false,
103
111
  focusOnClick: false,
104
112
  ...props,
105
113
  ref: mergeRefs(register, itemRef, ref),
@@ -113,9 +121,9 @@ var MenuItem = forwardRef(
113
121
  });
114
122
  useUpdateEffect(() => {
115
123
  if (!isOpen) return;
116
- const id = requestAnimationFrameId.current;
124
+ const id2 = requestAnimationFrameId.current;
117
125
  if (isFocused && !trulyDisabled && itemRef.current) {
118
- if (id) cancelAnimationFrame(id);
126
+ if (id2) cancelAnimationFrame(id2);
119
127
  requestAnimationFrameId.current = requestAnimationFrame(() => {
120
128
  var _a2;
121
129
  (_a2 = itemRef.current) == null ? void 0 : _a2.focus({ preventScroll: true });
@@ -125,7 +133,7 @@ var MenuItem = forwardRef(
125
133
  menuRef.current.focus({ preventScroll: true });
126
134
  }
127
135
  return () => {
128
- if (id) cancelAnimationFrame(id);
136
+ if (id2) cancelAnimationFrame(id2);
129
137
  };
130
138
  }, [isFocused, trulyDisabled, menuRef, isOpen]);
131
139
  children = icon || command ? /* @__PURE__ */ jsx(ui.span, { style: { flex: 1 }, children }) : children;
@@ -154,12 +162,13 @@ var MenuItem = forwardRef(
154
162
  children: /* @__PURE__ */ jsxs(
155
163
  ui.div,
156
164
  {
157
- ...rest,
158
- ...isDownstreamOpen ? { "data-active": "" } : {},
165
+ id,
159
166
  className: cx("ui-menu__item", className),
160
- role: "menuitem",
161
- tabIndex: isFocused ? 0 : -1,
167
+ "data-focus": dataAttr(isDownstreamOpen),
162
168
  __css: css,
169
+ ...rest,
170
+ role,
171
+ tabIndex: !isDownstreamOpen && isFocused ? 0 : -1,
163
172
  children: [
164
173
  icon ? /* @__PURE__ */ jsx(MenuIcon, { children: icon }) : null,
165
174
  children,
@@ -180,7 +189,7 @@ var MenuOptionItem = forwardRef(
180
189
  {
181
190
  ref,
182
191
  className: cx("ui-menu__item--option", className),
183
- "aria-checked": ariaAttr(isChecked),
192
+ "aria-checked": isChecked,
184
193
  closeOnSelect,
185
194
  ...rest,
186
195
  children: [
@@ -249,4 +258,4 @@ export {
249
258
  MenuIcon,
250
259
  MenuCommand
251
260
  };
252
- //# sourceMappingURL=chunk-7FDQPFQM.mjs.map
261
+ //# sourceMappingURL=chunk-X5YYJEDZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu-item.tsx"],"sourcesContent":["import type { CSSUIObject, FC, HTMLUIProps } from \"@yamada-ui/core\"\nimport type {\n KeyboardEvent,\n KeyboardEventHandler,\n MouseEvent,\n ReactElement,\n} from \"react\"\nimport { forwardRef, ui } from \"@yamada-ui/core\"\nimport { useClickable } from \"@yamada-ui/use-clickable\"\nimport {\n cx,\n dataAttr,\n funcAll,\n handlerAll,\n isActiveElement,\n isHTMLElement,\n mergeRefs,\n useUpdateEffect,\n} from \"@yamada-ui/utils\"\nimport { useCallback, useId, useRef, useState } from \"react\"\nimport {\n UpstreamMenuItemProvider,\n useMenu,\n useMenuDescendant,\n useUpstreamMenuItem,\n} from \"./menu-context\"\n\nconst isTargetMenuItem = (target: EventTarget | null) => {\n return (\n isHTMLElement(target) &&\n !!target.getAttribute(\"role\")?.startsWith(\"menuitem\")\n )\n}\n\ninterface MenuItemOptions {\n /**\n * If `true`, the list element will be closed when selected.\n *\n * @default false\n */\n closeOnSelect?: boolean\n /**\n * Right-aligned label text content, useful for displaying hotkeys.\n */\n command?: string\n /**\n * The menu item icon to use.\n */\n icon?: ReactElement\n /**\n * If `true`, the menu item will be disabled.\n *\n * @default false\n */\n isDisabled?: boolean\n /**\n * If `true`, the menu item will be focusable.\n *\n * @default false\n */\n isFocusable?: boolean\n}\n\nexport interface MenuItemProps extends HTMLUIProps, MenuItemOptions {}\n\nexport const MenuItem = forwardRef<MenuItemProps, \"div\">(\n (\n {\n id,\n className,\n children,\n closeOnSelect: customCloseOnSelect,\n command,\n icon,\n isDisabled,\n isFocusable,\n ...props\n },\n ref,\n ) => {\n const {\n closeOnSelect,\n focusedIndex,\n isNested,\n isOpen,\n menuRef,\n requestAnimationFrameId,\n setFocusedIndex,\n styles,\n onClose,\n onUpstreamClose,\n } = useMenu()\n const { onUpstreamRestoreFocus } = useUpstreamMenuItem() ?? {}\n const [isDownstreamOpen, setDownstreamOpen] = useState<boolean>(false)\n const uuid = useId()\n const itemRef = useRef<HTMLDivElement>(null)\n const hasDownstreamRef = useRef<boolean>(false)\n const onKeyDownRef = useRef<KeyboardEventHandler<HTMLDivElement>>(\n () => void 0,\n )\n\n id ??= uuid\n\n const trulyDisabled = isDisabled && !isFocusable\n const type = itemRef.current?.getAttribute(\"type\")\n const role = !!type\n ? type === \"checkbox\"\n ? \"menuitemcheckbox\"\n : \"menuitemradio\"\n : \"menuitem\"\n\n const { index, register } = useMenuDescendant({ disabled: trulyDisabled })\n\n const isFocused = index === focusedIndex\n\n const onMouseOver = useCallback(() => {\n if (isDisabled) return\n\n setFocusedIndex(index)\n }, [index, isDisabled, setFocusedIndex])\n\n const onMouseLeave = useCallback(() => {\n if (isDisabled) return\n\n setFocusedIndex(-1)\n }, [setFocusedIndex, isDisabled])\n\n const onClick = useCallback(\n (ev: MouseEvent<HTMLDivElement>) => {\n if (!isTargetMenuItem(ev.currentTarget)) return\n\n const hasDownstream = hasDownstreamRef.current\n\n if (customCloseOnSelect ?? (!hasDownstream && closeOnSelect)) {\n onClose()\n onUpstreamClose?.()\n }\n },\n [customCloseOnSelect, closeOnSelect, onClose, onUpstreamClose],\n )\n\n const onFocus = useCallback(() => {\n setFocusedIndex(index)\n }, [setFocusedIndex, index])\n\n const onRestoreFocus = useCallback(() => {\n itemRef.current?.focus()\n\n setFocusedIndex(index)\n }, [setFocusedIndex, index])\n\n const onKeyDown = useCallback(\n (ev: KeyboardEvent<HTMLDivElement>) => {\n if (ev.key === \" \") ev.key = ev.code\n\n const actions: { [key: string]: Function | undefined } = {\n ArrowLeft: isNested\n ? funcAll(onUpstreamRestoreFocus, onClose)\n : undefined,\n Space: !hasDownstreamRef.current\n ? funcAll(onUpstreamClose, onClose)\n : undefined,\n }\n\n const action = actions[ev.key]\n\n if (!action) return\n\n ev.preventDefault()\n ev.stopPropagation()\n\n action()\n },\n [isNested, onUpstreamRestoreFocus, onClose, onUpstreamClose],\n )\n\n const rest = useClickable<HTMLDivElement>({\n clickOnSpace: false,\n focusOnClick: false,\n ...props,\n ref: mergeRefs(register, itemRef, ref),\n isDisabled,\n isFocusable,\n onClick: handlerAll(props.onClick, onClick),\n onFocus: handlerAll(props.onFocus, onFocus),\n onKeyDown: handlerAll(props.onKeyDown, onKeyDown, onKeyDownRef.current),\n onMouseLeave: handlerAll(props.onMouseLeave, onMouseLeave),\n onMouseOver: handlerAll(props.onMouseOver, onMouseOver),\n })\n\n useUpdateEffect(() => {\n if (!isOpen) return\n\n const id = requestAnimationFrameId.current\n\n if (isFocused && !trulyDisabled && itemRef.current) {\n if (id) cancelAnimationFrame(id)\n\n requestAnimationFrameId.current = requestAnimationFrame(() => {\n itemRef.current?.focus({ preventScroll: true })\n\n requestAnimationFrameId.current = null\n })\n } else if (menuRef.current && !isActiveElement(menuRef.current)) {\n menuRef.current.focus({ preventScroll: true })\n }\n\n return () => {\n if (id) cancelAnimationFrame(id)\n }\n }, [isFocused, trulyDisabled, menuRef, isOpen])\n\n children =\n icon || command ? (\n <ui.span style={{ flex: 1 }}>{children}</ui.span>\n ) : (\n children\n )\n\n const css: CSSUIObject = {\n alignItems: \"center\",\n color: \"inherit\",\n display: \"flex\",\n flex: \"0 0 auto\",\n gap: \"0.75rem\",\n outline: 0,\n textAlign: \"start\",\n textDecoration: \"none\",\n userSelect: \"none\",\n width: \"100%\",\n ...styles.item,\n }\n\n return (\n <UpstreamMenuItemProvider\n value={{\n hasDownstreamRef,\n setDownstreamOpen,\n onKeyDownRef,\n onUpstreamRestoreFocus: onRestoreFocus,\n }}\n >\n <ui.div\n id={id}\n className={cx(\"ui-menu__item\", className)}\n data-focus={dataAttr(isDownstreamOpen)}\n __css={css}\n {...rest}\n role={role}\n tabIndex={!isDownstreamOpen && isFocused ? 0 : -1}\n >\n {icon ? <MenuIcon>{icon}</MenuIcon> : null}\n {children}\n {command ? <MenuCommand>{command}</MenuCommand> : null}\n </ui.div>\n </UpstreamMenuItemProvider>\n )\n },\n)\n\nMenuItem.displayName = \"MenuItem\"\nMenuItem.__ui__ = \"MenuItem\"\n\ninterface MenuOptionItemOptions {\n /**\n * The type of the menu option item.\n */\n type?: \"checkbox\" | \"radio\"\n /**\n * The menu option item icon to use.\n */\n icon?: null | ReactElement\n /**\n * If `true`, the checkbox or radio will be checked.\n *\n * @default false\n */\n isChecked?: boolean\n /**\n * The value of the menu option item.\n */\n value?: string\n}\n\nexport interface MenuOptionItemProps\n extends Omit<MenuItemProps, \"command\" | \"icon\" | \"value\">,\n MenuOptionItemOptions {}\n\nexport const MenuOptionItem = forwardRef<MenuOptionItemProps, \"button\">(\n (\n { className, children, closeOnSelect = false, icon, isChecked, ...rest },\n ref,\n ) => {\n return (\n <MenuItem\n ref={ref}\n className={cx(\"ui-menu__item--option\", className)}\n aria-checked={isChecked}\n closeOnSelect={closeOnSelect}\n {...rest}\n >\n {icon !== null ? (\n <MenuIcon opacity={isChecked ? 1 : 0}>\n {icon || <CheckIcon />}\n </MenuIcon>\n ) : null}\n {children}\n </MenuItem>\n )\n },\n)\n\nMenuOptionItem.displayName = \"MenuOptionItem\"\nMenuOptionItem.__ui__ = \"MenuOptionItem\"\n\nexport interface MenuIconProps extends HTMLUIProps<\"span\"> {}\n\nexport const MenuIcon = forwardRef<MenuIconProps, \"span\">(\n ({ className, ...rest }, ref) => {\n const { styles } = useMenu()\n\n const css: CSSUIObject = {\n alignItems: \"center\",\n display: \"inline-flex\",\n flexShrink: 0,\n fontSize: \"0.85em\",\n justifyContent: \"center\",\n ...styles.icon,\n }\n\n return (\n <ui.span\n ref={ref}\n className={cx(\"ui-menu__item__icon\", className)}\n aria-hidden\n __css={css}\n {...rest}\n />\n )\n },\n)\n\nMenuIcon.displayName = \"MenuIcon\"\nMenuIcon.__ui__ = \"MenuIcon\"\n\nexport interface MenuCommandProps extends HTMLUIProps<\"span\"> {}\n\nexport const MenuCommand = forwardRef<MenuCommandProps, \"span\">(\n ({ className, ...rest }, ref) => {\n const { styles } = useMenu()\n\n const css: CSSUIObject = { ...styles.command }\n\n return (\n <ui.span\n ref={ref}\n className={cx(\"ui-menu__item__command\", className)}\n __css={css}\n {...rest}\n />\n )\n },\n)\n\nMenuCommand.displayName = \"MenuCommand\"\nMenuCommand.__ui__ = \"MenuCommand\"\n\nconst CheckIcon: FC = () => (\n <svg height=\"1em\" viewBox=\"0 0 14 14\" width=\"1em\">\n <polygon\n fill=\"currentColor\"\n points=\"5.5 11.9993304 14 3.49933039 12.5 2 5.5 8.99933039 1.5 4.9968652 0 6.49933039\"\n />\n </svg>\n)\n"],"mappings":"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","names":["_a","id"]}
package/dist/index.js CHANGED
@@ -294,6 +294,7 @@ var isTargetMenuItem = (target) => {
294
294
  };
295
295
  var MenuItem = (0, import_core4.forwardRef)(
296
296
  ({
297
+ id,
297
298
  className,
298
299
  children,
299
300
  closeOnSelect: customCloseOnSelect,
@@ -303,7 +304,7 @@ var MenuItem = (0, import_core4.forwardRef)(
303
304
  isFocusable,
304
305
  ...props
305
306
  }, ref) => {
306
- var _a;
307
+ var _a, _b;
307
308
  const {
308
309
  closeOnSelect,
309
310
  focusedIndex,
@@ -317,14 +318,18 @@ var MenuItem = (0, import_core4.forwardRef)(
317
318
  onUpstreamClose
318
319
  } = useMenu();
319
320
  const { onUpstreamRestoreFocus } = (_a = useUpstreamMenuItem()) != null ? _a : {};
320
- const trulyDisabled = isDisabled && !isFocusable;
321
+ const [isDownstreamOpen, setDownstreamOpen] = (0, import_react3.useState)(false);
322
+ const uuid = (0, import_react3.useId)();
321
323
  const itemRef = (0, import_react3.useRef)(null);
322
324
  const hasDownstreamRef = (0, import_react3.useRef)(false);
323
325
  const onKeyDownRef = (0, import_react3.useRef)(
324
326
  () => void 0
325
327
  );
328
+ id != null ? id : id = uuid;
329
+ const trulyDisabled = isDisabled && !isFocusable;
330
+ const type = (_b = itemRef.current) == null ? void 0 : _b.getAttribute("type");
331
+ const role = !!type ? type === "checkbox" ? "menuitemcheckbox" : "menuitemradio" : "menuitem";
326
332
  const { index, register } = useMenuDescendant({ disabled: trulyDisabled });
327
- const [isDownstreamOpen, setDownstreamOpen] = (0, import_react3.useState)(false);
328
333
  const isFocused = index === focusedIndex;
329
334
  const onMouseOver = (0, import_react3.useCallback)(() => {
330
335
  if (isDisabled) return;
@@ -355,8 +360,10 @@ var MenuItem = (0, import_core4.forwardRef)(
355
360
  }, [setFocusedIndex, index]);
356
361
  const onKeyDown = (0, import_react3.useCallback)(
357
362
  (ev) => {
363
+ if (ev.key === " ") ev.key = ev.code;
358
364
  const actions = {
359
- ArrowLeft: isNested ? (0, import_utils4.funcAll)(onUpstreamRestoreFocus, onClose) : void 0
365
+ ArrowLeft: isNested ? (0, import_utils4.funcAll)(onUpstreamRestoreFocus, onClose) : void 0,
366
+ Space: !hasDownstreamRef.current ? (0, import_utils4.funcAll)(onUpstreamClose, onClose) : void 0
360
367
  };
361
368
  const action = actions[ev.key];
362
369
  if (!action) return;
@@ -364,9 +371,10 @@ var MenuItem = (0, import_core4.forwardRef)(
364
371
  ev.stopPropagation();
365
372
  action();
366
373
  },
367
- [onUpstreamRestoreFocus, onClose, isNested]
374
+ [isNested, onUpstreamRestoreFocus, onClose, onUpstreamClose]
368
375
  );
369
376
  const rest = (0, import_use_clickable.useClickable)({
377
+ clickOnSpace: false,
370
378
  focusOnClick: false,
371
379
  ...props,
372
380
  ref: (0, import_utils4.mergeRefs)(register, itemRef, ref),
@@ -380,9 +388,9 @@ var MenuItem = (0, import_core4.forwardRef)(
380
388
  });
381
389
  (0, import_utils4.useUpdateEffect)(() => {
382
390
  if (!isOpen) return;
383
- const id = requestAnimationFrameId.current;
391
+ const id2 = requestAnimationFrameId.current;
384
392
  if (isFocused && !trulyDisabled && itemRef.current) {
385
- if (id) cancelAnimationFrame(id);
393
+ if (id2) cancelAnimationFrame(id2);
386
394
  requestAnimationFrameId.current = requestAnimationFrame(() => {
387
395
  var _a2;
388
396
  (_a2 = itemRef.current) == null ? void 0 : _a2.focus({ preventScroll: true });
@@ -392,7 +400,7 @@ var MenuItem = (0, import_core4.forwardRef)(
392
400
  menuRef.current.focus({ preventScroll: true });
393
401
  }
394
402
  return () => {
395
- if (id) cancelAnimationFrame(id);
403
+ if (id2) cancelAnimationFrame(id2);
396
404
  };
397
405
  }, [isFocused, trulyDisabled, menuRef, isOpen]);
398
406
  children = icon || command ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.ui.span, { style: { flex: 1 }, children }) : children;
@@ -421,12 +429,13 @@ var MenuItem = (0, import_core4.forwardRef)(
421
429
  children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
422
430
  import_core4.ui.div,
423
431
  {
424
- ...rest,
425
- ...isDownstreamOpen ? { "data-active": "" } : {},
432
+ id,
426
433
  className: (0, import_utils4.cx)("ui-menu__item", className),
427
- role: "menuitem",
428
- tabIndex: isFocused ? 0 : -1,
434
+ "data-focus": (0, import_utils4.dataAttr)(isDownstreamOpen),
429
435
  __css: css,
436
+ ...rest,
437
+ role,
438
+ tabIndex: !isDownstreamOpen && isFocused ? 0 : -1,
430
439
  children: [
431
440
  icon ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MenuIcon, { children: icon }) : null,
432
441
  children,
@@ -447,7 +456,7 @@ var MenuOptionItem = (0, import_core4.forwardRef)(
447
456
  {
448
457
  ref,
449
458
  className: (0, import_utils4.cx)("ui-menu__item--option", className),
450
- "aria-checked": (0, import_utils4.ariaAttr)(isChecked),
459
+ "aria-checked": isChecked,
451
460
  closeOnSelect,
452
461
  ...rest,
453
462
  children: [
@@ -528,10 +537,12 @@ var MenuButton = (0, import_core5.forwardRef)(
528
537
  id != null ? id : id = uuid;
529
538
  const onKeyDown = (0, import_react4.useCallback)(
530
539
  (ev) => {
540
+ if (ev.key === " ") ev.key = ev.code;
531
541
  const actions = {
532
542
  ArrowDown: (0, import_utils5.funcAll)(onOpen, onFocusFirstItem),
533
543
  ArrowUp: (0, import_utils5.funcAll)(onOpen, onFocusLastItem),
534
- Enter: (0, import_utils5.funcAll)(onOpen, onFocusFirstItem)
544
+ Enter: (0, import_utils5.funcAll)(onOpen, onFocusFirstItem),
545
+ Space: (0, import_utils5.funcAll)(onOpen, onFocusFirstItem)
535
546
  };
536
547
  const action = actions[ev.key];
537
548
  if (!action) return;
@@ -542,9 +553,12 @@ var MenuButton = (0, import_core5.forwardRef)(
542
553
  );
543
554
  const onItemKeyDown = (0, import_react4.useCallback)(
544
555
  (ev) => {
556
+ if (ev.key === " ") ev.key = ev.code;
545
557
  const actions = {
546
558
  ArrowLeft: isOpen ? (0, import_utils5.funcAll)(onUpstreamRestoreFocus, onClose) : void 0,
547
- ArrowRight: !isOpen ? (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) : void 0
559
+ ArrowRight: !isOpen ? (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) : void 0,
560
+ Enter: !isOpen ? (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) : void 0,
561
+ Space: !isOpen ? (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) : void 0
548
562
  };
549
563
  const action = actions[ev.key];
550
564
  if (!action) return;
@@ -561,7 +575,6 @@ var MenuButton = (0, import_core5.forwardRef)(
561
575
  id,
562
576
  ref: (0, import_utils5.mergeRefs)(buttonRef, ref),
563
577
  className: (0, import_utils5.cx)("ui-menu", className),
564
- "aria-expanded": isOpen,
565
578
  "aria-haspopup": "menu",
566
579
  ...rest,
567
580
  "data-active": (0, import_utils5.dataAttr)(isOpen),
@@ -675,8 +688,8 @@ var import_utils8 = require("@yamada-ui/utils");
675
688
  var import_react6 = require("react");
676
689
  var import_jsx_runtime8 = require("react/jsx-runtime");
677
690
  var MenuList = (0, import_core8.forwardRef)(
678
- ({ className, children, contentProps, ...rest }, ref) => {
679
- var _a;
691
+ ({ id, className, children, contentProps, ...rest }, ref) => {
692
+ var _a, _b;
680
693
  const {
681
694
  buttonRef,
682
695
  focusedIndex,
@@ -685,7 +698,10 @@ var MenuList = (0, import_core8.forwardRef)(
685
698
  styles,
686
699
  onClose
687
700
  } = useMenu();
701
+ const uuid = (0, import_react6.useId)();
702
+ id != null ? id : id = uuid;
688
703
  const descendants = useMenuDescendantsContext();
704
+ const activedescendantId = (_a = descendants.value(focusedIndex)) == null ? void 0 : _a.node.id;
689
705
  const onNext = (0, import_react6.useCallback)(() => {
690
706
  const next = descendants.enabledNextValue(focusedIndex);
691
707
  if (next) setFocusedIndex(next.index);
@@ -710,7 +726,7 @@ var MenuList = (0, import_core8.forwardRef)(
710
726
  End: onLast,
711
727
  Escape: onClose,
712
728
  Home: onFirst,
713
- Tab: (ev2) => ev2.preventDefault()
729
+ Tab: onClose
714
730
  };
715
731
  const action = actions[ev.key];
716
732
  if (!action) return;
@@ -722,8 +738,12 @@ var MenuList = (0, import_core8.forwardRef)(
722
738
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
723
739
  import_popover4.PopoverContent,
724
740
  {
741
+ id,
725
742
  as: "div",
726
743
  className: "ui-menu__content",
744
+ "aria-activedescendant": activedescendantId,
745
+ "aria-labelledby": (_b = buttonRef.current) == null ? void 0 : _b.id,
746
+ role: "menu",
727
747
  __css: { ...styles.content },
728
748
  ...contentProps,
729
749
  onKeyDown: (0, import_utils8.handlerAll)(contentProps == null ? void 0 : contentProps.onKeyDown, onKeyDown),
@@ -732,8 +752,6 @@ var MenuList = (0, import_core8.forwardRef)(
732
752
  {
733
753
  ref: (0, import_utils8.mergeRefs)(menuRef, ref),
734
754
  className: (0, import_utils8.cx)("ui-menu__list", className),
735
- "aria-labelledby": (_a = buttonRef.current) == null ? void 0 : _a.id,
736
- role: "menu",
737
755
  tabIndex: -1,
738
756
  __css: { ...styles.list },
739
757
  ...rest,