@dxos/react-ui-menu 0.8.2-main.f11618f → 0.8.2-main.fbd8ed0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +58 -63
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +53 -58
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +58 -63
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ActionLabel.d.ts +8 -4
- package/dist/types/src/components/ActionLabel.d.ts.map +1 -1
- package/dist/types/src/components/DropdownMenu.d.ts +3 -2
- package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/MenuContext.d.ts +4 -13
- package/dist/types/src/components/MenuContext.d.ts.map +1 -1
- package/dist/types/src/{testing → components}/Menus.stories.d.ts +1 -1
- package/dist/types/src/components/Menus.stories.d.ts.map +1 -0
- package/dist/types/src/components/ToolbarMenu.d.ts +5 -1
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useMenuActions.d.ts +12 -0
- package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +26 -0
- package/dist/types/src/testing/generator.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +1 -25
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/{defs.d.ts → types.d.ts} +3 -5
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/src/util.d.ts +2 -2
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -12
- package/src/components/ActionLabel.tsx +11 -8
- package/src/components/DropdownMenu.tsx +5 -5
- package/src/components/MenuContext.tsx +11 -26
- package/src/{testing → components}/Menus.stories.tsx +13 -13
- package/src/components/ToolbarMenu.tsx +27 -29
- package/src/hooks/index.ts +5 -0
- package/src/{hooks.ts → hooks/useMenuActions.ts} +20 -20
- package/src/index.ts +1 -1
- package/src/testing/generator.ts +115 -0
- package/src/testing/index.ts +1 -107
- package/src/{defs.ts → types.ts} +2 -5
- package/src/util.ts +7 -7
- package/dist/types/src/defs.d.ts.map +0 -1
- package/dist/types/src/hooks.d.ts +0 -17
- package/dist/types/src/hooks.d.ts.map +0 -1
- package/dist/types/src/testing/Menus.stories.d.ts.map +0 -1
package/dist/lib/node/index.cjs
CHANGED
|
@@ -60,6 +60,7 @@ var import_react4 = __toESM(require("react"));
|
|
|
60
60
|
var import_react_ui3 = require("@dxos/react-ui");
|
|
61
61
|
var import_react_ui_attention = require("@dxos/react-ui-attention");
|
|
62
62
|
var import_app_graph2 = require("@dxos/app-graph");
|
|
63
|
+
var import_rx_react = require("@effect-rx/rx-react");
|
|
63
64
|
var import_signals_react = require("@preact/signals-react");
|
|
64
65
|
var import_react5 = require("react");
|
|
65
66
|
var import_app_graph3 = require("@dxos/app-graph");
|
|
@@ -74,13 +75,11 @@ var translations_default = [
|
|
|
74
75
|
var getShortcut = (action) => {
|
|
75
76
|
return typeof action.properties?.keyBinding === "string" ? action.properties.keyBinding : action.properties?.keyBinding?.[(0, import_util.getHostPlatform)()];
|
|
76
77
|
};
|
|
77
|
-
var
|
|
78
|
-
};
|
|
79
|
-
var createMenuAction = (id, properties) => ({
|
|
78
|
+
var createMenuAction = (id, invoke, properties) => ({
|
|
80
79
|
id,
|
|
81
80
|
type: import_app_graph.ACTION_TYPE,
|
|
82
81
|
properties,
|
|
83
|
-
data:
|
|
82
|
+
data: invoke
|
|
84
83
|
});
|
|
85
84
|
var createMenuItemGroup = (id, properties) => ({
|
|
86
85
|
id,
|
|
@@ -133,32 +132,33 @@ var ActionLabel = ({ action }) => {
|
|
|
133
132
|
className: (0, import_react_ui_theme.mx)("shrink-0", import_react_ui_theme.descriptionText)
|
|
134
133
|
}, (0, import_keyboard.keySymbols)(shortcut).join("")));
|
|
135
134
|
};
|
|
135
|
+
var actionLabel = (action, t) => {
|
|
136
|
+
const shortcut = getShortcut(action);
|
|
137
|
+
return `${(0, import_react_ui2.toLocalizedString)(action.properties.label, t)}${shortcut ? ` (${(0, import_keyboard.keySymbols)(shortcut).join("")})` : ""}`;
|
|
138
|
+
};
|
|
136
139
|
var MENU_NAME = "GraphMenu";
|
|
137
140
|
var [createMenuContext, createMenuScope] = (0, import_react_context.createContextScope)(MENU_NAME, []);
|
|
138
141
|
var [MenuContextProvider, useMenu] = createMenuContext(MENU_NAME);
|
|
139
142
|
var menuContextDefaults = {
|
|
140
143
|
iconSize: 5,
|
|
141
|
-
|
|
142
|
-
},
|
|
143
|
-
resolveGroupItems: () => null
|
|
144
|
+
useGroupItems: () => null
|
|
144
145
|
};
|
|
145
146
|
var useMenuScope = createMenuScope();
|
|
146
|
-
var MenuProvider = ({ children,
|
|
147
|
+
var MenuProvider = ({ children, useGroupItems = menuContextDefaults.useGroupItems, iconSize = menuContextDefaults.iconSize, attendableId }) => {
|
|
147
148
|
const { scope } = useMenuScope(void 0);
|
|
148
149
|
return /* @__PURE__ */ import_react3.default.createElement(MenuContextProvider, {
|
|
149
|
-
|
|
150
|
-
onAction,
|
|
150
|
+
useGroupItems,
|
|
151
151
|
iconSize,
|
|
152
152
|
attendableId,
|
|
153
153
|
scope
|
|
154
154
|
}, children);
|
|
155
155
|
};
|
|
156
156
|
var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __menuScope) => {
|
|
157
|
-
const {
|
|
158
|
-
|
|
157
|
+
const { useGroupItems } = useMenu(consumerName, __menuScope);
|
|
158
|
+
const groupItems = useGroupItems(group);
|
|
159
|
+
return (0, import_react3.useMemo)(() => propsItems ?? groupItems ?? void 0, [
|
|
159
160
|
propsItems,
|
|
160
|
-
|
|
161
|
-
resolveGroupItems
|
|
161
|
+
groupItems
|
|
162
162
|
]);
|
|
163
163
|
};
|
|
164
164
|
var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
|
|
@@ -182,13 +182,12 @@ var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
|
|
|
182
182
|
action
|
|
183
183
|
}));
|
|
184
184
|
};
|
|
185
|
-
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, suppressNextTooltip, children, __menuScope, ...naturalProps }) => {
|
|
185
|
+
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, suppressNextTooltip, caller, children, __menuScope, ...naturalProps }) => {
|
|
186
186
|
const [optionsMenuOpen, setOptionsMenuOpen] = (0, import_react_use_controllable_state.useControllableState)({
|
|
187
187
|
prop: open,
|
|
188
188
|
defaultProp: defaultOpen,
|
|
189
189
|
onChange: onOpenChange
|
|
190
190
|
});
|
|
191
|
-
const { onAction } = useMenu("DropdownMenuRoot", __menuScope);
|
|
192
191
|
const handleActionClick = (0, import_react.useCallback)((action, event) => {
|
|
193
192
|
if (action.properties?.disabled) {
|
|
194
193
|
return;
|
|
@@ -198,9 +197,14 @@ var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenCha
|
|
|
198
197
|
suppressNextTooltip.current = true;
|
|
199
198
|
}
|
|
200
199
|
setOptionsMenuOpen(false);
|
|
201
|
-
|
|
200
|
+
void action.data?.({
|
|
201
|
+
parent: group,
|
|
202
|
+
caller
|
|
203
|
+
});
|
|
202
204
|
}, [
|
|
203
|
-
|
|
205
|
+
suppressNextTooltip,
|
|
206
|
+
group,
|
|
207
|
+
caller
|
|
204
208
|
]);
|
|
205
209
|
const items = useMenuItems(group, propsItems);
|
|
206
210
|
return /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Root, {
|
|
@@ -227,12 +231,10 @@ var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
|
|
|
227
231
|
var isSeparator = (node) => node.type === MenuSeparatorType;
|
|
228
232
|
var isMenuGroup = (node) => node.type === import_app_graph2.ACTION_GROUP_TYPE;
|
|
229
233
|
var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
230
|
-
const {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
action,
|
|
235
|
-
onAction
|
|
234
|
+
const { iconSize } = useMenu("ActionToolbarItem", __menuScope);
|
|
235
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
236
|
+
const handleClick = (0, import_react4.useCallback)(() => action.data?.(), [
|
|
237
|
+
action
|
|
236
238
|
]);
|
|
237
239
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
238
240
|
const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
|
|
@@ -240,9 +242,7 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
240
242
|
icon,
|
|
241
243
|
size: iconSize,
|
|
242
244
|
iconOnly,
|
|
243
|
-
label:
|
|
244
|
-
action
|
|
245
|
-
})
|
|
245
|
+
label: actionLabel(action, t)
|
|
246
246
|
} : {
|
|
247
247
|
children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
|
|
248
248
|
action
|
|
@@ -263,24 +263,25 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
263
263
|
var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
264
264
|
const { iconOnly, disabled, testId } = group.properties;
|
|
265
265
|
const suppressNextTooltip = (0, import_react4.useRef)(false);
|
|
266
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
266
267
|
const { iconSize } = useMenu("DropdownMenuToolbarItem", __menuScope);
|
|
267
268
|
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
268
269
|
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
269
270
|
const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
|
|
270
271
|
activeItem?.properties.icon || group.properties.icon;
|
|
271
272
|
const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
|
|
272
|
-
const
|
|
273
|
-
action: group.properties.applyActive && activeItem ? activeItem : group
|
|
274
|
-
});
|
|
273
|
+
const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
|
|
275
274
|
const rootProps = icon ? {
|
|
276
275
|
icon,
|
|
277
276
|
size: iconSize,
|
|
278
277
|
iconOnly,
|
|
279
|
-
label,
|
|
278
|
+
label: actionLabel(labelAction, t),
|
|
280
279
|
caretDown: true,
|
|
281
280
|
suppressNextTooltip
|
|
282
281
|
} : {
|
|
283
|
-
children: /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null,
|
|
282
|
+
children: /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
|
|
283
|
+
action: labelAction
|
|
284
|
+
}), /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Icon, {
|
|
284
285
|
size: 3,
|
|
285
286
|
icon: "ph--caret-down--bold",
|
|
286
287
|
classNames: "mis-1"
|
|
@@ -301,23 +302,22 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
301
302
|
}
|
|
302
303
|
})));
|
|
303
304
|
};
|
|
304
|
-
var ToggleGroupItem = ({ action, __menuScope }) => {
|
|
305
|
-
const { iconSize
|
|
305
|
+
var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
306
|
+
const { iconSize } = useMenu("ToggleGroupItem", __menuScope);
|
|
307
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
306
308
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
307
|
-
const handleClick = (0, import_react4.useCallback)(() => {
|
|
308
|
-
|
|
309
|
-
}, [
|
|
309
|
+
const handleClick = (0, import_react4.useCallback)(() => action.data?.({
|
|
310
|
+
parent: group
|
|
311
|
+
}), [
|
|
310
312
|
action,
|
|
311
|
-
|
|
313
|
+
group
|
|
312
314
|
]);
|
|
313
315
|
const Root = icon ? import_react_ui3.Toolbar.ToggleGroupIconItem : import_react_ui3.Toolbar.ToggleGroupItem;
|
|
314
316
|
const rootProps = icon ? {
|
|
315
317
|
icon,
|
|
316
318
|
size: iconSize,
|
|
317
319
|
iconOnly,
|
|
318
|
-
label:
|
|
319
|
-
action
|
|
320
|
-
})
|
|
320
|
+
label: actionLabel(action, t)
|
|
321
321
|
} : {
|
|
322
322
|
children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
|
|
323
323
|
action
|
|
@@ -351,6 +351,7 @@ var ToggleGroupToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
351
351
|
// TODO(thure): Handle other menu item types.
|
|
352
352
|
items.map((action) => /* @__PURE__ */ import_react4.default.createElement(ToggleGroupItem, {
|
|
353
353
|
key: action.id,
|
|
354
|
+
group,
|
|
354
355
|
action
|
|
355
356
|
}))
|
|
356
357
|
)
|
|
@@ -363,8 +364,8 @@ var ToolbarMenu = ({ __menuScope, classNames, ...props }) => {
|
|
|
363
364
|
return /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Toolbar.Root, {
|
|
364
365
|
...props,
|
|
365
366
|
classNames: [
|
|
366
|
-
"p-
|
|
367
|
-
!hasAttention && "opacity-20",
|
|
367
|
+
"p-1",
|
|
368
|
+
!hasAttention && "[&>*]:opacity-20 !bg-transparent",
|
|
368
369
|
classNames
|
|
369
370
|
]
|
|
370
371
|
}, items?.map((item, i) => isSeparator(item) ? /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Toolbar.Separator, {
|
|
@@ -413,35 +414,29 @@ var edgesArrayToRecord = (edges) => {
|
|
|
413
414
|
targetEdges.inbound.push(source);
|
|
414
415
|
}
|
|
415
416
|
return acc;
|
|
416
|
-
}, {}))
|
|
417
|
-
id,
|
|
418
|
-
outbound
|
|
419
|
-
]));
|
|
417
|
+
}, {})));
|
|
420
418
|
};
|
|
421
419
|
var useMenuActions = (actionCreator) => {
|
|
420
|
+
const registry = (0, import_react5.useContext)(import_rx_react.RegistryContext);
|
|
422
421
|
const initialMenuGraphProps = actionCreator();
|
|
423
422
|
const [graph] = (0, import_react5.useState)(new import_app_graph3.Graph({
|
|
423
|
+
registry,
|
|
424
424
|
nodes: initialMenuGraphProps.nodes,
|
|
425
425
|
edges: edgesArrayToRecord(initialMenuGraphProps.edges)
|
|
426
426
|
}));
|
|
427
427
|
(0, import_signals_react.useSignalEffect)(() => {
|
|
428
428
|
const menuGraphProps = actionCreator();
|
|
429
|
-
graph.
|
|
430
|
-
graph.
|
|
429
|
+
graph.addNodes(menuGraphProps.nodes);
|
|
430
|
+
graph.addEdges(menuGraphProps.edges);
|
|
431
431
|
});
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
filter: (n) => true
|
|
436
|
-
}) || null;
|
|
437
|
-
} else {
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
432
|
+
const useGroupItems = (0, import_react5.useCallback)((sourceNode) => {
|
|
433
|
+
const items = (0, import_rx_react.useRxValue)(graph.connections(sourceNode?.id || import_app_graph3.ROOT_ID));
|
|
434
|
+
return items;
|
|
440
435
|
}, [
|
|
441
436
|
graph
|
|
442
437
|
]);
|
|
443
438
|
return {
|
|
444
|
-
|
|
439
|
+
useGroupItems
|
|
445
440
|
};
|
|
446
441
|
};
|
|
447
442
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/DropdownMenu.tsx", "../../../src/components/ActionLabel.tsx", "../../../src/translations.ts", "../../../src/util.ts", "../../../src/components/MenuContext.tsx", "../../../src/components/ToolbarMenu.tsx", "../../../src/
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, { type MouseEvent, type MutableRefObject, useCallback } from 'react';\n\nimport { DropdownMenu as NaturalDropdownMenu, Icon, type DropdownMenuRootProps } from '@dxos/react-ui';\n\nimport { ActionLabel } from './ActionLabel';\nimport { type MenuScopedProps, useMenu, useMenuItems } from './MenuContext';\nimport { type MenuAction, type MenuItem, type MenuItemGroup } from '../defs';\n\nexport type DropdownMenuProps = DropdownMenuRootProps & {\n group?: MenuItemGroup;\n items?: MenuItem[];\n suppressNextTooltip?: MutableRefObject<boolean>;\n};\n\nconst DropdownMenuItem = ({\n item,\n onClick,\n __menuScope,\n}: MenuScopedProps<{\n item: MenuItem;\n onClick: (action: MenuAction, event: MouseEvent) => void;\n}>) => {\n // TODO(thure): handle other items.\n const action = item as MenuAction;\n const handleClick = useCallback((event: MouseEvent) => onClick(action, event), [action, onClick]);\n const { iconSize } = useMenu('DropdownMenuItem', __menuScope);\n return (\n <NaturalDropdownMenu.Item\n onClick={handleClick}\n classNames='gap-2'\n disabled={action.properties?.disabled}\n {...(action.properties?.testId && { 'data-testid': action.properties.testId })}\n >\n {action.properties?.icon && <Icon icon={action.properties!.icon} size={iconSize} />}\n <ActionLabel action={action} />\n </NaturalDropdownMenu.Item>\n );\n};\n\nconst DropdownMenuRoot = ({\n items: propsItems,\n group,\n open,\n defaultOpen,\n onOpenChange,\n suppressNextTooltip,\n children,\n __menuScope,\n ...naturalProps\n}: MenuScopedProps<DropdownMenuProps>) => {\n const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({\n prop: open,\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n });\n\n const { onAction } = useMenu('DropdownMenuRoot', __menuScope);\n\n const handleActionClick = useCallback(\n (action: MenuAction, event: MouseEvent) => {\n if (action.properties?.disabled) {\n return;\n }\n event.stopPropagation();\n // TODO(thure): Why does Dialog’s modal-ness cause issues if we don’t explicitly close the menu here?\n if (suppressNextTooltip) {\n suppressNextTooltip.current = true;\n }\n setOptionsMenuOpen(false);\n onAction?.(action);\n },\n [onAction],\n );\n\n const items = useMenuItems(group, propsItems);\n\n return (\n <NaturalDropdownMenu.Root\n {...{\n open: optionsMenuOpen,\n onOpenChange: (nextOpen: boolean) => {\n if (!nextOpen && suppressNextTooltip) {\n suppressNextTooltip.current = true;\n }\n return setOptionsMenuOpen(nextOpen);\n },\n }}\n {...naturalProps}\n >\n {children}\n <NaturalDropdownMenu.Portal>\n <NaturalDropdownMenu.Content>\n <NaturalDropdownMenu.Viewport>\n {items?.map((item) => <DropdownMenuItem key={item.id} item={item} onClick={handleActionClick} />)}\n </NaturalDropdownMenu.Viewport>\n <NaturalDropdownMenu.Arrow />\n </NaturalDropdownMenu.Content>\n </NaturalDropdownMenu.Portal>\n </NaturalDropdownMenu.Root>\n );\n};\n\nexport const DropdownMenu = {\n Root: DropdownMenuRoot,\n Trigger: NaturalDropdownMenu.Trigger,\n VirtualTrigger: NaturalDropdownMenu.VirtualTrigger,\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type Action, type ActionGroup } from '@dxos/app-graph';\nimport { keySymbols } from '@dxos/keyboard';\nimport { toLocalizedString, useTranslation } from '@dxos/react-ui';\nimport { mx, descriptionText } from '@dxos/react-ui-theme';\n\nimport { type MenuActionProperties } from '../defs';\nimport { translationKey } from '../translations';\nimport { getShortcut } from '../util';\n\nexport const ActionLabel = ({\n action,\n}: {\n action: Action<MenuActionProperties> | ActionGroup<Omit<MenuActionProperties, 'variant'>>;\n}) => {\n const shortcut = getShortcut(action);\n const { t } = useTranslation(translationKey);\n\n return (\n <>\n <span className='grow truncate'>{toLocalizedString(action.properties!.label, t)}</span>\n {shortcut && <span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>}\n </>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport const translationKey = 'menus';\n\nexport default [\n {\n 'en-US': {\n [translationKey]: {},\n },\n },\n] as const;\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { ACTION_GROUP_TYPE, ACTION_TYPE, actionGroupSymbol, type ActionLike } from '@dxos/app-graph';\nimport { getHostPlatform } from '@dxos/util';\n\nimport {\n type MenuAction,\n type MenuActionProperties,\n type MenuItemGroup,\n type MenuItemGroupProperties,\n type MenuSeparator,\n} from './defs';\n\nexport const getShortcut = (action: ActionLike) => {\n return typeof action.properties?.keyBinding === 'string'\n ? action.properties.keyBinding\n : action.properties?.keyBinding?.[getHostPlatform()];\n};\n\nexport const fallbackIcon = 'ph--placeholder--regular';\n\n// TODO(thure,wittjosiah): This is probably a smell; consider the whether react-ui-menu should use action nodes if the\n// callback in `data` is never used. See https://github.com/dxos/dxos/pull/8506#discussion_r1925855118\nconst noop = () => {};\n\nexport const createMenuAction = <P extends {} = {}>(id: string, properties: P & MenuActionProperties) =>\n ({\n id,\n type: ACTION_TYPE,\n properties,\n data: noop,\n }) satisfies MenuAction;\n\nexport const createMenuItemGroup = <\n P extends MenuItemGroupProperties = MenuItemGroupProperties & Partial<MenuActionProperties>,\n>(\n id: string,\n properties: P,\n) =>\n ({\n id,\n type: ACTION_GROUP_TYPE,\n properties,\n data: actionGroupSymbol,\n }) satisfies MenuItemGroup;\n\nexport const createGapSeparator = (id: string = 'gap', source: string = 'root') => ({\n nodes: [\n {\n id,\n type: '@dxos/react-ui-toolbar/separator',\n properties: { variant: 'gap' },\n data: undefined as never,\n } satisfies MenuSeparator,\n ],\n edges: [{ source, target: id }],\n});\n\nexport const createLineSeparator = (id: string = 'line', source: string = 'root') => ({\n nodes: [\n {\n id,\n type: '@dxos/react-ui-toolbar/separator',\n properties: { variant: 'line' },\n data: undefined as never,\n } satisfies MenuSeparator,\n ],\n edges: [{ source, target: id }],\n});\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContextScope, type Scope } from '@radix-ui/react-context';\nimport React, { type PropsWithChildren, useMemo } from 'react';\n\nimport { type Node } from '@dxos/app-graph';\n\nimport {\n type MenuActionHandler,\n type MenuAction,\n type MenuContextValue,\n type MenuItem,\n type MenuItemGroup,\n} from '../defs';\n\nexport type MenuScopedProps<P> = P & { __menuScope?: Scope };\n\nconst MENU_NAME = 'GraphMenu';\n\nconst [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);\n\nconst [MenuContextProvider, useMenu] = createMenuContext<MenuContextValue<any>>(MENU_NAME);\n\nexport const menuContextDefaults: MenuContextValue<MenuAction> = {\n iconSize: 5,\n onAction: () => {},\n resolveGroupItems: () => null,\n};\n\nconst useMenuScope = createMenuScope();\n\nconst MenuProvider = <A extends Node = MenuAction>({\n children,\n resolveGroupItems = menuContextDefaults.resolveGroupItems,\n onAction = menuContextDefaults.onAction as MenuActionHandler<A>,\n iconSize = menuContextDefaults.iconSize,\n attendableId,\n}: PropsWithChildren<Partial<MenuContextValue<A>>>) => {\n const { scope } = useMenuScope(undefined);\n return (\n <MenuContextProvider\n resolveGroupItems={resolveGroupItems}\n onAction={onAction}\n iconSize={iconSize}\n attendableId={attendableId}\n scope={scope}\n >\n {children}\n </MenuContextProvider>\n );\n};\n\nexport const useMenuItems = (\n group?: MenuItemGroup,\n propsItems?: MenuItem[],\n consumerName: string = 'useMenuItemConsumer',\n __menuScope?: Scope,\n) => {\n const { resolveGroupItems } = useMenu(consumerName, __menuScope);\n return useMemo(() => propsItems ?? resolveGroupItems?.(group) ?? undefined, [propsItems, group, resolveGroupItems]);\n};\n\nexport { useMenu, createMenuScope, MenuProvider };\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useRef } from 'react';\n\nimport { Icon, type IconButtonProps, Toolbar as NaturalToolbar, type ToolbarRootProps } from '@dxos/react-ui';\nimport { useAttention } from '@dxos/react-ui-attention';\n\nimport { ActionLabel } from './ActionLabel';\nimport { DropdownMenu } from './DropdownMenu';\nimport { type MenuScopedProps, useMenu, useMenuItems } from './MenuContext';\nimport {\n type MenuAction,\n type MenuItem,\n isMenuGroup,\n isSeparator,\n type MenuItemGroup,\n type MenuActionProperties,\n type MenuMultipleSelectActionGroup,\n type MenuSingleSelectActionGroup,\n} from '../defs';\n\nexport type ToolbarMenuDropdownMenuActionGroup = Omit<MenuActionProperties, 'variant' | 'icon'> & {\n variant: 'dropdownMenu';\n icon: string;\n applyActive?: boolean;\n};\n\nexport type ToolbarMenuToggleGroupActionGroup = Omit<MenuActionProperties, 'variant'> & {\n variant: 'toggleGroup';\n};\n\nexport type ToolbarMenuActionGroupProperties = (\n | ToolbarMenuDropdownMenuActionGroup\n | ToolbarMenuToggleGroupActionGroup\n) &\n (MenuSingleSelectActionGroup | MenuMultipleSelectActionGroup);\n\nexport type ToolbarMenuProps = ToolbarRootProps;\n\nexport type ToolbarMenuActionGroupProps = {\n group: MenuItemGroup<ToolbarMenuActionGroupProperties>;\n items?: MenuItem[];\n};\n\nconst ActionToolbarItem = ({ action, __menuScope }: MenuScopedProps<{ action: MenuAction }>) => {\n const { onAction, iconSize } = useMenu('ActionToolbarItem', __menuScope);\n const handleClick = useCallback(() => {\n onAction?.(action);\n }, [action, onAction]);\n const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;\n const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;\n const rootProps = icon\n ? { icon, size: iconSize, iconOnly, label: <ActionLabel action={action} /> }\n : { children: <ActionLabel action={action} /> };\n return hidden ? null : (\n <Root\n key={action.id}\n disabled={disabled}\n onClick={handleClick}\n variant='ghost'\n {...(testId && { 'data-testid': testId })}\n {...(rootProps as IconButtonProps)}\n classNames={classNames}\n />\n );\n};\n\nconst DropdownMenuToolbarItem = ({\n group,\n items: propsItems,\n __menuScope,\n}: MenuScopedProps<ToolbarMenuActionGroupProps>) => {\n const { iconOnly, disabled, testId } = group.properties;\n const suppressNextTooltip = useRef(false);\n const { iconSize } = useMenu('DropdownMenuToolbarItem', __menuScope);\n const items = useMenuItems(group, propsItems, 'DropdownMenuToolbarItem', __menuScope);\n const activeItem = items?.find((item) => !!(item as MenuAction).properties.checked);\n const icon =\n ((group.properties as any).applyActive &&\n // TODO(thure): Handle other menu item types.\n (activeItem as MenuAction)?.properties.icon) ||\n group.properties.icon;\n const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;\n const label = (\n <ActionLabel action={(group.properties as any).applyActive && activeItem ? (activeItem as MenuAction) : group} />\n );\n const rootProps = icon\n ? { icon, size: iconSize, iconOnly, label, caretDown: true, suppressNextTooltip }\n : {\n children: (\n <>\n {label}\n <Icon size={3} icon='ph--caret-down--bold' classNames='mis-1' />\n </>\n ),\n };\n return (\n <DropdownMenu.Root group={group} items={items} suppressNextTooltip={suppressNextTooltip}>\n <DropdownMenu.Trigger asChild>\n <Root\n variant='ghost'\n disabled={disabled}\n {...(rootProps as IconButtonProps)}\n {...(testId && { 'data-testid': testId })}\n />\n </DropdownMenu.Trigger>\n </DropdownMenu.Root>\n );\n};\n\nconst ToggleGroupItem = ({ action, __menuScope }: MenuScopedProps<{ action: MenuAction }>) => {\n const { iconSize, onAction } = useMenu('ToggleGroupItem', __menuScope);\n const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;\n const handleClick = useCallback(() => {\n onAction?.(action);\n }, [action, onAction]);\n const Root = icon ? NaturalToolbar.ToggleGroupIconItem : NaturalToolbar.ToggleGroupItem;\n const rootProps = icon\n ? { icon, size: iconSize, iconOnly, label: <ActionLabel action={action} /> }\n : { children: <ActionLabel action={action} /> };\n return hidden ? null : (\n <Root\n key={action.id}\n value={action.id as any}\n disabled={disabled}\n onClick={handleClick}\n variant='ghost'\n {...(testId && { 'data-testid': testId })}\n {...(rootProps as IconButtonProps)}\n classNames={classNames}\n />\n );\n};\n\nconst ToggleGroupToolbarItem = ({\n group,\n items: propsItems,\n __menuScope,\n}: MenuScopedProps<ToolbarMenuActionGroupProps>) => {\n const items = useMenuItems(group, propsItems, 'ToggleGroupToolbarItem', __menuScope);\n const { selectCardinality, value } = group.properties;\n return (\n // TODO(thure): The type here is difficult to manage, what do?\n // @ts-ignore\n <NaturalToolbar.ToggleGroup type={selectCardinality} value={value}>\n {\n // TODO(thure): Handle other menu item types.\n (items as MenuAction[]).map((action) => (\n <ToggleGroupItem key={action.id} action={action} />\n ))\n }\n </NaturalToolbar.ToggleGroup>\n );\n};\n\nexport const ToolbarMenu = ({ __menuScope, classNames, ...props }: MenuScopedProps<ToolbarMenuProps>) => {\n const items = useMenuItems(undefined, undefined, 'ToolbarMenu', __menuScope);\n const { attendableId } = useMenu('ToolbarMenu', __menuScope);\n const { hasAttention } = useAttention(attendableId);\n return (\n <NaturalToolbar.Root\n {...props}\n classNames={['p-0 pointer-fine:p-1 attention-surface', !hasAttention && 'opacity-20', classNames]}\n >\n {items?.map((item: MenuItem, i: number) =>\n isSeparator(item) ? (\n <NaturalToolbar.Separator key={i} variant={item.properties.variant} />\n ) : isMenuGroup(item) ? (\n item.properties.variant === 'dropdownMenu' ? (\n // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.\n <DropdownMenuToolbarItem key={item.id} group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />\n ) : (\n // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.\n <ToggleGroupToolbarItem key={item.id} group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />\n )\n ) : (\n // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.\n <ActionToolbarItem key={item.id} action={item as MenuAction} />\n ),\n )}\n </NaturalToolbar.Root>\n );\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Node, type Action, type ActionGroup, ACTION_GROUP_TYPE } from '@dxos/app-graph';\nimport { type ToolbarSeparatorProps, type Label, type IconButtonProps, type ClassNameValue } from '@dxos/react-ui';\n\nexport type MenuActionProperties = {\n label: Label;\n icon?: string;\n value?: string;\n disabled?: boolean;\n hidden?: boolean;\n iconOnly?: boolean;\n testId?: string;\n variant?: 'action' | 'toggle';\n checked?: boolean;\n classNames?: ClassNameValue;\n};\n\nexport type MenuItemGroupProperties = {\n label: Label;\n icon?: string;\n iconOnly?: boolean;\n};\n\nexport type MenuAction<P extends {} = {}> = Action<P & MenuActionProperties>;\n\nexport type MenuActionHandler<A extends Node = MenuAction> = (action: A) => void;\n\nexport const MenuSeparatorType = '@dxos/react-ui-toolbar/separator' as const;\n\nexport type MenuSeparator = Node<never, Pick<ToolbarSeparatorProps, 'variant'>> & {\n type: typeof MenuSeparatorType;\n};\n\nexport const isSeparator = (node: Node): node is MenuSeparator => node.type === MenuSeparatorType;\n\nexport type MenuSingleSelectActionGroup = { selectCardinality: 'single'; value: string };\nexport type MenuMultipleSelectActionGroup = { selectCardinality: 'multiple'; value: string[] };\n\nexport type MenuItemGroup<P extends Record<string, any> = Record<string, any>> = ActionGroup<P>;\n\nexport const isMenuGroup = (node: Node): node is MenuItemGroup => node.type === ACTION_GROUP_TYPE;\n\nexport type MenuItem = MenuSeparator | MenuAction | MenuItemGroup;\n\nexport type MenuItemsResolver = (group?: MenuItemGroup) => MenuItem[] | null;\n\nexport type MenuContextValue<A extends Node = MenuAction> = {\n resolveGroupItems: MenuItemsResolver;\n iconSize: IconButtonProps['size'];\n onAction: MenuActionHandler<A>;\n attendableId?: string;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useSignalEffect } from '@preact/signals-react';\nimport { useCallback, useState } from 'react';\n\nimport { Graph, type NodeArg, type Node } from '@dxos/app-graph';\n\nimport { type MenuItem, type MenuItemGroup } from './defs';\n\ntype Edge = { source: string; target: string };\n\nconst edgesArrayToRecord = (edges: { source: string; target: string }[]): Record<string, string[]> => {\n return Object.fromEntries(\n Object.entries(\n edges.reduce((acc: Record<string, { inbound: string[]; outbound: string[] }>, { source, target }) => {\n if (!acc[source]) {\n acc[source] = { inbound: [], outbound: [] };\n }\n if (!acc[target]) {\n acc[target] = { inbound: [], outbound: [] };\n }\n\n const sourceEdges = acc[source];\n if (!sourceEdges.outbound.includes(target)) {\n sourceEdges.outbound.push(target);\n }\n\n const targetEdges = acc[target];\n if (!targetEdges.inbound.includes(source)) {\n targetEdges.inbound.push(source);\n }\n\n return acc;\n }, {}),\n ).map(([id, { outbound }]): [string, string[]] => [id, outbound]),\n );\n};\n\nexport type ActionGraphNodes = NodeArg<any>[];\nexport type ActionGraphEdges = Edge[];\nexport type ActionGraphProps = { nodes: ActionGraphNodes; edges: ActionGraphEdges };\n\nexport const useMenuActions = (actionCreator: () => ActionGraphProps) => {\n const initialMenuGraphProps = actionCreator();\n\n const [graph] = useState(\n new Graph({ nodes: initialMenuGraphProps.nodes as Node[], edges: edgesArrayToRecord(initialMenuGraphProps.edges) }),\n );\n\n useSignalEffect(() => {\n const menuGraphProps = actionCreator();\n // @ts-ignore\n graph._addNodes(menuGraphProps.nodes);\n // @ts-ignore\n graph._addEdges(menuGraphProps.edges);\n });\n\n const resolveGroupItems = useCallback(\n (sourceNode: MenuItemGroup = graph.root as MenuItemGroup) => {\n if (graph) {\n return (graph.nodes(sourceNode, { filter: (n): n is any => true }) || null) as MenuItem[] | null;\n } else {\n return null;\n }\n },\n [graph],\n );\n\n return { resolveGroupItems };\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,0CAAqC;AACrC,mBAA2E;AAE3E,sBAAsF;ACHtF,IAAAA,gBAAkB;AAGlB,sBAA2B;AAC3B,IAAAC,
|
|
6
|
-
"names": ["import_react", "import_react_ui", "import_app_graph", "translationKey", "getShortcut", "action", "properties", "keyBinding", "getHostPlatform", "
|
|
3
|
+
"sources": ["../../../src/components/DropdownMenu.tsx", "../../../src/components/ActionLabel.tsx", "../../../src/translations.ts", "../../../src/util.ts", "../../../src/components/MenuContext.tsx", "../../../src/components/ToolbarMenu.tsx", "../../../src/types.ts", "../../../src/hooks/useMenuActions.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, { type MouseEvent, type MutableRefObject, useCallback } from 'react';\n\nimport { DropdownMenu as NaturalDropdownMenu, Icon, type DropdownMenuRootProps } from '@dxos/react-ui';\n\nimport { ActionLabel } from './ActionLabel';\nimport { type MenuScopedProps, useMenu, useMenuItems } from './MenuContext';\nimport { type MenuAction, type MenuItem, type MenuItemGroup } from '../types';\n\nexport type DropdownMenuProps = DropdownMenuRootProps & {\n group?: MenuItemGroup;\n items?: MenuItem[];\n suppressNextTooltip?: MutableRefObject<boolean>;\n caller?: string;\n};\n\nconst DropdownMenuItem = ({\n item,\n onClick,\n __menuScope,\n}: MenuScopedProps<{\n item: MenuItem;\n onClick: (action: MenuAction, event: MouseEvent) => void;\n}>) => {\n // TODO(thure): handle other items.\n const action = item as MenuAction;\n const handleClick = useCallback((event: MouseEvent) => onClick(action, event), [action, onClick]);\n const { iconSize } = useMenu('DropdownMenuItem', __menuScope);\n return (\n <NaturalDropdownMenu.Item\n onClick={handleClick}\n classNames='gap-2'\n disabled={action.properties?.disabled}\n {...(action.properties?.testId && { 'data-testid': action.properties.testId })}\n >\n {action.properties?.icon && <Icon icon={action.properties!.icon} size={iconSize} />}\n <ActionLabel action={action} />\n </NaturalDropdownMenu.Item>\n );\n};\n\nconst DropdownMenuRoot = ({\n items: propsItems,\n group,\n open,\n defaultOpen,\n onOpenChange,\n suppressNextTooltip,\n caller,\n children,\n __menuScope,\n ...naturalProps\n}: MenuScopedProps<DropdownMenuProps>) => {\n const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({\n prop: open,\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n });\n\n const handleActionClick = useCallback(\n (action: MenuAction, event: MouseEvent) => {\n if (action.properties?.disabled) {\n return;\n }\n event.stopPropagation();\n // TODO(thure): Why does Dialog’s modal-ness cause issues if we don’t explicitly close the menu here?\n if (suppressNextTooltip) {\n suppressNextTooltip.current = true;\n }\n setOptionsMenuOpen(false);\n void action.data?.({ parent: group, caller });\n },\n [suppressNextTooltip, group, caller],\n );\n\n const items = useMenuItems(group, propsItems);\n\n return (\n <NaturalDropdownMenu.Root\n {...{\n open: optionsMenuOpen,\n onOpenChange: (nextOpen: boolean) => {\n if (!nextOpen && suppressNextTooltip) {\n suppressNextTooltip.current = true;\n }\n return setOptionsMenuOpen(nextOpen);\n },\n }}\n {...naturalProps}\n >\n {children}\n <NaturalDropdownMenu.Portal>\n <NaturalDropdownMenu.Content>\n <NaturalDropdownMenu.Viewport>\n {items?.map((item) => <DropdownMenuItem key={item.id} item={item} onClick={handleActionClick} />)}\n </NaturalDropdownMenu.Viewport>\n <NaturalDropdownMenu.Arrow />\n </NaturalDropdownMenu.Content>\n </NaturalDropdownMenu.Portal>\n </NaturalDropdownMenu.Root>\n );\n};\n\nexport const DropdownMenu = {\n Root: DropdownMenuRoot,\n Trigger: NaturalDropdownMenu.Trigger,\n VirtualTrigger: NaturalDropdownMenu.VirtualTrigger,\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type Action as GraphAction, type ActionGroup } from '@dxos/app-graph';\nimport { keySymbols } from '@dxos/keyboard';\nimport { toLocalizedString, useTranslation, type TFunction } from '@dxos/react-ui';\nimport { mx, descriptionText } from '@dxos/react-ui-theme';\n\nimport { translationKey } from '../translations';\nimport { type MenuActionProperties } from '../types';\nimport { getShortcut } from '../util';\n\ntype Action = GraphAction<MenuActionProperties> | ActionGroup<Omit<MenuActionProperties, 'variant'>>;\n\nexport const ActionLabel = ({ action }: { action: Action }) => {\n const shortcut = getShortcut(action);\n const { t } = useTranslation(translationKey);\n\n return (\n <>\n <span className='grow truncate'>{toLocalizedString(action.properties!.label, t)}</span>\n {shortcut && <span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>}\n </>\n );\n};\n\nexport const actionLabel = (action: Action, t: TFunction) => {\n const shortcut = getShortcut(action);\n return `${toLocalizedString(action.properties!.label, t)}${shortcut ? ` (${keySymbols(shortcut).join('')})` : ''}`;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport const translationKey = 'menus';\n\nexport default [\n {\n 'en-US': {\n [translationKey]: {},\n },\n },\n] as const;\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { ACTION_GROUP_TYPE, ACTION_TYPE, actionGroupSymbol, type ActionLike } from '@dxos/app-graph';\nimport { getHostPlatform } from '@dxos/util';\n\nimport {\n type MenuAction,\n type MenuActionProperties,\n type MenuItemGroup,\n type MenuItemGroupProperties,\n type MenuSeparator,\n} from './types';\n\nexport const getShortcut = (action: ActionLike) => {\n return typeof action.properties?.keyBinding === 'string'\n ? action.properties.keyBinding\n : action.properties?.keyBinding?.[getHostPlatform()];\n};\n\nexport const fallbackIcon = 'ph--placeholder--regular';\n\nexport const createMenuAction = <P extends {} = {}>(\n id: string,\n invoke: () => void,\n properties: P & MenuActionProperties,\n) =>\n ({\n id,\n type: ACTION_TYPE,\n properties,\n data: invoke,\n }) satisfies MenuAction;\n\nexport const createMenuItemGroup = <\n P extends MenuItemGroupProperties = MenuItemGroupProperties & Partial<MenuActionProperties>,\n>(\n id: string,\n properties: P,\n) =>\n ({\n id,\n type: ACTION_GROUP_TYPE,\n properties,\n data: actionGroupSymbol,\n }) satisfies MenuItemGroup;\n\nexport const createGapSeparator = (id: string = 'gap', source: string = 'root') => ({\n nodes: [\n {\n id,\n type: '@dxos/react-ui-toolbar/separator',\n properties: { variant: 'gap' },\n data: undefined as never,\n } satisfies MenuSeparator,\n ],\n edges: [{ source, target: id }],\n});\n\nexport const createLineSeparator = (id: string = 'line', source: string = 'root') => ({\n nodes: [\n {\n id,\n type: '@dxos/react-ui-toolbar/separator',\n properties: { variant: 'line' },\n data: undefined as never,\n } satisfies MenuSeparator,\n ],\n edges: [{ source, target: id }],\n});\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContextScope, type Scope } from '@radix-ui/react-context';\nimport React, { type PropsWithChildren, useMemo } from 'react';\n\nimport { type MenuContextValue, type MenuItem, type MenuItemGroup } from '../types';\n\nexport type MenuScopedProps<P> = P & { __menuScope?: Scope };\n\nconst MENU_NAME = 'GraphMenu';\n\nconst [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);\n\nconst [MenuContextProvider, useMenu] = createMenuContext<MenuContextValue>(MENU_NAME);\n\nexport const menuContextDefaults: MenuContextValue = {\n iconSize: 5,\n useGroupItems: () => null,\n};\n\nconst useMenuScope = createMenuScope();\n\nconst MenuProvider = ({\n children,\n useGroupItems = menuContextDefaults.useGroupItems,\n iconSize = menuContextDefaults.iconSize,\n attendableId,\n}: PropsWithChildren<Partial<MenuContextValue>>) => {\n const { scope } = useMenuScope(undefined);\n return (\n <MenuContextProvider useGroupItems={useGroupItems} iconSize={iconSize} attendableId={attendableId} scope={scope}>\n {children}\n </MenuContextProvider>\n );\n};\n\nexport const useMenuItems = (\n group?: MenuItemGroup,\n propsItems?: MenuItem[],\n consumerName: string = 'useMenuItemConsumer',\n __menuScope?: Scope,\n) => {\n const { useGroupItems } = useMenu(consumerName, __menuScope);\n const groupItems = useGroupItems(group);\n return useMemo(() => propsItems ?? groupItems ?? undefined, [propsItems, groupItems]);\n};\n\nexport { useMenu, createMenuScope, MenuProvider };\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback, useRef } from 'react';\n\nimport { Icon, Toolbar as NaturalToolbar, type ToolbarRootProps, useTranslation } from '@dxos/react-ui';\nimport { useAttention } from '@dxos/react-ui-attention';\n\nimport { actionLabel, ActionLabel } from './ActionLabel';\nimport { DropdownMenu } from './DropdownMenu';\nimport { type MenuScopedProps, useMenu, useMenuItems } from './MenuContext';\nimport { translationKey } from '../translations';\nimport {\n type MenuAction,\n type MenuItem,\n isMenuGroup,\n isSeparator,\n type MenuItemGroup,\n type MenuActionProperties,\n type MenuMultipleSelectActionGroup,\n type MenuSingleSelectActionGroup,\n} from '../types';\n\nexport type ToolbarMenuDropdownMenuActionGroup = Omit<MenuActionProperties, 'variant' | 'icon'> & {\n variant: 'dropdownMenu';\n icon: string;\n applyActive?: boolean;\n};\n\nexport type ToolbarMenuToggleGroupActionGroup = Omit<MenuActionProperties, 'variant'> & {\n variant: 'toggleGroup';\n};\n\nexport type ToolbarMenuActionGroupProperties = (\n | ToolbarMenuDropdownMenuActionGroup\n | ToolbarMenuToggleGroupActionGroup\n) &\n (MenuSingleSelectActionGroup | MenuMultipleSelectActionGroup);\n\nexport type ToolbarMenuProps = ToolbarRootProps;\n\nexport type ToolbarMenuActionGroupProps = {\n group: MenuItemGroup<ToolbarMenuActionGroupProperties>;\n items?: MenuItem[];\n};\n\nexport type ToolbarMenuActionProps = {\n group: MenuItemGroup<ToolbarMenuActionGroupProperties>;\n action: MenuAction;\n};\n\nconst ActionToolbarItem = ({ action, __menuScope }: MenuScopedProps<{ action: MenuAction }>) => {\n const { iconSize } = useMenu('ActionToolbarItem', __menuScope);\n const { t } = useTranslation(translationKey);\n const handleClick = useCallback(() => action.data?.(), [action]);\n const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;\n const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;\n const rootProps = icon\n ? { icon, size: iconSize, iconOnly, label: actionLabel(action, t) }\n : { children: <ActionLabel action={action} /> };\n return hidden ? null : (\n <Root\n key={action.id}\n disabled={disabled}\n onClick={handleClick}\n variant='ghost'\n {...(testId && { 'data-testid': testId })}\n {...(rootProps as any)}\n classNames={classNames}\n />\n );\n};\n\nconst DropdownMenuToolbarItem = ({\n group,\n items: propsItems,\n __menuScope,\n}: MenuScopedProps<ToolbarMenuActionGroupProps>) => {\n const { iconOnly, disabled, testId } = group.properties;\n const suppressNextTooltip = useRef(false);\n const { t } = useTranslation(translationKey);\n const { iconSize } = useMenu('DropdownMenuToolbarItem', __menuScope);\n const items = useMenuItems(group, propsItems, 'DropdownMenuToolbarItem', __menuScope);\n const activeItem = items?.find((item) => !!(item as MenuAction).properties.checked);\n const icon =\n ((group.properties as any).applyActive &&\n // TODO(thure): Handle other menu item types.\n (activeItem as MenuAction)?.properties.icon) ||\n group.properties.icon;\n const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;\n const labelAction = (group.properties as any).applyActive && activeItem ? (activeItem as MenuAction) : group;\n const rootProps = icon\n ? { icon, size: iconSize, iconOnly, label: actionLabel(labelAction, t), caretDown: true, suppressNextTooltip }\n : {\n children: (\n <>\n <ActionLabel action={labelAction} />\n <Icon size={3} icon='ph--caret-down--bold' classNames='mis-1' />\n </>\n ),\n };\n return (\n <DropdownMenu.Root group={group} items={items} suppressNextTooltip={suppressNextTooltip}>\n <DropdownMenu.Trigger asChild>\n <Root variant='ghost' disabled={disabled} {...(rootProps as any)} {...(testId && { 'data-testid': testId })} />\n </DropdownMenu.Trigger>\n </DropdownMenu.Root>\n );\n};\n\nconst ToggleGroupItem = ({ group, action, __menuScope }: MenuScopedProps<ToolbarMenuActionProps>) => {\n const { iconSize } = useMenu('ToggleGroupItem', __menuScope);\n const { t } = useTranslation(translationKey);\n const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;\n const handleClick = useCallback(() => action.data?.({ parent: group }), [action, group]);\n const Root = icon ? NaturalToolbar.ToggleGroupIconItem : NaturalToolbar.ToggleGroupItem;\n const rootProps = icon\n ? { icon, size: iconSize, iconOnly, label: actionLabel(action, t) }\n : { children: <ActionLabel action={action} /> };\n return hidden ? null : (\n <Root\n key={action.id}\n value={action.id as any}\n disabled={disabled}\n onClick={handleClick}\n variant='ghost'\n {...(testId && { 'data-testid': testId })}\n {...(rootProps as any)}\n classNames={classNames}\n />\n );\n};\n\nconst ToggleGroupToolbarItem = ({\n group,\n items: propsItems,\n __menuScope,\n}: MenuScopedProps<ToolbarMenuActionGroupProps>) => {\n const items = useMenuItems(group, propsItems, 'ToggleGroupToolbarItem', __menuScope);\n const { selectCardinality, value } = group.properties;\n return (\n // TODO(thure): The type here is difficult to manage, what do?\n // @ts-ignore\n <NaturalToolbar.ToggleGroup type={selectCardinality} value={value}>\n {\n // TODO(thure): Handle other menu item types.\n (items as MenuAction[]).map((action) => (\n <ToggleGroupItem key={action.id} group={group} action={action} />\n ))\n }\n </NaturalToolbar.ToggleGroup>\n );\n};\n\nexport const ToolbarMenu = ({ __menuScope, classNames, ...props }: MenuScopedProps<ToolbarMenuProps>) => {\n const items = useMenuItems(undefined, undefined, 'ToolbarMenu', __menuScope);\n const { attendableId } = useMenu('ToolbarMenu', __menuScope);\n const { hasAttention } = useAttention(attendableId);\n return (\n <NaturalToolbar.Root\n {...props}\n classNames={['p-1', !hasAttention && '[&>*]:opacity-20 !bg-transparent', classNames]}\n >\n {items?.map((item: MenuItem, i: number) =>\n isSeparator(item) ? (\n <NaturalToolbar.Separator key={i} variant={item.properties.variant} />\n ) : isMenuGroup(item) ? (\n item.properties.variant === 'dropdownMenu' ? (\n // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.\n <DropdownMenuToolbarItem key={item.id} group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />\n ) : (\n // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.\n <ToggleGroupToolbarItem key={item.id} group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />\n )\n ) : (\n // TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.\n <ActionToolbarItem key={item.id} action={item as MenuAction} />\n ),\n )}\n </NaturalToolbar.Root>\n );\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Node, type Action, type ActionGroup, ACTION_GROUP_TYPE } from '@dxos/app-graph';\nimport { type ToolbarSeparatorProps, type Label, type IconButtonProps, type ClassNameValue } from '@dxos/react-ui';\n\nexport type MenuActionProperties = {\n label: Label;\n icon?: string;\n value?: string;\n disabled?: boolean;\n hidden?: boolean;\n iconOnly?: boolean;\n testId?: string;\n variant?: 'action' | 'toggle';\n checked?: boolean;\n classNames?: ClassNameValue;\n};\n\nexport type MenuItemGroupProperties = {\n label: Label;\n icon?: string;\n iconOnly?: boolean;\n};\n\nexport type MenuAction<P extends {} = {}> = Action<P & MenuActionProperties>;\n\nexport const MenuSeparatorType = '@dxos/react-ui-toolbar/separator' as const;\n\nexport type MenuSeparator = Node<never, Pick<ToolbarSeparatorProps, 'variant'>> & {\n type: typeof MenuSeparatorType;\n};\n\nexport const isSeparator = (node: Node): node is MenuSeparator => node.type === MenuSeparatorType;\n\nexport type MenuSingleSelectActionGroup = { selectCardinality: 'single'; value: string };\nexport type MenuMultipleSelectActionGroup = { selectCardinality: 'multiple'; value: string[] };\n\nexport type MenuItemGroup<P extends Record<string, any> = Record<string, any>> = ActionGroup<P>;\n\nexport const isMenuGroup = (node: Node): node is MenuItemGroup => node.type === ACTION_GROUP_TYPE;\n\nexport type MenuItem = MenuSeparator | MenuAction | MenuItemGroup;\n\nexport type MenuItemsResolver = (group?: MenuItemGroup) => MenuItem[] | null;\n\nexport type MenuContextValue = {\n useGroupItems: MenuItemsResolver;\n iconSize: IconButtonProps['size'];\n attendableId?: string;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext, useRxValue } from '@effect-rx/rx-react';\nimport { useSignalEffect } from '@preact/signals-react';\nimport { useCallback, useContext, useState } from 'react';\n\nimport { type Edge, type Edges, Graph, type NodeArg, type Node, ROOT_ID } from '@dxos/app-graph';\n\nimport { type MenuItem, type MenuItemGroup } from '../types';\n\nconst edgesArrayToRecord = (edges: Edge[]): Record<string, Edges> => {\n return Object.fromEntries(\n Object.entries(\n edges.reduce((acc: Record<string, { inbound: string[]; outbound: string[] }>, { source, target }) => {\n if (!acc[source]) {\n acc[source] = { inbound: [], outbound: [] };\n }\n if (!acc[target]) {\n acc[target] = { inbound: [], outbound: [] };\n }\n\n const sourceEdges = acc[source];\n if (!sourceEdges.outbound.includes(target)) {\n sourceEdges.outbound.push(target);\n }\n\n const targetEdges = acc[target];\n if (!targetEdges.inbound.includes(source)) {\n targetEdges.inbound.push(source);\n }\n\n return acc;\n }, {}),\n ),\n );\n};\n\nexport type ActionGraphNodes = NodeArg<any>[];\nexport type ActionGraphEdges = Edge[];\nexport type ActionGraphProps = { nodes: ActionGraphNodes; edges: ActionGraphEdges };\n\nexport const useMenuActions = (actionCreator: () => ActionGraphProps) => {\n const registry = useContext(RegistryContext);\n const initialMenuGraphProps = actionCreator();\n\n const [graph] = useState(\n new Graph({\n registry,\n nodes: initialMenuGraphProps.nodes as Node[],\n edges: edgesArrayToRecord(initialMenuGraphProps.edges),\n }),\n );\n\n // TODO(wittjosiah): Remove dependence on signals.\n useSignalEffect(() => {\n const menuGraphProps = actionCreator();\n graph.addNodes(menuGraphProps.nodes);\n graph.addEdges(menuGraphProps.edges);\n });\n\n const useGroupItems = useCallback(\n (sourceNode?: MenuItemGroup) => {\n const items = useRxValue(graph.connections(sourceNode?.id || ROOT_ID)) as MenuItem[];\n return items;\n },\n [graph],\n );\n\n return { useGroupItems };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_react", "import_react_ui", "import_app_graph", "translationKey", "getShortcut", "action", "properties", "keyBinding", "getHostPlatform", "createMenuAction", "id", "invoke", "type", "ACTION_TYPE", "data", "createMenuItemGroup", "ACTION_GROUP_TYPE", "actionGroupSymbol", "createGapSeparator", "source", "nodes", "variant", "undefined", "edges", "target", "createLineSeparator", "ActionLabel", "shortcut", "t", "useTranslation", "React", "span", "className", "toLocalizedString", "label", "mx", "descriptionText", "keySymbols", "join", "actionLabel", "MENU_NAME", "createMenuContext", "createMenuScope", "createContextScope", "MenuContextProvider", "useMenu", "menuContextDefaults", "iconSize", "useGroupItems", "useMenuScope", "MenuProvider", "children", "attendableId", "scope", "useMenuItems", "group", "propsItems", "consumerName", "__menuScope", "groupItems", "useMemo", "DropdownMenuItem", "item", "onClick", "handleClick", "useCallback", "event", "NaturalDropdownMenu", "Item", "classNames", "disabled", "testId", "icon", "Icon", "size", "DropdownMenuRoot", "items", "open", "defaultOpen", "onOpenChange", "suppressNextTooltip", "caller", "naturalProps", "optionsMenuOpen", "setOptionsMenuOpen", "useControllableState", "prop", "defaultProp", "onChange", "handleActionClick", "stopPropagation", "current", "parent", "Root", "nextOpen", "Portal", "Content", "Viewport", "map", "key", "Arrow", "DropdownMenu", "Trigger", "VirtualTrigger", "MenuSeparatorType", "isSeparator", "node", "isMenuGroup", "ActionToolbarItem", "iconOnly", "hidden", "NaturalToolbar", "IconButton", "Button", "rootProps", "DropdownMenuToolbarItem", "useRef", "activeItem", "find", "checked", "applyActive", "labelAction", "caretDown", "asChild", "ToggleGroupItem", "ToggleGroupIconItem", "value", "ToggleGroupToolbarItem", "selectCardinality", "ToggleGroup", "ToolbarMenu", "props", "hasAttention", "useAttention", "i", "Separator", "edgesArrayToRecord", "Object", "fromEntries", "entries", "reduce", "acc", "inbound", "outbound", "sourceEdges", "includes", "push", "targetEdges", "useMenuActions", "actionCreator", "registry", "useContext", "RegistryContext", "initialMenuGraphProps", "graph", "useState", "Graph", "useSignalEffect", "menuGraphProps", "addNodes", "addEdges", "sourceNode", "useRxValue", "connections", "ROOT_ID"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/react-ui-menu/src/translations.ts":{"bytes":909,"imports":[],"format":"esm"},"packages/ui/react-ui-menu/src/util.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/react-ui-menu/src/translations.ts":{"bytes":909,"imports":[],"format":"esm"},"packages/ui/react-ui-menu/src/util.ts":{"bytes":5996,"imports":[{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-menu/src/components/ActionLabel.tsx":{"bytes":4200,"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/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-menu/src/translations.ts","kind":"import-statement","original":"../translations"},{"path":"packages/ui/react-ui-menu/src/util.ts","kind":"import-statement","original":"../util"}],"format":"esm"},"packages/ui/react-ui-menu/src/components/MenuContext.tsx":{"bytes":5088,"imports":[{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-menu/src/components/DropdownMenu.tsx":{"bytes":11327,"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":"packages/ui/react-ui-menu/src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"packages/ui/react-ui-menu/src/components/MenuContext.tsx","kind":"import-statement","original":"./MenuContext"}],"format":"esm"},"packages/ui/react-ui-menu/src/types.ts":{"bytes":3243,"imports":[{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-menu/src/components/ToolbarMenu.tsx":{"bytes":22596,"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":"packages/ui/react-ui-menu/src/components/ActionLabel.tsx","kind":"import-statement","original":"./ActionLabel"},{"path":"packages/ui/react-ui-menu/src/components/DropdownMenu.tsx","kind":"import-statement","original":"./DropdownMenu"},{"path":"packages/ui/react-ui-menu/src/components/MenuContext.tsx","kind":"import-statement","original":"./MenuContext"},{"path":"packages/ui/react-ui-menu/src/translations.ts","kind":"import-statement","original":"../translations"},{"path":"packages/ui/react-ui-menu/src/types.ts","kind":"import-statement","original":"../types"}],"format":"esm"},"packages/ui/react-ui-menu/src/components/index.ts":{"bytes":718,"imports":[{"path":"packages/ui/react-ui-menu/src/components/DropdownMenu.tsx","kind":"import-statement","original":"./DropdownMenu"},{"path":"packages/ui/react-ui-menu/src/components/ToolbarMenu.tsx","kind":"import-statement","original":"./ToolbarMenu"},{"path":"packages/ui/react-ui-menu/src/components/MenuContext.tsx","kind":"import-statement","original":"./MenuContext"}],"format":"esm"},"packages/ui/react-ui-menu/src/hooks/useMenuActions.ts":{"bytes":7433,"imports":[{"path":"@effect-rx/rx-react","kind":"import-statement","external":true},{"path":"@preact/signals-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-menu/src/hooks/index.ts":{"bytes":521,"imports":[{"path":"packages/ui/react-ui-menu/src/hooks/useMenuActions.ts","kind":"import-statement","original":"./useMenuActions"}],"format":"esm"},"packages/ui/react-ui-menu/src/index.ts":{"bytes":1114,"imports":[{"path":"packages/ui/react-ui-menu/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/ui/react-ui-menu/src/hooks/index.ts","kind":"import-statement","original":"./hooks"},{"path":"packages/ui/react-ui-menu/src/types.ts","kind":"import-statement","original":"./types"},{"path":"packages/ui/react-ui-menu/src/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-menu/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":31698},"packages/ui/react-ui-menu/dist/lib/node/index.cjs":{"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":"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/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"react","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/app-graph","kind":"import-statement","external":true},{"path":"@effect-rx/rx-react","kind":"import-statement","external":true},{"path":"@preact/signals-react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"exports":["DropdownMenu","MenuProvider","MenuSeparatorType","ToolbarMenu","createGapSeparator","createLineSeparator","createMenuAction","createMenuItemGroup","createMenuScope","isMenuGroup","isSeparator","menuContextDefaults","useMenu","useMenuActions","useMenuItems"],"entryPoint":"packages/ui/react-ui-menu/src/index.ts","inputs":{"packages/ui/react-ui-menu/src/components/DropdownMenu.tsx":{"bytesInOutput":2562},"packages/ui/react-ui-menu/src/components/ActionLabel.tsx":{"bytesInOutput":862},"packages/ui/react-ui-menu/src/translations.ts":{"bytesInOutput":118},"packages/ui/react-ui-menu/src/util.ts":{"bytesInOutput":1113},"packages/ui/react-ui-menu/src/components/MenuContext.tsx":{"bytesInOutput":1028},"packages/ui/react-ui-menu/src/components/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-menu/src/components/ToolbarMenu.tsx":{"bytesInOutput":5638},"packages/ui/react-ui-menu/src/types.ts":{"bytesInOutput":258},"packages/ui/react-ui-menu/src/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-menu/src/hooks/useMenuActions.ts":{"bytesInOutput":1544},"packages/ui/react-ui-menu/src/hooks/index.ts":{"bytesInOutput":0}},"bytes":14063}}}
|