@dxos/react-ui-menu 0.8.4-main.40e3dcdf1b → 0.8.4-main.422d1c7879

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 (42) hide show
  1. package/dist/lib/browser/index.mjs +99 -98
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +99 -98
  5. package/dist/lib/node-esm/index.mjs.map +3 -3
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/builder.d.ts +23 -4
  8. package/dist/types/src/builder.d.ts.map +1 -1
  9. package/dist/types/src/builder.test.d.ts +2 -0
  10. package/dist/types/src/builder.test.d.ts.map +1 -0
  11. package/dist/types/src/components/DropdownMenu.d.ts +3 -1
  12. package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
  13. package/dist/types/src/components/Menu.d.ts +8 -4
  14. package/dist/types/src/components/Menu.d.ts.map +1 -1
  15. package/dist/types/src/components/{MenuItems.stories.d.ts → Menu.stories.d.ts} +1 -1
  16. package/dist/types/src/components/Menu.stories.d.ts.map +1 -0
  17. package/dist/types/src/components/ToolbarMenu.d.ts +4 -4
  18. package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
  19. package/dist/types/src/components/ToolbarMenu.stories.d.ts +3 -1
  20. package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -1
  21. package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
  22. package/dist/types/src/index.d.ts +1 -1
  23. package/dist/types/src/index.d.ts.map +1 -1
  24. package/dist/types/src/testing/generator.d.ts +7 -3
  25. package/dist/types/src/testing/generator.d.ts.map +1 -1
  26. package/dist/types/src/types.d.ts +1 -0
  27. package/dist/types/src/types.d.ts.map +1 -1
  28. package/dist/types/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +17 -20
  30. package/src/builder.test.ts +224 -0
  31. package/src/builder.ts +41 -18
  32. package/src/components/DropdownMenu.tsx +0 -1
  33. package/src/components/Menu.test.tsx +0 -1
  34. package/src/components/Menu.tsx +9 -10
  35. package/src/components/ToolbarMenu.stories.tsx +13 -11
  36. package/src/components/ToolbarMenu.tsx +109 -85
  37. package/src/hooks/useMenuActions.ts +6 -7
  38. package/src/index.ts +1 -1
  39. package/src/testing/generator.ts +15 -10
  40. package/src/types.ts +1 -0
  41. package/dist/types/src/components/MenuItems.stories.d.ts.map +0 -1
  42. /package/src/components/{MenuItems.stories.tsx → Menu.stories.tsx} +0 -0
