@dxos/plugin-navtree 0.8.4-main.b97322e → 0.8.4-main.bcb3aa67d6

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 (202) hide show
  1. package/dist/lib/browser/index.mjs +168 -115
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/NavTreePlugin.d.ts +2 -1
  5. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  6. package/dist/types/src/capabilities/app-graph-builder.d.ts +4 -2
  7. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  8. package/dist/types/src/capabilities/index.d.ts +7 -105
  9. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  10. package/dist/types/src/capabilities/keyboard.d.ts +3 -2
  11. package/dist/types/src/capabilities/keyboard.d.ts.map +1 -1
  12. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  13. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  14. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  15. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  16. package/dist/types/src/capabilities/state.d.ts +4 -18
  17. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  18. package/dist/types/src/components/NavTree/NavTree.d.ts +12 -5
  19. package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
  20. package/dist/types/src/components/NavTree/NavTree.stories.d.ts +26 -5
  21. package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
  22. package/dist/types/src/components/{NavTreeContext.d.ts → NavTreeContext/NavTreeContext.d.ts} +1 -1
  23. package/dist/types/src/components/NavTreeContext/NavTreeContext.d.ts.map +1 -0
  24. package/dist/types/src/components/NavTreeContext/index.d.ts +2 -0
  25. package/dist/types/src/components/NavTreeContext/index.d.ts.map +1 -0
  26. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +17 -9
  27. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
  28. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +33 -4
  29. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
  30. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts +2 -2
  31. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
  32. package/dist/types/src/components/Sidebar/L0Menu.d.ts +10 -5
  33. package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
  34. package/dist/types/src/components/Sidebar/L1Panel.d.ts +4 -8
  35. package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
  36. package/dist/types/src/components/Sidebar/L1Tabs.d.ts +13 -0
  37. package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -0
  38. package/dist/types/src/components/Sidebar/index.d.ts +1 -0
  39. package/dist/types/src/components/Sidebar/index.d.ts.map +1 -1
  40. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
  41. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts +8 -5
  42. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
  43. package/dist/types/src/components/index.d.ts +0 -3
  44. package/dist/types/src/components/index.d.ts.map +1 -1
  45. package/dist/types/src/components/types.d.ts +8 -16
  46. package/dist/types/src/components/types.d.ts.map +1 -1
  47. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts +6 -0
  48. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -0
  49. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +29 -0
  50. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -0
  51. package/dist/types/src/containers/CommandsDialogContent/index.d.ts +3 -0
  52. package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -0
  53. package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -0
  54. package/dist/types/src/containers/CommandsTrigger/index.d.ts +3 -0
  55. package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -0
  56. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts +9 -0
  57. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -0
  58. package/dist/types/src/containers/NavTreeContainer/index.d.ts +3 -0
  59. package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -0
  60. package/dist/types/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.d.ts +1 -1
  61. package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -0
  62. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +3 -0
  63. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -0
  64. package/dist/types/src/containers/index.d.ts +7 -0
  65. package/dist/types/src/containers/index.d.ts.map +1 -0
  66. package/dist/types/src/experimental/Tree.d.ts +1 -2
  67. package/dist/types/src/experimental/Tree.d.ts.map +1 -1
  68. package/dist/types/src/experimental/Tree.stories.d.ts +23 -6
  69. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
  70. package/dist/types/src/hooks/index.d.ts +5 -0
  71. package/dist/types/src/hooks/index.d.ts.map +1 -0
  72. package/dist/types/src/hooks/useActions.d.ts +5 -0
  73. package/dist/types/src/hooks/useActions.d.ts.map +1 -0
  74. package/dist/types/src/hooks/useLoadDescendents.d.ts +6 -0
  75. package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -0
  76. package/dist/types/src/hooks/useNavTreeModel.d.ts +7 -0
  77. package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -0
  78. package/dist/types/src/hooks/useNavTreeState.d.ts +22 -0
  79. package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -0
  80. package/dist/types/src/index.d.ts +1 -2
  81. package/dist/types/src/index.d.ts.map +1 -1
  82. package/dist/types/src/meta.d.ts +3 -4
  83. package/dist/types/src/meta.d.ts.map +1 -1
  84. package/dist/types/src/operations/expose.d.ts +5 -0
  85. package/dist/types/src/operations/expose.d.ts.map +1 -0
  86. package/dist/types/src/operations/index.d.ts +3 -0
  87. package/dist/types/src/operations/index.d.ts.map +1 -0
  88. package/dist/types/src/testing/app-graph-builder.d.ts +2 -3
  89. package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
  90. package/dist/types/src/testing/generator.d.ts +5 -6
  91. package/dist/types/src/testing/generator.d.ts.map +1 -1
  92. package/dist/types/src/testing/update-state.d.ts +2 -2
  93. package/dist/types/src/testing/update-state.d.ts.map +1 -1
  94. package/dist/types/src/translations.d.ts +9 -9
  95. package/dist/types/src/translations.d.ts.map +1 -1
  96. package/dist/types/src/types/capabilities.d.ts +16 -0
  97. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  98. package/dist/types/src/types/events.d.ts +5 -0
  99. package/dist/types/src/types/events.d.ts.map +1 -0
  100. package/dist/types/src/types/index.d.ts +4 -0
  101. package/dist/types/src/types/index.d.ts.map +1 -0
  102. package/dist/types/src/{types.d.ts → types/schema.d.ts} +10 -9
  103. package/dist/types/src/types/schema.d.ts.map +1 -0
  104. package/dist/types/src/util.d.ts +12 -9
  105. package/dist/types/src/util.d.ts.map +1 -1
  106. package/dist/types/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +67 -54
  108. package/src/NavTreePlugin.tsx +65 -84
  109. package/src/capabilities/app-graph-builder.ts +34 -44
  110. package/src/capabilities/index.ts +10 -8
  111. package/src/capabilities/keyboard.ts +58 -51
  112. package/src/capabilities/operation-handler.ts +16 -0
  113. package/src/capabilities/react-surface.tsx +45 -37
  114. package/src/capabilities/state.ts +129 -84
  115. package/src/components/NavTree/NavTree.stories.tsx +106 -99
  116. package/src/components/NavTree/NavTree.tsx +70 -35
  117. package/src/components/{NavTreeContext.tsx → NavTreeContext/NavTreeContext.tsx} +1 -1
  118. package/src/components/NavTreeContext/index.ts +5 -0
  119. package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +19 -13
  120. package/src/components/NavTreeItem/NavTreeItemAction.tsx +71 -47
  121. package/src/components/NavTreeItem/NavTreeItemColumns.tsx +70 -38
  122. package/src/components/Sidebar/L0Menu.tsx +171 -206
  123. package/src/components/Sidebar/L1Panel.tsx +270 -135
  124. package/src/components/Sidebar/L1Tabs.tsx +43 -0
  125. package/src/components/Sidebar/index.ts +1 -0
  126. package/src/components/UserAccountAvatar/UserAccountAvatar.stories.tsx +9 -9
  127. package/src/components/UserAccountAvatar/UserAccountAvatar.tsx +20 -12
  128. package/src/components/index.ts +1 -3
  129. package/src/components/types.ts +15 -19
  130. package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
  131. package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +131 -0
  132. package/src/containers/CommandsDialogContent/index.ts +7 -0
  133. package/src/containers/CommandsTrigger/CommandsTrigger.tsx +28 -0
  134. package/src/containers/CommandsTrigger/index.ts +7 -0
  135. package/src/containers/NavTreeContainer/NavTreeContainer.tsx +271 -0
  136. package/src/containers/NavTreeContainer/index.ts +6 -0
  137. package/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.tsx +5 -4
  138. package/src/containers/NavTreeDocumentTitle/index.ts +7 -0
  139. package/src/containers/index.ts +12 -0
  140. package/src/experimental/Tree.stories.tsx +78 -83
  141. package/src/experimental/Tree.tsx +6 -23
  142. package/src/hooks/index.ts +8 -0
  143. package/src/hooks/useActions.ts +34 -0
  144. package/src/hooks/useLoadDescendents.ts +23 -0
  145. package/src/hooks/useNavTreeModel.ts +118 -0
  146. package/src/hooks/useNavTreeState.ts +42 -0
  147. package/src/index.ts +1 -2
  148. package/src/meta.ts +11 -8
  149. package/src/operations/expose.ts +42 -0
  150. package/src/operations/index.ts +7 -0
  151. package/src/testing/app-graph-builder.ts +166 -237
  152. package/src/testing/generator.ts +20 -18
  153. package/src/testing/update-state.ts +6 -6
  154. package/src/translations.ts +9 -9
  155. package/src/types/capabilities.ts +21 -0
  156. package/src/types/events.ts +12 -0
  157. package/src/types/index.ts +7 -0
  158. package/src/{types.ts → types/schema.ts} +9 -8
  159. package/src/util.ts +26 -33
  160. package/dist/lib/browser/app-graph-builder-5J4LRWDX.mjs +0 -45
  161. package/dist/lib/browser/app-graph-builder-5J4LRWDX.mjs.map +0 -7
  162. package/dist/lib/browser/chunk-ERDGQTH5.mjs +0 -16
  163. package/dist/lib/browser/chunk-ERDGQTH5.mjs.map +0 -7
  164. package/dist/lib/browser/chunk-SICQTLXC.mjs +0 -1442
  165. package/dist/lib/browser/chunk-SICQTLXC.mjs.map +0 -7
  166. package/dist/lib/browser/chunk-WCARAZ7J.mjs +0 -15
  167. package/dist/lib/browser/chunk-WCARAZ7J.mjs.map +0 -7
  168. package/dist/lib/browser/intent-resolver-3XYN2CBU.mjs +0 -47
  169. package/dist/lib/browser/intent-resolver-3XYN2CBU.mjs.map +0 -7
  170. package/dist/lib/browser/keyboard-QRS6WOQH.mjs +0 -51
  171. package/dist/lib/browser/keyboard-QRS6WOQH.mjs.map +0 -7
  172. package/dist/lib/browser/react-surface-WURHCBQQ.mjs +0 -51
  173. package/dist/lib/browser/react-surface-WURHCBQQ.mjs.map +0 -7
  174. package/dist/lib/browser/state-54DY3DOY.mjs +0 -117
  175. package/dist/lib/browser/state-54DY3DOY.mjs.map +0 -7
  176. package/dist/types/src/capabilities/capabilities.d.ts +0 -21
  177. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  178. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  179. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  180. package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts +0 -5
  181. package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts.map +0 -1
  182. package/dist/types/src/components/CommandsDialog/CommandsTrigger.d.ts.map +0 -1
  183. package/dist/types/src/components/CommandsDialog/index.d.ts +0 -3
  184. package/dist/types/src/components/CommandsDialog/index.d.ts.map +0 -1
  185. package/dist/types/src/components/NavTreeContainer.d.ts +0 -9
  186. package/dist/types/src/components/NavTreeContainer.d.ts.map +0 -1
  187. package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
  188. package/dist/types/src/components/NavTreeDocumentTitle.d.ts.map +0 -1
  189. package/dist/types/src/events.d.ts +0 -4
  190. package/dist/types/src/events.d.ts.map +0 -1
  191. package/dist/types/src/hooks.d.ts +0 -3
  192. package/dist/types/src/hooks.d.ts.map +0 -1
  193. package/dist/types/src/types.d.ts.map +0 -1
  194. package/src/capabilities/capabilities.ts +0 -20
  195. package/src/capabilities/intent-resolver.ts +0 -37
  196. package/src/components/CommandsDialog/CommandsDialog.tsx +0 -118
  197. package/src/components/CommandsDialog/CommandsTrigger.tsx +0 -35
  198. package/src/components/CommandsDialog/index.ts +0 -6
  199. package/src/components/NavTreeContainer.tsx +0 -313
  200. package/src/events.ts +0 -11
  201. package/src/hooks.ts +0 -21
  202. /package/dist/types/src/{components/CommandsDialog → containers/CommandsTrigger}/CommandsTrigger.d.ts +0 -0
