@dxos/plugin-simple-layout 0.8.4-main.d05673bc65 → 0.8.4-main.d9fc60f731

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/neutral/SimpleLayoutPlugin.mjs +52 -0
  3. package/dist/lib/neutral/SimpleLayoutPlugin.mjs.map +7 -0
  4. package/dist/lib/neutral/app-graph-builder-MSPO34DT.mjs +21 -0
  5. package/dist/lib/neutral/app-graph-builder-MSPO34DT.mjs.map +7 -0
  6. package/dist/lib/neutral/capabilities/index.mjs +21 -0
  7. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  8. package/dist/lib/neutral/chunk-7UDV3JDT.mjs +22 -0
  9. package/dist/lib/neutral/chunk-7UDV3JDT.mjs.map +7 -0
  10. package/dist/lib/neutral/chunk-FD2CAY4Q.mjs +26 -0
  11. package/dist/lib/neutral/chunk-FD2CAY4Q.mjs.map +7 -0
  12. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  13. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  14. package/dist/lib/neutral/chunk-OK5336TS.mjs +22 -0
  15. package/dist/lib/neutral/chunk-OK5336TS.mjs.map +7 -0
  16. package/dist/lib/neutral/chunk-QRTV5UNX.mjs +8 -0
  17. package/dist/lib/neutral/chunk-QRTV5UNX.mjs.map +7 -0
  18. package/dist/lib/neutral/close-WKMURGUB.mjs +35 -0
  19. package/dist/lib/neutral/close-WKMURGUB.mjs.map +7 -0
  20. package/dist/lib/neutral/components/index.mjs +929 -0
  21. package/dist/lib/neutral/components/index.mjs.map +7 -0
  22. package/dist/lib/neutral/hooks/index.mjs +332 -0
  23. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  24. package/dist/lib/neutral/index.mjs +14 -0
  25. package/dist/lib/neutral/index.mjs.map +7 -0
  26. package/dist/lib/neutral/meta.json +1 -0
  27. package/dist/lib/neutral/meta.mjs +8 -0
  28. package/dist/lib/neutral/meta.mjs.map +7 -0
  29. package/dist/lib/neutral/open-APISM3AA.mjs +63 -0
  30. package/dist/lib/neutral/open-APISM3AA.mjs.map +7 -0
  31. package/dist/lib/neutral/operation-handler-EAIE7KPR.mjs +13 -0
  32. package/dist/lib/neutral/operation-handler-EAIE7KPR.mjs.map +7 -0
  33. package/dist/lib/neutral/operations/index.mjs +8 -0
  34. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  35. package/dist/lib/neutral/plugin.mjs +16 -0
  36. package/dist/lib/neutral/plugin.mjs.map +7 -0
  37. package/dist/lib/{browser/react-root-WVQYY2JA.mjs → neutral/react-root-VE265VX4.mjs} +5 -8
  38. package/dist/lib/neutral/react-root-VE265VX4.mjs.map +7 -0
  39. package/dist/lib/{browser/react-surface-VLBR37ED.mjs → neutral/react-surface-N3PGKIYV.mjs} +16 -14
  40. package/dist/lib/neutral/react-surface-N3PGKIYV.mjs.map +7 -0
  41. package/dist/lib/neutral/revert-workspace-ST6NZUNG.mjs +22 -0
  42. package/dist/lib/neutral/revert-workspace-ST6NZUNG.mjs.map +7 -0
  43. package/dist/lib/neutral/set-6ZRLWPJS.mjs +22 -0
  44. package/dist/lib/neutral/set-6ZRLWPJS.mjs.map +7 -0
  45. package/dist/lib/neutral/set-layout-mode-L22HRCKS.mjs +13 -0
  46. package/dist/lib/neutral/set-layout-mode-L22HRCKS.mjs.map +7 -0
  47. package/dist/lib/{browser/spotlight-dismiss-67PHYS5B.mjs → neutral/spotlight-dismiss-EIYW5E7M.mjs} +7 -15
  48. package/dist/lib/{node-esm/spotlight-dismiss-RMLRZUVY.mjs.map → neutral/spotlight-dismiss-EIYW5E7M.mjs.map} +3 -3
  49. package/dist/lib/{browser/state-TXSMUWYI.mjs → neutral/state-7NXKBLPY.mjs} +5 -6
  50. package/dist/lib/neutral/state-7NXKBLPY.mjs.map +7 -0
  51. package/dist/lib/neutral/switch-workspace-PYWPTMFO.mjs +25 -0
  52. package/dist/lib/neutral/switch-workspace-PYWPTMFO.mjs.map +7 -0
  53. package/dist/lib/neutral/translations.mjs +36 -0
  54. package/dist/lib/neutral/translations.mjs.map +7 -0
  55. package/dist/lib/neutral/types/index.mjs +10 -0
  56. package/dist/lib/neutral/types/index.mjs.map +7 -0
  57. package/dist/lib/neutral/update-complementary-HKWF5OXT.mjs +33 -0
  58. package/dist/lib/neutral/update-complementary-HKWF5OXT.mjs.map +7 -0
  59. package/dist/lib/neutral/update-dialog-P4ASXCE7.mjs +30 -0
  60. package/dist/lib/neutral/update-dialog-P4ASXCE7.mjs.map +7 -0
  61. package/dist/lib/neutral/update-popover-REAKC2GN.mjs +34 -0
  62. package/dist/lib/neutral/update-popover-REAKC2GN.mjs.map +7 -0
  63. package/dist/lib/neutral/update-sidebar-O5SQPR6Q.mjs +12 -0
  64. package/dist/lib/neutral/update-sidebar-O5SQPR6Q.mjs.map +7 -0
  65. package/dist/lib/neutral/url-handler-GZXUUAHD.mjs +129 -0
  66. package/dist/lib/neutral/url-handler-GZXUUAHD.mjs.map +7 -0
  67. package/dist/types/src/SimpleLayoutPlugin.d.ts +2 -1
  68. package/dist/types/src/SimpleLayoutPlugin.d.ts.map +1 -1
  69. package/dist/types/src/capabilities/app-graph-builder.d.ts +6 -0
  70. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/index.d.ts +21 -6
  72. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  73. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  74. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  75. package/dist/types/src/capabilities/react-root.d.ts.map +1 -0
  76. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/{spotlight-dismiss/spotlight-dismiss.d.ts → spotlight-dismiss.d.ts} +1 -1
  78. package/dist/types/src/capabilities/spotlight-dismiss.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/{state/state.d.ts → state.d.ts} +3 -3
  80. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  81. package/dist/types/src/capabilities/{url-handler/url-handler.d.ts → url-handler.d.ts} +1 -1
  82. package/dist/types/src/capabilities/url-handler.d.ts.map +1 -0
  83. package/dist/types/src/components/ContentError.stories.d.ts +26 -19
  84. package/dist/types/src/components/ContentError.stories.d.ts.map +1 -1
  85. package/dist/types/src/components/DebugOverlay/DebugOverlay.d.ts +19 -0
  86. package/dist/types/src/components/DebugOverlay/DebugOverlay.d.ts.map +1 -0
  87. package/dist/types/src/components/DebugOverlay/index.d.ts +2 -0
  88. package/dist/types/src/components/DebugOverlay/index.d.ts.map +1 -0
  89. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  90. package/dist/types/src/components/Home/Home.d.ts.map +1 -1
  91. package/dist/types/src/components/Loading/Loading.d.ts +3 -0
  92. package/dist/types/src/components/Loading/Loading.d.ts.map +1 -0
  93. package/dist/types/src/components/{ContentLoading/ContentLoading.stories.d.ts → Loading/Loading.stories.d.ts} +1 -1
  94. package/dist/types/src/components/Loading/Loading.stories.d.ts.map +1 -0
  95. package/dist/types/src/components/Loading/index.d.ts +2 -0
  96. package/dist/types/src/components/Loading/index.d.ts.map +1 -0
  97. package/dist/types/src/components/MobileLayout/MobileLayout.d.ts +2 -2
  98. package/dist/types/src/components/MobileLayout/MobileLayout.d.ts.map +1 -1
  99. package/dist/types/src/components/MobileLayout/MobileLayout.stories.d.ts.map +1 -1
  100. package/dist/types/src/components/NavBranch/NavBranch.d.ts.map +1 -1
  101. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  102. package/dist/types/src/components/SimpleLayout/AppBar.d.ts +5 -7
  103. package/dist/types/src/components/SimpleLayout/AppBar.d.ts.map +1 -1
  104. package/dist/types/src/components/SimpleLayout/AppBar.stories.d.ts +29 -22
  105. package/dist/types/src/components/SimpleLayout/AppBar.stories.d.ts.map +1 -1
  106. package/dist/types/src/components/SimpleLayout/Drawer.d.ts +4 -7
  107. package/dist/types/src/components/SimpleLayout/Drawer.d.ts.map +1 -1
  108. package/dist/types/src/components/SimpleLayout/Main.d.ts +4 -7
  109. package/dist/types/src/components/SimpleLayout/Main.d.ts.map +1 -1
  110. package/dist/types/src/components/SimpleLayout/NavBar.d.ts +5 -7
  111. package/dist/types/src/components/SimpleLayout/NavBar.d.ts.map +1 -1
  112. package/dist/types/src/components/SimpleLayout/NavBar.stories.d.ts +29 -23
  113. package/dist/types/src/components/SimpleLayout/NavBar.stories.d.ts.map +1 -1
  114. package/dist/types/src/components/SimpleLayout/SimpleLayout.d.ts.map +1 -1
  115. package/dist/types/src/components/SimpleLayout/SimpleLayout.stories.d.ts +26 -25
  116. package/dist/types/src/components/SimpleLayout/SimpleLayout.stories.d.ts.map +1 -1
  117. package/dist/types/src/components/hooks.d.ts.map +1 -1
  118. package/dist/types/src/components/index.d.ts +2 -1
  119. package/dist/types/src/components/index.d.ts.map +1 -1
  120. package/dist/types/src/hooks/actions.d.ts +3 -3
  121. package/dist/types/src/hooks/actions.d.ts.map +1 -1
  122. package/dist/types/src/hooks/useAppBarProps.d.ts +2 -2
  123. package/dist/types/src/hooks/useAppBarProps.d.ts.map +1 -1
  124. package/dist/types/src/hooks/useCompanions.d.ts.map +1 -1
  125. package/dist/types/src/hooks/useDrawerActions.d.ts.map +1 -1
  126. package/dist/types/src/hooks/useSimpleLayoutState.d.ts +3 -3
  127. package/dist/types/src/hooks/useSimpleLayoutState.d.ts.map +1 -1
  128. package/dist/types/src/index.d.ts +2 -1
  129. package/dist/types/src/index.d.ts.map +1 -1
  130. package/dist/types/src/meta.d.ts +1 -1
  131. package/dist/types/src/meta.d.ts.map +1 -1
  132. package/dist/types/src/operations/close.d.ts +5 -0
  133. package/dist/types/src/operations/close.d.ts.map +1 -0
  134. package/dist/types/src/operations/index.d.ts +3 -0
  135. package/dist/types/src/operations/index.d.ts.map +1 -0
  136. package/dist/types/src/operations/open.d.ts +5 -0
  137. package/dist/types/src/operations/open.d.ts.map +1 -0
  138. package/dist/types/src/operations/revert-workspace.d.ts +5 -0
  139. package/dist/types/src/operations/revert-workspace.d.ts.map +1 -0
  140. package/dist/types/src/operations/set-layout-mode.d.ts +5 -0
  141. package/dist/types/src/operations/set-layout-mode.d.ts.map +1 -0
  142. package/dist/types/src/operations/set.d.ts +5 -0
  143. package/dist/types/src/operations/set.d.ts.map +1 -0
  144. package/dist/types/src/operations/state-access.d.ts +8 -0
  145. package/dist/types/src/operations/state-access.d.ts.map +1 -0
  146. package/dist/types/src/operations/switch-workspace.d.ts +5 -0
  147. package/dist/types/src/operations/switch-workspace.d.ts.map +1 -0
  148. package/dist/types/src/operations/update-complementary.d.ts +5 -0
  149. package/dist/types/src/operations/update-complementary.d.ts.map +1 -0
  150. package/dist/types/src/operations/update-dialog.d.ts +5 -0
  151. package/dist/types/src/operations/update-dialog.d.ts.map +1 -0
  152. package/dist/types/src/operations/update-popover.d.ts +5 -0
  153. package/dist/types/src/operations/update-popover.d.ts.map +1 -0
  154. package/dist/types/src/operations/update-sidebar.d.ts +5 -0
  155. package/dist/types/src/operations/update-sidebar.d.ts.map +1 -0
  156. package/dist/types/src/plugin.d.ts +4 -0
  157. package/dist/types/src/plugin.d.ts.map +1 -0
  158. package/dist/types/src/translations.d.ts +26 -20
  159. package/dist/types/src/translations.d.ts.map +1 -1
  160. package/dist/types/src/types/{capabilities.d.ts → SimpleLayoutCapabilities.d.ts} +12 -10
  161. package/dist/types/src/types/SimpleLayoutCapabilities.d.ts.map +1 -0
  162. package/dist/types/src/types/SimpleLayoutEvents.d.ts +4 -0
  163. package/dist/types/src/types/SimpleLayoutEvents.d.ts.map +1 -0
  164. package/dist/types/src/types/index.d.ts +2 -2
  165. package/dist/types/src/types/index.d.ts.map +1 -1
  166. package/dist/types/tsconfig.tsbuildinfo +1 -1
  167. package/package.json +87 -37
  168. package/src/SimpleLayoutPlugin.ts +19 -8
  169. package/src/capabilities/app-graph-builder.ts +21 -0
  170. package/src/capabilities/index.ts +13 -6
  171. package/src/capabilities/operation-handler.ts +14 -0
  172. package/src/capabilities/{react-root/react-root.tsx → react-root.tsx} +2 -2
  173. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +13 -6
  174. package/src/capabilities/{state/state.tsx → state.tsx} +5 -6
  175. package/src/capabilities/url-handler.ts +164 -0
  176. package/src/components/ContentError.stories.tsx +1 -1
  177. package/src/components/DebugOverlay/DebugOverlay.tsx +96 -0
  178. package/src/components/DebugOverlay/index.ts +5 -0
  179. package/src/components/Dialog/Dialog.tsx +14 -3
  180. package/src/components/Home/Home.tsx +31 -31
  181. package/src/components/{ContentLoading/ContentLoading.stories.tsx → Loading/Loading.stories.tsx} +4 -4
  182. package/src/components/{ContentLoading/ContentLoading.tsx → Loading/Loading.tsx} +2 -2
  183. package/src/components/{ContentLoading → Loading}/index.ts +1 -1
  184. package/src/components/MobileLayout/MobileLayout.stories.tsx +21 -17
  185. package/src/components/MobileLayout/MobileLayout.tsx +118 -51
  186. package/src/components/NavBranch/NavBranch.tsx +27 -33
  187. package/src/components/Popover/Popover.tsx +17 -21
  188. package/src/components/SimpleLayout/AppBar.stories.tsx +10 -10
  189. package/src/components/SimpleLayout/AppBar.tsx +63 -60
  190. package/src/components/SimpleLayout/Drawer.tsx +30 -22
  191. package/src/components/SimpleLayout/Main.tsx +19 -23
  192. package/src/components/SimpleLayout/NavBar.stories.tsx +2 -2
  193. package/src/components/SimpleLayout/NavBar.tsx +8 -9
  194. package/src/components/SimpleLayout/SimpleLayout.stories.tsx +46 -69
  195. package/src/components/SimpleLayout/SimpleLayout.tsx +33 -34
  196. package/src/components/hooks.ts +1 -1
  197. package/src/components/index.ts +2 -1
  198. package/src/hooks/actions.ts +9 -6
  199. package/src/hooks/useAppBarProps.ts +9 -29
  200. package/src/hooks/useDrawerActions.ts +7 -7
  201. package/src/hooks/useNavbarActions.ts +4 -4
  202. package/src/hooks/useSimpleLayoutState.ts +7 -5
  203. package/src/index.ts +2 -1
  204. package/src/meta.ts +7 -4
  205. package/src/operations/close.ts +34 -0
  206. package/src/operations/index.ts +16 -0
  207. package/src/operations/open.ts +82 -0
  208. package/src/operations/revert-workspace.ts +22 -0
  209. package/src/operations/set-layout-mode.ts +12 -0
  210. package/src/operations/set.ts +23 -0
  211. package/src/operations/state-access.ts +21 -0
  212. package/src/operations/switch-workspace.ts +26 -0
  213. package/src/operations/update-complementary.ts +35 -0
  214. package/src/operations/update-dialog.ts +28 -0
  215. package/src/operations/update-popover.ts +35 -0
  216. package/src/operations/update-sidebar.ts +12 -0
  217. package/src/plugin.ts +11 -0
  218. package/src/translations.ts +21 -19
  219. package/src/types/{capabilities.ts → SimpleLayoutCapabilities.ts} +6 -18
  220. package/src/types/SimpleLayoutEvents.ts +15 -0
  221. package/src/types/index.ts +2 -2
  222. package/dist/lib/browser/chunk-MDPEKLKR.mjs +0 -1163
  223. package/dist/lib/browser/chunk-MDPEKLKR.mjs.map +0 -7
  224. package/dist/lib/browser/chunk-MRR7PXSM.mjs +0 -29
  225. package/dist/lib/browser/chunk-MRR7PXSM.mjs.map +0 -7
  226. package/dist/lib/browser/index.mjs +0 -101
  227. package/dist/lib/browser/index.mjs.map +0 -7
  228. package/dist/lib/browser/meta.json +0 -1
  229. package/dist/lib/browser/operation-resolver-VTZ6HZ4B.mjs +0 -194
  230. package/dist/lib/browser/operation-resolver-VTZ6HZ4B.mjs.map +0 -7
  231. package/dist/lib/browser/react-root-WVQYY2JA.mjs.map +0 -7
  232. package/dist/lib/browser/react-surface-VLBR37ED.mjs.map +0 -7
  233. package/dist/lib/browser/spotlight-dismiss-67PHYS5B.mjs.map +0 -7
  234. package/dist/lib/browser/state-TXSMUWYI.mjs.map +0 -7
  235. package/dist/lib/browser/url-handler-RBRONH7S.mjs +0 -151
  236. package/dist/lib/browser/url-handler-RBRONH7S.mjs.map +0 -7
  237. package/dist/lib/node-esm/chunk-DCKASLMP.mjs +0 -1164
  238. package/dist/lib/node-esm/chunk-DCKASLMP.mjs.map +0 -7
  239. package/dist/lib/node-esm/chunk-WMNTJ2MK.mjs +0 -31
  240. package/dist/lib/node-esm/chunk-WMNTJ2MK.mjs.map +0 -7
  241. package/dist/lib/node-esm/index.mjs +0 -102
  242. package/dist/lib/node-esm/index.mjs.map +0 -7
  243. package/dist/lib/node-esm/meta.json +0 -1
  244. package/dist/lib/node-esm/operation-resolver-R7CQ6ERU.mjs +0 -195
  245. package/dist/lib/node-esm/operation-resolver-R7CQ6ERU.mjs.map +0 -7
  246. package/dist/lib/node-esm/react-root-XBNDM7BE.mjs +0 -22
  247. package/dist/lib/node-esm/react-root-XBNDM7BE.mjs.map +0 -7
  248. package/dist/lib/node-esm/react-surface-U5NHA367.mjs +0 -45
  249. package/dist/lib/node-esm/react-surface-U5NHA367.mjs.map +0 -7
  250. package/dist/lib/node-esm/spotlight-dismiss-RMLRZUVY.mjs +0 -68
  251. package/dist/lib/node-esm/state-JMX6FAG4.mjs +0 -49
  252. package/dist/lib/node-esm/state-JMX6FAG4.mjs.map +0 -7
  253. package/dist/lib/node-esm/url-handler-QSMCH3JB.mjs +0 -152
  254. package/dist/lib/node-esm/url-handler-QSMCH3JB.mjs.map +0 -7
  255. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  256. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  257. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  258. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  259. package/dist/types/src/capabilities/react-root/index.d.ts +0 -6
  260. package/dist/types/src/capabilities/react-root/index.d.ts.map +0 -1
  261. package/dist/types/src/capabilities/react-root/react-root.d.ts.map +0 -1
  262. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  263. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  264. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  265. package/dist/types/src/capabilities/spotlight-dismiss/index.d.ts +0 -3
  266. package/dist/types/src/capabilities/spotlight-dismiss/index.d.ts.map +0 -1
  267. package/dist/types/src/capabilities/spotlight-dismiss/spotlight-dismiss.d.ts.map +0 -1
  268. package/dist/types/src/capabilities/state/index.d.ts +0 -13
  269. package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
  270. package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
  271. package/dist/types/src/capabilities/url-handler/index.d.ts +0 -3
  272. package/dist/types/src/capabilities/url-handler/index.d.ts.map +0 -1
  273. package/dist/types/src/capabilities/url-handler/url-handler.d.ts.map +0 -1
  274. package/dist/types/src/components/ContentLoading/ContentLoading.d.ts +0 -3
  275. package/dist/types/src/components/ContentLoading/ContentLoading.d.ts.map +0 -1
  276. package/dist/types/src/components/ContentLoading/ContentLoading.stories.d.ts.map +0 -1
  277. package/dist/types/src/components/ContentLoading/index.d.ts +0 -2
  278. package/dist/types/src/components/ContentLoading/index.d.ts.map +0 -1
  279. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  280. package/dist/types/src/types/events.d.ts +0 -6
  281. package/dist/types/src/types/events.d.ts.map +0 -1
  282. package/src/capabilities/operation-resolver/index.ts +0 -10
  283. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -202
  284. package/src/capabilities/react-root/index.ts +0 -7
  285. package/src/capabilities/react-surface/index.ts +0 -7
  286. package/src/capabilities/spotlight-dismiss/index.ts +0 -7
  287. package/src/capabilities/state/index.ts +0 -9
  288. package/src/capabilities/url-handler/index.ts +0 -7
  289. package/src/capabilities/url-handler/url-handler.ts +0 -133
  290. package/src/types/events.ts +0 -15
  291. /package/dist/types/src/capabilities/{react-root/react-root.d.ts → react-root.d.ts} +0 -0
  292. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
  293. /package/src/capabilities/{spotlight-dismiss/spotlight-dismiss.ts → spotlight-dismiss.ts} +0 -0
