@dxos/react-ui-menu 0.8.4-main.ef1bc66f44 → 0.8.4-main.effb148878
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/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +396 -217
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +14 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +396 -217
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/translations.mjs +16 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/builder.d.ts +26 -1
- package/dist/types/src/builder.d.ts.map +1 -1
- package/dist/types/src/builder.test.d.ts +2 -0
- package/dist/types/src/builder.test.d.ts.map +1 -0
- package/dist/types/src/components/ActionLabel.d.ts.map +1 -1
- package/dist/types/src/components/DropdownMenu.d.ts +4 -2
- package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu.d.ts +50 -0
- package/dist/types/src/components/Menu.d.ts.map +1 -0
- package/dist/types/src/components/Menu.stories.d.ts +21 -0
- package/dist/types/src/components/Menu.stories.d.ts.map +1 -0
- package/dist/types/src/components/Menu.test.d.ts +2 -0
- package/dist/types/src/components/Menu.test.d.ts.map +1 -0
- package/dist/types/src/components/ToolbarMenu.d.ts +5 -5
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts +15 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useMenuActions.d.ts +11 -3
- package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +10 -6
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +25 -3
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +3 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -21
- package/src/builder.test.ts +224 -0
- package/src/builder.ts +68 -18
- package/src/components/ActionLabel.tsx +4 -3
- package/src/components/DropdownMenu.tsx +3 -4
- package/src/components/Menu.stories.tsx +266 -0
- package/src/components/Menu.test.tsx +447 -0
- package/src/components/Menu.tsx +348 -0
- package/src/components/ToolbarMenu.stories.tsx +41 -27
- package/src/components/ToolbarMenu.tsx +123 -90
- package/src/components/index.ts +1 -3
- package/src/hooks/useMenuActions.ts +26 -15
- package/src/index.ts +1 -1
- package/src/testing/generator.ts +24 -19
- package/src/types.ts +26 -2
- package/src/util.ts +3 -2
- package/dist/types/src/components/MenuContext.d.ts +0 -15
- package/dist/types/src/components/MenuContext.d.ts.map +0 -1
- package/src/components/MenuContext.tsx +0 -64
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
// src/components/
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
// src/components/Menu.tsx
|
|
2
|
+
import { Atom, RegistryContext, useAtomValue } from "@effect-atom/atom-react";
|
|
3
|
+
import { createContextScope } from "@radix-ui/react-context";
|
|
4
|
+
import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
|
|
5
|
+
import React4, { createContext, useCallback as useCallback3, useContext, useMemo } from "react";
|
|
6
|
+
import { log } from "@dxos/log";
|
|
7
|
+
import { Icon as Icon3, DropdownMenu as NaturalDropdownMenu2 } from "@dxos/react-ui";
|
|
5
8
|
|
|
6
9
|
// src/util.ts
|
|
7
10
|
import * as Effect from "effect/Effect";
|
|
@@ -44,7 +47,8 @@ var createGapSeparator = (id = "gap", source = "root") => ({
|
|
|
44
47
|
edges: [
|
|
45
48
|
{
|
|
46
49
|
source,
|
|
47
|
-
target: id
|
|
50
|
+
target: id,
|
|
51
|
+
relation: "child"
|
|
48
52
|
}
|
|
49
53
|
]
|
|
50
54
|
});
|
|
@@ -62,7 +66,8 @@ var createLineSeparator = (id = "line", source = "root") => ({
|
|
|
62
66
|
edges: [
|
|
63
67
|
{
|
|
64
68
|
source,
|
|
65
|
-
target: id
|
|
69
|
+
target: id,
|
|
70
|
+
relation: "child"
|
|
66
71
|
}
|
|
67
72
|
]
|
|
68
73
|
});
|
|
@@ -71,26 +76,15 @@ var createLineSeparator = (id = "line", source = "root") => ({
|
|
|
71
76
|
import React from "react";
|
|
72
77
|
import { keySymbols } from "@dxos/keyboard";
|
|
73
78
|
import { toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
74
|
-
import {
|
|
75
|
-
|
|
76
|
-
// src/translations.ts
|
|
77
|
-
var translationKey = "@dxos/react-ui-menu";
|
|
78
|
-
var translations = [
|
|
79
|
-
{
|
|
80
|
-
"en-US": {
|
|
81
|
-
[translationKey]: {}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
// src/components/ActionLabel.tsx
|
|
79
|
+
import { mx } from "@dxos/ui-theme";
|
|
80
|
+
import { translationKey } from "#translations";
|
|
87
81
|
var ActionLabel = ({ action }) => {
|
|
88
82
|
const { t } = useTranslation(translationKey);
|
|
89
83
|
const shortcut = getShortcut(action);
|
|
90
84
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", {
|
|
91
85
|
className: "grow truncate"
|
|
92
86
|
}, toLocalizedString(action.properties.label, t)), shortcut && /* @__PURE__ */ React.createElement("span", {
|
|
93
|
-
className: mx("shrink-0",
|
|
87
|
+
className: mx("shrink-0", "text-description")
|
|
94
88
|
}, keySymbols(shortcut).join("")));
|
|
95
89
|
};
|
|
96
90
|
var actionLabel = (action, t) => {
|
|
@@ -98,57 +92,41 @@ var actionLabel = (action, t) => {
|
|
|
98
92
|
return `${toLocalizedString(action.properties.label, t)}${shortcut ? ` (${keySymbols(shortcut).join("")})` : ""}`;
|
|
99
93
|
};
|
|
100
94
|
|
|
101
|
-
// src/components/
|
|
102
|
-
import {
|
|
103
|
-
import
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
var
|
|
113
|
-
var MenuProvider = ({ children, useGroupItems = menuContextDefaults.useGroupItems, iconSize = menuContextDefaults.iconSize, attendableId, alwaysActive, onAction }) => {
|
|
114
|
-
const { scope } = useMenuScope(void 0);
|
|
115
|
-
return /* @__PURE__ */ React2.createElement(MenuContextProvider, {
|
|
116
|
-
useGroupItems,
|
|
117
|
-
iconSize,
|
|
118
|
-
attendableId,
|
|
119
|
-
alwaysActive,
|
|
120
|
-
onAction,
|
|
121
|
-
scope
|
|
122
|
-
}, children);
|
|
123
|
-
};
|
|
124
|
-
var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __menuScope) => {
|
|
125
|
-
const { useGroupItems } = useMenu(consumerName, __menuScope);
|
|
126
|
-
const groupItems = useGroupItems(group);
|
|
127
|
-
return useMemo(() => propsItems ?? groupItems ?? void 0, [
|
|
128
|
-
propsItems,
|
|
129
|
-
groupItems
|
|
130
|
-
]);
|
|
131
|
-
};
|
|
95
|
+
// src/components/ToolbarMenu.tsx
|
|
96
|
+
import React3, { useCallback as useCallback2 } from "react";
|
|
97
|
+
import { Icon as Icon2, Toolbar as NaturalToolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
98
|
+
import { composable, composableProps } from "@dxos/react-ui";
|
|
99
|
+
import { useAttention } from "@dxos/react-ui-attention";
|
|
100
|
+
import { translationKey as translationKey2 } from "#translations";
|
|
101
|
+
|
|
102
|
+
// src/types.ts
|
|
103
|
+
import { Node as Node2 } from "@dxos/app-graph";
|
|
104
|
+
var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
|
|
105
|
+
var isSeparator = (node) => node.type === MenuSeparatorType;
|
|
106
|
+
var isMenuGroup = (node) => node.type === Node2.ActionGroupType;
|
|
132
107
|
|
|
133
108
|
// src/components/DropdownMenu.tsx
|
|
109
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
110
|
+
import React2, { useCallback } from "react";
|
|
111
|
+
import { Icon, DropdownMenu as NaturalDropdownMenu } from "@dxos/react-ui";
|
|
134
112
|
var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
|
|
135
113
|
const action = item;
|
|
136
114
|
const handleClick = useCallback((event) => onClick(action, event), [
|
|
137
115
|
action,
|
|
138
116
|
onClick
|
|
139
117
|
]);
|
|
140
|
-
const { iconSize } =
|
|
141
|
-
return /* @__PURE__ */
|
|
118
|
+
const { iconSize } = useMenuScoped("DropdownMenuItem", __menuScope);
|
|
119
|
+
return /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Item, {
|
|
142
120
|
onClick: handleClick,
|
|
143
121
|
classNames: "gap-2",
|
|
144
122
|
disabled: action.properties?.disabled,
|
|
145
123
|
...action.properties?.testId && {
|
|
146
124
|
"data-testid": action.properties.testId
|
|
147
125
|
}
|
|
148
|
-
}, action.properties?.icon && /* @__PURE__ */
|
|
126
|
+
}, action.properties?.icon && /* @__PURE__ */ React2.createElement(Icon, {
|
|
149
127
|
icon: action.properties.icon,
|
|
150
128
|
size: iconSize
|
|
151
|
-
}), /* @__PURE__ */
|
|
129
|
+
}), /* @__PURE__ */ React2.createElement(ActionLabel, {
|
|
152
130
|
action
|
|
153
131
|
}));
|
|
154
132
|
};
|
|
@@ -158,7 +136,7 @@ var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenCha
|
|
|
158
136
|
defaultProp: defaultOpen,
|
|
159
137
|
onChange: onOpenChange
|
|
160
138
|
});
|
|
161
|
-
const { onAction } =
|
|
139
|
+
const { onAction } = useMenuScoped("DropdownMenuRoot", __menuScope);
|
|
162
140
|
const handleActionClick = useCallback((action, event) => {
|
|
163
141
|
if (action.properties?.disabled) {
|
|
164
142
|
return;
|
|
@@ -182,15 +160,15 @@ var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenCha
|
|
|
182
160
|
onAction
|
|
183
161
|
]);
|
|
184
162
|
const items = useMenuItems(group, propsItems);
|
|
185
|
-
return /* @__PURE__ */
|
|
163
|
+
return /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Root, {
|
|
186
164
|
open: optionsMenuOpen,
|
|
187
165
|
onOpenChange: setOptionsMenuOpen,
|
|
188
166
|
...naturalProps
|
|
189
|
-
}, children, /* @__PURE__ */
|
|
167
|
+
}, children, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Portal, null, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Content, null, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Viewport, null, items?.map((item) => /* @__PURE__ */ React2.createElement(DropdownMenuItem, {
|
|
190
168
|
key: item.id,
|
|
191
169
|
item,
|
|
192
170
|
onClick: handleActionClick
|
|
193
|
-
}))), /* @__PURE__ */
|
|
171
|
+
}))), /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Arrow, null))));
|
|
194
172
|
};
|
|
195
173
|
var DropdownMenu = {
|
|
196
174
|
Root: DropdownMenuRoot,
|
|
@@ -199,33 +177,11 @@ var DropdownMenu = {
|
|
|
199
177
|
};
|
|
200
178
|
|
|
201
179
|
// src/components/ToolbarMenu.tsx
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
// src/types.ts
|
|
208
|
-
import { Node as Node2 } from "@dxos/app-graph";
|
|
209
|
-
var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
|
|
210
|
-
var isSeparator = (node) => node.type === MenuSeparatorType;
|
|
211
|
-
var isMenuGroup = (node) => node.type === Node2.ActionGroupType;
|
|
212
|
-
|
|
213
|
-
// src/components/ToolbarMenu.tsx
|
|
214
|
-
var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
215
|
-
const { iconSize, onAction } = useMenu("ActionToolbarItem", __menuScope);
|
|
216
|
-
const { t } = useTranslation2(translationKey);
|
|
217
|
-
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
218
|
-
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
219
|
-
const rootProps = icon ? {
|
|
220
|
-
icon,
|
|
221
|
-
size: iconSize,
|
|
222
|
-
iconOnly,
|
|
223
|
-
label: actionLabel(action, t)
|
|
224
|
-
} : {
|
|
225
|
-
children: /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
226
|
-
action
|
|
227
|
-
})
|
|
228
|
-
};
|
|
180
|
+
var ActionToolbarItem = ({ __menuScope, action }) => {
|
|
181
|
+
const { iconSize, onAction } = useMenuScoped("ActionToolbarItem", __menuScope);
|
|
182
|
+
const { t } = useTranslation2(translationKey2);
|
|
183
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames, iconClassNames } = action.properties;
|
|
184
|
+
const buttonVariant = action.properties.variant === "primary" ? "primary" : "ghost";
|
|
229
185
|
const handleClick = useCallback2(() => {
|
|
230
186
|
if (onAction) {
|
|
231
187
|
onAction(action, {});
|
|
@@ -236,49 +192,66 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
236
192
|
action,
|
|
237
193
|
onAction
|
|
238
194
|
]);
|
|
239
|
-
|
|
240
|
-
|
|
195
|
+
const commonProps = {
|
|
196
|
+
variant: buttonVariant,
|
|
241
197
|
disabled,
|
|
198
|
+
classNames,
|
|
242
199
|
onClick: handleClick,
|
|
243
|
-
variant: "ghost",
|
|
244
200
|
...testId && {
|
|
245
201
|
"data-testid": testId
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
if (hidden) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
return icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.IconButton, {
|
|
208
|
+
key: action.id,
|
|
209
|
+
...commonProps,
|
|
210
|
+
icon,
|
|
211
|
+
size: iconSize,
|
|
212
|
+
iconOnly,
|
|
213
|
+
iconClassNames,
|
|
214
|
+
label: actionLabel(action, t)
|
|
215
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
216
|
+
key: action.id,
|
|
217
|
+
...commonProps
|
|
218
|
+
}, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
219
|
+
action
|
|
220
|
+
}));
|
|
250
221
|
};
|
|
251
|
-
var DropdownMenuToolbarItem = ({ group, items: propsItems
|
|
222
|
+
var DropdownMenuToolbarItem = ({ __menuScope, group, items: propsItems }) => {
|
|
252
223
|
const { iconOnly, disabled, testId } = group.properties;
|
|
253
|
-
const { t } = useTranslation2(
|
|
254
|
-
const { iconSize } =
|
|
224
|
+
const { t } = useTranslation2(translationKey2);
|
|
225
|
+
const { iconSize } = useMenuScoped("DropdownMenuToolbarItem", __menuScope);
|
|
255
226
|
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
256
227
|
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
257
228
|
const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
|
|
258
229
|
activeItem?.properties.icon || group.properties.icon;
|
|
230
|
+
const iconClassNames = group.properties.applyActive && activeItem?.properties.iconClassNames || group.properties.iconClassNames;
|
|
259
231
|
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
260
232
|
const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
|
|
261
233
|
const rootProps = icon ? {
|
|
262
234
|
icon,
|
|
263
235
|
size: iconSize,
|
|
264
236
|
iconOnly,
|
|
237
|
+
iconClassNames,
|
|
265
238
|
label: actionLabel(labelAction, t),
|
|
266
239
|
caretDown: true
|
|
267
240
|
} : {
|
|
268
|
-
children: /* @__PURE__ */
|
|
241
|
+
children: /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
269
242
|
action: labelAction
|
|
270
|
-
}), /* @__PURE__ */
|
|
243
|
+
}), /* @__PURE__ */ React3.createElement(Icon2, {
|
|
271
244
|
size: 3,
|
|
272
245
|
icon: "ph--caret-down--bold",
|
|
273
|
-
classNames: "
|
|
246
|
+
classNames: "ms-1"
|
|
274
247
|
}))
|
|
275
248
|
};
|
|
276
|
-
return /* @__PURE__ */
|
|
249
|
+
return /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
|
277
250
|
group,
|
|
278
251
|
items
|
|
279
|
-
}, /* @__PURE__ */
|
|
252
|
+
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
|
280
253
|
asChild: true
|
|
281
|
-
}, /* @__PURE__ */
|
|
254
|
+
}, /* @__PURE__ */ React3.createElement(Root, {
|
|
282
255
|
variant: "ghost",
|
|
283
256
|
disabled,
|
|
284
257
|
...rootProps,
|
|
@@ -287,10 +260,10 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
287
260
|
}
|
|
288
261
|
})));
|
|
289
262
|
};
|
|
290
|
-
var ToggleGroupItem = ({ group, action
|
|
291
|
-
const { iconSize, onAction } =
|
|
292
|
-
const { t } = useTranslation2(
|
|
293
|
-
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
263
|
+
var ToggleGroupItem = ({ __menuScope, group, action }) => {
|
|
264
|
+
const { iconSize, onAction } = useMenuScoped("ToggleGroupItem", __menuScope);
|
|
265
|
+
const { t } = useTranslation2(translationKey2);
|
|
266
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames, iconClassNames } = action.properties;
|
|
294
267
|
const handleClick = useCallback2(() => {
|
|
295
268
|
if (onAction) {
|
|
296
269
|
onAction(action, {
|
|
@@ -306,168 +279,342 @@ var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
|
306
279
|
group,
|
|
307
280
|
onAction
|
|
308
281
|
]);
|
|
309
|
-
const
|
|
310
|
-
const rootProps = icon ? {
|
|
311
|
-
icon,
|
|
312
|
-
size: iconSize,
|
|
313
|
-
iconOnly,
|
|
314
|
-
label: actionLabel(action, t)
|
|
315
|
-
} : {
|
|
316
|
-
children: /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
317
|
-
action
|
|
318
|
-
})
|
|
319
|
-
};
|
|
320
|
-
return hidden ? null : /* @__PURE__ */ React4.createElement(Root, {
|
|
321
|
-
key: action.id,
|
|
282
|
+
const commonProps = {
|
|
322
283
|
value: action.id,
|
|
323
284
|
disabled,
|
|
324
|
-
onClick: handleClick,
|
|
325
285
|
variant: "ghost",
|
|
286
|
+
classNames,
|
|
287
|
+
onClick: handleClick,
|
|
326
288
|
...testId && {
|
|
327
289
|
"data-testid": testId
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
return hidden ? null : icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupIconItem, {
|
|
293
|
+
...commonProps,
|
|
294
|
+
icon,
|
|
295
|
+
size: iconSize,
|
|
296
|
+
iconOnly,
|
|
297
|
+
iconClassNames,
|
|
298
|
+
label: actionLabel(action, t)
|
|
299
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, commonProps, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
300
|
+
action
|
|
301
|
+
}));
|
|
332
302
|
};
|
|
333
|
-
var ToggleGroupToolbarItem = ({ group, items:
|
|
334
|
-
const items = useMenuItems(group,
|
|
335
|
-
const { selectCardinality
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
);
|
|
303
|
+
var ToggleGroupToolbarItem = ({ __menuScope, group, items: itemsProp }) => {
|
|
304
|
+
const items = useMenuItems(group, itemsProp, "ToggleGroupToolbarItem", __menuScope);
|
|
305
|
+
const { selectCardinality } = group.properties;
|
|
306
|
+
const children = items.map((action) => /* @__PURE__ */ React3.createElement(ToggleGroupItem, {
|
|
307
|
+
key: action.id,
|
|
308
|
+
group,
|
|
309
|
+
action
|
|
310
|
+
}));
|
|
311
|
+
if (selectCardinality === "multiple") {
|
|
312
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
313
|
+
type: "multiple",
|
|
314
|
+
value: group.properties.value
|
|
315
|
+
}, children);
|
|
316
|
+
} else {
|
|
317
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
318
|
+
type: "single",
|
|
319
|
+
value: group.properties.value
|
|
320
|
+
}, children);
|
|
321
|
+
}
|
|
353
322
|
};
|
|
354
|
-
var ToolbarMenu = ({ __menuScope,
|
|
323
|
+
var ToolbarMenu = composable(({ __menuScope, children, ...props }, forwardedRef) => {
|
|
355
324
|
const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
|
|
356
|
-
const { attendableId, alwaysActive } =
|
|
325
|
+
const { attendableId, alwaysActive } = useMenuScoped("ToolbarMenu", __menuScope);
|
|
357
326
|
const { hasAttention } = useAttention(attendableId);
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
} : {};
|
|
363
|
-
return /* @__PURE__ */ React4.createElement(NaturalToolbar.Root, {
|
|
364
|
-
...props,
|
|
365
|
-
classNames: [
|
|
366
|
-
attendableId,
|
|
367
|
-
classNames
|
|
368
|
-
],
|
|
327
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
|
|
328
|
+
...composableProps(props, {
|
|
329
|
+
classNames: attendableId
|
|
330
|
+
}),
|
|
369
331
|
disabled: !alwaysActive && !hasAttention,
|
|
370
|
-
|
|
371
|
-
},
|
|
372
|
-
key: item.id
|
|
332
|
+
ref: forwardedRef
|
|
333
|
+
}, items?.map((item) => /* @__PURE__ */ React3.createElement(ToolbarMenuItem, {
|
|
334
|
+
key: item.id,
|
|
335
|
+
__menuScope,
|
|
373
336
|
item
|
|
374
|
-
})))
|
|
375
|
-
};
|
|
376
|
-
var ToolbarMenuItem = ({ item }) => {
|
|
337
|
+
})), children);
|
|
338
|
+
});
|
|
339
|
+
var ToolbarMenuItem = ({ __menuScope, item }) => {
|
|
377
340
|
if (isSeparator(item)) {
|
|
378
|
-
return /* @__PURE__ */
|
|
341
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Separator, {
|
|
379
342
|
variant: item.properties.variant
|
|
380
343
|
});
|
|
381
344
|
}
|
|
382
345
|
if (isMenuGroup(item)) {
|
|
383
346
|
if (item.properties.variant === "dropdownMenu") {
|
|
384
|
-
return /* @__PURE__ */
|
|
347
|
+
return /* @__PURE__ */ React3.createElement(DropdownMenuToolbarItem, {
|
|
348
|
+
__menuScope,
|
|
385
349
|
group: item
|
|
386
350
|
});
|
|
387
351
|
} else {
|
|
388
|
-
return /* @__PURE__ */
|
|
352
|
+
return /* @__PURE__ */ React3.createElement(ToggleGroupToolbarItem, {
|
|
353
|
+
__menuScope,
|
|
389
354
|
group: item
|
|
390
355
|
});
|
|
391
356
|
}
|
|
392
357
|
}
|
|
393
|
-
return /* @__PURE__ */
|
|
358
|
+
return /* @__PURE__ */ React3.createElement(ActionToolbarItem, {
|
|
359
|
+
__menuScope,
|
|
394
360
|
action: item
|
|
395
361
|
});
|
|
396
362
|
};
|
|
397
363
|
|
|
364
|
+
// src/components/Menu.tsx
|
|
365
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-menu/src/components/Menu.tsx";
|
|
366
|
+
var MENU_NAME = "Menu";
|
|
367
|
+
var [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);
|
|
368
|
+
var nullItemsAtom = Atom.make(null);
|
|
369
|
+
var defaultItemsAccessor = () => nullItemsAtom;
|
|
370
|
+
var menuContextDefaults = {
|
|
371
|
+
iconSize: 5,
|
|
372
|
+
items: defaultItemsAccessor,
|
|
373
|
+
onAction: void 0,
|
|
374
|
+
menuItemsAtom: Atom.make(/* @__PURE__ */ new Map()),
|
|
375
|
+
addMenuItems: () => {
|
|
376
|
+
},
|
|
377
|
+
removeMenuItems: () => {
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
var [MenuContextProvider, useMenuScoped] = createMenuContext(MENU_NAME, menuContextDefaults);
|
|
381
|
+
var useMenuScope = createMenuScope();
|
|
382
|
+
var MenuDropdownContext = /* @__PURE__ */ createContext({
|
|
383
|
+
closeMenu: () => {
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
var DEFAULT_PRIORITY = 100;
|
|
387
|
+
var sortMenuItems = (items) => [
|
|
388
|
+
...items
|
|
389
|
+
].sort((a, b) => {
|
|
390
|
+
if (a.priority !== b.priority) {
|
|
391
|
+
return a.priority - b.priority;
|
|
392
|
+
}
|
|
393
|
+
return a.id.localeCompare(b.id);
|
|
394
|
+
});
|
|
395
|
+
var MenuProvider = ({ children, items = menuContextDefaults.items, iconSize = menuContextDefaults.iconSize, attendableId, alwaysActive, onAction }) => {
|
|
396
|
+
const { scope } = useMenuScope(void 0);
|
|
397
|
+
const registry = useContext(RegistryContext);
|
|
398
|
+
const menuItemsAtom = useMemo(() => Atom.make(/* @__PURE__ */ new Map()).pipe(Atom.keepAlive), []);
|
|
399
|
+
const addMenuItems = useCallback3((props) => {
|
|
400
|
+
const priority = props.priority ?? DEFAULT_PRIORITY;
|
|
401
|
+
const prev = registry.get(menuItemsAtom);
|
|
402
|
+
const next = new Map(prev);
|
|
403
|
+
next.set(props.id, {
|
|
404
|
+
...props,
|
|
405
|
+
priority
|
|
406
|
+
});
|
|
407
|
+
registry.set(menuItemsAtom, next);
|
|
408
|
+
}, [
|
|
409
|
+
registry,
|
|
410
|
+
menuItemsAtom
|
|
411
|
+
]);
|
|
412
|
+
const removeMenuItems = useCallback3((id) => {
|
|
413
|
+
const prev = registry.get(menuItemsAtom);
|
|
414
|
+
const next = new Map(prev);
|
|
415
|
+
next.delete(id);
|
|
416
|
+
registry.set(menuItemsAtom, next);
|
|
417
|
+
}, [
|
|
418
|
+
registry,
|
|
419
|
+
menuItemsAtom
|
|
420
|
+
]);
|
|
421
|
+
return /* @__PURE__ */ React4.createElement(MenuContextProvider, {
|
|
422
|
+
items,
|
|
423
|
+
iconSize,
|
|
424
|
+
attendableId,
|
|
425
|
+
alwaysActive,
|
|
426
|
+
menuItemsAtom,
|
|
427
|
+
addMenuItems,
|
|
428
|
+
removeMenuItems,
|
|
429
|
+
onAction,
|
|
430
|
+
scope
|
|
431
|
+
}, children);
|
|
432
|
+
};
|
|
433
|
+
var resolveItems = (baseItems, group, entries) => {
|
|
434
|
+
const applicable = [
|
|
435
|
+
...entries.values()
|
|
436
|
+
].filter((entry) => !entry.groupFilter || entry.groupFilter(group));
|
|
437
|
+
if (applicable.length === 0) {
|
|
438
|
+
return baseItems;
|
|
439
|
+
}
|
|
440
|
+
const sorted = sortMenuItems(applicable);
|
|
441
|
+
const replacements = sorted.filter((entry) => entry.mode === "replacement");
|
|
442
|
+
if (replacements.length > 0) {
|
|
443
|
+
if (replacements.length > 1) {
|
|
444
|
+
log.warn("multiple replacement entries found", {
|
|
445
|
+
ids: replacements.map((r) => r.id).join(", "),
|
|
446
|
+
using: replacements[0].id
|
|
447
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 94, S: void 0 });
|
|
448
|
+
}
|
|
449
|
+
return replacements[0].items;
|
|
450
|
+
}
|
|
451
|
+
const additive = sorted.filter((entry) => entry.mode === "additive");
|
|
452
|
+
const additiveItems = additive.flatMap((entry) => entry.items);
|
|
453
|
+
if (!baseItems || baseItems.length === 0) {
|
|
454
|
+
return additiveItems.length > 0 ? additiveItems : null;
|
|
455
|
+
}
|
|
456
|
+
return [
|
|
457
|
+
...baseItems,
|
|
458
|
+
...additiveItems
|
|
459
|
+
];
|
|
460
|
+
};
|
|
461
|
+
var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __menuScope) => {
|
|
462
|
+
const { items, menuItemsAtom } = useMenuScoped(consumerName, __menuScope);
|
|
463
|
+
const groupItems = useAtomValue(items(group));
|
|
464
|
+
const entries = useAtomValue(menuItemsAtom) ?? /* @__PURE__ */ new Map();
|
|
465
|
+
const baseItems = useMemo(() => propsItems ?? groupItems ?? null, [
|
|
466
|
+
propsItems,
|
|
467
|
+
groupItems
|
|
468
|
+
]);
|
|
469
|
+
const resolved = useMemo(() => resolveItems(baseItems, group, entries), [
|
|
470
|
+
baseItems,
|
|
471
|
+
group,
|
|
472
|
+
entries
|
|
473
|
+
]);
|
|
474
|
+
return resolved ?? void 0;
|
|
475
|
+
};
|
|
476
|
+
var useMenu = (consumerName) => {
|
|
477
|
+
return useMenuScoped(consumerName, void 0);
|
|
478
|
+
};
|
|
479
|
+
var MenuRoot = ({ children, open, defaultOpen, onOpenChange, caller, ...props }) => {
|
|
480
|
+
const [menuOpen, setMenuOpen] = useControllableState2({
|
|
481
|
+
prop: open,
|
|
482
|
+
defaultProp: defaultOpen,
|
|
483
|
+
onChange: onOpenChange
|
|
484
|
+
});
|
|
485
|
+
const closeMenu = useCallback3(() => setMenuOpen(false), [
|
|
486
|
+
setMenuOpen
|
|
487
|
+
]);
|
|
488
|
+
return /* @__PURE__ */ React4.createElement(MenuProvider, props, /* @__PURE__ */ React4.createElement(MenuDropdownContext.Provider, {
|
|
489
|
+
value: {
|
|
490
|
+
closeMenu,
|
|
491
|
+
caller
|
|
492
|
+
}
|
|
493
|
+
}, /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Root, {
|
|
494
|
+
open: menuOpen,
|
|
495
|
+
onOpenChange: setMenuOpen
|
|
496
|
+
}, children)));
|
|
497
|
+
};
|
|
498
|
+
var MenuContentItem = ({ item, onClick, __menuScope }) => {
|
|
499
|
+
const action = item;
|
|
500
|
+
const handleClick = useCallback3((event) => onClick(action, event), [
|
|
501
|
+
action,
|
|
502
|
+
onClick
|
|
503
|
+
]);
|
|
504
|
+
const { iconSize } = useMenuScoped("MenuContentItem", __menuScope);
|
|
505
|
+
return /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Item, {
|
|
506
|
+
onClick: handleClick,
|
|
507
|
+
classNames: "gap-2",
|
|
508
|
+
disabled: action.properties?.disabled,
|
|
509
|
+
...action.properties?.testId && {
|
|
510
|
+
"data-testid": action.properties.testId
|
|
511
|
+
}
|
|
512
|
+
}, action.properties?.icon && /* @__PURE__ */ React4.createElement(Icon3, {
|
|
513
|
+
icon: action.properties.icon,
|
|
514
|
+
size: iconSize
|
|
515
|
+
}), /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
516
|
+
action
|
|
517
|
+
}));
|
|
518
|
+
};
|
|
519
|
+
var MenuContent = ({ group, items: propsItems, caller: callerOverride, __menuScope }) => {
|
|
520
|
+
const { closeMenu, caller: contextCaller } = useContext(MenuDropdownContext);
|
|
521
|
+
const caller = callerOverride ?? contextCaller;
|
|
522
|
+
const { onAction } = useMenuScoped("MenuContent", __menuScope);
|
|
523
|
+
const resolvedItems = useMenuItems(group, propsItems, "MenuContent", __menuScope);
|
|
524
|
+
const handleActionClick = useCallback3((action, event) => {
|
|
525
|
+
if (action.properties?.disabled) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
event.stopPropagation();
|
|
529
|
+
closeMenu();
|
|
530
|
+
if (onAction) {
|
|
531
|
+
onAction(action, {
|
|
532
|
+
parent: group,
|
|
533
|
+
caller
|
|
534
|
+
});
|
|
535
|
+
} else {
|
|
536
|
+
void executeMenuAction(action, {
|
|
537
|
+
parent: group,
|
|
538
|
+
caller
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
}, [
|
|
542
|
+
group,
|
|
543
|
+
caller,
|
|
544
|
+
onAction,
|
|
545
|
+
closeMenu
|
|
546
|
+
]);
|
|
547
|
+
return /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Portal, null, /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Content, null, /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Viewport, null, resolvedItems?.map((item) => /* @__PURE__ */ React4.createElement(MenuContentItem, {
|
|
548
|
+
key: item.id,
|
|
549
|
+
item,
|
|
550
|
+
onClick: handleActionClick
|
|
551
|
+
}))), /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Arrow, null)));
|
|
552
|
+
};
|
|
553
|
+
var Menu = {
|
|
554
|
+
Root: MenuRoot,
|
|
555
|
+
Trigger: NaturalDropdownMenu2.Trigger,
|
|
556
|
+
Content: MenuContent,
|
|
557
|
+
VirtualTrigger: NaturalDropdownMenu2.VirtualTrigger,
|
|
558
|
+
Toolbar: ToolbarMenu
|
|
559
|
+
};
|
|
560
|
+
|
|
398
561
|
// src/hooks/useMenuActions.ts
|
|
399
|
-
import { RegistryContext, useAtomValue } from "@effect-atom/atom-react";
|
|
400
|
-
import { useCallback as
|
|
562
|
+
import { Atom as Atom2, RegistryContext as RegistryContext2, useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
563
|
+
import { useCallback as useCallback4, useContext as useContext2, useMemo as useMemo2 } from "react";
|
|
401
564
|
import { Graph, Node as Node3 } from "@dxos/app-graph";
|
|
402
565
|
var useMenuActions = (props) => {
|
|
403
|
-
const registry =
|
|
404
|
-
const menuGraphProps =
|
|
405
|
-
const
|
|
406
|
-
if (!graphRef.current || graphRef.current.props !== menuGraphProps) {
|
|
566
|
+
const registry = useContext2(RegistryContext2);
|
|
567
|
+
const menuGraphProps = useAtomValue2(props);
|
|
568
|
+
const graph = useMemo2(() => {
|
|
407
569
|
const newGraph = Graph.make({
|
|
408
570
|
registry
|
|
409
571
|
});
|
|
410
572
|
newGraph.pipe(Graph.addNodes(menuGraphProps.nodes), Graph.addEdges(menuGraphProps.edges));
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
const items = useAtomValue(graph.connections(sourceNode?.id || Node3.RootId));
|
|
419
|
-
return items;
|
|
573
|
+
return newGraph;
|
|
574
|
+
}, [
|
|
575
|
+
registry,
|
|
576
|
+
menuGraphProps
|
|
577
|
+
]);
|
|
578
|
+
const items = useCallback4((group) => {
|
|
579
|
+
return graph.connections(group?.id || Node3.RootId, "child");
|
|
420
580
|
}, [
|
|
421
581
|
graph
|
|
422
582
|
]);
|
|
423
583
|
return {
|
|
424
|
-
|
|
584
|
+
items
|
|
425
585
|
};
|
|
426
586
|
};
|
|
587
|
+
var useMenuBuilder = (build, deps) => {
|
|
588
|
+
const atom = useMemo2(() => Atom2.make(build), deps);
|
|
589
|
+
return useMenuActions(atom);
|
|
590
|
+
};
|
|
427
591
|
|
|
428
592
|
// src/builder.ts
|
|
429
593
|
import { invariant } from "@dxos/invariant";
|
|
430
|
-
var
|
|
431
|
-
var MenuBuilder = Object.freeze({
|
|
432
|
-
make: () => new MenuBuilderImpl({
|
|
433
|
-
nodes: [],
|
|
434
|
-
edges: []
|
|
435
|
-
}, "root")
|
|
436
|
-
});
|
|
594
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-menu/src/builder.ts";
|
|
437
595
|
var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
438
596
|
_data;
|
|
439
597
|
_rootId;
|
|
598
|
+
_separatorCount = 0;
|
|
440
599
|
constructor(_data, _rootId) {
|
|
441
600
|
this._data = _data;
|
|
442
601
|
this._rootId = _rootId;
|
|
443
602
|
}
|
|
444
603
|
root(props) {
|
|
445
|
-
invariant(this._rootId === "root", "Root group can only be at the top level", {
|
|
446
|
-
|
|
447
|
-
L: 36,
|
|
448
|
-
S: this,
|
|
449
|
-
A: [
|
|
450
|
-
"this._rootId === 'root'",
|
|
451
|
-
"'Root group can only be at the top level'"
|
|
452
|
-
]
|
|
453
|
-
});
|
|
454
|
-
invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", {
|
|
455
|
-
F: __dxlog_file,
|
|
456
|
-
L: 37,
|
|
457
|
-
S: this,
|
|
458
|
-
A: [
|
|
459
|
-
"this._data.nodes.find((node) => node.id === 'root') === undefined",
|
|
460
|
-
"'Root group can only be created once'"
|
|
461
|
-
]
|
|
462
|
-
});
|
|
604
|
+
invariant(this._rootId === "root", "Root group can only be at the top level", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 16, S: this, A: ["this._rootId === 'root'", "'Root group can only be at the top level'"] });
|
|
605
|
+
invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 17, S: this, A: ["this._data.nodes.find((node)=>node.id === 'root') === undefined", "'Root group can only be created once'"] });
|
|
463
606
|
this._data.nodes.push(createMenuItemGroup("root", props));
|
|
464
607
|
return this;
|
|
465
608
|
}
|
|
609
|
+
build() {
|
|
610
|
+
return this._data;
|
|
611
|
+
}
|
|
466
612
|
action(id, props, invoke) {
|
|
467
613
|
this._data.nodes.push(createMenuAction(id, invoke, props));
|
|
468
614
|
this._data.edges.push({
|
|
469
615
|
source: this._rootId,
|
|
470
|
-
target: id
|
|
616
|
+
target: id,
|
|
617
|
+
relation: "child"
|
|
471
618
|
});
|
|
472
619
|
return this;
|
|
473
620
|
}
|
|
@@ -475,31 +622,63 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
475
622
|
this._data.nodes.push(createMenuItemGroup(id, props));
|
|
476
623
|
this._data.edges.push({
|
|
477
624
|
source: this._rootId,
|
|
478
|
-
target: id
|
|
625
|
+
target: id,
|
|
626
|
+
relation: "child"
|
|
479
627
|
});
|
|
480
628
|
cb(new _MenuBuilderImpl(this._data, id));
|
|
481
629
|
return this;
|
|
482
630
|
}
|
|
483
|
-
|
|
484
|
-
|
|
631
|
+
subgraph(subgraphOrCb) {
|
|
632
|
+
if (!subgraphOrCb) {
|
|
633
|
+
return this;
|
|
634
|
+
}
|
|
635
|
+
if (typeof subgraphOrCb === "function") {
|
|
636
|
+
subgraphOrCb(new _MenuBuilderImpl(this._data, this._rootId));
|
|
637
|
+
} else {
|
|
638
|
+
this._data.nodes.push(...subgraphOrCb.nodes);
|
|
639
|
+
this._data.edges.push(...subgraphOrCb.edges);
|
|
640
|
+
}
|
|
641
|
+
return this;
|
|
642
|
+
}
|
|
643
|
+
separator(variant = "gap") {
|
|
644
|
+
const id = `separator-${++this._separatorCount}`;
|
|
645
|
+
this._data.nodes.push({
|
|
646
|
+
id,
|
|
647
|
+
type: MenuSeparatorType,
|
|
648
|
+
properties: {
|
|
649
|
+
variant
|
|
650
|
+
},
|
|
651
|
+
data: void 0
|
|
652
|
+
});
|
|
653
|
+
this._data.edges.push({
|
|
654
|
+
source: this._rootId,
|
|
655
|
+
target: id,
|
|
656
|
+
relation: "child"
|
|
657
|
+
});
|
|
658
|
+
return this;
|
|
485
659
|
}
|
|
486
660
|
};
|
|
661
|
+
var MenuBuilder = Object.freeze({
|
|
662
|
+
make: () => new MenuBuilderImpl({
|
|
663
|
+
nodes: [],
|
|
664
|
+
edges: []
|
|
665
|
+
}, "root")
|
|
666
|
+
});
|
|
487
667
|
export {
|
|
488
|
-
|
|
668
|
+
Menu,
|
|
489
669
|
MenuBuilder,
|
|
490
|
-
MenuProvider,
|
|
491
670
|
MenuSeparatorType,
|
|
492
|
-
ToolbarMenu,
|
|
493
671
|
createGapSeparator,
|
|
494
672
|
createLineSeparator,
|
|
495
673
|
createMenuAction,
|
|
496
674
|
createMenuItemGroup,
|
|
497
|
-
createMenuScope,
|
|
498
675
|
isMenuGroup,
|
|
499
676
|
isSeparator,
|
|
500
677
|
menuContextDefaults,
|
|
501
678
|
useMenu,
|
|
502
679
|
useMenuActions,
|
|
503
|
-
|
|
680
|
+
useMenuBuilder,
|
|
681
|
+
useMenuItems,
|
|
682
|
+
useMenuScoped
|
|
504
683
|
};
|
|
505
684
|
//# sourceMappingURL=index.mjs.map
|