@dxos/react-ui-menu 0.8.4-main.ead640a → 0.8.4-main.ef1bc66f44
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 +298 -355
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +298 -355
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/builder.d.ts +1 -1
- package/dist/types/src/builder.d.ts.map +1 -1
- package/dist/types/src/components/ActionLabel.d.ts +3 -3
- package/dist/types/src/components/ActionLabel.d.ts.map +1 -1
- package/dist/types/src/components/DropdownMenu.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 +3 -2
- package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
- package/dist/types/src/components/ToolbarMenu.stories.d.ts +2 -2
- package/dist/types/src/components/ToolbarMenu.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useMenuActions.d.ts +5 -5
- package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +13 -11
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +13 -24
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +12 -5
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -28
- package/src/builder.ts +1 -1
- package/src/components/ActionLabel.tsx +4 -4
- package/src/components/DropdownMenu.tsx +10 -3
- package/src/components/MenuContext.tsx +17 -3
- package/src/components/ToolbarMenu.stories.tsx +17 -9
- package/src/components/ToolbarMenu.tsx +38 -13
- package/src/hooks/useMenuActions.ts +20 -47
- package/src/index.ts +0 -2
- package/src/testing/generator.ts +63 -58
- package/src/translations.ts +1 -1
- package/src/types.ts +14 -26
- package/src/util.ts +32 -14
package/src/types.ts
CHANGED
|
@@ -2,51 +2,39 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import { type
|
|
7
|
-
|
|
8
|
-
export type MenuActionProperties = {
|
|
9
|
-
label: Label;
|
|
10
|
-
icon?: string;
|
|
11
|
-
value?: string;
|
|
12
|
-
disabled?: boolean;
|
|
13
|
-
hidden?: boolean;
|
|
14
|
-
iconOnly?: boolean;
|
|
15
|
-
testId?: string;
|
|
16
|
-
variant?: 'action' | 'toggle';
|
|
17
|
-
checked?: boolean;
|
|
18
|
-
classNames?: ClassNameValue;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type MenuItemGroupProperties = {
|
|
22
|
-
label: Label;
|
|
23
|
-
icon?: string;
|
|
24
|
-
iconOnly?: boolean;
|
|
25
|
-
};
|
|
5
|
+
import { Node } from '@dxos/app-graph';
|
|
6
|
+
import { type IconButtonProps, type ToolbarSeparatorProps } from '@dxos/react-ui';
|
|
7
|
+
import { type MenuActionProperties } from '@dxos/ui-types';
|
|
26
8
|
|
|
27
|
-
export type MenuAction<P extends {} = {}> = Action<P & MenuActionProperties>;
|
|
9
|
+
export type MenuAction<P extends {} = {}> = Node.Action<P & MenuActionProperties>;
|
|
28
10
|
|
|
29
11
|
export const MenuSeparatorType = '@dxos/react-ui-toolbar/separator' as const;
|
|
30
12
|
|
|
31
|
-
export type MenuSeparator = Node<never, Pick<ToolbarSeparatorProps, 'variant'>> & {
|
|
13
|
+
export type MenuSeparator = Node.Node<never, Pick<ToolbarSeparatorProps, 'variant'>> & {
|
|
32
14
|
type: typeof MenuSeparatorType;
|
|
33
15
|
};
|
|
34
16
|
|
|
35
|
-
export const isSeparator = (node: Node): node is MenuSeparator => node.type === MenuSeparatorType;
|
|
17
|
+
export const isSeparator = (node: Node.Node): node is MenuSeparator => node.type === MenuSeparatorType;
|
|
36
18
|
|
|
37
19
|
export type MenuSingleSelectActionGroup = { selectCardinality: 'single'; value: string };
|
|
38
20
|
export type MenuMultipleSelectActionGroup = { selectCardinality: 'multiple'; value: string[] };
|
|
39
21
|
|
|
40
|
-
export type MenuItemGroup<P extends Record<string, any> = Record<string, any>> = ActionGroup<P>;
|
|
22
|
+
export type MenuItemGroup<P extends Record<string, any> = Record<string, any>> = Node.ActionGroup<P>;
|
|
41
23
|
|
|
42
|
-
export const isMenuGroup = (node: Node): node is MenuItemGroup => node.type ===
|
|
24
|
+
export const isMenuGroup = (node: Node.Node): node is MenuItemGroup => node.type === Node.ActionGroupType;
|
|
43
25
|
|
|
44
26
|
export type MenuItem = MenuSeparator | MenuAction | MenuItemGroup;
|
|
45
27
|
|
|
46
28
|
export type MenuItemsResolver = (group?: MenuItemGroup) => MenuItem[] | null;
|
|
47
29
|
|
|
30
|
+
export type ActionExecutor = (action: MenuAction, params: Node.InvokeProps) => void;
|
|
31
|
+
|
|
48
32
|
export type MenuContextValue = {
|
|
49
33
|
useGroupItems: MenuItemsResolver;
|
|
50
34
|
iconSize: IconButtonProps['size'];
|
|
51
35
|
attendableId?: string;
|
|
36
|
+
/** If true, the menu is always active regardless of attention state. */
|
|
37
|
+
alwaysActive?: boolean;
|
|
38
|
+
/** Optional action executor. If provided, will be used instead of default execution. */
|
|
39
|
+
onAction?: ActionExecutor;
|
|
52
40
|
};
|
package/src/util.ts
CHANGED
|
@@ -2,18 +2,31 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Node } from '@dxos/app-graph';
|
|
8
|
+
import { runAndForwardErrors } from '@dxos/effect';
|
|
9
|
+
import { type MenuActionProperties, type MenuItemGroupProperties } from '@dxos/ui-types';
|
|
6
10
|
import { getHostPlatform } from '@dxos/util';
|
|
7
11
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
12
|
+
import { type MenuAction, type MenuItemGroup, type MenuSeparator } from './types';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Execute a menu action's Effect with its captured context.
|
|
16
|
+
* This provides the `_actionContext` layer if available.
|
|
17
|
+
*/
|
|
18
|
+
export const executeMenuAction = async (action: MenuAction, params: Node.InvokeProps = {}): Promise<void> => {
|
|
19
|
+
let effect = action.data(params);
|
|
20
|
+
|
|
21
|
+
// Provide captured action context if available.
|
|
22
|
+
if (action._actionContext) {
|
|
23
|
+
effect = effect.pipe(Effect.provide(action._actionContext));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
await runAndForwardErrors(effect);
|
|
27
|
+
};
|
|
15
28
|
|
|
16
|
-
export const getShortcut = (action: ActionLike) => {
|
|
29
|
+
export const getShortcut = (action: Node.ActionLike) => {
|
|
17
30
|
return typeof action.properties?.keyBinding === 'string'
|
|
18
31
|
? action.properties.keyBinding
|
|
19
32
|
: action.properties?.keyBinding?.[getHostPlatform()];
|
|
@@ -28,9 +41,9 @@ export const createMenuAction = <P extends {} = {}>(
|
|
|
28
41
|
) =>
|
|
29
42
|
({
|
|
30
43
|
id,
|
|
31
|
-
type:
|
|
44
|
+
type: Node.ActionType,
|
|
32
45
|
properties,
|
|
33
|
-
data: invoke,
|
|
46
|
+
data: () => Effect.sync(invoke),
|
|
34
47
|
}) satisfies MenuAction;
|
|
35
48
|
|
|
36
49
|
export const createMenuItemGroup = <
|
|
@@ -41,9 +54,9 @@ export const createMenuItemGroup = <
|
|
|
41
54
|
) =>
|
|
42
55
|
({
|
|
43
56
|
id,
|
|
44
|
-
type:
|
|
57
|
+
type: Node.ActionGroupType,
|
|
45
58
|
properties,
|
|
46
|
-
data: actionGroupSymbol,
|
|
59
|
+
data: Node.actionGroupSymbol,
|
|
47
60
|
}) satisfies MenuItemGroup;
|
|
48
61
|
|
|
49
62
|
export const createGapSeparator = (id: string = 'gap', source: string = 'root') => ({
|
|
@@ -55,7 +68,12 @@ export const createGapSeparator = (id: string = 'gap', source: string = 'root')
|
|
|
55
68
|
data: undefined as never,
|
|
56
69
|
} satisfies MenuSeparator,
|
|
57
70
|
],
|
|
58
|
-
edges: [
|
|
71
|
+
edges: [
|
|
72
|
+
{
|
|
73
|
+
source,
|
|
74
|
+
target: id,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
59
77
|
});
|
|
60
78
|
|
|
61
79
|
export const createLineSeparator = (id: string = 'line', source: string = 'root') => ({
|