@@ -5,10 +5,11 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { Surface } from '@dxos/app-framework/ui';
8
+ import { AppSurface } from '@dxos/app-toolkit/ui';
8
9
  import { AlertDialog, Dialog as NaturalDialog } from '@dxos/react-ui';
9
10
  import { ErrorFallback } from '@dxos/react-ui';
10
11
 
11
- import { useSimpleLayoutState } from '../../hooks';
12
+ import { useSimpleLayoutState } from '#hooks';
12
13
 
13
14
  export const Dialog = () => {
14
15
  const { state, updateState } = useSimpleLayoutState();
@@ -23,14 +24,24 @@ export const Dialog = () => {
23
24
  onOpenChange={(nextOpen) => updateState((state) => ({ ...state, dialogOpen: nextOpen }))}
24
25
  >
25
26
  {state.dialogBlockAlign === 'end' ? (
26
- <Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={ErrorFallback} />
27
+ <Surface.Surface
28
+ type={AppSurface.Dialog}
29
+ data={state.dialogContent ?? undefined}
30
+ limit={1}
31
+ fallback={ErrorFallback}
32
+ />
27
33
  ) : (
28
34
  <DialogOverlay
29
35
  blockAlign={state.dialogBlockAlign}
30
36
  classNames={state.dialogOverlayClasses}
31
37
  style={state.dialogOverlayStyle}
32
38
  >
33
- <Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={ErrorFallback} />
39
+ <Surface.Surface
40
+ type={AppSurface.Dialog}
41
+ data={state.dialogContent ?? undefined}
42
+ limit={1}
43
+ fallback={ErrorFallback}
44
+ />
34
45
  </DialogOverlay>
35
46
  )}
36
47
  </DialogRoot>
@@ -8,14 +8,15 @@ import { useOperationInvoker } from '@dxos/app-framework/ui';
8
8
  import { LayoutOperation } from '@dxos/app-toolkit';
9
9
  import { useAppGraph } from '@dxos/app-toolkit/ui';
10
10
  import { Node, useConnections } from '@dxos/plugin-graph';
11
- import { Avatar, Icon, Panel, ScrollArea, Toolbar, toLocalizedString, useTranslation } from '@dxos/react-ui';
11
+ import { Avatar, Icon, ScrollArea, toLocalizedString, useTranslation } from '@dxos/react-ui';
12
12
  import { Card } from '@dxos/react-ui';
13
13
  import { Mosaic, type MosaicStackTileComponent } from '@dxos/react-ui-mosaic';
14
- import { SearchList, useSearchListItem, useSearchListResults } from '@dxos/react-ui-searchlist';
14
+ import { SearchPanel, useSearchListItem, useSearchListResults } from '@dxos/react-ui-search';
15
15
  import { mx } from '@dxos/ui-theme';
16
- import { byPosition } from '@dxos/util';
16
+ import { byPosition, getHostPlatform, isTauri } from '@dxos/util';
17
+
18
+ import { meta } from '#meta';
17
19
 
18
- import { meta } from '../../meta';
19
20
  import { useExpandPath } from '../hooks';
20
21
 
21
22
  export type HomeProps = {};
@@ -40,27 +41,24 @@ export const Home = (_: HomeProps) => {
40
41
  extract: (node) => toLocalizedString(node.properties.label, t),
41
42
  });
42
43
 
44
+ const autoFocus = !isTauri() || getHostPlatform() !== 'ios';
45
+
43
46
  return (
44
- <SearchList.Root onSearch={handleSearch}>
45
- <Panel.Root>
46
- <Panel.Toolbar asChild>
47
- <Toolbar.Root>
48
- <SearchList.Input placeholder={t('search placeholder')} autoFocus />
49
- </Toolbar.Root>
50
- </Panel.Toolbar>
51
- <Panel.Content asChild>
52
- <SearchList.Content>
53
- <Mosaic.Container asChild>
54
- <ScrollArea.Root orientation='vertical'>
55
- <ScrollArea.Viewport classNames='p-2'>
56
- <Mosaic.Stack items={results} getId={(node) => node.id} Tile={WorkspaceTile} />
57
- </ScrollArea.Viewport>
58
- </ScrollArea.Root>
59
- </Mosaic.Container>
60
- </SearchList.Content>
61
- </Panel.Content>
62
- </Panel.Root>
63
- </SearchList.Root>
47
+ <SearchPanel onSearch={handleSearch}>
48
+ <Mosaic.Container asChild>
49
+ <ScrollArea.Root centered padding thin>
50
+ <ScrollArea.Viewport>
51
+ <Mosaic.Stack
52
+ classNames='gap-1'
53
+ draggable={false}
54
+ items={results}
55
+ getId={(item) => item.id}
56
+ Tile={WorkspaceTile}
57
+ />
58
+ </ScrollArea.Viewport>
59
+ </ScrollArea.Root>
60
+ </Mosaic.Container>
61
+ </SearchPanel>
64
62
  );
65
63
  };
