@dxos/react-ui-menu 0.8.2-main.2f9c567 → 0.8.2-main.30e4dbb
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 +38 -38
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +35 -35
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +38 -38
- 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.d.ts → hooks/useMenuActions.d.ts} +2 -2
- 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} +2 -4
- 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 +12 -12
- package/src/components/ActionLabel.tsx +11 -8
- package/src/components/DropdownMenu.tsx +5 -5
- package/src/components/MenuContext.tsx +5 -16
- package/src/{testing → components}/Menus.stories.tsx +14 -14
- package/src/components/ToolbarMenu.tsx +26 -28
- package/src/hooks/index.ts +5 -0
- package/src/{hooks.ts → hooks/useMenuActions.ts} +1 -1
- package/src/index.ts +1 -1
- package/src/testing/generator.ts +111 -0
- package/src/testing/index.ts +1 -107
- package/src/{defs.ts → types.ts} +1 -4
- package/src/util.ts +7 -7
- package/dist/types/src/defs.d.ts.map +0 -1
- package/dist/types/src/hooks.d.ts.map +0 -1
- package/dist/types/src/testing/Menus.stories.d.ts.map +0 -1
|
@@ -25,13 +25,11 @@ import { getHostPlatform } from "@dxos/util";
|
|
|
25
25
|
var getShortcut = (action) => {
|
|
26
26
|
return typeof action.properties?.keyBinding === "string" ? action.properties.keyBinding : action.properties?.keyBinding?.[getHostPlatform()];
|
|
27
27
|
};
|
|
28
|
-
var
|
|
29
|
-
};
|
|
30
|
-
var createMenuAction = (id, properties) => ({
|
|
28
|
+
var createMenuAction = (id, invoke, properties) => ({
|
|
31
29
|
id,
|
|
32
30
|
type: ACTION_TYPE,
|
|
33
31
|
properties,
|
|
34
|
-
data:
|
|
32
|
+
data: invoke
|
|
35
33
|
});
|
|
36
34
|
var createMenuItemGroup = (id, properties) => ({
|
|
37
35
|
id,
|
|
@@ -86,6 +84,10 @@ var ActionLabel = ({ action }) => {
|
|
|
86
84
|
className: mx("shrink-0", descriptionText)
|
|
87
85
|
}, keySymbols(shortcut).join("")));
|
|
88
86
|
};
|
|
87
|
+
var actionLabel = (action, t) => {
|
|
88
|
+
const shortcut = getShortcut(action);
|
|
89
|
+
return `${toLocalizedString(action.properties.label, t)}${shortcut ? ` (${keySymbols(shortcut).join("")})` : ""}`;
|
|
90
|
+
};
|
|
89
91
|
|
|
90
92
|
// packages/ui/react-ui-menu/src/components/MenuContext.tsx
|
|
91
93
|
import { createContextScope } from "@radix-ui/react-context";
|
|
@@ -95,16 +97,13 @@ var [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);
|
|
|
95
97
|
var [MenuContextProvider, useMenu] = createMenuContext(MENU_NAME);
|
|
96
98
|
var menuContextDefaults = {
|
|
97
99
|
iconSize: 5,
|
|
98
|
-
onAction: () => {
|
|
99
|
-
},
|
|
100
100
|
resolveGroupItems: () => null
|
|
101
101
|
};
|
|
102
102
|
var useMenuScope = createMenuScope();
|
|
103
|
-
var MenuProvider = ({ children, resolveGroupItems = menuContextDefaults.resolveGroupItems,
|
|
103
|
+
var MenuProvider = ({ children, resolveGroupItems = menuContextDefaults.resolveGroupItems, iconSize = menuContextDefaults.iconSize, attendableId }) => {
|
|
104
104
|
const { scope } = useMenuScope(void 0);
|
|
105
105
|
return /* @__PURE__ */ React2.createElement(MenuContextProvider, {
|
|
106
106
|
resolveGroupItems,
|
|
107
|
-
onAction,
|
|
108
107
|
iconSize,
|
|
109
108
|
attendableId,
|
|
110
109
|
scope
|
|
@@ -141,13 +140,12 @@ var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
|
|
|
141
140
|
action
|
|
142
141
|
}));
|
|
143
142
|
};
|
|
144
|
-
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, suppressNextTooltip, children, __menuScope, ...naturalProps }) => {
|
|
143
|
+
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, suppressNextTooltip, caller, children, __menuScope, ...naturalProps }) => {
|
|
145
144
|
const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({
|
|
146
145
|
prop: open,
|
|
147
146
|
defaultProp: defaultOpen,
|
|
148
147
|
onChange: onOpenChange
|
|
149
148
|
});
|
|
150
|
-
const { onAction } = useMenu("DropdownMenuRoot", __menuScope);
|
|
151
149
|
const handleActionClick = useCallback((action, event) => {
|
|
152
150
|
if (action.properties?.disabled) {
|
|
153
151
|
return;
|
|
@@ -157,9 +155,14 @@ var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenCha
|
|
|
157
155
|
suppressNextTooltip.current = true;
|
|
158
156
|
}
|
|
159
157
|
setOptionsMenuOpen(false);
|
|
160
|
-
|
|
158
|
+
void action.data?.({
|
|
159
|
+
parent: group,
|
|
160
|
+
caller
|
|
161
|
+
});
|
|
161
162
|
}, [
|
|
162
|
-
|
|
163
|
+
suppressNextTooltip,
|
|
164
|
+
group,
|
|
165
|
+
caller
|
|
163
166
|
]);
|
|
164
167
|
const items = useMenuItems(group, propsItems);
|
|
165
168
|
return /* @__PURE__ */ React3.createElement(NaturalDropdownMenu.Root, {
|
|
@@ -185,10 +188,10 @@ var DropdownMenu = {
|
|
|
185
188
|
|
|
186
189
|
// packages/ui/react-ui-menu/src/components/ToolbarMenu.tsx
|
|
187
190
|
import React4, { useCallback as useCallback2, useRef } from "react";
|
|
188
|
-
import { Icon as Icon2, Toolbar as NaturalToolbar } from "@dxos/react-ui";
|
|
191
|
+
import { Icon as Icon2, Toolbar as NaturalToolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
189
192
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
190
193
|
|
|
191
|
-
// packages/ui/react-ui-menu/src/
|
|
194
|
+
// packages/ui/react-ui-menu/src/types.ts
|
|
192
195
|
import { ACTION_GROUP_TYPE as ACTION_GROUP_TYPE2 } from "@dxos/app-graph";
|
|
193
196
|
var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
|
|
194
197
|
var isSeparator = (node) => node.type === MenuSeparatorType;
|
|
@@ -196,12 +199,10 @@ var isMenuGroup = (node) => node.type === ACTION_GROUP_TYPE2;
|
|
|
196
199
|
|
|
197
200
|
// packages/ui/react-ui-menu/src/components/ToolbarMenu.tsx
|
|
198
201
|
var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
199
|
-
const {
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
action,
|
|
204
|
-
onAction
|
|
202
|
+
const { iconSize } = useMenu("ActionToolbarItem", __menuScope);
|
|
203
|
+
const { t } = useTranslation2(translationKey);
|
|
204
|
+
const handleClick = useCallback2(() => action.data?.(), [
|
|
205
|
+
action
|
|
205
206
|
]);
|
|
206
207
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
207
208
|
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
@@ -209,9 +210,7 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
209
210
|
icon,
|
|
210
211
|
size: iconSize,
|
|
211
212
|
iconOnly,
|
|
212
|
-
label:
|
|
213
|
-
action
|
|
214
|
-
})
|
|
213
|
+
label: actionLabel(action, t)
|
|
215
214
|
} : {
|
|
216
215
|
children: /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
217
216
|
action
|
|
@@ -232,24 +231,25 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
232
231
|
var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
233
232
|
const { iconOnly, disabled, testId } = group.properties;
|
|
234
233
|
const suppressNextTooltip = useRef(false);
|
|
234
|
+
const { t } = useTranslation2(translationKey);
|
|
235
235
|
const { iconSize } = useMenu("DropdownMenuToolbarItem", __menuScope);
|
|
236
236
|
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
237
237
|
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
238
238
|
const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
|
|
239
239
|
activeItem?.properties.icon || group.properties.icon;
|
|
240
240
|
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
241
|
-
const
|
|
242
|
-
action: group.properties.applyActive && activeItem ? activeItem : group
|
|
243
|
-
});
|
|
241
|
+
const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
|
|
244
242
|
const rootProps = icon ? {
|
|
245
243
|
icon,
|
|
246
244
|
size: iconSize,
|
|
247
245
|
iconOnly,
|
|
248
|
-
label,
|
|
246
|
+
label: actionLabel(labelAction, t),
|
|
249
247
|
caretDown: true,
|
|
250
248
|
suppressNextTooltip
|
|
251
249
|
} : {
|
|
252
|
-
children: /* @__PURE__ */ React4.createElement(React4.Fragment, null,
|
|
250
|
+
children: /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
251
|
+
action: labelAction
|
|
252
|
+
}), /* @__PURE__ */ React4.createElement(Icon2, {
|
|
253
253
|
size: 3,
|
|
254
254
|
icon: "ph--caret-down--bold",
|
|
255
255
|
classNames: "mis-1"
|
|
@@ -270,23 +270,22 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
270
270
|
}
|
|
271
271
|
})));
|
|
272
272
|
};
|
|
273
|
-
var ToggleGroupItem = ({ action, __menuScope }) => {
|
|
274
|
-
const { iconSize
|
|
273
|
+
var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
274
|
+
const { iconSize } = useMenu("ToggleGroupItem", __menuScope);
|
|
275
|
+
const { t } = useTranslation2(translationKey);
|
|
275
276
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
276
|
-
const handleClick = useCallback2(() => {
|
|
277
|
-
|
|
278
|
-
}, [
|
|
277
|
+
const handleClick = useCallback2(() => action.data?.({
|
|
278
|
+
parent: group
|
|
279
|
+
}), [
|
|
279
280
|
action,
|
|
280
|
-
|
|
281
|
+
group
|
|
281
282
|
]);
|
|
282
283
|
const Root = icon ? NaturalToolbar.ToggleGroupIconItem : NaturalToolbar.ToggleGroupItem;
|
|
283
284
|
const rootProps = icon ? {
|
|
284
285
|
icon,
|
|
285
286
|
size: iconSize,
|
|
286
287
|
iconOnly,
|
|
287
|
-
label:
|
|
288
|
-
action
|
|
289
|
-
})
|
|
288
|
+
label: actionLabel(action, t)
|
|
290
289
|
} : {
|
|
291
290
|
children: /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
292
291
|
action
|
|
@@ -320,6 +319,7 @@ var ToggleGroupToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
320
319
|
// TODO(thure): Handle other menu item types.
|
|
321
320
|
items.map((action) => /* @__PURE__ */ React4.createElement(ToggleGroupItem, {
|
|
322
321
|
key: action.id,
|
|
322
|
+
group,
|
|
323
323
|
action
|
|
324
324
|
}))
|
|
325
325
|
)
|
|
@@ -360,7 +360,7 @@ var ToolbarMenu = ({ __menuScope, classNames, ...props }) => {
|
|
|
360
360
|
)));
|
|
361
361
|
};
|
|
362
362
|
|
|
363
|
-
// packages/ui/react-ui-menu/src/hooks.ts
|
|
363
|
+
// packages/ui/react-ui-menu/src/hooks/useMenuActions.ts
|
|
364
364
|
import { useSignalEffect } from "@preact/signals-react";
|
|
365
365
|
import { useCallback as useCallback3, useState } from "react";
|
|
366
366
|
import { Graph } from "@dxos/app-graph";
|
|
@@ -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,SAASA,4BAA4B;AACrC,OAAOC,UAAiDC,mBAAmB;AAE3E,SAASC,gBAAgBC,qBAAqBC,YAAwC;;;ACHtF,OAAOC,WAAW;AAGlB,SAASC,kBAAkB;AAC3B,SAASC,mBAAmBC,
|
|
6
|
-
"names": ["useControllableState", "React", "useCallback", "DropdownMenu", "NaturalDropdownMenu", "Icon", "React", "keySymbols", "toLocalizedString", "useTranslation", "mx", "descriptionText", "translationKey", "ACTION_GROUP_TYPE", "ACTION_TYPE", "actionGroupSymbol", "getHostPlatform", "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 resolveGroupItems: () => null,\n};\n\nconst useMenuScope = createMenuScope();\n\nconst MenuProvider = ({\n children,\n resolveGroupItems = menuContextDefaults.resolveGroupItems,\n iconSize = menuContextDefaults.iconSize,\n attendableId,\n}: PropsWithChildren<Partial<MenuContextValue>>) => {\n const { scope } = useMenuScope(undefined);\n return (\n <MenuContextProvider\n resolveGroupItems={resolveGroupItems}\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, 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-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 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 resolveGroupItems: MenuItemsResolver;\n iconSize: IconButtonProps['size'];\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 '../types';\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": "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",
|
|
6
|
+
"names": ["useControllableState", "React", "useCallback", "DropdownMenu", "NaturalDropdownMenu", "Icon", "React", "keySymbols", "toLocalizedString", "useTranslation", "mx", "descriptionText", "translationKey", "ACTION_GROUP_TYPE", "ACTION_TYPE", "actionGroupSymbol", "getHostPlatform", "getShortcut", "action", "properties", "keyBinding", "getHostPlatform", "createMenuAction", "id", "invoke", "properties", "type", "ACTION_TYPE", "data", "createMenuItemGroup", "ACTION_GROUP_TYPE", "actionGroupSymbol", "createGapSeparator", "source", "nodes", "variant", "undefined", "edges", "target", "createLineSeparator", "ActionLabel", "action", "shortcut", "getShortcut", "t", "useTranslation", "translationKey", "span", "className", "toLocalizedString", "properties", "label", "mx", "descriptionText", "keySymbols", "join", "actionLabel", "createContextScope", "React", "useMemo", "MENU_NAME", "createMenuContext", "createMenuScope", "createContextScope", "MenuContextProvider", "useMenu", "menuContextDefaults", "iconSize", "resolveGroupItems", "useMenuScope", "MenuProvider", "children", "attendableId", "scope", "undefined", "React", "useMenuItems", "group", "propsItems", "consumerName", "__menuScope", "useMemo", "DropdownMenuItem", "item", "onClick", "__menuScope", "action", "handleClick", "useCallback", "event", "iconSize", "useMenu", "React", "NaturalDropdownMenu", "Item", "classNames", "disabled", "properties", "testId", "icon", "Icon", "size", "ActionLabel", "DropdownMenuRoot", "items", "propsItems", "group", "open", "defaultOpen", "onOpenChange", "suppressNextTooltip", "caller", "children", "naturalProps", "optionsMenuOpen", "setOptionsMenuOpen", "useControllableState", "prop", "defaultProp", "onChange", "handleActionClick", "stopPropagation", "current", "data", "parent", "useMenuItems", "Root", "nextOpen", "Portal", "Content", "Viewport", "map", "key", "id", "Arrow", "DropdownMenu", "Trigger", "VirtualTrigger", "React", "useCallback", "useRef", "Icon", "Toolbar", "NaturalToolbar", "useTranslation", "useAttention", "ACTION_GROUP_TYPE", "MenuSeparatorType", "isSeparator", "node", "type", "isMenuGroup", "ACTION_GROUP_TYPE", "ActionToolbarItem", "action", "__menuScope", "iconSize", "useMenu", "t", "useTranslation", "translationKey", "handleClick", "useCallback", "data", "icon", "iconOnly", "disabled", "testId", "hidden", "classNames", "properties", "Root", "NaturalToolbar", "IconButton", "Button", "rootProps", "size", "label", "actionLabel", "children", "React", "ActionLabel", "key", "id", "onClick", "variant", "DropdownMenuToolbarItem", "group", "items", "propsItems", "suppressNextTooltip", "useRef", "useMenuItems", "activeItem", "find", "item", "checked", "applyActive", "labelAction", "caretDown", "Icon", "DropdownMenu", "Trigger", "asChild", "ToggleGroupItem", "parent", "ToggleGroupIconItem", "value", "ToggleGroupToolbarItem", "selectCardinality", "ToggleGroup", "type", "map", "ToolbarMenu", "props", "undefined", "attendableId", "hasAttention", "useAttention", "i", "isSeparator", "Separator", "isMenuGroup", "useSignalEffect", "useCallback", "useState", "Graph", "edgesArrayToRecord", "edges", "Object", "fromEntries", "entries", "reduce", "acc", "source", "target", "inbound", "outbound", "sourceEdges", "includes", "push", "targetEdges", "map", "id", "useMenuActions", "actionCreator", "initialMenuGraphProps", "graph", "useState", "Graph", "nodes", "useSignalEffect", "menuGraphProps", "_addNodes", "_addEdges", "resolveGroupItems", "useCallback", "sourceNode", "root", "filter", "n"]
|
|
7
7
|
}
|
|
@@ -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":5149,"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":3247,"imports":[{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-menu/src/components/ToolbarMenu.tsx":{"bytes":22625,"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":7491,"imports":[{"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/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":31700},"packages/ui/react-ui-menu/dist/lib/browser/index.mjs":{"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":"@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":1039},"packages/ui/react-ui-menu/src/components/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-menu/src/components/ToolbarMenu.tsx":{"bytesInOutput":5651},"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":1519},"packages/ui/react-ui-menu/src/hooks/index.ts":{"bytesInOutput":0}},"bytes":14062}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -74,13 +74,11 @@ var translations_default = [
|
|
|
74
74
|
var getShortcut = (action) => {
|
|
75
75
|
return typeof action.properties?.keyBinding === "string" ? action.properties.keyBinding : action.properties?.keyBinding?.[(0, import_util.getHostPlatform)()];
|
|
76
76
|
};
|
|
77
|
-
var
|
|
78
|
-
};
|
|
79
|
-
var createMenuAction = (id, properties) => ({
|
|
77
|
+
var createMenuAction = (id, invoke, properties) => ({
|
|
80
78
|
id,
|
|
81
79
|
type: import_app_graph.ACTION_TYPE,
|
|
82
80
|
properties,
|
|
83
|
-
data:
|
|
81
|
+
data: invoke
|
|
84
82
|
});
|
|
85
83
|
var createMenuItemGroup = (id, properties) => ({
|
|
86
84
|
id,
|
|
@@ -133,21 +131,22 @@ var ActionLabel = ({ action }) => {
|
|
|
133
131
|
className: (0, import_react_ui_theme.mx)("shrink-0", import_react_ui_theme.descriptionText)
|
|
134
132
|
}, (0, import_keyboard.keySymbols)(shortcut).join("")));
|
|
135
133
|
};
|
|
134
|
+
var actionLabel = (action, t) => {
|
|
135
|
+
const shortcut = getShortcut(action);
|
|
136
|
+
return `${(0, import_react_ui2.toLocalizedString)(action.properties.label, t)}${shortcut ? ` (${(0, import_keyboard.keySymbols)(shortcut).join("")})` : ""}`;
|
|
137
|
+
};
|
|
136
138
|
var MENU_NAME = "GraphMenu";
|
|
137
139
|
var [createMenuContext, createMenuScope] = (0, import_react_context.createContextScope)(MENU_NAME, []);
|
|
138
140
|
var [MenuContextProvider, useMenu] = createMenuContext(MENU_NAME);
|
|
139
141
|
var menuContextDefaults = {
|
|
140
142
|
iconSize: 5,
|
|
141
|
-
onAction: () => {
|
|
142
|
-
},
|
|
143
143
|
resolveGroupItems: () => null
|
|
144
144
|
};
|
|
145
145
|
var useMenuScope = createMenuScope();
|
|
146
|
-
var MenuProvider = ({ children, resolveGroupItems = menuContextDefaults.resolveGroupItems,
|
|
146
|
+
var MenuProvider = ({ children, resolveGroupItems = menuContextDefaults.resolveGroupItems, iconSize = menuContextDefaults.iconSize, attendableId }) => {
|
|
147
147
|
const { scope } = useMenuScope(void 0);
|
|
148
148
|
return /* @__PURE__ */ import_react3.default.createElement(MenuContextProvider, {
|
|
149
149
|
resolveGroupItems,
|
|
150
|
-
onAction,
|
|
151
150
|
iconSize,
|
|
152
151
|
attendableId,
|
|
153
152
|
scope
|
|
@@ -182,13 +181,12 @@ var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
|
|
|
182
181
|
action
|
|
183
182
|
}));
|
|
184
183
|
};
|
|
185
|
-
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, suppressNextTooltip, children, __menuScope, ...naturalProps }) => {
|
|
184
|
+
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, suppressNextTooltip, caller, children, __menuScope, ...naturalProps }) => {
|
|
186
185
|
const [optionsMenuOpen, setOptionsMenuOpen] = (0, import_react_use_controllable_state.useControllableState)({
|
|
187
186
|
prop: open,
|
|
188
187
|
defaultProp: defaultOpen,
|
|
189
188
|
onChange: onOpenChange
|
|
190
189
|
});
|
|
191
|
-
const { onAction } = useMenu("DropdownMenuRoot", __menuScope);
|
|
192
190
|
const handleActionClick = (0, import_react.useCallback)((action, event) => {
|
|
193
191
|
if (action.properties?.disabled) {
|
|
194
192
|
return;
|
|
@@ -198,9 +196,14 @@ var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenCha
|
|
|
198
196
|
suppressNextTooltip.current = true;
|
|
199
197
|
}
|
|
200
198
|
setOptionsMenuOpen(false);
|
|
201
|
-
|
|
199
|
+
void action.data?.({
|
|
200
|
+
parent: group,
|
|
201
|
+
caller
|
|
202
|
+
});
|
|
202
203
|
}, [
|
|
203
|
-
|
|
204
|
+
suppressNextTooltip,
|
|
205
|
+
group,
|
|
206
|
+
caller
|
|
204
207
|
]);
|
|
205
208
|
const items = useMenuItems(group, propsItems);
|
|
206
209
|
return /* @__PURE__ */ import_react.default.createElement(import_react_ui.DropdownMenu.Root, {
|
|
@@ -227,12 +230,10 @@ var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
|
|
|
227
230
|
var isSeparator = (node) => node.type === MenuSeparatorType;
|
|
228
231
|
var isMenuGroup = (node) => node.type === import_app_graph2.ACTION_GROUP_TYPE;
|
|
229
232
|
var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
230
|
-
const {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
action,
|
|
235
|
-
onAction
|
|
233
|
+
const { iconSize } = useMenu("ActionToolbarItem", __menuScope);
|
|
234
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
235
|
+
const handleClick = (0, import_react4.useCallback)(() => action.data?.(), [
|
|
236
|
+
action
|
|
236
237
|
]);
|
|
237
238
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
238
239
|
const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
|
|
@@ -240,9 +241,7 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
240
241
|
icon,
|
|
241
242
|
size: iconSize,
|
|
242
243
|
iconOnly,
|
|
243
|
-
label:
|
|
244
|
-
action
|
|
245
|
-
})
|
|
244
|
+
label: actionLabel(action, t)
|
|
246
245
|
} : {
|
|
247
246
|
children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
|
|
248
247
|
action
|
|
@@ -263,24 +262,25 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
263
262
|
var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
264
263
|
const { iconOnly, disabled, testId } = group.properties;
|
|
265
264
|
const suppressNextTooltip = (0, import_react4.useRef)(false);
|
|
265
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
266
266
|
const { iconSize } = useMenu("DropdownMenuToolbarItem", __menuScope);
|
|
267
267
|
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
268
268
|
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
269
269
|
const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
|
|
270
270
|
activeItem?.properties.icon || group.properties.icon;
|
|
271
271
|
const Root = icon ? import_react_ui3.Toolbar.IconButton : import_react_ui3.Toolbar.Button;
|
|
272
|
-
const
|
|
273
|
-
action: group.properties.applyActive && activeItem ? activeItem : group
|
|
274
|
-
});
|
|
272
|
+
const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
|
|
275
273
|
const rootProps = icon ? {
|
|
276
274
|
icon,
|
|
277
275
|
size: iconSize,
|
|
278
276
|
iconOnly,
|
|
279
|
-
label,
|
|
277
|
+
label: actionLabel(labelAction, t),
|
|
280
278
|
caretDown: true,
|
|
281
279
|
suppressNextTooltip
|
|
282
280
|
} : {
|
|
283
|
-
children: /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null,
|
|
281
|
+
children: /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
|
|
282
|
+
action: labelAction
|
|
283
|
+
}), /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.Icon, {
|
|
284
284
|
size: 3,
|
|
285
285
|
icon: "ph--caret-down--bold",
|
|
286
286
|
classNames: "mis-1"
|
|
@@ -301,23 +301,22 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
301
301
|
}
|
|
302
302
|
})));
|
|
303
303
|
};
|
|
304
|
-
var ToggleGroupItem = ({ action, __menuScope }) => {
|
|
305
|
-
const { iconSize
|
|
304
|
+
var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
305
|
+
const { iconSize } = useMenu("ToggleGroupItem", __menuScope);
|
|
306
|
+
const { t } = (0, import_react_ui3.useTranslation)(translationKey);
|
|
306
307
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
307
|
-
const handleClick = (0, import_react4.useCallback)(() => {
|
|
308
|
-
|
|
309
|
-
}, [
|
|
308
|
+
const handleClick = (0, import_react4.useCallback)(() => action.data?.({
|
|
309
|
+
parent: group
|
|
310
|
+
}), [
|
|
310
311
|
action,
|
|
311
|
-
|
|
312
|
+
group
|
|
312
313
|
]);
|
|
313
314
|
const Root = icon ? import_react_ui3.Toolbar.ToggleGroupIconItem : import_react_ui3.Toolbar.ToggleGroupItem;
|
|
314
315
|
const rootProps = icon ? {
|
|
315
316
|
icon,
|
|
316
317
|
size: iconSize,
|
|
317
318
|
iconOnly,
|
|
318
|
-
label:
|
|
319
|
-
action
|
|
320
|
-
})
|
|
319
|
+
label: actionLabel(action, t)
|
|
321
320
|
} : {
|
|
322
321
|
children: /* @__PURE__ */ import_react4.default.createElement(ActionLabel, {
|
|
323
322
|
action
|
|
@@ -351,6 +350,7 @@ var ToggleGroupToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
351
350
|
// TODO(thure): Handle other menu item types.
|
|
352
351
|
items.map((action) => /* @__PURE__ */ import_react4.default.createElement(ToggleGroupItem, {
|
|
353
352
|
key: action.id,
|
|
353
|
+
group,
|
|
354
354
|
action
|
|
355
355
|
}))
|
|
356
356
|
)
|