@dxos/plugin-navtree 0.8.4-main.c85a9c8dae → 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 (258) 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-A27AKTHH.mjs → neutral/CommandsDialogContent-UBGIQ5FI.mjs} +24 -23
  5. package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs.map +7 -0
  6. package/dist/lib/{browser/CommandsTrigger-HBZYQCGV.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/neutral/NavTreeContainer-6AR4BFDD.mjs.map +7 -0
  10. package/dist/lib/{browser/NavTreeDocumentTitle-GEE3URWH.mjs → neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs} +5 -9
  11. package/dist/lib/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs.map +7 -0
  12. package/dist/lib/neutral/NavTreePlugin.mjs +68 -0
  13. package/dist/lib/neutral/NavTreePlugin.mjs.map +7 -0
  14. package/dist/lib/neutral/NavTreePlugin.node.mjs +18 -0
  15. package/dist/lib/neutral/NavTreePlugin.node.mjs.map +7 -0
  16. package/dist/lib/neutral/NavTreePlugin.workerd.mjs +16 -0
  17. package/dist/lib/neutral/NavTreePlugin.workerd.mjs.map +7 -0
  18. package/dist/lib/{browser/app-graph-builder-XGA4GPGL.mjs → neutral/app-graph-builder-Z347LKSF.mjs} +10 -12
  19. package/dist/lib/neutral/app-graph-builder-Z347LKSF.mjs.map +7 -0
  20. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  21. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  22. package/dist/lib/neutral/chunk-5OPDKH6B.mjs +273 -0
  23. package/dist/lib/neutral/chunk-5OPDKH6B.mjs.map +7 -0
  24. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  25. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  26. package/dist/lib/neutral/chunk-JOSNCOV4.mjs +79 -0
  27. package/dist/lib/neutral/chunk-JOSNCOV4.mjs.map +7 -0
  28. package/dist/lib/neutral/chunk-MDGKDQMZ.mjs +37 -0
  29. package/dist/lib/neutral/chunk-MDGKDQMZ.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-T7QS2EFI.mjs +8 -0
  31. package/dist/lib/neutral/chunk-T7QS2EFI.mjs.map +7 -0
  32. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs +27 -0
  33. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs.map +7 -0
  34. package/dist/lib/neutral/components/index.mjs +807 -0
  35. package/dist/lib/neutral/components/index.mjs.map +7 -0
  36. package/dist/lib/neutral/containers/index.mjs +20 -0
  37. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  38. package/dist/lib/neutral/expose-26FV4W5D.mjs +38 -0
  39. package/dist/lib/neutral/expose-26FV4W5D.mjs.map +7 -0
  40. package/dist/lib/neutral/hooks/index.mjs +178 -0
  41. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  42. package/dist/lib/neutral/index.mjs +34 -0
  43. package/dist/lib/neutral/index.mjs.map +7 -0
  44. package/dist/lib/{browser/keyboard-OJZC54PK.mjs → neutral/keyboard-EJ65BVTC.mjs} +8 -6
  45. package/dist/lib/neutral/keyboard-EJ65BVTC.mjs.map +7 -0
  46. package/dist/lib/neutral/meta.json +1 -0
  47. package/dist/lib/neutral/meta.mjs +12 -0
  48. package/dist/lib/neutral/meta.mjs.map +7 -0
  49. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs +13 -0
  50. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs.map +7 -0
  51. package/dist/lib/neutral/operations/index.mjs +8 -0
  52. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  53. package/dist/lib/neutral/plugin.mjs +16 -0
  54. package/dist/lib/neutral/plugin.mjs.map +7 -0
  55. package/dist/lib/{browser/react-surface-AYHOAJ4I.mjs → neutral/react-surface-Q5XMAG7Z.mjs} +11 -20
  56. package/dist/lib/neutral/react-surface-Q5XMAG7Z.mjs.map +7 -0
  57. package/dist/lib/{browser/state-AC3EETN7.mjs → neutral/state-VVITVXWM.mjs} +7 -11
  58. package/dist/lib/neutral/state-VVITVXWM.mjs.map +7 -0
  59. package/dist/lib/neutral/testing/index.mjs +439 -0
  60. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  61. package/dist/lib/neutral/translations.mjs +23 -0
  62. package/dist/lib/neutral/translations.mjs.map +7 -0
  63. package/dist/lib/neutral/types/index.mjs +10 -0
  64. package/dist/lib/neutral/types/index.mjs.map +7 -0
  65. package/dist/types/src/NavTreePlugin.d.ts +1 -0
  66. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  67. package/dist/types/src/NavTreePlugin.node.d.ts +4 -0
  68. package/dist/types/src/NavTreePlugin.node.d.ts.map +1 -0
  69. package/dist/types/src/NavTreePlugin.test.d.ts +2 -0
  70. package/dist/types/src/NavTreePlugin.test.d.ts.map +1 -0
  71. package/dist/types/src/NavTreePlugin.workerd.d.ts +4 -0
  72. package/dist/types/src/NavTreePlugin.workerd.d.ts.map +1 -0
  73. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  74. package/dist/types/src/capabilities/index.d.ts +7 -5
  75. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  76. package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  78. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  80. package/dist/types/src/capabilities/state.d.ts +6 -0
  81. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  82. package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
  83. package/dist/types/src/components/NavTree/NavTree.stories.d.ts +9 -11
  84. package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
  85. package/dist/types/src/components/{NavTreeContext.d.ts → NavTreeContext/NavTreeContext.d.ts} +1 -1
  86. package/dist/types/src/components/NavTreeContext/NavTreeContext.d.ts.map +1 -0
  87. package/dist/types/src/components/NavTreeContext/index.d.ts +2 -0
  88. package/dist/types/src/components/NavTreeContext/index.d.ts.map +1 -0
  89. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +7 -3
  90. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
  91. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +1 -1
  92. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
  94. package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
  95. package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
  96. package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
  97. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
  98. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
  99. package/dist/types/src/components/types.d.ts +1 -2
  100. package/dist/types/src/components/types.d.ts.map +1 -1
  101. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -1
  102. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +28 -0
  103. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -0
  104. package/dist/types/src/containers/CommandsDialogContent/index.d.ts +1 -2
  105. package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -1
  106. package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -1
  107. package/dist/types/src/containers/CommandsTrigger/index.d.ts +1 -2
  108. package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -1
  109. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -1
  110. package/dist/types/src/containers/NavTreeContainer/index.d.ts +2 -2
  111. package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -1
  112. package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -1
  113. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +1 -2
  114. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -1
  115. package/dist/types/src/containers/index.d.ts +1 -1
  116. package/dist/types/src/containers/index.d.ts.map +1 -1
  117. package/dist/types/src/experimental/Tree.d.ts +2 -2
  118. package/dist/types/src/experimental/Tree.d.ts.map +1 -1
  119. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
  120. package/dist/types/src/hooks/useActions.d.ts +6 -2
  121. package/dist/types/src/hooks/useActions.d.ts.map +1 -1
  122. package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -1
  123. package/dist/types/src/hooks/useNavTreeModel.d.ts +1 -1
  124. package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -1
  125. package/dist/types/src/hooks/useNavTreeState.d.ts +2 -6
  126. package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -1
  127. package/dist/types/src/index.d.ts +1 -2
  128. package/dist/types/src/index.d.ts.map +1 -1
  129. package/dist/types/src/meta.d.ts +3 -2
  130. package/dist/types/src/meta.d.ts.map +1 -1
  131. package/dist/types/src/operations/expose.d.ts +5 -0
  132. package/dist/types/src/operations/expose.d.ts.map +1 -0
  133. package/dist/types/src/operations/index.d.ts +3 -0
  134. package/dist/types/src/operations/index.d.ts.map +1 -0
  135. package/dist/types/src/plugin.d.ts +4 -0
  136. package/dist/types/src/plugin.d.ts.map +1 -0
  137. package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
  138. package/dist/types/src/testing/generator.d.ts.map +1 -1
  139. package/dist/types/src/testing/update-state.d.ts.map +1 -1
  140. package/dist/types/src/translations.d.ts +8 -11
  141. package/dist/types/src/translations.d.ts.map +1 -1
  142. package/dist/types/src/types/NavTreeCapabilities.d.ts +13 -0
  143. package/dist/types/src/types/NavTreeCapabilities.d.ts.map +1 -0
  144. package/dist/types/src/types/NavTreeEvents.d.ts +3 -0
  145. package/dist/types/src/types/NavTreeEvents.d.ts.map +1 -0
  146. package/dist/types/src/types/index.d.ts +2 -2
  147. package/dist/types/src/types/index.d.ts.map +1 -1
  148. package/dist/types/src/types/schema.d.ts +4 -0
  149. package/dist/types/src/types/schema.d.ts.map +1 -1
  150. package/dist/types/src/util.d.ts +2 -2
  151. package/dist/types/src/util.d.ts.map +1 -1
  152. package/dist/types/tsconfig.tsbuildinfo +1 -1
  153. package/package.json +110 -50
  154. package/src/NavTreePlugin.node.ts +17 -0
  155. package/src/NavTreePlugin.test.ts +27 -0
  156. package/src/NavTreePlugin.tsx +16 -27
  157. package/src/NavTreePlugin.workerd.ts +16 -0
  158. package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +7 -7
  159. package/src/capabilities/index.ts +11 -5
  160. package/src/capabilities/{keyboard/keyboard.ts → keyboard.ts} +2 -2
  161. package/src/capabilities/operation-handler.ts +16 -0
  162. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +9 -9
  163. package/src/capabilities/{state/state.ts → state.ts} +14 -10
  164. package/src/components/NavTree/NavTree.stories.tsx +23 -24
  165. package/src/components/NavTree/NavTree.tsx +5 -4
  166. package/src/components/{NavTreeContext.tsx → NavTreeContext/NavTreeContext.tsx} +1 -1
  167. package/src/components/NavTreeContext/index.ts +5 -0
  168. package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +8 -10
  169. package/src/components/NavTreeItem/NavTreeItemAction.tsx +66 -48
  170. package/src/components/NavTreeItem/NavTreeItemColumns.tsx +22 -63
  171. package/src/components/Sidebar/L0Menu.tsx +62 -81
  172. package/src/components/Sidebar/L1Panel.tsx +99 -158
  173. package/src/components/Sidebar/L1Tabs.tsx +0 -1
  174. package/src/components/types.ts +1 -2
  175. package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
  176. package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +52 -58
  177. package/src/containers/CommandsDialogContent/index.ts +1 -3
  178. package/src/containers/CommandsTrigger/CommandsTrigger.tsx +7 -5
  179. package/src/containers/CommandsTrigger/index.ts +1 -3
  180. package/src/containers/NavTreeContainer/NavTreeContainer.tsx +28 -27
  181. package/src/containers/NavTreeContainer/index.ts +2 -3
  182. package/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.tsx +2 -2
  183. package/src/containers/NavTreeDocumentTitle/index.ts +1 -3
  184. package/src/containers/index.ts +1 -1
  185. package/src/experimental/Tree.stories.tsx +27 -27
  186. package/src/experimental/Tree.tsx +2 -2
  187. package/src/hooks/useActions.ts +26 -20
  188. package/src/hooks/useNavTreeModel.ts +13 -5
  189. package/src/hooks/useNavTreeState.ts +2 -9
  190. package/src/index.ts +1 -2
  191. package/src/meta.ts +22 -7
  192. package/src/operations/expose.ts +42 -0
  193. package/src/operations/index.ts +7 -0
  194. package/src/plugin.ts +11 -0
  195. package/src/testing/app-graph-builder.ts +47 -41
  196. package/src/testing/generator.ts +23 -28
  197. package/src/translations.ts +8 -10
  198. package/src/types/NavTreeCapabilities.ts +21 -0
  199. package/src/types/NavTreeEvents.ts +12 -0
  200. package/src/types/index.ts +3 -2
  201. package/src/types/schema.ts +4 -0
  202. package/src/util.ts +2 -2
  203. package/src/vite-env.d.ts +10 -0
  204. package/dist/lib/browser/CommandsDialogContent-A27AKTHH.mjs.map +0 -7
  205. package/dist/lib/browser/CommandsTrigger-HBZYQCGV.mjs.map +0 -7
  206. package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs +0 -12
  207. package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs.map +0 -7
  208. package/dist/lib/browser/NavTreeDocumentTitle-GEE3URWH.mjs.map +0 -7
  209. package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs.map +0 -7
  210. package/dist/lib/browser/chunk-DQCYMXEU.mjs +0 -1426
  211. package/dist/lib/browser/chunk-DQCYMXEU.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-H3OJ4WLF.mjs +0 -14
  213. package/dist/lib/browser/chunk-H3OJ4WLF.mjs.map +0 -7
  214. package/dist/lib/browser/chunk-X2HDG62A.mjs +0 -23
  215. package/dist/lib/browser/chunk-X2HDG62A.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-YKTYPINZ.mjs +0 -19
  217. package/dist/lib/browser/chunk-YKTYPINZ.mjs.map +0 -7
  218. package/dist/lib/browser/index.mjs +0 -141
  219. package/dist/lib/browser/index.mjs.map +0 -7
  220. package/dist/lib/browser/keyboard-OJZC54PK.mjs.map +0 -7
  221. package/dist/lib/browser/meta.json +0 -1
  222. package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs +0 -53
  223. package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs.map +0 -7
  224. package/dist/lib/browser/react-surface-AYHOAJ4I.mjs.map +0 -7
  225. package/dist/lib/browser/state-AC3EETN7.mjs.map +0 -7
  226. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  227. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  228. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  229. package/dist/types/src/capabilities/keyboard/index.d.ts +0 -3
  230. package/dist/types/src/capabilities/keyboard/index.d.ts.map +0 -1
  231. package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +0 -1
  232. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  233. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  234. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  235. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  236. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  237. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  238. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  239. package/dist/types/src/capabilities/state/index.d.ts +0 -3
  240. package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
  241. package/dist/types/src/capabilities/state/state.d.ts +0 -6
  242. package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
  243. package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
  244. package/dist/types/src/types/capabilities.d.ts +0 -16
  245. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  246. package/dist/types/src/types/events.d.ts +0 -5
  247. package/dist/types/src/types/events.d.ts.map +0 -1
  248. package/src/capabilities/app-graph-builder/index.ts +0 -7
  249. package/src/capabilities/keyboard/index.ts +0 -7
  250. package/src/capabilities/operation-resolver/index.ts +0 -7
  251. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -44
  252. package/src/capabilities/react-surface/index.ts +0 -7
  253. package/src/capabilities/state/index.ts +0 -7
  254. package/src/types/capabilities.ts +0 -21
  255. package/src/types/events.ts +0 -12
  256. /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
  257. /package/dist/types/src/capabilities/{keyboard/keyboard.d.ts → keyboard.d.ts} +0 -0
  258. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -12,38 +12,35 @@ import { Capabilities, Capability } from '@dxos/app-framework';
12
12
  import { withPluginManager } from '@dxos/app-framework/testing';
13
13
  import { useAtomCapability } from '@dxos/app-framework/ui';
14
14
  import { AppCapabilities, LayoutOperation } from '@dxos/app-toolkit';
15
- import { OperationResolver } from '@dxos/operation';
15
+ import { Operation, OperationHandlerSet } from '@dxos/compute';
16
16
  import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
17
- import { faker } from '@dxos/random';
17
+ import { random } from '@dxos/random';
18
18
  import { IconButton, Input, Main, Toolbar } from '@dxos/react-ui';
19
- import { withLayout, withTheme } from '@dxos/react-ui/testing';
20
19
  import { useAttention, useAttentionAttributes } from '@dxos/react-ui-attention';
21
20
  import { Stack, StackItem } from '@dxos/react-ui-stack';
21
+ import { withLayout } from '@dxos/react-ui/testing';
22
22
  import { mx } from '@dxos/ui-theme';
23
23
 
24
- import { NavTreeContainer } from '../../containers';
24
+ import { NavTreeContainer } from '#containers';
25
+ import { storybookGraphBuilders } from '#testing';
26
+ import { translations } from '#translations';
27
+
25
28
  import { NavTreePlugin } from '../../NavTreePlugin';
26
- import { storybookGraphBuilders } from '../../testing';
27
- import { translations } from '../../translations';
28
29
 
29
- faker.seed(1234);
30
+ random.seed(1234);
30
31
 
31
32
  const StoryState = Capability.make<Atom.Atom<{ tab: string }>>('story-state');
32
33
 
33
- // TODO(burdon): Fix outline (e.g., button in sidebar nav is clipped when focused).
34
- // TODO(burdon): Consider similar containment of: Table, Sheet, Kanban Column, Form, etc.
35
-
36
34
  const container = 'flex flex-col grow gap-2 p-4 rounded-md';
37
35
 
38
- // TODO(burdon): Factor out PlankHeader.
39
36
  const StoryPlankHeading = ({ attendableId }: { attendableId: string }) => {
40
37
  const { hasAttention } = useAttention(attendableId);
41
38
  console.log('hasAttention', hasAttention);
42
39
  return (
43
40
  <div className='flex p-1 items-center border-b border-separator'>
44
41
  <IconButton
45
- density='coarse'
46
- icon='ph--atom--regular'
42
+ density='lg'
43
+ icon='ph--circle--regular'
47
44
  label='Test'
48
45
  iconOnly
49
46
  variant={hasAttention ? 'primary' : 'ghost'}
@@ -81,7 +78,7 @@ const StoryPlank = ({ attendableId }: { attendableId: string }) => {
81
78
  <Toolbar.Button>Test</Toolbar.Button>
82
79
  </Toolbar.Root>
83
80
 
84
- <div className={mx(container, 'm-2 bg-active-surface')}>
81
+ <div className={mx(container, 'm-2 bg-current-surface')}>
85
82
  <Input.Root>
86
83
  <Input.Label>Level 1 (group)</Input.Label>
87
84
  </Input.Root>
@@ -120,7 +117,6 @@ const meta = {
120
117
  component: NavTreeContainer,
121
118
  render: DefaultStory,
122
119
  decorators: [
123
- withTheme(),
124
120
  withLayout({ layout: 'fullscreen' }),
125
121
  withPluginManager({
126
122
  plugins: [
@@ -132,20 +128,21 @@ const meta = {
132
128
  NavTreePlugin(),
133
129
  ],
134
130
  capabilities: () => {
135
- const storyStateAtom = Atom.make({ tab: 'space-0' }).pipe(Atom.keepAlive);
131
+ const storyStateAtom = Atom.make({ tab: 'root/space-0' }).pipe(Atom.keepAlive);
136
132
  return [
137
133
  Capability.contributes(StoryState, storyStateAtom),
138
134
  Capability.contributes(AppCapabilities.AppGraphBuilder, storybookGraphBuilders()),
139
- Capability.contributes(Capabilities.OperationResolver, [
140
- OperationResolver.make({
141
- operation: LayoutOperation.SwitchWorkspace,
142
- handler: ({ subject }) =>
135
+ Capability.contributes(
136
+ Capabilities.OperationHandler,
137
+ OperationHandlerSet.make(
138
+ Operation.withHandler(LayoutOperation.SwitchWorkspace, ({ subject }) =>
143
139
  Effect.gen(function* () {
144
140
  const registry: Registry.Registry = yield* Capability.get(Capabilities.AtomRegistry);
145
141
  registry.set(storyStateAtom, { tab: subject });
146
142
  }),
147
- }),
148
- ]),
143
+ ),
144
+ ),
145
+ ),
149
146
  ];
150
147
  },
151
148
  }),
@@ -164,8 +161,10 @@ export const Default: Story = {
164
161
  play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
165
162
  const canvas = within(canvasElement);
166
163
 
167
- // Find the element with treegrid role and click on its parent
168
- const treegridElement = await canvas.findByRole('treegrid');
164
+ // Plugin startup is async; the treegrid only appears after the Startup event
165
+ // fires and the graph is built. Use a generous timeout so slower CI runners
166
+ // don't race the default 1 s limit.
167
+ const treegridElement = await canvas.findByRole('treegrid', {}, { timeout: 10000 });
169
168
  const treegridParent = treegridElement.parentElement;
170
169
  if (treegridParent) {
171
170
  await userEvent.click(treegridParent);
@@ -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
 
@@ -6,7 +6,7 @@ import { createContext, useContext } from 'react';
6
6
 
7
7
  import { raise } from '@dxos/debug';
8
8
 
9
- import { type NavTreeContextValue } from './types';
9
+ import { type NavTreeContextValue } from '../types';
10
10
 
11
11
  export const NavTreeContext = createContext<NavTreeContextValue | null>(null);
12
12
 
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './NavTreeContext';
@@ -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: {
@@ -2,70 +2,82 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React from 'react';
5
+ import React, { useCallback } from 'react';
6
6
 
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;
31
+ path?: string[];
18
32
  caller?: string;
19
33
  monolithic?: boolean;
20
34
  menuActions?: Node.Action[];
21
35
  };
22
36
 
23
- 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
+ );
24
46
 
25
- const fineActionButtonProps = {
26
- size: 4 as const,
27
- density: 'fine' as const,
28
- };
29
- const coarseActionButtonProps = {
30
- size: 5 as const,
31
- density: 'coarse' as const,
32
- };
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
+ );
33
67
 
34
- export const NavTreeItemActionDropdownMenu = ({
35
- parent,
36
- label,
37
- icon,
38
- testId,
39
- menuActions,
40
- caller,
41
- }: NavTreeItemActionMenuProps) => {
42
- const { t } = useTranslation(meta.id);
43
- const density = useDensityContext();
44
- const runAction = useActionRunner();
45
-
46
- return (
47
- <Menu.Root caller={caller} onAction={runAction}>
48
- <Menu.Trigger asChild>
49
- <IconButton
50
- {...(density === 'coarse' ? coarseActionButtonProps : fineActionButtonProps)}
51
- classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
52
- variant='ghost'
53
- icon={icon ?? fallbackIcon}
54
- iconOnly
55
- label={toLocalizedString(label, t)}
56
- data-testid={testId}
57
- />
58
- </Menu.Trigger>
59
- <Menu.Content group={parent} items={menuActions as MenuItem[]} />
60
- </Menu.Root>
61
- );
62
- };
68
+ NavTreeItemActionDropdownMenu.displayName = 'NavTreeItemActionDropdownMenu';
63
69
 
64
70
  export const NavTreeItemMonolithicAction = (
65
- props: Node.Action & { parent: Node.Node; onAction?: (action: Node.Action) => void; baseLabel: string },
71
+ props: Node.Action & {
72
+ parent: Node.Node;
73
+ path?: string[];
74
+ onAction?: (action: Node.Action) => void;
75
+ baseLabel: string;
76
+ },
66
77
  ) => {
67
78
  const {
68
79
  parent,
80
+ path,
69
81
  properties: { disabled, caller, testId, icon, variant = 'ghost', iconOnly = true } = { label: 'never' },
70
82
  baseLabel,
71
83
  } = props;
@@ -73,7 +85,7 @@ export const NavTreeItemMonolithicAction = (
73
85
  const runAction = useActionRunner();
74
86
  return (
75
87
  <IconButton
76
- {...(density === 'coarse' ? coarseActionButtonProps : fineActionButtonProps)}
88
+ {...(density === 'lg' ? lgActionButtonProps : mdActionButtonProps)}
77
89
  variant={variant}
78
90
  classNames={[
79
91
  'shrink-0',
@@ -91,22 +103,28 @@ export const NavTreeItemMonolithicAction = (
91
103
  return;
92
104
  }
93
105
 
94
- void runAction(props, caller ? { parent, caller } : { parent });
106
+ void runAction(props, caller ? { parent, caller, path } : { parent, path });
95
107
  }}
96
108
  data-testid={testId}
97
109
  />
98
110
  );
99
111
  };
100
112
 
101
- export const NavTreeItemAction = ({ monolithic, menuActions, parent: node, ...props }: NavTreeItemActionMenuProps) => {
113
+ export const NavTreeItemAction = ({
114
+ monolithic,
115
+ menuActions,
116
+ menuType,
117
+ parent,
118
+ path,
119
+ ...props
120
+ }: NavTreeItemActionMenuProps) => {
102
121
  const { t } = useTranslation(meta.id);
103
122
 
104
123
  const monolithicAction = menuActions?.length === 1 && menuActions[0];
105
124
  const baseLabel = toLocalizedString(monolithicAction ? monolithicAction.properties!.label : props.label, t);
106
-
107
125
  return monolithic && menuActions?.length === 1 ? (
108
- <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={node} {...menuActions[0]} />
126
+ <NavTreeItemMonolithicAction baseLabel={baseLabel} parent={parent} path={path} {...menuActions[0]} />
109
127
  ) : (
110
- <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={node} menuActions={menuActions} />
128
+ <NavTreeItemActionDropdownMenu {...props} label={baseLabel} parent={parent} path={path} menuActions={menuActions} />
111
129
  );
112
130
  };
@@ -4,88 +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
- const ActionRoot = popoverAnchorId === `dxos.org/ui/${NAV_TREE_ITEM}/${item.id}` ? Popover.Anchor : Fragment;
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
- monolithic={Node.isAction(primaryAction)}
71
- menuActions={primaryMenuActions}
72
- menuType={primaryAction.properties?.menuType}
73
- caller={NAV_TREE_ITEM}
74
- />
75
- </Treegrid.Cell>
76
- ) : (
77
- <Treegrid.Cell role='none' />
78
- )}
28
+ <div className='contents dx-app-no-drag'>
79
29
  <ActionRoot>
80
- {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 ? (
81
40
  <Treegrid.Cell classNames='contents'>
82
- <NavTreeItemAction
41
+ <NavTreeItemActionDropdownMenu
83
42
  testId={`navtree.treeItem.actionsLevel${level}`}
84
- label={t('tree item actions label')}
43
+ label={t('tree-item-actions.label')}
85
44
  icon='ph--dots-three-vertical--regular'
86
45
  parent={item}
87
- menuActions={actions}
88
- menuType='dropdown'
46
+ path={path}
47
+ menuActions={allActions}
89
48
  caller={NAV_TREE_ITEM}
90
49
  />
91
50
  </Treegrid.Cell>