@dxos/react-ui-menu 0.8.4-main.d05673bc65 → 0.8.4-main.e00bdcdb52
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 +104 -134
- 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 +104 -134
- 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 +111 -86
- 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
|
@@ -4,7 +4,7 @@ import { createRequire } from 'node:module';const require = createRequire(import
|
|
|
4
4
|
import { Atom, RegistryContext, useAtomValue } from "@effect-atom/atom-react";
|
|
5
5
|
import { createContextScope } from "@radix-ui/react-context";
|
|
6
6
|
import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
|
|
7
|
-
import React4, { useCallback as useCallback3, useContext, useMemo } from "react";
|
|
7
|
+
import React4, { createContext, useCallback as useCallback3, useContext, useMemo } from "react";
|
|
8
8
|
import { log } from "@dxos/log";
|
|
9
9
|
import { Icon as Icon3, DropdownMenu as NaturalDropdownMenu2 } from "@dxos/react-ui";
|
|
10
10
|
|
|
@@ -79,18 +79,7 @@ import React from "react";
|
|
|
79
79
|
import { keySymbols } from "@dxos/keyboard";
|
|
80
80
|
import { toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
81
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
|
-
}
|
|
90
|
-
}
|
|
91
|
-
];
|
|
92
|
-
|
|
93
|
-
// src/components/ActionLabel.tsx
|
|
82
|
+
import { translationKey } from "#translations";
|
|
94
83
|
var ActionLabel = ({ action }) => {
|
|
95
84
|
const { t } = useTranslation(translationKey);
|
|
96
85
|
const shortcut = getShortcut(action);
|
|
@@ -106,10 +95,11 @@ var actionLabel = (action, t) => {
|
|
|
106
95
|
};
|
|
107
96
|
|
|
108
97
|
// src/components/ToolbarMenu.tsx
|
|
109
|
-
import React3, {
|
|
98
|
+
import React3, { useCallback as useCallback2 } from "react";
|
|
110
99
|
import { Icon as Icon2, Toolbar as NaturalToolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
111
100
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
112
|
-
import {
|
|
101
|
+
import { composable, composableProps } from "@dxos/ui-theme";
|
|
102
|
+
import { translationKey as translationKey2 } from "#translations";
|
|
113
103
|
|
|
114
104
|
// src/types.ts
|
|
115
105
|
import { Node as Node2 } from "@dxos/app-graph";
|
|
@@ -189,21 +179,11 @@ var DropdownMenu = {
|
|
|
189
179
|
};
|
|
190
180
|
|
|
191
181
|
// src/components/ToolbarMenu.tsx
|
|
192
|
-
var ActionToolbarItem = ({
|
|
182
|
+
var ActionToolbarItem = ({ __menuScope, action }) => {
|
|
193
183
|
const { iconSize, onAction } = useMenuScoped("ActionToolbarItem", __menuScope);
|
|
194
|
-
const { t } = useTranslation2(
|
|
195
|
-
const { icon, iconOnly = true, disabled, testId, hidden, classNames
|
|
196
|
-
const
|
|
197
|
-
const rootProps = icon ? {
|
|
198
|
-
icon,
|
|
199
|
-
size: iconSize,
|
|
200
|
-
iconOnly,
|
|
201
|
-
label: actionLabel(action, t)
|
|
202
|
-
} : {
|
|
203
|
-
children: /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
204
|
-
action
|
|
205
|
-
})
|
|
206
|
-
};
|
|
184
|
+
const { t } = useTranslation2(translationKey2);
|
|
185
|
+
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
186
|
+
const buttonVariant = action.properties.variant === "primary" ? "primary" : "ghost";
|
|
207
187
|
const handleClick = useCallback2(() => {
|
|
208
188
|
if (onAction) {
|
|
209
189
|
onAction(action, {});
|
|
@@ -214,21 +194,35 @@ var ActionToolbarItem = ({ action, __menuScope }) => {
|
|
|
214
194
|
action,
|
|
215
195
|
onAction
|
|
216
196
|
]);
|
|
217
|
-
|
|
218
|
-
|
|
197
|
+
const commonProps = {
|
|
198
|
+
variant: buttonVariant,
|
|
219
199
|
disabled,
|
|
200
|
+
classNames,
|
|
220
201
|
onClick: handleClick,
|
|
221
|
-
variant: variant ?? "ghost",
|
|
222
202
|
...testId && {
|
|
223
203
|
"data-testid": testId
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
if (hidden) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.IconButton, {
|
|
210
|
+
key: action.id,
|
|
211
|
+
...commonProps,
|
|
212
|
+
icon,
|
|
213
|
+
size: iconSize,
|
|
214
|
+
iconOnly,
|
|
215
|
+
label: actionLabel(action, t)
|
|
216
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
|
|
217
|
+
key: action.id,
|
|
218
|
+
...commonProps
|
|
219
|
+
}, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
220
|
+
action
|
|
221
|
+
}));
|
|
228
222
|
};
|
|
229
|
-
var DropdownMenuToolbarItem = ({ group, items: propsItems
|
|
223
|
+
var DropdownMenuToolbarItem = ({ __menuScope, group, items: propsItems }) => {
|
|
230
224
|
const { iconOnly, disabled, testId } = group.properties;
|
|
231
|
-
const { t } = useTranslation2(
|
|
225
|
+
const { t } = useTranslation2(translationKey2);
|
|
232
226
|
const { iconSize } = useMenuScoped("DropdownMenuToolbarItem", __menuScope);
|
|
233
227
|
const items = useMenuItems(group, propsItems, "DropdownMenuToolbarItem", __menuScope);
|
|
234
228
|
const activeItem = items?.find((item) => !!item.properties.checked);
|
|
@@ -265,9 +259,9 @@ var DropdownMenuToolbarItem = ({ group, items: propsItems, __menuScope }) => {
|
|
|
265
259
|
}
|
|
266
260
|
})));
|
|
267
261
|
};
|
|
268
|
-
var ToggleGroupItem = ({ group, action
|
|
262
|
+
var ToggleGroupItem = ({ __menuScope, group, action }) => {
|
|
269
263
|
const { iconSize, onAction } = useMenuScoped("ToggleGroupItem", __menuScope);
|
|
270
|
-
const { t } = useTranslation2(
|
|
264
|
+
const { t } = useTranslation2(translationKey2);
|
|
271
265
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
272
266
|
const handleClick = useCallback2(() => {
|
|
273
267
|
if (onAction) {
|
|
@@ -284,74 +278,63 @@ var ToggleGroupItem = ({ group, action, __menuScope }) => {
|
|
|
284
278
|
group,
|
|
285
279
|
onAction
|
|
286
280
|
]);
|
|
287
|
-
const
|
|
288
|
-
const rootProps = icon ? {
|
|
289
|
-
icon,
|
|
290
|
-
size: iconSize,
|
|
291
|
-
iconOnly,
|
|
292
|
-
label: actionLabel(action, t)
|
|
293
|
-
} : {
|
|
294
|
-
children: /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
295
|
-
action
|
|
296
|
-
})
|
|
297
|
-
};
|
|
298
|
-
return hidden ? null : /* @__PURE__ */ React3.createElement(Root, {
|
|
299
|
-
key: action.id,
|
|
281
|
+
const commonProps = {
|
|
300
282
|
value: action.id,
|
|
301
283
|
disabled,
|
|
302
|
-
onClick: handleClick,
|
|
303
284
|
variant: "ghost",
|
|
285
|
+
classNames,
|
|
286
|
+
onClick: handleClick,
|
|
304
287
|
...testId && {
|
|
305
288
|
"data-testid": testId
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
return hidden ? null : icon ? /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupIconItem, {
|
|
292
|
+
...commonProps,
|
|
293
|
+
icon,
|
|
294
|
+
size: iconSize,
|
|
295
|
+
iconOnly,
|
|
296
|
+
label: actionLabel(action, t)
|
|
297
|
+
}) : /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, commonProps, /* @__PURE__ */ React3.createElement(ActionLabel, {
|
|
298
|
+
action
|
|
299
|
+
}));
|
|
310
300
|
};
|
|
311
|
-
var ToggleGroupToolbarItem = ({ group, items:
|
|
312
|
-
const items = useMenuItems(group,
|
|
313
|
-
const { selectCardinality
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
);
|
|
301
|
+
var ToggleGroupToolbarItem = ({ __menuScope, group, items: itemsProp }) => {
|
|
302
|
+
const items = useMenuItems(group, itemsProp, "ToggleGroupToolbarItem", __menuScope);
|
|
303
|
+
const { selectCardinality } = group.properties;
|
|
304
|
+
const children = items.map((action) => /* @__PURE__ */ React3.createElement(ToggleGroupItem, {
|
|
305
|
+
key: action.id,
|
|
306
|
+
group,
|
|
307
|
+
action
|
|
308
|
+
}));
|
|
309
|
+
if (selectCardinality === "multiple") {
|
|
310
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
311
|
+
type: "multiple",
|
|
312
|
+
value: group.properties.value
|
|
313
|
+
}, children);
|
|
314
|
+
} else {
|
|
315
|
+
return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
|
|
316
|
+
type: "single",
|
|
317
|
+
value: group.properties.value
|
|
318
|
+
}, children);
|
|
319
|
+
}
|
|
331
320
|
};
|
|
332
|
-
var ToolbarMenu = ({ __menuScope,
|
|
321
|
+
var ToolbarMenu = composable(({ __menuScope, children, ...props }, forwardedRef) => {
|
|
333
322
|
const items = useMenuItems(void 0, void 0, "ToolbarMenu", __menuScope);
|
|
334
323
|
const { attendableId, alwaysActive } = useMenuScoped("ToolbarMenu", __menuScope);
|
|
335
324
|
const { hasAttention } = useAttention(attendableId);
|
|
336
|
-
const InnerRoot = textBlockWidthProp ? "div" : Fragment;
|
|
337
|
-
const innerRootProps = textBlockWidthProp ? {
|
|
338
|
-
role: "none",
|
|
339
|
-
className: mx2(textBlockWidth, toolbarLayout, "h-full")
|
|
340
|
-
} : {};
|
|
341
325
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
|
|
342
|
-
...props,
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
classNames
|
|
346
|
-
],
|
|
326
|
+
...composableProps(props, {
|
|
327
|
+
classNames: attendableId
|
|
328
|
+
}),
|
|
347
329
|
disabled: !alwaysActive && !hasAttention,
|
|
348
|
-
|
|
349
|
-
},
|
|
350
|
-
key: item.id
|
|
330
|
+
ref: forwardedRef
|
|
331
|
+
}, items?.map((item) => /* @__PURE__ */ React3.createElement(ToolbarMenuItem, {
|
|
332
|
+
key: item.id,
|
|
333
|
+
__menuScope,
|
|
351
334
|
item
|
|
352
|
-
})))
|
|
353
|
-
};
|
|
354
|
-
var ToolbarMenuItem = ({ item }) => {
|
|
335
|
+
})), children);
|
|
336
|
+
});
|
|
337
|
+
var ToolbarMenuItem = ({ __menuScope, item }) => {
|
|
355
338
|
if (isSeparator(item)) {
|
|
356
339
|
return /* @__PURE__ */ React3.createElement(NaturalToolbar.Separator, {
|
|
357
340
|
variant: item.properties.variant
|
|
@@ -360,15 +343,18 @@ var ToolbarMenuItem = ({ item }) => {
|
|
|
360
343
|
if (isMenuGroup(item)) {
|
|
361
344
|
if (item.properties.variant === "dropdownMenu") {
|
|
362
345
|
return /* @__PURE__ */ React3.createElement(DropdownMenuToolbarItem, {
|
|
346
|
+
__menuScope,
|
|
363
347
|
group: item
|
|
364
348
|
});
|
|
365
349
|
} else {
|
|
366
350
|
return /* @__PURE__ */ React3.createElement(ToggleGroupToolbarItem, {
|
|
351
|
+
__menuScope,
|
|
367
352
|
group: item
|
|
368
353
|
});
|
|
369
354
|
}
|
|
370
355
|
}
|
|
371
356
|
return /* @__PURE__ */ React3.createElement(ActionToolbarItem, {
|
|
357
|
+
__menuScope,
|
|
372
358
|
action: item
|
|
373
359
|
});
|
|
374
360
|
};
|
|
@@ -391,7 +377,7 @@ var menuContextDefaults = {
|
|
|
391
377
|
};
|
|
392
378
|
var [MenuContextProvider, useMenuScoped] = createMenuContext(MENU_NAME, menuContextDefaults);
|
|
393
379
|
var useMenuScope = createMenuScope();
|
|
394
|
-
var MenuDropdownContext = /* @__PURE__ */
|
|
380
|
+
var MenuDropdownContext = /* @__PURE__ */ createContext({
|
|
395
381
|
closeMenu: () => {
|
|
396
382
|
}
|
|
397
383
|
});
|
|
@@ -456,12 +442,7 @@ var resolveItems = (baseItems, group, entries) => {
|
|
|
456
442
|
log.warn("multiple replacement entries found", {
|
|
457
443
|
ids: replacements.map((r) => r.id).join(", "),
|
|
458
444
|
using: replacements[0].id
|
|
459
|
-
}, {
|
|
460
|
-
F: __dxlog_file,
|
|
461
|
-
L: 152,
|
|
462
|
-
S: void 0,
|
|
463
|
-
C: (f, a) => f(...a)
|
|
464
|
-
});
|
|
445
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 94, S: void 0 });
|
|
465
446
|
}
|
|
466
447
|
return replacements[0].items;
|
|
467
448
|
}
|
|
@@ -577,23 +558,21 @@ var Menu = {
|
|
|
577
558
|
|
|
578
559
|
// src/hooks/useMenuActions.ts
|
|
579
560
|
import { RegistryContext as RegistryContext2, useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
580
|
-
import { useCallback as useCallback4, useContext as useContext2,
|
|
561
|
+
import { useCallback as useCallback4, useContext as useContext2, useMemo as useMemo2 } from "react";
|
|
581
562
|
import { Graph, Node as Node3 } from "@dxos/app-graph";
|
|
582
563
|
var useMenuActions = (props) => {
|
|
583
564
|
const registry = useContext2(RegistryContext2);
|
|
584
565
|
const menuGraphProps = useAtomValue2(props);
|
|
585
|
-
const
|
|
586
|
-
if (!graphRef.current || graphRef.current.props !== menuGraphProps) {
|
|
566
|
+
const graph = useMemo2(() => {
|
|
587
567
|
const newGraph = Graph.make({
|
|
588
568
|
registry
|
|
589
569
|
});
|
|
590
570
|
newGraph.pipe(Graph.addNodes(menuGraphProps.nodes), Graph.addEdges(menuGraphProps.edges));
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
const graph = graphRef.current.graph;
|
|
571
|
+
return newGraph;
|
|
572
|
+
}, [
|
|
573
|
+
registry,
|
|
574
|
+
menuGraphProps
|
|
575
|
+
]);
|
|
597
576
|
const items = useCallback4((group) => {
|
|
598
577
|
return graph.connections(group?.id || Node3.RootId, "child");
|
|
599
578
|
}, [
|
|
@@ -616,24 +595,8 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
616
595
|
this._rootId = _rootId;
|
|
617
596
|
}
|
|
618
597
|
root(props) {
|
|
619
|
-
invariant(this._rootId === "root", "Root group can only be at the top level", {
|
|
620
|
-
|
|
621
|
-
L: 41,
|
|
622
|
-
S: this,
|
|
623
|
-
A: [
|
|
624
|
-
"this._rootId === 'root'",
|
|
625
|
-
"'Root group can only be at the top level'"
|
|
626
|
-
]
|
|
627
|
-
});
|
|
628
|
-
invariant(this._data.nodes.find((node) => node.id === "root") === void 0, "Root group can only be created once", {
|
|
629
|
-
F: __dxlog_file2,
|
|
630
|
-
L: 42,
|
|
631
|
-
S: this,
|
|
632
|
-
A: [
|
|
633
|
-
"this._data.nodes.find((node) => node.id === 'root') === undefined",
|
|
634
|
-
"'Root group can only be created once'"
|
|
635
|
-
]
|
|
636
|
-
});
|
|
598
|
+
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'"] });
|
|
599
|
+
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'"] });
|
|
637
600
|
this._data.nodes.push(createMenuItemGroup("root", props));
|
|
638
601
|
return this;
|
|
639
602
|
}
|
|
@@ -659,13 +622,20 @@ var MenuBuilderImpl = class _MenuBuilderImpl {
|
|
|
659
622
|
cb(new _MenuBuilderImpl(this._data, id));
|
|
660
623
|
return this;
|
|
661
624
|
}
|
|
662
|
-
subgraph(
|
|
663
|
-
|
|
664
|
-
|
|
625
|
+
subgraph(subgraphOrCb) {
|
|
626
|
+
if (!subgraphOrCb) {
|
|
627
|
+
return this;
|
|
628
|
+
}
|
|
629
|
+
if (typeof subgraphOrCb === "function") {
|
|
630
|
+
subgraphOrCb(new _MenuBuilderImpl(this._data, this._rootId));
|
|
631
|
+
} else {
|
|
632
|
+
this._data.nodes.push(...subgraphOrCb.nodes);
|
|
633
|
+
this._data.edges.push(...subgraphOrCb.edges);
|
|
634
|
+
}
|
|
665
635
|
return this;
|
|
666
636
|
}
|
|
667
|
-
separator(
|
|
668
|
-
id
|
|
637
|
+
separator(variant = "gap") {
|
|
638
|
+
const id = `separator-${++this._separatorCount}`;
|
|
669
639
|
this._data.nodes.push({
|
|
670
640
|
id,
|
|
671
641
|
type: MenuSeparatorType,
|