66
64
 
@@ -102,24 +100,24 @@ const WorkspaceTile: MosaicStackTileComponent<Node.Node> = (props) => {
102
100
  fullWidth
103
101
  tabIndex={-1} // TODO(burdon): Use Mosaic.Focus.
104
102
  data-selected={isSelected}
105
- classNames={mx('dx-focus-ring', isSelected && 'bg-hover-overlay')}
103
+ classNames={mx('dx-focus-ring', isSelected && 'bg-selected-surface')}
106
104
  onClick={handleSelect}
107
105
  ref={cardRef}
108
106
  >
109
- <Card.Toolbar density='coarse'>
107
+ <Card.Header density='md'>
110
108
  <Avatar.Root>
111
109
  <Avatar.Content
112
110
  icon={data.properties.icon}
113
111
  hue={data.properties.hue}
114
112
  hueVariant='transparent'
115
113
  variant='square'
116
- size={12}
114
+ size={8}
117
115
  fallback={name}
118
116
  />
119
- <Avatar.Label>{name}</Avatar.Label>
117
+ <Avatar.Label classNames='cursor-pointer'>{name}</Avatar.Label>
120
118
  <Icon icon='ph--caret-right--regular' />
121
119
  </Avatar.Root>
122
- </Card.Toolbar>
120
+ </Card.Header>
123
121
  </Card.Root>
124
122
  );
