@dxos/react-ui-menu 0.8.4-main.406dc2a → 0.8.4-main.422d1c7879
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +549 -405
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +549 -405
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/builder.d.ts +27 -2
- package/dist/types/src/builder.d.ts.map +1 -1
- package/dist/types/src/builder.test.d.ts +2 -0
- package/dist/types/src/builder.test.d.ts.map +1 -0
- package/dist/types/src/components/ActionLabel.d.ts +3 -3
- package/dist/types/src/components/ActionLabel.d.ts.map +1 -1
- package/dist/types/src/components/DropdownMenu.d.ts +4 -2
- package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu.d.ts +50 -0
- package/dist/types/src/components/Menu.d.ts.map +1 -0
- package/dist/types/src/components/Menu.stories.d.ts +21 -0
- package/dist/types/src/components/Menu.stories.d.ts.map +1 -0
- package/dist/types/src/components/Menu.test.d.ts +2 -0
- package/dist/types/src/components/Menu.test.d.ts.map +1 -0
- package/dist/types/src/components/ToolbarMenu.d.ts +7 -6
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts +4 -2
- package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useMenuActions.d.ts +8 -7
- package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +19 -13
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +37 -26
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +14 -5
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -32
- package/src/builder.test.ts +224 -0
- package/src/builder.ts +69 -19
- package/src/components/ActionLabel.tsx +5 -5
- package/src/components/DropdownMenu.tsx +12 -6
- package/src/components/Menu.stories.tsx +265 -0
- package/src/components/Menu.test.tsx +447 -0
- package/src/components/Menu.tsx +348 -0
- package/src/components/ToolbarMenu.stories.tsx +36 -27
- package/src/components/ToolbarMenu.tsx +138 -89
- package/src/components/index.ts +1 -3
- package/src/hooks/useMenuActions.ts +28 -54
- package/src/index.ts +1 -3
- package/src/testing/generator.ts +74 -64
- package/src/translations.ts +1 -1
- package/src/types.ts +39 -27
- package/src/util.ts +34 -15
- package/dist/types/src/components/MenuContext.d.ts +0 -13
- package/dist/types/src/components/MenuContext.d.ts.map +0 -1
- package/src/components/MenuContext.tsx +0 -50
|
@@ -1,46 +1,37 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import { Icon, DropdownMenu as NaturalDropdownMenu } from "@dxos/react-ui";
|
|
9
|
-
|
|
10
|
-
// src/components/ActionLabel.tsx
|
|
11
|
-
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
12
|
-
import React from "react";
|
|
13
|
-
import { keySymbols } from "@dxos/keyboard";
|
|
14
|
-
import { toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
15
|
-
import { descriptionText, mx } from "@dxos/react-ui-theme";
|
|
16
|
-
|
|
17
|
-
// src/translations.ts
|
|
18
|
-
var translationKey = "react-ui-menu";
|
|
19
|
-
var translations = [
|
|
20
|
-
{
|
|
21
|
-
"en-US": {
|
|
22
|
-
[translationKey]: {}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
];
|
|
1
|
+
// src/components/Menu.tsx
|
|
2
|
+
import { Atom, RegistryContext, useAtomValue } from "@effect-atom/atom-react";
|
|
3
|
+
import { createContextScope } from "@radix-ui/react-context";
|
|
4
|
+
import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
|
|
5
|
+
import React4, { createContext, useCallback as useCallback3, useContext, useMemo } from "react";
|
|
6
|
+
import { log } from "@dxos/log";
|
|
7
|
+
import { Icon as Icon3, DropdownMenu as NaturalDropdownMenu2 } from "@dxos/react-ui";
|
|
26
8
|
|
|
27
9
|
// src/util.ts
|
|
28
|
-
import
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import { Node } from "@dxos/app-graph";
|
|
12
|
+
import { runAndForwardErrors } from "@dxos/effect";
|
|
29
13
|
import { getHostPlatform } from "@dxos/util";
|
|
14
|
+
var executeMenuAction = async (action, params = {}) => {
|
|
15
|
+
let effect = action.data(params);
|
|
16
|
+
if (action._actionContext) {
|
|
17
|
+
effect = effect.pipe(Effect.provide(action._actionContext));
|
|
18
|
+
}
|
|
19
|
+
await runAndForwardErrors(effect);
|
|
20
|
+
};
|
|
30
21
|
var getShortcut = (action) => {
|
|
31
22
|
return typeof action.properties?.keyBinding === "string" ? action.properties.keyBinding : action.properties?.keyBinding?.[getHostPlatform()];
|
|
32
23
|
};
|
|
33
24
|
var createMenuAction = (id, invoke, properties) => ({
|
|
34
25
|
id,
|
|
35
|
-
type:
|
|
26
|
+
type: Node.ActionType,
|
|
36
27
|
properties,
|
|
37
|
-
data: invoke
|
|
28
|
+
data: () => Effect.sync(invoke)
|
|
38
29
|
});
|
|
39
30
|
var createMenuItemGroup = (id, properties) => ({
|
|
40
31
|
id,
|
|
41
|
-
type:
|
|
32
|
+
type: Node.ActionGroupType,
|
|
42
33
|
properties,
|
|
43
|
-
data: actionGroupSymbol
|
|
34
|
+
data: Node.actionGroupSymbol
|
|
44
35
|
});
|
|
45
36
|
var createGapSeparator = (id = "gap", source = "root") => ({
|
|
46
37
|
nodes: [
|
|
@@ -56,7 +47,8 @@ var createGapSeparator = (id = "gap", source = "root") => ({
|
|
|
56
47
|
edges: [
|
|
57
48
|
{
|
|
58
49
|
source,
|
|
59
|
-
target: id
|
|
50
|
+
target: id,
|
|
51
|
+
relation: "child"
|
|
60
52
|
}
|
|
61
53
|
]
|
|
62
54
|
});
|
|
@@ -74,128 +66,119 @@ var createLineSeparator = (id = "line", source = "root") => ({
|
|
|
74
66
|
edges: [
|
|
75
67
|
{
|
|
76
68
|
source,
|
|
77
|
-
target: id
|
|
69
|
+
target: id,
|
|
70
|
+
relation: "child"
|
|
78
71
|
}
|
|
79
72
|
]
|
|
80
73
|
});
|
|
81
74
|
|
|
82
75
|
// src/components/ActionLabel.tsx
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
76
|
+
import React from "react";
|
|
77
|
+
import { keySymbols } from "@dxos/keyboard";
|
|
78
|
+
import { toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
79
|
+
import { mx } from "@dxos/ui-theme";
|
|
80
|
+
|
|
81
|
+
// src/translations.ts
|
|
82
|
+
var translationKey = "@dxos/react-ui-menu";
|
|
83
|
+
var translations = [
|
|
84
|
+
{
|
|
85
|
+
"en-US": {
|
|
86
|
+
[translationKey]: {}
|
|
87
|
+
}
|
|
95
88
|
}
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
// src/components/ActionLabel.tsx
|
|
92
|
+
var ActionLabel = ({ action }) => {
|
|
93
|
+
const { t } = useTranslation(translationKey);
|
|
94
|
+
const shortcut = getShortcut(action);
|
|
95
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", {
|
|
96
|
+
className: "grow truncate"
|
|
97
|
+
}, toLocalizedString(action.properties.label, t)), shortcut && /* @__PURE__ */ React.createElement("span", {
|
|
98
|
+
className: mx("shrink-0", "text-description")
|
|
99
|
+
}, keySymbols(shortcut).join("")));
|
|
96
100
|
};
|
|
97
101
|
var actionLabel = (action, t) => {
|
|
98
102
|
const shortcut = getShortcut(action);
|
|
99
103
|
return `${toLocalizedString(action.properties.label, t)}${shortcut ? ` (${keySymbols(shortcut).join("")})` : ""}`;
|
|
100
104
|
};
|
|
101
105
|
|
|
102
|
-
// src/components/
|
|
103
|
-
import {
|
|
104
|
-
import {
|
|
105
|
-
import
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
var useMenuScope = createMenuScope();
|
|
114
|
-
var MenuProvider = ({ children, useGroupItems = menuContextDefaults.useGroupItems, iconSize = menuContextDefaults.iconSize, attendableId }) => {
|
|
115
|
-
var _effect = _useSignals2();
|
|
116
|
-
try {
|
|
117
|
-
const { scope } = useMenuScope(void 0);
|
|
118
|
-
return /* @__PURE__ */ React2.createElement(MenuContextProvider, {
|
|
119
|
-
useGroupItems,
|
|
120
|
-
iconSize,
|
|
121
|
-
attendableId,
|
|
122
|
-
scope
|
|
123
|
-
}, children);
|
|
124
|
-
} finally {
|
|
125
|
-
_effect.f();
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __menuScope) => {
|
|
129
|
-
const { useGroupItems } = useMenu(consumerName, __menuScope);
|
|
130
|
-
const groupItems = useGroupItems(group);
|
|
131
|
-
return useMemo(() => propsItems ?? groupItems ?? void 0, [
|
|
132
|
-
propsItems,
|
|
133
|
-
groupItems
|
|
134
|
-
]);
|
|
135
|
-
};
|
|
106
|
+
// src/components/ToolbarMenu.tsx
|
|
107
|
+
import React3, { useCallback as useCallback2 } from "react";
|
|
108
|
+
import { Icon as Icon2, Toolbar as NaturalToolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
109
|
+
import { useAttention } from "@dxos/react-ui-attention";
|
|
110
|
+
import { composable, composableProps } from "@dxos/ui-theme";
|
|
111
|
+
|
|
112
|
+
// src/types.ts
|
|
113
|
+
import { Node as Node2 } from "@dxos/app-graph";
|
|
114
|
+
var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
|
|
115
|
+
var isSeparator = (node) => node.type === MenuSeparatorType;
|
|
116
|
+
var isMenuGroup = (node) => node.type === Node2.ActionGroupType;
|
|
136
117
|
|
|
137
118
|
// src/components/DropdownMenu.tsx
|
|
119
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
120
|
+
import React2, { useCallback } from "react";
|
|
121
|
+
import { Icon, DropdownMenu as NaturalDropdownMenu } from "@dxos/react-ui";
|
|
138
122
|
var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
action
|
|
159
|
-
}));
|
|
160
|
-
} finally {
|
|
161
|
-
_effect.f();
|
|
162
|
-
}
|
|
123
|
+
const action = item;
|
|
124
|
+
const handleClick = useCallback((event) => onClick(action, event), [
|
|
125
|
+
action,
|
|
126
|
+
onClick
|
|
127
|
+
]);
|
|
128
|
+
const { iconSize } = useMenuScoped("DropdownMenuItem", __menuScope);
|
|
129
|
+
return /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Item, {
|
|
130
|
+
onClick: handleClick,
|
|
131
|
+
classNames: "gap-2",
|
|
132
|
+
disabled: action.properties?.disabled,
|
|
133
|
+
...action.properties?.testId && {
|
|
134
|
+
"data-testid": action.properties.testId
|
|
135
|
+
}
|
|
136
|
+
}, action.properties?.icon && /* @__PURE__ */ React2.createElement(Icon, {
|
|
137
|
+
icon: action.properties.icon,
|
|
138
|
+
size: iconSize
|
|
139
|
+
}), /* @__PURE__ */ React2.createElement(ActionLabel, {
|
|
140
|
+
action
|
|
141
|
+
}));
|
|
163
142
|
};
|
|
164
143
|
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, caller, children, __menuScope, ...naturalProps }) => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
144
|
+
const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({
|
|
145
|
+
prop: open,
|
|
146
|
+
defaultProp: defaultOpen,
|
|
147
|
+
onChange: onOpenChange
|
|
148
|
+
});
|
|
149
|
+
const { onAction } = useMenuScoped("DropdownMenuRoot", __menuScope);
|
|
150
|
+
const handleActionClick = useCallback((action, event) => {
|
|
151
|
+
if (action.properties?.disabled) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
event.stopPropagation();
|
|
155
|
+
setOptionsMenuOpen(false);
|
|
156
|
+
if (onAction) {
|
|
157
|
+
onAction(action, {
|
|
179
158
|
parent: group,
|
|
180
159
|
caller
|
|
181
160
|
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
161
|
+
} else {
|
|
162
|
+
void executeMenuAction(action, {
|
|
163
|
+
parent: group,
|
|
164
|
+
caller
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}, [
|
|
168
|
+
group,
|
|
169
|
+
caller,
|
|
170
|
+
onAction
|
|
171
|
+
]);
|
|
172
|
+
const items = useMenuItems(group, propsItems);
|
|
173
|
+
return /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Root, {
|
|
174
|
+
open: optionsMenuOpen,
|
|
175
|
+
onOpenChange: setOptionsMenuOpen,
|
|
176
|
+
...naturalProps
|
|
177
|
+
}, children, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Portal, null, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Content, null, /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Viewport, null, items?.map((item) => /* @__PURE__ */ React2.createElement(DropdownMenuItem, {
|
|
178
|
+
key: item.id,
|
|
179
|
+
item,
|
|
180
|
+
onClick: handleActionClick
|
|
181
|
+
}))), /* @__PURE__ */ React2.createElement(NaturalDropdownMenu.Arrow, null))));
|
|
199
182
|
};
|
|
200
183
|
var DropdownMenu = {
|
|
201
184
|
Root: DropdownMenuRoot,
|
|
@@ -204,297 +187,430 @@ var DropdownMenu = {
|
|
|
204
187
|
};
|
|
205
188
|
|
|
206
189
|
// src/components/ToolbarMenu.tsx
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
iconOnly,
|
|
234
|
-
label: actionLabel(action, t)
|
|
235
|
-
} : {
|
|
236
|
-
children: /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
237
|
-
action
|
|
238
|
-
})
|
|
239
|
-
};
|
|
240
|
-
return hidden ? null : /* @__PURE__ */ React4.createElement(Root, {
|
|
241
|
-
key: action.id,
|
|
242
|
-
disabled,
|
|
243
|
-
onClick: handleClick,
|
|
244
|
-
variant: "ghost",
|
|
245
|
-
...testId && {
|
|
246
|
-
"data-testid": testId
|
|
247
|
-
},
|
|
248
|
-
...rootProps,
|
|
249
|
-
classNames
|
|
250
|
-
});
|
|
251
|
-
} finally {
|
|
252
|
-
_effect.f();
|
|
190
|
+
var ActionToolbarItem = ({ __menuScope, action }) => {
|
|
191
|
+
const { iconSize, onAction } = useMenuScoped("ActionToolbarItem", __menuScope);
|
|
192
|
+
const { t } = useTranslation2(translationKey);
|
|
193
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
194
|
+
const buttonVariant = action.properties.variant === "primary" ? "primary" : "ghost";
|
|
195
|
+
const handleClick = useCallback2(() => {
|
|
196
|
+
if (onAction) {
|
|
197
|
+
onAction(action, {});
|
|
198
|
+
} else {
|
|
199
|
+
void executeMenuAction(action);
|
|
200
|
+
}
|
|
201
|
+
}, [
|
|
202
|
+
action,
|
|
203
|
+
onAction
|
|
204
|
+
]);
|
|
205
|
+
const commonProps = {
|
|
206
|
+
variant: buttonVariant,
|
|
207
|
+
disabled,
|
|
208
|
+
classNames,
|
|
209
|
+
onClick: handleClick,
|
|
210
|
+
...testId && {
|
|
211
|
+
"data-testid": testId
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
if (hidden) {
|
|
215
|
+
return null;
|
|
253
216
|
}
|
|
217
|
+
return icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.IconButton, {
|
|
218
|
+
key: action.id,
|
|
219
|
+
...commonProps,
|
|
220
|
+
icon,
|
|
221
|
+
size: iconSize,
|
|
222
|
+
iconOnly,
|
|
223
|
+
label: actionLabel(action, t)
|
|
224
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
225
|
+
key: action.id,
|
|
226
|
+
...commonProps
|
|
227
|
+
}, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
228
|
+
action
|
|
229
|
+
}));
|
|
254
230
|
};
|
|
255
|
-
var DropdownMenuToolbarItem = ({ group, items: propsItems
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
|
|
231
|
+
var DropdownMenuToolbarItem = ({ __menuScope, group, items: propsItems }) => {
|
|
232
|
+
const { iconOnly, disabled, testId } = group.properties;
|
|
233
|
+
const { t } = useTranslation2(translationKey);
|
|
234
|
+
const { iconSize } = useMenuScoped("DropdownMenuToolbarItem", __menuScope);
|
|
235
|
+
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
236
|
+
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
237
|
+
const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
|
|
238
|
+
activeItem?.properties.icon || group.properties.icon;
|
|
239
|
+
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
240
|
+
const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
|
|
241
|
+
const rootProps = icon ? {
|
|
242
|
+
icon,
|
|
243
|
+
size: iconSize,
|
|
244
|
+
iconOnly,
|
|
245
|
+
label: actionLabel(labelAction, t),
|
|
246
|
+
caretDown: true
|
|
247
|
+
} : {
|
|
248
|
+
children: /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
249
|
+
action: labelAction
|
|
250
|
+
}), /* @__PURE__ */ React3.createElement(Icon2, {
|
|
251
|
+
size: 3,
|
|
252
|
+
icon: "ph--caret-down--bold",
|
|
253
|
+
classNames: "ms-1"
|
|
254
|
+
}))
|
|
255
|
+
};
|
|
256
|
+
return /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
|
257
|
+
group,
|
|
258
|
+
items
|
|
259
|
+
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
|
260
|
+
asChild: true
|
|
261
|
+
}, /* @__PURE__ */ React3.createElement(Root, {
|
|
262
|
+
variant: "ghost",
|
|
263
|
+
disabled,
|
|
264
|
+
...rootProps,
|
|
265
|
+
...testId && {
|
|
266
|
+
"data-testid": testId
|
|
267
|
+
}
|
|
268
|
+
})));
|
|
269
|
+
};
|
|
270
|
+
var ToggleGroupItem = ({ __menuScope, group, action }) => {
|
|
271
|
+
const { iconSize, onAction } = useMenuScoped("ToggleGroupItem", __menuScope);
|
|
272
|
+
const { t } = useTranslation2(translationKey);
|
|
273
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
274
|
+
const handleClick = useCallback2(() => {
|
|
275
|
+
if (onAction) {
|
|
276
|
+
onAction(action, {
|
|
277
|
+
parent: group
|
|
278
|
+
});
|
|
279
|
+
} else {
|
|
280
|
+
void executeMenuAction(action, {
|
|
281
|
+
parent: group
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}, [
|
|
285
|
+
action,
|
|
286
|
+
group,
|
|
287
|
+
onAction
|
|
288
|
+
]);
|
|
289
|
+
const commonProps = {
|
|
290
|
+
value: action.id,
|
|
291
|
+
disabled,
|
|
292
|
+
variant: "ghost",
|
|
293
|
+
classNames,
|
|
294
|
+
onClick: handleClick,
|
|
295
|
+
...testId && {
|
|
296
|
+
"data-testid": testId
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
return hidden ? null : icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupIconItem, {
|
|
300
|
+
...commonProps,
|
|
301
|
+
icon,
|
|
302
|
+
size: iconSize,
|
|
303
|
+
iconOnly,
|
|
304
|
+
label: actionLabel(action, t)
|
|
305
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, commonProps, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
306
|
+
action
|
|
307
|
+
}));
|
|
308
|
+
};
|
|
309
|
+
var ToggleGroupToolbarItem = ({ __menuScope, group, items: itemsProp }) => {
|
|
310
|
+
const items = useMenuItems(group, itemsProp, "ToggleGroupToolbarItem", __menuScope);
|
|
311
|
+
const { selectCardinality } = group.properties;
|
|
312
|
+
const children = items.map((action) => /* @__PURE__ */ React3.createElement(ToggleGroupItem, {
|
|
313
|
+
key: action.id,
|
|
314
|
+
group,
|
|
315
|
+
action
|
|
316
|
+
}));
|
|
317
|
+
if (selectCardinality === "multiple") {
|
|
318
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
319
|
+
type: "multiple",
|
|
320
|
+
value: group.properties.value
|
|
321
|
+
}, children);
|
|
322
|
+
} else {
|
|
323
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
324
|
+
type: "single",
|
|
325
|
+
value: group.properties.value
|
|
326
|
+
}, children);
|
|
297
327
|
}
|
|
298
328
|
};
|
|
299
|
-
var
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
action
|
|
320
|
-
})
|
|
321
|
-
};
|
|
322
|
-
return hidden ? null : /* @__PURE__ */ React4.createElement(Root, {
|
|
323
|
-
key: action.id,
|
|
324
|
-
value: action.id,
|
|
325
|
-
disabled,
|
|
326
|
-
onClick: handleClick,
|
|
327
|
-
variant: "ghost",
|
|
328
|
-
...testId && {
|
|
329
|
-
"data-testid": testId
|
|
330
|
-
},
|
|
331
|
-
...rootProps,
|
|
332
|
-
classNames
|
|
329
|
+
var ToolbarMenu = composable(({ __menuScope, children, ...props }, forwardedRef) => {
|
|
330
|
+
const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
|
|
331
|
+
const { attendableId, alwaysActive } = useMenuScoped("ToolbarMenu", __menuScope);
|
|
332
|
+
const { hasAttention } = useAttention(attendableId);
|
|
333
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
|
|
334
|
+
...composableProps(props, {
|
|
335
|
+
classNames: attendableId
|
|
336
|
+
}),
|
|
337
|
+
disabled: !alwaysActive && !hasAttention,
|
|
338
|
+
ref: forwardedRef
|
|
339
|
+
}, items?.map((item) => /* @__PURE__ */ React3.createElement(ToolbarMenuItem, {
|
|
340
|
+
key: item.id,
|
|
341
|
+
__menuScope,
|
|
342
|
+
item
|
|
343
|
+
})), children);
|
|
344
|
+
});
|
|
345
|
+
var ToolbarMenuItem = ({ __menuScope, item }) => {
|
|
346
|
+
if (isSeparator(item)) {
|
|
347
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Separator, {
|
|
348
|
+
variant: item.properties.variant
|
|
333
349
|
});
|
|
334
|
-
} finally {
|
|
335
|
-
_effect.f();
|
|
336
350
|
}
|
|
351
|
+
if (isMenuGroup(item)) {
|
|
352
|
+
if (item.properties.variant === "dropdownMenu") {
|
|
353
|
+
return /* @__PURE__ */ React3.createElement(DropdownMenuToolbarItem, {
|
|
354
|
+
__menuScope,
|
|
355
|
+
group: item
|
|
356
|
+
});
|
|
357
|
+
} else {
|
|
358
|
+
return /* @__PURE__ */ React3.createElement(ToggleGroupToolbarItem, {
|
|
359
|
+
__menuScope,
|
|
360
|
+
group: item
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return /* @__PURE__ */ React3.createElement(ActionToolbarItem, {
|
|
365
|
+
__menuScope,
|
|
366
|
+
action: item
|
|
367
|
+
});
|
|
337
368
|
};
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
items.map((action) => /* @__PURE__ */ React4.createElement(ToggleGroupItem, {
|
|
354
|
-
key: action.id,
|
|
355
|
-
group,
|
|
356
|
-
action
|
|
357
|
-
}))
|
|
358
|
-
)
|
|
359
|
-
);
|
|
360
|
-
} finally {
|
|
361
|
-
_effect.f();
|
|
369
|
+
|
|
370
|
+
// src/components/Menu.tsx
|
|
371
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-menu/src/components/Menu.tsx";
|
|
372
|
+
var MENU_NAME = "Menu";
|
|
373
|
+
var [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);
|
|
374
|
+
var nullItemsAtom = Atom.make(null);
|
|
375
|
+
var defaultItemsAccessor = () => nullItemsAtom;
|
|
376
|
+
var menuContextDefaults = {
|
|
377
|
+
iconSize: 5,
|
|
378
|
+
items: defaultItemsAccessor,
|
|
379
|
+
onAction: void 0,
|
|
380
|
+
menuItemsAtom: Atom.make(/* @__PURE__ */ new Map()),
|
|
381
|
+
addMenuItems: () => {
|
|
382
|
+
},
|
|
383
|
+
removeMenuItems: () => {
|
|
362
384
|
}
|
|
363
385
|
};
|
|
364
|
-
var
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const { attendableId } = useMenu("ToolbarMenu", __menuScope);
|
|
369
|
-
const { hasAttention } = useAttention(attendableId);
|
|
370
|
-
const InnerRoot = wrapContents ? "div" : Fragment;
|
|
371
|
-
const innerRootProps = wrapContents ? {
|
|
372
|
-
role: "none",
|
|
373
|
-
className: mx2(textBlockWidth, toolbarLayout, "bs-full")
|
|
374
|
-
} : {};
|
|
375
|
-
return /* @__PURE__ */ React4.createElement(NaturalToolbar.Root, {
|
|
376
|
-
...props,
|
|
377
|
-
layoutManaged: wrapContents,
|
|
378
|
-
classNames: [
|
|
379
|
-
attendableId && !hasAttention && "*:opacity-20 !bg-transparent",
|
|
380
|
-
classNames
|
|
381
|
-
]
|
|
382
|
-
}, /* @__PURE__ */ React4.createElement(InnerRoot, innerRootProps, items?.map((item, i) => /* @__PURE__ */ React4.createElement(ToolbarMenuItem, {
|
|
383
|
-
key: item.id ?? i,
|
|
384
|
-
item
|
|
385
|
-
}))));
|
|
386
|
-
} finally {
|
|
387
|
-
_effect.f();
|
|
386
|
+
var [MenuContextProvider, useMenuScoped] = createMenuContext(MENU_NAME, menuContextDefaults);
|
|
387
|
+
var useMenuScope = createMenuScope();
|
|
388
|
+
var MenuDropdownContext = /* @__PURE__ */ createContext({
|
|
389
|
+
closeMenu: () => {
|
|
388
390
|
}
|
|
391
|
+
});
|
|
392
|
+
var DEFAULT_PRIORITY = 100;
|
|
393
|
+
var sortMenuItems = (items) => [
|
|
394
|
+
...items
|
|
395
|
+
].sort((a, b) => {
|
|
396
|
+
if (a.priority !== b.priority) {
|
|
397
|
+
return a.priority - b.priority;
|
|
398
|
+
}
|
|
399
|
+
return a.id.localeCompare(b.id);
|
|
400
|
+
});
|
|
401
|
+
var MenuProvider = ({ children, items = menuContextDefaults.items, iconSize = menuContextDefaults.iconSize, attendableId, alwaysActive, onAction }) => {
|
|
402
|
+
const { scope } = useMenuScope(void 0);
|
|
403
|
+
const registry = useContext(RegistryContext);
|
|
404
|
+
const menuItemsAtom = useMemo(() => Atom.make(/* @__PURE__ */ new Map()).pipe(Atom.keepAlive), []);
|
|
405
|
+
const addMenuItems = useCallback3((props) => {
|
|
406
|
+
const priority = props.priority ?? DEFAULT_PRIORITY;
|
|
407
|
+
const prev = registry.get(menuItemsAtom);
|
|
408
|
+
const next = new Map(prev);
|
|
409
|
+
next.set(props.id, {
|
|
410
|
+
...props,
|
|
411
|
+
priority
|
|
412
|
+
});
|
|
413
|
+
registry.set(menuItemsAtom, next);
|
|
414
|
+
}, [
|
|
415
|
+
registry,
|
|
416
|
+
menuItemsAtom
|
|
417
|
+
]);
|
|
418
|
+
const removeMenuItems = useCallback3((id) => {
|
|
419
|
+
const prev = registry.get(menuItemsAtom);
|
|
420
|
+
const next = new Map(prev);
|
|
421
|
+
next.delete(id);
|
|
422
|
+
registry.set(menuItemsAtom, next);
|
|
423
|
+
}, [
|
|
424
|
+
registry,
|
|
425
|
+
menuItemsAtom
|
|
426
|
+
]);
|
|
427
|
+
return /* @__PURE__ */ React4.createElement(MenuContextProvider, {
|
|
428
|
+
items,
|
|
429
|
+
iconSize,
|
|
430
|
+
attendableId,
|
|
431
|
+
alwaysActive,
|
|
432
|
+
menuItemsAtom,
|
|
433
|
+
addMenuItems,
|
|
434
|
+
removeMenuItems,
|
|
435
|
+
onAction,
|
|
436
|
+
scope
|
|
437
|
+
}, children);
|
|
389
438
|
};
|
|
390
|
-
var
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
439
|
+
var resolveItems = (baseItems, group, entries) => {
|
|
440
|
+
const applicable = [
|
|
441
|
+
...entries.values()
|
|
442
|
+
].filter((entry) => !entry.groupFilter || entry.groupFilter(group));
|
|
443
|
+
if (applicable.length === 0) {
|
|
444
|
+
return baseItems;
|
|
445
|
+
}
|
|
446
|
+
const sorted = sortMenuItems(applicable);
|
|
447
|
+
const replacements = sorted.filter((entry) => entry.mode === "replacement");
|
|
448
|
+
if (replacements.length > 0) {
|
|
449
|
+
if (replacements.length > 1) {
|
|
450
|
+
log.warn("multiple replacement entries found", {
|
|
451
|
+
ids: replacements.map((r) => r.id).join(", "),
|
|
452
|
+
using: replacements[0].id
|
|
453
|
+
}, {
|
|
454
|
+
F: __dxlog_file,
|
|
455
|
+
L: 151,
|
|
456
|
+
S: void 0,
|
|
457
|
+
C: (f, a) => f(...a)
|
|
396
458
|
});
|
|
397
459
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
return /* @__PURE__ */ React4.createElement(ToggleGroupToolbarItem, {
|
|
405
|
-
group: item
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
return /* @__PURE__ */ React4.createElement(ActionToolbarItem, {
|
|
410
|
-
action: item
|
|
411
|
-
});
|
|
412
|
-
} finally {
|
|
413
|
-
_effect.f();
|
|
460
|
+
return replacements[0].items;
|
|
461
|
+
}
|
|
462
|
+
const additive = sorted.filter((entry) => entry.mode === "additive");
|
|
463
|
+
const additiveItems = additive.flatMap((entry) => entry.items);
|
|
464
|
+
if (!baseItems || baseItems.length === 0) {
|
|
465
|
+
return additiveItems.length > 0 ? additiveItems : null;
|
|
414
466
|
}
|
|
467
|
+
return [
|
|
468
|
+
...baseItems,
|
|
469
|
+
...additiveItems
|
|
470
|
+
];
|
|
415
471
|
};
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
472
|
+
var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __menuScope) => {
|
|
473
|
+
const { items, menuItemsAtom } = useMenuScoped(consumerName, __menuScope);
|
|
474
|
+
const groupItems = useAtomValue(items(group));
|
|
475
|
+
const entries = useAtomValue(menuItemsAtom) ?? /* @__PURE__ */ new Map();
|
|
476
|
+
const baseItems = useMemo(() => propsItems ?? groupItems ?? null, [
|
|
477
|
+
propsItems,
|
|
478
|
+
groupItems
|
|
479
|
+
]);
|
|
480
|
+
const resolved = useMemo(() => resolveItems(baseItems, group, entries), [
|
|
481
|
+
baseItems,
|
|
482
|
+
group,
|
|
483
|
+
entries
|
|
484
|
+
]);
|
|
485
|
+
return resolved ?? void 0;
|
|
486
|
+
};
|
|
487
|
+
var useMenu = (consumerName) => {
|
|
488
|
+
return useMenuScoped(consumerName, void 0);
|
|
489
|
+
};
|
|
490
|
+
var MenuRoot = ({ children, open, defaultOpen, onOpenChange, caller, ...props }) => {
|
|
491
|
+
const [menuOpen, setMenuOpen] = useControllableState2({
|
|
492
|
+
prop: open,
|
|
493
|
+
defaultProp: defaultOpen,
|
|
494
|
+
onChange: onOpenChange
|
|
495
|
+
});
|
|
496
|
+
const closeMenu = useCallback3(() => setMenuOpen(false), [
|
|
497
|
+
setMenuOpen
|
|
498
|
+
]);
|
|
499
|
+
return /* @__PURE__ */ React4.createElement(MenuProvider, props, /* @__PURE__ */ React4.createElement(MenuDropdownContext.Provider, {
|
|
500
|
+
value: {
|
|
501
|
+
closeMenu,
|
|
502
|
+
caller
|
|
428
503
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
504
|
+
}, /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Root, {
|
|
505
|
+
open: menuOpen,
|
|
506
|
+
onOpenChange: setMenuOpen
|
|
507
|
+
}, children)));
|
|
508
|
+
};
|
|
509
|
+
var MenuContentItem = ({ item, onClick, __menuScope }) => {
|
|
510
|
+
const action = item;
|
|
511
|
+
const handleClick = useCallback3((event) => onClick(action, event), [
|
|
512
|
+
action,
|
|
513
|
+
onClick
|
|
514
|
+
]);
|
|
515
|
+
const { iconSize } = useMenuScoped("MenuContentItem", __menuScope);
|
|
516
|
+
return /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Item, {
|
|
517
|
+
onClick: handleClick,
|
|
518
|
+
classNames: "gap-2",
|
|
519
|
+
disabled: action.properties?.disabled,
|
|
520
|
+
...action.properties?.testId && {
|
|
521
|
+
"data-testid": action.properties.testId
|
|
434
522
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
523
|
+
}, action.properties?.icon && /* @__PURE__ */ React4.createElement(Icon3, {
|
|
524
|
+
icon: action.properties.icon,
|
|
525
|
+
size: iconSize
|
|
526
|
+
}), /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
527
|
+
action
|
|
528
|
+
}));
|
|
529
|
+
};
|
|
530
|
+
var MenuContent = ({ group, items: propsItems, caller: callerOverride, __menuScope }) => {
|
|
531
|
+
const { closeMenu, caller: contextCaller } = useContext(MenuDropdownContext);
|
|
532
|
+
const caller = callerOverride ?? contextCaller;
|
|
533
|
+
const { onAction } = useMenuScoped("MenuContent", __menuScope);
|
|
534
|
+
const resolvedItems = useMenuItems(group, propsItems, "MenuContent", __menuScope);
|
|
535
|
+
const handleActionClick = useCallback3((action, event) => {
|
|
536
|
+
if (action.properties?.disabled) {
|
|
537
|
+
return;
|
|
438
538
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
539
|
+
event.stopPropagation();
|
|
540
|
+
closeMenu();
|
|
541
|
+
if (onAction) {
|
|
542
|
+
onAction(action, {
|
|
543
|
+
parent: group,
|
|
544
|
+
caller
|
|
545
|
+
});
|
|
546
|
+
} else {
|
|
547
|
+
void executeMenuAction(action, {
|
|
548
|
+
parent: group,
|
|
549
|
+
caller
|
|
550
|
+
});
|
|
442
551
|
}
|
|
443
|
-
|
|
444
|
-
|
|
552
|
+
}, [
|
|
553
|
+
group,
|
|
554
|
+
caller,
|
|
555
|
+
onAction,
|
|
556
|
+
closeMenu
|
|
557
|
+
]);
|
|
558
|
+
return /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Portal, null, /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Content, null, /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Viewport, null, resolvedItems?.map((item) => /* @__PURE__ */ React4.createElement(MenuContentItem, {
|
|
559
|
+
key: item.id,
|
|
560
|
+
item,
|
|
561
|
+
onClick: handleActionClick
|
|
562
|
+
}))), /* @__PURE__ */ React4.createElement(NaturalDropdownMenu2.Arrow, null)));
|
|
445
563
|
};
|
|
564
|
+
var Menu = {
|
|
565
|
+
Root: MenuRoot,
|
|
566
|
+
Trigger: NaturalDropdownMenu2.Trigger,
|
|
567
|
+
Content: MenuContent,
|
|
568
|
+
VirtualTrigger: NaturalDropdownMenu2.VirtualTrigger,
|
|
569
|
+
Toolbar: ToolbarMenu
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// src/hooks/useMenuActions.ts
|
|
573
|
+
import { RegistryContext as RegistryContext2, useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
574
|
+
import { useCallback as useCallback4, useContext as useContext2, useMemo as useMemo2 } from "react";
|
|
575
|
+
import { Graph, Node as Node3 } from "@dxos/app-graph";
|
|
446
576
|
var useMenuActions = (props) => {
|
|
447
|
-
const registry =
|
|
448
|
-
const menuGraphProps =
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
graph.addNodes(menuGraphProps.nodes);
|
|
456
|
-
graph.addEdges(menuGraphProps.edges);
|
|
577
|
+
const registry = useContext2(RegistryContext2);
|
|
578
|
+
const menuGraphProps = useAtomValue2(props);
|
|
579
|
+
const graph = useMemo2(() => {
|
|
580
|
+
const newGraph = Graph.make({
|
|
581
|
+
registry
|
|
582
|
+
});
|
|
583
|
+
newGraph.pipe(Graph.addNodes(menuGraphProps.nodes), Graph.addEdges(menuGraphProps.edges));
|
|
584
|
+
return newGraph;
|
|
457
585
|
}, [
|
|
586
|
+
registry,
|
|
458
587
|
menuGraphProps
|
|
459
588
|
]);
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
return items;
|
|
589
|
+
const items = useCallback4((group) => {
|
|
590
|
+
return graph.connections(group?.id || Node3.RootId, "child");
|
|
463
591
|
}, [
|
|
464
592
|
graph
|
|
465
593
|
]);
|
|
466
594
|
return {
|
|
467
|
-
|
|
595
|
+
items
|
|
468
596
|
};
|
|
469
597
|
};
|
|
470
598
|
|
|
471
599
|
// src/builder.ts
|
|
472
600
|
import { invariant } from "@dxos/invariant";
|
|
473
|
-
|
|
474
|
-
if (key in obj) {
|
|
475
|
-
Object.defineProperty(obj, key, {
|
|
476
|
-
value,
|
|
477
|
-
enumerable: true,
|
|
478
|
-
configurable: true,
|
|
479
|
-
writable: true
|
|
480
|
-
});
|
|
481
|
-
} else {
|
|
482
|
-
obj[key] = value;
|
|
483
|
-
}
|
|
484
|
-
return obj;
|
|
485
|
-
}
|
|
486
|
-
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-menu/src/builder.ts";
|
|
487
|
-
var MenuBuilder = Object.freeze({
|
|
488
|
-
make: () => new MenuBuilderImpl({
|
|
489
|
-
nodes: [],
|
|
490
|
-
edges: []
|
|
491
|
-
}, "root")
|
|
492
|
-
});
|
|
601
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-menu/src/builder.ts";
|
|
493
602
|
var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
603
|
+
_data;
|
|
604
|
+
_rootId;
|
|
605
|
+
_separatorCount = 0;
|
|
606
|
+
constructor(_data, _rootId) {
|
|
607
|
+
this._data = _data;
|
|
608
|
+
this._rootId = _rootId;
|
|
609
|
+
}
|
|
494
610
|
root(props) {
|
|
495
611
|
invariant(this._rootId === "root", "Root group can only be at the top level", {
|
|
496
|
-
F:
|
|
497
|
-
L:
|
|
612
|
+
F: __dxlog_file2,
|
|
613
|
+
L: 61,
|
|
498
614
|
S: this,
|
|
499
615
|
A: [
|
|
500
616
|
"this._rootId === 'root'",
|
|
@@ -502,8 +618,8 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
502
618
|
]
|
|
503
619
|
});
|
|
504
620
|
invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", {
|
|
505
|
-
F:
|
|
506
|
-
L:
|
|
621
|
+
F: __dxlog_file2,
|
|
622
|
+
L: 62,
|
|
507
623
|
S: this,
|
|
508
624
|
A: [
|
|
509
625
|
"this._data.nodes.find((node) => node.id === 'root') === undefined",
|
|
@@ -513,11 +629,15 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
513
629
|
this._data.nodes.push(createMenuItemGroup("root", props));
|
|
514
630
|
return this;
|
|
515
631
|
}
|
|
632
|
+
build() {
|
|
633
|
+
return this._data;
|
|
634
|
+
}
|
|
516
635
|
action(id, props, invoke) {
|
|
517
636
|
this._data.nodes.push(createMenuAction(id, invoke, props));
|
|
518
637
|
this._data.edges.push({
|
|
519
638
|
source: this._rootId,
|
|
520
|
-
target: id
|
|
639
|
+
target: id,
|
|
640
|
+
relation: "child"
|
|
521
641
|
});
|
|
522
642
|
return this;
|
|
523
643
|
}
|
|
@@ -525,38 +645,62 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
525
645
|
this._data.nodes.push(createMenuItemGroup(id, props));
|
|
526
646
|
this._data.edges.push({
|
|
527
647
|
source: this._rootId,
|
|
528
|
-
target: id
|
|
648
|
+
target: id,
|
|
649
|
+
relation: "child"
|
|
529
650
|
});
|
|
530
651
|
cb(new _MenuBuilderImpl(this._data, id));
|
|
531
652
|
return this;
|
|
532
653
|
}
|
|
533
|
-
|
|
534
|
-
|
|
654
|
+
subgraph(subgraphOrCb) {
|
|
655
|
+
if (!subgraphOrCb) {
|
|
656
|
+
return this;
|
|
657
|
+
}
|
|
658
|
+
if (typeof subgraphOrCb === "function") {
|
|
659
|
+
subgraphOrCb(new _MenuBuilderImpl(this._data, this._rootId));
|
|
660
|
+
} else {
|
|
661
|
+
this._data.nodes.push(...subgraphOrCb.nodes);
|
|
662
|
+
this._data.edges.push(...subgraphOrCb.edges);
|
|
663
|
+
}
|
|
664
|
+
return this;
|
|
535
665
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
666
|
+
separator(variant = "gap") {
|
|
667
|
+
const id = `separator-${++this._separatorCount}`;
|
|
668
|
+
this._data.nodes.push({
|
|
669
|
+
id,
|
|
670
|
+
type: MenuSeparatorType,
|
|
671
|
+
properties: {
|
|
672
|
+
variant
|
|
673
|
+
},
|
|
674
|
+
data: void 0
|
|
675
|
+
});
|
|
676
|
+
this._data.edges.push({
|
|
677
|
+
source: this._rootId,
|
|
678
|
+
target: id,
|
|
679
|
+
relation: "child"
|
|
680
|
+
});
|
|
681
|
+
return this;
|
|
541
682
|
}
|
|
542
683
|
};
|
|
684
|
+
var MenuBuilder = Object.freeze({
|
|
685
|
+
make: () => new MenuBuilderImpl({
|
|
686
|
+
nodes: [],
|
|
687
|
+
edges: []
|
|
688
|
+
}, "root")
|
|
689
|
+
});
|
|
543
690
|
export {
|
|
544
|
-
|
|
691
|
+
Menu,
|
|
545
692
|
MenuBuilder,
|
|
546
|
-
MenuProvider,
|
|
547
693
|
MenuSeparatorType,
|
|
548
|
-
ToolbarMenu,
|
|
549
694
|
createGapSeparator,
|
|
550
695
|
createLineSeparator,
|
|
551
696
|
createMenuAction,
|
|
552
697
|
createMenuItemGroup,
|
|
553
|
-
createMenuScope,
|
|
554
698
|
isMenuGroup,
|
|
555
699
|
isSeparator,
|
|
556
700
|
menuContextDefaults,
|
|
557
|
-
rxFromSignal,
|
|
558
701
|
useMenu,
|
|
559
702
|
useMenuActions,
|
|
560
|
-
useMenuItems
|
|
703
|
+
useMenuItems,
|
|
704
|
+
useMenuScoped
|
|
561
705
|
};
|
|
562
706
|
//# sourceMappingURL=index.mjs.map
|