@dxos/react-ui-menu 0.8.4-main.f5c0578 → 0.8.4-main.fcfe5033a5
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 +556 -391
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +556 -391
- 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 +28 -3
- 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 +22 -0
- package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -0
- 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 -29
- package/src/builder.test.ts +224 -0
- package/src/builder.ts +76 -26
- 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 +82 -0
- package/src/components/ToolbarMenu.tsx +153 -95
- package/src/components/index.ts +1 -3
- package/src/hooks/useMenuActions.ts +30 -53
- 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/dist/types/src/components/Menus.stories.d.ts +0 -25
- package/dist/types/src/components/Menus.stories.d.ts.map +0 -1
- package/src/components/MenuContext.tsx +0 -50
- package/src/components/Menus.stories.tsx +0 -69
|
@@ -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,290 +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
|
-
} finally {
|
|
296
|
-
_effect.f();
|
|
297
|
-
}
|
|
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
|
+
})));
|
|
298
269
|
};
|
|
299
|
-
var ToggleGroupItem = ({ group, action
|
|
300
|
-
|
|
301
|
-
|
|
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
|
-
}
|
|
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
|
+
}));
|
|
337
308
|
};
|
|
338
|
-
var ToggleGroupToolbarItem = ({ group, items:
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
action
|
|
357
|
-
}))
|
|
358
|
-
)
|
|
359
|
-
);
|
|
360
|
-
} finally {
|
|
361
|
-
_effect.f();
|
|
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);
|
|
362
327
|
}
|
|
363
328
|
};
|
|
364
|
-
var ToolbarMenu = ({ __menuScope,
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
key: i,
|
|
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, {
|
|
384
348
|
variant: item.properties.variant
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
if (isMenuGroup(item)) {
|
|
352
|
+
if (item.properties.variant === "dropdownMenu") {
|
|
353
|
+
return /* @__PURE__ */ React3.createElement(DropdownMenuToolbarItem, {
|
|
354
|
+
__menuScope,
|
|
389
355
|
group: item
|
|
390
|
-
})
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
key: item.id,
|
|
356
|
+
});
|
|
357
|
+
} else {
|
|
358
|
+
return /* @__PURE__ */ React3.createElement(ToggleGroupToolbarItem, {
|
|
359
|
+
__menuScope,
|
|
395
360
|
group: item
|
|
396
|
-
})
|
|
397
|
-
|
|
398
|
-
// TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
|
|
399
|
-
/* @__PURE__ */ React4.createElement(ActionToolbarItem, {
|
|
400
|
-
key: item.id,
|
|
401
|
-
action: item
|
|
402
|
-
})
|
|
403
|
-
))));
|
|
404
|
-
} finally {
|
|
405
|
-
_effect.f();
|
|
361
|
+
});
|
|
362
|
+
}
|
|
406
363
|
}
|
|
364
|
+
return /* @__PURE__ */ React3.createElement(ActionToolbarItem, {
|
|
365
|
+
__menuScope,
|
|
366
|
+
action: item
|
|
367
|
+
});
|
|
407
368
|
};
|
|
408
369
|
|
|
409
|
-
// src/
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
var
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
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: () => {
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
var [MenuContextProvider, useMenuScoped] = createMenuContext(MENU_NAME, menuContextDefaults);
|
|
387
|
+
var useMenuScope = createMenuScope();
|
|
388
|
+
var MenuDropdownContext = /* @__PURE__ */ createContext({
|
|
389
|
+
closeMenu: () => {
|
|
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);
|
|
438
|
+
};
|
|
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)
|
|
458
|
+
});
|
|
420
459
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
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;
|
|
466
|
+
}
|
|
467
|
+
return [
|
|
468
|
+
...baseItems,
|
|
469
|
+
...additiveItems
|
|
470
|
+
];
|
|
471
|
+
};
|
|
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
|
|
426
503
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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
|
|
430
522
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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;
|
|
434
538
|
}
|
|
435
|
-
|
|
436
|
-
|
|
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
|
+
});
|
|
551
|
+
}
|
|
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)));
|
|
437
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";
|
|
438
576
|
var useMenuActions = (props) => {
|
|
439
|
-
const registry =
|
|
440
|
-
const menuGraphProps =
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
graph.addNodes(menuGraphProps.nodes);
|
|
448
|
-
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;
|
|
449
585
|
}, [
|
|
586
|
+
registry,
|
|
450
587
|
menuGraphProps
|
|
451
588
|
]);
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
return items;
|
|
589
|
+
const items = useCallback4((group) => {
|
|
590
|
+
return graph.connections(group?.id || Node3.RootId, "child");
|
|
455
591
|
}, [
|
|
456
592
|
graph
|
|
457
593
|
]);
|
|
458
594
|
return {
|
|
459
|
-
|
|
595
|
+
items
|
|
460
596
|
};
|
|
461
597
|
};
|
|
462
598
|
|
|
463
599
|
// src/builder.ts
|
|
464
600
|
import { invariant } from "@dxos/invariant";
|
|
465
|
-
var
|
|
466
|
-
var MenuBuilder = Object.freeze({
|
|
467
|
-
make: () => new MenuBuilderImpl({
|
|
468
|
-
nodes: [],
|
|
469
|
-
edges: []
|
|
470
|
-
}, "root")
|
|
471
|
-
});
|
|
601
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-menu/src/builder.ts";
|
|
472
602
|
var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
473
603
|
_data;
|
|
474
604
|
_rootId;
|
|
605
|
+
_separatorCount = 0;
|
|
475
606
|
constructor(_data, _rootId) {
|
|
476
607
|
this._data = _data;
|
|
477
608
|
this._rootId = _rootId;
|
|
478
609
|
}
|
|
479
|
-
action(id, invoke, properties) {
|
|
480
|
-
this._data.nodes.push(createMenuAction(id, invoke, properties));
|
|
481
|
-
this._data.edges.push({
|
|
482
|
-
source: this._rootId,
|
|
483
|
-
target: id
|
|
484
|
-
});
|
|
485
|
-
return this;
|
|
486
|
-
}
|
|
487
610
|
root(props) {
|
|
488
611
|
invariant(this._rootId === "root", "Root group can only be at the top level", {
|
|
489
|
-
F:
|
|
490
|
-
L:
|
|
612
|
+
F: __dxlog_file2,
|
|
613
|
+
L: 61,
|
|
491
614
|
S: this,
|
|
492
615
|
A: [
|
|
493
616
|
"this._rootId === 'root'",
|
|
@@ -495,8 +618,8 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
495
618
|
]
|
|
496
619
|
});
|
|
497
620
|
invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", {
|
|
498
|
-
F:
|
|
499
|
-
L:
|
|
621
|
+
F: __dxlog_file2,
|
|
622
|
+
L: 62,
|
|
500
623
|
S: this,
|
|
501
624
|
A: [
|
|
502
625
|
"this._data.nodes.find((node) => node.id === 'root') === undefined",
|
|
@@ -506,36 +629,78 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
506
629
|
this._data.nodes.push(createMenuItemGroup("root", props));
|
|
507
630
|
return this;
|
|
508
631
|
}
|
|
509
|
-
|
|
510
|
-
this._data
|
|
632
|
+
build() {
|
|
633
|
+
return this._data;
|
|
634
|
+
}
|
|
635
|
+
action(id, props, invoke) {
|
|
636
|
+
this._data.nodes.push(createMenuAction(id, invoke, props));
|
|
637
|
+
this._data.edges.push({
|
|
638
|
+
source: this._rootId,
|
|
639
|
+
target: id,
|
|
640
|
+
relation: "child"
|
|
641
|
+
});
|
|
642
|
+
return this;
|
|
643
|
+
}
|
|
644
|
+
group(id, props, cb) {
|
|
645
|
+
this._data.nodes.push(createMenuItemGroup(id, props));
|
|
511
646
|
this._data.edges.push({
|
|
512
647
|
source: this._rootId,
|
|
513
|
-
target: id
|
|
648
|
+
target: id,
|
|
649
|
+
relation: "child"
|
|
514
650
|
});
|
|
515
651
|
cb(new _MenuBuilderImpl(this._data, id));
|
|
516
652
|
return this;
|
|
517
653
|
}
|
|
518
|
-
|
|
519
|
-
|
|
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;
|
|
665
|
+
}
|
|
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;
|
|
520
682
|
}
|
|
521
683
|
};
|
|
684
|
+
var MenuBuilder = Object.freeze({
|
|
685
|
+
make: () => new MenuBuilderImpl({
|
|
686
|
+
nodes: [],
|
|
687
|
+
edges: []
|
|
688
|
+
}, "root")
|
|
689
|
+
});
|
|
522
690
|
export {
|
|
523
|
-
|
|
691
|
+
Menu,
|
|
524
692
|
MenuBuilder,
|
|
525
|
-
MenuProvider,
|
|
526
693
|
MenuSeparatorType,
|
|
527
|
-
ToolbarMenu,
|
|
528
694
|
createGapSeparator,
|
|
529
695
|
createLineSeparator,
|
|
530
696
|
createMenuAction,
|
|
531
697
|
createMenuItemGroup,
|
|
532
|
-
createMenuScope,
|
|
533
698
|
isMenuGroup,
|
|
534
699
|
isSeparator,
|
|
535
700
|
menuContextDefaults,
|
|
536
|
-
rxFromSignal,
|
|
537
701
|
useMenu,
|
|
538
702
|
useMenuActions,
|
|
539
|
-
useMenuItems
|
|
703
|
+
useMenuItems,
|
|
704
|
+
useMenuScoped
|
|
540
705
|
};
|
|
541
706
|
//# sourceMappingURL=index.mjs.map
|