125
123
  };
@@ -133,6 +131,8 @@ const filterItems = (node: Node.Node, disposition: string) => {
133
131
  const useItemsByDisposition = (disposition: string, sort = false) => {
134
132
  const { graph } = useAppGraph();
135
133
  const connections = useConnections(graph, Node.RootId, 'child');
136
- const filtered = connections.filter((node) => filterItems(node, disposition));
137
- return sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
134
+ return useMemo(() => {
135
+ const filtered = connections.filter((node) => filterItems(node, disposition));
136
+ return sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
137
+ }, [connections, disposition, sort]);
138
138
  };
@@ -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/components/ContentLoading',
13
- component: ContentLoading,
12
+ title: 'plugins/plugin-simple-layout/components/Loading',
13
+ component: Loading,
14
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 dx-attention-surface' />;
8
+ export const Loading = () => {
9
+ return <div className='grid place-items-center dx-attention-surface' />;
10
10
  };
@@ -2,4 +2,4 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './ContentLoading';
5
+ export * from './Loading';
@@ -6,7 +6,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { type PropsWithChildren, useEffect, useState } from 'react';
7
7
 
8
8
  import { addEventListener, combine } from '@dxos/async';
9
- import { Flex, Input, Panel, Splitter, type SplitterMode, Toolbar } from '@dxos/react-ui';
9
+ import { Column, Flex, Input, Panel, Splitter, type SplitterMode, Toolbar } from '@dxos/react-ui';
10
10
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
11
 
12
12
  import { MobileLayout, type MobileLayoutRootProps } from './MobileLayout';
@@ -65,44 +65,48 @@ const StoryPanel = ({ children, label }: PropsWithChildren<{ label: string }>) =
65
65
  </Toolbar.Root>
66
66
  </Panel.Toolbar>
67
67
  <Panel.Content asChild>
68
- <Flex column classNames='p-1'>
69
- <Input.Root>
70
- <Input.TextInput />
71
- </Input.Root>
72
- </Flex>
68
+ <Column.Root gutter='xs' classNames='py-form-chrome'>
69
+ <Column.Center>
70
+ <Flex column>
71
+ <Input.Root>
72
+ <Input.TextInput placeholder={label} />
73
+ </Input.Root>
74
+ </Flex>
75
+ </Column.Center>
76
+ </Column.Root>
73
77
  </Panel.Content>
74
78
  </Panel.Root>
75
79
  );
