@dxos/react-ui-menu 0.7.5-main.937ce75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +3 -0
  3. package/dist/lib/browser/index.mjs +231 -0
  4. package/dist/lib/browser/index.mjs.map +7 -0
  5. package/dist/lib/browser/meta.json +1 -0
  6. package/dist/lib/node/index.cjs +248 -0
  7. package/dist/lib/node/index.cjs.map +7 -0
  8. package/dist/lib/node/meta.json +1 -0
  9. package/dist/lib/node-esm/index.mjs +233 -0
  10. package/dist/lib/node-esm/index.mjs.map +7 -0
  11. package/dist/lib/node-esm/meta.json +1 -0
  12. package/dist/types/src/components/ActionLabel.d.ts +7 -0
  13. package/dist/types/src/components/ActionLabel.d.ts.map +1 -0
  14. package/dist/types/src/components/DropdownMenu.d.ts +19 -0
  15. package/dist/types/src/components/DropdownMenu.d.ts.map +1 -0
  16. package/dist/types/src/components/Toolbar/Toolbar.d.ts +4 -0
  17. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -0
  18. package/dist/types/src/components/Toolbar/ToolbarDropdownMenu.d.ts +4 -0
  19. package/dist/types/src/components/Toolbar/ToolbarDropdownMenu.d.ts.map +1 -0
  20. package/dist/types/src/components/Toolbar/ToolbarToggleGroup.d.ts +4 -0
  21. package/dist/types/src/components/Toolbar/ToolbarToggleGroup.d.ts.map +1 -0
  22. package/dist/types/src/components/Toolbar/defs.d.ts +30 -0
  23. package/dist/types/src/components/Toolbar/defs.d.ts.map +1 -0
  24. package/dist/types/src/components/Toolbar/index.d.ts +3 -0
  25. package/dist/types/src/components/Toolbar/index.d.ts.map +1 -0
  26. package/dist/types/src/components/index.d.ts +3 -0
  27. package/dist/types/src/components/index.d.ts.map +1 -0
  28. package/dist/types/src/defs.d.ts +18 -0
  29. package/dist/types/src/defs.d.ts.map +1 -0
  30. package/dist/types/src/index.d.ts +3 -0
  31. package/dist/types/src/index.d.ts.map +1 -0
  32. package/dist/types/src/testing/Menus.stories.d.ts +22 -0
  33. package/dist/types/src/testing/Menus.stories.d.ts.map +1 -0
  34. package/dist/types/src/testing/index.d.ts +26 -0
  35. package/dist/types/src/testing/index.d.ts.map +1 -0
  36. package/dist/types/src/translations.d.ts +8 -0
  37. package/dist/types/src/translations.d.ts.map +1 -0
  38. package/dist/types/src/util.d.ts +4 -0
  39. package/dist/types/src/util.d.ts.map +1 -0
  40. package/dist/types/tsconfig.tsbuildinfo +1 -0
  41. package/package.json +52 -0
  42. package/src/components/ActionLabel.tsx +30 -0
  43. package/src/components/DropdownMenu.tsx +104 -0
  44. package/src/components/Toolbar/Toolbar.tsx +71 -0
  45. package/src/components/Toolbar/ToolbarDropdownMenu.tsx +36 -0
  46. package/src/components/Toolbar/ToolbarToggleGroup.tsx +39 -0
  47. package/src/components/Toolbar/defs.ts +36 -0
  48. package/src/components/Toolbar/index.ts +6 -0
  49. package/src/components/index.ts +6 -0
  50. package/src/defs.ts +23 -0
  51. package/src/index.ts +6 -0
  52. package/src/testing/Menus.stories.tsx +55 -0
  53. package/src/testing/index.ts +92 -0
  54. package/src/translations.ts +13 -0
  55. package/src/util.ts +14 -0
