@dxos/react-ui-menu 0.8.2-staging.7ac8446 → 0.8.3-main.672df60

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 (52) hide show
  1. package/dist/lib/browser/index.mjs +298 -262
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +299 -264
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +298 -262
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/ActionLabel.d.ts +8 -4
  11. package/dist/types/src/components/ActionLabel.d.ts.map +1 -1
  12. package/dist/types/src/components/DropdownMenu.d.ts +4 -4
  13. package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
  14. package/dist/types/src/components/MenuContext.d.ts +4 -13
  15. package/dist/types/src/components/MenuContext.d.ts.map +1 -1
  16. package/dist/types/src/{testing → components}/Menus.stories.d.ts +1 -1
  17. package/dist/types/src/components/Menus.stories.d.ts.map +1 -0
  18. package/dist/types/src/components/ToolbarMenu.d.ts +5 -1
  19. package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
  20. package/dist/types/src/hooks/index.d.ts +2 -0
  21. package/dist/types/src/hooks/index.d.ts.map +1 -0
  22. package/dist/types/src/hooks/useMenuActions.d.ts +13 -0
  23. package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -0
  24. package/dist/types/src/index.d.ts +2 -1
  25. package/dist/types/src/index.d.ts.map +1 -1
  26. package/dist/types/src/testing/generator.d.ts +27 -0
  27. package/dist/types/src/testing/generator.d.ts.map +1 -0
  28. package/dist/types/src/testing/index.d.ts +1 -25
  29. package/dist/types/src/testing/index.d.ts.map +1 -1
  30. package/dist/types/src/{defs.d.ts → types.d.ts} +3 -5
  31. package/dist/types/src/types.d.ts.map +1 -0
  32. package/dist/types/src/util.d.ts +2 -2
  33. package/dist/types/src/util.d.ts.map +1 -1
  34. package/dist/types/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +20 -13
  36. package/src/components/ActionLabel.tsx +11 -8
  37. package/src/components/DropdownMenu.tsx +7 -23
  38. package/src/components/MenuContext.tsx +11 -26
  39. package/src/{testing → components}/Menus.stories.tsx +13 -13
  40. package/src/components/ToolbarMenu.tsx +29 -32
  41. package/src/hooks/index.ts +5 -0
  42. package/src/hooks/useMenuActions.ts +69 -0
  43. package/src/index.ts +3 -1
  44. package/src/testing/generator.ts +116 -0
  45. package/src/testing/index.ts +1 -107
  46. package/src/{defs.ts → types.ts} +2 -5
  47. package/src/util.ts +7 -7
  48. package/dist/types/src/defs.d.ts.map +0 -1
  49. package/dist/types/src/hooks.d.ts +0 -17
  50. package/dist/types/src/hooks.d.ts.map +0 -1
  51. package/dist/types/src/testing/Menus.stories.d.ts.map +0 -1
  52. package/src/hooks.ts +0 -72
@@ -40,29 +40,35 @@ __export(node_exports, {
40
40
  isMenuGroup: () => isMenuGroup,
41
41
  isSeparator: () => isSeparator,
42
42
  menuContextDefaults: () => menuContextDefaults,
43
+ rxFromSignal: () => import_app_graph.rxFromSignal,
43
44
  useMenu: () => useMenu,
44
45
  useMenuActions: () => useMenuActions,
45
46
  useMenuItems: () => useMenuItems
46
47
  });
47
48
  module.exports = __toCommonJS(node_exports);
49
+ var import_app_graph = require("@dxos/app-graph");
50
+ var import_tracking = require("@preact-signals/safe-react/tracking");
48
51
  var import_react_use_controllable_state = require("@radix-ui/react-use-controllable-state");
49
52
  var import_react = __toESM(require("react"));
50
53
  var import_react_ui = require("@dxos/react-ui");
54
+ var import_tracking2 = require("@preact-signals/safe-react/tracking");
51
55
  var import_react2 = __toESM(require("react"));
52
56
  var import_keyboard = require("@dxos/keyboard");
53
57
  var import_react_ui2 = require("@dxos/react-ui");
54
58
  var import_react_ui_theme = require("@dxos/react-ui-theme");
55
- var import_app_graph = require("@dxos/app-graph");
59
+ var import_app_graph2 = require("@dxos/app-graph");
56
60
  var import_util = require("@dxos/util");
