@dxos/react-ui-menu 0.8.3-staging.0fa589b → 0.8.4-main.28f8d3d

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.
Files changed (45) hide show
  1. package/dist/lib/browser/index.mjs +79 -18
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +79 -18
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/builder.d.ts +14 -0
  8. package/dist/types/src/builder.d.ts.map +1 -0
  9. package/dist/types/src/components/ActionLabel.d.ts +1 -1
  10. package/dist/types/src/components/ActionLabel.d.ts.map +1 -1
  11. package/dist/types/src/components/DropdownMenu.d.ts +1 -1
  12. package/dist/types/src/components/DropdownMenu.d.ts.map +1 -1
  13. package/dist/types/src/components/MenuContext.d.ts.map +1 -1
  14. package/dist/types/src/components/Menus.stories.d.ts +2 -2
  15. package/dist/types/src/components/Menus.stories.d.ts.map +1 -1
  16. package/dist/types/src/components/ToolbarMenu.d.ts +1 -1
  17. package/dist/types/src/components/ToolbarMenu.d.ts.map +1 -1
  18. package/dist/types/src/hooks/useMenuActions.d.ts.map +1 -1
  19. package/dist/types/src/index.d.ts +1 -0
  20. package/dist/types/src/index.d.ts.map +1 -1
  21. package/dist/types/src/testing/generator.d.ts +2 -2
  22. package/dist/types/src/testing/generator.d.ts.map +1 -1
  23. package/dist/types/src/translations.d.ts +3 -4
  24. package/dist/types/src/translations.d.ts.map +1 -1
  25. package/dist/types/src/types.d.ts +2 -2
  26. package/dist/types/src/types.d.ts.map +1 -1
  27. package/dist/types/src/util.d.ts +1 -1
  28. package/dist/types/src/util.d.ts.map +1 -1
  29. package/dist/types/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +18 -16
  31. package/src/builder.ts +62 -0
  32. package/src/components/ActionLabel.tsx +4 -5
  33. package/src/components/DropdownMenu.tsx +6 -3
  34. package/src/components/MenuContext.tsx +1 -1
  35. package/src/components/Menus.stories.tsx +7 -5
  36. package/src/components/ToolbarMenu.tsx +8 -7
  37. package/src/hooks/useMenuActions.ts +1 -1
  38. package/src/index.ts +1 -0
  39. package/src/testing/generator.ts +4 -4
  40. package/src/translations.ts +5 -3
  41. package/src/types.ts +2 -2
  42. package/src/util.ts +1 -1
  43. package/dist/lib/node/index.cjs +0 -506
  44. package/dist/lib/node/index.cjs.map +0 -7
  45. package/dist/lib/node/meta.json +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-menu",
3
- "version": "0.8.3-staging.0fa589b",
3
+ "version": "0.8.4-main.28f8d3d",
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",
@@ -10,6 +10,7 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs",
15
16
  "node": "./dist/lib/node-esm/index.mjs"
@@ -28,34 +29,35 @@
28
29
  "@preact/signals-react": "^3.2.0",
29
30
  "@radix-ui/react-context": "1.1.1",
30
31
  "@radix-ui/react-use-controllable-state": "1.1.0",
31
- "@dxos/app-graph": "0.8.3-staging.0fa589b",
32
- "@dxos/react-ui-attention": "0.8.3-staging.0fa589b",
33
- "@dxos/util": "0.8.3-staging.0fa589b",
34
- "@dxos/keyboard": "0.8.3-staging.0fa589b"
32
+ "@dxos/app-graph": "0.8.4-main.28f8d3d",
33
+ "@dxos/invariant": "0.8.4-main.28f8d3d",
34
+ "@dxos/react-ui-attention": "0.8.4-main.28f8d3d",
35
+ "@dxos/keyboard": "0.8.4-main.28f8d3d",
36
+ "@dxos/util": "0.8.4-main.28f8d3d"
35
37
  },
36
38
  "devDependencies": {
37
- "@effect-rx/rx-react": "^0.34.1",
38
- "@effect/platform": "0.80.12",
39
+ "@effect-rx/rx-react": "0.38.0",
40
+ "@effect/platform": "0.90.2",
39
41
  "@types/react": "~18.2.0",
40
42
  "@types/react-dom": "~18.2.0",
41
- "effect": "3.14.21",
43
+ "effect": "3.17.7",
42
44
  "react": "~18.2.0",
43
45
  "react-dom": "~18.2.0",
44
46
  "vite": "5.4.7",
45
- "@dxos/live-object": "0.8.3-staging.0fa589b",
46
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
47
- "@dxos/storybook-utils": "0.8.3-staging.0fa589b",
48
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b",
49
- "@dxos/random": "0.8.3-staging.0fa589b"
47
+ "@dxos/live-object": "0.8.4-main.28f8d3d",
48
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
49
+ "@dxos/random": "0.8.4-main.28f8d3d",
50
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d",
51
+ "@dxos/storybook-utils": "0.8.4-main.28f8d3d"
50
52
  },
