@dxos/react-ui-menu 0.8.4-main.21d9917 → 0.8.4-main.2244d791bb
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 +15 -40
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +15 -40
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/MenuContext.d.ts +1 -1
- package/dist/types/src/components/MenuContext.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +2 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -20
- package/src/components/MenuContext.tsx +2 -0
- package/src/components/ToolbarMenu.stories.tsx +1 -1
- package/src/components/ToolbarMenu.tsx +4 -3
- package/src/hooks/useMenuActions.ts +8 -43
- package/src/types.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-menu",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.2244d791bb",
|
|
4
4
|
"description": "Components for facilitating reactive and consistent menus.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -31,36 +31,36 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@radix-ui/react-context": "1.1.1",
|
|
33
33
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
34
|
-
"@dxos/app-graph": "0.8.4-main.
|
|
35
|
-
"@dxos/effect": "0.8.4-main.
|
|
36
|
-
"@dxos/invariant": "0.8.4-main.
|
|
37
|
-
"@dxos/keyboard": "0.8.4-main.
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/ui-
|
|
34
|
+
"@dxos/app-graph": "0.8.4-main.2244d791bb",
|
|
35
|
+
"@dxos/effect": "0.8.4-main.2244d791bb",
|
|
36
|
+
"@dxos/invariant": "0.8.4-main.2244d791bb",
|
|
37
|
+
"@dxos/keyboard": "0.8.4-main.2244d791bb",
|
|
38
|
+
"@dxos/ui-types": "0.8.4-main.2244d791bb",
|
|
39
|
+
"@dxos/util": "0.8.4-main.2244d791bb",
|
|
40
|
+
"@dxos/react-ui-attention": "0.8.4-main.2244d791bb"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@effect-atom/atom-react": "^0.
|
|
44
|
-
"@effect/platform": "0.
|
|
43
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
44
|
+
"@effect/platform": "0.94.4",
|
|
45
45
|
"@types/react": "~19.2.7",
|
|
46
46
|
"@types/react-dom": "~19.2.3",
|
|
47
|
-
"effect": "3.19.
|
|
47
|
+
"effect": "3.19.16",
|
|
48
48
|
"react": "~19.2.3",
|
|
49
49
|
"react-dom": "~19.2.3",
|
|
50
50
|
"vite": "7.1.9",
|
|
51
|
-
"@dxos/random": "0.8.4-main.
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
51
|
+
"@dxos/random": "0.8.4-main.2244d791bb",
|
|
52
|
+
"@dxos/storybook-utils": "0.8.4-main.2244d791bb",
|
|
53
|
+
"@dxos/react-ui": "0.8.4-main.2244d791bb",
|
|
54
|
+
"@dxos/ui-theme": "0.8.4-main.2244d791bb"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@effect-atom/atom-react": "^0.
|
|
58
|
-
"@effect/platform": "0.
|
|
59
|
-
"effect": "3.19.
|
|
57
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
58
|
+
"@effect/platform": "0.94.4",
|
|
59
|
+
"effect": "3.19.16",
|
|
60
60
|
"react": "~19.2.3",
|
|
61
61
|
"react-dom": "~19.2.3",
|
|
62
|
-
"@dxos/ui
|
|
63
|
-
"@dxos/
|
|
62
|
+
"@dxos/react-ui": "0.8.4-main.2244d791bb",
|
|
63
|
+
"@dxos/ui-theme": "0.8.4-main.2244d791bb"
|
|
64
64
|
},
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|
|
@@ -30,6 +30,7 @@ const MenuProvider = ({
|
|
|
30
30
|
useGroupItems = menuContextDefaults.useGroupItems,
|
|
31
31
|
iconSize = menuContextDefaults.iconSize,
|
|
32
32
|
attendableId,
|
|
33
|
+
alwaysActive,
|
|
33
34
|
onAction,
|
|
34
35
|
}: MenuProviderProps) => {
|
|
35
36
|
const { scope } = useMenuScope(undefined);
|
|
@@ -38,6 +39,7 @@ const MenuProvider = ({
|
|
|
38
39
|
useGroupItems={useGroupItems}
|
|
39
40
|
iconSize={iconSize}
|
|
40
41
|
attendableId={attendableId}
|
|
42
|
+
alwaysActive={alwaysActive}
|
|
41
43
|
onAction={onAction}
|
|
42
44
|
scope={scope}
|
|
43
45
|
>
|
|
@@ -6,7 +6,7 @@ import React, { Fragment, useCallback } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Icon, Toolbar as NaturalToolbar, type ToolbarRootProps, useTranslation } from '@dxos/react-ui';
|
|
8
8
|
import { useAttention } from '@dxos/react-ui-attention';
|
|
9
|
-
import { mx, textBlockWidth,
|
|
9
|
+
import { mx, textBlockWidth, toolbarLayout } from '@dxos/ui-theme';
|
|
10
10
|
import { type MenuActionProperties } from '@dxos/ui-types';
|
|
11
11
|
|
|
12
12
|
import { translationKey } from '../translations';
|
|
@@ -187,7 +187,7 @@ export const ToolbarMenu = ({
|
|
|
187
187
|
...props
|
|
188
188
|
}: MenuScopedProps<ToolbarMenuProps>) => {
|
|
189
189
|
const items = useMenuItems(undefined, undefined, 'ToolbarMenu', __menuScope);
|
|
190
|
-
const { attendableId } = useMenu('ToolbarMenu', __menuScope);
|
|
190
|
+
const { attendableId, alwaysActive } = useMenu('ToolbarMenu', __menuScope);
|
|
191
191
|
const { hasAttention } = useAttention(attendableId);
|
|
192
192
|
const InnerRoot = textBlockWidthProp ? 'div' : Fragment;
|
|
193
193
|
const innerRootProps = textBlockWidthProp
|
|
@@ -197,7 +197,8 @@ export const ToolbarMenu = ({
|
|
|
197
197
|
return (
|
|
198
198
|
<NaturalToolbar.Root
|
|
199
199
|
{...props}
|
|
200
|
-
classNames={[attendableId
|
|
200
|
+
classNames={[attendableId, classNames]}
|
|
201
|
+
disabled={!alwaysActive && !hasAttention}
|
|
201
202
|
layoutManaged={textBlockWidthProp}
|
|
202
203
|
>
|
|
203
204
|
<InnerRoot {...innerRootProps}>
|
|
@@ -9,33 +9,6 @@ import { Graph, Node } from '@dxos/app-graph';
|
|
|
9
9
|
|
|
10
10
|
import { type MenuItem, type MenuItemGroup } from '../types';
|
|
11
11
|
|
|
12
|
-
const edgesArrayToRecord = (edges: Graph.Edge[]): Record<string, Graph.Edges> => {
|
|
13
|
-
return Object.fromEntries(
|
|
14
|
-
Object.entries(
|
|
15
|
-
edges.reduce((acc: Record<string, { inbound: string[]; outbound: string[] }>, { source, target }) => {
|
|
16
|
-
if (!acc[source]) {
|
|
17
|
-
acc[source] = { inbound: [], outbound: [] };
|
|
18
|
-
}
|
|
19
|
-
if (!acc[target]) {
|
|
20
|
-
acc[target] = { inbound: [], outbound: [] };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const sourceEdges = acc[source];
|
|
24
|
-
if (!sourceEdges.outbound.includes(target)) {
|
|
25
|
-
sourceEdges.outbound.push(target);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const targetEdges = acc[target];
|
|
29
|
-
if (!targetEdges.inbound.includes(source)) {
|
|
30
|
-
targetEdges.inbound.push(source);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return acc;
|
|
34
|
-
}, {}),
|
|
35
|
-
),
|
|
36
|
-
);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
12
|
export type ActionGraphNodes = Node.NodeArg<any>[];
|
|
40
13
|
export type ActionGraphEdges = Graph.Edge[];
|
|
41
14
|
export type ActionGraphProps = {
|
|
@@ -51,24 +24,16 @@ export const useMenuActions = (props: Atom.Atom<ActionGraphProps>): MenuActions
|
|
|
51
24
|
const registry = useContext(RegistryContext);
|
|
52
25
|
const menuGraphProps = useAtomValue(props);
|
|
53
26
|
|
|
54
|
-
// Create graph
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
});
|
|
27
|
+
// Create a new graph whenever props change to preserve correct order.
|
|
28
|
+
// (Graph.addEdges appends rather than replaces, which breaks ordering on updates.)
|
|
29
|
+
const graphRef = useRef<{ graph: Graph.WritableGraph; props: ActionGraphProps } | null>(null);
|
|
30
|
+
if (!graphRef.current || graphRef.current.props !== menuGraphProps) {
|
|
31
|
+
const newGraph = Graph.make({ registry });
|
|
32
|
+
newGraph.pipe(Graph.addNodes(menuGraphProps.nodes as Node.NodeArg<any>[]), Graph.addEdges(menuGraphProps.edges));
|
|
33
|
+
graphRef.current = { graph: newGraph, props: menuGraphProps };
|
|
62
34
|
}
|
|
63
|
-
const graph = graphRef.current;
|
|
64
35
|
|
|
65
|
-
|
|
66
|
-
// Using a ref to track the previous value to detect changes.
|
|
67
|
-
const prevPropsRef = useRef(menuGraphProps);
|
|
68
|
-
if (prevPropsRef.current !== menuGraphProps) {
|
|
69
|
-
prevPropsRef.current = menuGraphProps;
|
|
70
|
-
graph.pipe(Graph.addNodes(menuGraphProps.nodes), Graph.addEdges(menuGraphProps.edges));
|
|
71
|
-
}
|
|
36
|
+
const graph = graphRef.current.graph;
|
|
72
37
|
|
|
73
38
|
const useGroupItems = useCallback(
|
|
74
39
|
(sourceNode?: MenuItemGroup) => {
|
package/src/types.ts
CHANGED
|
@@ -33,6 +33,8 @@ export type MenuContextValue = {
|
|
|
33
33
|
useGroupItems: MenuItemsResolver;
|
|
34
34
|
iconSize: IconButtonProps['size'];
|
|
35
35
|
attendableId?: string;
|
|
36
|
+
/** If true, the menu is always active regardless of attention state. */
|
|
37
|
+
alwaysActive?: boolean;
|
|
36
38
|
/** Optional action executor. If provided, will be used instead of default execution. */
|
|
37
39
|
onAction?: ActionExecutor;
|
|
38
40
|
};
|