61
+ var import_tracking3 = require("@preact-signals/safe-react/tracking");
57
62
  var import_react_context = require("@radix-ui/react-context");
58
63
  var import_react3 = __toESM(require("react"));
64
+ var import_tracking4 = require("@preact-signals/safe-react/tracking");
59
65
  var import_react4 = __toESM(require("react"));
60
66
  var import_react_ui3 = require("@dxos/react-ui");
61
67
  var import_react_ui_attention = require("@dxos/react-ui-attention");
62
- var import_app_graph2 = require("@dxos/app-graph");
63
- var import_signals_react = require("@preact/signals-react");
64
- var import_react5 = require("react");
65
68
  var import_app_graph3 = require("@dxos/app-graph");
69
+ var import_rx_react = require("@effect-rx/rx-react");
70
+ var import_react5 = require("react");
71
+ var import_app_graph4 = require("@dxos/app-graph");
66
72
  var translationKey = "menus";
67
73
  var translations_default = [
68
74
  {
@@ -74,19 +80,17 @@ var translations_default = [
74
80
  var getShortcut = (action) => {
75
81
  return typeof action.properties?.keyBinding === "string" ? action.properties.keyBinding : action.properties?.keyBinding?.[(0, import_util.getHostPlatform)()];
76
82
  };
77
- var noop = () => {
78
- };
79
- var createMenuAction = (id, properties) => ({
83
+ var createMenuAction = (id, invoke, properties) => ({
80
84
  id,
81
- type: import_app_graph.ACTION_TYPE,
85
+ type: import_app_graph2.ACTION_TYPE,
82
86
  properties,
83
- data: noop
87
+ data: invoke
84
88
  });
85
89
  var createMenuItemGroup = (id, properties) => ({
86
90
  id,
87
- type: import_app_graph.ACTION_GROUP_TYPE,
91
+ type: import_app_graph2.ACTION_GROUP_TYPE,
88
92
  properties,
89
- data: import_app_graph.actionGroupSymbol
93
+ data: import_app_graph2.actionGroupSymbol
90
94
  });
91
95
  var createGapSeparator = (id = "gap", source = "root") => ({
92
96
  nodes: [
@@ -125,98 +129,114 @@ var createLineSeparator = (id = "line", source = "root") => ({
125
129
  ]
126
130
  });
127
131
  var ActionLabel = ({ action }) => {
132
+ var _effect = (0, import_tracking2.useSignals)();
133
+ try {
134
+ const shortcut = getShortcut(action);
135
+ const { t } = (0, import_react_ui2.useTranslation)(translationKey);
136
+ return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("span", {
137
+ className: "grow truncate"
138
+ }, (0, import_react_ui2.toLocalizedString)(action.properties.label, t)), shortcut && /* @__PURE__ */ import_react2.default.createElement("span", {
139
+ className: (0, import_react_ui_theme.mx)("shrink-0", import_react_ui_theme.descriptionText)
140
+ }, (0, import_keyboard.keySymbols)(shortcut).join("")));
141
+ } finally {
142
+ _effect.f();
143
+ }
144
+ };
145
+ var actionLabel = (action, t) => {
128
146
  const shortcut = getShortcut(action);
129
- const { t } = (0, import_react_ui2.useTranslation)(translationKey);
130
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("span", {
131
- className: "grow truncate"
132
- }, (0, import_react_ui2.toLocalizedString)(action.properties.label, t)), shortcut && /* @__PURE__ */ import_react2.default.createElement("span", {
133
- className: (0, import_react_ui_theme.mx)("shrink-0", import_react_ui_theme.descriptionText)
134
- }, (0, import_keyboard.keySymbols)(shortcut).join("")));
147
+ return `${(0, import_react_ui2.toLocalizedString)(action.properties.label, t)}${shortcut ? ` (${(0, import_keyboard.keySymbols)(shortcut).join("")})` : ""}`;
135
148
  };
136
149
  var MENU_NAME = "GraphMenu";
137
150
  var [createMenuContext, createMenuScope] = (0, import_react_context.createContextScope)(MENU_NAME, []);
138
151
  var [MenuContextProvider, useMenu] = createMenuContext(MENU_NAME);
139
152
  var menuContextDefaults = {
140
153
  iconSize: 5,
141
- onAction: () => {
142
- },
143
- resolveGroupItems: () => null
154
+ useGroupItems: () => null
144
155
  };
145
156
  var useMenuScope = createMenuScope();
146
- var MenuProvider = ({ children, resolveGroupItems = menuContextDefaults.resolveGroupItems, onAction = menuContextDefaults.onAction, iconSize = menuContextDefaults.iconSize, attendableId }) => {
147
- const { scope } = useMenuScope(void 0);
148
- return /* @__PURE__ */ import_react3.default.createElement(MenuContextProvider, {
149
- resolveGroupItems,
150
- onAction,
151
- iconSize,
152
- attendableId,
153
- scope
154
- }, children);
157
+ var MenuProvider = ({ children, useGroupItems = menuContextDefaults.useGroupItems, iconSize = menuContextDefaults.iconSize, attendableId }) => {
158
+ var _effect = (0, import_tracking3.useSignals)();
159
+ try {
160
+ const { scope } = useMenuScope(void 0);
161
+ return /* @__PURE__ */ import_react3.default.createElement(MenuContextProvider, {
162
+ useGroupItems,
163
+ iconSize,
164
+ attendableId,
165
+ scope
166
+ }, children);
167
+ } finally {
168
+ _effect.f();
169
+ }
155
170
  };
156
171
  var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __menuScope) => {
157
- const { resolveGroupItems } = useMenu(consumerName, __menuScope);
158
- return (0, import_react3.useMemo)(() => propsItems ?? resolveGroupItems?.(group) ?? void 0, [
172
+ const { useGroupItems } = useMenu(consumerName, __menuScope);
173
+ const groupItems = useGroupItems(group);
174
+ return (0, import_react3.useMemo)(() => propsItems ?? groupItems ?? void 0, [
159
175
  propsItems,
160
- group,
161
- resolveGroupItems
176
+ groupItems
162
177
  ]);
163
178
  };
164
179
  var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
165
- const action = item;
166
- const handleClick = (0, import_react.useCallback)((event) => onClick(action, event), [
167
- action,
168
- onClick
169
- ]);
170
- const { iconSize } = useMenu("DropdownMenuItem", __menuScope);
171
- return /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Item, {
172
- onClick: handleClick,
173
- classNames: "gap-2",
174
- disabled: action.properties?.disabled,
175
- ...action.properties?.testId && {
176
- "data-testid": action.properties.testId
177
- }
178
- }, action.properties?.icon && /* @__PURE__ */ import_react.default.createElement(import_react_ui.Icon, {
179
- icon: action.properties.icon,
180
- size: iconSize
181
- }), /* @__PURE__ */ import_react.default.createElement(ActionLabel, {
182
- action
183
- }));
180
+ var _effect = (0, import_tracking.useSignals)();
181
+ try {
182
+ const action = item;
183
+ const handleClick = (0, import_react.useCallback)((event) => onClick(action, event), [
184
+ action,
185
+ onClick
186
+ ]);
187
+ const { iconSize } = useMenu("DropdownMenuItem", __menuScope);
188
+ return /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Item, {
189
+ onClick: handleClick,
190
+ classNames: "gap-2",
191
+ disabled: action.properties?.disabled,
192
+ ...action.properties?.testId && {
193
+ "data-testid": action.properties.testId
194
+ }
195
+ }, action.properties?.icon && /* @__PURE__ */ import_react.default.createElement(import_react_ui.Icon, {
196
+ icon: action.properties.icon,
197
+ size: iconSize
198
+ }), /* @__PURE__ */ import_react.default.createElement(ActionLabel, {
199
+ action
200
+ }));
201
+ } finally {
202
+ _effect.f();
203
+ }
184
204
  };
185
- var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, suppressNextTooltip, children, __menuScope, ...naturalProps }) => {
186
- const [optionsMenuOpen, setOptionsMenuOpen] = (0, import_react_use_controllable_state.useControllableState)({
187
- prop: open,
188
- defaultProp: defaultOpen,
189
- onChange: onOpenChange
190
- });
191
- const { onAction } = useMenu("DropdownMenuRoot", __menuScope);
192
- const handleActionClick = (0, import_react.useCallback)((action, event) => {
193
- if (action.properties?.disabled) {
194
- return;
195
- }
196
- event.stopPropagation();
197
- if (suppressNextTooltip) {
198
- suppressNextTooltip.current = true;
199
- }
200
- setOptionsMenuOpen(false);
201
- onAction?.(action);
202
- }, [
203
- onAction
204
- ]);
205
- const items = useMenuItems(group, propsItems);
206
- return /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Root, {
207
- open: optionsMenuOpen,
208
- onOpenChange: (nextOpen) => {
209
- if (!nextOpen && suppressNextTooltip) {
210
- suppressNextTooltip.current = true;
205
+ var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, caller, children, __menuScope, ...naturalProps }) => {
206
+ var _effect = (0, import_tracking.useSignals)();
207
+ try {
208
+ const [optionsMenuOpen, setOptionsMenuOpen] = (0, import_react_use_controllable_state.useControllableState)({
209
+ prop: open,
210
+ defaultProp: defaultOpen,
211
+ onChange: onOpenChange
212
+ });
213
+ const handleActionClick = (0, import_react.useCallback)((action, event) => {
214
+ if (action.properties?.disabled) {
215
+ return;
211
216
  }
212
- return setOptionsMenuOpen(nextOpen);
213
- },
214
- ...naturalProps
215
- }, children, /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Portal, null, /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Content, null, /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Viewport, null, items?.map((item) => /* @__PURE__ */ import_react.default.createElement(DropdownMenuItem, {
216
- key: item.id,
217
- item,
218
- onClick: handleActionClick
219
- }))), /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Arrow, null))));
217
+ event.stopPropagation();
218
+ setOptionsMenuOpen(false);
219
+ void action.data?.({
220
+ parent: group,
221
+ caller
222
+ });
223
+ }, [
224
+ group,
225
+ caller
226
+ ]);
227
+ const items = useMenuItems(group, propsItems);
228
+ return /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Root, {
229
+ open: optionsMenuOpen,
230
+ onOpenChange: setOptionsMenuOpen,
231
+ ...naturalProps
232
+ }, children, /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Portal, null, /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Content, null, /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Viewport, null, items?.map((item) => /* @__PURE__ */ import_react.default.createElement(DropdownMenuItem, {
233
+ key: item.id,
234
+ item,
235
+ onClick: handleActionClick
236
+ }))), /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Arrow, null))));
237
+ } finally {
238
+ _effect.f();
239
+ }
220
240
  };