@@ -1 +1 @@
1
- {"inputs":{"src/util.ts":{"bytes":7990,"imports":[{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/effect","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"src/translations.ts":{"bytes":1055,"imports":[],"format":"esm"},"src/components/ActionLabel.tsx":{"bytes":3991,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"src/translations.ts","kind":"import-statement","original":"../translations"},{"path":"src/util.ts","kind":"import-statement","original":"../util"}],"format":"esm"},"src/types.ts":{"bytes":4392,"imports":[{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"src/components/DropdownMenu.tsx":{"bytes":10952,"imports":[{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"src/components/Menu.tsx","kind":"import-statement","original":"./Menu"}],"format":"esm"},"src/components/ToolbarMenu.tsx":{"bytes":24943,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-attention","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"src/translations.ts","kind":"import-statement","original":"../translations"},{"path":"src/types.ts","kind":"import-statement","original":"../types"},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"src/components/DropdownMenu.tsx","kind":"import-statement","original":"./DropdownMenu"},{"path":"src/components/Menu.tsx","kind":"import-statement","original":"./Menu"}],"format":"esm"},"src/components/Menu.tsx":{"bytes":31537,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"src/components/ToolbarMenu.tsx","kind":"import-statement","original":"./ToolbarMenu"}],"format":"esm"},"src/components/index.ts":{"bytes":455,"imports":[{"path":"src/components/Menu.tsx","kind":"import-statement","original":"./Menu"}],"format":"esm"},"src/hooks/useMenuActions.ts":{"bytes":5090,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/index.ts":{"bytes":476,"imports":[{"path":"src/hooks/useMenuActions.ts","kind":"import-statement","original":"./useMenuActions"}],"format":"esm"},"src/builder.ts":{"bytes":9449,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"src/types.ts","kind":"import-statement","original":"./types"},{"path":"src/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"},"src/index.ts":{"bytes":1218,"imports":[{"path":"src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"src/hooks/index.ts","kind":"import-statement","original":"./hooks"},{"path":"src/types.ts","kind":"import-statement","original":"./types"},{"path":"src/util.ts","kind":"import-statement","original":"./util"},{"path":"src/builder.ts","kind":"import-statement","original":"./builder"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":52594},"dist/lib/browser/index.mjs":{"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/effect","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-attention","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"exports":["Menu","MenuBuilder","MenuSeparatorType","createGapSeparator","createLineSeparator","createMenuAction","createMenuItemGroup","isMenuGroup","isSeparator","menuContextDefaults","useMenu","useMenuActions","useMenuItems","useMenuScoped"],"entryPoint":"src/index.ts","inputs":{"src/components/Menu.tsx":{"bytesInOutput":6959},"src/util.ts":{"bytesInOutput":1475},"src/components/ActionLabel.tsx":{"bytesInOutput":842},"src/translations.ts":{"bytesInOutput":124},"src/components/ToolbarMenu.tsx":{"bytesInOutput":6105},"src/types.ts":{"bytesInOutput":235},"src/components/DropdownMenu.tsx":{"bytesInOutput":2516},"src/index.ts":{"bytesInOutput":0},"src/hooks/useMenuActions.ts":{"bytesInOutput":929},"src/builder.ts":{"bytesInOutput":2100}},"bytes":21917}}}
1
+ {"inputs":{"src/util.ts":{"bytes":7990,"imports":[{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/effect","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"src/translations.ts":{"bytes":1055,"imports":[],"format":"esm"},"src/components/ActionLabel.tsx":{"bytes":3991,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"src/translations.ts","kind":"import-statement","original":"../translations"},{"path":"src/util.ts","kind":"import-statement","original":"../util"}],"format":"esm"},"src/types.ts":{"bytes":4508,"imports":[{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"src/components/DropdownMenu.tsx":{"bytes":10952,"imports":[{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"src/components/Menu.tsx","kind":"import-statement","original":"./Menu"}],"format":"esm"},"src/components/ToolbarMenu.tsx":{"bytes":25150,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-attention","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"src/translations.ts","kind":"import-statement","original":"../translations"},{"path":"src/types.ts","kind":"import-statement","original":"../types"},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"src/components/DropdownMenu.tsx","kind":"import-statement","original":"./DropdownMenu"},{"path":"src/components/Menu.tsx","kind":"import-statement","original":"./Menu"}],"format":"esm"},"src/components/Menu.tsx":{"bytes":31685,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"src/util.ts","kind":"import-statement","original":"../util"},{"path":"src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"src/components/ToolbarMenu.tsx","kind":"import-statement","original":"./ToolbarMenu"}],"format":"esm"},"src/components/index.ts":{"bytes":455,"imports":[{"path":"src/components/Menu.tsx","kind":"import-statement","original":"./Menu"}],"format":"esm"},"src/hooks/useMenuActions.ts":{"bytes":5007,"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/index.ts":{"bytes":476,"imports":[{"path":"src/hooks/useMenuActions.ts","kind":"import-statement","original":"./useMenuActions"}],"format":"esm"},"src/builder.ts":{"bytes":11391,"imports":[{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"src/types.ts","kind":"import-statement","original":"./types"},{"path":"src/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"},"src/index.ts":{"bytes":1290,"imports":[{"path":"src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"src/hooks/index.ts","kind":"import-statement","original":"./hooks"},{"path":"src/types.ts","kind":"import-statement","original":"./types"},{"path":"src/util.ts","kind":"import-statement","original":"./util"},{"path":"src/builder.ts","kind":"import-statement","original":"./builder"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":54095},"dist/lib/browser/index.mjs":{"imports":[{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"effect/Effect","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/effect","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-attention","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@effect-atom/atom-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"exports":["Menu","MenuBuilder","MenuSeparatorType","createGapSeparator","createLineSeparator","createMenuAction","createMenuItemGroup","isMenuGroup","isSeparator","menuContextDefaults","useMenu","useMenuActions","useMenuItems","useMenuScoped"],"entryPoint":"src/index.ts","inputs":{"src/components/Menu.tsx":{"bytesInOutput":6967},"src/util.ts":{"bytesInOutput":1475},"src/components/ActionLabel.tsx":{"bytesInOutput":842},"src/translations.ts":{"bytesInOutput":124},"src/components/ToolbarMenu.tsx":{"bytesInOutput":6090},"src/types.ts":{"bytesInOutput":235},"src/components/DropdownMenu.tsx":{"bytesInOutput":2516},"src/index.ts":{"bytesInOutput":0},"src/hooks/useMenuActions.ts":{"bytesInOutput":810},"src/builder.ts":{"bytesInOutput":2299}},"bytes":21990}}}
@@ -4,7 +4,7 @@ import { createRequire } from 'node:module';const require = createRequire(import
4
4
  import { Atom, RegistryContext, useAtomValue } from "@effect-atom/atom-react";
5
5
  import { createContextScope } from "@radix-ui/react-context";
6
6
  import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
7
- import React4, { useCallback as useCallback3, useContext, useMemo } from "react";
7
+ import React4, { createContext, useCallback as useCallback3, useContext, useMemo } from "react";
8
8
  import { log } from "@dxos/log";
9
9
  import { Icon as Icon3, DropdownMenu as NaturalDropdownMenu2 } from "@dxos/react-ui";
10
10
 
@@ -106,10 +106,10 @@ var actionLabel = (action, t) => {
106
106
  };
107
107
 
108
108
  // src/components/ToolbarMenu.tsx
109
- import React3, { Fragment, useCallback as useCallback2 } from "react";
109
+ import React3, { useCallback as useCallback2 } from "react";
110
110
  import { Icon as Icon2, Toolbar as NaturalToolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
111
111
  import { useAttention } from "@dxos/react-ui-attention";
112
- import { mx as mx2, textBlockWidth, toolbarLayout } from "@dxos/ui-theme";
112
+ import { composable, composableProps } from "@dxos/ui-theme";
113
113
 
114
114
  // src/types.ts
115
115
  import { Node as Node2 } from "@dxos/app-graph";
@@ -189,21 +189,11 @@ var DropdownMenu = {
189
189
  };
190
190
 
191
191
  // src/components/ToolbarMenu.tsx
192
- var ActionToolbarItem = ({ action, __menuScope }) => {
192
+ var ActionToolbarItem = ({ __menuScope, action }) => {
193
193
  const { iconSize, onAction } = useMenuScoped("ActionToolbarItem", __menuScope);
194
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, {
204
- action
205
- })
206
- };
195
+ const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
196
+ const buttonVariant = action.properties.variant === "primary" ? "primary" : "ghost";
207
197
  const handleClick = useCallback2(() => {
208
198
  if (onAction) {
209
199
  onAction(action, {});
@@ -214,19 +204,33 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
214
204
  action,
215
205
  onAction
216
206
  ]);
217
- return hidden ? null : /* @__PURE__ */ React3.createElement(Root, {
218
- key: action.id,
207
+ const commonProps = {
208
+ variant: buttonVariant,
219
209
  disabled,
210
+ classNames,
220
211
  onClick: handleClick,
221
- variant: variant ?? "ghost",
222
212
  ...testId && {
223
213
  "data-testid": testId
224
- },
225
- ...rootProps,
226
- classNames
227
- });
214
+ }
215
+ };
216
+ if (hidden) {
217
+ return null;
218
+ }
219
+ return icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.IconButton, {
220
+ key: action.id,
221
+ ...commonProps,
222
+ icon,
223
+ size: iconSize,
224
+ iconOnly,
225
+ label: actionLabel(action, t)
226
+ }) : /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
227
+ key: action.id,
228
+ ...commonProps
229
+ }, /* @__PURE__ */ React3.createElement(ActionLabel, {
230
+ action
231
+ }));
228
232
  };
