@dxos/plugin-simple-layout 0.8.4-main.bc674ce → 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 (246) hide show
  1. package/dist/lib/browser/index.mjs +44 -64
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +44 -63
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/SimpleLayoutPlugin.d.ts +1 -1
  8. package/dist/types/src/SimpleLayoutPlugin.d.ts.map +1 -1
  9. package/dist/types/src/capabilities/app-graph-builder.d.ts +6 -0
  10. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  11. package/dist/types/src/capabilities/index.d.ts +21 -6
  12. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  13. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  14. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  15. package/dist/types/src/capabilities/{react-root/react-root.d.ts → react-root.d.ts} +1 -1
  16. package/dist/types/src/capabilities/react-root.d.ts.map +1 -0
  17. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  18. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  19. package/dist/types/src/capabilities/{spotlight-dismiss/spotlight-dismiss.d.ts → spotlight-dismiss.d.ts} +1 -1
  20. package/dist/types/src/capabilities/spotlight-dismiss.d.ts.map +1 -0
  21. package/dist/types/src/capabilities/{state/state.d.ts → state.d.ts} +2 -2
  22. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  23. package/dist/types/src/capabilities/url-handler.d.ts +12 -0
  24. package/dist/types/src/capabilities/url-handler.d.ts.map +1 -0
  25. package/dist/types/src/components/ContentError.stories.d.ts +26 -21
  26. package/dist/types/src/components/ContentError.stories.d.ts.map +1 -1
  27. package/dist/types/src/components/DebugOverlay/DebugOverlay.d.ts +19 -0
  28. package/dist/types/src/components/DebugOverlay/DebugOverlay.d.ts.map +1 -0
  29. package/dist/types/src/components/DebugOverlay/index.d.ts +2 -0
  30. package/dist/types/src/components/DebugOverlay/index.d.ts.map +1 -0
  31. package/dist/types/src/components/Home/Home.d.ts.map +1 -1
  32. package/dist/types/src/components/Loading/Loading.d.ts +3 -0
  33. package/dist/types/src/components/Loading/Loading.d.ts.map +1 -0
  34. package/dist/types/src/components/{ContentLoading.stories.d.ts → Loading/Loading.stories.d.ts} +1 -1
  35. package/dist/types/src/components/Loading/Loading.stories.d.ts.map +1 -0
  36. package/dist/types/src/components/Loading/index.d.ts +2 -0
  37. package/dist/types/src/components/Loading/index.d.ts.map +1 -0
  38. package/dist/types/src/components/MobileLayout/MobileLayout.d.ts +35 -0
  39. package/dist/types/src/components/MobileLayout/MobileLayout.d.ts.map +1 -0
  40. package/dist/types/src/components/MobileLayout/MobileLayout.stories.d.ts +7 -0
  41. package/dist/types/src/components/MobileLayout/MobileLayout.stories.d.ts.map +1 -0
  42. package/dist/types/src/components/MobileLayout/index.d.ts +2 -0
  43. package/dist/types/src/components/MobileLayout/index.d.ts.map +1 -0
  44. package/dist/types/src/components/NavBranch/NavBranch.d.ts +11 -0
  45. package/dist/types/src/components/NavBranch/NavBranch.d.ts.map +1 -0
  46. package/dist/types/src/components/NavBranch/index.d.ts +2 -0
  47. package/dist/types/src/components/NavBranch/index.d.ts.map +1 -0
  48. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  49. package/dist/types/src/components/SimpleLayout/AppBar.d.ts +28 -0
  50. package/dist/types/src/components/SimpleLayout/AppBar.d.ts.map +1 -0
  51. package/dist/types/src/components/SimpleLayout/AppBar.stories.d.ts +54 -0
  52. package/dist/types/src/components/SimpleLayout/AppBar.stories.d.ts.map +1 -0
  53. package/dist/types/src/components/SimpleLayout/Drawer.d.ts +1 -1
  54. package/dist/types/src/components/SimpleLayout/Drawer.d.ts.map +1 -1
  55. package/dist/types/src/components/SimpleLayout/Main.d.ts.map +1 -1
  56. package/dist/types/src/components/SimpleLayout/NavBar.d.ts +17 -8
  57. package/dist/types/src/components/SimpleLayout/NavBar.d.ts.map +1 -1
  58. package/dist/types/src/components/SimpleLayout/NavBar.stories.d.ts +35 -25
  59. package/dist/types/src/components/SimpleLayout/NavBar.stories.d.ts.map +1 -1
  60. package/dist/types/src/components/SimpleLayout/SimpleLayout.d.ts.map +1 -1
  61. package/dist/types/src/components/SimpleLayout/SimpleLayout.stories.d.ts +26 -25
  62. package/dist/types/src/components/SimpleLayout/SimpleLayout.stories.d.ts.map +1 -1
  63. package/dist/types/src/components/SimpleLayout/index.d.ts +3 -0
  64. package/dist/types/src/components/SimpleLayout/index.d.ts.map +1 -1
  65. package/dist/types/src/components/hooks.d.ts +4 -2
  66. package/dist/types/src/components/hooks.d.ts.map +1 -1
  67. package/dist/types/src/components/index.d.ts +4 -2
  68. package/dist/types/src/components/index.d.ts.map +1 -1
  69. package/dist/types/src/hooks/actions.d.ts +19 -0
  70. package/dist/types/src/hooks/actions.d.ts.map +1 -0
  71. package/dist/types/src/hooks/index.d.ts +4 -0
  72. package/dist/types/src/hooks/index.d.ts.map +1 -1
  73. package/dist/types/src/hooks/useAppBarProps.d.ts +7 -0
  74. package/dist/types/src/hooks/useAppBarProps.d.ts.map +1 -0
  75. package/dist/types/src/hooks/useCompanions.d.ts +5 -1
  76. package/dist/types/src/hooks/useCompanions.d.ts.map +1 -1
  77. package/dist/types/src/hooks/useDrawerActions.d.ts +13 -0
  78. package/dist/types/src/hooks/useDrawerActions.d.ts.map +1 -0
  79. package/dist/types/src/hooks/useNavbarActions.d.ts +14 -0
  80. package/dist/types/src/hooks/useNavbarActions.d.ts.map +1 -0
  81. package/dist/types/src/hooks/useSimpleLayoutState.d.ts +3 -3
  82. package/dist/types/src/hooks/useSimpleLayoutState.d.ts.map +1 -1
  83. package/dist/types/src/operations/close.d.ts +5 -0
  84. package/dist/types/src/operations/close.d.ts.map +1 -0
  85. package/dist/types/src/operations/index.d.ts +3 -0
  86. package/dist/types/src/operations/index.d.ts.map +1 -0
  87. package/dist/types/src/operations/open.d.ts +5 -0
  88. package/dist/types/src/operations/open.d.ts.map +1 -0
  89. package/dist/types/src/operations/revert-workspace.d.ts +5 -0
  90. package/dist/types/src/operations/revert-workspace.d.ts.map +1 -0
  91. package/dist/types/src/operations/set-layout-mode.d.ts +5 -0
  92. package/dist/types/src/operations/set-layout-mode.d.ts.map +1 -0
  93. package/dist/types/src/operations/set.d.ts +5 -0
  94. package/dist/types/src/operations/set.d.ts.map +1 -0
  95. package/dist/types/src/operations/state-access.d.ts +8 -0
  96. package/dist/types/src/operations/state-access.d.ts.map +1 -0
  97. package/dist/types/src/operations/switch-workspace.d.ts +5 -0
  98. package/dist/types/src/operations/switch-workspace.d.ts.map +1 -0
  99. package/dist/types/src/operations/update-complementary.d.ts +5 -0
  100. package/dist/types/src/operations/update-complementary.d.ts.map +1 -0
  101. package/dist/types/src/operations/update-dialog.d.ts +5 -0
  102. package/dist/types/src/operations/update-dialog.d.ts.map +1 -0
  103. package/dist/types/src/operations/update-popover.d.ts +5 -0
  104. package/dist/types/src/operations/update-popover.d.ts.map +1 -0
  105. package/dist/types/src/operations/update-sidebar.d.ts +5 -0
  106. package/dist/types/src/operations/update-sidebar.d.ts.map +1 -0
  107. package/dist/types/src/translations.d.ts +26 -19
  108. package/dist/types/src/translations.d.ts.map +1 -1
  109. package/dist/types/src/types/capabilities.d.ts +7 -6
  110. package/dist/types/src/types/capabilities.d.ts.map +1 -1
  111. package/dist/types/src/types/events.d.ts.map +1 -1
  112. package/dist/types/tsconfig.tsbuildinfo +1 -1
  113. package/package.json +46 -30
  114. package/src/SimpleLayoutPlugin.ts +24 -13
  115. package/src/capabilities/app-graph-builder.ts +21 -0
  116. package/src/capabilities/index.ts +13 -6
  117. package/src/capabilities/operation-handler.ts +14 -0
  118. package/src/capabilities/{react-root/react-root.tsx → react-root.tsx} +4 -4
  119. package/src/capabilities/react-surface.tsx +51 -0
  120. package/src/capabilities/{spotlight-dismiss/spotlight-dismiss.ts → spotlight-dismiss.ts} +2 -2
  121. package/src/capabilities/{state/state.tsx → state.tsx} +6 -5
  122. package/src/capabilities/url-handler.ts +161 -0
  123. package/src/components/ContentError.stories.tsx +8 -7
  124. package/src/components/DebugOverlay/DebugOverlay.tsx +96 -0
  125. package/src/components/DebugOverlay/index.ts +5 -0
  126. package/src/components/Dialog/Dialog.tsx +6 -6
  127. package/src/components/Home/Home.tsx +50 -43
  128. package/src/components/{ContentLoading.stories.tsx → Loading/Loading.stories.tsx} +5 -5
  129. package/src/components/{ContentLoading.tsx → Loading/Loading.tsx} +2 -2
  130. package/src/components/Loading/index.ts +5 -0
  131. package/src/components/MobileLayout/MobileLayout.stories.tsx +133 -0
  132. package/src/components/MobileLayout/MobileLayout.tsx +374 -0
  133. package/src/components/MobileLayout/index.ts +5 -0
  134. package/src/components/NavBranch/NavBranch.tsx +127 -0
  135. package/src/components/{Workspace → NavBranch}/index.ts +1 -1
  136. package/src/components/Popover/Popover.tsx +9 -9
  137. package/src/components/SimpleLayout/AppBar.stories.tsx +144 -0
  138. package/src/components/SimpleLayout/AppBar.tsx +93 -0
  139. package/src/components/SimpleLayout/Drawer.tsx +27 -82
  140. package/src/components/SimpleLayout/Main.tsx +40 -34
  141. package/src/components/SimpleLayout/NavBar.stories.tsx +131 -23
  142. package/src/components/SimpleLayout/NavBar.tsx +18 -51
  143. package/src/components/SimpleLayout/SimpleLayout.stories.tsx +45 -57
  144. package/src/components/SimpleLayout/SimpleLayout.tsx +40 -22
  145. package/src/components/SimpleLayout/index.ts +3 -0
  146. package/src/components/hooks.ts +9 -9
  147. package/src/components/index.ts +4 -2
  148. package/src/hooks/actions.ts +84 -0
  149. package/src/hooks/index.ts +4 -0
  150. package/src/hooks/useAppBarProps.ts +115 -0
  151. package/src/hooks/useCompanions.ts +8 -5
  152. package/src/hooks/useDrawerActions.ts +100 -0
  153. package/src/hooks/useNavbarActions.ts +87 -0
  154. package/src/hooks/useSimpleLayoutState.ts +5 -5
  155. package/src/meta.ts +1 -1
  156. package/src/operations/close.ts +34 -0
  157. package/src/operations/index.ts +16 -0
  158. package/src/operations/open.ts +63 -0
  159. package/src/operations/revert-workspace.ts +22 -0
  160. package/src/operations/set-layout-mode.ts +12 -0
  161. package/src/operations/set.ts +23 -0
  162. package/src/operations/state-access.ts +19 -0
  163. package/src/operations/switch-workspace.ts +26 -0
  164. package/src/operations/update-complementary.ts +35 -0
  165. package/src/operations/update-dialog.ts +28 -0
  166. package/src/operations/update-popover.ts +35 -0
  167. package/src/operations/update-sidebar.ts +12 -0
  168. package/src/translations.ts +21 -19
  169. package/src/types/capabilities.ts +12 -8
  170. package/src/types/events.ts +3 -2
  171. package/dist/lib/browser/chunk-LR3EE3VB.mjs +0 -789
  172. package/dist/lib/browser/chunk-LR3EE3VB.mjs.map +0 -7
  173. package/dist/lib/browser/chunk-P77G4YTR.mjs +0 -29
  174. package/dist/lib/browser/chunk-P77G4YTR.mjs.map +0 -7
  175. package/dist/lib/browser/operation-resolver-775UYAC2.mjs +0 -203
  176. package/dist/lib/browser/operation-resolver-775UYAC2.mjs.map +0 -7
  177. package/dist/lib/browser/react-root-KM55OMGJ.mjs +0 -21
  178. package/dist/lib/browser/react-root-KM55OMGJ.mjs.map +0 -7
  179. package/dist/lib/browser/react-surface-BABGAWGY.mjs +0 -39
  180. package/dist/lib/browser/react-surface-BABGAWGY.mjs.map +0 -7
  181. package/dist/lib/browser/spotlight-dismiss-VSNOPETH.mjs +0 -66
  182. package/dist/lib/browser/spotlight-dismiss-VSNOPETH.mjs.map +0 -7
  183. package/dist/lib/browser/state-OUFTC2KV.mjs +0 -47
  184. package/dist/lib/browser/state-OUFTC2KV.mjs.map +0 -7
  185. package/dist/lib/browser/url-handler-DOUFQIAC.mjs +0 -54
  186. package/dist/lib/browser/url-handler-DOUFQIAC.mjs.map +0 -7
  187. package/dist/lib/node-esm/chunk-F5TEKVJG.mjs +0 -31
  188. package/dist/lib/node-esm/chunk-F5TEKVJG.mjs.map +0 -7
  189. package/dist/lib/node-esm/chunk-HB2B3LLG.mjs +0 -790
  190. package/dist/lib/node-esm/chunk-HB2B3LLG.mjs.map +0 -7
  191. package/dist/lib/node-esm/operation-resolver-LDNYS3DI.mjs +0 -204
  192. package/dist/lib/node-esm/operation-resolver-LDNYS3DI.mjs.map +0 -7
  193. package/dist/lib/node-esm/react-root-36UYFEEB.mjs +0 -22
  194. package/dist/lib/node-esm/react-root-36UYFEEB.mjs.map +0 -7
  195. package/dist/lib/node-esm/react-surface-CGHFVWU3.mjs +0 -40
  196. package/dist/lib/node-esm/react-surface-CGHFVWU3.mjs.map +0 -7
  197. package/dist/lib/node-esm/spotlight-dismiss-L5PCWIJG.mjs +0 -68
  198. package/dist/lib/node-esm/spotlight-dismiss-L5PCWIJG.mjs.map +0 -7
  199. package/dist/lib/node-esm/state-Q2ZA26W5.mjs +0 -48
  200. package/dist/lib/node-esm/state-Q2ZA26W5.mjs.map +0 -7
  201. package/dist/lib/node-esm/url-handler-DVAZZEUO.mjs +0 -55
  202. package/dist/lib/node-esm/url-handler-DVAZZEUO.mjs.map +0 -7
  203. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  204. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  205. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  206. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  207. package/dist/types/src/capabilities/react-root/index.d.ts +0 -6
  208. package/dist/types/src/capabilities/react-root/index.d.ts.map +0 -1
  209. package/dist/types/src/capabilities/react-root/react-root.d.ts.map +0 -1
  210. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  211. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  212. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +0 -5
  213. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  214. package/dist/types/src/capabilities/spotlight-dismiss/index.d.ts +0 -3
  215. package/dist/types/src/capabilities/spotlight-dismiss/index.d.ts.map +0 -1
  216. package/dist/types/src/capabilities/spotlight-dismiss/spotlight-dismiss.d.ts.map +0 -1
  217. package/dist/types/src/capabilities/state/index.d.ts +0 -13
  218. package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
  219. package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
  220. package/dist/types/src/capabilities/url-handler/index.d.ts +0 -3
  221. package/dist/types/src/capabilities/url-handler/index.d.ts.map +0 -1
  222. package/dist/types/src/capabilities/url-handler/url-handler.d.ts +0 -10
  223. package/dist/types/src/capabilities/url-handler/url-handler.d.ts.map +0 -1
  224. package/dist/types/src/components/ContentError.d.ts +0 -5
  225. package/dist/types/src/components/ContentError.d.ts.map +0 -1
  226. package/dist/types/src/components/ContentLoading.d.ts +0 -3
  227. package/dist/types/src/components/ContentLoading.d.ts.map +0 -1
  228. package/dist/types/src/components/ContentLoading.stories.d.ts.map +0 -1
  229. package/dist/types/src/components/SimpleLayout/Banner.d.ts +0 -8
  230. package/dist/types/src/components/SimpleLayout/Banner.d.ts.map +0 -1
  231. package/dist/types/src/components/Workspace/Workspace.d.ts +0 -9
  232. package/dist/types/src/components/Workspace/Workspace.d.ts.map +0 -1
  233. package/dist/types/src/components/Workspace/index.d.ts +0 -2
  234. package/dist/types/src/components/Workspace/index.d.ts.map +0 -1
  235. package/src/capabilities/operation-resolver/index.ts +0 -10
  236. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -215
  237. package/src/capabilities/react-root/index.ts +0 -7
  238. package/src/capabilities/react-surface/index.ts +0 -7
  239. package/src/capabilities/react-surface/react-surface.tsx +0 -40
  240. package/src/capabilities/spotlight-dismiss/index.ts +0 -7
  241. package/src/capabilities/state/index.ts +0 -9
  242. package/src/capabilities/url-handler/index.ts +0 -7
  243. package/src/capabilities/url-handler/url-handler.ts +0 -80
  244. package/src/components/ContentError.tsx +0 -23
  245. package/src/components/SimpleLayout/Banner.tsx +0 -113
  246. package/src/components/Workspace/Workspace.tsx +0 -115
