@dxos/plugin-navtree 0.8.4-main.d05673bc65 → 0.8.4-main.d9fc60f731

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 (243) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +376 -0
  3. package/README.md +1 -1
  4. package/dist/lib/{browser/CommandsDialogContent-2DKIOLJL.mjs → neutral/CommandsDialogContent-UBGIQ5FI.mjs} +19 -20
  5. package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs.map +7 -0
  6. package/dist/lib/{browser/CommandsTrigger-ABODVVMP.mjs → neutral/CommandsTrigger-BH5WLMHK.mjs} +8 -14
  7. package/dist/lib/neutral/CommandsTrigger-BH5WLMHK.mjs.map +7 -0
  8. package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs +12 -0
  9. package/dist/lib/{browser/NavTreeDocumentTitle-L6NLLWLD.mjs → neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs} +5 -9
  10. package/dist/lib/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs.map +7 -0
  11. package/dist/lib/neutral/NavTreePlugin.mjs +68 -0
  12. package/dist/lib/neutral/NavTreePlugin.mjs.map +7 -0
  13. package/dist/lib/neutral/NavTreePlugin.node.mjs +18 -0
  14. package/dist/lib/neutral/NavTreePlugin.node.mjs.map +7 -0
  15. package/dist/lib/neutral/NavTreePlugin.workerd.mjs +16 -0
  16. package/dist/lib/neutral/NavTreePlugin.workerd.mjs.map +7 -0
  17. package/dist/lib/{browser/app-graph-builder-Z43OTNI2.mjs → neutral/app-graph-builder-Z347LKSF.mjs} +10 -12
  18. package/dist/lib/neutral/app-graph-builder-Z347LKSF.mjs.map +7 -0
  19. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  20. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  21. package/dist/lib/neutral/chunk-5OPDKH6B.mjs +273 -0
  22. package/dist/lib/neutral/chunk-5OPDKH6B.mjs.map +7 -0
  23. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  24. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  25. package/dist/lib/neutral/chunk-JOSNCOV4.mjs +79 -0
  26. package/dist/lib/neutral/chunk-JOSNCOV4.mjs.map +7 -0
  27. package/dist/lib/neutral/chunk-MDGKDQMZ.mjs +37 -0
  28. package/dist/lib/neutral/chunk-MDGKDQMZ.mjs.map +7 -0
  29. package/dist/lib/neutral/chunk-T7QS2EFI.mjs +8 -0
  30. package/dist/lib/neutral/chunk-T7QS2EFI.mjs.map +7 -0
  31. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs +27 -0
  32. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs.map +7 -0
  33. package/dist/lib/neutral/components/index.mjs +807 -0
  34. package/dist/lib/neutral/components/index.mjs.map +7 -0
  35. package/dist/lib/neutral/containers/index.mjs +20 -0
  36. package/dist/lib/{browser/chunk-AYF2TX65.mjs.map → neutral/containers/index.mjs.map} +3 -3
  37. package/dist/lib/neutral/expose-26FV4W5D.mjs +38 -0
  38. package/dist/lib/neutral/expose-26FV4W5D.mjs.map +7 -0
  39. package/dist/lib/neutral/hooks/index.mjs +178 -0
  40. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  41. package/dist/lib/neutral/index.mjs +34 -0
  42. package/dist/lib/neutral/index.mjs.map +7 -0
  43. package/dist/lib/{browser/keyboard-HYGFQO7T.mjs → neutral/keyboard-EJ65BVTC.mjs} +4 -5
  44. package/dist/lib/neutral/keyboard-EJ65BVTC.mjs.map +7 -0
  45. package/dist/lib/neutral/meta.json +1 -0
  46. package/dist/lib/neutral/meta.mjs +12 -0
  47. package/dist/lib/neutral/meta.mjs.map +7 -0
  48. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs +13 -0
  49. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs.map +7 -0
  50. package/dist/lib/neutral/operations/index.mjs +8 -0
  51. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  52. package/dist/lib/neutral/plugin.mjs +16 -0
  53. package/dist/lib/neutral/plugin.mjs.map +7 -0
  54. package/dist/lib/{browser/react-surface-D2RLMV4Z.mjs → neutral/react-surface-Q5XMAG7Z.mjs} +11 -20
  55. package/dist/lib/neutral/react-surface-Q5XMAG7Z.mjs.map +7 -0
  56. package/dist/lib/{browser/state-CWMNNF7K.mjs → neutral/state-VVITVXWM.mjs} +6 -10
  57. package/dist/lib/neutral/state-VVITVXWM.mjs.map +7 -0
  58. package/dist/lib/neutral/testing/index.mjs +439 -0
  59. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  60. package/dist/lib/neutral/translations.mjs +23 -0
  61. package/dist/lib/neutral/translations.mjs.map +7 -0
  62. package/dist/lib/neutral/types/index.mjs +10 -0
  63. package/dist/lib/neutral/types/index.mjs.map +7 -0
  64. package/dist/types/src/NavTreePlugin.d.ts +1 -0
  65. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  66. package/dist/types/src/NavTreePlugin.node.d.ts +4 -0
  67. package/dist/types/src/NavTreePlugin.node.d.ts.map +1 -0
  68. package/dist/types/src/NavTreePlugin.test.d.ts +2 -0
  69. package/dist/types/src/NavTreePlugin.test.d.ts.map +1 -0
  70. package/dist/types/src/NavTreePlugin.workerd.d.ts +4 -0
  71. package/dist/types/src/NavTreePlugin.workerd.d.ts.map +1 -0
  72. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  73. package/dist/types/src/capabilities/index.d.ts +7 -5
  74. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  75. package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
  76. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  77. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  78. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/state.d.ts +6 -0
  80. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  81. package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
  82. package/dist/types/src/components/NavTree/NavTree.stories.d.ts +9 -11
  83. package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
  84. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +5 -3
  85. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
  86. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +1 -1
  87. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
  88. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
  89. package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
  90. package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
  91. package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
  92. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
  93. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
  94. package/dist/types/src/components/types.d.ts +1 -2
  95. package/dist/types/src/components/types.d.ts.map +1 -1
  96. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -1
  97. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +28 -0
  98. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -0
  99. package/dist/types/src/containers/CommandsDialogContent/index.d.ts +1 -2
  100. package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -1
  101. package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -1
  102. package/dist/types/src/containers/CommandsTrigger/index.d.ts +1 -2
  103. package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -1
  104. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -1
  105. package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -1
  106. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +1 -2
  107. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -1
  108. package/dist/types/src/experimental/Tree.d.ts +2 -2
  109. package/dist/types/src/experimental/Tree.d.ts.map +1 -1
  110. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
  111. package/dist/types/src/hooks/useActions.d.ts +7 -1
  112. package/dist/types/src/hooks/useActions.d.ts.map +1 -1
  113. package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -1
  114. package/dist/types/src/hooks/useNavTreeModel.d.ts +1 -1
  115. package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -1
  116. package/dist/types/src/hooks/useNavTreeState.d.ts +2 -6
  117. package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -1
  118. package/dist/types/src/index.d.ts +1 -2
  119. package/dist/types/src/index.d.ts.map +1 -1
  120. package/dist/types/src/meta.d.ts +3 -2
  121. package/dist/types/src/meta.d.ts.map +1 -1
  122. package/dist/types/src/operations/expose.d.ts +5 -0
  123. package/dist/types/src/operations/expose.d.ts.map +1 -0
  124. package/dist/types/src/operations/index.d.ts +3 -0
  125. package/dist/types/src/operations/index.d.ts.map +1 -0
  126. package/dist/types/src/plugin.d.ts +4 -0
  127. package/dist/types/src/plugin.d.ts.map +1 -0
  128. package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
  129. package/dist/types/src/testing/generator.d.ts.map +1 -1
  130. package/dist/types/src/testing/update-state.d.ts.map +1 -1
  131. package/dist/types/src/translations.d.ts +8 -11
  132. package/dist/types/src/translations.d.ts.map +1 -1
  133. package/dist/types/src/types/NavTreeCapabilities.d.ts +13 -0
  134. package/dist/types/src/types/NavTreeCapabilities.d.ts.map +1 -0
  135. package/dist/types/src/types/NavTreeEvents.d.ts +3 -0
  136. package/dist/types/src/types/NavTreeEvents.d.ts.map +1 -0
  137. package/dist/types/src/types/index.d.ts +2 -2
  138. package/dist/types/src/types/index.d.ts.map +1 -1
  139. package/dist/types/src/types/schema.d.ts +4 -0
  140. package/dist/types/src/types/schema.d.ts.map +1 -1
  141. package/dist/types/src/util.d.ts +2 -2
  142. package/dist/types/src/util.d.ts.map +1 -1
  143. package/dist/types/tsconfig.tsbuildinfo +1 -1
  144. package/package.json +110 -50
  145. package/src/NavTreePlugin.node.ts +17 -0
  146. package/src/NavTreePlugin.test.ts +27 -0
  147. package/src/NavTreePlugin.tsx +16 -27
  148. package/src/NavTreePlugin.workerd.ts +16 -0
  149. package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +7 -7
  150. package/src/capabilities/index.ts +11 -5
  151. package/src/capabilities/{keyboard/keyboard.ts → keyboard.ts} +1 -1
  152. package/src/capabilities/operation-handler.ts +16 -0
  153. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +9 -9
  154. package/src/capabilities/{state/state.ts → state.ts} +13 -9
  155. package/src/components/NavTree/NavTree.stories.tsx +22 -23
  156. package/src/components/NavTree/NavTree.tsx +5 -4
  157. package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +8 -10
  158. package/src/components/NavTreeItem/NavTreeItemAction.tsx +50 -50
  159. package/src/components/NavTreeItem/NavTreeItemColumns.tsx +20 -63
  160. package/src/components/Sidebar/L0Menu.tsx +61 -80
  161. package/src/components/Sidebar/L1Panel.tsx +98 -174
  162. package/src/components/Sidebar/L1Tabs.tsx +0 -1
  163. package/src/components/types.ts +1 -2
  164. package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
  165. package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +51 -59
  166. package/src/containers/CommandsDialogContent/index.ts +1 -3
  167. package/src/containers/CommandsTrigger/CommandsTrigger.tsx +7 -5
  168. package/src/containers/CommandsTrigger/index.ts +1 -3
  169. package/src/containers/NavTreeContainer/NavTreeContainer.tsx +24 -24
  170. package/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.tsx +2 -2
  171. package/src/containers/NavTreeDocumentTitle/index.ts +1 -3
  172. package/src/experimental/Tree.stories.tsx +27 -27
  173. package/src/experimental/Tree.tsx +2 -2
  174. package/src/hooks/useActions.ts +11 -1
  175. package/src/hooks/useNavTreeModel.ts +5 -3
  176. package/src/hooks/useNavTreeState.ts +2 -9
  177. package/src/index.ts +1 -2
  178. package/src/meta.ts +22 -7
  179. package/src/operations/expose.ts +42 -0
  180. package/src/operations/index.ts +7 -0
  181. package/src/plugin.ts +11 -0
  182. package/src/testing/app-graph-builder.ts +42 -36
  183. package/src/testing/generator.ts +23 -28
  184. package/src/translations.ts +8 -10
  185. package/src/types/NavTreeCapabilities.ts +21 -0
  186. package/src/types/NavTreeEvents.ts +12 -0
  187. package/src/types/index.ts +3 -2
  188. package/src/types/schema.ts +4 -0
  189. package/src/util.ts +2 -2
  190. package/src/vite-env.d.ts +10 -0
  191. package/dist/lib/browser/CommandsDialogContent-2DKIOLJL.mjs.map +0 -7
  192. package/dist/lib/browser/CommandsTrigger-ABODVVMP.mjs.map +0 -7
  193. package/dist/lib/browser/NavTreeContainer-TLSYS4KK.mjs +0 -12
  194. package/dist/lib/browser/NavTreeDocumentTitle-L6NLLWLD.mjs.map +0 -7
  195. package/dist/lib/browser/app-graph-builder-Z43OTNI2.mjs.map +0 -7
  196. package/dist/lib/browser/chunk-A4VDCIJC.mjs +0 -19
  197. package/dist/lib/browser/chunk-A4VDCIJC.mjs.map +0 -7
  198. package/dist/lib/browser/chunk-AYF2TX65.mjs +0 -14
  199. package/dist/lib/browser/chunk-JT37R5HS.mjs +0 -1468
  200. package/dist/lib/browser/chunk-JT37R5HS.mjs.map +0 -7
  201. package/dist/lib/browser/chunk-KF26WA4O.mjs +0 -23
  202. package/dist/lib/browser/chunk-KF26WA4O.mjs.map +0 -7
  203. package/dist/lib/browser/index.mjs +0 -141
  204. package/dist/lib/browser/index.mjs.map +0 -7
  205. package/dist/lib/browser/keyboard-HYGFQO7T.mjs.map +0 -7
  206. package/dist/lib/browser/meta.json +0 -1
  207. package/dist/lib/browser/operation-resolver-VDWVUII5.mjs +0 -49
  208. package/dist/lib/browser/operation-resolver-VDWVUII5.mjs.map +0 -7
  209. package/dist/lib/browser/react-surface-D2RLMV4Z.mjs.map +0 -7
  210. package/dist/lib/browser/state-CWMNNF7K.mjs.map +0 -7
  211. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  212. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  213. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  214. package/dist/types/src/capabilities/keyboard/index.d.ts +0 -3
  215. package/dist/types/src/capabilities/keyboard/index.d.ts.map +0 -1
  216. package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +0 -1
  217. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  218. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  219. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  220. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  221. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  222. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  223. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  224. package/dist/types/src/capabilities/state/index.d.ts +0 -3
  225. package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
  226. package/dist/types/src/capabilities/state/state.d.ts +0 -6
  227. package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
  228. package/dist/types/src/types/capabilities.d.ts +0 -16
  229. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  230. package/dist/types/src/types/events.d.ts +0 -5
  231. package/dist/types/src/types/events.d.ts.map +0 -1
  232. package/src/capabilities/app-graph-builder/index.ts +0 -7
  233. package/src/capabilities/keyboard/index.ts +0 -7
  234. package/src/capabilities/operation-resolver/index.ts +0 -7
  235. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -45
  236. package/src/capabilities/react-surface/index.ts +0 -7
  237. package/src/capabilities/state/index.ts +0 -7
  238. package/src/types/capabilities.ts +0 -21
  239. package/src/types/events.ts +0 -12
  240. /package/dist/lib/{browser/NavTreeContainer-TLSYS4KK.mjs.map → neutral/NavTreeContainer-6AR4BFDD.mjs.map} +0 -0
  241. /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
  242. /package/dist/types/src/capabilities/{keyboard/keyboard.d.ts → keyboard.d.ts} +0 -0
  243. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -9,7 +9,8 @@ import { Node, useConnections, useActions as useGraphActions } from '@dxos/plugi
