@dxos/react-ui-menu 0.8.4-main.1da679c → 0.8.4-main.21d9917
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 +298 -330
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +298 -330
- 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 +1 -1
- package/dist/types/src/builder.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/types/src/components/MenuContext.d.ts +3 -1
- package/dist/types/src/components/MenuContext.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.d.ts +3 -2
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts +2 -3
- package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useMenuActions.d.ts +6 -5
- package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +13 -11
- 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 +11 -24
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +12 -5
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -29
- package/src/builder.ts +1 -1
- package/src/components/ActionLabel.tsx +4 -4
- package/src/components/DropdownMenu.tsx +10 -3
- package/src/components/MenuContext.tsx +15 -3
- package/src/components/ToolbarMenu.stories.tsx +18 -12
- package/src/components/ToolbarMenu.tsx +36 -12
- package/src/hooks/useMenuActions.ts +32 -19
- package/src/index.ts +0 -2
- package/src/testing/generator.ts +63 -58
- package/src/translations.ts +1 -1
- package/src/types.ts +12 -26
- package/src/util.ts +32 -14
|
@@ -1,48 +1,36 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
|
|
3
|
-
// src/index.ts
|
|
4
|
-
import { rxFromSignal } from "@dxos/app-graph";
|
|
5
|
-
|
|
6
3
|
// src/components/DropdownMenu.tsx
|
|
7
|
-
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
8
4
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
9
5
|
import React3, { useCallback } from "react";
|
|
10
6
|
import { Icon, DropdownMenu as NaturalDropdownMenu } from "@dxos/react-ui";
|
|
11
7
|
|
|
12
|
-
// src/components/ActionLabel.tsx
|
|
13
|
-
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
14
|
-
import React from "react";
|
|
15
|
-
import { keySymbols } from "@dxos/keyboard";
|
|
16
|
-
import { toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
17
|
-
import { descriptionText, mx } from "@dxos/react-ui-theme";
|
|
18
|
-
|
|
19
|
-
// src/translations.ts
|
|
20
|
-
var translationKey = "react-ui-menu";
|
|
21
|
-
var translations = [
|
|
22
|
-
{
|
|
23
|
-
"en-US": {
|
|
24
|
-
[translationKey]: {}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
];
|
|
28
|
-
|
|
29
8
|
// src/util.ts
|
|
30
|
-
import
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import { Node } from "@dxos/app-graph";
|
|
11
|
+
import { runAndForwardErrors } from "@dxos/effect";
|
|
31
12
|
import { getHostPlatform } from "@dxos/util";
|
|
13
|
+
var executeMenuAction = async (action, params = {}) => {
|
|
14
|
+
let effect = action.data(params);
|
|
15
|
+
if (action._actionContext) {
|
|
16
|
+
effect = effect.pipe(Effect.provide(action._actionContext));
|
|
17
|
+
}
|
|
18
|
+
await runAndForwardErrors(effect);
|
|
19
|
+
};
|
|
32
20
|
var getShortcut = (action) => {
|
|
33
21
|
return typeof action.properties?.keyBinding === "string" ? action.properties.keyBinding : action.properties?.keyBinding?.[getHostPlatform()];
|
|
34
22
|
};
|
|
35
23
|
var createMenuAction = (id, invoke, properties) => ({
|
|
36
24
|
id,
|
|
37
|
-
type:
|
|
25
|
+
type: Node.ActionType,
|
|
38
26
|
properties,
|
|
39
|
-
data: invoke
|
|
27
|
+
data: () => Effect.sync(invoke)
|
|
40
28
|
});
|
|
41
29
|
var createMenuItemGroup = (id, properties) => ({
|
|
42
30
|
id,
|
|
43
|
-
type:
|
|
31
|
+
type: Node.ActionGroupType,
|
|
44
32
|
properties,
|
|
45
|
-
data: actionGroupSymbol
|
|
33
|
+
data: Node.actionGroupSymbol
|
|
46
34
|
});
|
|
47
35
|
var createGapSeparator = (id = "gap", source = "root") => ({
|
|
48
36
|
nodes: [
|
|
@@ -82,19 +70,30 @@ var createLineSeparator = (id = "line", source = "root") => ({
|
|
|
82
70
|
});
|
|
83
71
|
|
|
84
72
|
// src/components/ActionLabel.tsx
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
73
|
+
import React from "react";
|
|
74
|
+
import { keySymbols } from "@dxos/keyboard";
|
|
75
|
+
import { toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
76
|
+
import { descriptionText, mx } from "@dxos/ui-theme";
|
|
77
|
+
|
|
78
|
+
// src/translations.ts
|
|
79
|
+
var translationKey = "@dxos/react-ui-menu";
|
|
80
|
+
var translations = [
|
|
81
|
+
{
|
|
82
|
+
"en-US": {
|
|
83
|
+
[translationKey]: {}
|
|
84
|
+
}
|
|
97
85
|
}
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
// src/components/ActionLabel.tsx
|
|
89
|
+
var ActionLabel = ({ action }) => {
|
|
90
|
+
const { t } = useTranslation(translationKey);
|
|
91
|
+
const shortcut = getShortcut(action);
|
|
92
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", {
|
|
93
|
+
className: "grow truncate"
|
|
94
|
+
}, toLocalizedString(action.properties.label, t)), shortcut && /* @__PURE__ */ React.createElement("span", {
|
|
95
|
+
className: mx("shrink-0", descriptionText)
|
|
96
|
+
}, keySymbols(shortcut).join("")));
|
|
98
97
|
};
|
|
99
98
|
var actionLabel = (action, t) => {
|
|
100
99
|
const shortcut = getShortcut(action);
|
|
@@ -102,30 +101,26 @@ var actionLabel = (action, t) => {
|
|
|
102
101
|
};
|
|
103
102
|
|
|
104
103
|
// src/components/MenuContext.tsx
|
|
105
|
-
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
106
104
|
import { createContextScope } from "@radix-ui/react-context";
|
|
107
105
|
import React2, { useMemo } from "react";
|
|
108
|
-
var MENU_NAME = "
|
|
106
|
+
var MENU_NAME = "Menu";
|
|
109
107
|
var [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);
|
|
110
108
|
var [MenuContextProvider, useMenu] = createMenuContext(MENU_NAME);
|
|
111
109
|
var menuContextDefaults = {
|
|
112
110
|
iconSize: 5,
|
|
113
|
-
useGroupItems: () => null
|
|
111
|
+
useGroupItems: () => null,
|
|
112
|
+
onAction: void 0
|
|
114
113
|
};
|
|
115
114
|
var useMenuScope = createMenuScope();
|
|
116
|
-
var MenuProvider = ({ children, useGroupItems = menuContextDefaults.useGroupItems, iconSize = menuContextDefaults.iconSize, attendableId }) => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}, children);
|
|
126
|
-
} finally {
|
|
127
|
-
_effect.f();
|
|
128
|
-
}
|
|
115
|
+
var MenuProvider = ({ children, useGroupItems = menuContextDefaults.useGroupItems, iconSize = menuContextDefaults.iconSize, attendableId, onAction }) => {
|
|
116
|
+
const { scope } = useMenuScope(void 0);
|
|
117
|
+
return /* @__PURE__ */ React2.createElement(MenuContextProvider, {
|
|
118
|
+
useGroupItems,
|
|
119
|
+
iconSize,
|
|
120
|
+
attendableId,
|
|
121
|
+
onAction,
|
|
122
|
+
scope
|
|
123
|
+
}, children);
|
|
129
124
|
};
|
|
130
125
|
var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __menuScope) => {
|
|
131
126
|
const { useGroupItems } = useMenu(consumerName, __menuScope);
|
|
@@ -138,66 +133,65 @@ var useMenuItems = (group, propsItems, consumerName = "useMenuItemConsumer", __m
|
|
|
138
133
|
|
|
139
134
|
// src/components/DropdownMenu.tsx
|
|
140
135
|
var DropdownMenuItem = ({ item, onClick, __menuScope }) => {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
action
|
|
161
|
-
}));
|
|
162
|
-
} finally {
|
|
163
|
-
_effect.f();
|
|
164
|
-
}
|
|
136
|
+
const action = item;
|
|
137
|
+
const handleClick = useCallback((event) => onClick(action, event), [
|
|
138
|
+
action,
|
|
139
|
+
onClick
|
|
140
|
+
]);
|
|
141
|
+
const { iconSize } = useMenu("DropdownMenuItem", __menuScope);
|
|
142
|
+
return /* @__PURE__ */ React3.createElement(NaturalDropdownMenu.Item, {
|
|
143
|
+
onClick: handleClick,
|
|
144
|
+
classNames: "gap-2",
|
|
145
|
+
disabled: action.properties?.disabled,
|
|
146
|
+
...action.properties?.testId && {
|
|
147
|
+
"data-testid": action.properties.testId
|
|
148
|
+
}
|
|
149
|
+
}, action.properties?.icon && /* @__PURE__ */ React3.createElement(Icon, {
|
|
150
|
+
icon: action.properties.icon,
|
|
151
|
+
size: iconSize
|
|
152
|
+
}), /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
153
|
+
action
|
|
154
|
+
}));
|
|
165
155
|
};
|
|
166
156
|
var DropdownMenuRoot = ({ items: propsItems, group, open, defaultOpen, onOpenChange, caller, children, __menuScope, ...naturalProps }) => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
157
|
+
const [optionsMenuOpen, setOptionsMenuOpen] = useControllableState({
|
|
158
|
+
prop: open,
|
|
159
|
+
defaultProp: defaultOpen,
|
|
160
|
+
onChange: onOpenChange
|
|
161
|
+
});
|
|
162
|
+
const { onAction } = useMenu("DropdownMenuRoot", __menuScope);
|
|
163
|
+
const handleActionClick = useCallback((action, event) => {
|
|
164
|
+
if (action.properties?.disabled) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
event.stopPropagation();
|
|
168
|
+
setOptionsMenuOpen(false);
|
|
169
|
+
if (onAction) {
|
|
170
|
+
onAction(action, {
|
|
181
171
|
parent: group,
|
|
182
172
|
caller
|
|
183
173
|
});
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
174
|
+
} else {
|
|
175
|
+
void executeMenuAction(action, {
|
|
176
|
+
parent: group,
|
|
177
|
+
caller
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}, [
|
|
181
|
+
group,
|
|
182
|
+
caller,
|
|
183
|
+
onAction
|
|
184
|
+
]);
|
|
185
|
+
const items = useMenuItems(group, propsItems);
|
|
186
|
+
return /* @__PURE__ */ React3.createElement(NaturalDropdownMenu.Root, {
|
|
187
|
+
open: optionsMenuOpen,
|
|
188
|
+
onOpenChange: setOptionsMenuOpen,
|
|
189
|
+
...naturalProps
|
|
190
|
+
}, children, /* @__PURE__ */ React3.createElement(NaturalDropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(NaturalDropdownMenu.Content, null, /* @__PURE__ */ React3.createElement(NaturalDropdownMenu.Viewport, null, items?.map((item) => /* @__PURE__ */ React3.createElement(DropdownMenuItem, {
|
|
191
|
+
key: item.id,
|
|
192
|
+
item,
|
|
193
|
+
onClick: handleActionClick
|
|
194
|
+
}))), /* @__PURE__ */ React3.createElement(NaturalDropdownMenu.Arrow, null))));
|
|
201
195
|
};
|
|
202
196
|
var DropdownMenu = {
|
|
203
197
|
Root: DropdownMenuRoot,
|
|
@@ -206,220 +200,205 @@ var DropdownMenu = {
|
|
|
206
200
|
};
|
|
207
201
|
|
|
208
202
|
// src/components/ToolbarMenu.tsx
|
|
209
|
-
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
210
203
|
import React4, { Fragment, useCallback as useCallback2 } from "react";
|
|
211
204
|
import { Icon as Icon2, Toolbar as NaturalToolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
212
205
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
213
|
-
import { mx as mx2, textBlockWidth, toolbarLayout } from "@dxos/
|
|
206
|
+
import { mx as mx2, textBlockWidth, toolbarInactive, toolbarLayout } from "@dxos/ui-theme";
|
|
214
207
|
|
|
215
208
|
// src/types.ts
|
|
216
|
-
import {
|
|
209
|
+
import { Node as Node2 } from "@dxos/app-graph";
|
|
217
210
|
var MenuSeparatorType = "@dxos/react-ui-toolbar/separator";
|
|
218
211
|
var isSeparator = (node) => node.type === MenuSeparatorType;
|
|
219
|
-
var isMenuGroup = (node) => node.type ===
|
|
212
|
+
var isMenuGroup = (node) => node.type === Node2.ActionGroupType;
|
|
220
213
|
|
|
221
214
|
// src/components/ToolbarMenu.tsx
|
|
222
215
|
var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
const { iconSize, onAction } = useMenu("ActionToolbarItem", __menuScope);
|
|
217
|
+
const { t } = useTranslation2(translationKey);
|
|
218
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
219
|
+
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
220
|
+
const rootProps = icon ? {
|
|
221
|
+
icon,
|
|
222
|
+
size: iconSize,
|
|
223
|
+
iconOnly,
|
|
224
|
+
label: actionLabel(action, t)
|
|
225
|
+
} : {
|
|
226
|
+
children: /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
228
227
|
action
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
});
|
|
253
|
-
} finally {
|
|
254
|
-
_effect.f();
|
|
255
|
-
}
|
|
228
|
+
})
|
|
229
|
+
};
|
|
230
|
+
const handleClick = useCallback2(() => {
|
|
231
|
+
if (onAction) {
|
|
232
|
+
onAction(action, {});
|
|
233
|
+
} else {
|
|
234
|
+
void executeMenuAction(action);
|
|
235
|
+
}
|
|
236
|
+
}, [
|
|
237
|
+
action,
|
|
238
|
+
onAction
|
|
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
|
+
});
|
|
256
251
|
};
|
|
257
252
|
var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
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
|
-
})));
|
|
297
|
-
} finally {
|
|
298
|
-
_effect.f();
|
|
299
|
-
}
|
|
253
|
+
const { iconOnly, disabled, testId } = group.properties;
|
|
254
|
+
const { t } = useTranslation2(translationKey);
|
|
255
|
+
const { iconSize } = useMenu("DropdownMenuToolbarItem", __menuScope);
|
|
256
|
+
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
257
|
+
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
258
|
+
const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
|
|
259
|
+
activeItem?.properties.icon || group.properties.icon;
|
|
260
|
+
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
261
|
+
const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
|
|
262
|
+
const rootProps = icon ? {
|
|
263
|
+
icon,
|
|
264
|
+
size: iconSize,
|
|
265
|
+
iconOnly,
|
|
266
|
+
label: actionLabel(labelAction, t),
|
|
267
|
+
caretDown: true
|
|
268
|
+
} : {
|
|
269
|
+
children: /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
270
|
+
action: labelAction
|
|
271
|
+
}), /* @__PURE__ */ React4.createElement(Icon2, {
|
|
272
|
+
size: 3,
|
|
273
|
+
icon: "ph--caret-down--bold",
|
|
274
|
+
classNames: "mis-1"
|
|
275
|
+
}))
|
|
276
|
+
};
|
|
277
|
+
return /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
|
|
278
|
+
group,
|
|
279
|
+
items
|
|
280
|
+
}, /* @__PURE__ */ React4.createElement(DropdownMenu.Trigger, {
|
|
281
|
+
asChild: true
|
|
282
|
+
}, /* @__PURE__ */ React4.createElement(Root, {
|
|
283
|
+
variant: "ghost",
|
|
284
|
+
disabled,
|
|
285
|
+
...rootProps,
|
|
286
|
+
...testId && {
|
|
287
|
+
"data-testid": testId
|
|
288
|
+
}
|
|
289
|
+
})));
|
|
300
290
|
};
|
|
301
291
|
var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
292
|
+
const { iconSize, onAction } = useMenu("ToggleGroupItem", __menuScope);
|
|
293
|
+
const { t } = useTranslation2(translationKey);
|
|
294
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
295
|
+
const handleClick = useCallback2(() => {
|
|
296
|
+
if (onAction) {
|
|
297
|
+
onAction(action, {
|
|
298
|
+
parent: group
|
|
299
|
+
});
|
|
300
|
+
} else {
|
|
301
|
+
void executeMenuAction(action, {
|
|
302
|
+
parent: group
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}, [
|
|
306
|
+
action,
|
|
307
|
+
group,
|
|
308
|
+
onAction
|
|
309
|
+
]);
|
|
310
|
+
const Root = icon ? NaturalToolbar.ToggleGroupIconItem : NaturalToolbar.ToggleGroupItem;
|
|
311
|
+
const rootProps = icon ? {
|
|
312
|
+
icon,
|
|
313
|
+
size: iconSize,
|
|
314
|
+
iconOnly,
|
|
315
|
+
label: actionLabel(action, t)
|
|
316
|
+
} : {
|
|
317
|
+
children: /* @__PURE__ */ React4.createElement(ActionLabel, {
|
|
318
|
+
action
|
|
319
|
+
})
|
|
320
|
+
};
|
|
321
|
+
return hidden ? null : /* @__PURE__ */ React4.createElement(Root, {
|
|
322
|
+
key: action.id,
|
|
323
|
+
value: action.id,
|
|
324
|
+
disabled,
|
|
325
|
+
onClick: handleClick,
|
|
326
|
+
variant: "ghost",
|
|
327
|
+
...testId && {
|
|
328
|
+
"data-testid": testId
|
|
329
|
+
},
|
|
330
|
+
...rootProps,
|
|
331
|
+
classNames
|
|
332
|
+
});
|
|
339
333
|
};
|
|
340
334
|
var ToggleGroupToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
)
|
|
361
|
-
);
|
|
362
|
-
} finally {
|
|
363
|
-
_effect.f();
|
|
364
|
-
}
|
|
335
|
+
const items = useMenuItems(group, propsItems, "ToggleGroupToolbarItem", __menuScope);
|
|
336
|
+
const { selectCardinality, value } = group.properties;
|
|
337
|
+
return (
|
|
338
|
+
// TODO(thure): Fix.
|
|
339
|
+
// @ts-ignore
|
|
340
|
+
/* @__PURE__ */ React4.createElement(
|
|
341
|
+
NaturalToolbar.ToggleGroup,
|
|
342
|
+
{
|
|
343
|
+
type: selectCardinality,
|
|
344
|
+
value
|
|
345
|
+
},
|
|
346
|
+
// TODO(thure): Handle other menu item types.
|
|
347
|
+
items.map((action) => /* @__PURE__ */ React4.createElement(ToggleGroupItem, {
|
|
348
|
+
key: action.id,
|
|
349
|
+
group,
|
|
350
|
+
action
|
|
351
|
+
}))
|
|
352
|
+
)
|
|
353
|
+
);
|
|
365
354
|
};
|
|
366
|
-
var ToolbarMenu = ({ __menuScope, classNames, textBlockWidth:
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
item
|
|
387
|
-
}))));
|
|
388
|
-
} finally {
|
|
389
|
-
_effect.f();
|
|
390
|
-
}
|
|
355
|
+
var ToolbarMenu = ({ __menuScope, classNames, textBlockWidth: textBlockWidthProp, ...props }) => {
|
|
356
|
+
const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
|
|
357
|
+
const { attendableId } = useMenu("ToolbarMenu", __menuScope);
|
|
358
|
+
const { hasAttention } = useAttention(attendableId);
|
|
359
|
+
const InnerRoot = textBlockWidthProp ? "div" : Fragment;
|
|
360
|
+
const innerRootProps = textBlockWidthProp ? {
|
|
361
|
+
role: "none",
|
|
362
|
+
className: mx2(textBlockWidth, toolbarLayout, "bs-full")
|
|
363
|
+
} : {};
|
|
364
|
+
return /* @__PURE__ */ React4.createElement(NaturalToolbar.Root, {
|
|
365
|
+
...props,
|
|
366
|
+
classNames: [
|
|
367
|
+
attendableId && !hasAttention && toolbarInactive,
|
|
368
|
+
classNames
|
|
369
|
+
],
|
|
370
|
+
layoutManaged: textBlockWidthProp
|
|
371
|
+
}, /* @__PURE__ */ React4.createElement(InnerRoot, innerRootProps, items?.map((item, i) => /* @__PURE__ */ React4.createElement(ToolbarMenuItem, {
|
|
372
|
+
key: item.id ?? i,
|
|
373
|
+
item
|
|
374
|
+
}))));
|
|
391
375
|
};
|
|
392
376
|
var ToolbarMenuItem = ({ item }) => {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
377
|
+
if (isSeparator(item)) {
|
|
378
|
+
return /* @__PURE__ */ React4.createElement(NaturalToolbar.Separator, {
|
|
379
|
+
variant: item.properties.variant
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
if (isMenuGroup(item)) {
|
|
383
|
+
if (item.properties.variant === "dropdownMenu") {
|
|
384
|
+
return /* @__PURE__ */ React4.createElement(DropdownMenuToolbarItem, {
|
|
385
|
+
group: item
|
|
386
|
+
});
|
|
387
|
+
} else {
|
|
388
|
+
return /* @__PURE__ */ React4.createElement(ToggleGroupToolbarItem, {
|
|
389
|
+
group: item
|
|
398
390
|
});
|
|
399
391
|
}
|
|
400
|
-
if (isMenuGroup(item)) {
|
|
401
|
-
if (item.properties.variant === "dropdownMenu") {
|
|
402
|
-
return /* @__PURE__ */ React4.createElement(DropdownMenuToolbarItem, {
|
|
403
|
-
group: item
|
|
404
|
-
});
|
|
405
|
-
} else {
|
|
406
|
-
return /* @__PURE__ */ React4.createElement(ToggleGroupToolbarItem, {
|
|
407
|
-
group: item
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return /* @__PURE__ */ React4.createElement(ActionToolbarItem, {
|
|
412
|
-
action: item
|
|
413
|
-
});
|
|
414
|
-
} finally {
|
|
415
|
-
_effect.f();
|
|
416
392
|
}
|
|
393
|
+
return /* @__PURE__ */ React4.createElement(ActionToolbarItem, {
|
|
394
|
+
action: item
|
|
395
|
+
});
|
|
417
396
|
};
|
|
418
397
|
|
|
419
398
|
// src/hooks/useMenuActions.ts
|
|
420
|
-
import { RegistryContext,
|
|
421
|
-
import { useCallback as useCallback3, useContext,
|
|
422
|
-
import { Graph,
|
|
399
|
+
import { RegistryContext, useAtomValue } from "@effect-atom/atom-react";
|
|
400
|
+
import { useCallback as useCallback3, useContext, useRef } from "react";
|
|
401
|
+
import { Graph, Node as Node3 } from "@dxos/app-graph";
|
|
423
402
|
var edgesArrayToRecord = (edges) => {
|
|
424
403
|
return Object.fromEntries(Object.entries(edges.reduce((acc, { source, target }) => {
|
|
425
404
|
if (!acc[source]) {
|
|
@@ -447,20 +426,23 @@ var edgesArrayToRecord = (edges) => {
|
|
|
447
426
|
};
|
|
448
427
|
var useMenuActions = (props) => {
|
|
449
428
|
const registry = useContext(RegistryContext);
|
|
450
|
-
const menuGraphProps =
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
429
|
+
const menuGraphProps = useAtomValue(props);
|
|
430
|
+
const graphRef = useRef(null);
|
|
431
|
+
if (!graphRef.current) {
|
|
432
|
+
graphRef.current = Graph.make({
|
|
433
|
+
registry,
|
|
434
|
+
nodes: menuGraphProps.nodes,
|
|
435
|
+
edges: edgesArrayToRecord(menuGraphProps.edges)
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
const graph = graphRef.current;
|
|
439
|
+
const prevPropsRef = useRef(menuGraphProps);
|
|
440
|
+
if (prevPropsRef.current !== menuGraphProps) {
|
|
441
|
+
prevPropsRef.current = menuGraphProps;
|
|
442
|
+
graph.pipe(Graph.addNodes(menuGraphProps.nodes), Graph.addEdges(menuGraphProps.edges));
|
|
443
|
+
}
|
|
462
444
|
const useGroupItems = useCallback3((sourceNode) => {
|
|
463
|
-
const items =
|
|
445
|
+
const items = useAtomValue(graph.connections(sourceNode?.id || Node3.RootId));
|
|
464
446
|
return items;
|
|
465
447
|
}, [
|
|
466
448
|
graph
|
|
@@ -472,19 +454,6 @@ var useMenuActions = (props) => {
|
|
|
472
454
|
|
|
473
455
|
// src/builder.ts
|
|
474
456
|
import { invariant } from "@dxos/invariant";
|
|
475
|
-
function _define_property(obj, key, value) {
|
|
476
|
-
if (key in obj) {
|
|
477
|
-
Object.defineProperty(obj, key, {
|
|
478
|
-
value,
|
|
479
|
-
enumerable: true,
|
|
480
|
-
configurable: true,
|
|
481
|
-
writable: true
|
|
482
|
-
});
|
|
483
|
-
} else {
|
|
484
|
-
obj[key] = value;
|
|
485
|
-
}
|
|
486
|
-
return obj;
|
|
487
|
-
}
|
|
488
457
|
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-menu/src/builder.ts";
|
|
489
458
|
var MenuBuilder = Object.freeze({
|
|
490
459
|
make: () => new MenuBuilderImpl({
|
|
@@ -493,6 +462,12 @@ var MenuBuilder = Object.freeze({
|
|
|
493
462
|
}, "root")
|
|
494
463
|
});
|
|
495
464
|
var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
465
|
+
_data;
|
|
466
|
+
_rootId;
|
|
467
|
+
constructor(_data, _rootId) {
|
|
468
|
+
this._data = _data;
|
|
469
|
+
this._rootId = _rootId;
|
|
470
|
+
}
|
|
496
471
|
root(props) {
|
|
497
472
|
invariant(this._rootId === "root", "Root group can only be at the top level", {
|
|
498
473
|
F: __dxlog_file,
|
|
@@ -535,12 +510,6 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
535
510
|
build() {
|
|
536
511
|
return this._data;
|
|
537
512
|
}
|
|
538
|
-
constructor(_data, _rootId) {
|
|
539
|
-
_define_property(this, "_data", void 0);
|
|
540
|
-
_define_property(this, "_rootId", void 0);
|
|
541
|
-
this._data = _data;
|
|
542
|
-
this._rootId = _rootId;
|
|
543
|
-
}
|
|
544
513
|
};
|
|
545
514
|
export {
|
|
546
515
|
DropdownMenu,
|
|
@@ -556,7 +525,6 @@ export {
|
|
|
556
525
|
isMenuGroup,
|
|
557
526
|
isSeparator,
|
|
558
527
|
menuContextDefaults,
|
|
559
|
-
rxFromSignal,
|
|
560
528
|
useMenu,
|
|
561
529
|
useMenuActions,
|
|
562
530
|
useMenuItems
|