@@ -1,80 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import * as Effect from 'effect/Effect';
6
-
7
- import { Capability, Common } from '@dxos/app-framework';
8
- import { Node } from '@dxos/plugin-graph';
9
-
10
- import { type SimpleLayoutState, SimpleLayoutState as SimpleLayoutStateCapability } from '../../types';
11
-
12
- /**
13
- * URL handler for simple layout that syncs browser URL with layout state.
14
- * URL format: /{workspace} or /{workspace}/{active}
15
- * Root is represented as / or /root.
16
- */
17
- export default Capability.makeModule(
18
- Effect.fnUntraced(function* () {
19
- const { invokeSync } = yield* Capability.get(Common.Capability.OperationInvoker);
20
-
21
- /**
22
- * Handle navigation events (initial load and popstate).
23
- * Parses URL and updates state accordingly.
24
- */
25
- const handleNavigation = () => {
26
- const pathname = window.location.pathname;
27
-
28
- // Parse URL segments: /{workspace}/{active}
29
- const [_, nextWorkspace, nextActive] = pathname.split('/');
30
-
31
- // Determine target workspace (empty or 'root' means Node.RootId).
32
- const targetWorkspace = !nextWorkspace || nextWorkspace === 'root' ? Node.RootId : nextWorkspace;
33
-
34
- // Navigate via operations (they will update state accordingly).
35
- invokeSync(Common.LayoutOperation.SwitchWorkspace, { subject: targetWorkspace });
36
- if (nextActive) {
37
- invokeSync(Common.LayoutOperation.Open, { subject: [nextActive] });
38
- }
39
- };
40
-
41
- // Handle initial URL and listen for browser navigation.
42
- yield* Effect.sync(() => handleNavigation());
43
- window.addEventListener('popstate', handleNavigation);
44
-
45
- // Subscribe to state changes to update the URL.
46
- let lastWorkspace: string | undefined;
47
- let lastActive: string | undefined;
48
- const unsubscribe = yield* Common.Capability.subscribeAtom(
49
- SimpleLayoutStateCapability,
50
- (state: SimpleLayoutState) => {
51
- const { workspace, active } = state;
52
-
53
- // Only update URL if relevant state changed.
54
- if (workspace !== lastWorkspace || active !== lastActive) {
55
- lastWorkspace = workspace;
56
- lastActive = active;
57
-
58
- // Build path: root is represented as /, other workspaces as /{workspace}.
59
- let path: string;
60
- if (workspace === Node.RootId) {
61
- path = active ? `/${Node.RootId}/${active}` : '/';
62
- } else {
63
- path = active ? `/${workspace}/${active}` : `/${workspace}`;
64
- }
65
-
66
- if (window.location.pathname !== path) {
67
- history.pushState(null, '', `${path}${window.location.search}`);
68
- }
69
- }
70
- },
71
- );
72
-
73
- return Capability.contributes(Common.Capability.Null, null, () =>
74
- Effect.sync(() => {
75
- window.removeEventListener('popstate', handleNavigation);
76
- unsubscribe();
77
- }),
78
- );
79
- }),
80
- );
@@ -1,23 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import React from 'react';
6
-
7
- import { useTranslation } from '@dxos/react-ui';
8
- import { descriptionMessage, mx } from '@dxos/ui-theme';
9
-
10
- import { meta } from '../meta';
11
-
12
- // TODO(burdon): Factor out.
13
- export const ContentError = ({ error }: { error?: Error }) => {
14
- const { t } = useTranslation(meta.id);
15
- const errorString = error?.toString() ?? '';
16
- return (
17
- <div role='none' className='grid place-items-center overflow-y-auto attention-surface'>
18
- <p role='alert' className={mx(descriptionMessage, 'p-2 break-all rounded-sm')}>
19
- {error ? errorString : t('error fallback message')}
20
- </p>
21
- </div>
22
- );
23
- };
@@ -1,113 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import React, { Fragment, useCallback, useMemo } from 'react';
6
-
7
- import { Common } from '@dxos/app-framework';
8
- import { useAppGraph, useOperationInvoker } from '@dxos/app-framework/react';
9
- import { Graph, Node, useActionRunner, useActions } from '@dxos/plugin-graph';
10
- import { IconButton, Popover, type ThemedClassName, Toolbar, toLocalizedString, useTranslation } from '@dxos/react-ui';
11
- import { DropdownMenu, MenuProvider } from '@dxos/react-ui-menu';
12
- import { mx, osTranslations } from '@dxos/ui-theme';
13
-
14
- import { useSimpleLayoutState } from '../../hooks';
15
- import { meta } from '../../meta';
16
-
17
- /**
18
- * Check if an item is a direct child of a workspace or collection.
19
- * Returns true if any parent node has disposition 'workspace' or 'collection'.
20
- */
21
- const isWorkspaceOrCollectionChild = (graph: Graph.ReadableGraph, itemId: string): boolean => {
22
- const parents = Graph.getConnections(graph, itemId, 'inbound');
23
- return parents.some(
24
- (node) => node.properties.disposition === 'workspace' || node.properties.disposition === 'collection',
25
- );
26
- };
27
-
28
- export type BannerProps = ThemedClassName<{
29
- node?: Node.Node;
30
- }>;
31
-
32
- export const Banner = ({ node, classNames }: BannerProps) => {
33
- const { t } = useTranslation(meta.id);
34
- const { state } = useSimpleLayoutState();
35
- const { invokePromise } = useOperationInvoker();
36
- const { graph } = useAppGraph();
37
- const runAction = useActionRunner();
38
-
39
- const label = (node && toLocalizedString(node.properties.label, t)) ?? t('current app name', { ns: osTranslations });
40
-
41
- // Get actions for the current node, filtered by disposition.
42
- // NOTE: Graph expansion is handled by useLoadDescendents in Main.tsx.
43
- const allActions = useActions(graph, node?.id);
44
- const actions = useMemo(() => {
45
- return allActions.filter((a) =>
46
- ['list-item', 'list-item-primary', 'heading-list-item'].includes(a.properties.disposition),
47
- );
48
- }, [allActions]);
49
-
50
- // Check if current active item is a top-level workspace/collection child.
51
- const isTopLevelItem = useMemo(() => {
52
- if (!state.active) {
53
- return false;
54
- }
55
- return isWorkspaceOrCollectionChild(graph, state.active);
56
- }, [graph, state.active]);
57
-
58
- const handleClick = useCallback(async () => {
59
- if (state.active) {
60
- // If history is empty and this is a top-level item, go to home.
61
- if (state.history.length === 0 && isTopLevelItem) {
62
- await invokePromise(Common.LayoutOperation.SwitchWorkspace, { subject: Node.RootId });
63
- } else {
64
- // Otherwise, close (which will pop from history or clear active).
65
- await invokePromise(Common.LayoutOperation.Close, { subject: [state.active] });
66
- }
67
- } else {
68
- await invokePromise(Common.LayoutOperation.SwitchWorkspace, { subject: Node.RootId });
69
- }
70
- }, [invokePromise, state.active, state.history.length, isTopLevelItem]);
71
-
72
- // Wrap the menu trigger with Popover.Anchor when the popoverAnchorId matches.
73
- const AnchorRoot = node && state.popoverAnchorId === `dxos.org/ui/${meta.id}/${node.id}` ? Popover.Anchor : Fragment;
74
-
75
- if (!node) {
76
- return null;
77
- }
78
-
79
- return (
80
- <Toolbar.Root role='banner' classNames={mx('grid grid-cols-[var(--rail-size)_1fr_var(--rail-size)]', classNames)}>
81
- {node.id !== Node.RootId ? (
82
- <IconButton
83
- iconOnly
84
- variant='ghost'
85
- icon='ph--caret-left--regular'
86
- label={t('back label')}
87
- onClick={handleClick}
88
- />
89
- ) : (
90
- <div />
91
- )}
92
- <h1 className={'grow text-center truncate font-medium'}>{label}</h1>
93
- {actions.length > 0 ? (
94
- <AnchorRoot>
95
- <MenuProvider onAction={runAction}>
96
- <DropdownMenu.Root items={actions} caller={meta.id}>
97
- <DropdownMenu.Trigger asChild>
98
- <IconButton
99
- iconOnly
100
- variant='ghost'
101
- icon='ph--dots-three-vertical--regular'
102
- label={t('actions menu label')}
103
- />
104
- </DropdownMenu.Trigger>
105
- </DropdownMenu.Root>
106
- </MenuProvider>
107
- </AnchorRoot>
108
- ) : (
109
- <span />
110
- )}
111
- </Toolbar.Root>
112
- );
113
- };
@@ -1,115 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import React, { useCallback, useEffect, useRef } from 'react';
6
-
7
- import { Common } from '@dxos/app-framework';
8
- import { useAppGraph, useOperationInvoker } from '@dxos/app-framework/react';
9
- import { type Node, useConnections } from '@dxos/plugin-graph';
10
- import { Avatar, Icon, Toolbar, toLocalizedString, useTranslation } from '@dxos/react-ui';
11
- import { Card, Layout, Mosaic, type StackTileComponent } from '@dxos/react-ui-mosaic';
12
- import { SearchList, useSearchListItem, useSearchListResults } from '@dxos/react-ui-searchlist';
13
- import { mx } from '@dxos/ui-theme';
14
-
15
- import { meta } from '../../meta';
16
- import { useLoadDescendents } from '../hooks';
17
-
18
- export type WorkspaceProps = {
19
- id: string;
20
- };
21
-
22
- /**
23
- *
24
- */
25
- // TODO(burdon): Rename or motivate name in comment.
26
- export const Workspace = ({ id }: WorkspaceProps) => {
27
- const { t } = useTranslation(meta.id);
28
- const { graph } = useAppGraph();
29
-
30
- // Expand the workspace node to load its children.
31
- useLoadDescendents(id);
32
-
33
- // Get direct children of the workspace node.
34
- const children = useConnections(graph, id, 'outbound');
35
-
36
- const { results, handleSearch } = useSearchListResults({
37
- items: children,
38
- extract: (child) => toLocalizedString(child.properties.label, t),
39
- });
40
-
41
- return (
42
- <Layout.Main toolbar>
43
- <SearchList.Root onSearch={handleSearch}>
44
- <Toolbar.Root>
45
- <SearchList.Input placeholder={t('search placeholder')} autoFocus />
46
- </Toolbar.Root>
47
- <SearchList.Content>
48
- <Mosaic.Container asChild>
49
- <Mosaic.Viewport padding>
50
- <Mosaic.Stack items={results} getId={(child) => child.id} Tile={WorkspaceChildTile} />
51
- </Mosaic.Viewport>
52
- </Mosaic.Container>
53
- </SearchList.Content>
54
- </SearchList.Root>
55
- </Layout.Main>
56
- );
57
- };
58
-
59
- const WorkspaceChildTile: StackTileComponent<Node.Node> = ({ data }) => {
60
- const { t } = useTranslation(meta.id);
61
- const { invokeSync } = useOperationInvoker();
62
- const ref = useRef<HTMLDivElement>(null);
63
- const { selectedValue, registerItem, unregisterItem } = useSearchListItem();
64
- const isSelected = selectedValue === data.id;
65
-
66
- const name = toLocalizedString(data.properties.label, t);
67
-
68
- const handleSelect = useCallback(
69
- () => invokeSync(Common.LayoutOperation.Open, { subject: [data.id] }),
70
- [invokeSync, data.id],
71
- );
72
-
73
- // Register this item with the search context.
74
- useEffect(() => {
75
- if (ref.current) {
76
- registerItem(data.id, ref.current, handleSelect);
77
- }
78
-
79
- return () => unregisterItem(data.id);
80
- }, [data.id, handleSelect, registerItem, unregisterItem]);
81
-
82
- // Scroll into view when selected.
83
- useEffect(() => {
84
- if (isSelected && ref.current) {
85
- ref.current.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
86
- }
87
- }, [isSelected]);
88
-
89
- return (
90
- <Card.Root
91
- ref={ref}
92
- role='button'
93
- fullWidth
94
- tabIndex={-1} // TODO(burdon): Use Mosaic.Focus.
95
- data-selected={isSelected}
96
- classNames={mx('dx-focus-ring', isSelected && 'bg-hoverOverlay')}
97
- onClick={handleSelect}
98
- >
99
- <Card.Toolbar density='coarse'>
100
- <Avatar.Root>
101
- <Avatar.Content
102
- hue={data.properties.hue}
103
- icon={data.properties.icon}
104
- hueVariant='transparent'
105
- variant='square'
106
- size={12}
107
- fallback={name}
108
- />
109
- <Avatar.Label>{name}</Avatar.Label>
110
- <Icon icon='ph--caret-right--regular' />
111
- </Avatar.Root>
112
- </Card.Toolbar>
113
- </Card.Root>
114
- );
115
- };