221
241
  var DropdownMenu = {
222
242
  Root: DropdownMenuRoot,
@@ -225,170 +245,189 @@ var DropdownMenu = {
225
245
  };
226
246
  var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
227
247
  var isSeparator = (node) => node.type === MenuSeparatorType;
228
- var isMenuGroup = (node) => node.type === import_app_graph2.ACTION_GROUP_TYPE;
248
+ var isMenuGroup = (node) => node.type === import_app_graph3.ACTION_GROUP_TYPE;
229
249
  var ActionToolbarItem = ({ action, __menuScope }) => {
230
- const { onAction, iconSize } = useMenu("ActionToolbarItem", __menuScope);
231
- const handleClick = (0, import_react4.useCallback)(() => {
232
- onAction?.(action);
233
- }, [
234
- action,
235
- onAction
236
- ]);
237
- const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
238
- const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
239
- const rootProps = icon ? {
240
- icon,
241
- size: iconSize,
242
- iconOnly,
243
- label: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
244
- action
245
- })
246
- } : {
247
- children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
250
+ var _effect = (0, import_tracking4.useSignals)();
251
+ try {
252
+ const { iconSize } = useMenu("ActionToolbarItem", __menuScope);
253
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
254
+ const handleClick = (0, import_react4.useCallback)(() => action.data?.(), [
248
255
  action
249
- })
250
- };
251
- return hidden ? null : /* @__PURE__ */ import_react4.default.createElement(Root, {
252
- key: action.id,
253
- disabled,
254
- onClick: handleClick,
255
- variant: "ghost",
256
- ...testId && {
257
- "data-testid": testId
258
- },
259
- ...rootProps,
260
- classNames
261
- });
256
+ ]);
257
+ const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
258
+ const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
259
+ const rootProps = icon ? {
260
+ icon,
261
+ size: iconSize,
262
+ iconOnly,
263
+ label: actionLabel(action, t)
264
+ } : {
265
+ children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
266
+ action
267
+ })
268
+ };
269
+ return hidden ? null : /* @__PURE__ */ import_react4.default.createElement(Root, {
270
+ key: action.id,
271
+ disabled,
272
+ onClick: handleClick,
273
+ variant: "ghost",
274
+ ...testId && {
275
+ "data-testid": testId
276
+ },
277
+ ...rootProps,
278
+ classNames
279
+ });
280
+ } finally {
281
+ _effect.f();
282
+ }
262
283
  };