@@ -2,15 +2,15 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Rx } from '@effect-rx/rx-react';
6
- import { Option, pipe } from 'effect';
5
+ import { Atom } from '@effect-atom/atom-react';
6
+ import * as Effect from 'effect/Effect';
7
7
 
8
- import { type PluginContext } from '@dxos/app-framework';
8
+ import { type BuilderExtensions } from '@dxos/app-graph';
9
9
  import { log } from '@dxos/log';
10
- import { createExtension, ROOT_ID, type BuilderExtensions } from '@dxos/plugin-graph';
10
+ import { GraphBuilder, Node, NodeMatcher } from '@dxos/plugin-graph';
11
11
  import { faker } from '@dxos/random';
12
12
 
13
- export const storybookGraphBuilders = (context: PluginContext): BuilderExtensions => {
13
+ export const storybookGraphBuilders = (): BuilderExtensions => {
14
14
  const propertiesCache = new Map<string, Record<string, unknown>>();
15
15
  const getProperties = (id: string, defaults: Record<string, unknown>) => {
16
16
  const cached = propertiesCache.get(id);
@@ -22,249 +22,178 @@ export const storybookGraphBuilders = (context: PluginContext): BuilderExtension
22
22
  return defaults;
23
23
  };
24
24
 
25
- return [
26
- // Create app menu actions.
27
- createExtension({
28
- id: 'app-menu',
29
- actions: (node) =>
30
- Rx.make((get) =>
31
- pipe(
32
- get(node),
33
- Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
34
- Option.map((node) => {
35
- return [
36
- ...Array.from({ length: 5 }, (_, i) => ({
37
- id: `${node.id}/action-${i}`,
38
- data: () => {
39
- log.info('action', { id: node.id, index: i });
40
- },
41
- properties: {
42
- label: `Action ${i}`,
43
- icon: faker.properties.icon(),
44
- disposition: 'menu',
45
- },
46
- })),
47
- ];
48
- }),
49
- Option.getOrElse(() => []),
25
+ return Effect.runSync(
26
+ Effect.all([
27
+ // Create app menu actions.
28
+ GraphBuilder.createExtension({
29
+ id: 'app-menu',
30
+ match: NodeMatcher.whenRoot,
31
+ actions: () =>
32
+ Effect.succeed(
33
+ Array.from({ length: 5 }, (_, i) => ({
34
+ id: `action-${i}`,
35
+ data: Effect.fnUntraced(function* () {
36
+ log.info('action', { id: 'app-menu', index: i });
37
+ }),
38
+ properties: {
39
+ label: `Action ${i}`,
40
+ icon: faker.properties.icon(),
41
+ disposition: 'menu',
42
+ },
43
+ })),
50
44
  ),
51
- ),
52
- }),
53
- // Create user account node.
54
- createExtension({
55
- id: 'user-account',
56
- connector: (node) =>
57
- Rx.make((get) =>
58
- pipe(
59
- get(node),
60
- Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
61
- Option.map(() => {
62
- return [
63
- {
64
- id: 'user-account',
65
- type: 'user-account',
45
+ }),
46
+ // Create user account node.
47
+ GraphBuilder.createExtension({
48
+ id: 'user-account',
49
+ match: NodeMatcher.whenRoot,
50
+ connector: () =>
51
+ Effect.succeed([
52
+ Node.make({
53
+ id: 'user-account',
54
+ type: 'user-account',
55
+ properties: {
56
+ label: 'User profile',
57
+ icon: 'ph--user--regular',
58
+ disposition: 'user-account',
59
+ userId: '1234567890ABCDEF',
60
+ hue: faker.properties.hue(),
61
+ emoji: faker.properties.emoji(),
62
+ status: 'active',
63
+ },
64
+ nodes: [
65
+ Node.make({
66
+ id: 'profile',
67
+ type: 'profile',
66
68
  properties: {
67
- label: 'User Account',
69
+ label: 'Profile',
68
70
  icon: 'ph--user--regular',
69
- disposition: 'user-account',
70
- userId: '1234567890ABCDEF',
71
- hue: faker.properties.hue(),
72
- emoji: faker.properties.emoji(),
73
- status: 'active',
74
71
  },
75
- nodes: [
76
- {
77
- id: 'profile',
78
- type: 'profile',
79
- properties: {
80
- label: 'Profile',
81
- icon: 'ph--user--regular',
82
- },
83
- },
84
- {
85
- id: 'devices',
86
- type: 'devices',
87
- properties: {
88
- label: 'Devices',
89
- icon: 'ph--devices--regular',
90
- },
91
- },
92
- {
93
- id: 'security',
94
- type: 'security',
95
- properties: {
96
- label: 'Security',
97
- icon: 'ph--key--regular',
98
- },
99
- },
100
- ],
101
- },
102
- ];
103
- }),
104
- Option.getOrElse(() => []),
105
- ),
106
- ),
107
- }),
108
- // TODO(wittjosiah): This group node probably is unnecessary now with the flat L0 structure.
109
- // Create spaces group node.
110
- createExtension({
111
- id: 'spaces-root',
112
- position: 'hoist',
113
- connector: (node) =>
114
- Rx.make((get) =>
115
- pipe(
116
- get(node),
117
- Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
118
- Option.map(() => {
119
- return [
120
- {
121
- id: 'spaces-root',
122
- type: 'spaces-root',
72
+ }),
73
+ Node.make({
74
+ id: 'devices',
75
+ type: 'devices',
76
+ properties: {
77
+ label: 'Devices',
78
+ icon: 'ph--devices--regular',
79
+ },
80
+ }),
81
+ Node.make({
82
+ id: 'security',
83
+ type: 'security',
123
84
  properties: {
124
- label: 'Spaces',
125
- icon: 'ph--planet--regular',
126
- role: 'branch',
127
- disposition: 'collection',
85
+ label: 'Security',
86
+ icon: 'ph--key--regular',
128
87
  },
129
- },
130
- ];
88
+ }),
89
+ ],
131
90
  }),
132
- Option.getOrElse(() => []),
133
- ),
134
- ),
135
- }),
136
- // Create space nodes.
137
- createExtension({
138
- id: 'spaces',
139
- connector: (node) => {
140
- const count = Rx.make((get) => {
141
- let value = 3;
142
- const interval = setInterval(() => {
143
- if (value >= 10) {
144
- clearInterval(interval);
145
- return;
146
- }
91
+ ]),
92
+ }),
93
+ // Create space (workspace) nodes directly under root.
94
+ GraphBuilder.createExtension({
95
+ id: 'spaces',
96
+ match: NodeMatcher.whenRoot,
97
+ connector: (_, get) =>
98
+ Effect.sync(() => {
99
+ const count = Atom.make((get) => {
100
+ let value = 3;
101
+ const interval = setInterval(() => {
102
+ if (value >= 10) {
103
+ clearInterval(interval);
104
+ return;
105
+ }
147
106
 
148
- value++;
149
- get.setSelf(value);
150
- }, 5000);
151
- get.addFinalizer(() => clearInterval(interval));
152
- return value;
153
- });
107
+ value++;
108
+ get.setSelf(value);
109
+ }, 5000);
110
+ get.addFinalizer(() => clearInterval(interval));
111
+ return value;
112
+ });
154
113
 
155
- return Rx.make((get) =>
156
- pipe(
157
- get(node),
158
- Option.flatMap((node) => (node.id === 'spaces-root' ? Option.some(node) : Option.none())),
159
- Option.map(() => {
160
- return [
161
- ...Array.from({ length: get(count) }, (_, i) => ({
162
- id: `space-${i}`,
163
- type: 'space',
164
- properties: getProperties(`space-${i}`, {
165
- label: `Space ${i}`,
166
- icon: faker.properties.icon(),
167
- hue: faker.properties.hue(),
168
- }),
169
- })),
170
- ];
171
- }),
172
- Option.getOrElse(() => []),
173
- ),
174
- );
175
- },
176
- }),
177
- // Create space actions.
178
- createExtension({
179
- id: 'space-actions',
180
- actions: (node) =>
181
- Rx.make((get) =>
182
- pipe(
183
- get(node),
184
- Option.flatMap((node) => (node.type === 'space' ? Option.some(node) : Option.none())),
185
- Option.map((node) => {
186
- return [
187
- ...Array.from({ length: 5 }, (_, i) => ({
188
- id: `${node.id}/action-${i}`,
189
- data: () => {
190
- log.info('action', { id: node.id, index: i });
191
- },
192
- properties: getProperties(`${node.id}/action-${i}`, {
193
- label: `Action ${i}`,
194
- icon: faker.properties.icon(),
195
- }),
196
- })),
197
- ];
198
- }),
199
- Option.getOrElse(() => []),
114
+ return Array.from({ length: get(count) }, (_, i) =>
115
+ Node.make({
116
+ id: `space-${i}`,
117
+ type: 'space',
118
+ properties: getProperties(`space-${i}`, {
119
+ label: `Space ${i}`,
120
+ icon: faker.properties.icon(),
121
+ hue: faker.properties.hue(),
122
+ disposition: 'workspace',
123
+ }),
124
+ }),
125
+ );
126
+ }),
127
+ }),
128
+ // Create space actions.
129
+ GraphBuilder.createExtension({
130
+ id: 'space-actions',
131
+ match: NodeMatcher.whenNodeType('space'),
132
+ actions: () =>
133
+ Effect.succeed(
134
+ Array.from({ length: 5 }, (_, i) => ({
135
+ id: `action-${i}`,
136
+ data: Effect.fnUntraced(function* () {
137
+ log.info('action', { id: 'space-actions', index: i });
138
+ }),
139
+ properties: getProperties(`action-${i}`, {
140
+ label: `Action ${i}`,
141
+ icon: faker.properties.icon(),
142
+ }),
143
+ })),
200
144
  ),
201
- ),
202
- }),
203
- // Create object nodes.
204
- createExtension({
205
- id: 'objects',
206
- connector: (node) => {
207
- const count = Rx.make((get) => {
208
- let value = 3;
209
- const interval = setInterval(() => {
210
- if (value >= 20) {
211
- clearInterval(interval);
212
- return;
213
- }
145
+ }),
146
+ // Create object nodes.
147
+ GraphBuilder.createExtension({
148
+ id: 'objects',
149
+ match: NodeMatcher.whenNodeType('space'),
150
+ connector: (_, get) =>
151
+ Effect.sync(() => {
152
+ const count = Atom.make((get) => {
153
+ let value = 3;
154
+ const interval = setInterval(() => {
155
+ if (value >= 20) {
156
+ clearInterval(interval);
157
+ return;
158
+ }
214
159
 
215
- value++;
216
- get.setSelf(value);
217
- }, 5000);
218
- get.addFinalizer(() => clearInterval(interval));
219
- return value;
220
- });
160
+ value++;
161
+ get.setSelf(value);
162
+ }, 5000);
163
+ get.addFinalizer(() => clearInterval(interval));
164
+ return value;
165
+ });
221
166
 
222
- return Rx.make((get) =>
223
- pipe(
224
- get(node),
225
- Option.flatMap((node) => (node.type === 'space' ? Option.some(node) : Option.none())),
226
- Option.map((node) => {
227
- return [
228
- ...Array.from({ length: get(count) }, (_, i) => ({
229
- id: `${node.id}/object-${i}`,
230
- type: 'object',
231
- properties: getProperties(`${node.id}/object-${i}`, {
232
- label: `Object ${i}`,
233
- icon: faker.properties.icon(),
234
- }),
235
- })),
236
- ];
237
- }),
238
- Option.getOrElse(() => []),
239
- ),
240
- );
241
- },
242
- }),
243
- // Create object actions.
244
- createExtension({
245
- id: 'object-actions',
246
- actions: (node) =>
247
- Rx.make((get) =>
248
- pipe(
249
- get(node),
250
- Option.flatMap((node) => (node.type === 'object' ? Option.some(node) : Option.none())),
251
- Option.map((node) => {
252
- return [
253
- ...Array.from({ length: 5 }, (_, i) => ({
254
- id: `${node.id}/action-${i}`,
255
- data: () => {
256
- log.info('action', { id: node.id, index: i });
257
- },
258
- properties: getProperties(`${node.id}/action-${i}`, {
259
- label: `Action ${i}`,
260
- icon: faker.properties.icon(),
261
- }),
262
- })),
263
- ];
264
- }),
265
- Option.getOrElse(() => []),
167
+ return Array.from({ length: get(count) }, (_, i) =>
168
+ Node.make({
169
+ id: `object-${i}`,
170
+ type: 'object',
171
+ properties: getProperties(`object-${i}`, {
172
+ label: `Object ${i}`,
173
+ icon: faker.properties.icon(),
174
+ }),
175
+ }),
176
+ );
177
+ }),
178
+ }),
179
+ // Create object actions.
180
+ GraphBuilder.createExtension({
181
+ id: 'object-actions',
182
+ match: NodeMatcher.whenNodeType('object'),
183
+ actions: () =>
184
+ Effect.succeed(
185
+ Array.from({ length: 5 }, (_, i) => ({
186
+ id: `action-${i}`,
187
+ data: Effect.fnUntraced(function* () {
188
+ log.info('action', { id: 'object-actions', index: i });
189
+ }),
190
+ properties: getProperties(`action-${i}`, {
191
+ label: `Action ${i}`,
192
+ icon: faker.properties.icon(),
193
+ }),
194
+ })),
266
195
  ),
267
- ),
268
- }),
269
- ];
196
+ }),
197
+ ]),
198
+ );
270
199
  };
@@ -2,11 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import * as Schema from 'effect/Schema';
6
6
 
7
- import { type NodeArg } from '@dxos/app-graph';
8
- import { type Live, Obj, Type } from '@dxos/echo';
9
- import { TypedObject } from '@dxos/echo-schema';
7
+ import { type Node } from '@dxos/app-graph';
8
+ import { Obj, Type } from '@dxos/echo';
9
+ import { TestSchema } from '@dxos/echo/testing';
10
10
  import { faker } from '@dxos/random';
11
11
  import { range } from '@dxos/util';
12
12
 
@@ -17,12 +17,12 @@ import { range } from '@dxos/util';
17
17
  export type TestItem = { id: string; type: string } & Record<string, any>;
18
18
 
19
19
  type ObjectDataGenerator = {
20
- createSchema?: () => Schema.Schema.AnyNoContext;
20
+ createSchema?: () => Type.AnyObj;
21
21
  createData: () => any;
22
22
  };
23
23
 
24
- type ObjectFactory<T extends Live<any>> = {
25
- schema?: Schema.Schema.AnyNoContext; // TODO(burdon): Support both typed and expando schema.
24
+ type ObjectFactory<T> = {
25
+ schema?: Type.AnyObj; // TODO(burdon): Support both typed and expando schema.
26
26
  createObject: () => T;
27
27
  };
28
28
 
@@ -32,7 +32,7 @@ const createFactory = ({ createSchema, createData }: ObjectDataGenerator) => {
32
32
  const schema = createSchema?.();
33
33
  return {
34
34
  schema,
35
- createObject: () => (schema ? Obj.make(schema, createData()) : Obj.make(Type.Expando, createData())),
35
+ createObject: () => (schema ? Obj.make(schema, createData()) : Obj.make(TestSchema.Expando, createData())),
36
36
  };
37
37
  };
38
38
 
@@ -58,15 +58,17 @@ export const defaultGenerators: { [type: string]: ObjectDataGenerator } = {
58
58
 
59
59
  project: {
60
60
  createSchema: () =>
61
- class ProjectType extends TypedObject({
62
- typename: 'example.com/type/Project',
63
- version: '0.1.0',
64
- })({
61
+ Schema.Struct({
65
62
  title: Schema.String,
66
63
  repo: Schema.String,
67
64
  status: Schema.String,
68
65
  priority: Schema.Number,
69
- }) {},
66
+ }).pipe(
67
+ Type.object({
68
+ typename: 'com.example.type.project',
69
+ version: '0.1.0',
70
+ }),
71
+ ),
70
72
 
71
73
  createData: () => ({
72
74
  title: faker.commerce.productName(),
@@ -92,7 +94,7 @@ export class TestObjectGenerator {
92
94
  }, {});
93
95
  }
94
96
 
95
- get schema(): Schema.Schema.AnyNoContext[] {
97
+ get schema(): Type.AnyObj[] {
96
98
  return Object.values(this.factories).map((f) => f.schema!);
97
99
  }
98
100
 
@@ -140,7 +142,7 @@ export const createTree = () => {
140
142
  properties: {
141
143
  label: l0.title,
142
144
  icon: 'ph--horse--regular',
143
- disposition: 'collection',
145
+ disposition: 'workspace',
144
146
  },
145
147
  nodes: [
146
148
  ...[...Array(4)].map(() => {
@@ -173,7 +175,7 @@ export const createTree = () => {
173
175
  },
174
176
  },
175
177
  ],
176
- } satisfies NodeArg<any>;
178
+ } satisfies Node.NodeArg<any>;
177
179
  }),
178
180
  {
179
181
  id: `${faker.string.uuid()}__a1`,
@@ -194,9 +196,9 @@ export const createTree = () => {
194
196
  },
195
197
  },
196
198
  ],
197
- } satisfies NodeArg<any>;
199
+ } satisfies Node.NodeArg<any>;
198
200
  }),
199
- } satisfies NodeArg<any>;
201
+ } satisfies Node.NodeArg<any>;
200
202
 
201
203
  return initialContent;
202
204
  };