76
80
  };
77
81
 
78
82
  const DefaultStory = () => {
79
- const [splitterMode, setSplitterMode] = useState<SplitterMode>('upper');
83
+ const [splitterMode, setSplitterMode] = useState<SplitterMode>('top');
80
84
  const [keyboardOpen, setKeyboardOpen] = useState(false);
81
85
 
82
86
  useEffect(() => {
83
- setSplitterMode(splitterMode === 'both' ? 'lower' : splitterMode);
87
+ setSplitterMode(splitterMode === 'split' ? 'bottom' : splitterMode);
84
88
  }, [keyboardOpen]);
85
89
 
86
90
  return (
87
91
  <WithKeyboard>
88
92
  <MobileLayout.Root onKeyboardOpenChange={setKeyboardOpen}>
89
- <MobileLayout.Panel safe={{ top: true, bottom: splitterMode === 'upper' }}>
93
+ <MobileLayout.Panel safe={{ top: true, bottom: splitterMode === 'top' }}>
90
94
  <Splitter.Root mode={splitterMode} ratio={0.5}>
91
- <Splitter.Panel position='upper'>
95
+ <Splitter.Panel position='top'>
92
96
  <StoryPanel label='Main'>
93
- {splitterMode === 'upper' && (
94
- <Toolbar.IconButton icon='ph--plus--regular' label='Open' onClick={() => setSplitterMode('both')} />
97
+ {splitterMode === 'top' && (
98
+ <Toolbar.IconButton icon='ph--plus--regular' label='Open' onClick={() => setSplitterMode('split')} />
95
99
  )}
96
100
  </StoryPanel>
97
101
  </Splitter.Panel>
98
- <Splitter.Panel position='lower'>
102
+ <Splitter.Panel position='bottom'>
99
103
  <StoryPanel label='Drawer'>
100
104
  <Toolbar.IconButton
101
- icon={splitterMode === 'lower' ? 'ph--arrow-down--regular' : 'ph--arrow-up--regular'}
102
- label={splitterMode === 'lower' ? 'Collapse' : 'Expand'}
103
- onClick={() => setSplitterMode((splitterMode) => (splitterMode === 'both' ? 'lower' : 'both'))}
105
+ icon={splitterMode === 'bottom' ? 'ph--arrow-down--regular' : 'ph--arrow-up--regular'}
106
+ label={splitterMode === 'bottom' ? 'Collapse' : 'Expand'}
107
+ onClick={() => setSplitterMode((splitterMode) => (splitterMode === 'split' ? 'bottom' : 'split'))}
104
108
  />
105
- <Toolbar.IconButton icon='ph--x--regular' label='Close' onClick={() => setSplitterMode('upper')} />
109
+ <Toolbar.IconButton icon='ph--x--regular' label='Close' onClick={() => setSplitterMode('top')} />
106
110
  </StoryPanel>
107
111
  </Splitter.Panel>
108
112
  </Splitter.Root>
@@ -3,14 +3,14 @@
3
3
  //
4
4
 
5
5
  import { createContext } from '@radix-ui/react-context';
6
- import React, { type PropsWithChildren, forwardRef, useEffect, useState } from 'react';
6
+ import React, { type PropsWithChildren, forwardRef, useEffect, useLayoutEffect, useState } from 'react';
7
7
 
8
8
  import { addEventListener, combine } from '@dxos/async';
9
9
  import { log } from '@dxos/log';
10
10
  import { type ThemedClassName } from '@dxos/react-ui';
11
11
  import { mx } from '@dxos/ui-theme';
12
12
 
13
- // TODO(burdon): Move into @dxos/react-ui?
13
+ import { useDebugLog } from '../DebugOverlay';
14
14
 
15
15
  const MOBILE_LAYOUT_NAME = 'MobileLayout';
16
16
  const MOBILE_LAYOUT_ROOT_NAME = 'MobileLayout.Root';
@@ -42,22 +42,26 @@ type MobileLayoutRootProps = ThemedClassName<
42
42
  */
43
43
  // TODO(burdon): Should this be ios-only?
44
44
  const MobileLayoutRoot = forwardRef<HTMLDivElement, MobileLayoutRootProps>(
45
- ({ classNames, children, transition = 250, onKeyboardOpenChange, ...props }, forwardedRef) => {
45
+ ({ classNames, children, transition = 500, onKeyboardOpenChange, ...props }, forwardedRef) => {
46
46
  const { open: keyboardOpen } = useIOSKeyboard();
47
- useAutoScroll();
48
- useEffect(() => onKeyboardOpenChange?.(keyboardOpen), [onKeyboardOpenChange, keyboardOpen]);
49
47
  useLockBodyScroll(keyboardOpen);
48
+ useAutoScroll();
49
+
50
+ // Fire synchronously after DOM mutation (before paint) so SimpleLayout's Splitter mode
51
+ // change is batched into the same paint as the keyboard open state change, preventing
52
+ // intermediate render frames from showing an un-adjusted layout.
53
+ useLayoutEffect(() => onKeyboardOpenChange?.(keyboardOpen), [keyboardOpen, onKeyboardOpenChange]);
50
54
 
51
55
  return (
52
56
  <MobileLayoutProvider keyboardOpen={keyboardOpen}>
53
57
  <div
54
58
  {...props}
55
- role='none'
56
59
  style={{
57
- transition: `h-size ${transition}ms ease-out`,
58
- blockSize: 'calc(100vh - var(--kb-height, 0px))',
60
+ height: 'calc(100vh - var(--kb-height, 0px))',
61
+ transition: `height ${keyboardOpen ? 0 : transition}ms ease-out`,
62
+ // transition: `height ${animationDuration}ms ease-out`,
59
63
  }}
60
- className={mx('absolute top-0 left-0 right-0 flex flex-col', classNames)}
64
+ className={mx('fixed top-0 left-0 right-0 grid overflow-hidden', classNames)}
61
65
  ref={forwardedRef}
62
66
  >
63
67
  {children}
@@ -90,12 +94,11 @@ const MobileLayoutPanel = forwardRef<HTMLDivElement, MobileLayoutPanelProps>(
90
94
  return (
91
95
  <div
92
96
  {...props}
93
- role='none'
94
97
  style={{
95
98
  paddingTop: safe?.top ? 'env(safe-area-inset-top)' : undefined,
96
99
  paddingBottom: safe?.bottom ? `calc((1 - var(--kb-open, 0)) * env(safe-area-inset-bottom))` : undefined,
97
100
  }}
98
- className={mx('relative h-full flex flex-col overflow-hidden', classNames)}
101
+ className={mx(classNames)}
99
102
  ref={forwardedRef}
100
103
  >
101
104
  {children}
@@ -120,42 +123,62 @@ export { useMobileLayout };
120
123
  export type { MobileLayoutRootProps, MobileLayoutPanelProps };
121
124
 
122
125
  /**
123
- * Prevent auto-scroll when input is focused.
126
+ * Prevents iOS (WKWebView) from shifting the layout when the keyboard appears.
127
+ *
128
+ * Scroll events and window.scrollY stay at 0 in this WKWebView setup — the shift is
129
+ * caused by the browser's scroll-into-view for the focused input. We keep a window
130
+ * scroll reset as belt-and-suspenders, and also monitor container scroll events.
124
131
  */
125
132
  const useAutoScroll = () => {
133
+ // TODO(burdon): Remove debug logging.
134
+ const { dbg } = useDebugLog('useAutoScroll');
135
+
126
136
  useEffect(() => {
127
- // Prevent auto-scroll when input is focused.
128
- return addEventListener(
129
- document,
130
- 'focus',
131
- (event: FocusEvent) => {
132
- const target = event.target as HTMLElement;
133
- if (
134
- target.tagName === 'INPUT' ||
135
- target.tagName === 'TEXTAREA' ||
136
- (target.tagName === 'DIV' && target.isContentEditable)
137
- ) {
138
- // Prevent default focus behavior.
139
- event.preventDefault();
140
-
141
- // Manually focus without scroll.
142
- target.focus({ preventScroll: true });
143
-
144
- // Lock current scroll position.
145
- const scrollX = window.scrollX;
146
- const scrollY = window.scrollY;
147
- requestAnimationFrame(() => {
148
- window.scrollTo(scrollX, scrollY);
149
- });
150
-
151
- // TODO(burdon): Scroll to position in parent; this may need to be via an intent,
152
- // since it may be plugin-specific (e.g., codemirror document.)
153
- }
154
- },
155
- // Important: focus events don't bubble, so capture phase is required.
156
- { capture: true },
137
+ const resetScroll = () => {
138
+ if (window.scrollX !== 0 || window.scrollY !== 0) {
139
+ window.scrollTo(0, 0);
140
+ }
141
+ };
142
+
143
+ const detectContainerScroll = (event: Event) => {
144
+ const el = event.target as HTMLElement;
145
+ if (el === document.documentElement || el === document.body) {
146
+ return;
147
+ }
148
+
149
+ dbg(`scroll: ${el.tagName}.${Array.from(el.classList).slice(0, 2).join('.')} top=${el.scrollTop.toFixed(0)}`);
150
+ };
151
+
152
+ return combine(
153
+ addEventListener(window, 'scroll', resetScroll),
154
+ window.visualViewport ? addEventListener(window.visualViewport, 'scroll' as any, resetScroll) : () => {},
155
+
156
+ // TODO(burdon): Remove debug logging.
157
+ addEventListener(document, 'scroll', detectContainerScroll as EventListener, { capture: true } as any),
158
+
159
+ // Prevent focus-triggered scroll-into-view on inputs.
160
+ (() => {
161
+ let focusingWithPreventScroll = false;
162
+ return addEventListener(
163
+ document,
164
+ 'focus',
165
+ (event: FocusEvent) => {
166
+ if (focusingWithPreventScroll) {
167
+ return;
168
+ }
169
+
170
+ const target = event.target as HTMLElement;
171
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
172
+ focusingWithPreventScroll = true;
173
+ target.focus({ preventScroll: true });
174
+ focusingWithPreventScroll = false;
175
+ }
176
+ },
177
+ { capture: true },
178
+ );
179
+ })(),
157
180
  );
158
- }, []);
181
+ }, [dbg]);
159
182
  };
160
183
 
161
184
  /**
@@ -231,6 +254,8 @@ const useLockBodyScroll = (enabled: boolean) => {
231
254
  type IOSKeyboard = {
232
255
  open: boolean;
233
256
  height: number;
257
+ /** Native keyboard animation duration in ms, from the iOS keyboard event. */
258
+ duration: number | undefined;
234
259
  };
235
260
 
236
261
  /**
@@ -263,10 +288,13 @@ type IOSKeyboard = {
263
288
  * Falls back to VisualViewport API on other platforms.
264
289
  */
265
290
  const useIOSKeyboard = (): IOSKeyboard => {
291
+ const { dbg } = useDebugLog('useIOSKeyboard');
292
+
266
293
  const [open, setOpen] = useState(false);
267
294
  const [height, setHeight] = useState(0);
295
+ const [duration, setDuration] = useState<number | undefined>(undefined);
268
296
 
269
- // Detect keybaord state.
297
+ // Detect keyboard state.
270
298
  useEffect(() => {
271
299
  const viewport = window.visualViewport;
272
300
  if (!viewport) {
@@ -276,30 +304,69 @@ const useIOSKeyboard = (): IOSKeyboard => {
276
304
  // Handler for VisualViewport resize (fallback for non-iOS).
277
305
  const initialHeight = viewport.height ?? window.innerHeight;
278
306
 
279
- const updateState = (keyboardHeight: number, keyboardOpen: boolean) => {
307
+ const updateState = (keyboardHeight: number, keyboardOpen: boolean, animationDuration?: number) => {
280
308
  setOpen(keyboardOpen);
281
309
  setHeight(keyboardHeight);
310
+ setDuration(animationDuration);
282
311
 
283
312
  const vvh = initialHeight - keyboardHeight;
284
313
  document.documentElement.style.setProperty('--vvh', `${vvh}px`);
285
314
  document.documentElement.style.setProperty('--kb-height', `${keyboardHeight}px`);
286
315
  document.documentElement.style.setProperty('--kb-open', keyboardOpen ? '1' : '0');
287
- log.info('viewport size', { initialHeight, vvh, keyboardHeight, keyboardOpen });
316
+ log.info('viewport size', { initialHeight, vvh, keyboardHeight, keyboardOpen, animationDuration });
288
317
  };
289
318
 
319
+ let rafId: number | undefined;
320
+
290
321
  return combine(
291
322
  // Handler for native iOS keyboard events (from KeyboardObserver.swift).
292
323
  addEventListener(
293
324
  window,
294
325
  'keyboard' as any,
295
326
  (event: CustomEvent<{ type: 'show' | 'hide'; height: number; duration: number }>) => {
296
- const { type, height } = event.detail;
297
- log.info('keyboard event', { type, height });
298
- updateState(height, type === 'show');
327
+ const { type, height, duration } = event.detail;
328
+ // iOS KeyboardObserver.swift sends duration in seconds (e.g., 0.25). Convert to ms.
329
+ const durationMs = duration < 1 ? duration * 1000 : duration;
330
+
331
+ // TODO(burdon): Remove debug logging.
332
+ const vp = window.visualViewport;
333
+ dbg(
334
+ `kb:${type} h=${height} dur=${duration} scrollY=${window.scrollY} vpOffset=${vp?.offsetTop?.toFixed(0) ?? '?'}`,
335
+ );
336
+ log.info('keyboard event', { type, height, duration });
337
+
338
+ updateState(height, type === 'show', durationMs);
339
+
340
+ // RAF loop: monitor visualViewport.offsetTop and window.scrollY every frame.
341
+ // TODO(burdon): Remove debug logging.
342
+ const end = performance.now() + durationMs + 300;
343
+ let prevOffsetTop = vp?.offsetTop ?? 0;
344
+ let prevScrollY = window.scrollY;
345
+ const monitorFrame = () => {
346
+ const offsetTop = vp?.offsetTop ?? 0;
347
+ const scrollY = window.scrollY;
348
+ if (offsetTop !== prevOffsetTop || scrollY !== prevScrollY) {
349
+ dbg(`Δ vpOffset=${offsetTop.toFixed(0)} scrollY=${scrollY.toFixed(0)}`);
350
+ prevOffsetTop = offsetTop;
351
+ prevScrollY = scrollY;
352
+ }
353
+ if (scrollY !== 0) {
354
+ window.scrollTo(0, 0);
355
+ }
356
+ if (performance.now() < end) {
357
+ rafId = requestAnimationFrame(monitorFrame);
358
+ }
359
+ };
360
+ rafId = requestAnimationFrame(monitorFrame);
299
361
  },
300
362
  ),
363
+ () => {
364
+ if (rafId !== undefined) {
365
+ cancelAnimationFrame(rafId);
366
+ }
367
+ },
301
368
  );
302
- }, []);
369
+ }, [dbg]);
303
370
 
304
- return { open, height };
371
+ return { open, height, duration };
305
372
  };
@@ -8,13 +8,14 @@ import { useOperationInvoker } from '@dxos/app-framework/ui';
8
8
  import { LayoutOperation } from '@dxos/app-toolkit';
9
9
  import { useAppGraph } from '@dxos/app-toolkit/ui';
10
10
  import { type Node, useConnections } from '@dxos/plugin-graph';
11
- import { Avatar, Icon, Panel, ScrollArea, Toolbar, toLocalizedString, useTranslation } from '@dxos/react-ui';
11
+ import { Avatar, Icon, ScrollArea, toLocalizedString, useTranslation } from '@dxos/react-ui';
12
12
  import { Card } from '@dxos/react-ui';
13
13
  import { Mosaic, type MosaicStackTileComponent } from '@dxos/react-ui-mosaic';
14
- import { SearchList, useSearchListItem, useSearchListResults } from '@dxos/react-ui-searchlist';
14
+ import { SearchPanel, useSearchListItem, useSearchListResults } from '@dxos/react-ui-search';
15
15
  import { mx } from '@dxos/ui-theme';
16
16
 
17
- import { meta } from '../../meta';
17
+ import { meta } from '#meta';
18
+
18
19
  import { useExpandPath } from '../hooks';
19
20
 
20
21
  export type NavBranchProps = {
@@ -34,9 +35,8 @@ export const NavBranch = ({ id }: NavBranchProps) => {
34
35
 
35
36
  const children = useConnections(graph, id, 'child');
36
37
 
37
- // TODO(wittjosiah): Move alternate-tree nodes to a non-child relation so they don't need filtering.
38
38
  const visibleChildren = useMemo(
39
- () => children.filter((node) => node.properties.disposition !== 'alternate-tree'),
39
+ () => children.filter((node) => node.properties.disposition !== 'hidden'),
40
40
  [children],
41
41
  );
42
42
 
@@ -46,34 +46,28 @@ export const NavBranch = ({ id }: NavBranchProps) => {
46
46
  });
47
47
 
48
48
  return (
49
- <SearchList.Root onSearch={handleSearch}>
50
- <Panel.Root>
51
- <Panel.Toolbar asChild>
52
- <Toolbar.Root>
53
- {/* TODO(wittjosiah): Search should be pluggable. Must support searching via ECHO query inside a space. */}
54
- <SearchList.Input placeholder={t('search placeholder')} autoFocus />
55
- </Toolbar.Root>
56
- </Panel.Toolbar>
57
- <Panel.Content asChild>
58
- <SearchList.Content>
59
- <Mosaic.Container asChild>
60
- <ScrollArea.Root orientation='vertical'>
61
- <ScrollArea.Viewport classNames='p-2'>
62
- <Mosaic.Stack items={results} getId={(child) => child.id} Tile={NavBranchTile} />
63
- </ScrollArea.Viewport>
64
- </ScrollArea.Root>
65
- </Mosaic.Container>
66
- </SearchList.Content>
67
- </Panel.Content>
68
- </Panel.Root>
69
- </SearchList.Root>
49
+ <SearchPanel onSearch={handleSearch}>
50
+ <Mosaic.Container asChild>
51
+ <ScrollArea.Root centered padding thin>
52
+ <ScrollArea.Viewport>
53
+ <Mosaic.Stack
54
+ classNames='gap-1'
55
+ draggable={false}
56
+ items={results}
57
+ getId={(item) => item.id}
58
+ Tile={NavBranchTile}
59
+ />
60
+ </ScrollArea.Viewport>
61
+ </ScrollArea.Root>
62
+ </Mosaic.Container>
63
+ </SearchPanel>
70
64
  );
71
65
  };
72
66
 
73
67
  const NavBranchTile: MosaicStackTileComponent<Node.Node> = (props) => {
74
68
  const data = props.data;
75
69
  const { t } = useTranslation(meta.id);
76
- const { invokeSync } = useOperationInvoker();
70
+ const { invokePromise } = useOperationInvoker();
77
71
  const ref = useRef<HTMLDivElement>(null);
78
72
  const { selectedValue, registerItem, unregisterItem } = useSearchListItem();
79
73
  const isSelected = selectedValue === data.id;
@@ -81,8 +75,8 @@ const NavBranchTile: MosaicStackTileComponent<Node.Node> = (props) => {
81
75
  const name = toLocalizedString(data.properties.label, t);
82
76
 
83
77
  const handleSelect = useCallback(
84
- () => invokeSync(LayoutOperation.Open, { subject: [data.id] }),
85
- [invokeSync, data.id],
78
+ () => void invokePromise(LayoutOperation.Open, { subject: [data.id] }),
79
+ [invokePromise, data.id],
86
80
  );
87
81
 
88
82
  // Register this item with the search context.
@@ -108,23 +102,23 @@ const NavBranchTile: MosaicStackTileComponent<Node.Node> = (props) => {
108
102
  fullWidth
109
103
  tabIndex={-1} // TODO(burdon): Use Mosaic.Focus.
110
104
  data-selected={isSelected}
111
- classNames={mx('dx-focus-ring', isSelected && 'bg-hover-overlay')}
105
+ classNames={mx('dx-focus-ring cursor-pointer', isSelected && 'bg-selected-surface')}
112
106
  onClick={handleSelect}
113
107
  >
114
- <Card.Toolbar density='coarse'>
108
+ <Card.Header>
115
109
  <Avatar.Root>
116
110
  <Avatar.Content
117
111
  hue={data.properties.hue}
118
112
  icon={data.properties.icon}
119
113
  hueVariant='transparent'
120
114
  variant='square'
121
- size={12}
115
+ size={8}
122
116
  fallback={name}
123
117
  />
124
118
  <Avatar.Label>{name}</Avatar.Label>
125
119
  <Icon icon='ph--caret-right--regular' />
126
120
  </Avatar.Root>
127
- </Card.Toolbar>
121
+ </Card.Header>
128
122
  </Card.Root>
129
123
  );
130
124
  };