229
- var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
233
+ var DropdownMenuToolbarItem = ({ __menuScope, group, items: propsItems }) => {
230
234
  const { iconOnly, disabled, testId } = group.properties;
231
235
  const { t } = useTranslation2(translationKey);
232
236
  const { iconSize } = useMenuScoped("DropdownMenuToolbarItem", __menuScope);
@@ -265,7 +269,7 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
265
269
  }
266
270
  })));
267
271
  };
268
- var ToggleGroupItem = ({ group, action, __menuScope }) => {
272
+ var ToggleGroupItem = ({ __menuScope, group, action }) => {
269
273
  const { iconSize, onAction } = useMenuScoped("ToggleGroupItem", __menuScope);
270
274
  const { t } = useTranslation2(translationKey);
271
275
  const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
@@ -284,74 +288,63 @@ var ToggleGroupItem = ({ group, action, __menuScope }) => {
284
288
  group,
285
289
  onAction
286
290
  ]);
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,
291
+ const commonProps = {
300
292
  value: action.id,
301
293
  disabled,
302
- onClick: handleClick,
303
294
  variant: "ghost",
295
+ classNames,
296
+ onClick: handleClick,
304
297
  ...testId && {
305
298
  "data-testid": testId
306
- },
307
- ...rootProps,
308
- classNames
309
- });
299
+ }
300
+ };
301
+ return hidden ? null : icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupIconItem, {
302
+ ...commonProps,
303
+ icon,
304
+ size: iconSize,
305
+ iconOnly,
306
+ label: actionLabel(action, t)
307
+ }) : /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, commonProps, /* @__PURE__ */ React3.createElement(ActionLabel, {
308
+ action
309
+ }));
310
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
322
- },
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
- );
311
+ var ToggleGroupToolbarItem = ({ __menuScope, group, items: itemsProp }) => {
312
+ const items = useMenuItems(group, itemsProp, "ToggleGroupToolbarItem", __menuScope);
313
+ const { selectCardinality } = group.properties;
314
+ const children = items.map((action) => /* @__PURE__ */ React3.createElement(ToggleGroupItem, {
315
+ key: action.id,
316
+ group,
317
+ action
318
+ }));
319
+ if (selectCardinality === "multiple") {
320
+ return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
321
+ type: "multiple",
322
+ value: group.properties.value
323
+ }, children);
324
+ } else {
325
+ return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
326
+ type: "single",
327
+ value: group.properties.value
328
+ }, children);
329
+ }
331
330
  };
