@yamada-ui/menu 0.1.12 → 0.2.0
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/chunk-4VY7HO44.mjs +70 -0
- package/dist/chunk-562FLKUK.mjs +32 -0
- package/dist/chunk-FLFY6YIF.mjs +59 -0
- package/dist/chunk-IWMBG2LC.mjs +59 -0
- package/dist/chunk-MIXRGNW3.mjs +168 -0
- package/dist/chunk-VMGROBTU.mjs +17 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -8
- package/dist/index.mjs +18 -14
- package/dist/menu-button.mjs +1 -1
- package/dist/menu-divider.mjs +1 -1
- package/dist/menu-group.mjs +1 -1
- package/dist/menu-item.d.ts +35 -0
- package/dist/menu-item.mjs +1 -1
- package/dist/menu-list.mjs +1 -1
- package/dist/menu-option-group.d.ts +14 -0
- package/dist/menu-option-group.js +49 -49
- package/dist/menu-option-group.mjs +3 -1
- package/dist/menu.d.ts +5 -0
- package/package.json +6 -6
- package/dist/chunk-OXXUVU6S.mjs +0 -374
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMenu,
|
|
3
|
+
useMenuDescendantsContext
|
|
4
|
+
} from "./chunk-6ALPY7K4.mjs";
|
|
5
|
+
|
|
6
|
+
// src/menu-list.tsx
|
|
7
|
+
import { forwardRef } from "@yamada-ui/core";
|
|
8
|
+
import { PopoverContent } from "@yamada-ui/popover";
|
|
9
|
+
import { cx, handlerAll, mergeRefs } from "@yamada-ui/utils";
|
|
10
|
+
import { useCallback } from "react";
|
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
|
12
|
+
var MenuList = forwardRef(({ className, ...rest }, ref) => {
|
|
13
|
+
const { menuRef, focusedIndex, setFocusedIndex, onClose, styles } = useMenu();
|
|
14
|
+
const descendants = useMenuDescendantsContext();
|
|
15
|
+
const onNext = useCallback(() => {
|
|
16
|
+
const next = descendants.enabledNextValue(focusedIndex);
|
|
17
|
+
if (next)
|
|
18
|
+
setFocusedIndex(next.index);
|
|
19
|
+
}, [descendants, focusedIndex, setFocusedIndex]);
|
|
20
|
+
const onPrev = useCallback(() => {
|
|
21
|
+
const prev = descendants.enabledPrevValue(focusedIndex);
|
|
22
|
+
if (prev)
|
|
23
|
+
setFocusedIndex(prev.index);
|
|
24
|
+
}, [descendants, focusedIndex, setFocusedIndex]);
|
|
25
|
+
const onFirst = useCallback(() => {
|
|
26
|
+
const first = descendants.enabledfirstValue();
|
|
27
|
+
if (first)
|
|
28
|
+
setFocusedIndex(first.index);
|
|
29
|
+
}, [descendants, setFocusedIndex]);
|
|
30
|
+
const onLast = useCallback(() => {
|
|
31
|
+
const last = descendants.enabledlastValue();
|
|
32
|
+
if (last)
|
|
33
|
+
setFocusedIndex(last.index);
|
|
34
|
+
}, [descendants, setFocusedIndex]);
|
|
35
|
+
const onKeyDown = useCallback(
|
|
36
|
+
(ev) => {
|
|
37
|
+
const actions = {
|
|
38
|
+
Tab: (ev2) => ev2.preventDefault(),
|
|
39
|
+
Escape: onClose,
|
|
40
|
+
ArrowDown: focusedIndex === -1 ? onFirst : onNext,
|
|
41
|
+
ArrowUp: focusedIndex === -1 ? onLast : onPrev,
|
|
42
|
+
Home: onFirst,
|
|
43
|
+
End: onLast
|
|
44
|
+
};
|
|
45
|
+
const action = actions[ev.key];
|
|
46
|
+
if (!action)
|
|
47
|
+
return;
|
|
48
|
+
ev.preventDefault();
|
|
49
|
+
action(ev);
|
|
50
|
+
},
|
|
51
|
+
[focusedIndex, onClose, onFirst, onLast, onNext, onPrev]
|
|
52
|
+
);
|
|
53
|
+
const css = { ...styles.list };
|
|
54
|
+
return /* @__PURE__ */ jsx(
|
|
55
|
+
PopoverContent,
|
|
56
|
+
{
|
|
57
|
+
ref: mergeRefs(menuRef, ref),
|
|
58
|
+
className: cx("ui-menu-list", className),
|
|
59
|
+
role: "menu",
|
|
60
|
+
tabIndex: -1,
|
|
61
|
+
__css: css,
|
|
62
|
+
...rest,
|
|
63
|
+
onKeyDown: handlerAll(rest.onKeyDown, onKeyDown)
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
MenuList
|
|
70
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMenu
|
|
3
|
+
} from "./chunk-6ALPY7K4.mjs";
|
|
4
|
+
|
|
5
|
+
// src/menu-group.tsx
|
|
6
|
+
import { ui, forwardRef } from "@yamada-ui/core";
|
|
7
|
+
import { cx } from "@yamada-ui/utils";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
var MenuGroup = forwardRef(
|
|
10
|
+
({ className, title, children, ...rest }, ref) => {
|
|
11
|
+
const { styles } = useMenu();
|
|
12
|
+
const css = { ...styles.group };
|
|
13
|
+
return /* @__PURE__ */ jsxs(
|
|
14
|
+
ui.div,
|
|
15
|
+
{
|
|
16
|
+
ref,
|
|
17
|
+
className: cx("ui-menu-group", className),
|
|
18
|
+
role: "group",
|
|
19
|
+
__css: css,
|
|
20
|
+
...rest,
|
|
21
|
+
children: [
|
|
22
|
+
title ? /* @__PURE__ */ jsx(ui.span, { className: cx("ui-menu-group-title"), __css: styles.groupTitle, children: title }) : null,
|
|
23
|
+
children
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
MenuGroup
|
|
32
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MenuGroup
|
|
3
|
+
} from "./chunk-562FLKUK.mjs";
|
|
4
|
+
import {
|
|
5
|
+
MenuOptionItem
|
|
6
|
+
} from "./chunk-MIXRGNW3.mjs";
|
|
7
|
+
|
|
8
|
+
// src/menu-option-group.tsx
|
|
9
|
+
import { useControllableState } from "@yamada-ui/use-controllable-state";
|
|
10
|
+
import { cx, getValidChildren, omitObject, isArray } from "@yamada-ui/utils";
|
|
11
|
+
import { cloneElement, forwardRef, useCallback } from "react";
|
|
12
|
+
import { jsx } from "react/jsx-runtime";
|
|
13
|
+
var MenuOptionGroup = forwardRef(
|
|
14
|
+
({ className, defaultValue, type, children, ...rest }, ref) => {
|
|
15
|
+
const isRadio = type === "radio";
|
|
16
|
+
defaultValue = isRadio ? "" : [];
|
|
17
|
+
const [value, setValue] = useControllableState({
|
|
18
|
+
...rest,
|
|
19
|
+
defaultValue
|
|
20
|
+
});
|
|
21
|
+
const onChange = useCallback(
|
|
22
|
+
(selectedValue) => {
|
|
23
|
+
if (isRadio && typeof value === "string")
|
|
24
|
+
setValue(selectedValue);
|
|
25
|
+
if (!isRadio && isArray(value)) {
|
|
26
|
+
const nextValue = value.includes(selectedValue) ? value.filter((item) => item !== selectedValue) : value.concat(selectedValue);
|
|
27
|
+
setValue(nextValue);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
[isRadio, value, setValue]
|
|
31
|
+
);
|
|
32
|
+
const validChildren = getValidChildren(children);
|
|
33
|
+
const cloneChildren = validChildren.map((child) => {
|
|
34
|
+
if (child.type !== MenuOptionItem)
|
|
35
|
+
return child;
|
|
36
|
+
const onClick = (ev) => {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
onChange(child.props.value);
|
|
39
|
+
(_b = (_a = child.props).onClick) == null ? void 0 : _b.call(_a, ev);
|
|
40
|
+
};
|
|
41
|
+
const isChecked = !isRadio && isArray(value) ? value.includes(child.props.value) : child.props.value === value;
|
|
42
|
+
return cloneElement(child, { type, onClick, isChecked });
|
|
43
|
+
});
|
|
44
|
+
return /* @__PURE__ */ jsx(
|
|
45
|
+
MenuGroup,
|
|
46
|
+
{
|
|
47
|
+
ref,
|
|
48
|
+
className: cx("ui-menu-option-group", className),
|
|
49
|
+
...omitObject(rest, ["value", "onChange"]),
|
|
50
|
+
children: cloneChildren
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
MenuOptionGroup.displayName = "MenuOptionGroup";
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
MenuOptionGroup
|
|
59
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMenu
|
|
3
|
+
} from "./chunk-6ALPY7K4.mjs";
|
|
4
|
+
|
|
5
|
+
// src/menu-button.tsx
|
|
6
|
+
import { ui, forwardRef } from "@yamada-ui/core";
|
|
7
|
+
import { PopoverTrigger } from "@yamada-ui/popover";
|
|
8
|
+
import { ariaAttr, cx, dataAttr, funcAll, handlerAll } from "@yamada-ui/utils";
|
|
9
|
+
import { useCallback } from "react";
|
|
10
|
+
import { jsx } from "react/jsx-runtime";
|
|
11
|
+
var MenuButton = forwardRef(
|
|
12
|
+
({ className, children, as: As, ...rest }, ref) => {
|
|
13
|
+
const { isOpen, onOpen, onFocusFirstItem, onFocusLastItem } = useMenu();
|
|
14
|
+
const onKeyDown = useCallback(
|
|
15
|
+
(ev) => {
|
|
16
|
+
const actions = {
|
|
17
|
+
Enter: funcAll(onOpen, onFocusFirstItem),
|
|
18
|
+
ArrowDown: funcAll(onOpen, onFocusFirstItem),
|
|
19
|
+
ArrowUp: funcAll(onOpen, onFocusLastItem)
|
|
20
|
+
};
|
|
21
|
+
const action = actions[ev.key];
|
|
22
|
+
if (!action)
|
|
23
|
+
return;
|
|
24
|
+
ev.preventDefault();
|
|
25
|
+
ev.stopPropagation();
|
|
26
|
+
action();
|
|
27
|
+
},
|
|
28
|
+
[onFocusFirstItem, onFocusLastItem, onOpen]
|
|
29
|
+
);
|
|
30
|
+
const Component = As || Button;
|
|
31
|
+
return /* @__PURE__ */ jsx(PopoverTrigger, { children: /* @__PURE__ */ jsx(
|
|
32
|
+
Component,
|
|
33
|
+
{
|
|
34
|
+
ref,
|
|
35
|
+
className: cx("ui-menu-button", className),
|
|
36
|
+
...rest,
|
|
37
|
+
"data-active": dataAttr(isOpen),
|
|
38
|
+
"aria-expanded": ariaAttr(isOpen),
|
|
39
|
+
onKeyDown: handlerAll(rest.onKeyDown, onKeyDown),
|
|
40
|
+
children: /* @__PURE__ */ jsx(ui.span, { __css: { pointerEvents: "none", flex: "1 1 auto", minW: 0 }, children })
|
|
41
|
+
}
|
|
42
|
+
) });
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
var Button = forwardRef((rest, ref) => {
|
|
46
|
+
const { styles } = useMenu();
|
|
47
|
+
const css = {
|
|
48
|
+
display: "inline-flex",
|
|
49
|
+
appearance: "none",
|
|
50
|
+
alignItems: "center",
|
|
51
|
+
outline: 0,
|
|
52
|
+
...styles.button
|
|
53
|
+
};
|
|
54
|
+
return /* @__PURE__ */ jsx(ui.button, { ref, __css: css, ...rest });
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
MenuButton
|
|
59
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMenu,
|
|
3
|
+
useMenuDescendant
|
|
4
|
+
} from "./chunk-6ALPY7K4.mjs";
|
|
5
|
+
|
|
6
|
+
// src/menu-item.tsx
|
|
7
|
+
import { ui, forwardRef } from "@yamada-ui/core";
|
|
8
|
+
import { useClickable } from "@yamada-ui/use-clickable";
|
|
9
|
+
import {
|
|
10
|
+
ariaAttr,
|
|
11
|
+
cx,
|
|
12
|
+
isActiveElement,
|
|
13
|
+
isHTMLElement,
|
|
14
|
+
mergeRefs,
|
|
15
|
+
useUpdateEffect
|
|
16
|
+
} from "@yamada-ui/utils";
|
|
17
|
+
import { useCallback, useRef } from "react";
|
|
18
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
var isTargetMenuItem = (target) => {
|
|
20
|
+
var _a;
|
|
21
|
+
return isHTMLElement(target) && !!((_a = target == null ? void 0 : target.getAttribute("role")) == null ? void 0 : _a.startsWith("menu-item"));
|
|
22
|
+
};
|
|
23
|
+
var MenuItem = forwardRef(
|
|
24
|
+
({
|
|
25
|
+
as,
|
|
26
|
+
className,
|
|
27
|
+
type,
|
|
28
|
+
isDisabled,
|
|
29
|
+
isFocusable,
|
|
30
|
+
closeOnSelect: customCloseOnSelect,
|
|
31
|
+
icon,
|
|
32
|
+
command,
|
|
33
|
+
children,
|
|
34
|
+
...props
|
|
35
|
+
}, ref) => {
|
|
36
|
+
const {
|
|
37
|
+
focusedIndex,
|
|
38
|
+
setFocusedIndex,
|
|
39
|
+
isOpen,
|
|
40
|
+
onClose,
|
|
41
|
+
closeOnSelect: generalCloseOnSelect,
|
|
42
|
+
menuRef,
|
|
43
|
+
styles
|
|
44
|
+
} = useMenu();
|
|
45
|
+
const trulyDisabled = isDisabled && !isFocusable;
|
|
46
|
+
const buttonRef = useRef(null);
|
|
47
|
+
const { index, register } = useMenuDescendant({ disabled: trulyDisabled });
|
|
48
|
+
const isFocused = index === focusedIndex;
|
|
49
|
+
const onClick = useCallback(
|
|
50
|
+
(ev) => {
|
|
51
|
+
var _a;
|
|
52
|
+
(_a = props.onClick) == null ? void 0 : _a.call(props, ev);
|
|
53
|
+
if (!isTargetMenuItem(ev.currentTarget))
|
|
54
|
+
return;
|
|
55
|
+
if (customCloseOnSelect != null ? customCloseOnSelect : generalCloseOnSelect)
|
|
56
|
+
onClose();
|
|
57
|
+
},
|
|
58
|
+
[props, customCloseOnSelect, generalCloseOnSelect, onClose]
|
|
59
|
+
);
|
|
60
|
+
const onFocus = useCallback(
|
|
61
|
+
(ev) => {
|
|
62
|
+
var _a;
|
|
63
|
+
(_a = props.onFocus) == null ? void 0 : _a.call(props, ev);
|
|
64
|
+
setFocusedIndex(index);
|
|
65
|
+
},
|
|
66
|
+
[props, setFocusedIndex, index]
|
|
67
|
+
);
|
|
68
|
+
const rest = useClickable({
|
|
69
|
+
onClick,
|
|
70
|
+
onFocus,
|
|
71
|
+
ref: mergeRefs(register, buttonRef, ref),
|
|
72
|
+
isDisabled,
|
|
73
|
+
isFocusable
|
|
74
|
+
});
|
|
75
|
+
useUpdateEffect(() => {
|
|
76
|
+
if (!isOpen)
|
|
77
|
+
return;
|
|
78
|
+
if (isFocused && !trulyDisabled && buttonRef.current) {
|
|
79
|
+
requestAnimationFrame(() => {
|
|
80
|
+
var _a;
|
|
81
|
+
return (_a = buttonRef.current) == null ? void 0 : _a.focus();
|
|
82
|
+
});
|
|
83
|
+
} else if (menuRef.current && !isActiveElement(menuRef.current)) {
|
|
84
|
+
menuRef.current.focus();
|
|
85
|
+
}
|
|
86
|
+
}, [isFocused, trulyDisabled, menuRef, isOpen]);
|
|
87
|
+
type = as || type ? type != null ? type : void 0 : "button";
|
|
88
|
+
children = icon || command ? /* @__PURE__ */ jsx(ui.span, { style: { pointerEvents: "none", flex: 1 }, children }) : children;
|
|
89
|
+
const css = {
|
|
90
|
+
textDecoration: "none",
|
|
91
|
+
color: "inherit",
|
|
92
|
+
userSelect: "none",
|
|
93
|
+
display: "flex",
|
|
94
|
+
width: "100%",
|
|
95
|
+
alignItems: "center",
|
|
96
|
+
textAlign: "start",
|
|
97
|
+
flex: "0 0 auto",
|
|
98
|
+
outline: 0,
|
|
99
|
+
gap: "0.75rem",
|
|
100
|
+
...styles.item
|
|
101
|
+
};
|
|
102
|
+
return /* @__PURE__ */ jsxs(
|
|
103
|
+
ui.button,
|
|
104
|
+
{
|
|
105
|
+
...props,
|
|
106
|
+
...rest,
|
|
107
|
+
as,
|
|
108
|
+
type,
|
|
109
|
+
role: "menu-item",
|
|
110
|
+
tabIndex: isFocused ? 0 : -1,
|
|
111
|
+
className: cx("ui-menu-item", className),
|
|
112
|
+
__css: css,
|
|
113
|
+
children: [
|
|
114
|
+
icon ? /* @__PURE__ */ jsx(MenuIcon, { children: icon }) : null,
|
|
115
|
+
children,
|
|
116
|
+
command ? /* @__PURE__ */ jsx(MenuCommand, { children: command }) : null
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
var MenuOptionItem = forwardRef(
|
|
123
|
+
({ className, icon, isChecked, closeOnSelect = false, children, ...rest }, ref) => {
|
|
124
|
+
return /* @__PURE__ */ jsxs(
|
|
125
|
+
MenuItem,
|
|
126
|
+
{
|
|
127
|
+
ref,
|
|
128
|
+
className: cx("ui-menu-option-item", className),
|
|
129
|
+
"aria-checked": ariaAttr(isChecked),
|
|
130
|
+
closeOnSelect,
|
|
131
|
+
...rest,
|
|
132
|
+
children: [
|
|
133
|
+
icon !== null ? /* @__PURE__ */ jsx(MenuIcon, { opacity: isChecked ? 1 : 0, children: icon || /* @__PURE__ */ jsx(CheckIcon, {}) }) : null,
|
|
134
|
+
children
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
var MenuIcon = forwardRef(({ className, ...rest }, ref) => {
|
|
141
|
+
const { styles } = useMenu();
|
|
142
|
+
const css = {
|
|
143
|
+
flexShrink: 0,
|
|
144
|
+
display: "inline-flex",
|
|
145
|
+
justifyContent: "center",
|
|
146
|
+
alignItems: "center",
|
|
147
|
+
fontSize: "0.85em",
|
|
148
|
+
...styles.icon
|
|
149
|
+
};
|
|
150
|
+
return /* @__PURE__ */ jsx(ui.span, { ref, className: cx("ui-menu-icon", className), __css: css, ...rest });
|
|
151
|
+
});
|
|
152
|
+
var MenuCommand = forwardRef(({ className, ...rest }, ref) => {
|
|
153
|
+
const { styles } = useMenu();
|
|
154
|
+
const css = { ...styles.command };
|
|
155
|
+
return /* @__PURE__ */ jsx(ui.span, { ref, className: cx("ui-menu-command", className), __css: css, ...rest });
|
|
156
|
+
});
|
|
157
|
+
var CheckIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 14 14", width: "1em", height: "1em", children: /* @__PURE__ */ jsx(
|
|
158
|
+
"polygon",
|
|
159
|
+
{
|
|
160
|
+
fill: "currentColor",
|
|
161
|
+
points: "5.5 11.9993304 14 3.49933039 12.5 2 5.5 8.99933039 1.5 4.9968652 0 6.49933039"
|
|
162
|
+
}
|
|
163
|
+
) });
|
|
164
|
+
|
|
165
|
+
export {
|
|
166
|
+
MenuItem,
|
|
167
|
+
MenuOptionItem
|
|
168
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useMenu
|
|
3
|
+
} from "./chunk-6ALPY7K4.mjs";
|
|
4
|
+
|
|
5
|
+
// src/menu-divider.tsx
|
|
6
|
+
import { ui, forwardRef } from "@yamada-ui/core";
|
|
7
|
+
import { cx } from "@yamada-ui/utils";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
var MenuDivider = forwardRef(({ className, ...rest }, ref) => {
|
|
10
|
+
const { styles } = useMenu();
|
|
11
|
+
const css = { ...styles.divider };
|
|
12
|
+
return /* @__PURE__ */ jsx(ui.hr, { ref, className: cx("ui-menu-divider", className), __css: css, ...rest });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
MenuDivider
|
|
17
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Menu, MenuProps
|
|
1
|
+
export { Menu, MenuProps } from './menu.js';
|
|
2
2
|
export { MenuButton, MenuButtonProps } from './menu-button.js';
|
|
3
3
|
export { MenuList, MenuListProps } from './menu-list.js';
|
|
4
4
|
export { MenuItem, MenuItemProps, MenuOptionItem, MenuOptionItemProps } from './menu-item.js';
|
package/dist/index.js
CHANGED
|
@@ -27,10 +27,7 @@ __export(src_exports, {
|
|
|
27
27
|
MenuItem: () => MenuItem,
|
|
28
28
|
MenuList: () => MenuList,
|
|
29
29
|
MenuOptionGroup: () => MenuOptionGroup,
|
|
30
|
-
MenuOptionItem: () => MenuOptionItem
|
|
31
|
-
useMenu: () => useMenu,
|
|
32
|
-
useMenuDescendant: () => useMenuDescendant,
|
|
33
|
-
useMenuDescendantsContext: () => useMenuDescendantsContext
|
|
30
|
+
MenuOptionItem: () => MenuOptionItem
|
|
34
31
|
});
|
|
35
32
|
module.exports = __toCommonJS(src_exports);
|
|
36
33
|
|
|
@@ -497,8 +494,5 @@ var MenuDivider = (0, import_core6.forwardRef)(({ className, ...rest }, ref) =>
|
|
|
497
494
|
MenuItem,
|
|
498
495
|
MenuList,
|
|
499
496
|
MenuOptionGroup,
|
|
500
|
-
MenuOptionItem
|
|
501
|
-
useMenu,
|
|
502
|
-
useMenuDescendant,
|
|
503
|
-
useMenuDescendantsContext
|
|
497
|
+
MenuOptionItem
|
|
504
498
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
|
-
MenuButton
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
MenuButton
|
|
3
|
+
} from "./chunk-IWMBG2LC.mjs";
|
|
4
|
+
import {
|
|
5
|
+
MenuDivider
|
|
6
|
+
} from "./chunk-VMGROBTU.mjs";
|
|
7
|
+
import {
|
|
8
|
+
MenuList
|
|
9
|
+
} from "./chunk-4VY7HO44.mjs";
|
|
10
|
+
import {
|
|
11
|
+
MenuOptionGroup
|
|
12
|
+
} from "./chunk-FLFY6YIF.mjs";
|
|
13
|
+
import {
|
|
14
|
+
MenuGroup
|
|
15
|
+
} from "./chunk-562FLKUK.mjs";
|
|
16
|
+
import {
|
|
5
17
|
MenuItem,
|
|
6
|
-
MenuList,
|
|
7
|
-
MenuOptionGroup,
|
|
8
18
|
MenuOptionItem
|
|
9
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-MIXRGNW3.mjs";
|
|
10
20
|
import {
|
|
11
|
-
Menu
|
|
12
|
-
useMenu,
|
|
13
|
-
useMenuDescendant,
|
|
14
|
-
useMenuDescendantsContext
|
|
21
|
+
Menu
|
|
15
22
|
} from "./chunk-6ALPY7K4.mjs";
|
|
16
23
|
export {
|
|
17
24
|
Menu,
|
|
@@ -21,8 +28,5 @@ export {
|
|
|
21
28
|
MenuItem,
|
|
22
29
|
MenuList,
|
|
23
30
|
MenuOptionGroup,
|
|
24
|
-
MenuOptionItem
|
|
25
|
-
useMenu,
|
|
26
|
-
useMenuDescendant,
|
|
27
|
-
useMenuDescendantsContext
|
|
31
|
+
MenuOptionItem
|
|
28
32
|
};
|
package/dist/menu-button.mjs
CHANGED
package/dist/menu-divider.mjs
CHANGED
package/dist/menu-group.mjs
CHANGED
package/dist/menu-item.d.ts
CHANGED
|
@@ -3,18 +3,53 @@ import { HTMLUIProps } from '@yamada-ui/core';
|
|
|
3
3
|
import { ReactElement } from 'react';
|
|
4
4
|
|
|
5
5
|
type MenuItemOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* If `true`, the menu item will be disabled.
|
|
8
|
+
*
|
|
9
|
+
* @default false
|
|
10
|
+
*/
|
|
6
11
|
isDisabled?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* If `true`, the menu item will be focusable.
|
|
14
|
+
*
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
7
17
|
isFocusable?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* If `true`, the list element will be closed when selected.
|
|
20
|
+
*
|
|
21
|
+
* @default false
|
|
22
|
+
*/
|
|
8
23
|
closeOnSelect?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The menu item icon to use.
|
|
26
|
+
*/
|
|
9
27
|
icon?: ReactElement;
|
|
28
|
+
/**
|
|
29
|
+
* Right-aligned label text content, useful for displaying hotkeys.
|
|
30
|
+
*/
|
|
10
31
|
command?: string;
|
|
11
32
|
};
|
|
12
33
|
type MenuItemProps = HTMLUIProps<'button'> & MenuItemOptions;
|
|
13
34
|
declare const MenuItem: _yamada_ui_core.Component<"button", MenuItemProps>;
|
|
14
35
|
type MenuOptionItemOptions = {
|
|
36
|
+
/**
|
|
37
|
+
* The menu option item icon to use.
|
|
38
|
+
*/
|
|
15
39
|
icon?: ReactElement | null;
|
|
40
|
+
/**
|
|
41
|
+
* The value of the menu option item.
|
|
42
|
+
*/
|
|
16
43
|
value?: string;
|
|
44
|
+
/**
|
|
45
|
+
* If `true`, the checkbox or radio will be checked.
|
|
46
|
+
*
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
17
49
|
isChecked?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* The type of the menu option item.
|
|
52
|
+
*/
|
|
18
53
|
type?: 'radio' | 'checkbox';
|
|
19
54
|
};
|
|
20
55
|
type MenuOptionItemProps = Omit<MenuItemProps, 'icon' | 'command'> & MenuOptionItemOptions;
|
package/dist/menu-item.mjs
CHANGED
package/dist/menu-list.mjs
CHANGED
|
@@ -2,9 +2,23 @@ import { HTMLUIProps, ComponentArgs } from '@yamada-ui/core';
|
|
|
2
2
|
import { Ref } from 'react';
|
|
3
3
|
|
|
4
4
|
type MenuOptionGroupOptions<Y extends string | string[] = string> = {
|
|
5
|
+
/**
|
|
6
|
+
* The value of the menu item group.
|
|
7
|
+
*/
|
|
5
8
|
value?: Y;
|
|
9
|
+
/**
|
|
10
|
+
* The initial value of the menu item group.
|
|
11
|
+
*/
|
|
6
12
|
defaultValue?: Y;
|
|
13
|
+
/**
|
|
14
|
+
* The type of the menu option group.
|
|
15
|
+
*
|
|
16
|
+
* @default 'checkbox'
|
|
17
|
+
*/
|
|
7
18
|
type?: 'radio' | 'checkbox';
|
|
19
|
+
/**
|
|
20
|
+
* The callback fired when any children checkbox is checked or unchecked.
|
|
21
|
+
*/
|
|
8
22
|
onChange?: (value: Y) => void;
|
|
9
23
|
};
|
|
10
24
|
type MenuOptionGroupProps<Y extends string | string[] = string> = Omit<HTMLUIProps<'div'>, keyof MenuOptionGroupOptions> & MenuOptionGroupOptions<Y>;
|
|
@@ -28,8 +28,8 @@ var import_utils4 = require("@yamada-ui/utils");
|
|
|
28
28
|
var import_react3 = require("react");
|
|
29
29
|
|
|
30
30
|
// src/menu-group.tsx
|
|
31
|
-
var
|
|
32
|
-
var
|
|
31
|
+
var import_core2 = require("@yamada-ui/core");
|
|
32
|
+
var import_utils2 = require("@yamada-ui/utils");
|
|
33
33
|
|
|
34
34
|
// src/menu.tsx
|
|
35
35
|
var import_core = require("@yamada-ui/core");
|
|
@@ -50,17 +50,40 @@ var [MenuProvider, useMenu] = (0, import_utils.createContext)({
|
|
|
50
50
|
errorMessage: `useMenu returned is 'undefined'. Seems you forgot to wrap the components in "<Menu />"`
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
// src/menu-group.tsx
|
|
54
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
55
|
+
var MenuGroup = (0, import_core2.forwardRef)(
|
|
56
|
+
({ className, title, children, ...rest }, ref) => {
|
|
57
|
+
const { styles } = useMenu();
|
|
58
|
+
const css = { ...styles.group };
|
|
59
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
60
|
+
import_core2.ui.div,
|
|
61
|
+
{
|
|
62
|
+
ref,
|
|
63
|
+
className: (0, import_utils2.cx)("ui-menu-group", className),
|
|
64
|
+
role: "group",
|
|
65
|
+
__css: css,
|
|
66
|
+
...rest,
|
|
67
|
+
children: [
|
|
68
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core2.ui.span, { className: (0, import_utils2.cx)("ui-menu-group-title"), __css: styles.groupTitle, children: title }) : null,
|
|
69
|
+
children
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
|
|
53
76
|
// src/menu-item.tsx
|
|
54
|
-
var
|
|
77
|
+
var import_core3 = require("@yamada-ui/core");
|
|
55
78
|
var import_use_clickable = require("@yamada-ui/use-clickable");
|
|
56
|
-
var
|
|
79
|
+
var import_utils3 = require("@yamada-ui/utils");
|
|
57
80
|
var import_react2 = require("react");
|
|
58
|
-
var
|
|
81
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
59
82
|
var isTargetMenuItem = (target) => {
|
|
60
83
|
var _a;
|
|
61
|
-
return (0,
|
|
84
|
+
return (0, import_utils3.isHTMLElement)(target) && !!((_a = target == null ? void 0 : target.getAttribute("role")) == null ? void 0 : _a.startsWith("menu-item"));
|
|
62
85
|
};
|
|
63
|
-
var MenuItem = (0,
|
|
86
|
+
var MenuItem = (0, import_core3.forwardRef)(
|
|
64
87
|
({
|
|
65
88
|
as,
|
|
66
89
|
className,
|
|
@@ -108,11 +131,11 @@ var MenuItem = (0, import_core2.forwardRef)(
|
|
|
108
131
|
const rest = (0, import_use_clickable.useClickable)({
|
|
109
132
|
onClick,
|
|
110
133
|
onFocus,
|
|
111
|
-
ref: (0,
|
|
134
|
+
ref: (0, import_utils3.mergeRefs)(register, buttonRef, ref),
|
|
112
135
|
isDisabled,
|
|
113
136
|
isFocusable
|
|
114
137
|
});
|
|
115
|
-
(0,
|
|
138
|
+
(0, import_utils3.useUpdateEffect)(() => {
|
|
116
139
|
if (!isOpen)
|
|
117
140
|
return;
|
|
118
141
|
if (isFocused && !trulyDisabled && buttonRef.current) {
|
|
@@ -120,12 +143,12 @@ var MenuItem = (0, import_core2.forwardRef)(
|
|
|
120
143
|
var _a;
|
|
121
144
|
return (_a = buttonRef.current) == null ? void 0 : _a.focus();
|
|
122
145
|
});
|
|
123
|
-
} else if (menuRef.current && !(0,
|
|
146
|
+
} else if (menuRef.current && !(0, import_utils3.isActiveElement)(menuRef.current)) {
|
|
124
147
|
menuRef.current.focus();
|
|
125
148
|
}
|
|
126
149
|
}, [isFocused, trulyDisabled, menuRef, isOpen]);
|
|
127
150
|
type = as || type ? type != null ? type : void 0 : "button";
|
|
128
|
-
children = icon || command ? /* @__PURE__ */ (0,
|
|
151
|
+
children = icon || command ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.ui.span, { style: { pointerEvents: "none", flex: 1 }, children }) : children;
|
|
129
152
|
const css = {
|
|
130
153
|
textDecoration: "none",
|
|
131
154
|
color: "inherit",
|
|
@@ -139,8 +162,8 @@ var MenuItem = (0, import_core2.forwardRef)(
|
|
|
139
162
|
gap: "0.75rem",
|
|
140
163
|
...styles.item
|
|
141
164
|
};
|
|
142
|
-
return /* @__PURE__ */ (0,
|
|
143
|
-
|
|
165
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
166
|
+
import_core3.ui.button,
|
|
144
167
|
{
|
|
145
168
|
...props,
|
|
146
169
|
...rest,
|
|
@@ -148,36 +171,36 @@ var MenuItem = (0, import_core2.forwardRef)(
|
|
|
148
171
|
type,
|
|
149
172
|
role: "menu-item",
|
|
150
173
|
tabIndex: isFocused ? 0 : -1,
|
|
151
|
-
className: (0,
|
|
174
|
+
className: (0, import_utils3.cx)("ui-menu-item", className),
|
|
152
175
|
__css: css,
|
|
153
176
|
children: [
|
|
154
|
-
icon ? /* @__PURE__ */ (0,
|
|
177
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MenuIcon, { children: icon }) : null,
|
|
155
178
|
children,
|
|
156
|
-
command ? /* @__PURE__ */ (0,
|
|
179
|
+
command ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MenuCommand, { children: command }) : null
|
|
157
180
|
]
|
|
158
181
|
}
|
|
159
182
|
);
|
|
160
183
|
}
|
|
161
184
|
);
|
|
162
|
-
var MenuOptionItem = (0,
|
|
185
|
+
var MenuOptionItem = (0, import_core3.forwardRef)(
|
|
163
186
|
({ className, icon, isChecked, closeOnSelect = false, children, ...rest }, ref) => {
|
|
164
|
-
return /* @__PURE__ */ (0,
|
|
187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
165
188
|
MenuItem,
|
|
166
189
|
{
|
|
167
190
|
ref,
|
|
168
|
-
className: (0,
|
|
169
|
-
"aria-checked": (0,
|
|
191
|
+
className: (0, import_utils3.cx)("ui-menu-option-item", className),
|
|
192
|
+
"aria-checked": (0, import_utils3.ariaAttr)(isChecked),
|
|
170
193
|
closeOnSelect,
|
|
171
194
|
...rest,
|
|
172
195
|
children: [
|
|
173
|
-
icon !== null ? /* @__PURE__ */ (0,
|
|
196
|
+
icon !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MenuIcon, { opacity: isChecked ? 1 : 0, children: icon || /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CheckIcon, {}) }) : null,
|
|
174
197
|
children
|
|
175
198
|
]
|
|
176
199
|
}
|
|
177
200
|
);
|
|
178
201
|
}
|
|
179
202
|
);
|
|
180
|
-
var MenuIcon = (0,
|
|
203
|
+
var MenuIcon = (0, import_core3.forwardRef)(({ className, ...rest }, ref) => {
|
|
181
204
|
const { styles } = useMenu();
|
|
182
205
|
const css = {
|
|
183
206
|
flexShrink: 0,
|
|
@@ -187,14 +210,14 @@ var MenuIcon = (0, import_core2.forwardRef)(({ className, ...rest }, ref) => {
|
|
|
187
210
|
fontSize: "0.85em",
|
|
188
211
|
...styles.icon
|
|
189
212
|
};
|
|
190
|
-
return /* @__PURE__ */ (0,
|
|
213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.ui.span, { ref, className: (0, import_utils3.cx)("ui-menu-icon", className), __css: css, ...rest });
|
|
191
214
|
});
|
|
192
|
-
var MenuCommand = (0,
|
|
215
|
+
var MenuCommand = (0, import_core3.forwardRef)(({ className, ...rest }, ref) => {
|
|
193
216
|
const { styles } = useMenu();
|
|
194
217
|
const css = { ...styles.command };
|
|
195
|
-
return /* @__PURE__ */ (0,
|
|
218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.ui.span, { ref, className: (0, import_utils3.cx)("ui-menu-command", className), __css: css, ...rest });
|
|
196
219
|
});
|
|
197
|
-
var CheckIcon = () => /* @__PURE__ */ (0,
|
|
220
|
+
var CheckIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 14 14", width: "1em", height: "1em", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
198
221
|
"polygon",
|
|
199
222
|
{
|
|
200
223
|
fill: "currentColor",
|
|
@@ -202,29 +225,6 @@ var CheckIcon = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { view
|
|
|
202
225
|
}
|
|
203
226
|
) });
|
|
204
227
|
|
|
205
|
-
// src/menu-group.tsx
|
|
206
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
207
|
-
var MenuGroup = (0, import_core3.forwardRef)(
|
|
208
|
-
({ className, title, children, ...rest }, ref) => {
|
|
209
|
-
const { styles } = useMenu();
|
|
210
|
-
const css = { ...styles.group };
|
|
211
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
212
|
-
import_core3.ui.div,
|
|
213
|
-
{
|
|
214
|
-
ref,
|
|
215
|
-
className: (0, import_utils3.cx)("ui-menu-group", className),
|
|
216
|
-
role: "group",
|
|
217
|
-
__css: css,
|
|
218
|
-
...rest,
|
|
219
|
-
children: [
|
|
220
|
-
title ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.ui.span, { className: (0, import_utils3.cx)("ui-menu-group-title"), __css: styles.groupTitle, children: title }) : null,
|
|
221
|
-
children
|
|
222
|
-
]
|
|
223
|
-
}
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
);
|
|
227
|
-
|
|
228
228
|
// src/menu-option-group.tsx
|
|
229
229
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
230
230
|
var MenuOptionGroup = (0, import_react3.forwardRef)(
|
package/dist/menu.d.ts
CHANGED
|
@@ -2126,6 +2126,11 @@ type MenuContext = MenuOptions & {
|
|
|
2126
2126
|
declare const useMenu: () => MenuContext;
|
|
2127
2127
|
|
|
2128
2128
|
type MenuOptions = {
|
|
2129
|
+
/**
|
|
2130
|
+
* If `true`, the list element will be closed when value is selected.
|
|
2131
|
+
*
|
|
2132
|
+
* @default true
|
|
2133
|
+
*/
|
|
2129
2134
|
closeOnSelect?: boolean;
|
|
2130
2135
|
};
|
|
2131
2136
|
type MenuProps = ThemeProps<'Menu'> & Omit<PopoverProps, 'closeOnButton'> & MenuOptions;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yamada-ui/menu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Yamada UI menu component",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yamada",
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
"url": "https://github.com/hirotomoyamada/yamada-ui/issues"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@yamada-ui/core": "0.3.
|
|
38
|
+
"@yamada-ui/core": "0.3.1",
|
|
39
39
|
"@yamada-ui/utils": "0.1.1",
|
|
40
|
-
"@yamada-ui/popover": "0.
|
|
41
|
-
"@yamada-ui/transitions": "0.
|
|
40
|
+
"@yamada-ui/popover": "0.2.0",
|
|
41
|
+
"@yamada-ui/transitions": "0.2.0",
|
|
42
42
|
"@yamada-ui/use-disclosure": "0.1.1",
|
|
43
43
|
"@yamada-ui/use-descendant": "0.1.1",
|
|
44
|
-
"@yamada-ui/use-clickable": "0.
|
|
44
|
+
"@yamada-ui/use-clickable": "0.2.0",
|
|
45
45
|
"@yamada-ui/use-controllable-state": "0.1.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
@@ -76,6 +76,6 @@
|
|
|
76
76
|
"build:fast": "tsup src",
|
|
77
77
|
"clean": "rimraf dist .turbo",
|
|
78
78
|
"typecheck": "tsc --noEmit",
|
|
79
|
-
"gen:
|
|
79
|
+
"gen:docs": "tsx ../../../scripts/generate-docs"
|
|
80
80
|
}
|
|
81
81
|
}
|
package/dist/chunk-OXXUVU6S.mjs
DELETED
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useMenu,
|
|
3
|
-
useMenuDescendant,
|
|
4
|
-
useMenuDescendantsContext
|
|
5
|
-
} from "./chunk-6ALPY7K4.mjs";
|
|
6
|
-
|
|
7
|
-
// src/menu-button.tsx
|
|
8
|
-
import { ui as ui4, forwardRef as forwardRef6 } from "@yamada-ui/core";
|
|
9
|
-
import { PopoverTrigger } from "@yamada-ui/popover";
|
|
10
|
-
import { ariaAttr as ariaAttr2, cx as cx6, dataAttr, funcAll, handlerAll as handlerAll2 } from "@yamada-ui/utils";
|
|
11
|
-
import { useCallback as useCallback4 } from "react";
|
|
12
|
-
|
|
13
|
-
// src/menu-list.tsx
|
|
14
|
-
import { forwardRef } from "@yamada-ui/core";
|
|
15
|
-
import { PopoverContent } from "@yamada-ui/popover";
|
|
16
|
-
import { cx, handlerAll, mergeRefs } from "@yamada-ui/utils";
|
|
17
|
-
import { useCallback } from "react";
|
|
18
|
-
import { jsx } from "react/jsx-runtime";
|
|
19
|
-
var MenuList = forwardRef(({ className, ...rest }, ref) => {
|
|
20
|
-
const { menuRef, focusedIndex, setFocusedIndex, onClose, styles } = useMenu();
|
|
21
|
-
const descendants = useMenuDescendantsContext();
|
|
22
|
-
const onNext = useCallback(() => {
|
|
23
|
-
const next = descendants.enabledNextValue(focusedIndex);
|
|
24
|
-
if (next)
|
|
25
|
-
setFocusedIndex(next.index);
|
|
26
|
-
}, [descendants, focusedIndex, setFocusedIndex]);
|
|
27
|
-
const onPrev = useCallback(() => {
|
|
28
|
-
const prev = descendants.enabledPrevValue(focusedIndex);
|
|
29
|
-
if (prev)
|
|
30
|
-
setFocusedIndex(prev.index);
|
|
31
|
-
}, [descendants, focusedIndex, setFocusedIndex]);
|
|
32
|
-
const onFirst = useCallback(() => {
|
|
33
|
-
const first = descendants.enabledfirstValue();
|
|
34
|
-
if (first)
|
|
35
|
-
setFocusedIndex(first.index);
|
|
36
|
-
}, [descendants, setFocusedIndex]);
|
|
37
|
-
const onLast = useCallback(() => {
|
|
38
|
-
const last = descendants.enabledlastValue();
|
|
39
|
-
if (last)
|
|
40
|
-
setFocusedIndex(last.index);
|
|
41
|
-
}, [descendants, setFocusedIndex]);
|
|
42
|
-
const onKeyDown = useCallback(
|
|
43
|
-
(ev) => {
|
|
44
|
-
const actions = {
|
|
45
|
-
Tab: (ev2) => ev2.preventDefault(),
|
|
46
|
-
Escape: onClose,
|
|
47
|
-
ArrowDown: focusedIndex === -1 ? onFirst : onNext,
|
|
48
|
-
ArrowUp: focusedIndex === -1 ? onLast : onPrev,
|
|
49
|
-
Home: onFirst,
|
|
50
|
-
End: onLast
|
|
51
|
-
};
|
|
52
|
-
const action = actions[ev.key];
|
|
53
|
-
if (!action)
|
|
54
|
-
return;
|
|
55
|
-
ev.preventDefault();
|
|
56
|
-
action(ev);
|
|
57
|
-
},
|
|
58
|
-
[focusedIndex, onClose, onFirst, onLast, onNext, onPrev]
|
|
59
|
-
);
|
|
60
|
-
const css = { ...styles.list };
|
|
61
|
-
return /* @__PURE__ */ jsx(
|
|
62
|
-
PopoverContent,
|
|
63
|
-
{
|
|
64
|
-
ref: mergeRefs(menuRef, ref),
|
|
65
|
-
className: cx("ui-menu-list", className),
|
|
66
|
-
role: "menu",
|
|
67
|
-
tabIndex: -1,
|
|
68
|
-
__css: css,
|
|
69
|
-
...rest,
|
|
70
|
-
onKeyDown: handlerAll(rest.onKeyDown, onKeyDown)
|
|
71
|
-
}
|
|
72
|
-
);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// src/menu-item.tsx
|
|
76
|
-
import { ui, forwardRef as forwardRef2 } from "@yamada-ui/core";
|
|
77
|
-
import { useClickable } from "@yamada-ui/use-clickable";
|
|
78
|
-
import {
|
|
79
|
-
ariaAttr,
|
|
80
|
-
cx as cx2,
|
|
81
|
-
isActiveElement,
|
|
82
|
-
isHTMLElement,
|
|
83
|
-
mergeRefs as mergeRefs2,
|
|
84
|
-
useUpdateEffect
|
|
85
|
-
} from "@yamada-ui/utils";
|
|
86
|
-
import { useCallback as useCallback2, useRef } from "react";
|
|
87
|
-
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
88
|
-
var isTargetMenuItem = (target) => {
|
|
89
|
-
var _a;
|
|
90
|
-
return isHTMLElement(target) && !!((_a = target == null ? void 0 : target.getAttribute("role")) == null ? void 0 : _a.startsWith("menu-item"));
|
|
91
|
-
};
|
|
92
|
-
var MenuItem = forwardRef2(
|
|
93
|
-
({
|
|
94
|
-
as,
|
|
95
|
-
className,
|
|
96
|
-
type,
|
|
97
|
-
isDisabled,
|
|
98
|
-
isFocusable,
|
|
99
|
-
closeOnSelect: customCloseOnSelect,
|
|
100
|
-
icon,
|
|
101
|
-
command,
|
|
102
|
-
children,
|
|
103
|
-
...props
|
|
104
|
-
}, ref) => {
|
|
105
|
-
const {
|
|
106
|
-
focusedIndex,
|
|
107
|
-
setFocusedIndex,
|
|
108
|
-
isOpen,
|
|
109
|
-
onClose,
|
|
110
|
-
closeOnSelect: generalCloseOnSelect,
|
|
111
|
-
menuRef,
|
|
112
|
-
styles
|
|
113
|
-
} = useMenu();
|
|
114
|
-
const trulyDisabled = isDisabled && !isFocusable;
|
|
115
|
-
const buttonRef = useRef(null);
|
|
116
|
-
const { index, register } = useMenuDescendant({ disabled: trulyDisabled });
|
|
117
|
-
const isFocused = index === focusedIndex;
|
|
118
|
-
const onClick = useCallback2(
|
|
119
|
-
(ev) => {
|
|
120
|
-
var _a;
|
|
121
|
-
(_a = props.onClick) == null ? void 0 : _a.call(props, ev);
|
|
122
|
-
if (!isTargetMenuItem(ev.currentTarget))
|
|
123
|
-
return;
|
|
124
|
-
if (customCloseOnSelect != null ? customCloseOnSelect : generalCloseOnSelect)
|
|
125
|
-
onClose();
|
|
126
|
-
},
|
|
127
|
-
[props, customCloseOnSelect, generalCloseOnSelect, onClose]
|
|
128
|
-
);
|
|
129
|
-
const onFocus = useCallback2(
|
|
130
|
-
(ev) => {
|
|
131
|
-
var _a;
|
|
132
|
-
(_a = props.onFocus) == null ? void 0 : _a.call(props, ev);
|
|
133
|
-
setFocusedIndex(index);
|
|
134
|
-
},
|
|
135
|
-
[props, setFocusedIndex, index]
|
|
136
|
-
);
|
|
137
|
-
const rest = useClickable({
|
|
138
|
-
onClick,
|
|
139
|
-
onFocus,
|
|
140
|
-
ref: mergeRefs2(register, buttonRef, ref),
|
|
141
|
-
isDisabled,
|
|
142
|
-
isFocusable
|
|
143
|
-
});
|
|
144
|
-
useUpdateEffect(() => {
|
|
145
|
-
if (!isOpen)
|
|
146
|
-
return;
|
|
147
|
-
if (isFocused && !trulyDisabled && buttonRef.current) {
|
|
148
|
-
requestAnimationFrame(() => {
|
|
149
|
-
var _a;
|
|
150
|
-
return (_a = buttonRef.current) == null ? void 0 : _a.focus();
|
|
151
|
-
});
|
|
152
|
-
} else if (menuRef.current && !isActiveElement(menuRef.current)) {
|
|
153
|
-
menuRef.current.focus();
|
|
154
|
-
}
|
|
155
|
-
}, [isFocused, trulyDisabled, menuRef, isOpen]);
|
|
156
|
-
type = as || type ? type != null ? type : void 0 : "button";
|
|
157
|
-
children = icon || command ? /* @__PURE__ */ jsx2(ui.span, { style: { pointerEvents: "none", flex: 1 }, children }) : children;
|
|
158
|
-
const css = {
|
|
159
|
-
textDecoration: "none",
|
|
160
|
-
color: "inherit",
|
|
161
|
-
userSelect: "none",
|
|
162
|
-
display: "flex",
|
|
163
|
-
width: "100%",
|
|
164
|
-
alignItems: "center",
|
|
165
|
-
textAlign: "start",
|
|
166
|
-
flex: "0 0 auto",
|
|
167
|
-
outline: 0,
|
|
168
|
-
gap: "0.75rem",
|
|
169
|
-
...styles.item
|
|
170
|
-
};
|
|
171
|
-
return /* @__PURE__ */ jsxs(
|
|
172
|
-
ui.button,
|
|
173
|
-
{
|
|
174
|
-
...props,
|
|
175
|
-
...rest,
|
|
176
|
-
as,
|
|
177
|
-
type,
|
|
178
|
-
role: "menu-item",
|
|
179
|
-
tabIndex: isFocused ? 0 : -1,
|
|
180
|
-
className: cx2("ui-menu-item", className),
|
|
181
|
-
__css: css,
|
|
182
|
-
children: [
|
|
183
|
-
icon ? /* @__PURE__ */ jsx2(MenuIcon, { children: icon }) : null,
|
|
184
|
-
children,
|
|
185
|
-
command ? /* @__PURE__ */ jsx2(MenuCommand, { children: command }) : null
|
|
186
|
-
]
|
|
187
|
-
}
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
);
|
|
191
|
-
var MenuOptionItem = forwardRef2(
|
|
192
|
-
({ className, icon, isChecked, closeOnSelect = false, children, ...rest }, ref) => {
|
|
193
|
-
return /* @__PURE__ */ jsxs(
|
|
194
|
-
MenuItem,
|
|
195
|
-
{
|
|
196
|
-
ref,
|
|
197
|
-
className: cx2("ui-menu-option-item", className),
|
|
198
|
-
"aria-checked": ariaAttr(isChecked),
|
|
199
|
-
closeOnSelect,
|
|
200
|
-
...rest,
|
|
201
|
-
children: [
|
|
202
|
-
icon !== null ? /* @__PURE__ */ jsx2(MenuIcon, { opacity: isChecked ? 1 : 0, children: icon || /* @__PURE__ */ jsx2(CheckIcon, {}) }) : null,
|
|
203
|
-
children
|
|
204
|
-
]
|
|
205
|
-
}
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
);
|
|
209
|
-
var MenuIcon = forwardRef2(({ className, ...rest }, ref) => {
|
|
210
|
-
const { styles } = useMenu();
|
|
211
|
-
const css = {
|
|
212
|
-
flexShrink: 0,
|
|
213
|
-
display: "inline-flex",
|
|
214
|
-
justifyContent: "center",
|
|
215
|
-
alignItems: "center",
|
|
216
|
-
fontSize: "0.85em",
|
|
217
|
-
...styles.icon
|
|
218
|
-
};
|
|
219
|
-
return /* @__PURE__ */ jsx2(ui.span, { ref, className: cx2("ui-menu-icon", className), __css: css, ...rest });
|
|
220
|
-
});
|
|
221
|
-
var MenuCommand = forwardRef2(({ className, ...rest }, ref) => {
|
|
222
|
-
const { styles } = useMenu();
|
|
223
|
-
const css = { ...styles.command };
|
|
224
|
-
return /* @__PURE__ */ jsx2(ui.span, { ref, className: cx2("ui-menu-command", className), __css: css, ...rest });
|
|
225
|
-
});
|
|
226
|
-
var CheckIcon = () => /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 14 14", width: "1em", height: "1em", children: /* @__PURE__ */ jsx2(
|
|
227
|
-
"polygon",
|
|
228
|
-
{
|
|
229
|
-
fill: "currentColor",
|
|
230
|
-
points: "5.5 11.9993304 14 3.49933039 12.5 2 5.5 8.99933039 1.5 4.9968652 0 6.49933039"
|
|
231
|
-
}
|
|
232
|
-
) });
|
|
233
|
-
|
|
234
|
-
// src/menu-group.tsx
|
|
235
|
-
import { ui as ui2, forwardRef as forwardRef3 } from "@yamada-ui/core";
|
|
236
|
-
import { cx as cx3 } from "@yamada-ui/utils";
|
|
237
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
238
|
-
var MenuGroup = forwardRef3(
|
|
239
|
-
({ className, title, children, ...rest }, ref) => {
|
|
240
|
-
const { styles } = useMenu();
|
|
241
|
-
const css = { ...styles.group };
|
|
242
|
-
return /* @__PURE__ */ jsxs2(
|
|
243
|
-
ui2.div,
|
|
244
|
-
{
|
|
245
|
-
ref,
|
|
246
|
-
className: cx3("ui-menu-group", className),
|
|
247
|
-
role: "group",
|
|
248
|
-
__css: css,
|
|
249
|
-
...rest,
|
|
250
|
-
children: [
|
|
251
|
-
title ? /* @__PURE__ */ jsx3(ui2.span, { className: cx3("ui-menu-group-title"), __css: styles.groupTitle, children: title }) : null,
|
|
252
|
-
children
|
|
253
|
-
]
|
|
254
|
-
}
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
);
|
|
258
|
-
|
|
259
|
-
// src/menu-option-group.tsx
|
|
260
|
-
import { useControllableState } from "@yamada-ui/use-controllable-state";
|
|
261
|
-
import { cx as cx4, getValidChildren, omitObject, isArray } from "@yamada-ui/utils";
|
|
262
|
-
import { cloneElement, forwardRef as forwardRef4, useCallback as useCallback3 } from "react";
|
|
263
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
264
|
-
var MenuOptionGroup = forwardRef4(
|
|
265
|
-
({ className, defaultValue, type, children, ...rest }, ref) => {
|
|
266
|
-
const isRadio = type === "radio";
|
|
267
|
-
defaultValue = isRadio ? "" : [];
|
|
268
|
-
const [value, setValue] = useControllableState({
|
|
269
|
-
...rest,
|
|
270
|
-
defaultValue
|
|
271
|
-
});
|
|
272
|
-
const onChange = useCallback3(
|
|
273
|
-
(selectedValue) => {
|
|
274
|
-
if (isRadio && typeof value === "string")
|
|
275
|
-
setValue(selectedValue);
|
|
276
|
-
if (!isRadio && isArray(value)) {
|
|
277
|
-
const nextValue = value.includes(selectedValue) ? value.filter((item) => item !== selectedValue) : value.concat(selectedValue);
|
|
278
|
-
setValue(nextValue);
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
[isRadio, value, setValue]
|
|
282
|
-
);
|
|
283
|
-
const validChildren = getValidChildren(children);
|
|
284
|
-
const cloneChildren = validChildren.map((child) => {
|
|
285
|
-
if (child.type !== MenuOptionItem)
|
|
286
|
-
return child;
|
|
287
|
-
const onClick = (ev) => {
|
|
288
|
-
var _a, _b;
|
|
289
|
-
onChange(child.props.value);
|
|
290
|
-
(_b = (_a = child.props).onClick) == null ? void 0 : _b.call(_a, ev);
|
|
291
|
-
};
|
|
292
|
-
const isChecked = !isRadio && isArray(value) ? value.includes(child.props.value) : child.props.value === value;
|
|
293
|
-
return cloneElement(child, { type, onClick, isChecked });
|
|
294
|
-
});
|
|
295
|
-
return /* @__PURE__ */ jsx4(
|
|
296
|
-
MenuGroup,
|
|
297
|
-
{
|
|
298
|
-
ref,
|
|
299
|
-
className: cx4("ui-menu-option-group", className),
|
|
300
|
-
...omitObject(rest, ["value", "onChange"]),
|
|
301
|
-
children: cloneChildren
|
|
302
|
-
}
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
);
|
|
306
|
-
MenuOptionGroup.displayName = "MenuOptionGroup";
|
|
307
|
-
|
|
308
|
-
// src/menu-divider.tsx
|
|
309
|
-
import { ui as ui3, forwardRef as forwardRef5 } from "@yamada-ui/core";
|
|
310
|
-
import { cx as cx5 } from "@yamada-ui/utils";
|
|
311
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
312
|
-
var MenuDivider = forwardRef5(({ className, ...rest }, ref) => {
|
|
313
|
-
const { styles } = useMenu();
|
|
314
|
-
const css = { ...styles.divider };
|
|
315
|
-
return /* @__PURE__ */ jsx5(ui3.hr, { ref, className: cx5("ui-menu-divider", className), __css: css, ...rest });
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// src/menu-button.tsx
|
|
319
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
320
|
-
var MenuButton = forwardRef6(
|
|
321
|
-
({ className, children, as: As, ...rest }, ref) => {
|
|
322
|
-
const { isOpen, onOpen, onFocusFirstItem, onFocusLastItem } = useMenu();
|
|
323
|
-
const onKeyDown = useCallback4(
|
|
324
|
-
(ev) => {
|
|
325
|
-
const actions = {
|
|
326
|
-
Enter: funcAll(onOpen, onFocusFirstItem),
|
|
327
|
-
ArrowDown: funcAll(onOpen, onFocusFirstItem),
|
|
328
|
-
ArrowUp: funcAll(onOpen, onFocusLastItem)
|
|
329
|
-
};
|
|
330
|
-
const action = actions[ev.key];
|
|
331
|
-
if (!action)
|
|
332
|
-
return;
|
|
333
|
-
ev.preventDefault();
|
|
334
|
-
ev.stopPropagation();
|
|
335
|
-
action();
|
|
336
|
-
},
|
|
337
|
-
[onFocusFirstItem, onFocusLastItem, onOpen]
|
|
338
|
-
);
|
|
339
|
-
const Component = As || Button;
|
|
340
|
-
return /* @__PURE__ */ jsx6(PopoverTrigger, { children: /* @__PURE__ */ jsx6(
|
|
341
|
-
Component,
|
|
342
|
-
{
|
|
343
|
-
ref,
|
|
344
|
-
className: cx6("ui-menu-button", className),
|
|
345
|
-
...rest,
|
|
346
|
-
"data-active": dataAttr(isOpen),
|
|
347
|
-
"aria-expanded": ariaAttr2(isOpen),
|
|
348
|
-
onKeyDown: handlerAll2(rest.onKeyDown, onKeyDown),
|
|
349
|
-
children: /* @__PURE__ */ jsx6(ui4.span, { __css: { pointerEvents: "none", flex: "1 1 auto", minW: 0 }, children })
|
|
350
|
-
}
|
|
351
|
-
) });
|
|
352
|
-
}
|
|
353
|
-
);
|
|
354
|
-
var Button = forwardRef6((rest, ref) => {
|
|
355
|
-
const { styles } = useMenu();
|
|
356
|
-
const css = {
|
|
357
|
-
display: "inline-flex",
|
|
358
|
-
appearance: "none",
|
|
359
|
-
alignItems: "center",
|
|
360
|
-
outline: 0,
|
|
361
|
-
...styles.button
|
|
362
|
-
};
|
|
363
|
-
return /* @__PURE__ */ jsx6(ui4.button, { ref, __css: css, ...rest });
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
export {
|
|
367
|
-
MenuButton,
|
|
368
|
-
MenuList,
|
|
369
|
-
MenuItem,
|
|
370
|
-
MenuOptionItem,
|
|
371
|
-
MenuGroup,
|
|
372
|
-
MenuOptionGroup,
|
|
373
|
-
MenuDivider
|
|
374
|
-
};
|