263
284
  var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
264
- const { iconOnly, disabled, testId } = group.properties;
265
- const suppressNextTooltip = (0, import_react4.useRef)(false);
266
- const { iconSize } = useMenu("DropdownMenuToolbarItem", __menuScope);
267
- const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
268
- const activeItem = items?.find((item) => !!item.properties.checked);
269
- const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
270
- activeItem?.properties.icon || group.properties.icon;
271
- const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
272
- const label = /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
273
- action: group.properties.applyActive && activeItem ? activeItem : group
274
- });
275
- const rootProps = icon ? {
276
- icon,
277
- size: iconSize,
278
- iconOnly,
279
- label,
280
- caretDown: true,
281
- suppressNextTooltip
282
- } : {
283
- children: /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, label, /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Icon, {
284
- size: 3,
285
- icon: "ph--caret-down--bold",
286
- classNames: "mis-1"
287
- }))
288
- };
289
- return /* @__PURE__ */ import_react4.default.createElement(DropdownMenu.Root, {
290
- group,
291
- items,
292
- suppressNextTooltip
293
- }, /* @__PURE__ */ import_react4.default.createElement(DropdownMenu.Trigger, {
294
- asChild: true
295
- }, /* @__PURE__ */ import_react4.default.createElement(Root, {
296
- variant: "ghost",
297
- disabled,
298
- ...rootProps,
299
- ...testId && {
300
- "data-testid": testId
301
- }
302
- })));
285
+ var _effect = (0, import_tracking4.useSignals)();
286
+ try {
287
+ const { iconOnly, disabled, testId } = group.properties;
288
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
289
+ const { iconSize } = useMenu("DropdownMenuToolbarItem", __menuScope);
290
+ const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
291
+ const activeItem = items?.find((item) => !!item.properties.checked);
292
+ const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
293
+ activeItem?.properties.icon || group.properties.icon;
294
+ const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
295
+ const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
296
+ const rootProps = icon ? {
297
+ icon,
298
+ size: iconSize,
299
+ iconOnly,
300
+ label: actionLabel(labelAction, t),
301
+ caretDown: true
302
+ } : {
303
+ children: /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
304
+ action: labelAction
305
+ }), /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Icon, {
306
+ size: 3,
307
+ icon: "ph--caret-down--bold",
308
+ classNames: "mis-1"
309
+ }))
310
+ };
311
+ return /* @__PURE__ */ import_react4.default.createElement(DropdownMenu.Root, {
312
+ group,
313
+ items
314
+ }, /* @__PURE__ */ import_react4.default.createElement(DropdownMenu.Trigger, {
315
+ asChild: true
316
+ }, /* @__PURE__ */ import_react4.default.createElement(Root, {
317
+ variant: "ghost",
318
+ disabled,
319
+ ...rootProps,
320
+ ...testId && {
321
+ "data-testid": testId
322
+ }
323
+ })));
324
+ } finally {
325
+ _effect.f();
326
+ }
303
327
  };
