@dxos/react-ui-menu 0.8.4-main.fd6878d → 0.8.4-main.fffef41
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 +59 -51
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +59 -51
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/builder.d.ts +2 -2
- package/dist/types/src/builder.d.ts.map +1 -1
- package/dist/types/src/components/MenuContext.d.ts +3 -1
- package/dist/types/src/components/MenuContext.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.d.ts +1 -1
- 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/hooks/useMenuActions.d.ts +3 -2
- 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 +2 -2
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -25
- package/src/builder.ts +10 -10
- package/src/components/MenuContext.tsx +6 -2
- package/src/components/{Menus.stories.tsx → ToolbarMenu.stories.tsx} +13 -9
- package/src/components/ToolbarMenu.tsx +38 -24
- package/src/hooks/useMenuActions.ts +12 -5
- package/src/index.ts +1 -1
- package/src/testing/generator.ts +2 -2
- package/src/util.ts +6 -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/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.fffef41",
|
|
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",
|
|
@@ -26,38 +26,38 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@preact-signals/safe-react": "^0.9.0",
|
|
29
|
-
"@preact/signals-react": "^3.
|
|
29
|
+
"@preact/signals-react": "^3.3.0",
|
|
30
30
|
"@radix-ui/react-context": "1.1.1",
|
|
31
31
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
32
|
-
"@dxos/app-graph": "0.8.4-main.
|
|
33
|
-
"@dxos/invariant": "0.8.4-main.
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/util": "0.8.4-main.
|
|
32
|
+
"@dxos/app-graph": "0.8.4-main.fffef41",
|
|
33
|
+
"@dxos/invariant": "0.8.4-main.fffef41",
|
|
34
|
+
"@dxos/react-ui-attention": "0.8.4-main.fffef41",
|
|
35
|
+
"@dxos/keyboard": "0.8.4-main.fffef41",
|
|
36
|
+
"@dxos/util": "0.8.4-main.fffef41"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@effect-
|
|
40
|
-
"@effect/platform": "0.
|
|
41
|
-
"@types/react": "~
|
|
42
|
-
"@types/react-dom": "~
|
|
43
|
-
"effect": "3.
|
|
44
|
-
"react": "~
|
|
45
|
-
"react-dom": "~
|
|
46
|
-
"vite": "
|
|
47
|
-
"@dxos/live-object": "0.8.4-main.
|
|
48
|
-
"@dxos/random": "0.8.4-main.
|
|
49
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
50
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
51
|
-
"@dxos/storybook-utils": "0.8.4-main.
|
|
39
|
+
"@effect-atom/atom-react": "^0.3.4",
|
|
40
|
+
"@effect/platform": "0.92.1",
|
|
41
|
+
"@types/react": "~19.2.2",
|
|
42
|
+
"@types/react-dom": "~19.2.2",
|
|
43
|
+
"effect": "3.18.3",
|
|
44
|
+
"react": "~19.2.0",
|
|
45
|
+
"react-dom": "~19.2.0",
|
|
46
|
+
"vite": "7.1.9",
|
|
47
|
+
"@dxos/live-object": "0.8.4-main.fffef41",
|
|
48
|
+
"@dxos/random": "0.8.4-main.fffef41",
|
|
49
|
+
"@dxos/react-ui": "0.8.4-main.fffef41",
|
|
50
|
+
"@dxos/react-ui-theme": "0.8.4-main.fffef41",
|
|
51
|
+
"@dxos/storybook-utils": "0.8.4-main.fffef41"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@effect-
|
|
54
|
+
"@effect-atom/atom-react": "^0.3.4",
|
|
55
55
|
"@effect/platform": "^0.80.12",
|
|
56
56
|
"effect": "^3.13.3",
|
|
57
|
-
"react": "
|
|
58
|
-
"react-dom": "
|
|
59
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
60
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
57
|
+
"react": "^19.0.0",
|
|
58
|
+
"react-dom": "^19.0.0",
|
|
59
|
+
"@dxos/react-ui": "0.8.4-main.fffef41",
|
|
60
|
+
"@dxos/react-ui-theme": "0.8.4-main.fffef41"
|
|
61
61
|
},
|
|
62
62
|
"publishConfig": {
|
|
63
63
|
"access": "public"
|
package/src/builder.ts
CHANGED
|
@@ -9,10 +9,10 @@ import type { MenuActionProperties, MenuItemGroupProperties } from './types';
|
|
|
9
9
|
import { createMenuAction, createMenuItemGroup } from './util';
|
|
10
10
|
|
|
11
11
|
export interface ActionGroupBuilder {
|
|
12
|
-
action<P extends {} = {}>(id: string,
|
|
12
|
+
action<P extends {} = {}>(id: string, props: P & MenuActionProperties, invoke: () => void): this;
|
|
13
13
|
group<P extends {} = {}>(
|
|
14
14
|
id: string,
|
|
15
|
-
|
|
15
|
+
props: P & MenuItemGroupProperties,
|
|
16
16
|
cb: (builder: ActionGroupBuilder) => void,
|
|
17
17
|
): this;
|
|
18
18
|
}
|
|
@@ -32,12 +32,6 @@ class MenuBuilderImpl implements MenuBuilder {
|
|
|
32
32
|
private readonly _rootId: string,
|
|
33
33
|
) {}
|
|
34
34
|
|
|
35
|
-
action<P extends {} = {}>(id: string, invoke: () => void, properties: P & MenuActionProperties): this {
|
|
36
|
-
this._data.nodes.push(createMenuAction(id, invoke, properties));
|
|
37
|
-
this._data.edges.push({ source: this._rootId, target: id });
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
35
|
root(props: MenuItemGroupProperties): this {
|
|
42
36
|
invariant(this._rootId === 'root', 'Root group can only be at the top level');
|
|
43
37
|
invariant(this._data.nodes.find((node) => node.id === 'root') === undefined, 'Root group can only be created once');
|
|
@@ -45,12 +39,18 @@ class MenuBuilderImpl implements MenuBuilder {
|
|
|
45
39
|
return this;
|
|
46
40
|
}
|
|
47
41
|
|
|
42
|
+
action<P extends {} = {}>(id: string, props: P & MenuActionProperties, invoke: () => void): this {
|
|
43
|
+
this._data.nodes.push(createMenuAction(id, invoke, props));
|
|
44
|
+
this._data.edges.push({ source: this._rootId, target: id });
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
48
|
group<P extends {} = {}>(
|
|
49
49
|
id: string,
|
|
50
|
-
|
|
50
|
+
props: P & MenuItemGroupProperties,
|
|
51
51
|
cb: (builder: ActionGroupBuilder) => void,
|
|
52
52
|
): this {
|
|
53
|
-
this._data.nodes.push(createMenuItemGroup(id,
|
|
53
|
+
this._data.nodes.push(createMenuItemGroup(id, props));
|
|
54
54
|
this._data.edges.push({ source: this._rootId, target: id });
|
|
55
55
|
cb(new MenuBuilderImpl(this._data, id));
|
|
56
56
|
return this;
|
|
@@ -9,7 +9,7 @@ import { type MenuContextValue, type MenuItem, type MenuItemGroup } from '../typ
|
|
|
9
9
|
|
|
10
10
|
export type MenuScopedProps<P> = P & { __menuScope?: Scope };
|
|
11
11
|
|
|
12
|
-
const MENU_NAME = '
|
|
12
|
+
const MENU_NAME = 'Menu';
|
|
13
13
|
|
|
14
14
|
const [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, []);
|
|
15
15
|
|
|
@@ -22,12 +22,14 @@ export const menuContextDefaults: MenuContextValue = {
|
|
|
22
22
|
|
|
23
23
|
const useMenuScope = createMenuScope();
|
|
24
24
|
|
|
25
|
+
type MenuProviderProps = PropsWithChildren<Partial<MenuContextValue>>;
|
|
26
|
+
|
|
25
27
|
const MenuProvider = ({
|
|
26
28
|
children,
|
|
27
29
|
useGroupItems = menuContextDefaults.useGroupItems,
|
|
28
30
|
iconSize = menuContextDefaults.iconSize,
|
|
29
31
|
attendableId,
|
|
30
|
-
}:
|
|
32
|
+
}: MenuProviderProps) => {
|
|
31
33
|
const { scope } = useMenuScope(undefined);
|
|
32
34
|
return (
|
|
33
35
|
<MenuContextProvider useGroupItems={useGroupItems} iconSize={iconSize} attendableId={attendableId} scope={scope}>
|
|
@@ -48,3 +50,5 @@ export const useMenuItems = (
|
|
|
48
50
|
};
|
|
49
51
|
|
|
50
52
|
export { useMenu, createMenuScope, MenuProvider };
|
|
53
|
+
|
|
54
|
+
export type { MenuProviderProps };
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
import React, { useCallback, useMemo } from 'react';
|
|
7
7
|
|
|
8
8
|
import { faker } from '@dxos/random';
|
|
9
9
|
import { IconButton } from '@dxos/react-ui';
|
|
10
|
-
import { withTheme } from '@dxos/
|
|
10
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
11
|
|
|
12
12
|
import { MenuProvider, DropdownMenu as NaturalDropdownMenu, ToolbarMenu } from '../components';
|
|
13
13
|
import { useMenuActions } from '../hooks';
|
|
@@ -17,16 +17,20 @@ import { type MenuAction } from '../types';
|
|
|
17
17
|
|
|
18
18
|
faker.seed(1234);
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
title: 'ui/react-ui-menu/
|
|
20
|
+
const meta = {
|
|
21
|
+
title: 'ui/react-ui-menu/ToolbarMenu',
|
|
22
22
|
component: ToolbarMenu,
|
|
23
23
|
decorators: [withTheme],
|
|
24
24
|
parameters: {
|
|
25
25
|
translations,
|
|
26
26
|
},
|
|
27
|
-
}
|
|
27
|
+
} satisfies Meta<typeof ToolbarMenu>;
|
|
28
|
+
|
|
29
|
+
export default meta;
|
|
30
|
+
|
|
31
|
+
type Story = StoryObj<typeof meta>;
|
|
28
32
|
|
|
29
|
-
export const DropdownMenu = {
|
|
33
|
+
export const DropdownMenu: Story = {
|
|
30
34
|
render: () => {
|
|
31
35
|
const menuActions = useMemo(() => createActions() as MenuAction[], []);
|
|
32
36
|
const resolveGroupItems = useCallback(() => menuActions, [menuActions]);
|
|
@@ -36,7 +40,7 @@ export const DropdownMenu = {
|
|
|
36
40
|
<MenuProvider useGroupItems={resolveGroupItems}>
|
|
37
41
|
<NaturalDropdownMenu.Root>
|
|
38
42
|
<NaturalDropdownMenu.Trigger asChild>
|
|
39
|
-
<IconButton icon='ph--list-checks--regular'
|
|
43
|
+
<IconButton icon='ph--list-checks--regular' label='Options' />
|
|
40
44
|
</NaturalDropdownMenu.Trigger>
|
|
41
45
|
</NaturalDropdownMenu.Root>
|
|
42
46
|
</MenuProvider>
|
|
@@ -44,7 +48,7 @@ export const DropdownMenu = {
|
|
|
44
48
|
},
|
|
45
49
|
};
|
|
46
50
|
|
|
47
|
-
export const Toolbar = {
|
|
51
|
+
export const Toolbar: Story = {
|
|
48
52
|
render: () => {
|
|
49
53
|
const nestedMenuActions = useMemo(() => createNestedActionsResolver(), []);
|
|
50
54
|
|
|
@@ -56,7 +60,7 @@ export const Toolbar = {
|
|
|
56
60
|
},
|
|
57
61
|
};
|
|
58
62
|
|
|
59
|
-
export const UseMenuActionsToolbar = {
|
|
63
|
+
export const UseMenuActionsToolbar: Story = {
|
|
60
64
|
render: () => {
|
|
61
65
|
const menu = useMenuActions(createNestedActions);
|
|
62
66
|
|
|
@@ -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, toolbarLayout } from '@dxos/react-ui-theme';
|
|
9
|
+
import { mx, textBlockWidth, toolbarInactive, toolbarLayout } from '@dxos/react-ui-theme';
|
|
10
10
|
|
|
11
11
|
import { translationKey } from '../translations';
|
|
12
12
|
import {
|
|
@@ -55,12 +55,15 @@ export type ToolbarMenuActionProps = {
|
|
|
55
55
|
const ActionToolbarItem = ({ action, __menuScope }: MenuScopedProps<{ action: MenuAction }>) => {
|
|
56
56
|
const { iconSize } = useMenu('ActionToolbarItem', __menuScope);
|
|
57
57
|
const { t } = useTranslation(translationKey);
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
const { icon, iconOnly = true, disabled, testId, hidden, classNames } = action.properties;
|
|
60
60
|
const Root = icon ? NaturalToolbar.IconButton : NaturalToolbar.Button;
|
|
61
61
|
const rootProps = icon
|
|
62
62
|
? { icon, size: iconSize, iconOnly, label: actionLabel(action, t) }
|
|
63
63
|
: { children: <ActionLabel action={action} /> };
|
|
64
|
+
|
|
65
|
+
const handleClick = useCallback(() => action.data?.(), [action]);
|
|
66
|
+
|
|
64
67
|
return hidden ? null : (
|
|
65
68
|
<Root
|
|
66
69
|
key={action.id}
|
|
@@ -101,6 +104,7 @@ const DropdownMenuToolbarItem = ({
|
|
|
101
104
|
</>
|
|
102
105
|
),
|
|
103
106
|
};
|
|
107
|
+
|
|
104
108
|
return (
|
|
105
109
|
<DropdownMenu.Root group={group} items={items}>
|
|
106
110
|
<DropdownMenu.Trigger asChild>
|
|
@@ -119,6 +123,7 @@ const ToggleGroupItem = ({ group, action, __menuScope }: MenuScopedProps<Toolbar
|
|
|
119
123
|
const rootProps = icon
|
|
120
124
|
? { icon, size: iconSize, iconOnly, label: actionLabel(action, t) }
|
|
121
125
|
: { children: <ActionLabel action={action} /> };
|
|
126
|
+
|
|
122
127
|
return hidden ? null : (
|
|
123
128
|
<Root
|
|
124
129
|
key={action.id}
|
|
@@ -140,8 +145,9 @@ const ToggleGroupToolbarItem = ({
|
|
|
140
145
|
}: MenuScopedProps<ToolbarMenuActionGroupProps>) => {
|
|
141
146
|
const items = useMenuItems(group, propsItems, 'ToggleGroupToolbarItem', __menuScope);
|
|
142
147
|
const { selectCardinality, value } = group.properties;
|
|
148
|
+
|
|
143
149
|
return (
|
|
144
|
-
// TODO(thure):
|
|
150
|
+
// TODO(thure): Fix.
|
|
145
151
|
// @ts-ignore
|
|
146
152
|
<NaturalToolbar.ToggleGroup type={selectCardinality} value={value}>
|
|
147
153
|
{
|
|
@@ -154,41 +160,49 @@ const ToggleGroupToolbarItem = ({
|
|
|
154
160
|
);
|
|
155
161
|
};
|
|
156
162
|
|
|
163
|
+
// TODO(burdon): Reconcile with react-ui/Toolbar (incl. textBlockWidth)
|
|
157
164
|
export const ToolbarMenu = ({
|
|
158
165
|
__menuScope,
|
|
159
166
|
classNames,
|
|
160
|
-
textBlockWidth:
|
|
167
|
+
textBlockWidth: textBlockWidthParam,
|
|
161
168
|
...props
|
|
162
169
|
}: MenuScopedProps<ToolbarMenuProps>) => {
|
|
163
170
|
const items = useMenuItems(undefined, undefined, 'ToolbarMenu', __menuScope);
|
|
164
171
|
const { attendableId } = useMenu('ToolbarMenu', __menuScope);
|
|
165
172
|
const { hasAttention } = useAttention(attendableId);
|
|
166
|
-
const InnerRoot =
|
|
167
|
-
const innerRootProps =
|
|
173
|
+
const InnerRoot = textBlockWidthParam ? 'div' : Fragment;
|
|
174
|
+
const innerRootProps = textBlockWidthParam
|
|
175
|
+
? { role: 'none', className: mx(textBlockWidth, toolbarLayout, 'bs-full') }
|
|
176
|
+
: {};
|
|
177
|
+
|
|
168
178
|
return (
|
|
169
179
|
<NaturalToolbar.Root
|
|
170
180
|
{...props}
|
|
171
|
-
|
|
172
|
-
|
|
181
|
+
classNames={[attendableId && !hasAttention && toolbarInactive, classNames]}
|
|
182
|
+
layoutManaged={textBlockWidthParam}
|
|
173
183
|
>
|
|
174
184
|
<InnerRoot {...innerRootProps}>
|
|
175
|
-
{items?.map((item: MenuItem, i: number) =>
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
) : isMenuGroup(item) ? (
|
|
179
|
-
item.properties.variant === 'dropdownMenu' ? (
|
|
180
|
-
// TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
|
|
181
|
-
<DropdownMenuToolbarItem key={item.id} group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />
|
|
182
|
-
) : (
|
|
183
|
-
// TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
|
|
184
|
-
<ToggleGroupToolbarItem key={item.id} group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />
|
|
185
|
-
)
|
|
186
|
-
) : (
|
|
187
|
-
// TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
|
|
188
|
-
<ActionToolbarItem key={item.id} action={item as MenuAction} />
|
|
189
|
-
),
|
|
190
|
-
)}
|
|
185
|
+
{items?.map((item: MenuItem, i: number) => (
|
|
186
|
+
<ToolbarMenuItem key={item.id ?? i} item={item} />
|
|
187
|
+
))}
|
|
191
188
|
</InnerRoot>
|
|
192
189
|
</NaturalToolbar.Root>
|
|
193
190
|
);
|
|
194
191
|
};
|
|
192
|
+
|
|
193
|
+
const ToolbarMenuItem = ({ item }: { item: MenuItem }) => {
|
|
194
|
+
if (isSeparator(item)) {
|
|
195
|
+
return <NaturalToolbar.Separator variant={item.properties.variant} />;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// TODO(thure): Figure out type narrowing that doesn’t require so much use of `as`.
|
|
199
|
+
if (isMenuGroup(item)) {
|
|
200
|
+
if (item.properties.variant === 'dropdownMenu') {
|
|
201
|
+
return <DropdownMenuToolbarItem group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />;
|
|
202
|
+
} else {
|
|
203
|
+
return <ToggleGroupToolbarItem group={item as MenuItemGroup<ToolbarMenuActionGroupProperties>} />;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return <ActionToolbarItem action={item as MenuAction} />;
|
|
208
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type Atom, RegistryContext, useAtomValue } from '@effect-atom/atom-react';
|
|
6
6
|
import { useCallback, useContext, useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { type Edge, type Edges, Graph, type Node, type NodeArg, ROOT_ID } from '@dxos/app-graph';
|
|
@@ -38,11 +38,18 @@ const edgesArrayToRecord = (edges: Edge[]): Record<string, Edges> => {
|
|
|
38
38
|
|
|
39
39
|
export type ActionGraphNodes = NodeArg<any>[];
|
|
40
40
|
export type ActionGraphEdges = Edge[];
|
|
41
|
-
export type ActionGraphProps = {
|
|
41
|
+
export type ActionGraphProps = {
|
|
42
|
+
nodes: ActionGraphNodes;
|
|
43
|
+
edges: ActionGraphEdges;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type MenuActions = {
|
|
47
|
+
useGroupItems: (sourceNode?: MenuItemGroup) => MenuItem[];
|
|
48
|
+
};
|
|
42
49
|
|
|
43
|
-
export const useMenuActions = (props:
|
|
50
|
+
export const useMenuActions = (props: Atom.Atom<ActionGraphProps>): MenuActions => {
|
|
44
51
|
const registry = useContext(RegistryContext);
|
|
45
|
-
const menuGraphProps =
|
|
52
|
+
const menuGraphProps = useAtomValue(props);
|
|
46
53
|
|
|
47
54
|
const [graph] = useState(
|
|
48
55
|
new Graph({
|
|
@@ -59,7 +66,7 @@ export const useMenuActions = (props: Rx.Rx<ActionGraphProps>) => {
|
|
|
59
66
|
|
|
60
67
|
const useGroupItems = useCallback(
|
|
61
68
|
(sourceNode?: MenuItemGroup) => {
|
|
62
|
-
const items =
|
|
69
|
+
const items = useAtomValue(graph.connections(sourceNode?.id || ROOT_ID)) as MenuItem[];
|
|
63
70
|
return items;
|
|
64
71
|
},
|
|
65
72
|
[graph],
|
package/src/index.ts
CHANGED
package/src/testing/generator.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Atom } from '@effect-atom/atom-react';
|
|
6
6
|
import { useEffect } from 'react';
|
|
7
7
|
|
|
8
8
|
import {
|
|
@@ -66,7 +66,7 @@ export const createActions = (params?: CreateActionsParams) => {
|
|
|
66
66
|
);
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
export const createNestedActions =
|
|
69
|
+
export const createNestedActions = Atom.make(() => {
|
|
70
70
|
const result: ActionGraphProps = { edges: [], nodes: [] };
|
|
71
71
|
const actionGroups = createActions({ type: ACTION_GROUP_TYPE });
|
|
72
72
|
actionGroups.forEach((group) => {
|
package/src/util.ts
CHANGED
|
@@ -55,7 +55,12 @@ export const createGapSeparator = (id: string = 'gap', source: string = 'root')
|
|
|
55
55
|
data: undefined as never,
|
|
56
56
|
} satisfies MenuSeparator,
|
|
57
57
|
],
|
|
58
|
-
edges: [
|
|
58
|
+
edges: [
|
|
59
|
+
{
|
|
60
|
+
source,
|
|
61
|
+
target: id,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
59
64
|
});
|
|
60
65
|
|
|
61
66
|
export const createLineSeparator = (id: string = 'line', source: string = 'root') => ({
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import '@dxos-theme';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
declare const _default: {
|
|
4
|
-
title: string;
|
|
5
|
-
component: ({ __menuScope, classNames, textBlockWidth: wrapContents, ...props }: import("./MenuContext").MenuScopedProps<import("./ToolbarMenu").ToolbarMenuProps>) => React.JSX.Element;
|
|
6
|
-
decorators: import("@storybook/react").Decorator[];
|
|
7
|
-
parameters: {
|
|
8
|
-
translations: [{
|
|
9
|
-
readonly 'en-US': {
|
|
10
|
-
readonly "react-ui-menu": {};
|
|
11
|
-
};
|
|
12
|
-
}];
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
export default _default;
|
|
16
|
-
export declare const DropdownMenu: {
|
|
17
|
-
render: () => React.JSX.Element;
|
|
18
|
-
};
|
|
19
|
-
export declare const Toolbar: {
|
|
20
|
-
render: () => React.JSX.Element;
|
|
21
|
-
};
|
|
22
|
-
export declare const UseMenuActionsToolbar: {
|
|
23
|
-
render: () => React.JSX.Element;
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=Menus.stories.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Menus.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/Menus.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AACrB,OAAO,KAA+B,MAAM,OAAO,CAAC;;;;;;;;;;;;;AAcpD,wBAOE;AAEF,eAAO,MAAM,YAAY;;CAgBxB,CAAC;AAEF,eAAO,MAAM,OAAO;;CAUnB,CAAC;AAEF,eAAO,MAAM,qBAAqB;;CAUjC,CAAC"}
|