@@ -4,22 +4,22 @@
4
4
 
5
5
  import { type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
6
6
 
7
- import { type NodeArg } from '@dxos/app-graph';
7
+ import { type Node } from '@dxos/app-graph';
8
8
  import { log } from '@dxos/log';
9
9
  import { type TreeData } from '@dxos/react-ui-list';
10
10
 
11
- const removeItem = (tree: NodeArg<any>, source: TreeData) => {
11
+ const removeItem = (tree: Node.NodeArg<any>, source: TreeData) => {
12
12
  const parent = getNode(tree, source.path.slice(1, -1));
13
- const index = parent.nodes!.findIndex(({ id }) => id === source.id);
13
+ const index = parent.nodes!.findIndex((node: Node.NodeArg<any>) => node.id === source.id);
14
14
  const item = parent.nodes![index];
15
15
  parent.nodes!.splice(index, 1);
16
16
  return item;
17
17
  };
18
18
 
19
- const getNode = (tree: NodeArg<any>, path: string[]) => {
19
+ const getNode = (tree: Node.NodeArg<any>, path: string[]) => {
20
20
  let node = tree;
21
21
  for (const part of path) {
22
- node = node.nodes!.find(({ id }) => id === part)!;
22
+ node = node.nodes!.find((n: Node.NodeArg<any>) => n.id === part)!;
23
23
  }
24
24
  return node;
25
25
  };
@@ -31,7 +31,7 @@ export const updateState = ({
31
31
  source,
32
32
  target,
33
33
  }: {
34
- state: NodeArg<any>;
34
+ state: Node.NodeArg<any>;
35
35
  instruction: Instruction;
36
36
  source: TreeData;
37
37
  target: TreeData;
@@ -4,20 +4,20 @@
4
4
 
5
5
  import { type Resource } from '@dxos/react-ui';
6
6
 
7
- import { meta } from './meta';
7
+ import { meta } from '#meta';
8
8
 
9
9
  export const translations = [
10
10
  {
11
11
  'en-US': {
12
12
  [meta.id]: {
13
- 'app menu label': 'App menu',
14
- 'open settings label': 'Settings',
15
- 'open commands label': 'Search commands',
16
- 'commands dialog title': 'Commands',
17
- 'command list input placeholder': 'Search for commands…',
18
- 'node actions menu invoker label': 'More options',
19
- 'tree item actions label': 'More actions',
20
- 'empty branch message': ' ',
13
+ 'app-menu.label': 'App menu',
14
+ 'open-settings.label': 'Settings',
15
+ 'open-commands.label': 'Search commands',
16
+ 'commands-dialog.title': 'Commands',
17
+ 'command-list-input.placeholder': 'Search for commands…',
18
+ 'node-actions-menu-invoker.label': 'More options',
19
+ 'tree-item-actions.label': 'More actions',
20
+ 'button-back.button': 'Back to Space',
21
21
  },
22
22
  },
23
23
  },
@@ -0,0 +1,21 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Atom } from '@effect-atom/atom-react';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+
9
+ import { meta } from '#meta';
10
+
11
+ export namespace NavTreeCapabilities {
12
+ export type NavTreeItemState = { open: boolean; current: boolean; alternateTree?: boolean };
13
+
14
+ export type NavTreeStateStore = {
15
+ getItem: (path: string[]) => NavTreeItemState;
16
+ getItemAtom: (path: string[]) => Atom.Atom<NavTreeItemState>;
17
+ setItem: (path: string[], key: 'open' | 'current' | 'alternateTree', next: boolean) => void;
18
+ };
19
+
20
+ export const State = Capability.make<NavTreeStateStore>(`${meta.id}.capability.state`);
21
+ }
@@ -0,0 +1,12 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type ActivationEvent } from '@dxos/app-framework';
6
+ import { AppActivationEvents } from '@dxos/app-toolkit';
7
+
8
+ import { meta } from '#meta';
9
+
10
+ export namespace NavTreeEvents {
11
+ export const StateReady: ActivationEvent.ActivationEvent = AppActivationEvents.createStateEvent(meta.id);
12
+ }
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './capabilities';
6
+ export * from './events';
7
+ export * from './schema';