@dxos/react-ui-menu 0.8.4-main.f9ba587 → 0.8.4-main.fcc0d83b33

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