304
- var ToggleGroupItem = ({ action, __menuScope }) => {
305
- const { iconSize, onAction } = useMenu("ToggleGroupItem", __menuScope);
306
- const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
307
- const handleClick = (0, import_react4.useCallback)(() => {
308
- onAction?.(action);
309
- }, [
310
- action,
311
- onAction
312
- ]);
313
- const Root = icon ? import_react_ui3.Toolbar.ToggleGroupIconItem : import_react_ui3.Toolbar.ToggleGroupItem;
314
- const rootProps = icon ? {
315
- icon,
316
- size: iconSize,
317
- iconOnly,
318
- label: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
319
- action
320
- })
321
- } : {
322
- children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
323
- action
324
- })
325
- };
326
- return hidden ? null : /* @__PURE__ */ import_react4.default.createElement(Root, {
327
- key: action.id,
328
- value: action.id,
329
- disabled,
330
- onClick: handleClick,
331
- variant: "ghost",
332
- ...testId && {
333
- "data-testid": testId
334
- },
335
- ...rootProps,
336
- classNames
337
- });
328
+ var ToggleGroupItem = ({ group, action, __menuScope }) => {
329
+ var _effect = (0, import_tracking4.useSignals)();
330
+ try {
331
+ const { iconSize } = useMenu("ToggleGroupItem", __menuScope);
332
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
333
+ const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
334
+ const handleClick = (0, import_react4.useCallback)(() => action.data?.({
335
+ parent: group
336
+ }), [
337
+ action,
338
+ group
339
+ ]);
340
+ const Root = icon ? import_react_ui3.Toolbar.ToggleGroupIconItem : import_react_ui3.Toolbar.ToggleGroupItem;
341
+ const rootProps = icon ? {
342
+ icon,
343
+ size: iconSize,
344
+ iconOnly,
345
+ label: actionLabel(action, t)
346
+ } : {
347
+ children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
348
+ action
349
+ })
350
+ };
351
+ return hidden ? null : /* @__PURE__ */ import_react4.default.createElement(Root, {
352
+ key: action.id,
353
+ value: action.id,
354
+ disabled,
355
+ onClick: handleClick,
356
+ variant: "ghost",
357
+ ...testId && {
358
+ "data-testid": testId
359
+ },
360
+ ...rootProps,
361
+ classNames
362
+ });
363
+ } finally {
364
+ _effect.f();
365
+ }
338
366
  };
