@dxos/plugin-navtree 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced

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 (235) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/{browser/CommandsDialogContent-2DKIOLJL.mjs → neutral/CommandsDialogContent-UBGIQ5FI.mjs} +19 -20
  4. package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs.map +7 -0
  5. package/dist/lib/{browser/CommandsTrigger-ABODVVMP.mjs → neutral/CommandsTrigger-BH5WLMHK.mjs} +8 -14
  6. package/dist/lib/neutral/CommandsTrigger-BH5WLMHK.mjs.map +7 -0
  7. package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs +12 -0
  8. package/dist/lib/{browser/NavTreeDocumentTitle-L6NLLWLD.mjs → neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs} +5 -9
  9. package/dist/lib/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs.map +7 -0
  10. package/dist/lib/neutral/NavTreePlugin.mjs +56 -0
  11. package/dist/lib/neutral/NavTreePlugin.mjs.map +7 -0
  12. package/dist/lib/neutral/NavTreePlugin.node.mjs +18 -0
  13. package/dist/lib/neutral/NavTreePlugin.node.mjs.map +7 -0
  14. package/dist/lib/neutral/NavTreePlugin.workerd.mjs +16 -0
  15. package/dist/lib/neutral/NavTreePlugin.workerd.mjs.map +7 -0
  16. package/dist/lib/{browser/app-graph-builder-Z43OTNI2.mjs → neutral/app-graph-builder-Z347LKSF.mjs} +10 -12
  17. package/dist/lib/neutral/app-graph-builder-Z347LKSF.mjs.map +7 -0
  18. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  19. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  20. package/dist/lib/neutral/chunk-5OPDKH6B.mjs +273 -0
  21. package/dist/lib/neutral/chunk-5OPDKH6B.mjs.map +7 -0
  22. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  23. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  24. package/dist/lib/neutral/chunk-JOSNCOV4.mjs +79 -0
  25. package/dist/lib/neutral/chunk-JOSNCOV4.mjs.map +7 -0
  26. package/dist/lib/neutral/chunk-T7QS2EFI.mjs +8 -0
  27. package/dist/lib/neutral/chunk-T7QS2EFI.mjs.map +7 -0
  28. package/dist/lib/{browser/chunk-A4VDCIJC.mjs → neutral/chunk-VRTNKDBX.mjs} +6 -2
  29. package/dist/lib/neutral/chunk-VRTNKDBX.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs +27 -0
  31. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs.map +7 -0
  32. package/dist/lib/{browser/chunk-OGUYILOW.mjs → neutral/components/index.mjs} +140 -723
  33. package/dist/lib/neutral/components/index.mjs.map +7 -0
  34. package/dist/lib/neutral/containers/index.mjs +20 -0
  35. package/dist/lib/{browser/chunk-DINDC6HE.mjs.map → neutral/containers/index.mjs.map} +3 -3
  36. package/dist/lib/neutral/expose-26FV4W5D.mjs +38 -0
  37. package/dist/lib/neutral/expose-26FV4W5D.mjs.map +7 -0
  38. package/dist/lib/neutral/hooks/index.mjs +169 -0
  39. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  40. package/dist/lib/neutral/index.mjs +34 -0
  41. package/dist/lib/neutral/index.mjs.map +7 -0
  42. package/dist/lib/{browser/keyboard-HYGFQO7T.mjs → neutral/keyboard-EJ65BVTC.mjs} +4 -5
  43. package/dist/lib/neutral/keyboard-EJ65BVTC.mjs.map +7 -0
  44. package/dist/lib/neutral/meta.json +1 -0
  45. package/dist/lib/neutral/meta.mjs +12 -0
  46. package/dist/lib/neutral/meta.mjs.map +7 -0
  47. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs +13 -0
  48. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs.map +7 -0
  49. package/dist/lib/neutral/operations/index.mjs +8 -0
  50. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  51. package/dist/lib/neutral/plugin.mjs +16 -0
  52. package/dist/lib/neutral/plugin.mjs.map +7 -0
  53. package/dist/lib/{browser/react-surface-LFMKIKNY.mjs → neutral/react-surface-EWCZMKVX.mjs} +11 -20
  54. package/dist/lib/neutral/react-surface-EWCZMKVX.mjs.map +7 -0
  55. package/dist/lib/{browser/state-CWMNNF7K.mjs → neutral/state-VVITVXWM.mjs} +6 -10
  56. package/dist/lib/neutral/state-VVITVXWM.mjs.map +7 -0
  57. package/dist/lib/neutral/testing/index.mjs +436 -0
  58. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  59. package/dist/lib/neutral/translations.mjs +23 -0
  60. package/dist/lib/neutral/translations.mjs.map +7 -0
  61. package/dist/lib/neutral/types/index.mjs +10 -0
  62. package/dist/lib/neutral/types/index.mjs.map +7 -0
  63. package/dist/types/src/NavTreePlugin.d.ts +1 -0
  64. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  65. package/dist/types/src/NavTreePlugin.node.d.ts +4 -0
  66. package/dist/types/src/NavTreePlugin.node.d.ts.map +1 -0
  67. package/dist/types/src/NavTreePlugin.test.d.ts +2 -0
  68. package/dist/types/src/NavTreePlugin.test.d.ts.map +1 -0
  69. package/dist/types/src/NavTreePlugin.workerd.d.ts +4 -0
  70. package/dist/types/src/NavTreePlugin.workerd.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  72. package/dist/types/src/capabilities/index.d.ts +7 -5
  73. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  74. package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
  75. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  76. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  78. package/dist/types/src/capabilities/state.d.ts +6 -0
  79. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  80. package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
  81. package/dist/types/src/components/NavTree/NavTree.stories.d.ts +9 -11
  82. package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
  83. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +5 -3
  84. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
  85. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +1 -1
  86. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
  87. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
  88. package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
  89. package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
  90. package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
  91. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
  92. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/types.d.ts +1 -2
  94. package/dist/types/src/components/types.d.ts.map +1 -1
  95. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -1
  96. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +28 -0
  97. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -0
  98. package/dist/types/src/containers/CommandsDialogContent/index.d.ts +1 -2
  99. package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -1
  100. package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -1
  101. package/dist/types/src/containers/CommandsTrigger/index.d.ts +1 -2
  102. package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -1
  103. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -1
  104. package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -1
  105. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +1 -2
  106. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -1
  107. package/dist/types/src/experimental/Tree.d.ts +2 -2
  108. package/dist/types/src/experimental/Tree.d.ts.map +1 -1
  109. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
  110. package/dist/types/src/hooks/useActions.d.ts +1 -1
  111. package/dist/types/src/hooks/useActions.d.ts.map +1 -1
  112. package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -1
  113. package/dist/types/src/hooks/useNavTreeModel.d.ts +1 -1
  114. package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -1
  115. package/dist/types/src/hooks/useNavTreeState.d.ts +2 -6
  116. package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -1
  117. package/dist/types/src/index.d.ts +1 -2
  118. package/dist/types/src/index.d.ts.map +1 -1
  119. package/dist/types/src/meta.d.ts.map +1 -1
  120. package/dist/types/src/operations/expose.d.ts +5 -0
  121. package/dist/types/src/operations/expose.d.ts.map +1 -0
  122. package/dist/types/src/operations/index.d.ts +3 -0
  123. package/dist/types/src/operations/index.d.ts.map +1 -0
  124. package/dist/types/src/plugin.d.ts +4 -0
  125. package/dist/types/src/plugin.d.ts.map +1 -0
  126. package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
  127. package/dist/types/src/testing/generator.d.ts.map +1 -1
  128. package/dist/types/src/testing/update-state.d.ts.map +1 -1
  129. package/dist/types/src/translations.d.ts +8 -11
  130. package/dist/types/src/translations.d.ts.map +1 -1
  131. package/dist/types/src/types/NavTreeCapabilities.d.ts +13 -0
  132. package/dist/types/src/types/NavTreeCapabilities.d.ts.map +1 -0
  133. package/dist/types/src/types/NavTreeEvents.d.ts +3 -0
  134. package/dist/types/src/types/NavTreeEvents.d.ts.map +1 -0
  135. package/dist/types/src/types/index.d.ts +2 -2
  136. package/dist/types/src/types/index.d.ts.map +1 -1
  137. package/dist/types/src/util.d.ts +2 -2
  138. package/dist/types/src/util.d.ts.map +1 -1
  139. package/dist/types/tsconfig.tsbuildinfo +1 -1
  140. package/package.json +110 -45
  141. package/src/NavTreePlugin.node.ts +17 -0
  142. package/src/NavTreePlugin.test.ts +27 -0
  143. package/src/NavTreePlugin.tsx +10 -27
  144. package/src/NavTreePlugin.workerd.ts +16 -0
  145. package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +7 -7
  146. package/src/capabilities/index.ts +11 -5
  147. package/src/capabilities/{keyboard/keyboard.ts → keyboard.ts} +1 -1
  148. package/src/capabilities/operation-handler.ts +16 -0
  149. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +9 -9
  150. package/src/capabilities/{state/state.ts → state.ts} +13 -9
  151. package/src/components/NavTree/NavTree.stories.tsx +17 -16
  152. package/src/components/NavTree/NavTree.tsx +5 -4
  153. package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +8 -10
  154. package/src/components/NavTreeItem/NavTreeItemAction.tsx +47 -48
  155. package/src/components/NavTreeItem/NavTreeItemColumns.tsx +5 -5
  156. package/src/components/Sidebar/L0Menu.tsx +50 -58
  157. package/src/components/Sidebar/L1Panel.tsx +97 -150
  158. package/src/components/Sidebar/L1Tabs.tsx +0 -1
  159. package/src/components/types.ts +1 -2
  160. package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
  161. package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +51 -59
  162. package/src/containers/CommandsDialogContent/index.ts +1 -3
  163. package/src/containers/CommandsTrigger/CommandsTrigger.tsx +7 -5
  164. package/src/containers/CommandsTrigger/index.ts +1 -3
  165. package/src/containers/NavTreeContainer/NavTreeContainer.tsx +24 -24
  166. package/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.tsx +2 -2
  167. package/src/containers/NavTreeDocumentTitle/index.ts +1 -3
  168. package/src/experimental/Tree.stories.tsx +27 -27
  169. package/src/experimental/Tree.tsx +2 -2
  170. package/src/hooks/useActions.ts +1 -1
  171. package/src/hooks/useNavTreeModel.ts +3 -3
  172. package/src/hooks/useNavTreeState.ts +2 -9
  173. package/src/index.ts +1 -2
  174. package/src/meta.ts +2 -0
  175. package/src/operations/expose.ts +42 -0
  176. package/src/operations/index.ts +7 -0
  177. package/src/plugin.ts +11 -0
  178. package/src/testing/app-graph-builder.ts +35 -31
  179. package/src/testing/generator.ts +21 -21
  180. package/src/translations.ts +8 -10
  181. package/src/types/NavTreeCapabilities.ts +21 -0
  182. package/src/types/NavTreeEvents.ts +12 -0
  183. package/src/types/index.ts +3 -2
  184. package/src/util.ts +2 -2
  185. package/dist/lib/browser/CommandsDialogContent-2DKIOLJL.mjs.map +0 -7
  186. package/dist/lib/browser/CommandsTrigger-ABODVVMP.mjs.map +0 -7
  187. package/dist/lib/browser/NavTreeContainer-IQZCK4Y4.mjs +0 -12
  188. package/dist/lib/browser/NavTreeDocumentTitle-L6NLLWLD.mjs.map +0 -7
  189. package/dist/lib/browser/app-graph-builder-Z43OTNI2.mjs.map +0 -7
  190. package/dist/lib/browser/chunk-A4VDCIJC.mjs.map +0 -7
  191. package/dist/lib/browser/chunk-DINDC6HE.mjs +0 -14
  192. package/dist/lib/browser/chunk-KF26WA4O.mjs +0 -23
  193. package/dist/lib/browser/chunk-KF26WA4O.mjs.map +0 -7
  194. package/dist/lib/browser/chunk-OGUYILOW.mjs.map +0 -7
  195. package/dist/lib/browser/index.mjs +0 -141
  196. package/dist/lib/browser/index.mjs.map +0 -7
  197. package/dist/lib/browser/keyboard-HYGFQO7T.mjs.map +0 -7
  198. package/dist/lib/browser/meta.json +0 -1
  199. package/dist/lib/browser/operation-resolver-VDWVUII5.mjs +0 -49
  200. package/dist/lib/browser/operation-resolver-VDWVUII5.mjs.map +0 -7
  201. package/dist/lib/browser/react-surface-LFMKIKNY.mjs.map +0 -7
  202. package/dist/lib/browser/state-CWMNNF7K.mjs.map +0 -7
  203. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  204. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  205. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  206. package/dist/types/src/capabilities/keyboard/index.d.ts +0 -3
  207. package/dist/types/src/capabilities/keyboard/index.d.ts.map +0 -1
  208. package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +0 -1
  209. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  210. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  211. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  212. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  213. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  214. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  215. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  216. package/dist/types/src/capabilities/state/index.d.ts +0 -3
  217. package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
  218. package/dist/types/src/capabilities/state/state.d.ts +0 -6
  219. package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
  220. package/dist/types/src/types/capabilities.d.ts +0 -16
  221. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  222. package/dist/types/src/types/events.d.ts +0 -5
  223. package/dist/types/src/types/events.d.ts.map +0 -1
  224. package/src/capabilities/app-graph-builder/index.ts +0 -7
  225. package/src/capabilities/keyboard/index.ts +0 -7
  226. package/src/capabilities/operation-resolver/index.ts +0 -7
  227. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -45
  228. package/src/capabilities/react-surface/index.ts +0 -7
  229. package/src/capabilities/state/index.ts +0 -7
  230. package/src/types/capabilities.ts +0 -21
  231. package/src/types/events.ts +0 -12
  232. /package/dist/lib/{browser/NavTreeContainer-IQZCK4Y4.mjs.map → neutral/NavTreeContainer-6AR4BFDD.mjs.map} +0 -0
  233. /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
  234. /package/dist/types/src/capabilities/{keyboard/keyboard.d.ts → keyboard.d.ts} +0 -0
  235. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -5,37 +5,36 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import * as Effect from 'effect/Effect';