332
- var ToolbarMenu = ({ __menuScope, classNames, textBlockWidth: textBlockWidthProp, ...props }) => {
331
+ var ToolbarMenu = composable(({ __menuScope, children, ...props }, forwardedRef) => {
333
332
  const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
334
333
  const { attendableId, alwaysActive } = useMenuScoped("ToolbarMenu", __menuScope);
335
334
  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
335
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
342
- ...props,
343
- classNames: [
344
- attendableId,
345
- classNames
346
- ],
336
+ ...composableProps(props, {
337
+ classNames: attendableId
338
+ }),
347
339
  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,
340
+ ref: forwardedRef
341
+ }, items?.map((item) => /* @__PURE__ */ React3.createElement(ToolbarMenuItem, {
342
+ key: item.id,
343
+ __menuScope,
351
344
  item
352
- }))));
353
- };
354
- var ToolbarMenuItem = ({ item }) => {
345
+ })), children);
346
+ });
347
+ var ToolbarMenuItem = ({ __menuScope, item }) => {
355
348
  if (isSeparator(item)) {
356
349
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.Separator, {
357
350
  variant: item.properties.variant
@@ -360,15 +353,18 @@ var ToolbarMenuItem = ({ item }) => {
360
353
  if (isMenuGroup(item)) {
361
354
  if (item.properties.variant === "dropdownMenu") {
362
355
  return /* @__PURE__ */ React3.createElement(DropdownMenuToolbarItem, {
356
+ __menuScope,
363
357
  group: item
364
358
  });
365
359
  } else {
366
360
  return /* @__PURE__ */ React3.createElement(ToggleGroupToolbarItem, {
361
+ __menuScope,
367
362
  group: item
368
363
  });
369
364
  }
370
365
  }
371
366
  return /* @__PURE__ */ React3.createElement(ActionToolbarItem, {
367
+ __menuScope,
372
368
  action: item
373
369
  });
374
370
  };
@@ -391,7 +387,7 @@ var menuContextDefaults = {
391
387
  };
392
388
  var [MenuContextProvider, useMenuScoped] = createMenuContext(MENU_NAME, menuContextDefaults);
393
389
  var useMenuScope = createMenuScope();
394
- var MenuDropdownContext = /* @__PURE__ */ React4.createContext({
390
+ var MenuDropdownContext = /* @__PURE__ */ createContext({
395
391
  closeMenu: () => {
396
392
  }
397
393
  });
@@ -458,7 +454,7 @@ var resolveItems = (baseItems, group, entries) => {
458
454
  using: replacements[0].id
459
455
  }, {
460
456
  F: __dxlog_file,
461
- L: 152,
457
+ L: 151,
462
458
  S: void 0,
463
459
  C: (f, a) => f(...a)
464
460
  });
@@ -577,23 +573,21 @@ var Menu = {
577
573
 
578
574
  // src/hooks/useMenuActions.ts
579
575
  import { RegistryContext as RegistryContext2, useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
580
- import { useCallback as useCallback4, useContext as useContext2, useRef } from "react";
576
+ import { useCallback as useCallback4, useContext as useContext2, useMemo as useMemo2 } from "react";
581
577
  import { Graph, Node as Node3 } from "@dxos/app-graph";
582
578
  var useMenuActions = (props) => {
583
579
  const registry = useContext2(RegistryContext2);
584
580
  const menuGraphProps = useAtomValue2(props);
585
- const graphRef = useRef(null);
586
- if (!graphRef.current || graphRef.current.props !== menuGraphProps) {
581
+ const graph = useMemo2(() => {
587
582
  const newGraph = Graph.make({
588
583
  registry
589
584
  });
590
585
  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;
586
+ return newGraph;
587
+ }, [
588
+ registry,
589
+ menuGraphProps
590
+ ]);
597
591
  const items = useCallback4((group) => {
598
592
  return graph.connections(group?.id || Node3.RootId, "child");
599
593
  }, [
@@ -618,7 +612,7 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
618
612
  root(props) {
619
613
  invariant(this._rootId === "root", "Root group can only be at the top level", {
620
614
  F: __dxlog_file2,
621
- L: 41,
615
+ L: 61,
622
616
  S: this,
623
617
  A: [
624
618
  "this._rootId === 'root'",
@@ -627,7 +621,7 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
627
621
  });
628
622
  invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", {
629
623
  F: __dxlog_file2,
630
- L: 42,
624
+ L: 62,
631
625
  S: this,
632
626
  A: [
633
627
  "this._data.nodes.find((node) => node.id === 'root') === undefined",
@@ -659,13 +653,20 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
659
653
  cb(new _MenuBuilderImpl(this._data, id));
660
654
  return this;
661
655
  }
662
- subgraph(subgraph) {
663
- this._data.nodes.push(...subgraph.nodes);
664
- this._data.edges.push(...subgraph.edges);
656
+ subgraph(subgraphOrCb) {
657
+ if (!subgraphOrCb) {
658
+ return this;
659
+ }
660
+ if (typeof subgraphOrCb === "function") {
661
+ subgraphOrCb(new _MenuBuilderImpl(this._data, this._rootId));
662
+ } else {
663
+ this._data.nodes.push(...subgraphOrCb.nodes);
664
+ this._data.edges.push(...subgraphOrCb.edges);
665
+ }
665
666
  return this;
666
667
  }
667
- separator(id, variant = "gap") {
668
- id ??= `separator-${++this._separatorCount}`;
668
+ separator(variant = "gap") {
669
+ const id = `separator-${++this._separatorCount}`;
669
670
  this._data.nodes.push({
670
671
  id,
671
672
  type: MenuSeparatorType,