@dxos/plugin-simple-layout 0.8.4-main.9735255 → 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
@@ -4,11 +4,11 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { Surface } from '@dxos/app-framework/react';
7
+ import { Surface } from '@dxos/app-framework/ui';
8
8
  import { AlertDialog, Dialog as NaturalDialog } from '@dxos/react-ui';
9
+ import { ErrorFallback } from '@dxos/react-ui';
9
10
 
10
- import { useSimpleLayoutState } from '../../hooks';
11
- import { ContentError } from '../ContentError';
11
+ import { useSimpleLayoutState } from '#hooks';
12
12
 
13
13
  export const Dialog = () => {
14
14
  const { state, updateState } = useSimpleLayoutState();
@@ -20,17 +20,17 @@ export const Dialog = () => {
20
20
  <DialogRoot
21
21
  modal={state.dialogBlockAlign !== 'end'}
22
22
  open={state.dialogOpen}
23
- onOpenChange={(nextOpen) => updateState((s) => ({ ...s, dialogOpen: nextOpen }))}
23
+ onOpenChange={(nextOpen) => updateState((state) => ({ ...state, dialogOpen: nextOpen }))}
24
24
  >
25
25
  {state.dialogBlockAlign === 'end' ? (
26
- <Surface role='dialog' data={state.dialogContent} limit={1} fallback={ContentError} />
26
+ <Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={ErrorFallback} />
27
27
  ) : (
28
28
  <DialogOverlay
29
29
  blockAlign={state.dialogBlockAlign}
30
30
  classNames={state.dialogOverlayClasses}
31
31
  style={state.dialogOverlayStyle}
32
32
  >
33
- <Surface role='dialog' data={state.dialogContent} limit={1} fallback={ContentError} />
33
+ <Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={ErrorFallback} />
34
34
  </DialogOverlay>
35
35
  )}
36
36
  </DialogRoot>
@@ -4,17 +4,19 @@
4
4
 
5
5
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
6
6
 
7
- import { Common } from '@dxos/app-framework';
8
- import { useAppGraph, useOperationInvoker } from '@dxos/app-framework/react';
7
+ import { useOperationInvoker } from '@dxos/app-framework/ui';
8
+ import { LayoutOperation } from '@dxos/app-toolkit';
9
+ import { useAppGraph } from '@dxos/app-toolkit/ui';
9
10
  import { 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';
11
+ import { Avatar, Icon, ScrollArea, toLocalizedString, useTranslation } from '@dxos/react-ui';
12
+ import { Card } from '@dxos/react-ui';
13
+ import { Mosaic, type MosaicStackTileComponent } from '@dxos/react-ui-mosaic';
14
+ import { SearchPanel, useSearchListItem, useSearchListResults } from '@dxos/react-ui-search';
13
15
  import { mx } from '@dxos/ui-theme';
14
- import { byPosition } from '@dxos/util';
16
+ import { byPosition, getHostPlatform, isTauri } from '@dxos/util';
15
17
 
16
- import { meta } from '../../meta';
17
- import { useLoadDescendents } from '../hooks';
18
+ import { meta } from '#meta';
19
+ import { useExpandPath } from '../hooks';
18
20
 
19
21
  export type HomeProps = {};
20
22
 
@@ -26,7 +28,7 @@ export const Home = (_: HomeProps) => {
26
28
  const userAccountItem = useItemsByDisposition('user-account')[0];
27
29
  const pinnedItems = useItemsByDisposition('pin-end', true);
28
30
  const workspaceItems = useItemsByDisposition('workspace');
29
- useLoadDescendents(Node.RootId);
31
+ useExpandPath(Node.RootId);
30
32
 
31
33
  const items = useMemo(
32
34
  () => [...(userAccountItem ? [userAccountItem] : []), ...pinnedItems, ...workspaceItems],
@@ -38,44 +40,47 @@ export const Home = (_: HomeProps) => {
38
40
  extract: (node) => toLocalizedString(node.properties.label, t),
39
41
  });
40
42
 
43
+ const autoFocus = !isTauri() || getHostPlatform() !== 'ios';
44
+
41
45
  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={(node) => node.id} Tile={WorkspaceTile} />
51
- </Mosaic.Viewport>
52
- </Mosaic.Container>
53
- </SearchList.Content>
54
- </SearchList.Root>
55
- </Layout.Main>
46
+ <SearchPanel onSearch={handleSearch}>
47
+ <Mosaic.Container asChild>
48
+ <ScrollArea.Root centered padding thin>
49
+ <ScrollArea.Viewport>
50
+ <Mosaic.Stack
51
+ classNames='gap-1'
52
+ draggable={false}
53
+ items={results}
54
+ getId={(item) => item.id}
55
+ Tile={WorkspaceTile}
56
+ />
57
+ </ScrollArea.Viewport>
58
+ </ScrollArea.Root>
59
+ </Mosaic.Container>
60
+ </SearchPanel>
56
61
  );
57
62
  };
58
63
 
59
- const WorkspaceTile: StackTileComponent<Node.Node> = ({ data }) => {
64
+ const WorkspaceTile: MosaicStackTileComponent<Node.Node> = (props) => {
65
+ const data = props.data;
60
66
  const { t } = useTranslation(meta.id);
61
67
  const { invokePromise } = useOperationInvoker();
62
68
  const { selectedValue, registerItem, unregisterItem } = useSearchListItem();
63
- const ref = useRef<HTMLDivElement>(null);
69
+ const name = toLocalizedString(data.properties.label, t);
70
+ const isSelected = selectedValue === data.id;
71
+ const cardRef = useRef<HTMLDivElement>(null);
72
+
73
+ useExpandPath(data.id);
64
74
 
65
75
  const handleSelect = useCallback(
66
- () => invokePromise(Common.LayoutOperation.SwitchWorkspace, { subject: data.id }),
76
+ () => invokePromise(LayoutOperation.SwitchWorkspace, { subject: data.id }),
67
77
  [invokePromise, data.id],
68
78
  );
69
79
 
70
- useLoadDescendents(data.id);
71
-
72
- const name = toLocalizedString(data.properties.label, t);
73
- const isSelected = selectedValue === data.id;
74
-
75
80
  // Register this workspace with the search context.
76
81
  useEffect(() => {
77
- if (ref.current) {
78
- registerItem(data.id, ref.current, handleSelect);
82
+ if (cardRef.current) {
83
+ registerItem(data.id, cardRef.current, handleSelect);
79
84
  }
80
85
 
81
86
  return () => unregisterItem(data.id);
@@ -83,32 +88,32 @@ const WorkspaceTile: StackTileComponent<Node.Node> = ({ data }) => {
83
88
 
84
89
  // Scroll into view when selected.
85
90
  useEffect(() => {
86
- if (isSelected && ref.current) {
87
- ref.current.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
91
+ if (isSelected && cardRef.current) {
92
+ cardRef.current.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
88
93
  }
89
94
  }, [isSelected]);
90
95
 
91
96
  return (
92
97
  <Card.Root
93
- ref={ref}
94
98
  role='button'
95
99
  fullWidth
96
100
  tabIndex={-1} // TODO(burdon): Use Mosaic.Focus.
97
101
  data-selected={isSelected}
98
- classNames={mx('dx-focus-ring', isSelected && 'bg-hoverOverlay')}
102
+ classNames={mx('dx-focus-ring', isSelected && 'bg-hover-overlay')}
99
103
  onClick={handleSelect}
104
+ ref={cardRef}
100
105
  >
101
- <Card.Toolbar density='coarse'>
106
+ <Card.Toolbar density='fine'>
102
107
  <Avatar.Root>
103
108
  <Avatar.Content
104
109
  icon={data.properties.icon}
105
110
  hue={data.properties.hue}
106
111
  hueVariant='transparent'
107
112
  variant='square'
108
- size={12}
113
+ size={8}
109
114
  fallback={name}
110
115
  />
111
- <Avatar.Label>{name}</Avatar.Label>
116
+ <Avatar.Label classNames='cursor-pointer'>{name}</Avatar.Label>
112
117
  <Icon icon='ph--caret-right--regular' />
113
118
  </Avatar.Root>
114
119
  </Card.Toolbar>
@@ -124,7 +129,9 @@ const filterItems = (node: Node.Node, disposition: string) => {
124
129
  /** Returns root-level items filtered by disposition. */
125
130
  const useItemsByDisposition = (disposition: string, sort = false) => {
126
131
  const { graph } = useAppGraph();
127
- const connections = useConnections(graph, Node.RootId);
128
- const filtered = connections.filter((node) => filterItems(node, disposition));
129
- return sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
132
+ const connections = useConnections(graph, Node.RootId, 'child');
133
+ return useMemo(() => {
134
+ const filtered = connections.filter((node) => filterItems(node, disposition));
135
+ return sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
136
+ }, [connections, disposition, sort]);
130
137
  };
@@ -6,16 +6,16 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
 
7
7
  import { withTheme } from '@dxos/react-ui/testing';
8
8
 
9
- import { ContentLoading } from './ContentLoading';
9
+ import { Loading } from './Loading';
10
10
 
11
11
  const meta = {
12
- title: 'plugins/plugin-simple-layout/ContentLoading',
13
- component: ContentLoading,
14
- decorators: [withTheme],
12
+ title: 'plugins/plugin-simple-layout/components/Loading',
13
+ component: Loading,
14
+ decorators: [withTheme()],
15
15
  parameters: {
16
16
  layout: 'centered',
17
17
  },
18
- } satisfies Meta<typeof ContentLoading>;
18
+ } satisfies Meta<typeof Loading>;
19
19
 
20
20
  export default meta;
21
21
 
@@ -5,6 +5,6 @@
5
5
  import React from 'react';
6
6
 
7
7
  // TODO(burdon): Show skeleton: https://github.com/dxos/dxos/issues/8259
8
- export const ContentLoading = () => {
9
- return <div role='none' className='grid place-items-center attention-surface' />;
8
+ export const Loading = () => {
9
+ return <div role='none' className='grid place-items-center dx-attention-surface' />;
10
10
  };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './Loading';
@@ -0,0 +1,133 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { type PropsWithChildren, useEffect, useState } from 'react';
7
+
8
+ import { addEventListener, combine } from '@dxos/async';
9
+ import { Column, Flex, Input, Panel, Splitter, type SplitterMode, Toolbar } from '@dxos/react-ui';
10
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
+
12
+ import { MobileLayout, type MobileLayoutRootProps } from './MobileLayout';
13
+
14
+ /**
15
+ * Simulate ios keyboard.
16
+ */
17
+ const WithKeyboard = ({ children }: PropsWithChildren) => {
18
+ const [keyboardOpen, setKeyboardOpen] = useState(false);
19
+
20
+ useEffect(() => {
21
+ return combine(
22
+ addEventListener(document, 'focusin', (event: FocusEvent) => {
23
+ const target = event.target as HTMLElement;
24
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
25
+ setKeyboardOpen(true);
26
+ }
27
+ }),
28
+ addEventListener(document, 'focusout', (event: FocusEvent) => {
29
+ const target = event.target as HTMLElement;
30
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
31
+ setKeyboardOpen(false);
32
+ }
33
+ }),
34
+ );
35
+ }, []);
36
+
37
+ useEffect(() => {
38
+ const keyboardHeight = keyboardOpen ? 300 : 0;
39
+ document.documentElement.style.setProperty('--kb-height', `${keyboardHeight}px`);
40
+ document.documentElement.style.setProperty('--kb-open', keyboardOpen ? '1' : '0');
41
+
42
+ // Dispatch custom keyboard event that useIOSKeyboard listens for.
43
+ window.dispatchEvent(
44
+ new CustomEvent('keyboard', {
45
+ detail: {
46
+ type: keyboardOpen ? 'show' : 'hide',
47
+ height: keyboardHeight,
48
+ duration: 300,
49
+ },
50
+ }),
51
+ );
52
+ }, [keyboardOpen]);
53
+
54
+ return <div className='h-screen relative'>{children}</div>;
55
+ };
56
+
57
+ const StoryPanel = ({ children, label }: PropsWithChildren<{ label: string }>) => {
58
+ return (
59
+ <Panel.Root>
60
+ <Panel.Toolbar asChild>
61
+ <Toolbar.Root>
62
+ {label}
63
+ <Toolbar.Separator />
64
+ {children}
65
+ </Toolbar.Root>
66
+ </Panel.Toolbar>
67
+ <Panel.Content asChild>
68
+ <Column.Root gutter='xs' classNames='py-form-chrome'>
69
+ <Column.Content>
70
+ <Flex column>
71
+ <Input.Root>
72
+ <Input.TextInput placeholder={label} />
73
+ </Input.Root>
74
+ </Flex>
75
+ </Column.Content>
76
+ </Column.Root>
77
+ </Panel.Content>
78
+ </Panel.Root>
79
+ );
80
+ };
81
+
82
+ const DefaultStory = () => {
83
+ const [splitterMode, setSplitterMode] = useState<SplitterMode>('upper');
84
+ const [keyboardOpen, setKeyboardOpen] = useState(false);
85
+
86
+ useEffect(() => {
87
+ setSplitterMode(splitterMode === 'both' ? 'lower' : splitterMode);
88
+ }, [keyboardOpen]);
89
+
90
+ return (
91
+ <WithKeyboard>
92
+ <MobileLayout.Root onKeyboardOpenChange={setKeyboardOpen}>
93
+ <MobileLayout.Panel safe={{ top: true, bottom: splitterMode === 'upper' }}>
94
+ <Splitter.Root mode={splitterMode} ratio={0.5}>
95
+ <Splitter.Panel position='upper'>
96
+ <StoryPanel label='Main'>
97
+ {splitterMode === 'upper' && (
98
+ <Toolbar.IconButton icon='ph--plus--regular' label='Open' onClick={() => setSplitterMode('both')} />
99
+ )}
100
+ </StoryPanel>
101
+ </Splitter.Panel>
102
+ <Splitter.Panel position='lower'>
103
+ <StoryPanel label='Drawer'>
104
+ <Toolbar.IconButton
105
+ icon={splitterMode === 'lower' ? 'ph--arrow-down--regular' : 'ph--arrow-up--regular'}
106
+ label={splitterMode === 'lower' ? 'Collapse' : 'Expand'}
107
+ onClick={() => setSplitterMode((splitterMode) => (splitterMode === 'both' ? 'lower' : 'both'))}
108
+ />
109
+ <Toolbar.IconButton icon='ph--x--regular' label='Close' onClick={() => setSplitterMode('upper')} />
110
+ </StoryPanel>
111
+ </Splitter.Panel>
112
+ </Splitter.Root>
113
+ </MobileLayout.Panel>
114
+ </MobileLayout.Root>
115
+ </WithKeyboard>
116
+ );
117
+ };
118
+
119
+ const meta: Meta<MobileLayoutRootProps> = {
120
+ title: 'plugins/plugin-simple-layout/components/MobileLayout',
121
+ component: MobileLayout.Root,
122
+ render: DefaultStory,
123
+ decorators: [withTheme(), withLayout({ layout: 'column', classNames: 'relative' })],
124
+ parameters: {
125
+ layout: 'fullscreen',
126
+ },
127
+ };
128
+
129
+ export default meta;
130
+
131
+ type Story = StoryObj<MobileLayoutRootProps>;
132
+
133
+ export const Default: Story = {};