7
7
 
8
- import { RuntimePlugin } from '@dxos/app-framework';
8
+ import { ProcessManagerPlugin } from '@dxos/app-framework';
9
9
  import { withPluginManager } from '@dxos/app-framework/testing';
10
10
  import { type Node } from '@dxos/app-graph';
11
11
  import { corePlugins } from '@dxos/plugin-testing';
12
- import { faker } from '@dxos/random';
13
- import { withTheme } from '@dxos/react-ui/testing';
12
+ import { random } from '@dxos/random';
14
13
 
15
14
  import { NavTreeItemAction, type NavTreeItemActionMenuProps } from './NavTreeItemAction';
16
15
 
17
16
  const parent = {
18
- id: faker.string.uuid(),
17
+ id: random.string.uuid(),
19
18
  type: 'node',
20
19
  data: null,
21
20
  properties: {
22
- label: faker.lorem.words(2),
21
+ label: random.lorem.words(2),
23
22
  icon: 'ph--circle--regular',
24
23
  },
25
24
  } satisfies Node.NodeArg<any>;
26
25
 
27
26
  // TODO(burdon): Factor out across tests.
28
- const menuActions = faker.helpers.multiple(
27
+ const menuActions = random.helpers.multiple(
29
28
  () =>
30
29
  ({
31
- id: faker.string.uuid(),
30
+ id: random.string.uuid(),
32
31
  type: 'action',
33
32
  data: () =>
34
33
  Effect.sync(() => {
35
34
  console.log('invoke');
36
35
  }),
37
36
  properties: {
38
- label: faker.lorem.words(2),
37
+ label: random.lorem.words(2),
39
38
  icon: 'ph--circle--regular',
40
39
  },
41
40
  }) satisfies Node.NodeArg<any>,
@@ -52,9 +51,8 @@ const meta = {
52
51
  label: 'Select action',
53
52
  } satisfies Partial<NavTreeItemActionMenuProps>,
54
53
  decorators: [
55
- withTheme(),
56
54
  withPluginManager({
57
- plugins: [...corePlugins(), RuntimePlugin()],
55
+ plugins: [...corePlugins(), ProcessManagerPlugin()],
58
56
  }),
59
57
  ],
60
58
  parameters: {
@@ -8,18 +8,10 @@ import { type Node } from '@dxos/app-graph';
8
8
  import { useActionRunner } from '@dxos/plugin-graph';
9
9
  import { IconButton, toLocalizedString, useDensityContext, useTranslation } from '@dxos/react-ui';
10
10
  import { Menu, type MenuItem } from '@dxos/react-ui-menu';
11
- import { hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';
11
+ import { composable, composableProps, hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';
12
12
 
13
- import { meta } from '../../meta';
14
- import { type ActionProperties } from '../../types';
15
-
16
- export type NavTreeItemActionMenuProps = ActionProperties & {
17
- parent: Node.Node;
18
- path?: string[];
19
- caller?: string;
20
- monolithic?: boolean;
21
- menuActions?: Node.Action[];
22
- };
13
+ import { meta } from '#meta';
14
+ import { type ActionProperties } from '#types';
23
15
 
24
16
  const fallbackIcon = 'ph--placeholder--regular';
25
17
 
@@ -27,46 +19,53 @@ const fineActionButtonProps = {
27
19
  size: 4 as const,
28
20
  density: 'fine' as const,
29
21
  };
22
+
30
23
  const coarseActionButtonProps = {
31
24
  size: 5 as const,
32
25
  density: 'coarse' as const,
33
26
  };
34
27
 
35
- export const NavTreeItemActionDropdownMenu = ({
36
- parent,
37
- path,
38
- label,
39
- icon,
40
- testId,
41
- menuActions,
42
- caller,
43
- }: NavTreeItemActionMenuProps) => {
44
- const { t } = useTranslation(meta.id);
45
- const density = useDensityContext();
46
- const runAction = useActionRunner();
47
- const handleAction = useCallback(
48
- (action: Node.Action, params: Node.InvokeProps = {}) => runAction(action, { ...params, path }),
49
- [runAction, path],
50
- );
51
-
52
- return (
53
- <Menu.Root caller={caller} onAction={handleAction}>
54
- <Menu.Trigger asChild>
55
- <IconButton
56
- {...(density === 'coarse' ? coarseActionButtonProps : fineActionButtonProps)}
57
- classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
58
- variant='ghost'
59
- icon={icon ?? fallbackIcon}
60
- iconOnly
61
- label={toLocalizedString(label, t)}
62
- data-testid={testId}
63
- />
64
- </Menu.Trigger>
65
- <Menu.Content group={parent} items={menuActions as MenuItem[]} />
66
- </Menu.Root>
67
- );
28
+ export type NavTreeItemActionMenuProps = ActionProperties & {
29
+ parent: Node.Node;
30
+ path?: string[];
31
+ caller?: string;
32
+ monolithic?: boolean;
33
+ menuActions?: Node.Action[];
68
34
  };
69
35
 
36
+ export const NavTreeItemActionDropdownMenu = composable<HTMLButtonElement, NavTreeItemActionMenuProps>(
37
+ ({ parent, path, label, icon, testId, menuActions, caller, ...props }, forwardedRef) => {
38
+ const { t } = useTranslation(meta.id);
39
+ const density = useDensityContext();
40
+ const runAction = useActionRunner();
41
+ const handleAction = useCallback(
42
+ (action: Node.Action, params: Node.InvokeProps = {}) => runAction(action, { ...params, path }),
43
+ [runAction, path],
44
+ );
45
+
46
+ return (
47
+ <Menu.Root caller={caller} onAction={handleAction}>
48
+ <Menu.Trigger asChild>
49
+ <IconButton
50
+ {...(density === 'coarse' ? coarseActionButtonProps : fineActionButtonProps)}
51
+ {...composableProps(props)}
52
+ classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
53
+ variant='ghost'
54
+ icon={icon ?? fallbackIcon}
55
+ iconOnly
56
+ label={toLocalizedString(label, t)}
57
+ data-testid={testId}
58
+ ref={forwardedRef}
59
+ />
60
+ </Menu.Trigger>
61
+ <Menu.Content group={parent} items={menuActions as MenuItem[]} />
62
+ </Menu.Root>
63
+ );
64
+ },
65
+ );
66
+
67
+ NavTreeItemActionDropdownMenu.displayName = 'NavTreeItemActionDropdownMenu';
68
+
70
69
  export const NavTreeItemMonolithicAction = (
71
70
  props: Node.Action & {
72
71
  parent: Node.Node;
@@ -113,7 +112,8 @@ export const NavTreeItemMonolithicAction = (
113
112
  export const NavTreeItemAction = ({
114
113
  monolithic,
115
114
  menuActions,
116
- parent: node,
115
+ menuType,
116
+ parent,
117
117
  path,
118
118
  ...props
119
119
  }: NavTreeItemActionMenuProps) => {
@@ -121,10 +121,9 @@ export const NavTreeItemAction = ({
121
121
 
122
122
  const monolithicAction = menuActions?.length === 1 && menuActions[0];
123
123
  const baseLabel = toLocalizedString(monolithicAction ? monolithicAction.properties!.label : props.label, t);
124
-
125
124
  return monolithic && menuActions?.length === 1 ? (
126
- <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={node} path={path} {...menuActions[0]} />
125
+ <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={parent} path={path} {...menuActions[0]} />
127
126
  ) : (
128
- <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={node} path={path} menuActions={menuActions} />
127
+ <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={parent} path={path} menuActions={menuActions} />
129
128
  );
130
129
  };
@@ -7,12 +7,12 @@ import React, { Fragment, memo, useMemo } from 'react';
7
7
  import { Node } from '@dxos/app-graph';
8
8
  import { Popover, Treegrid, toLocalizedString, useTranslation } from '@dxos/react-ui';
9
9
 
10
- import { useActions } from '../../hooks';
11
- import { meta } from '../../meta';
10
+ import { useActions } from '#hooks';
11
+ import { meta } from '#meta';
12
+
12
13
  import { NAV_TREE_ITEM } from '../NavTree';
13
14
  import { useNavTreeContext } from '../NavTreeContext';
14
15
  import { type NavTreeItemColumnsProps } from '../types';
15
-
16
16
  import { NavTreeItemAction } from './NavTreeItemAction';
17
17
 
18
18
  export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumnsProps) => {
@@ -59,7 +59,7 @@ export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumns
59
59
  const ActionRoot = popoverAnchorId === `${NAV_TREE_ITEM}:${item.id}` ? Popover.Anchor : Fragment;
60
60
 
61
61
  return (
62
- <div role='none' className='contents dx-app-no-drag'>
62
+ <div className='contents dx-app-no-drag'>
63
63
  {primaryAction?.properties?.disposition === 'list-item-primary' && !primaryAction?.properties?.disabled ? (
64
64
  <Treegrid.Cell classNames='contents'>
65
65
  <NavTreeItemAction
@@ -82,7 +82,7 @@ export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumns
82
82
  <Treegrid.Cell classNames='contents'>
83
83
  <NavTreeItemAction
84
84
  testId={`navtree.treeItem.actionsLevel${level}`}
85
- label={t('tree item actions label')}
85
+ label={t('tree-item-actions.label')}
86
86
  icon='ph--dots-three-vertical--regular'
87
87
  parent={item}
88
88
  path={path}
@@ -2,15 +2,15 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
6
- import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
7
- import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
8
- import { scrollJustEnoughIntoView } from '@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view';
9
5
  import {
10
6
  type Edge,
11
7
  attachClosestEdge,
12
8
  extractClosestEdge,
13
9
  } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
10
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
11
+ import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
12
+ import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
13
+ import { scrollJustEnoughIntoView } from '@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view';
14
14
  import { useAtomValue } from '@effect-atom/atom-react';
15
15
  import React, {
16
16
  type MouseEvent,
@@ -44,8 +44,9 @@ import { Tabs } from '@dxos/react-ui-tabs';
44
44
  import { mx } from '@dxos/ui-theme';
45
45
  import { arrayMove } from '@dxos/util';
46
46
 
47
- import { useNavTreeState } from '../../hooks';
48
- import { meta } from '../../meta';
47
+ import { useNavTreeState } from '#hooks';
48
+ import { meta } from '#meta';
49
+
49
50
  import { l0ItemType } from '../../util';
50
51
  import { useNavTreeContext } from '../NavTreeContext';
51
52
  import { UserAccountAvatar } from '../UserAccountAvatar';
@@ -102,36 +103,34 @@ const l0Breakpoints: Record<string, string> = {
102
103
  lg: 'hidden lg:grid',
103
104
  };
104
105
 
105
- const l0ItemRoot =
106
- 'group/l0item flex w-full justify-center items-center relative data[type!="collection"]:cursor-pointer dx-app-no-drag dx-focus-ring-group';
107
-
108
- const l0ItemContent = 'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm';
109
-
110
106
  const L0ItemRoot = memo(
111
- forwardRef<HTMLElement, PropsWithChildren<L0ItemRootProps>>(
107
+ forwardRef<HTMLButtonElement, PropsWithChildren<L0ItemRootProps>>(
112
108
  ({ item, parent, path, onMouseEnter, children }, forwardedRef) => {
109
+ const { t } = useTranslation(meta.id);
113
110
  const { model } = useNavTreeContext();
114
111
  const itemPath = useMemo(() => [...path, item.id], [item.id, path]);
115
112
  const { id, testId } = useAtomValue(model.itemProps(itemPath));
116
- const type = l0ItemType(item);
117
-
118
- const { t } = useTranslation(meta.id);
119
113
  const localizedString = toLocalizedString(item.properties.label, t);
120
114
 
115
+ const type = l0ItemType(item);
121
116
  const handleClick = useL0ItemClick({ item, parent, path: itemPath }, type);
122
- const rootProps =
123
- type === 'tab'
124
- ? { value: item.id, tabIndex: 0, onClick: handleClick, 'data-testid': testId, 'data-object-id': id }
125
- : { onClick: handleClick, 'data-testid': testId, 'data-object-id': id };
126
117
 
127
118
  return (
128
119
  <Tooltip.Trigger asChild delayDuration={0} side='right' content={localizedString}>
129
120
  <Tabs.TabPrimitive
130
- {...(rootProps as any)}
121
+ className={mx(
122
+ 'group/l0item flex w-full justify-center items-center relative',
123
+ 'dx-app-no-drag dx-focus-ring-group data[type!="collection"]:cursor-pointer',
124
+ l0Breakpoints[item.properties.l0Breakpoint],
125
+ )}
126
+ tabIndex={type === 'tab' ? 0 : undefined}
131
127
  data-type={type}
132
- className={mx(l0ItemRoot, l0Breakpoints[item.properties.l0Breakpoint])}
133
- ref={forwardedRef}
128
+ data-testid={testId}
129
+ data-object-id={id}
130
+ value={item.id}
131
+ onClick={handleClick}
134
132
  onMouseEnter={onMouseEnter}
133
+ ref={forwardedRef}
135
134
  >
136
135
  {children}
137
136
  </Tabs.TabPrimitive>
@@ -143,9 +142,8 @@ const L0ItemRoot = memo(
143
142
 
144
143
  export const L0ItemActiveTabIndicator = ({ classNames }: ThemedClassName<{}>) => (
145
144
  <div
146
- role='none'
147
145
  className={mx(
148
- 'hidden group-aria-selected/l0item:block absolute start-0 inset-y-2 w-1 bg-accent-surface rounded-ie',
146
+ 'hidden group-aria-selected/l0item:block absolute start-0 h-6 w-1.5 bg-accent-surface rounded-sm',
149
147
  classNames,
150
148
  )}
151
149
  />
@@ -154,13 +152,12 @@ export const L0ItemActiveTabIndicator = ({ classNames }: ThemedClassName<{}>) =>
154
152
  // TODO(burdon): Factor out pinned (non-draggable) items.
155
153
  const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L0ItemProps) => {
156
154
  const { t } = useTranslation(meta.id);
157
- const itemElement = useRef<HTMLElement | null>(null);
155
+ const itemElement = useRef<HTMLButtonElement | null>(null);
158
156
  const [closestEdge, setEdge] = useState<Edge | null>(null);
159
157
  const localizedString = toLocalizedString(item.properties.label, t);
160
158
  const hue = item.properties.hue ?? null;
161
159
 
162
160
  useLayoutEffect(() => {
163
- // NOTE(thure): This is copied from StackItem, perhaps this should be DRYed out.
164
161
  if (!itemElement.current || !onRearrange) {
165
162
  return;
166
163
  }
@@ -220,14 +217,13 @@ const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L
220
217
  return (
221
218
  <L0ItemRoot ref={itemElement} item={item} parent={parent} path={path} onMouseEnter={handleMouseEnter}>
222
219
  <div
223
- role='none'
224
220
  data-frame={true}
225
221
  {...(hue && { style: { background: `var(--color-${hue}-surface)` } })}
226
222
  className={mx(
227
- l0ItemContent,
223
+ 'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm',
228
224
  pinned
229
- ? 'p-2 group-hover/l0item:bg-active-surface'
230
- : 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-active-surface',
225
+ ? 'p-2 group-hover/l0item:bg-current-surface'
226
+ : 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-current-surface',
231
227
  )}
232
228
  >
233
229
  <ItemAvatar item={item} />
@@ -243,13 +239,15 @@ const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L
243
239
 
244
240
  const ItemAvatar = ({ item }: Pick<L0ItemProps, 'item'>) => {
245
241
  const { t } = useTranslation(meta.id);
246
- const type = l0ItemType(item);
242
+
243
+ // Actions.
247
244
  if (item.properties.icon) {
248
245
  const hue = item.properties.hue ?? null;
249
- const hueFgStyle = hue && { style: { color: `var(--color-${hue}-surface-text)` } };
246
+ const hueFgStyle = hue && { style: { color: `var(--color-${hue}-foreground)` } };
250
247
  return <Icon icon={item.properties.icon} size={6} {...hueFgStyle} />;
251
248
  }
252
249
 
250
+ const type = l0ItemType(item);
253
251
  if (type === 'tab' && item.properties.disposition !== 'pin-end') {
254
252
  const hue = item.properties.hue ?? null;
255
253
  const localizedString = toLocalizedString(item.properties.label, t);
@@ -316,56 +314,50 @@ export const L0Menu = ({
316
314
 
317
315
  return (
318
316
  <Tabs.Tablist
317
+ data-tauri-drag-region
319
318
  classNames={[
320
319
  'group/l0 absolute z-[1] inset-y-0 start-0 rounded-is',
321
320
  'grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout',
322
- '!w-(--dx-l0-size) bg-toolbar-surface border-e border-subdued-separator dx-app-drag pb-[env(safe-area-inset-bottom)]',
321
+ 'w-(--dx-l0-size) bg-toolbar-surface dx-app-drag pb-[env(safe-area-inset-bottom)]',
322
+ '[body[data-platform="macos"]_&]:pt-[30px]',
323
+ '[body[data-platform="ios"]_&]:pt-[max(env(safe-area-inset-top),0.25rem)]',
323
324
  ]}
324
325
  >
325
326
  {/* TODO(wittjosiah): Use L0Item trigger. */}
326
327
  <Menu.Root onAction={handleAction}>
327
328
  <Menu.Trigger asChild data-testid='spacePlugin.addSpace'>
328
- <div role='none' className='grid place-items-center'>
329
- <IconButton variant='ghost' icon='ph--list--regular' iconOnly label={t('app menu label')} size={5} />
329
+ <div className='grid place-items-center'>
330
+ <IconButton variant='ghost' icon='ph--list--regular' iconOnly label={t('app-menu.label')} />
330
331
  </div>
331
332
  </Menu.Trigger>
332
333
  <Menu.Content group={parent} items={menuActions} />
333
334
  </Menu.Root>
334
335
 
335
336
  {/* Space list. */}
336
- <ScrollArea.Root thin orientation='vertical'>
337
- <ScrollArea.Viewport>
338
- <div
339
- role='none'
340
- className={mx([
341
- 'flex flex-col gap-2 pt-1',
342
- '[body[data-platform="macos"]_&]:py-[30px]',
343
- '[body[data-platform="ios"]_&]:py-[max(env(safe-area-inset-top),0.25rem)]',
344
- ])}
345
- >
346
- {topLevelItems.map((item) => (
347
- <L0Item
348
- key={item.id}
349
- item={item}
350
- parent={parent}
351
- path={path}
352
- onItemHover={onItemHover}
353
- {...(hasRearrangeableItems && { onRearrange: handleRearrange })}
354
- />
355
- ))}
356
- </div>
337
+ <ScrollArea.Root centered thin orientation='vertical'>
338
+ <ScrollArea.Viewport classNames='flex flex-col gap-2 py-1'>
339
+ {topLevelItems.map((item) => (
340
+ <L0Item
341
+ key={item.id}
342
+ item={item}
343
+ parent={parent}
344
+ path={path}
345
+ onItemHover={onItemHover}
346
+ {...(hasRearrangeableItems && { onRearrange: handleRearrange })}
347
+ />
348
+ ))}
357
349
  </ScrollArea.Viewport>
358
350
  </ScrollArea.Root>
359
351
 
360
352
  {/* Actions. */}
361
- <div role='none' className='grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2'>
353
+ <div className='grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2'>
362
354
  {pinnedItems.map((item) => (
363
355
  <L0Item key={item.id} item={item} parent={parent} path={path} pinned />
364
356
  ))}
365
357
  </div>
366
358
 
367
359
  {userAccountItem && (
368
- <div role='none' className='grid dx-app-no-drag'>
360
+ <div className='grid dx-app-no-drag'>
369
361
  <L0ItemRoot key={userAccountItem.id} item={userAccountItem} parent={parent} path={path}>
370
362
  <UserAccountAvatar
371
363
  userId={userAccountItem.properties.userId}