51
53
  "peerDependencies": {
52
54
  "@effect-rx/rx-react": "^0.34.1",
53
- "@effect/platform": "0.80.12",
55
+ "@effect/platform": "^0.80.12",
54
56
  "effect": "^3.13.3",
55
57
  "react": "~18.2.0",
56
58
  "react-dom": "~18.2.0",
57
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b",
58
- "@dxos/react-ui": "0.8.3-staging.0fa589b"
59
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
60
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d"
59
61
  },
60
62
  "publishConfig": {
61
63
  "access": "public"
package/src/builder.ts ADDED
@@ -0,0 +1,62 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { invariant } from '@dxos/invariant';
6
+
7
+ import type { ActionGraphProps } from './hooks';
8
+ import type { MenuActionProperties, MenuItemGroupProperties } from './types';
9
+ import { createMenuAction, createMenuItemGroup } from './util';
10
+
11
+ export interface ActionGroupBuilder {
12
+ action<P extends {} = {}>(id: string, invoke: () => void, properties: P & MenuActionProperties): this;
13
+ group<P extends {} = {}>(
14
+ id: string,
15
+ properties: P & MenuItemGroupProperties,
16
+ cb: (builder: ActionGroupBuilder) => void,
17
+ ): this;
18
+ }
19
+
20
+ export interface MenuBuilder extends ActionGroupBuilder {
21
+ root(props: MenuItemGroupProperties): this;
22
+ build(): ActionGraphProps;
23
+ }
24
+
25
+ export const MenuBuilder = Object.freeze({
26
+ make: (): MenuBuilder => new MenuBuilderImpl({ nodes: [], edges: [] }, 'root'),
27
+ });
28
+
29
+ class MenuBuilderImpl implements MenuBuilder {
30
+ constructor(
31
+ private readonly _data: ActionGraphProps,
32
+ private readonly _rootId: string,
33
+ ) {}
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
+ root(props: MenuItemGroupProperties): this {
42
+ invariant(this._rootId === 'root', 'Root group can only be at the top level');
43
+ invariant(this._data.nodes.find((node) => node.id === 'root') === undefined, 'Root group can only be created once');
44
+ this._data.nodes.push(createMenuItemGroup('root', props));
45
+ return this;
46
+ }
47
+
48
+ group<P extends {} = {}>(
49
+ id: string,
50
+ properties: P & MenuItemGroupProperties,
51
+ cb: (builder: ActionGroupBuilder) => void,
52
+ ): this {
53
+ this._data.nodes.push(createMenuItemGroup(id, properties));
54
+ this._data.edges.push({ source: this._rootId, target: id });
55
+ cb(new MenuBuilderImpl(this._data, id));
56
+ return this;
57
+ }
58
+
59
+ build(): ActionGraphProps {
60
+ return this._data;
61
+ }
62
+ }
@@ -4,10 +4,10 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { type Action as GraphAction, type ActionGroup } from '@dxos/app-graph';
7
+ import { type ActionGroup, type Action as GraphAction } from '@dxos/app-graph';
8
8
  import { keySymbols } from '@dxos/keyboard';
9
- import { toLocalizedString, useTranslation, type TFunction } from '@dxos/react-ui';
10
- import { mx, descriptionText } from '@dxos/react-ui-theme';
9
+ import { type TFunction, toLocalizedString, useTranslation } from '@dxos/react-ui';
10
+ import { descriptionText, mx } from '@dxos/react-ui-theme';
11
11
 
12
12
  import { translationKey } from '../translations';
13
13
  import { type MenuActionProperties } from '../types';
@@ -16,9 +16,8 @@ import { getShortcut } from '../util';
16
16
  type Action = GraphAction<MenuActionProperties> | ActionGroup<Omit<MenuActionProperties, 'variant'>>;
17
17
 
18
18
  export const ActionLabel = ({ action }: { action: Action }) => {
19
- const shortcut = getShortcut(action);
20
19
  const { t } = useTranslation(translationKey);
21
-
20
+ const shortcut = getShortcut(action);
22
21
  return (
23
22
  <>
24
23
  <span className='grow truncate'>{toLocalizedString(action.properties!.label, t)}</span>
@@ -5,11 +5,12 @@
5
5
  import { useControllableState } from '@radix-ui/react-use-controllable-state';
6
6
  import React, { type MouseEvent, useCallback } from 'react';
7
7
 
8
- import { DropdownMenu as NaturalDropdownMenu, Icon, type DropdownMenuRootProps } from '@dxos/react-ui';
8
+ import { type DropdownMenuRootProps, Icon, DropdownMenu as NaturalDropdownMenu } from '@dxos/react-ui';
9
+
10
+ import { type MenuAction, type MenuItem, type MenuItemGroup } from '../types';
9
11
 
10
12
  import { ActionLabel } from './ActionLabel';
11
13
  import { type MenuScopedProps, useMenu, useMenuItems } from './MenuContext';
12
- import { type MenuAction, type MenuItem, type MenuItemGroup } from '../types';
13
14
 
14
15
  export type DropdownMenuProps = DropdownMenuRootProps & {
15
16
  group?: MenuItemGroup;
@@ -80,7 +81,9 @@ const DropdownMenuRoot = ({
80
81
  <NaturalDropdownMenu.Portal>
81
82
  <NaturalDropdownMenu.Content>
82
83
  <NaturalDropdownMenu.Viewport>
83
- {items?.map((item) => <DropdownMenuItem key={item.id} item={item} onClick={handleActionClick} />)}
84
+ {items?.map((item) => (
85
+ <DropdownMenuItem key={item.id} item={item} onClick={handleActionClick} />
86
+ ))}
84
87
  </NaturalDropdownMenu.Viewport>
85
88
  <NaturalDropdownMenu.Arrow />
86
89
  </NaturalDropdownMenu.Content>
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { createContextScope, type Scope } from '@radix-ui/react-context';
5
+ import { type Scope, createContextScope } from '@radix-ui/react-context';
6
6
  import React, { type PropsWithChildren, useMemo } from 'react';
7
7
 
8
8
  import { type MenuContextValue, type MenuItem, type MenuItemGroup } from '../types';
@@ -7,12 +7,12 @@ 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 { withLayout, withSignals, withTheme } from '@dxos/storybook-utils';
10
+ import { withTheme } from '@dxos/storybook-utils';
11
11
 
12
- import { DropdownMenu as NaturalDropdownMenu, ToolbarMenu, MenuProvider } from '../components';
12
+ import { MenuProvider, DropdownMenu as NaturalDropdownMenu, ToolbarMenu } from '../components';
13
13
  import { useMenuActions } from '../hooks';
14
14
  import { createActions, createNestedActions, createNestedActionsResolver, useMutateActions } from '../testing';
15
- import translations from '../translations';
15
+ import { translations } from '../translations';
16
16
  import { type MenuAction } from '../types';
17
17
 
18
18
  faker.seed(1234);
@@ -20,8 +20,10 @@ faker.seed(1234);
20
20
  export default {
21
21
  title: 'ui/react-ui-menu/Menus',
22
22
  component: ToolbarMenu,
23
- decorators: [withTheme, withLayout(), withSignals],
24
- parameters: { translations },
23
+ decorators: [withTheme],
24
+ parameters: {
25
+ translations,
26
+ },
25
27
  };
26
28
 
27
29
  export const DropdownMenu = {
@@ -8,21 +8,22 @@ import { Icon, Toolbar as NaturalToolbar, type ToolbarRootProps, useTranslation
8
8
  import { useAttention } from '@dxos/react-ui-attention';
9
9
  import { mx, textBlockWidth, toolbarLayout } from '@dxos/react-ui-theme';
10
10
 
11
- import { actionLabel, ActionLabel } from './ActionLabel';
12
- import { DropdownMenu } from './DropdownMenu';
13
- import { type MenuScopedProps, useMenu, useMenuItems } from './MenuContext';
14
11
  import { translationKey } from '../translations';
15
12
  import {
16
13
  type MenuAction,
14
+ type MenuActionProperties,
17
15
  type MenuItem,
18
- isMenuGroup,
19
- isSeparator,
20
16
  type MenuItemGroup,
21
- type MenuActionProperties,
22
17
  type MenuMultipleSelectActionGroup,
23
18
  type MenuSingleSelectActionGroup,
19
+ isMenuGroup,
20
+ isSeparator,
24
21
  } from '../types';
25
22
 
23
+ import { ActionLabel, actionLabel } from './ActionLabel';
24
+ import { DropdownMenu } from './DropdownMenu';
25
+ import { type MenuScopedProps, useMenu, useMenuItems } from './MenuContext';
26
+
26
27
  export type ToolbarMenuDropdownMenuActionGroup = Omit<MenuActionProperties, 'variant' | 'icon'> & {
27
28
  variant: 'dropdownMenu';
28
29
  icon: string;
@@ -163,7 +164,7 @@ export const ToolbarMenu = ({
163
164
  const { attendableId } = useMenu('ToolbarMenu', __menuScope);
164
165
  const { hasAttention } = useAttention(attendableId);
165
166
  const InnerRoot = wrapContents ? 'div' : Fragment;
166
- const innerRootProps = wrapContents ? { role: 'none', className: mx(textBlockWidth, toolbarLayout) } : {};
167
+ const innerRootProps = wrapContents ? { role: 'none', className: mx(textBlockWidth, toolbarLayout, 'bs-full') } : {};
167
168
  return (
168
169
  <NaturalToolbar.Root
169
170
  {...props}
@@ -5,7 +5,7 @@
5
5
  import { RegistryContext, type Rx, useRxValue } from '@effect-rx/rx-react';
6
6
  import { useCallback, useContext, useEffect, useState } from 'react';
7
7
 
8
- import { type Edge, type Edges, Graph, type NodeArg, type Node, ROOT_ID } from '@dxos/app-graph';
8
+ import { type Edge, type Edges, Graph, type Node, type NodeArg, ROOT_ID } from '@dxos/app-graph';
9
9
 
10
10
  import { type MenuItem, type MenuItemGroup } from '../types';
11
11
 
package/src/index.ts CHANGED
@@ -8,3 +8,4 @@ export * from './components';
8
8
  export * from './hooks';
9
9
  export * from './types';
10
10
  export { createMenuAction, createMenuItemGroup, createLineSeparator, createGapSeparator } from './util';
11
+ export { MenuBuilder } from './builder';
@@ -6,20 +6,20 @@ import { Rx } from '@effect-rx/rx-react';
6
6
  import { useEffect } from 'react';
7
7
 
8
8
  import {
9
+ ACTION_GROUP_TYPE,
10
+ ACTION_TYPE,
9
11
  type Action,
10
12
  Graph,
11
13
  type NodeArg,
12
- ACTION_TYPE,
13
- ACTION_GROUP_TYPE,
14
- actionGroupSymbol,
15
14
  ROOT_ID,
15
+ actionGroupSymbol,
16
16
  } from '@dxos/app-graph';
17
17
  import { live } from '@dxos/live-object';
18
18
  import { faker } from '@dxos/random';
19
19
  import { type DeepWriteable } from '@dxos/util';
20
20
 
21
21
  import { type ActionGraphProps } from '../hooks/useMenuActions';
22
- import { type MenuAction, type MenuItemGroup, type MenuItem } from '../types';
22
+ import { type MenuAction, type MenuItem, type MenuItemGroup } from '../types';
23
23
 
24
24
  export type CreateActionsParams = Partial<{
25
25
  type?: typeof ACTION_TYPE | typeof ACTION_GROUP_TYPE;
@@ -2,12 +2,14 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export const translationKey = 'menus';
5
+ import { type Resource } from '@dxos/react-ui';
6
6
 
7
- export default [
7
+ export const translationKey = 'react-ui-menu';
8
+
9
+ export const translations = [
8
10
  {
9
11
  'en-US': {
10
12
  [translationKey]: {},
11
13
  },
12
14
  },
13
- ] as const;
15
+ ] as const satisfies Resource[];
package/src/types.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Node, type Action, type ActionGroup, ACTION_GROUP_TYPE } from '@dxos/app-graph';
6
- import { type ToolbarSeparatorProps, type Label, type IconButtonProps, type ClassNameValue } from '@dxos/react-ui';
5
+ import { ACTION_GROUP_TYPE, type Action, type ActionGroup, type Node } from '@dxos/app-graph';
6
+ import { type ClassNameValue, type IconButtonProps, type Label, type ToolbarSeparatorProps } from '@dxos/react-ui';
7
7
 
8
8
  export type MenuActionProperties = {
9
9
  label: Label;
package/src/util.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { ACTION_GROUP_TYPE, ACTION_TYPE, actionGroupSymbol, type ActionLike } from '@dxos/app-graph';
5
+ import { ACTION_GROUP_TYPE, ACTION_TYPE, type ActionLike, actionGroupSymbol } from '@dxos/app-graph';
6
6
  import { getHostPlatform } from '@dxos/util';
7
7
 
8
8
  import {