339
367
  var ToggleGroupToolbarItem = ({ group, items: propsItems, __menuScope }) => {
340
- const items = useMenuItems(group, propsItems, "ToggleGroupToolbarItem", __menuScope);
341
- const { selectCardinality, value } = group.properties;
342
- return (
343
- // TODO(thure): The type here is difficult to manage, what do?
344
- // @ts-ignore
345
- /* @__PURE__ */ import_react4.default.createElement(
346
- import_react_ui3.Toolbar.ToggleGroup,
347
- {
348
- type: selectCardinality,
349
- value
350
- },
351
- // TODO(thure): Handle other menu item types.
352
- items.map((action) => /* @__PURE__ */ import_react4.default.createElement(ToggleGroupItem, {
353
- key: action.id,
354
- action
355
- }))
356
- )
357
- );
368
+ var _effect = (0, import_tracking4.useSignals)();
369
+ try {
370
+ const items = useMenuItems(group, propsItems, "ToggleGroupToolbarItem", __menuScope);
371
+ const { selectCardinality, value } = group.properties;
372
+ return (
373
+ // TODO(thure): The type here is difficult to manage, what do?
374
+ // @ts-ignore
375
+ /* @__PURE__ */ import_react4.default.createElement(
376
+ import_react_ui3.Toolbar.ToggleGroup,
377
+ {
378
+ type: selectCardinality,
379
+ value
380
+ },
381
+ // TODO(thure): Handle other menu item types.
382
+ items.map((action) => /* @__PURE__ */ import_react4.default.createElement(ToggleGroupItem, {
383
+ key: action.id,
384
+ group,
385
+ action
386
+ }))
387
+ )
388
+ );
389
+ } finally {
390
+ _effect.f();
391
+ }
358
392
  };