9
9
  import { Tabs } from '@dxos/react-ui-tabs';
10
10
  import { byPosition } from '@dxos/util';
11
11
 
12
- import { useLoadDescendents } from '../../hooks';
12
+ import { useLoadDescendents } from '#hooks';
13
+
13
14
  import { useNavTreeContext } from '../NavTreeContext';
14
15
  import { L0Menu, L1Tabs, type L1TabsProps } from '../Sidebar';
15
16
 
@@ -30,7 +31,7 @@ export const NavTree = forwardRef<HTMLDivElement, NavTreeProps>(({ id, root, tab
30
31
  // it uses RovingFocus and doesn't support moving focus to an item that is not a tab. Assess whether this situation
31
32
  // should change including whether it should motivate a change in the design/taxonomy, or if this means this should
32
33
  // not use `react-ui-tabs` at all.
33
- <Tabs.Root value={tab} orientation='vertical' verticalVariant='stateless' classNames='relative' ref={forwardedRef}>
34
+ <Tabs.Root value={tab} orientation='vertical' classNames='relative' ref={forwardedRef}>
34
35
  <L0Menu
35
36
  menuActions={topLevelActions}
36
37
  topLevelItems={l0Items}
@@ -81,10 +82,10 @@ const useTopLevelNavItems = (root?: Node.Node) => {
81
82
  ].toSorted((a, b) => byPosition(a.properties, b.properties));
82
83
 
83
84
  return {
84
- topLevelActions,
85
- l0Items: topLevelWorkspaces,
86
85
  pinnedItems,
86
+ topLevelActions,
87
87
  userAccountItem,
88
+ l0Items: topLevelWorkspaces,
88
89
  };
89
90
  }, [rootActions, rootOutboundItems]);
90
91
 
@@ -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: {
@@ -7,11 +7,24 @@ import React, { useCallback } from 'react';
7
7
  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
+ import { composable, composableProps } from '@dxos/react-ui';
10
11
  import { Menu, type MenuItem } from '@dxos/react-ui-menu';
11
12
  import { hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';
12
13
 
13
- import { meta } from '../../meta';
14
- import { type ActionProperties } from '../../types';
14
+ import { meta } from '#meta';
15
+ import { type ActionProperties } from '#types';
16
+
17
+ const fallbackIcon = 'ph--circle-dashed--regular';
18
+
19
+ const mdActionButtonProps = {
20
+ size: 4 as const,
21
+ density: 'md' as const,
22
+ };
23
+
24
+ const lgActionButtonProps = {
25
+ size: 5 as const,
26
+ density: 'lg' as const,
27
+ };
15
28
 
16
29
  export type NavTreeItemActionMenuProps = ActionProperties & {
17
30
  parent: Node.Node;
@@ -21,51 +34,38 @@ export type NavTreeItemActionMenuProps = ActionProperties & {
21
34
  menuActions?: Node.Action[];
22
35
  };
23
36
 
24
- const fallbackIcon = 'ph--placeholder--regular';
37
+ export const NavTreeItemActionDropdownMenu = composable<HTMLButtonElement, NavTreeItemActionMenuProps>(
38
+ ({ parent, path, label, icon, testId, menuActions, caller, ...props }, forwardedRef) => {
39
+ const { t } = useTranslation(meta.id);
40
+ const density = useDensityContext();
41
+ const runAction = useActionRunner();
42
+ const handleAction = useCallback(
43
+ (action: Node.Action, params: Node.InvokeProps = {}) => runAction(action, { ...params, path }),
44
+ [runAction, path],
45
+ );
25
46
 
26
- const fineActionButtonProps = {
27
- size: 4 as const,
28
- density: 'fine' as const,
29
- };
30
- const coarseActionButtonProps = {
31
- size: 5 as const,
32
- density: 'coarse' as const,
33
- };
34
-
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
- );
47
+ return (
48
+ <Menu.Root caller={caller} onAction={handleAction}>
49
+ <Menu.Trigger asChild>
50
+ <IconButton
51
+ {...(density === 'lg' ? lgActionButtonProps : mdActionButtonProps)}
52
+ {...composableProps(props)}
53
+ classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
54
+ variant='ghost'
55
+ icon={icon ?? fallbackIcon}
56
+ iconOnly
57
+ label={toLocalizedString(label, t)}
58
+ data-testid={testId}
59
+ ref={forwardedRef}
60
+ />
61
+ </Menu.Trigger>
62
+ <Menu.Content group={parent} items={menuActions as MenuItem[]} />
63
+ </Menu.Root>
64
+ );
65
+ },
66
+ );
51
67
 
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
- );
68
- };
68
+ NavTreeItemActionDropdownMenu.displayName = 'NavTreeItemActionDropdownMenu';
69
69
 
70
70
  export const NavTreeItemMonolithicAction = (
71
71
  props: Node.Action & {
@@ -85,7 +85,7 @@ export const NavTreeItemMonolithicAction = (
85
85
  const runAction = useActionRunner();
86
86
  return (
87
87
  <IconButton
88
- {...(density === 'coarse' ? coarseActionButtonProps : fineActionButtonProps)}
88
+ {...(density === 'lg' ? lgActionButtonProps : mdActionButtonProps)}
89
89
  variant={variant}
90
90
  classNames={[
91
91
  'shrink-0',
@@ -113,7 +113,8 @@ export const NavTreeItemMonolithicAction = (
113
113
  export const NavTreeItemAction = ({
114
114
  monolithic,
115
115
  menuActions,
116
- parent: node,
116
+ menuType,
117
+ parent,
117
118
  path,
118
119
  ...props
119
120
  }: NavTreeItemActionMenuProps) => {
@@ -121,10 +122,9 @@ export const NavTreeItemAction = ({
121
122
 
122
123
  const monolithicAction = menuActions?.length === 1 && menuActions[0];
123
124
  const baseLabel = toLocalizedString(monolithicAction ? monolithicAction.properties!.label : props.label, t);
124
-
125
125
  return monolithic && menuActions?.length === 1 ? (
126
- <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={node} path={path} {...menuActions[0]} />
126
+ <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={parent} path={path} {...menuActions[0]} />
127
127
  ) : (
128
- <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={node} path={path} menuActions={menuActions} />
128
+ <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={parent} path={path} menuActions={menuActions} />
129
129
  );
130
130
  };
@@ -4,90 +4,47 @@
4
4
 
5
5
  import React, { Fragment, memo, useMemo } from 'react';
6
6
 
7
- import { Node } from '@dxos/app-graph';
8
7
  import { Popover, Treegrid, toLocalizedString, useTranslation } from '@dxos/react-ui';
9
8
 
10
- import { useActions } from '../../hooks';
11
- import { meta } from '../../meta';
9
+ import { getListActions, useActions } from '#hooks';
10
+ import { meta } from '#meta';
11
+
12
12
  import { NAV_TREE_ITEM } from '../NavTree';
13
13
  import { useNavTreeContext } from '../NavTreeContext';
14
14
  import { type NavTreeItemColumnsProps } from '../types';
15
-
16
- import { NavTreeItemAction } from './NavTreeItemAction';
15
+ import { NavTreeItemActionDropdownMenu, NavTreeItemMonolithicAction } from './NavTreeItemAction';
17
16
 
18
17
  export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumnsProps) => {
19
18
  const { t } = useTranslation(meta.id);
20
19
  const { renderItemEnd: ItemEnd, popoverAnchorId } = useNavTreeContext();
21
20
 
22
21
  const level = path.length - 2;
23
- const { actions: actionsProp, groupedActions } = useActions(item);
24
- const sortedActions = useMemo(
25
- () =>
26
- actionsProp.toSorted((actionA, actionB) => {
27
- const primaryA = actionA.properties?.disposition === 'list-item-primary';
28
- const primaryB = actionB.properties?.disposition === 'list-item-primary';
29
- if (primaryA && !primaryB) {
30
- return -1;
31
- }
32
- if (primaryB && !primaryA) {
33
- return 1;
34
- }
35
- return 0;
36
- }),
37
- [actionsProp],
38
- );
39
- const [primaryAction, ...secondaryActions] = sortedActions;
40
-
41
- const actions = useMemo(
42
- () =>
43
- (primaryAction?.properties?.disposition === 'list-item-primary' ? secondaryActions : sortedActions)
44
- .flatMap((action) => (Node.isAction(action) ? [action] : []))
45
- .filter((a) => ['list-item', 'list-item-primary'].includes(a.properties?.disposition)),
46
- [sortedActions, primaryAction],
47
- );
48
-
49
- const primaryMenuActions = useMemo(
50
- () =>
51
- primaryAction
52
- ? Node.isAction(primaryAction)
53
- ? [primaryAction]
54
- : groupedActions[primaryAction?.id ?? '']
55
- : undefined,
56
- [primaryAction, groupedActions],
57
- );
22
+ const flattenedActions = useActions(item);
23
+ const allActions = useMemo(() => getListActions(flattenedActions), [flattenedActions]);
58
24
 
59
25
  const ActionRoot = popoverAnchorId === `${NAV_TREE_ITEM}:${item.id}` ? Popover.Anchor : Fragment;
60
26
 
61
27
  return (
62
- <div role='none' className='contents dx-app-no-drag'>
63
- {primaryAction?.properties?.disposition === 'list-item-primary' && !primaryAction?.properties?.disabled ? (
64
- <Treegrid.Cell classNames='contents'>
65
- <NavTreeItemAction
66
- testId={primaryAction.properties?.testId}
67
- label={toLocalizedString(primaryAction.properties?.label, t)}
68
- icon={primaryAction.properties?.icon ?? 'ph--placeholder--regular'}
69
- parent={item}
70
- path={path}
71
- monolithic={Node.isAction(primaryAction)}
72
- menuActions={primaryMenuActions}
73
- menuType={primaryAction.properties?.menuType}
74
- caller={NAV_TREE_ITEM}
75
- />
76
- </Treegrid.Cell>
77
- ) : (
78
- <Treegrid.Cell role='none' />
79
- )}
28
+ <div className='contents dx-app-no-drag'>
80
29
  <ActionRoot>
81
- {actions.length > 0 ? (
30
+ {allActions.length === 1 ? (
31
+ <Treegrid.Cell classNames='contents'>
32
+ <NavTreeItemMonolithicAction
33
+ baseLabel={toLocalizedString(allActions[0].properties?.label, t)}
34
+ parent={item}
35
+ path={path}
36
+ {...allActions[0]}
37
+ />
38
+ </Treegrid.Cell>
39
+ ) : allActions.length > 1 ? (
82
40
  <Treegrid.Cell classNames='contents'>
83
- <NavTreeItemAction
41
+ <NavTreeItemActionDropdownMenu
84
42
  testId={`navtree.treeItem.actionsLevel${level}`}
85
- label={t('tree item actions label')}
43
+ label={t('tree-item-actions.label')}
86
44
  icon='ph--dots-three-vertical--regular'
87
45
  parent={item}
88
46
  path={path}
89
- menuActions={actions}
90
- menuType='dropdown'
47
+ menuActions={allActions}
91
48
  caller={NAV_TREE_ITEM}
92
49
  />
93
50
  </Treegrid.Cell>
@@ -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,
@@ -29,6 +29,7 @@ import { DxAvatar } from '@dxos/lit-ui/react';
29
29
  import { useActionRunner } from '@dxos/plugin-graph';
30
30
  import {
31
31
  Icon,
32
+ IconButton,
32
33
  ListItem,
33
34
  ScrollArea,
34
35
  type ThemedClassName,
@@ -43,8 +44,9 @@ import { Tabs } from '@dxos/react-ui-tabs';
43
44
  import { mx } from '@dxos/ui-theme';
44
45
  import { arrayMove } from '@dxos/util';
45
46
 
46
- import { useNavTreeState } from '../../hooks';
47
- import { meta } from '../../meta';
47
+ import { useNavTreeState } from '#hooks';
48
+ import { meta } from '#meta';
49
+
48
50
  import { l0ItemType } from '../../util';
49
51
  import { useNavTreeContext } from '../NavTreeContext';
50
52
  import { UserAccountAvatar } from '../UserAccountAvatar';
@@ -87,10 +89,8 @@ const useL0ItemClick = ({ item, parent, path }: L0ItemProps, type: string) => {
87
89
  const { properties: { caller } = {} } = item;
88
90
  return void runAction(item as Node.Action, caller ? { parent, path, caller } : { parent, path });
89
91
  }
90
-
91
92
  case 'tab':
92
93
  return onTabChange?.(item);
93
-
94
94
  case 'link':
95
95
  return onSelect?.({ item, path, current: !getItem(path).current, option: event.altKey });
96
96
  }
@@ -103,36 +103,34 @@ const l0Breakpoints: Record<string, string> = {
103
103
  lg: 'hidden lg:grid',
104
104
  };
105
105
 
106
- const l0ItemRoot =
107
- 'group/l0item flex w-full justify-center items-center relative data[type!="collection"]:cursor-pointer dx-app-no-drag dx-focus-ring-group';
108
-
109
- const l0ItemContent = 'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm';
110
-
111
106
  const L0ItemRoot = memo(
112
- forwardRef<HTMLElement, PropsWithChildren<L0ItemRootProps>>(
107
+ forwardRef<HTMLButtonElement, PropsWithChildren<L0ItemRootProps>>(
113
108
  ({ item, parent, path, onMouseEnter, children }, forwardedRef) => {
109
+ const { t } = useTranslation(meta.id);
114
110
  const { model } = useNavTreeContext();
115
111
  const itemPath = useMemo(() => [...path, item.id], [item.id, path]);
116
112
  const { id, testId } = useAtomValue(model.itemProps(itemPath));
117
- const type = l0ItemType(item);
118
-
119
- const { t } = useTranslation(meta.id);
120
113
  const localizedString = toLocalizedString(item.properties.label, t);
121
114
 
115
+ const type = l0ItemType(item);
122
116
  const handleClick = useL0ItemClick({ item, parent, path: itemPath }, type);
123
- const rootProps =
124
- type === 'tab'
125
- ? { value: item.id, tabIndex: 0, onClick: handleClick, 'data-testid': testId, 'data-object-id': id }
126
- : { onClick: handleClick, 'data-testid': testId, 'data-object-id': id };
127
117
 
128
118
  return (
129
119
  <Tooltip.Trigger asChild delayDuration={0} side='right' content={localizedString}>
130
120
  <Tabs.TabPrimitive
131
- {...(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}
132
127
  data-type={type}
133
- className={mx(l0ItemRoot, l0Breakpoints[item.properties.l0Breakpoint])}
134
- ref={forwardedRef}
128
+ data-testid={testId}
129
+ data-object-id={id}
130
+ value={item.id}
131
+ onClick={handleClick}
135
132
  onMouseEnter={onMouseEnter}
133
+ ref={forwardedRef}
136
134
  >
137
135
  {children}
138
136
  </Tabs.TabPrimitive>
@@ -144,9 +142,8 @@ const L0ItemRoot = memo(
144
142
 
145
143
  export const L0ItemActiveTabIndicator = ({ classNames }: ThemedClassName<{}>) => (
146
144
  <div
147
- role='none'
148
145
  className={mx(
149
- '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-bg rounded-sm',
150
147
  classNames,
151
148
  )}
152
149
  />
@@ -155,13 +152,12 @@ export const L0ItemActiveTabIndicator = ({ classNames }: ThemedClassName<{}>) =>
155
152
  // TODO(burdon): Factor out pinned (non-draggable) items.
156
153
  const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L0ItemProps) => {
157
154
  const { t } = useTranslation(meta.id);
158
- const itemElement = useRef<HTMLElement | null>(null);
155
+ const itemElement = useRef<HTMLButtonElement | null>(null);
159
156
  const [closestEdge, setEdge] = useState<Edge | null>(null);
160
157
  const localizedString = toLocalizedString(item.properties.label, t);
161
158
  const hue = item.properties.hue ?? null;
162
159
 
163
160
  useLayoutEffect(() => {
164
- // NOTE(thure): This is copied from StackItem, perhaps this should be DRYed out.
165
161
  if (!itemElement.current || !onRearrange) {
166
162
  return;
167
163
  }
@@ -221,14 +217,13 @@ const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L
221
217
  return (
222
218
  <L0ItemRoot ref={itemElement} item={item} parent={parent} path={path} onMouseEnter={handleMouseEnter}>
223
219
  <div
224
- role='none'
225
220
  data-frame={true}
226
221
  {...(hue && { style: { background: `var(--color-${hue}-surface)` } })}
227
222
  className={mx(
228
- l0ItemContent,
223
+ 'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm',
229
224
  pinned
230
- ? 'p-2 group-hover/l0item:bg-active-surface'
231
- : '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',
232
227
  )}
233
228
  >
234
229
  <ItemAvatar item={item} />
@@ -244,13 +239,15 @@ const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L
244
239
 
245
240
  const ItemAvatar = ({ item }: Pick<L0ItemProps, 'item'>) => {
246
241
  const { t } = useTranslation(meta.id);
247
- const type = l0ItemType(item);
242
+
243
+ // Actions.
248
244
  if (item.properties.icon) {
249
245
  const hue = item.properties.hue ?? null;
250
- const hueFgStyle = hue && { style: { color: `var(--color-${hue}-surface-text)` } };
246
+ const hueFgStyle = hue && { style: { color: `var(--color-${hue}-fg)` } };
251
247
  return <Icon icon={item.properties.icon} size={6} {...hueFgStyle} />;
252
248
  }
253
249
 
250
+ const type = l0ItemType(item);
254
251
  if (type === 'tab' && item.properties.disposition !== 'pin-end') {
255
252
  const hue = item.properties.hue ?? null;
256
253
  const localizedString = toLocalizedString(item.properties.label, t);
@@ -317,74 +314,58 @@ export const L0Menu = ({
317
314
 
318
315
  return (
319
316
  <Tabs.Tablist
317
+ data-tauri-drag-region
320
318
  classNames={[
321
319
  'group/l0 absolute z-[1] inset-y-0 start-0 rounded-is',
322
320
  'grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout',
323
- '!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-l0-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)]',
324
324
  ]}
325
325
  >
326
326
  {/* TODO(wittjosiah): Use L0Item trigger. */}
327
327
  <Menu.Root onAction={handleAction}>
328
- <Menu.Trigger
329
- asChild
330
- data-testid='spacePlugin.addSpace'
331
- className={mx(
332
- l0ItemRoot,
333
- 'grid place-items-center dx-focus-ring-group',
334
- '[body[data-platform="macos"]_&]:mt-[30px]',
335
- )}
336
- >
337
- <Tooltip.Trigger content={t('app menu label')} side='right' asChild>
338
- <Tabs.TabPrimitive value='options' asChild role='button'>
339
- <div
340
- role='none'
341
- className={mx(
342
- l0ItemContent,
343
- 'h-(--dx-rail-action) w-(--dx-rail-action) group-hover/l0item:bg-hover-surface',
344
- )}
345
- >
346
- <Icon icon='ph--list--regular' size={5} />
347
- </div>
348
- </Tabs.TabPrimitive>
349
- </Tooltip.Trigger>
328
+ <Menu.Trigger asChild data-testid='spacePlugin.addSpace'>
329
+ <div className='grid place-items-center'>
330
+ <IconButton
331
+ density='lg'
332
+ variant='ghost'
333
+ size={5}
334
+ icon='ph--list--regular'
335
+ iconOnly
336
+ square
337
+ label={t('app-menu.label')}
338
+ />
339
+ </div>
350
340
  </Menu.Trigger>
351
341
  <Menu.Content group={parent} items={menuActions} />
352
342
  </Menu.Root>
353
343
 
354
344
  {/* Space list. */}
355
- <ScrollArea.Root thin orientation='vertical'>
356
- <ScrollArea.Viewport>
357
- <div
358
- role='none'
359
- className={mx([
360
- 'flex flex-col gap-1 pt-1',
361
- '[body[data-platform="macos"]_&]:py-[30px]',
362
- '[body[data-platform="ios"]_&]:py-[max(env(safe-area-inset-top),0.25rem)]',
363
- ])}
364
- >
365
- {topLevelItems.map((item) => (
366
- <L0Item
367
- key={item.id}
368
- item={item}
369
- parent={parent}
370
- path={path}
371
- onItemHover={onItemHover}
372
- {...(hasRearrangeableItems && { onRearrange: handleRearrange })}
373
- />
374
- ))}
375
- </div>
345
+ <ScrollArea.Root centered thin orientation='vertical'>
346
+ <ScrollArea.Viewport classNames='flex flex-col gap-2 py-1'>
347
+ {topLevelItems.map((item) => (
348
+ <L0Item
349
+ key={item.id}
350
+ item={item}
351
+ parent={parent}
352
+ path={path}
353
+ onItemHover={onItemHover}
354
+ {...(hasRearrangeableItems && { onRearrange: handleRearrange })}
355
+ />
356
+ ))}
376
357
  </ScrollArea.Viewport>
377
358
  </ScrollArea.Root>
378
359
 
379
360
  {/* Actions. */}
380
- <div role='none' className='grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2'>
361
+ <div className='grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2'>
381
362
  {pinnedItems.map((item) => (
382
363
  <L0Item key={item.id} item={item} parent={parent} path={path} pinned />
383
364
  ))}
384
365
  </div>
385
366
 
386
367
  {userAccountItem && (
387
- <div role='none' className='grid dx-app-no-drag'>
368
+ <div className='grid dx-app-no-drag'>
388
369
  <L0ItemRoot key={userAccountItem.id} item={userAccountItem} parent={parent} path={path}>
389
370
  <UserAccountAvatar
390
371
  userId={userAccountItem.properties.userId}