@dxos/react-ui-menu 0.8.4-main.c4373fc → 0.8.4-main.d05673bc65

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