@dxos/react-ui-menu 0.8.4-main.d05673bc65 → 0.8.4-main.d9fc60f731
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/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +115 -136
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +14 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +115 -136
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/translations.mjs +16 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/builder.d.ts +23 -4
- 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.map +1 -1
- package/dist/types/src/components/DropdownMenu.d.ts +3 -1
- package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu.d.ts +8 -4
- package/dist/types/src/components/Menu.d.ts.map +1 -1
- package/dist/types/src/components/{MenuItems.stories.d.ts → Menu.stories.d.ts} +1 -1
- package/dist/types/src/components/Menu.stories.d.ts.map +1 -0
- package/dist/types/src/components/ToolbarMenu.d.ts +4 -4
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts +15 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useMenuActions.d.ts +9 -1
- package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +8 -4
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +2 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +3 -3
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -24
- package/src/builder.test.ts +224 -0
- package/src/builder.ts +41 -18
- package/src/components/ActionLabel.tsx +2 -1
- package/src/components/DropdownMenu.tsx +0 -1
- package/src/components/{MenuItems.stories.tsx → Menu.stories.tsx} +2 -1
- package/src/components/Menu.test.tsx +0 -1
- package/src/components/Menu.tsx +9 -10
- package/src/components/ToolbarMenu.stories.tsx +27 -12
- package/src/components/ToolbarMenu.tsx +118 -85
- package/src/hooks/useMenuActions.ts +19 -8
- package/src/index.ts +1 -1
- package/src/testing/generator.ts +15 -10
- package/src/types.ts +1 -0
- package/src/util.ts +1 -1
- package/dist/types/src/components/MenuItems.stories.d.ts.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,8 +1,105 @@
|
|
|
1
|
-
|
|
2
|
-
Copyright (c) 2024 DXOS
|
|
1
|
+
# Functional Source License, Version 1.1, ALv2 Future License
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
## Abbreviation
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
FSL-1.1-Apache-2.0
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 DXOS
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Atom, RegistryContext, useAtomValue } from "@effect-atom/atom-react";
|
|
3
3
|
import { createContextScope } from "@radix-ui/react-context";
|
|
4
4
|
import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
|
|
5
|
-
import React4, { useCallback as useCallback3, useContext, useMemo } from "react";
|
|
5
|
+
import React4, { createContext, useCallback as useCallback3, useContext, useMemo } from "react";
|
|
6
6
|
import { log } from "@dxos/log";
|
|
7
7
|
import { Icon as Icon3, DropdownMenu as NaturalDropdownMenu2 } from "@dxos/react-ui";
|
|
8
8
|
|
|
@@ -77,18 +77,7 @@ import React from "react";
|
|
|
77
77
|
import { keySymbols } from "@dxos/keyboard";
|
|
78
78
|
import { toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
79
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
|
-
}
|
|
88
|
-
}
|
|
89
|
-
];
|
|
90
|
-
|
|
91
|
-
// src/components/ActionLabel.tsx
|
|
80
|
+
import { translationKey } from "#translations";
|
|
92
81
|
var ActionLabel = ({ action }) => {
|
|
93
82
|
const { t } = useTranslation(translationKey);
|
|
94
83
|
const shortcut = getShortcut(action);
|
|
@@ -104,10 +93,11 @@ var actionLabel = (action, t) => {
|
|
|
104
93
|
};
|
|
105
94
|
|
|
106
95
|
// src/components/ToolbarMenu.tsx
|
|
107
|
-
import React3, {
|
|
96
|
+
import React3, { useCallback as useCallback2 } from "react";
|
|
108
97
|
import { Icon as Icon2, Toolbar as NaturalToolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
98
|
+
import { composable, composableProps } from "@dxos/react-ui";
|
|
109
99
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
110
|
-
import {
|
|
100
|
+
import { translationKey as translationKey2 } from "#translations";
|
|
111
101
|
|
|
112
102
|
// src/types.ts
|
|
113
103
|
import { Node as Node2 } from "@dxos/app-graph";
|
|
@@ -187,21 +177,11 @@ var DropdownMenu = {
|
|
|
187
177
|
};
|
|
188
178
|
|
|
189
179
|
// src/components/ToolbarMenu.tsx
|
|
190
|
-
var ActionToolbarItem = ({
|
|
180
|
+
var ActionToolbarItem = ({ __menuScope, action }) => {
|
|
191
181
|
const { iconSize, onAction } = useMenuScoped("ActionToolbarItem", __menuScope);
|
|
192
|
-
const { t } = useTranslation2(
|
|
193
|
-
const { icon, iconOnly = true, disabled, testId, hidden, classNames,
|
|
194
|
-
const
|
|
195
|
-
const rootProps = icon ? {
|
|
196
|
-
icon,
|
|
197
|
-
size: iconSize,
|
|
198
|
-
iconOnly,
|
|
199
|
-
label: actionLabel(action, t)
|
|
200
|
-
} : {
|
|
201
|
-
children: /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
202
|
-
action
|
|
203
|
-
})
|
|
204
|
-
};
|
|
182
|
+
const { t } = useTranslation2(translationKey2);
|
|
183
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames, iconClassNames } = action.properties;
|
|
184
|
+
const buttonVariant = action.properties.variant === "primary" ? "primary" : "ghost";
|
|
205
185
|
const handleClick = useCallback2(() => {
|
|
206
186
|
if (onAction) {
|
|
207
187
|
onAction(action, {});
|
|
@@ -212,32 +192,49 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
212
192
|
action,
|
|
213
193
|
onAction
|
|
214
194
|
]);
|
|
215
|
-
|
|
216
|
-
|
|
195
|
+
const commonProps = {
|
|
196
|
+
variant: buttonVariant,
|
|
217
197
|
disabled,
|
|
198
|
+
classNames,
|
|
218
199
|
onClick: handleClick,
|
|
219
|
-
variant: variant ?? "ghost",
|
|
220
200
|
...testId && {
|
|
221
201
|
"data-testid": testId
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
if (hidden) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
return icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.IconButton, {
|
|
208
|
+
key: action.id,
|
|
209
|
+
...commonProps,
|
|
210
|
+
icon,
|
|
211
|
+
size: iconSize,
|
|
212
|
+
iconOnly,
|
|
213
|
+
iconClassNames,
|
|
214
|
+
label: actionLabel(action, t)
|
|
215
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
216
|
+
key: action.id,
|
|
217
|
+
...commonProps
|
|
218
|
+
}, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
219
|
+
action
|
|
220
|
+
}));
|
|
226
221
|
};
|
|
227
|
-
var DropdownMenuToolbarItem = ({ group, items: propsItems
|
|
222
|
+
var DropdownMenuToolbarItem = ({ __menuScope, group, items: propsItems }) => {
|
|
228
223
|
const { iconOnly, disabled, testId } = group.properties;
|
|
229
|
-
const { t } = useTranslation2(
|
|
224
|
+
const { t } = useTranslation2(translationKey2);
|
|
230
225
|
const { iconSize } = useMenuScoped("DropdownMenuToolbarItem", __menuScope);
|
|
231
226
|
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
232
227
|
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
233
228
|
const icon = group.properties.applyActive && // TODO(thure): Handle other menu item types.
|
|
234
229
|
activeItem?.properties.icon || group.properties.icon;
|
|
230
|
+
const iconClassNames = group.properties.applyActive && activeItem?.properties.iconClassNames || group.properties.iconClassNames;
|
|
235
231
|
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
236
232
|
const labelAction = group.properties.applyActive && activeItem ? activeItem : group;
|
|
237
233
|
const rootProps = icon ? {
|
|
238
234
|
icon,
|
|
239
235
|
size: iconSize,
|
|
240
236
|
iconOnly,
|
|
237
|
+
iconClassNames,
|
|
241
238
|
label: actionLabel(labelAction, t),
|
|
242
239
|
caretDown: true
|
|
243
240
|
} : {
|
|
@@ -263,10 +260,10 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
263
260
|
}
|
|
264
261
|
})));
|
|
265
262
|
};
|
|
266
|
-
var ToggleGroupItem = ({ group, action
|
|
263
|
+
var ToggleGroupItem = ({ __menuScope, group, action }) => {
|
|
267
264
|
const { iconSize, onAction } = useMenuScoped("ToggleGroupItem", __menuScope);
|
|
268
|
-
const { t } = useTranslation2(
|
|
269
|
-
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
265
|
+
const { t } = useTranslation2(translationKey2);
|
|
266
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames, iconClassNames } = action.properties;
|
|
270
267
|
const handleClick = useCallback2(() => {
|
|
271
268
|
if (onAction) {
|
|
272
269
|
onAction(action, {
|
|
@@ -282,74 +279,64 @@ var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
|
282
279
|
group,
|
|
283
280
|
onAction
|
|
284
281
|
]);
|
|
285
|
-
const
|
|
286
|
-
const rootProps = icon ? {
|
|
287
|
-
icon,
|
|
288
|
-
size: iconSize,
|
|
289
|
-
iconOnly,
|
|
290
|
-
label: actionLabel(action, t)
|
|
291
|
-
} : {
|
|
292
|
-
children: /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
293
|
-
action
|
|
294
|
-
})
|
|
295
|
-
};
|
|
296
|
-
return hidden ? null : /* @__PURE__ */ React3.createElement(Root, {
|
|
297
|
-
key: action.id,
|
|
282
|
+
const commonProps = {
|
|
298
283
|
value: action.id,
|
|
299
284
|
disabled,
|
|
300
|
-
onClick: handleClick,
|
|
301
285
|
variant: "ghost",
|
|
286
|
+
classNames,
|
|
287
|
+
onClick: handleClick,
|
|
302
288
|
...testId && {
|
|
303
289
|
"data-testid": testId
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
return hidden ? null : icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupIconItem, {
|
|
293
|
+
...commonProps,
|
|
294
|
+
icon,
|
|
295
|
+
size: iconSize,
|
|
296
|
+
iconOnly,
|
|
297
|
+
iconClassNames,
|
|
298
|
+
label: actionLabel(action, t)
|
|
299
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, commonProps, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
300
|
+
action
|
|
301
|
+
}));
|
|
308
302
|
};
|
|
309
|
-
var ToggleGroupToolbarItem = ({ group, items:
|
|
310
|
-
const items = useMenuItems(group,
|
|
311
|
-
const { selectCardinality
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
);
|
|
303
|
+
var ToggleGroupToolbarItem = ({ __menuScope, group, items: itemsProp }) => {
|
|
304
|
+
const items = useMenuItems(group, itemsProp, "ToggleGroupToolbarItem", __menuScope);
|
|
305
|
+
const { selectCardinality } = group.properties;
|
|
306
|
+
const children = items.map((action) => /* @__PURE__ */ React3.createElement(ToggleGroupItem, {
|
|
307
|
+
key: action.id,
|
|
308
|
+
group,
|
|
309
|
+
action
|
|
310
|
+
}));
|
|
311
|
+
if (selectCardinality === "multiple") {
|
|
312
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
313
|
+
type: "multiple",
|
|
314
|
+
value: group.properties.value
|
|
315
|
+
}, children);
|
|
316
|
+
} else {
|
|
317
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
318
|
+
type: "single",
|
|
319
|
+
value: group.properties.value
|
|
320
|
+
}, children);
|
|
321
|
+
}
|
|
329
322
|
};
|
|
330
|
-
var ToolbarMenu = ({ __menuScope,
|
|
323
|
+
var ToolbarMenu = composable(({ __menuScope, children, ...props }, forwardedRef) => {
|
|
331
324
|
const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
|
|
332
325
|
const { attendableId, alwaysActive } = useMenuScoped("ToolbarMenu", __menuScope);
|
|
333
326
|
const { hasAttention } = useAttention(attendableId);
|
|
334
|
-
const InnerRoot = textBlockWidthProp ? "div" : Fragment;
|
|
335
|
-
const innerRootProps = textBlockWidthProp ? {
|
|
336
|
-
role: "none",
|
|
337
|
-
className: mx2(textBlockWidth, toolbarLayout, "h-full")
|
|
338
|
-
} : {};
|
|
339
327
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
|
|
340
|
-
...props,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
classNames
|
|
344
|
-
],
|
|
328
|
+
...composableProps(props, {
|
|
329
|
+
classNames: attendableId
|
|
330
|
+
}),
|
|
345
331
|
disabled: !alwaysActive && !hasAttention,
|
|
346
|
-
|
|
347
|
-
},
|
|
348
|
-
key: item.id
|
|
332
|
+
ref: forwardedRef
|
|
333
|
+
}, items?.map((item) => /* @__PURE__ */ React3.createElement(ToolbarMenuItem, {
|
|
334
|
+
key: item.id,
|
|
335
|
+
__menuScope,
|
|
349
336
|
item
|
|
350
|
-
})))
|
|
351
|
-
};
|
|
352
|
-
var ToolbarMenuItem = ({ item }) => {
|
|
337
|
+
})), children);
|
|
338
|
+
});
|
|
339
|
+
var ToolbarMenuItem = ({ __menuScope, item }) => {
|
|
353
340
|
if (isSeparator(item)) {
|
|
354
341
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Separator, {
|
|
355
342
|
variant: item.properties.variant
|
|
@@ -358,15 +345,18 @@ var ToolbarMenuItem = ({ item }) => {
|
|
|
358
345
|
if (isMenuGroup(item)) {
|
|
359
346
|
if (item.properties.variant === "dropdownMenu") {
|
|
360
347
|
return /* @__PURE__ */ React3.createElement(DropdownMenuToolbarItem, {
|
|
348
|
+
__menuScope,
|
|
361
349
|
group: item
|
|
362
350
|
});
|
|
363
351
|
} else {
|
|
364
352
|
return /* @__PURE__ */ React3.createElement(ToggleGroupToolbarItem, {
|
|
353
|
+
__menuScope,
|
|
365
354
|
group: item
|
|
366
355
|
});
|
|
367
356
|
}
|
|
368
357
|
}
|
|
369
358
|
return /* @__PURE__ */ React3.createElement(ActionToolbarItem, {
|
|
359
|
+
__menuScope,
|
|
370
360
|
action: item
|
|
371
361
|
});
|
|
372
362
|
};
|
|
@@ -389,7 +379,7 @@ var menuContextDefaults = {
|
|
|
389
379
|
};
|
|
390
380
|
var [MenuContextProvider, useMenuScoped] = createMenuContext(MENU_NAME, menuContextDefaults);
|
|
391
381
|
var useMenuScope = createMenuScope();
|
|
392
|
-
var MenuDropdownContext = /* @__PURE__ */
|
|
382
|
+
var MenuDropdownContext = /* @__PURE__ */ createContext({
|
|
393
383
|
closeMenu: () => {
|
|
394
384
|
}
|
|
395
385
|
});
|
|
@@ -454,12 +444,7 @@ var resolveItems = (baseItems, group, entries) => {
|
|
|
454
444
|
log.warn("multiple replacement entries found", {
|
|
455
445
|
ids: replacements.map((r) => r.id).join(", "),
|
|
456
446
|
using: replacements[0].id
|
|
457
|
-
}, {
|
|
458
|
-
F: __dxlog_file,
|
|
459
|
-
L: 152,
|
|
460
|
-
S: void 0,
|
|
461
|
-
C: (f, a) => f(...a)
|
|
462
|
-
});
|
|
447
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 94, S: void 0 });
|
|
463
448
|
}
|
|
464
449
|
return replacements[0].items;
|
|
465
450
|
}
|
|
@@ -574,24 +559,22 @@ var Menu = {
|
|
|
574
559
|
};
|
|
575
560
|
|
|
576
561
|
// src/hooks/useMenuActions.ts
|
|
577
|
-
import { RegistryContext as RegistryContext2, useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
578
|
-
import { useCallback as useCallback4, useContext as useContext2,
|
|
562
|
+
import { Atom as Atom2, RegistryContext as RegistryContext2, useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
563
|
+
import { useCallback as useCallback4, useContext as useContext2, useMemo as useMemo2 } from "react";
|
|
579
564
|
import { Graph, Node as Node3 } from "@dxos/app-graph";
|
|
580
565
|
var useMenuActions = (props) => {
|
|
581
566
|
const registry = useContext2(RegistryContext2);
|
|
582
567
|
const menuGraphProps = useAtomValue2(props);
|
|
583
|
-
const
|
|
584
|
-
if (!graphRef.current || graphRef.current.props !== menuGraphProps) {
|
|
568
|
+
const graph = useMemo2(() => {
|
|
585
569
|
const newGraph = Graph.make({
|
|
586
570
|
registry
|
|
587
571
|
});
|
|
588
572
|
newGraph.pipe(Graph.addNodes(menuGraphProps.nodes), Graph.addEdges(menuGraphProps.edges));
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
const graph = graphRef.current.graph;
|
|
573
|
+
return newGraph;
|
|
574
|
+
}, [
|
|
575
|
+
registry,
|
|
576
|
+
menuGraphProps
|
|
577
|
+
]);
|
|
595
578
|
const items = useCallback4((group) => {
|
|
596
579
|
return graph.connections(group?.id || Node3.RootId, "child");
|
|
597
580
|
}, [
|
|
@@ -601,6 +584,10 @@ var useMenuActions = (props) => {
|
|
|
601
584
|
items
|
|
602
585
|
};
|
|
603
586
|
};
|
|
587
|
+
var useMenuBuilder = (build, deps) => {
|
|
588
|
+
const atom = useMemo2(() => Atom2.make(build), deps);
|
|
589
|
+
return useMenuActions(atom);
|
|
590
|
+
};
|
|
604
591
|
|
|
605
592
|
// src/builder.ts
|
|
606
593
|
import { invariant } from "@dxos/invariant";
|
|
@@ -614,24 +601,8 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
614
601
|
this._rootId = _rootId;
|
|
615
602
|
}
|
|
616
603
|
root(props) {
|
|
617
|
-
invariant(this._rootId === "root", "Root group can only be at the top level", {
|
|
618
|
-
|
|
619
|
-
L: 41,
|
|
620
|
-
S: this,
|
|
621
|
-
A: [
|
|
622
|
-
"this._rootId === 'root'",
|
|
623
|
-
"'Root group can only be at the top level'"
|
|
624
|
-
]
|
|
625
|
-
});
|
|
626
|
-
invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", {
|
|
627
|
-
F: __dxlog_file2,
|
|
628
|
-
L: 42,
|
|
629
|
-
S: this,
|
|
630
|
-
A: [
|
|
631
|
-
"this._data.nodes.find((node) => node.id === 'root') === undefined",
|
|
632
|
-
"'Root group can only be created once'"
|
|
633
|
-
]
|
|
634
|
-
});
|
|
604
|
+
invariant(this._rootId === "root", "Root group can only be at the top level", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 16, S: this, A: ["this._rootId === 'root'", "'Root group can only be at the top level'"] });
|
|
605
|
+
invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 17, S: this, A: ["this._data.nodes.find((node)=>node.id === 'root') === undefined", "'Root group can only be created once'"] });
|
|
635
606
|
this._data.nodes.push(createMenuItemGroup("root", props));
|
|
636
607
|
return this;
|
|
637
608
|
}
|
|
@@ -657,13 +628,20 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
657
628
|
cb(new _MenuBuilderImpl(this._data, id));
|
|
658
629
|
return this;
|
|
659
630
|
}
|
|
660
|
-
subgraph(
|
|
661
|
-
|
|
662
|
-
|
|
631
|
+
subgraph(subgraphOrCb) {
|
|
632
|
+
if (!subgraphOrCb) {
|
|
633
|
+
return this;
|
|
634
|
+
}
|
|
635
|
+
if (typeof subgraphOrCb === "function") {
|
|
636
|
+
subgraphOrCb(new _MenuBuilderImpl(this._data, this._rootId));
|
|
637
|
+
} else {
|
|
638
|
+
this._data.nodes.push(...subgraphOrCb.nodes);
|
|
639
|
+
this._data.edges.push(...subgraphOrCb.edges);
|
|
640
|
+
}
|
|
663
641
|
return this;
|
|
664
642
|
}
|
|
665
|
-
separator(
|
|
666
|
-
id
|
|
643
|
+
separator(variant = "gap") {
|
|
644
|
+
const id = `separator-${++this._separatorCount}`;
|
|
667
645
|
this._data.nodes.push({
|
|
668
646
|
id,
|
|
669
647
|
type: MenuSeparatorType,
|
|
@@ -699,6 +677,7 @@ export {
|
|
|
699
677
|
menuContextDefaults,
|
|
700
678
|
useMenu,
|
|
701
679
|
useMenuActions,
|
|
680
|
+
useMenuBuilder,
|
|
702
681
|
useMenuItems,
|
|
703
682
|
useMenuScoped
|
|
704
683
|
};
|