@@ -0,0 +1,233 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+
3
+ // packages/ui/react-ui-menu/src/components/DropdownMenu.tsx
4
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
5
+ import React2, { useCallback } from "react";
6
+ import { DropdownMenu as NaturalDropdownMenu, Icon } from "@dxos/react-ui";
7
+
8
+ // packages/ui/react-ui-menu/src/components/ActionLabel.tsx
9
+ import React from "react";
10
+ import { keySymbols } from "@dxos/keyboard";
11
+ import { toLocalizedString, useTranslation } from "@dxos/react-ui";
12
+ import { mx, descriptionText } from "@dxos/react-ui-theme";
13
+
14
+ // packages/ui/react-ui-menu/src/translations.ts
15
+ var translationKey = "menus";
16
+ var translations_default = [
17
+ {
18
+ "en-US": {
19
+ [translationKey]: {}
20
+ }
21
+ }
22
+ ];
23
+
24
+ // packages/ui/react-ui-menu/src/util.ts
25
+ import { getHostPlatform } from "@dxos/util";
26
+ var getShortcut = (action) => {
27
+ return typeof action.properties?.keyBinding === "string" ? action.properties.keyBinding : action.properties?.keyBinding?.[getHostPlatform()];
28
+ };
29
+
30
+ // packages/ui/react-ui-menu/src/components/ActionLabel.tsx
31
+ var ActionLabel = ({ action }) => {
32
+ const shortcut = getShortcut(action);
33
+ const { t } = useTranslation(translationKey);
34
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", {
35
+ className: "grow truncate"
36
+ }, toLocalizedString(action.properties.label, t)), shortcut && /* @__PURE__ */ React.createElement("span", {
37
+ className: mx("shrink-0", descriptionText)
38
+ }, keySymbols(shortcut).join("")));
39
+ };
40
+
41
+ // packages/ui/react-ui-menu/src/components/DropdownMenu.tsx
42
+ var DropdownMenuItem = ({ action, onClick }) => {
43
+ const handleClick = useCallback((event) => onClick(action, event), [
44
+ action,
45
+ onClick
46
+ ]);
47
+ return /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Item, {
48
+ onClick: handleClick,
49
+ classNames: "gap-2",
50
+ disabled: action.properties?.disabled,
51
+ ...action.properties?.testId && {
52
+ "data-testid": action.properties.testId
53
+ }
54
+ }, action.properties?.icon && /* @__PURE__ */ React2.createElement(Icon, {
55
+ icon: action.properties.icon,
56
+ size: 4
57
+ }), /* @__PURE__ */ React2.createElement(ActionLabel, {
58
+ action
59
+ }));
60
+ };
61
+ var DropdownMenuRoot = ({ defaultMenuOpen, actions, menuOpen, suppressNextTooltip, onMenuOpenChange, onAction, children }) => {
62
+ const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({
63
+ prop: menuOpen,
64
+ defaultProp: defaultMenuOpen,
65
+ onChange: onMenuOpenChange
66
+ });
67
+ const handleActionClick = useCallback((action, event) => {
68
+ if (action.properties?.disabled) {
69
+ return;
70
+ }
71
+ event.stopPropagation();
72
+ if (suppressNextTooltip) {
73
+ suppressNextTooltip.current = true;
74
+ }
75
+ setOptionsMenuOpen(false);
76
+ onAction?.(action);
77
+ }, [
78
+ onAction
79
+ ]);
80
+ return /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Root, {
81
+ open: optionsMenuOpen,
82
+ onOpenChange: (nextOpen) => {
83
+ if (!nextOpen && suppressNextTooltip) {
84
+ suppressNextTooltip.current = true;
85
+ }
86
+ return setOptionsMenuOpen(nextOpen);
87
+ }
88
+ }, children, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Portal, null, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Content, null, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Viewport, null, actions?.map((action) => /* @__PURE__ */ React2.createElement(DropdownMenuItem, {
89
+ key: action.id,
90
+ action,
91
+ onClick: handleActionClick
92
+ }))), /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Arrow, null))));
93
+ };
94
+ var DropdownMenu = {
95
+ Root: DropdownMenuRoot,
96
+ Trigger: NaturalDropdownMenu.Trigger,
97
+ VirtualTrigger: NaturalDropdownMenu.VirtualTrigger
98
+ };
99
+
100
+ // packages/ui/react-ui-menu/src/components/Toolbar/Toolbar.tsx
101
+ import React5, { useCallback as useCallback2 } from "react";
102
+ import { Toolbar as NaturalToolbar3 } from "@dxos/react-ui";
103
+
104
+ // packages/ui/react-ui-menu/src/components/Toolbar/ToolbarDropdownMenu.tsx
105
+ import React3, { useMemo, useRef } from "react";
106
+ import { Toolbar as NaturalToolbar } from "@dxos/react-ui";
107
+ var ToolbarDropdownMenu = ({ actionGroup, graph, onAction, applyActiveIcon }) => {
108
+ const menuActions = useMemo(() => graph ? graph.actions(actionGroup) : [], [
109
+ actionGroup,
110
+ graph
111
+ ]);
112
+ const { icon, iconOnly = true, disabled, testId } = actionGroup.properties;
113
+ const suppressNextTooltip = useRef(false);
114
+ return /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
115
+ actions: menuActions,
116
+ onAction,
117
+ suppressNextTooltip
118
+ }, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
119
+ asChild: true
120
+ }, /* @__PURE__ */ React3.createElement(NaturalToolbar.IconButton, {
121
+ size: 5,
122
+ variant: "ghost",
123
+ iconOnly,
124
+ disabled,
125
+ icon: applyActiveIcon && menuActions.find((action) => !!action.properties.checked)?.properties.icon || icon,
126
+ label: /* @__PURE__ */ React3.createElement(ActionLabel, {
127
+ action: actionGroup
128
+ }),
129
+ ...testId && {
130
+ "data-testid": testId
131
+ },
132
+ suppressNextTooltip,
133
+ caretDown: true
134
+ })));
135
+ };
136
+
137
+ // packages/ui/react-ui-menu/src/components/Toolbar/ToolbarToggleGroup.tsx
138
+ import React4, { useMemo as useMemo2 } from "react";
139
+ import { Toolbar as NaturalToolbar2 } from "@dxos/react-ui";
140
+ var ToolbarToggleGroupItem = ({ action }) => {
141
+ const { icon, iconOnly, disabled } = action.properties;
142
+ return /* @__PURE__ */ React4.createElement(NaturalToolbar2.ToggleGroupIconItem, {
143
+ key: action.id,
144
+ value: action.id,
145
+ icon,
146
+ iconOnly,
147
+ disabled,
148
+ label: /* @__PURE__ */ React4.createElement(ActionLabel, {
149
+ action
150
+ })
151
+ });
152
+ };
153
+ var ToolbarToggleGroup = ({ actionGroup, graph }) => {
154
+ const menuActions = useMemo2(() => graph ? graph.actions(actionGroup) : [], [
155
+ actionGroup,
156
+ graph
157
+ ]);
158
+ const { selectCardinality, value } = actionGroup.properties;
159
+ return (
160
+ // TODO(thure): This is extremely difficult to manage, what do?
161
+ // @ts-ignore
162
+ /* @__PURE__ */ React4.createElement(NaturalToolbar2.ToggleGroup, {
163
+ type: selectCardinality,
164
+ value
165
+ }, menuActions.map((action) => /* @__PURE__ */ React4.createElement(ToolbarToggleGroupItem, {
166
+ key: action.id,
167
+ action
168
+ })))
169
+ );
170
+ };
171
+
172
+ // packages/ui/react-ui-menu/src/components/Toolbar/defs.ts
173
+ import { ACTION_GROUP_TYPE } from "@dxos/app-graph";
174
+ var ToolbarSeparatorType = "@dxos/react-ui-toolbar/separator";
175
+ var isSeparator = (node) => node.type === ToolbarSeparatorType;
176
+ var isMenu = (node) => node.type === ACTION_GROUP_TYPE;
177
+
178
+ // packages/ui/react-ui-menu/src/components/Toolbar/Toolbar.tsx
179
+ var ToolbarItem = ({ iconSize, action, onAction }) => {
180
+ const handleClick = useCallback2(() => {
181
+ onAction?.(action);
182
+ }, [
183
+ action,
184
+ onAction
185
+ ]);
186
+ const { icon, iconOnly = true, disabled, testId } = action.properties;
187
+ return /* @__PURE__ */ React5.createElement(NaturalToolbar3.IconButton, {
188
+ key: action.id,
189
+ iconOnly,
190
+ variant: "ghost",
191
+ icon,
192
+ size: iconSize,
193
+ label: /* @__PURE__ */ React5.createElement(ActionLabel, {
194
+ action
195
+ }),
196
+ disabled,
197
+ onClick: handleClick,
198
+ ...testId && {
199
+ "data-testid": testId
200
+ }
201
+ });
202
+ };
203
+ var Toolbar = ({ actions: items, onAction, iconSize = 5, graph, ...props }) => {
204
+ return /* @__PURE__ */ React5.createElement(NaturalToolbar3.Root, props, items?.map((item, i) => isSeparator(item) ? /* @__PURE__ */ React5.createElement(NaturalToolbar3.Separator, {
205
+ key: i,
206
+ variant: item.properties.variant
207
+ }) : isMenu(item) ? item.properties.variant === "dropdownMenu" ? /* @__PURE__ */ React5.createElement(ToolbarDropdownMenu, {
208
+ key: item.id,
209
+ actionGroup: item,
210
+ onAction,
211
+ iconSize,
212
+ graph
213
+ }) : /* @__PURE__ */ React5.createElement(ToolbarToggleGroup, {
214
+ key: item.id,
215
+ actionGroup: item,
216
+ onAction,
217
+ iconSize,
218
+ graph
219
+ }) : /* @__PURE__ */ React5.createElement(ToolbarItem, {
220
+ key: item.id,
221
+ action: item,
222
+ onAction,
223
+ iconSize
224
+ })));
225
+ };
226
+ export {
227
+ DropdownMenu,
228
+ Toolbar,
229
+ ToolbarSeparatorType,
230
+ isMenu,
231
+ isSeparator
232
+ };
233
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/components/DropdownMenu.tsx", "../../../src/components/ActionLabel.tsx", "../../../src/translations.ts", "../../../src/util.ts", "../../../src/components/Toolbar/Toolbar.tsx", "../../../src/components/Toolbar/ToolbarDropdownMenu.tsx", "../../../src/components/Toolbar/ToolbarToggleGroup.tsx", "../../../src/components/Toolbar/defs.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, type PropsWithChildren, useCallback } from 'react';\n\nimport { DropdownMenu as NaturalDropdownMenu, Icon } from '@dxos/react-ui';\n\nimport { ActionLabel } from './ActionLabel';\nimport { type MenuAction, type MenuProps } from '../defs';\n\nexport type DropdownMenuProps = MenuProps &\n PropsWithChildren<\n Partial<{\n defaultMenuOpen: boolean;\n menuOpen: boolean;\n onMenuOpenChange: (nextOpen: boolean) => void;\n suppressNextTooltip?: MutableRefObject<boolean>;\n }>\n >;\n\nconst DropdownMenuItem = ({\n action,\n onClick,\n}: {\n action: MenuAction;\n onClick: (action: MenuAction, event: MouseEvent) => void;\n}) => {\n const handleClick = useCallback((event: MouseEvent) => onClick(action, event), [action, onClick]);\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={4} />}\n <ActionLabel action={action} />\n </NaturalDropdownMenu.Item>\n );\n};\n\nconst DropdownMenuRoot = ({\n defaultMenuOpen,\n actions,\n menuOpen,\n suppressNextTooltip,\n onMenuOpenChange,\n onAction,\n children,\n}: DropdownMenuProps) => {\n const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({\n prop: menuOpen,\n defaultProp: defaultMenuOpen,\n onChange: onMenuOpenChange,\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 onAction?.(action);\n },\n [onAction],\n );\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 >\n {children}\n <NaturalDropdownMenu.Portal>\n <NaturalDropdownMenu.Content>\n <NaturalDropdownMenu.Viewport>\n {actions?.map((action) => <DropdownMenuItem key={action.id} action={action} 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 { type ActionLike } from '@dxos/app-graph';\nimport { getHostPlatform } from '@dxos/util';\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// Copyright 2025 DXOS.org\n//\n\nimport React, { useCallback } from 'react';\n\nimport { Toolbar as NaturalToolbar } from '@dxos/react-ui';\n\nimport { ToolbarDropdownMenu } from './ToolbarDropdownMenu';\nimport { ToolbarToggleGroup } from './ToolbarToggleGroup';\nimport { isMenu, isSeparator, type ToolbarProps } from './defs';\nimport { type MenuAction } from '../../defs';\nimport { ActionLabel } from '../ActionLabel';\n\nconst ToolbarItem = ({\n iconSize,\n action,\n onAction,\n}: Pick<ToolbarProps, 'iconSize' | 'onAction'> & {\n action: MenuAction;\n}) => {\n const handleClick = useCallback(() => {\n onAction?.(action);\n }, [action, onAction]);\n const { icon, iconOnly = true, disabled, testId } = action.properties;\n return (\n <NaturalToolbar.IconButton\n key={action.id}\n iconOnly={iconOnly}\n variant='ghost'\n icon={icon}\n size={iconSize}\n label={<ActionLabel action={action} />}\n disabled={disabled}\n onClick={handleClick}\n {...(testId && { 'data-testid': testId })}\n />\n );\n};\n\nexport const Toolbar = ({ actions: items, onAction, iconSize = 5, graph, ...props }: ToolbarProps) => {\n return (\n <NaturalToolbar.Root {...props}>\n {items?.map((item, i) =>\n isSeparator(item) ? (\n <NaturalToolbar.Separator key={i} variant={item.properties.variant} />\n ) : isMenu(item) ? (\n item.properties.variant === 'dropdownMenu' ? (\n <ToolbarDropdownMenu\n key={item.id}\n actionGroup={item}\n onAction={onAction}\n iconSize={iconSize}\n graph={graph}\n />\n ) : (\n <ToolbarToggleGroup\n key={item.id}\n actionGroup={item}\n onAction={onAction}\n iconSize={iconSize}\n graph={graph}\n />\n )\n ) : (\n <ToolbarItem key={item.id} action={item as MenuAction} onAction={onAction} iconSize={iconSize} />\n ),\n )}\n </NaturalToolbar.Root>\n );\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useMemo, useRef } from 'react';\n\nimport { Toolbar as NaturalToolbar } from '@dxos/react-ui';\n\nimport { type ToolbarActionGroupProps } from './defs';\nimport { type MenuAction } from '../../defs';\nimport { ActionLabel } from '../ActionLabel';\nimport { DropdownMenu } from '../DropdownMenu';\n\nexport const ToolbarDropdownMenu = ({ actionGroup, graph, onAction, applyActiveIcon }: ToolbarActionGroupProps) => {\n const menuActions = useMemo(() => (graph ? graph.actions(actionGroup) : []) as MenuAction[], [actionGroup, graph]);\n const { icon, iconOnly = true, disabled, testId } = actionGroup.properties;\n const suppressNextTooltip = useRef(false);\n\n return (\n <DropdownMenu.Root actions={menuActions} onAction={onAction} suppressNextTooltip={suppressNextTooltip}>\n <DropdownMenu.Trigger asChild>\n <NaturalToolbar.IconButton\n size={5}\n variant='ghost'\n iconOnly={iconOnly}\n disabled={disabled}\n icon={(applyActiveIcon && menuActions.find((action) => !!action.properties.checked)?.properties.icon) || icon}\n label={<ActionLabel action={actionGroup} />}\n {...(testId && { 'data-testid': testId })}\n suppressNextTooltip={suppressNextTooltip}\n caretDown\n />\n </DropdownMenu.Trigger>\n </DropdownMenu.Root>\n );\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { Toolbar as NaturalToolbar } from '@dxos/react-ui';\n\nimport type { ToolbarActionGroupProps } from './defs';\nimport { type MenuAction } from '../../defs';\nimport { ActionLabel } from '../ActionLabel';\n\nconst ToolbarToggleGroupItem = ({ action }: { action: MenuAction }) => {\n const { icon, iconOnly, disabled } = action.properties;\n return (\n <NaturalToolbar.ToggleGroupIconItem\n key={action.id}\n value={action.id}\n icon={icon}\n iconOnly={iconOnly}\n disabled={disabled}\n label={<ActionLabel action={action} />}\n />\n );\n};\n\nexport const ToolbarToggleGroup = ({ actionGroup, graph }: ToolbarActionGroupProps) => {\n const menuActions = useMemo(() => (graph ? (graph.actions(actionGroup) as MenuAction[]) : []), [actionGroup, graph]);\n const { selectCardinality, value } = actionGroup.properties;\n return (\n // TODO(thure): This is extremely difficult to manage, what do?\n // @ts-ignore\n <NaturalToolbar.ToggleGroup type={selectCardinality} value={value}>\n {menuActions.map((action) => (\n <ToolbarToggleGroupItem key={action.id} action={action} />\n ))}\n </NaturalToolbar.ToggleGroup>\n );\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Node, type ActionGroup, type Graph, ACTION_GROUP_TYPE } from '@dxos/app-graph';\nimport { type ToolbarRootProps, type ToolbarSeparatorProps, type IconButtonProps } from '@dxos/react-ui';\n\nimport { type MenuAction, type MenuActionProperties, type MenuProps } from '../../defs';\n\nexport const ToolbarSeparatorType = '@dxos/react-ui-toolbar/separator' as const;\n\nexport type ToolbarSeparatorNode = Node<never, Pick<ToolbarSeparatorProps, 'variant'>> & {\n type: typeof ToolbarSeparatorType;\n};\n\nexport const isSeparator = (node: Node): node is ToolbarSeparatorNode => node.type === ToolbarSeparatorType;\n\nexport type ToolbarActionGroupProperties = Omit<MenuActionProperties, 'variant'> & {\n variant: 'dropdownMenu' | 'toggleGroup';\n} & ({ selectCardinality?: 'single'; value?: string } | { selectCardinality?: 'multiple'; value?: string[] });\n\nexport type ToolbarActionGroup = ActionGroup<ToolbarActionGroupProperties>;\n\nexport const isMenu = (node: Node): node is ToolbarActionGroup => node.type === ACTION_GROUP_TYPE;\n\nexport type ToolbarItem = ToolbarSeparatorNode | MenuAction | ToolbarActionGroup;\n\nexport type ToolbarProps = ToolbarRootProps &\n MenuProps<ToolbarItem, MenuAction> & { iconSize?: IconButtonProps['size']; graph?: Graph };\n\nexport type ToolbarActionGroupProps = Pick<ToolbarProps, 'iconSize'> &\n Omit<MenuProps<MenuAction>, 'actions'> & {\n actionGroup: ToolbarActionGroup;\n graph?: Graph;\n applyActiveIcon?: boolean;\n };\n"],
5
+ "mappings": "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",
6
+ "names": ["useControllableState", "React", "useCallback", "DropdownMenu", "NaturalDropdownMenu", "Icon", "React", "keySymbols", "toLocalizedString", "useTranslation", "mx", "descriptionText", "translationKey", "getHostPlatform", "getShortcut", "action", "properties", "keyBinding", "getHostPlatform", "ActionLabel", "action", "shortcut", "getShortcut", "t", "useTranslation", "translationKey", "span", "className", "toLocalizedString", "properties", "label", "mx", "descriptionText", "keySymbols", "join", "DropdownMenuItem", "action", "onClick", "handleClick", "useCallback", "event", "React", "NaturalDropdownMenu", "Item", "classNames", "disabled", "properties", "testId", "icon", "Icon", "size", "ActionLabel", "DropdownMenuRoot", "defaultMenuOpen", "actions", "menuOpen", "suppressNextTooltip", "onMenuOpenChange", "onAction", "children", "optionsMenuOpen", "setOptionsMenuOpen", "useControllableState", "prop", "defaultProp", "onChange", "handleActionClick", "stopPropagation", "current", "Root", "open", "onOpenChange", "nextOpen", "Portal", "Content", "Viewport", "map", "key", "id", "Arrow", "DropdownMenu", "Trigger", "VirtualTrigger", "React", "useCallback", "Toolbar", "NaturalToolbar", "React", "useMemo", "useRef", "Toolbar", "NaturalToolbar", "ToolbarDropdownMenu", "actionGroup", "graph", "onAction", "applyActiveIcon", "menuActions", "useMemo", "actions", "icon", "iconOnly", "disabled", "testId", "properties", "suppressNextTooltip", "useRef", "React", "DropdownMenu", "Root", "Trigger", "asChild", "NaturalToolbar", "IconButton", "size", "variant", "find", "action", "checked", "label", "ActionLabel", "caretDown", "React", "useMemo", "Toolbar", "NaturalToolbar", "ToolbarToggleGroupItem", "action", "icon", "iconOnly", "disabled", "properties", "React", "NaturalToolbar", "ToggleGroupIconItem", "key", "id", "value", "label", "ActionLabel", "ToolbarToggleGroup", "actionGroup", "graph", "menuActions", "useMemo", "actions", "selectCardinality", "ToggleGroup", "type", "map", "ACTION_GROUP_TYPE", "ToolbarSeparatorType", "isSeparator", "node", "type", "isMenu", "ACTION_GROUP_TYPE", "ToolbarItem", "iconSize", "action", "onAction", "handleClick", "useCallback", "icon", "iconOnly", "disabled", "testId", "properties", "React", "NaturalToolbar", "IconButton", "key", "id", "variant", "size", "label", "ActionLabel", "onClick", "Toolbar", "actions", "items", "graph", "props", "Root", "map", "item", "i", "isSeparator", "Separator", "isMenu", "ToolbarDropdownMenu", "actionGroup", "ToolbarToggleGroup"]
7
+ }
@@ -0,0 +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":1578,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-menu/src/components/ActionLabel.tsx":{"bytes":3310,"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/DropdownMenu.tsx":{"bytes":9986,"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"}],"format":"esm"},"packages/ui/react-ui-menu/src/components/Toolbar/ToolbarDropdownMenu.tsx":{"bytes":5223,"imports":[{"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/DropdownMenu.tsx","kind":"import-statement","original":"../DropdownMenu"}],"format":"esm"},"packages/ui/react-ui-menu/src/components/Toolbar/ToolbarToggleGroup.tsx":{"bytes":4731,"imports":[{"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"}],"format":"esm"},"packages/ui/react-ui-menu/src/components/Toolbar/defs.ts":{"bytes":3030,"imports":[{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-menu/src/components/Toolbar/Toolbar.tsx":{"bytes":7348,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-menu/src/components/Toolbar/ToolbarDropdownMenu.tsx","kind":"import-statement","original":"./ToolbarDropdownMenu"},{"path":"packages/ui/react-ui-menu/src/components/Toolbar/ToolbarToggleGroup.tsx","kind":"import-statement","original":"./ToolbarToggleGroup"},{"path":"packages/ui/react-ui-menu/src/components/Toolbar/defs.ts","kind":"import-statement","original":"./defs"},{"path":"packages/ui/react-ui-menu/src/components/ActionLabel.tsx","kind":"import-statement","original":"../ActionLabel"}],"format":"esm"},"packages/ui/react-ui-menu/src/components/Toolbar/index.ts":{"bytes":595,"imports":[{"path":"packages/ui/react-ui-menu/src/components/Toolbar/Toolbar.tsx","kind":"import-statement","original":"./Toolbar"},{"path":"packages/ui/react-ui-menu/src/components/Toolbar/defs.ts","kind":"import-statement","original":"./defs"}],"format":"esm"},"packages/ui/react-ui-menu/src/components/index.ts":{"bytes":607,"imports":[{"path":"packages/ui/react-ui-menu/src/components/DropdownMenu.tsx","kind":"import-statement","original":"./DropdownMenu"},{"path":"packages/ui/react-ui-menu/src/components/Toolbar/index.ts","kind":"import-statement","original":"./Toolbar"}],"format":"esm"},"packages/ui/react-ui-menu/src/defs.ts":{"bytes":1144,"imports":[],"format":"esm"},"packages/ui/react-ui-menu/src/index.ts":{"bytes":583,"imports":[{"path":"packages/ui/react-ui-menu/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/ui/react-ui-menu/src/defs.ts","kind":"import-statement","original":"./defs"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-menu/dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18405},"packages/ui/react-ui-menu/dist/lib/node-esm/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/util","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/react-ui","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/app-graph","kind":"import-statement","external":true}],"exports":["DropdownMenu","Toolbar","ToolbarSeparatorType","isMenu","isSeparator"],"entryPoint":"packages/ui/react-ui-menu/src/index.ts","inputs":{"packages/ui/react-ui-menu/src/components/DropdownMenu.tsx":{"bytesInOutput":2296},"packages/ui/react-ui-menu/src/components/ActionLabel.tsx":{"bytesInOutput":667},"packages/ui/react-ui-menu/src/translations.ts":{"bytesInOutput":118},"packages/ui/react-ui-menu/src/util.ts":{"bytesInOutput":225},"packages/ui/react-ui-menu/src/components/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-menu/src/components/Toolbar/Toolbar.tsx":{"bytesInOutput":1503},"packages/ui/react-ui-menu/src/components/Toolbar/ToolbarDropdownMenu.tsx":{"bytesInOutput":1096},"packages/ui/react-ui-menu/src/components/Toolbar/ToolbarToggleGroup.tsx":{"bytesInOutput":1069},"packages/ui/react-ui-menu/src/components/Toolbar/defs.ts":{"bytesInOutput":236},"packages/ui/react-ui-menu/src/components/Toolbar/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-menu/src/index.ts":{"bytesInOutput":0}},"bytes":8106}}}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { type Action, type ActionGroup } from '@dxos/app-graph';
3
+ import { type MenuActionProperties } from '../defs';
4
+ export declare const ActionLabel: ({ action, }: {
5
+ action: Action<MenuActionProperties> | ActionGroup<Omit<MenuActionProperties, "variant">>;
6
+ }) => React.JSX.Element;
7
+ //# sourceMappingURL=ActionLabel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionLabel.d.ts","sourceRoot":"","sources":["../../../../src/components/ActionLabel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAIpD,eAAO,MAAM,WAAW,gBAErB;IACD,MAAM,EAAE,MAAM,CAAC,oBAAoB,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC,CAAC;CAC3F,sBAUA,CAAC"}
@@ -0,0 +1,19 @@
1
+ import React, { type MutableRefObject, type PropsWithChildren } from 'react';
2
+ import { type MenuProps } from '../defs';
3
+ export type DropdownMenuProps = MenuProps & PropsWithChildren<Partial<{
4
+ defaultMenuOpen: boolean;
5
+ menuOpen: boolean;
6
+ onMenuOpenChange: (nextOpen: boolean) => void;
7
+ suppressNextTooltip?: MutableRefObject<boolean>;
8
+ }>>;
9
+ export declare const DropdownMenu: {
10
+ Root: ({ defaultMenuOpen, actions, menuOpen, suppressNextTooltip, onMenuOpenChange, onAction, children, }: DropdownMenuProps) => React.JSX.Element;
11
+ Trigger: React.ForwardRefExoticComponent<import("@dxos/react-ui").DropdownMenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
12
+ VirtualTrigger: {
13
+ (props: import("@dxos/react-ui").DropdownMenuVirtualTriggerProps & {
14
+ __scopeDropdownMenu?: import("@radix-ui/react-context").Scope;
15
+ }): React.JSX.Element;
16
+ displayName: string;
17
+ };
18
+ };
19
+ //# sourceMappingURL=DropdownMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../../../src/components/DropdownMenu.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAmB,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAe,MAAM,OAAO,CAAC;AAK3G,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG,SAAS,GACvC,iBAAiB,CACf,OAAO,CAAC;IACN,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACjD,CAAC,CACH,CAAC;AA+EJ,eAAO,MAAM,YAAY;+GAhDtB,iBAAiB;;;;;YAqDmgC,MAAO,GAAG,CAAC,OAAO;;;CADxiC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { type ToolbarProps } from './defs';
3
+ export declare const Toolbar: ({ actions: items, onAction, iconSize, graph, ...props }: ToolbarProps) => React.JSX.Element;
4
+ //# sourceMappingURL=Toolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../../../../src/components/Toolbar/Toolbar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAsB,MAAM,OAAO,CAAC;AAM3C,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AA8BhE,eAAO,MAAM,OAAO,4DAAiE,YAAY,sBA8BhG,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { type ToolbarActionGroupProps } from './defs';
3
+ export declare const ToolbarDropdownMenu: ({ actionGroup, graph, onAction, applyActiveIcon }: ToolbarActionGroupProps) => React.JSX.Element;
4
+ //# sourceMappingURL=ToolbarDropdownMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarDropdownMenu.d.ts","sourceRoot":"","sources":["../../../../../src/components/Toolbar/ToolbarDropdownMenu.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA0B,MAAM,OAAO,CAAC;AAI/C,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,QAAQ,CAAC;AAKtD,eAAO,MAAM,mBAAmB,sDAAuD,uBAAuB,sBAsB7G,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { ToolbarActionGroupProps } from './defs';
3
+ export declare const ToolbarToggleGroup: ({ actionGroup, graph }: ToolbarActionGroupProps) => React.JSX.Element;
4
+ //# sourceMappingURL=ToolbarToggleGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarToggleGroup.d.ts","sourceRoot":"","sources":["../../../../../src/components/Toolbar/ToolbarToggleGroup.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,QAAQ,CAAC;AAkBtD,eAAO,MAAM,kBAAkB,2BAA4B,uBAAuB,sBAYjF,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { type Node, type ActionGroup, type Graph } from '@dxos/app-graph';
2
+ import { type ToolbarRootProps, type ToolbarSeparatorProps, type IconButtonProps } from '@dxos/react-ui';
3
+ import { type MenuAction, type MenuActionProperties, type MenuProps } from '../../defs';
4
+ export declare const ToolbarSeparatorType: "@dxos/react-ui-toolbar/separator";
5
+ export type ToolbarSeparatorNode = Node<never, Pick<ToolbarSeparatorProps, 'variant'>> & {
6
+ type: typeof ToolbarSeparatorType;
7
+ };
8
+ export declare const isSeparator: (node: Node) => node is ToolbarSeparatorNode;
9
+ export type ToolbarActionGroupProperties = Omit<MenuActionProperties, 'variant'> & {
10
+ variant: 'dropdownMenu' | 'toggleGroup';
11
+ } & ({
12
+ selectCardinality?: 'single';
13
+ value?: string;
14
+ } | {
15
+ selectCardinality?: 'multiple';
16
+ value?: string[];
17
+ });
18
+ export type ToolbarActionGroup = ActionGroup<ToolbarActionGroupProperties>;
19
+ export declare const isMenu: (node: Node) => node is ToolbarActionGroup;
20
+ export type ToolbarItem = ToolbarSeparatorNode | MenuAction | ToolbarActionGroup;
21
+ export type ToolbarProps = ToolbarRootProps & MenuProps<ToolbarItem, MenuAction> & {
22
+ iconSize?: IconButtonProps['size'];
23
+ graph?: Graph;
24
+ };
25
+ export type ToolbarActionGroupProps = Pick<ToolbarProps, 'iconSize'> & Omit<MenuProps<MenuAction>, 'actions'> & {
26
+ actionGroup: ToolbarActionGroup;
27
+ graph?: Graph;
28
+ applyActiveIcon?: boolean;
29
+ };
30
+ //# sourceMappingURL=defs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../../../src/components/Toolbar/defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAqB,MAAM,iBAAiB,CAAC;AAC7F,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEzG,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,oBAAoB,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAExF,eAAO,MAAM,oBAAoB,EAAG,kCAA2C,CAAC;AAEhF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC,GAAG;IACvF,IAAI,EAAE,OAAO,oBAAoB,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,IAAI,KAAG,IAAI,IAAI,oBAA0D,CAAC;AAE5G,MAAM,MAAM,4BAA4B,GAAG,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,GAAG;IACjF,OAAO,EAAE,cAAc,GAAG,aAAa,CAAC;CACzC,GAAG,CAAC;IAAE,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC;AAE9G,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,4BAA4B,CAAC,CAAC;AAE3E,eAAO,MAAM,MAAM,SAAU,IAAI,KAAG,IAAI,IAAI,kBAAqD,CAAC;AAElG,MAAM,MAAM,WAAW,GAAG,oBAAoB,GAAG,UAAU,GAAG,kBAAkB,CAAC;AAEjF,MAAM,MAAM,YAAY,GAAG,gBAAgB,GACzC,SAAS,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE7F,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,GAClE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,GAAG;IACvC,WAAW,EAAE,kBAAkB,CAAC;IAChC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './Toolbar';
2
+ export * from './defs';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/Toolbar/index.ts"],"names":[],"mappings":"AAIA,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './DropdownMenu';
2
+ export * from './Toolbar';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAIA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type Node, type Action } from '@dxos/app-graph';
2
+ import { type Label } from '@dxos/react-ui';
3
+ export type MenuActionProperties = {
4
+ label: Label;
5
+ icon: string;
6
+ value?: string;
7
+ disabled?: boolean;
8
+ iconOnly?: boolean;
9
+ testId?: string;
10
+ variant?: 'action' | 'toggle';
11
+ checked?: boolean;
12
+ };
13
+ export type MenuAction = Action<MenuActionProperties>;
14
+ export type MenuProps<A extends Node = Action<MenuActionProperties>, P extends Node = A> = {
15
+ actions?: A[];
16
+ onAction?: (action: P) => void;
17
+ };
18
+ //# sourceMappingURL=defs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../src/defs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAEtD,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,IAAI,GAAG,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI;IACzF,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;IACd,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;CAChC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './components';
2
+ export * from './defs';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import '@dxos-theme';
2
+ import React from 'react';
3
+ declare const _default: {
4
+ title: string;
5
+ component: ({ actions: items, onAction, iconSize, graph, ...props }: import("../components").ToolbarProps) => React.JSX.Element;
6
+ decorators: import("@storybook/react/*").Decorator[];
7
+ parameters: {
8
+ translations: readonly [{
9
+ readonly 'en-US': {
10
+ readonly menus: {};
11
+ };
12
+ }];
13
+ };
14
+ };
15
+ export default _default;
16
+ export declare const DropdownMenu: {
17
+ render: () => React.JSX.Element;
18
+ };
19
+ export declare const Toolbar: {
20
+ render: () => React.JSX.Element;
21
+ };
22
+ //# sourceMappingURL=Menus.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Menus.stories.d.ts","sourceRoot":"","sources":["../../../../src/testing/Menus.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,MAAM,OAAO,CAAC;;;;;;;;;;;;;AAa1B,wBAKE;AAOF,eAAO,MAAM,YAAY;;CAWxB,CAAC;AAEF,eAAO,MAAM,OAAO;;CAUnB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type Action, Graph, ACTION_TYPE, ACTION_GROUP_TYPE } from '@dxos/app-graph';
2
+ import { type ToolbarItem } from '../components';
3
+ import { type MenuAction } from '../defs';
4
+ export type CreateActionsParams = Partial<{
5
+ type?: typeof ACTION_TYPE | typeof ACTION_GROUP_TYPE;
6
+ callback: () => void;
7
+ count: number;
8
+ }>;
9
+ export declare const createActions: (params?: CreateActionsParams) => import("@dxos/live-object").ReactiveObject<{
10
+ id: string;
11
+ type: "dxos.org/type/GraphActionGroup" | "dxos.org/type/GraphAction";
12
+ data: symbol | (() => void);
13
+ properties: {
14
+ variant?: string | undefined;
15
+ label: string;
16
+ icon: string;
17
+ disabled: boolean;
18
+ };
19
+ }>[];
20
+ export declare const createNestedActionGraph: (groupParams?: CreateActionsParams, params?: CreateActionsParams) => {
21
+ graph: Graph;
22
+ topLevelActions: ToolbarItem[];
23
+ };
24
+ export declare const mutateActionsOnInterval: (actions: Action[]) => NodeJS.Timeout;
25
+ export declare const useMutateActions: (actions: MenuAction[]) => void;
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/testing/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,EAAgB,WAAW,EAAE,iBAAiB,EAAqB,MAAM,iBAAiB,CAAC;AAKtH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC;IACxC,IAAI,CAAC,EAAE,OAAO,WAAW,GAAG,OAAO,iBAAiB,CAAC;IACrD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAqBH,eAAO,MAAM,aAAa,YAAa,mBAAmB;;;0BAvBxC,IAAI;;;;;;;IAyCrB,CAAC;AAEF,eAAO,MAAM,uBAAuB,iBAAkB,mBAAmB,WAAW,mBAAmB;;qBAapD,WAAW,EAAE;CAC/D,CAAC;AAEF,eAAO,MAAM,uBAAuB,YAAa,MAAM,EAAE,mBAUxD,CAAC;AAEF,eAAO,MAAM,gBAAgB,YAAa,UAAU,EAAE,SAI9C,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare const translationKey = "menus";
2
+ declare const _default: readonly [{
3
+ readonly 'en-US': {
4
+ readonly menus: {};
5
+ };
6
+ }];
7
+ export default _default;
8
+ //# sourceMappingURL=translations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../src/translations.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,UAAU,CAAC;;;;;;AAEtC,wBAMW"}
@@ -0,0 +1,4 @@
1
+ import { type ActionLike } from '@dxos/app-graph';
2
+ export declare const getShortcut: (action: ActionLike) => any;
3
+ export declare const fallbackIcon = "ph--placeholder--regular";
4
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,eAAO,MAAM,WAAW,WAAY,UAAU,QAI7C,CAAC;AAEF,eAAO,MAAM,YAAY,6BAA6B,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":"5.7.2"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@dxos/react-ui-menu",
3
+ "version": "0.7.5-main.937ce75",
4
+ "description": "Components for facilitating reactive and consistent menus.",
5
+ "homepage": "https://dxos.org",
6
+ "bugs": "https://github.com/dxos/dxos/issues",
7
+ "license": "MIT",
8
+ "author": "DXOS.org",
9
+ "sideEffects": true,
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/types/src/index.d.ts",
13
+ "browser": "./dist/lib/browser/index.mjs",
14
+ "node": "./dist/lib/node-esm/index.mjs"
15
+ }
16
+ },
17
+ "types": "dist/types/src/index.d.ts",
18
+ "typesVersions": {
19
+ "*": {}
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "src"
24
+ ],
25
+ "dependencies": {
26
+ "@radix-ui/react-use-controllable-state": "^1.0.0",
27
+ "@dxos/keyboard": "0.7.5-main.937ce75",
28
+ "@dxos/util": "0.7.5-main.937ce75",
29
+ "@dxos/app-graph": "0.7.5-main.937ce75"
30
+ },
31
+ "devDependencies": {
32
+ "@types/react": "~18.2.0",
33
+ "@types/react-dom": "~18.2.0",
34
+ "react": "~18.2.0",
35
+ "react-dom": "~18.2.0",
36
+ "vite": "5.4.7",
37
+ "@dxos/live-object": "0.7.5-main.937ce75",
38
+ "@dxos/random": "0.7.5-main.937ce75",
39
+ "@dxos/react-ui-theme": "0.7.5-main.937ce75",
40
+ "@dxos/react-ui": "0.7.5-main.937ce75",
41
+ "@dxos/storybook-utils": "0.7.5-main.937ce75"
42
+ },
43
+ "peerDependencies": {
44
+ "react": "~18.2.0",
45
+ "react-dom": "~18.2.0",
46
+ "@dxos/react-ui": "0.7.5-main.937ce75",
47
+ "@dxos/react-ui-theme": "0.7.5-main.937ce75"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }
@@ -0,0 +1,30 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { type Action, type ActionGroup } from '@dxos/app-graph';
8
+ import { keySymbols } from '@dxos/keyboard';
9
+ import { toLocalizedString, useTranslation } from '@dxos/react-ui';
10
+ import { mx, descriptionText } from '@dxos/react-ui-theme';
11
+
12
+ import { type MenuActionProperties } from '../defs';
13
+ import { translationKey } from '../translations';
14
+ import { getShortcut } from '../util';
15
+
16
+ export const ActionLabel = ({
17
+ action,
18
+ }: {
19
+ action: Action<MenuActionProperties> | ActionGroup<Omit<MenuActionProperties, 'variant'>>;
20
+ }) => {
21
+ const shortcut = getShortcut(action);
22
+ const { t } = useTranslation(translationKey);
23
+
24
+ return (
25
+ <>
26
+ <span className='grow truncate'>{toLocalizedString(action.properties!.label, t)}</span>
27
+ {shortcut && <span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>}
28
+ </>
29
+ );
30
+ };