359
393
  var ToolbarMenu = ({ __menuScope, classNames, ...props }) => {
360
- const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
361
- const { attendableId } = useMenu("ToolbarMenu", __menuScope);
362
- const { hasAttention } = (0, import_react_ui_attention.useAttention)(attendableId);
363
- return /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Toolbar.Root, {
364
- ...props,
365
- classNames: [
366
- "p-0 pointer-fine:p-1 attention-surface",
367
- !hasAttention && "opacity-20",
368
- classNames
369
- ]
370
- }, items?.map((item, i) => isSeparator(item) ? /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Toolbar.Separator, {
371
- key: i,
372
- variant: item.properties.variant
373
- }) : isMenuGroup(item) ? item.properties.variant === "dropdownMenu" ? (
374
- // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
375
- /* @__PURE__ */ import_react4.default.createElement(DropdownMenuToolbarItem, {
376
- key: item.id,
377
- group: item
378
- })
379
- ) : (
380
- // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
381
- /* @__PURE__ */ import_react4.default.createElement(ToggleGroupToolbarItem, {
382
- key: item.id,
383
- group: item
384
- })
385
- ) : (
386
- // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
387
- /* @__PURE__ */ import_react4.default.createElement(ActionToolbarItem, {
388
- key: item.id,
389
- action: item
390
- })
391
- )));
394
+ var _effect = (0, import_tracking4.useSignals)();
395
+ try {
396
+ const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
397
+ const { attendableId } = useMenu("ToolbarMenu", __menuScope);
398
+ const { hasAttention } = (0, import_react_ui_attention.useAttention)(attendableId);
399
+ return /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Toolbar.Root, {
400
+ ...props,
401
+ classNames: [
402
+ "p-1",
403
+ attendableId && !hasAttention && "[&>*]:opacity-20 !bg-transparent",
404
+ classNames
405
+ ]
406
+ }, items?.map((item, i) => isSeparator(item) ? /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Toolbar.Separator, {
407
+ key: i,
408
+ variant: item.properties.variant
409
+ }) : isMenuGroup(item) ? item.properties.variant === "dropdownMenu" ? (
410
+ // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
411
+ /* @__PURE__ */ import_react4.default.createElement(DropdownMenuToolbarItem, {
412
+ key: item.id,
413
+ group: item
414
+ })
415
+ ) : (
416
+ // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
417
+ /* @__PURE__ */ import_react4.default.createElement(ToggleGroupToolbarItem, {
418
+ key: item.id,
419
+ group: item
420
+ })
421
+ ) : (
422
+ // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
423
+ /* @__PURE__ */ import_react4.default.createElement(ActionToolbarItem, {
424
+ key: item.id,
425
+ action: item
426
+ })
427
+ )));
428
+ } finally {
429
+ _effect.f();
430
+ }
392
431
  };
393
432
  var edgesArrayToRecord = (edges) => {
394
433
  return Object.fromEntries(Object.entries(edges.reduce((acc, { source, target }) => {
@@ -413,35 +452,30 @@ var edgesArrayToRecord = (edges) => {
413
452
  targetEdges.inbound.push(source);
414
453
  }
415
454
  return acc;
416
- }, {})).map(([id, { outbound }]) => [
417
- id,
418
- outbound
419
- ]));
455
+ }, {})));
420
456
  };
421
- var useMenuActions = (actionCreator) => {
422
- const initialMenuGraphProps = actionCreator();
423
- const [graph] = (0, import_react5.useState)(new import_app_graph3.Graph({
424
- nodes: initialMenuGraphProps.nodes,
425
- edges: edgesArrayToRecord(initialMenuGraphProps.edges)
457
+ var useMenuActions = (props) => {
458
+ const registry = (0, import_react5.useContext)(import_rx_react.RegistryContext);
459
+ const menuGraphProps = (0, import_rx_react.useRxValue)(props);
460
+ const [graph] = (0, import_react5.useState)(new import_app_graph4.Graph({
461
+ registry,
462
+ nodes: menuGraphProps.nodes,
463
+ edges: edgesArrayToRecord(menuGraphProps.edges)
426
464
  }));
427
- (0, import_signals_react.useSignalEffect)(() => {
428
- const menuGraphProps = actionCreator();
429
- graph._addNodes(menuGraphProps.nodes);
430
- graph._addEdges(menuGraphProps.edges);
431
- });
432
- const resolveGroupItems = (0, import_react5.useCallback)((sourceNode = graph.root) => {
433
- if (graph) {
434
- return graph.nodes(sourceNode, {
435
- filter: (n) => true
436
- }) || null;
437
- } else {
438
- return null;
439
- }
465
+ (0, import_react5.useEffect)(() => {
466
+ graph.addNodes(menuGraphProps.nodes);
467
+ graph.addEdges(menuGraphProps.edges);
468
+ }, [
469
+ menuGraphProps
470
+ ]);
471
+ const useGroupItems = (0, import_react5.useCallback)((sourceNode) => {
472
+ const items = (0, import_rx_react.useRxValue)(graph.connections(sourceNode?.id || import_app_graph4.ROOT_ID));
473
+ return items;
440
474
  }, [
441
475
  graph
442
476
  ]);
443
477
  return {
444
- resolveGroupItems
478
+ useGroupItems
445
479
  };
446
480
  };
447
481
  // Annotate the CommonJS export names for ESM import in node:
@@ -458,6 +492,7 @@ var useMenuActions = (actionCreator) => {
458
492
  isMenuGroup,
459
493
  isSeparator,
460
494
  menuContextDefaults,
495
+ rxFromSignal,
461
496
  useMenu,
462
497
  useMenuActions,
463
498
  useMenuItems