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