@dxos/react-ui-menu 0.8.4-main.c85a9c8dae → 0.8.4-main.cb12b3f963
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 +103 -133
- 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 +103 -133
- 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 +3 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -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 +2 -2
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +27 -21
- 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 +15 -12
- package/src/components/ToolbarMenu.tsx +110 -85
- package/src/hooks/useMenuActions.ts +6 -7
- package/src/index.ts +1 -1
- package/src/testing/generator.ts +15 -10
- package/src/types.ts +1 -0
- package/dist/types/src/components/MenuItems.stories.d.ts.map +0 -1
|
@@ -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";
|
|
109
98
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
110
|
-
import {
|
|
99
|
+
import { composable, composableProps } from "@dxos/ui-theme";
|
|
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(
|
|
182
|
+
const { t } = useTranslation2(translationKey2);
|
|
193
183
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
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
|
-
};
|
|
184
|
+
const buttonVariant = action.properties.variant === "primary" ? "primary" : "ghost";
|
|
205
185
|
const handleClick = useCallback2(() => {
|
|
206
186
|
if (onAction) {
|
|
207
187
|
onAction(action, {});
|
|
@@ -212,21 +192,35 @@ 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: "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
|
+
label: actionLabel(action, t)
|
|
214
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
215
|
+
key: action.id,
|
|
216
|
+
...commonProps
|
|
217
|
+
}, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
218
|
+
action
|
|
219
|
+
}));
|
|
226
220
|
};
|
|
227
|
-
var DropdownMenuToolbarItem = ({ group, items: propsItems
|
|
221
|
+
var DropdownMenuToolbarItem = ({ __menuScope, group, items: propsItems }) => {
|
|
228
222
|
const { iconOnly, disabled, testId } = group.properties;
|
|
229
|
-
const { t } = useTranslation2(
|
|
223
|
+
const { t } = useTranslation2(translationKey2);
|
|
230
224
|
const { iconSize } = useMenuScoped("DropdownMenuToolbarItem", __menuScope);
|
|
231
225
|
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
232
226
|
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
@@ -263,9 +257,9 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
263
257
|
}
|
|
264
258
|
})));
|
|
265
259
|
};
|
|
266
|
-
var ToggleGroupItem = ({ group, action
|
|
260
|
+
var ToggleGroupItem = ({ __menuScope, group, action }) => {
|
|
267
261
|
const { iconSize, onAction } = useMenuScoped("ToggleGroupItem", __menuScope);
|
|
268
|
-
const { t } = useTranslation2(
|
|
262
|
+
const { t } = useTranslation2(translationKey2);
|
|
269
263
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
270
264
|
const handleClick = useCallback2(() => {
|
|
271
265
|
if (onAction) {
|
|
@@ -282,74 +276,63 @@ var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
|
282
276
|
group,
|
|
283
277
|
onAction
|
|
284
278
|
]);
|
|
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,
|
|
279
|
+
const commonProps = {
|
|
298
280
|
value: action.id,
|
|
299
281
|
disabled,
|
|
300
|
-
onClick: handleClick,
|
|
301
282
|
variant: "ghost",
|
|
283
|
+
classNames,
|
|
284
|
+
onClick: handleClick,
|
|
302
285
|
...testId && {
|
|
303
286
|
"data-testid": testId
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
return hidden ? null : icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupIconItem, {
|
|
290
|
+
...commonProps,
|
|
291
|
+
icon,
|
|
292
|
+
size: iconSize,
|
|
293
|
+
iconOnly,
|
|
294
|
+
label: actionLabel(action, t)
|
|
295
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, commonProps, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
296
|
+
action
|
|
297
|
+
}));
|
|
308
298
|
};
|
|
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
|
-
);
|
|
299
|
+
var ToggleGroupToolbarItem = ({ __menuScope, group, items: itemsProp }) => {
|
|
300
|
+
const items = useMenuItems(group, itemsProp, "ToggleGroupToolbarItem", __menuScope);
|
|
301
|
+
const { selectCardinality } = group.properties;
|
|
302
|
+
const children = items.map((action) => /* @__PURE__ */ React3.createElement(ToggleGroupItem, {
|
|
303
|
+
key: action.id,
|
|
304
|
+
group,
|
|
305
|
+
action
|
|
306
|
+
}));
|
|
307
|
+
if (selectCardinality === "multiple") {
|
|
308
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
309
|
+
type: "multiple",
|
|
310
|
+
value: group.properties.value
|
|
311
|
+
}, children);
|
|
312
|
+
} else {
|
|
313
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
314
|
+
type: "single",
|
|
315
|
+
value: group.properties.value
|
|
316
|
+
}, children);
|
|
317
|
+
}
|
|
329
318
|
};
|
|
330
|
-
var ToolbarMenu = ({ __menuScope,
|
|
319
|
+
var ToolbarMenu = composable(({ __menuScope, children, ...props }, forwardedRef) => {
|
|
331
320
|
const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
|
|
332
321
|
const { attendableId, alwaysActive } = useMenuScoped("ToolbarMenu", __menuScope);
|
|
333
322
|
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
323
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
|
|
340
|
-
...props,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
classNames
|
|
344
|
-
],
|
|
324
|
+
...composableProps(props, {
|
|
325
|
+
classNames: attendableId
|
|
326
|
+
}),
|
|
345
327
|
disabled: !alwaysActive && !hasAttention,
|
|
346
|
-
|
|
347
|
-
},
|
|
348
|
-
key: item.id
|
|
328
|
+
ref: forwardedRef
|
|
329
|
+
}, items?.map((item) => /* @__PURE__ */ React3.createElement(ToolbarMenuItem, {
|
|
330
|
+
key: item.id,
|
|
331
|
+
__menuScope,
|
|
349
332
|
item
|
|
350
|
-
})))
|
|
351
|
-
};
|
|
352
|
-
var ToolbarMenuItem = ({ item }) => {
|
|
333
|
+
})), children);
|
|
334
|
+
});
|
|
335
|
+
var ToolbarMenuItem = ({ __menuScope, item }) => {
|
|
353
336
|
if (isSeparator(item)) {
|
|
354
337
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Separator, {
|
|
355
338
|
variant: item.properties.variant
|
|
@@ -358,15 +341,18 @@ var ToolbarMenuItem = ({ item }) => {
|
|
|
358
341
|
if (isMenuGroup(item)) {
|
|
359
342
|
if (item.properties.variant === "dropdownMenu") {
|
|
360
343
|
return /* @__PURE__ */ React3.createElement(DropdownMenuToolbarItem, {
|
|
344
|
+
__menuScope,
|
|
361
345
|
group: item
|
|
362
346
|
});
|
|
363
347
|
} else {
|
|
364
348
|
return /* @__PURE__ */ React3.createElement(ToggleGroupToolbarItem, {
|
|
349
|
+
__menuScope,
|
|
365
350
|
group: item
|
|
366
351
|
});
|
|
367
352
|
}
|
|
368
353
|
}
|
|
369
354
|
return /* @__PURE__ */ React3.createElement(ActionToolbarItem, {
|
|
355
|
+
__menuScope,
|
|
370
356
|
action: item
|
|
371
357
|
});
|
|
372
358
|
};
|
|
@@ -389,7 +375,7 @@ var menuContextDefaults = {
|
|
|
389
375
|
};
|
|
390
376
|
var [MenuContextProvider, useMenuScoped] = createMenuContext(MENU_NAME, menuContextDefaults);
|
|
391
377
|
var useMenuScope = createMenuScope();
|
|
392
|
-
var MenuDropdownContext = /* @__PURE__ */
|
|
378
|
+
var MenuDropdownContext = /* @__PURE__ */ createContext({
|
|
393
379
|
closeMenu: () => {
|
|
394
380
|
}
|
|
395
381
|
});
|
|
@@ -454,12 +440,7 @@ var resolveItems = (baseItems, group, entries) => {
|
|
|
454
440
|
log.warn("multiple replacement entries found", {
|
|
455
441
|
ids: replacements.map((r) => r.id).join(", "),
|
|
456
442
|
using: replacements[0].id
|
|
457
|
-
}, {
|
|
458
|
-
F: __dxlog_file,
|
|
459
|
-
L: 152,
|
|
460
|
-
S: void 0,
|
|
461
|
-
C: (f, a) => f(...a)
|
|
462
|
-
});
|
|
443
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 94, S: void 0 });
|
|
463
444
|
}
|
|
464
445
|
return replacements[0].items;
|
|
465
446
|
}
|
|
@@ -575,23 +556,21 @@ var Menu = {
|
|
|
575
556
|
|
|
576
557
|
// src/hooks/useMenuActions.ts
|
|
577
558
|
import { RegistryContext as RegistryContext2, useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
578
|
-
import { useCallback as useCallback4, useContext as useContext2,
|
|
559
|
+
import { useCallback as useCallback4, useContext as useContext2, useMemo as useMemo2 } from "react";
|
|
579
560
|
import { Graph, Node as Node3 } from "@dxos/app-graph";
|
|
580
561
|
var useMenuActions = (props) => {
|
|
581
562
|
const registry = useContext2(RegistryContext2);
|
|
582
563
|
const menuGraphProps = useAtomValue2(props);
|
|
583
|
-
const
|
|
584
|
-
if (!graphRef.current || graphRef.current.props !== menuGraphProps) {
|
|
564
|
+
const graph = useMemo2(() => {
|
|
585
565
|
const newGraph = Graph.make({
|
|
586
566
|
registry
|
|
587
567
|
});
|
|
588
568
|
newGraph.pipe(Graph.addNodes(menuGraphProps.nodes), Graph.addEdges(menuGraphProps.edges));
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
const graph = graphRef.current.graph;
|
|
569
|
+
return newGraph;
|
|
570
|
+
}, [
|
|
571
|
+
registry,
|
|
572
|
+
menuGraphProps
|
|
573
|
+
]);
|
|
595
574
|
const items = useCallback4((group) => {
|
|
596
575
|
return graph.connections(group?.id || Node3.RootId, "child");
|
|
597
576
|
}, [
|
|
@@ -614,24 +593,8 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
614
593
|
this._rootId = _rootId;
|
|
615
594
|
}
|
|
616
595
|
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
|
-
});
|
|
596
|
+
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'"] });
|
|
597
|
+
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
598
|
this._data.nodes.push(createMenuItemGroup("root", props));
|
|
636
599
|
return this;
|
|
637
600
|
}
|
|
@@ -657,13 +620,20 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
657
620
|
cb(new _MenuBuilderImpl(this._data, id));
|
|
658
621
|
return this;
|
|
659
622
|
}
|
|
660
|
-
subgraph(
|
|
661
|
-
|
|
662
|
-
|
|
623
|
+
subgraph(subgraphOrCb) {
|
|
624
|
+
if (!subgraphOrCb) {
|
|
625
|
+
return this;
|
|
626
|
+
}
|
|
627
|
+
if (typeof subgraphOrCb === "function") {
|
|
628
|
+
subgraphOrCb(new _MenuBuilderImpl(this._data, this._rootId));
|
|
629
|
+
} else {
|
|
630
|
+
this._data.nodes.push(...subgraphOrCb.nodes);
|
|
631
|
+
this._data.edges.push(...subgraphOrCb.edges);
|
|
632
|
+
}
|
|
663
633
|
return this;
|
|
664
634
|
}
|
|
665
|
-
separator(
|
|
666
|
-
id
|
|
635
|
+
separator(variant = "gap") {
|
|
636
|
+
const id = `separator-${++this._separatorCount}`;
|
|
667
637
|
this._data.nodes.push({
|
|
668
638
|
id,
|
|
669
639
|
type: MenuSeparatorType,
|