@dxos/plugin-deck 0.8.4-main.422d1c7879 → 0.8.4-main.43cb759274

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 (381) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +541 -0
  3. package/README.md +1 -1
  4. package/dist/lib/neutral/DeckLayout-YABVXRDU.mjs +291 -0
  5. package/dist/lib/neutral/DeckLayout-YABVXRDU.mjs.map +7 -0
  6. package/dist/lib/neutral/DeckPlugin.mjs +87 -0
  7. package/dist/lib/neutral/DeckPlugin.mjs.map +7 -0
  8. package/dist/lib/neutral/DeckPlugin.node.mjs +18 -0
  9. package/dist/lib/neutral/DeckPlugin.node.mjs.map +7 -0
  10. package/dist/lib/neutral/DeckPlugin.workerd.mjs +16 -0
  11. package/dist/lib/neutral/DeckPlugin.workerd.mjs.map +7 -0
  12. package/dist/lib/neutral/DeckSettings-W5I57OXM.mjs +27 -0
  13. package/dist/lib/neutral/DeckSettings-W5I57OXM.mjs.map +7 -0
  14. package/dist/lib/{browser/add-toast-EUN62IUE.mjs → neutral/add-toast-TNB6DXWU.mjs} +5 -5
  15. package/dist/lib/{browser/add-toast-EUN62IUE.mjs.map → neutral/add-toast-TNB6DXWU.mjs.map} +2 -2
  16. package/dist/lib/{browser/adjust-XWB6ZZ6U.mjs → neutral/adjust-HNU5CCRO.mjs} +15 -17
  17. package/dist/lib/neutral/adjust-HNU5CCRO.mjs.map +7 -0
  18. package/dist/lib/neutral/app-graph-builder-HMLT627T.mjs +129 -0
  19. package/dist/lib/neutral/app-graph-builder-HMLT627T.mjs.map +7 -0
  20. package/dist/lib/neutral/capabilities/index.mjs +25 -0
  21. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  22. package/dist/lib/neutral/check-app-scheme-A7FZVNZO.mjs +10 -0
  23. package/dist/lib/neutral/chunk-BS4EOYMK.mjs +282 -0
  24. package/dist/lib/neutral/chunk-BS4EOYMK.mjs.map +7 -0
  25. package/dist/lib/neutral/chunk-GBIGQKYW.mjs +112 -0
  26. package/dist/lib/neutral/chunk-GBIGQKYW.mjs.map +7 -0
  27. package/dist/lib/{browser/chunk-KUTDCWZF.mjs → neutral/chunk-GLB73Q6U.mjs} +2 -10
  28. package/dist/lib/{browser/chunk-KUTDCWZF.mjs.map → neutral/chunk-GLB73Q6U.mjs.map} +2 -2
  29. package/dist/lib/neutral/chunk-OQGC7JYT.mjs +8 -0
  30. package/dist/lib/neutral/chunk-OQGC7JYT.mjs.map +7 -0
  31. package/dist/lib/neutral/chunk-PYEY5SEC.mjs +37 -0
  32. package/dist/lib/neutral/chunk-PYEY5SEC.mjs.map +7 -0
  33. package/dist/lib/neutral/chunk-Q534NBCS.mjs +1305 -0
  34. package/dist/lib/neutral/chunk-Q534NBCS.mjs.map +7 -0
  35. package/dist/lib/neutral/chunk-VHETZ22W.mjs +101 -0
  36. package/dist/lib/neutral/chunk-VHETZ22W.mjs.map +7 -0
  37. package/dist/lib/{browser/chunk-DF2VZ6W3.mjs → neutral/chunk-ZYYOSX5I.mjs} +1 -1
  38. package/dist/lib/{browser/chunk-DF2VZ6W3.mjs.map → neutral/chunk-ZYYOSX5I.mjs.map} +2 -2
  39. package/dist/lib/{browser/close-JXK73YIM.mjs → neutral/close-ASKR22A6.mjs} +12 -12
  40. package/dist/lib/{browser/close-JXK73YIM.mjs.map → neutral/close-ASKR22A6.mjs.map} +2 -2
  41. package/dist/lib/neutral/components/index.mjs +126 -0
  42. package/dist/lib/neutral/components/index.mjs.map +7 -0
  43. package/dist/lib/neutral/containers/index.mjs +32 -0
  44. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  45. package/dist/lib/neutral/hooks/index.mjs +159 -0
  46. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  47. package/dist/lib/{node-esm/types → neutral}/index.mjs +13 -8
  48. package/dist/lib/neutral/meta.json +1 -0
  49. package/dist/lib/neutral/meta.mjs +8 -0
  50. package/dist/lib/neutral/notification-tracker-BYKXOXDE.mjs +128 -0
  51. package/dist/lib/neutral/notification-tracker-BYKXOXDE.mjs.map +7 -0
  52. package/dist/lib/{browser/open-K2JOEW2E.mjs → neutral/open-IFIEYVHG.mjs} +34 -25
  53. package/dist/lib/neutral/open-IFIEYVHG.mjs.map +7 -0
  54. package/dist/lib/neutral/operation-handler-266CVMTW.mjs +13 -0
  55. package/dist/lib/neutral/operation-handler-266CVMTW.mjs.map +7 -0
  56. package/dist/lib/neutral/operations/index.mjs +8 -0
  57. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  58. package/dist/lib/neutral/plugin.mjs +16 -0
  59. package/dist/lib/neutral/plugin.mjs.map +7 -0
  60. package/dist/lib/neutral/react-root-HH5DEUOG.mjs +44 -0
  61. package/dist/lib/neutral/react-root-HH5DEUOG.mjs.map +7 -0
  62. package/dist/lib/neutral/react-surface-3UVVCK3O.mjs +34 -0
  63. package/dist/lib/neutral/react-surface-3UVVCK3O.mjs.map +7 -0
  64. package/dist/lib/{browser/revert-workspace-BNIR5U64.mjs → neutral/revert-workspace-B2QLT2C4.mjs} +5 -5
  65. package/dist/lib/{browser/revert-workspace-BNIR5U64.mjs.map → neutral/revert-workspace-B2QLT2C4.mjs.map} +2 -2
  66. package/dist/lib/{browser/scroll-into-view-4GSKC3GA.mjs → neutral/scroll-into-view-B52C3PJO.mjs} +5 -5
  67. package/dist/lib/{browser/scroll-into-view-4GSKC3GA.mjs.map → neutral/scroll-into-view-B52C3PJO.mjs.map} +2 -2
  68. package/dist/lib/{browser/set-XCG6NIAO.mjs → neutral/set-PA35ONXO.mjs} +11 -11
  69. package/dist/lib/{browser/set-XCG6NIAO.mjs.map → neutral/set-PA35ONXO.mjs.map} +2 -2
  70. package/dist/lib/{browser/set-layout-mode-BEVNGOY2.mjs → neutral/set-layout-mode-RPCCPQRB.mjs} +10 -15
  71. package/dist/lib/neutral/set-layout-mode-RPCCPQRB.mjs.map +7 -0
  72. package/dist/lib/neutral/settings-EGNYUM4T.mjs +33 -0
  73. package/dist/lib/neutral/settings-EGNYUM4T.mjs.map +7 -0
  74. package/dist/lib/neutral/state-IIDXMQUO.mjs +86 -0
  75. package/dist/lib/neutral/state-IIDXMQUO.mjs.map +7 -0
  76. package/dist/lib/{browser/switch-workspace-ICJJWNFT.mjs → neutral/switch-workspace-LZF4KZXH.mjs} +9 -17
  77. package/dist/lib/neutral/switch-workspace-LZF4KZXH.mjs.map +7 -0
  78. package/dist/lib/neutral/translations.mjs +59 -0
  79. package/dist/lib/neutral/translations.mjs.map +7 -0
  80. package/dist/lib/{browser → neutral}/types/index.mjs +7 -5
  81. package/dist/lib/neutral/types/index.mjs.map +7 -0
  82. package/dist/lib/{browser/update-companion-VPCBH3YT.mjs → neutral/update-companion-YUCZZVGY.mjs} +7 -7
  83. package/dist/lib/neutral/update-companion-YUCZZVGY.mjs.map +7 -0
  84. package/dist/lib/{browser/update-complementary-74DEQY6T.mjs → neutral/update-complementary-7FZNB55J.mjs} +6 -6
  85. package/dist/lib/neutral/update-complementary-7FZNB55J.mjs.map +7 -0
  86. package/dist/lib/{browser/update-dialog-6TDUYI5R.mjs → neutral/update-dialog-FNQTSSAP.mjs} +5 -5
  87. package/dist/lib/{browser/update-dialog-6TDUYI5R.mjs.map → neutral/update-dialog-FNQTSSAP.mjs.map} +2 -2
  88. package/dist/lib/neutral/update-plank-size-3YW4NXEY.mjs +26 -0
  89. package/dist/lib/neutral/update-plank-size-3YW4NXEY.mjs.map +7 -0
  90. package/dist/lib/{browser/update-popover-W7E2Z5T6.mjs → neutral/update-popover-G2VUD7E6.mjs} +5 -5
  91. package/dist/lib/{browser/update-popover-W7E2Z5T6.mjs.map → neutral/update-popover-G2VUD7E6.mjs.map} +2 -2
  92. package/dist/lib/{browser/update-sidebar-H3A6ZFRU.mjs → neutral/update-sidebar-KRHPUHUB.mjs} +6 -6
  93. package/dist/lib/{browser/update-sidebar-H3A6ZFRU.mjs.map → neutral/update-sidebar-KRHPUHUB.mjs.map} +2 -2
  94. package/dist/lib/neutral/url-handler-4SW6BFAC.mjs +229 -0
  95. package/dist/lib/neutral/url-handler-4SW6BFAC.mjs.map +7 -0
  96. package/dist/types/src/DeckPlugin.d.ts +1 -0
  97. package/dist/types/src/DeckPlugin.d.ts.map +1 -1
  98. package/dist/types/src/DeckPlugin.node.d.ts +4 -0
  99. package/dist/types/src/DeckPlugin.node.d.ts.map +1 -0
  100. package/dist/types/src/DeckPlugin.test.d.ts +2 -0
  101. package/dist/types/src/DeckPlugin.test.d.ts.map +1 -0
  102. package/dist/types/src/DeckPlugin.workerd.d.ts +4 -0
  103. package/dist/types/src/DeckPlugin.workerd.d.ts.map +1 -0
  104. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  105. package/dist/types/src/capabilities/check-app-scheme.d.ts +1 -1
  106. package/dist/types/src/capabilities/check-app-scheme.d.ts.map +1 -1
  107. package/dist/types/src/capabilities/index.d.ts +30 -29
  108. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  109. package/dist/types/src/capabilities/notification-tracker.d.ts +13 -0
  110. package/dist/types/src/capabilities/notification-tracker.d.ts.map +1 -0
  111. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  112. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -1
  113. package/dist/types/src/capabilities/react-root.d.ts.map +1 -1
  114. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  115. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  116. package/dist/types/src/capabilities/state.d.ts +28 -28
  117. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  118. package/dist/types/src/capabilities/tools.d.ts.map +1 -1
  119. package/dist/types/src/capabilities/url-handler.d.ts +1 -1
  120. package/dist/types/src/capabilities/url-handler.d.ts.map +1 -1
  121. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -1
  122. package/dist/types/src/components/DeckSettings/DeckSettings.stories.d.ts +44 -52
  123. package/dist/types/src/components/DeckSettings/DeckSettings.stories.d.ts.map +1 -1
  124. package/dist/types/src/components/Matrix/Matrix.d.ts +2 -2
  125. package/dist/types/src/components/Matrix/Matrix.d.ts.map +1 -1
  126. package/dist/types/src/components/Matrix/Matrix.stories.d.ts.map +1 -1
  127. package/dist/types/src/containers/Deck/Banner.d.ts +1 -1
  128. package/dist/types/src/containers/Deck/Banner.d.ts.map +1 -1
  129. package/dist/types/src/containers/Deck/Deck.d.ts.map +1 -1
  130. package/dist/types/src/containers/Deck/Deck.stories.d.ts +44 -52
  131. package/dist/types/src/containers/Deck/Deck.stories.d.ts.map +1 -1
  132. package/dist/types/src/containers/Deck/DeckContent.d.ts +4 -4
  133. package/dist/types/src/containers/Deck/DeckContent.d.ts.map +1 -1
  134. package/dist/types/src/containers/Deck/DeckRoot.d.ts +5 -8
  135. package/dist/types/src/containers/Deck/DeckRoot.d.ts.map +1 -1
  136. package/dist/types/src/containers/Deck/DeckViewport.d.ts +4 -7
  137. package/dist/types/src/containers/Deck/DeckViewport.d.ts.map +1 -1
  138. package/dist/types/src/containers/Deck/StatusBar.d.ts.map +1 -1
  139. package/dist/types/src/containers/DeckLayout/DeckLayout.d.ts.map +1 -1
  140. package/dist/types/src/containers/DeckLayout/DeckLayout.stories.d.ts +44 -52
  141. package/dist/types/src/containers/DeckLayout/DeckLayout.stories.d.ts.map +1 -1
  142. package/dist/types/src/containers/DeckLayout/Popover.d.ts.map +1 -1
  143. package/dist/types/src/containers/DeckLayout/Toast.d.ts +1 -1
  144. package/dist/types/src/containers/DeckLayout/Toast.d.ts.map +1 -1
  145. package/dist/types/src/containers/DeckLayout/index.d.ts.map +1 -1
  146. package/dist/types/src/containers/Plank/Plank.d.ts +1 -1
  147. package/dist/types/src/containers/Plank/Plank.d.ts.map +1 -1
  148. package/dist/types/src/containers/Plank/Plank.stories.d.ts +44 -52
  149. package/dist/types/src/containers/Plank/Plank.stories.d.ts.map +1 -1
  150. package/dist/types/src/containers/Plank/PlankComponent.d.ts.map +1 -1
  151. package/dist/types/src/containers/Plank/PlankContent.d.ts +1 -1
  152. package/dist/types/src/containers/Plank/PlankError.d.ts +1 -1
  153. package/dist/types/src/containers/Plank/PlankError.d.ts.map +1 -1
  154. package/dist/types/src/containers/Plank/PlankRoot.d.ts +1 -1
  155. package/dist/types/src/containers/Plank/PlankRoot.d.ts.map +1 -1
  156. package/dist/types/src/containers/Sidebar/ComplementarySidebar.d.ts.map +1 -1
  157. package/dist/types/src/containers/Sidebar/Sidebar.d.ts.map +1 -1
  158. package/dist/types/src/containers/Sidebar/SidebarButton.d.ts +1 -1
  159. package/dist/types/src/containers/Sidebar/SidebarButton.d.ts.map +1 -1
  160. package/dist/types/src/hooks/index.d.ts +0 -1
  161. package/dist/types/src/hooks/index.d.ts.map +1 -1
  162. package/dist/types/src/hooks/useBreakpoints.d.ts +1 -1
  163. package/dist/types/src/hooks/useCompanions.d.ts.map +1 -1
  164. package/dist/types/src/hooks/useDeckCompanions.d.ts +1 -1
  165. package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
  166. package/dist/types/src/hooks/useMainSize.d.ts.map +1 -1
  167. package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -1
  168. package/dist/types/src/hooks/useSelectedCompanion.d.ts.map +1 -1
  169. package/dist/types/src/index.d.ts +1 -3
  170. package/dist/types/src/index.d.ts.map +1 -1
  171. package/dist/types/src/layout.d.ts.map +1 -1
  172. package/dist/types/src/meta.d.ts +1 -1
  173. package/dist/types/src/meta.d.ts.map +1 -1
  174. package/dist/types/src/operations/add-toast.d.ts +1 -1
  175. package/dist/types/src/operations/add-toast.d.ts.map +1 -1
  176. package/dist/types/src/operations/adjust.d.ts +3 -3
  177. package/dist/types/src/operations/adjust.d.ts.map +1 -1
  178. package/dist/types/src/operations/close.d.ts +1 -1
  179. package/dist/types/src/operations/close.d.ts.map +1 -1
  180. package/dist/types/src/operations/helpers.d.ts.map +1 -1
  181. package/dist/types/src/operations/index.d.ts +1 -2
  182. package/dist/types/src/operations/index.d.ts.map +1 -1
  183. package/dist/types/src/operations/open.d.ts +1 -1
  184. package/dist/types/src/operations/open.d.ts.map +1 -1
  185. package/dist/types/src/operations/revert-workspace.d.ts +1 -1
  186. package/dist/types/src/operations/revert-workspace.d.ts.map +1 -1
  187. package/dist/types/src/operations/scroll-into-view.d.ts +1 -1
  188. package/dist/types/src/operations/scroll-into-view.d.ts.map +1 -1
  189. package/dist/types/src/operations/set-layout-mode.d.ts +1 -1
  190. package/dist/types/src/operations/set-layout-mode.d.ts.map +1 -1
  191. package/dist/types/src/operations/set.d.ts +1 -1
  192. package/dist/types/src/operations/set.d.ts.map +1 -1
  193. package/dist/types/src/operations/switch-workspace.d.ts +1 -1
  194. package/dist/types/src/operations/switch-workspace.d.ts.map +1 -1
  195. package/dist/types/src/operations/update-companion.d.ts +1 -1
  196. package/dist/types/src/operations/update-companion.d.ts.map +1 -1
  197. package/dist/types/src/operations/update-complementary.d.ts +1 -1
  198. package/dist/types/src/operations/update-complementary.d.ts.map +1 -1
  199. package/dist/types/src/operations/update-dialog.d.ts +1 -1
  200. package/dist/types/src/operations/update-dialog.d.ts.map +1 -1
  201. package/dist/types/src/operations/update-plank-size.d.ts +3 -3
  202. package/dist/types/src/operations/update-plank-size.d.ts.map +1 -1
  203. package/dist/types/src/operations/update-popover.d.ts +1 -1
  204. package/dist/types/src/operations/update-popover.d.ts.map +1 -1
  205. package/dist/types/src/operations/update-sidebar.d.ts +1 -1
  206. package/dist/types/src/operations/update-sidebar.d.ts.map +1 -1
  207. package/dist/types/src/plugin.d.ts +4 -0
  208. package/dist/types/src/plugin.d.ts.map +1 -0
  209. package/dist/types/src/translations.d.ts +44 -53
  210. package/dist/types/src/translations.d.ts.map +1 -1
  211. package/dist/types/src/types/DeckCapabilities.d.ts +188 -0
  212. package/dist/types/src/types/DeckCapabilities.d.ts.map +1 -0
  213. package/dist/types/src/types/DeckEvents.d.ts +5 -0
  214. package/dist/types/src/types/DeckEvents.d.ts.map +1 -0
  215. package/dist/types/src/types/DeckOperation.d.ts +15 -0
  216. package/dist/types/src/types/DeckOperation.d.ts.map +1 -0
  217. package/dist/types/src/types/Settings.d.ts +4 -5
  218. package/dist/types/src/types/Settings.d.ts.map +1 -1
  219. package/dist/types/src/types/index.d.ts +3 -2
  220. package/dist/types/src/types/index.d.ts.map +1 -1
  221. package/dist/types/src/types/schema.d.ts +6 -7
  222. package/dist/types/src/types/schema.d.ts.map +1 -1
  223. package/dist/types/src/util/layoutAppliesTopbar.d.ts.map +1 -1
  224. package/dist/types/src/util/plank-url-params.d.ts.map +1 -1
  225. package/dist/types/src/util/sanitize-persisted-state.d.ts.map +1 -1
  226. package/dist/types/src/util/set-active.d.ts.map +1 -1
  227. package/dist/types/tsconfig.tsbuildinfo +1 -1
  228. package/package.json +109 -73
  229. package/src/DeckPlugin.node.ts +17 -0
  230. package/src/DeckPlugin.test.ts +27 -0
  231. package/src/DeckPlugin.ts +16 -4
  232. package/src/DeckPlugin.workerd.ts +16 -0
  233. package/src/capabilities/app-graph-builder.ts +4 -4
  234. package/src/capabilities/index.ts +2 -1
  235. package/src/capabilities/notification-tracker.ts +132 -0
  236. package/src/capabilities/operation-handler.ts +1 -1
  237. package/src/capabilities/react-root.tsx +20 -15
  238. package/src/capabilities/react-surface.tsx +2 -2
  239. package/src/capabilities/settings.ts +1 -2
  240. package/src/capabilities/tools.ts +1 -1
  241. package/src/capabilities/url-handler.ts +73 -2
  242. package/src/components/DeckSettings/DeckSettings.stories.tsx +2 -2
  243. package/src/components/DeckSettings/DeckSettings.tsx +8 -47
  244. package/src/components/Matrix/Matrix.stories.tsx +2 -2
  245. package/src/components/Matrix/Matrix.tsx +1 -1
  246. package/src/containers/Deck/Banner.tsx +2 -2
  247. package/src/containers/Deck/Deck.stories.tsx +1 -1
  248. package/src/containers/Deck/DeckContent.tsx +2 -5
  249. package/src/containers/Deck/DeckViewport.tsx +7 -13
  250. package/src/containers/DeckLayout/ActiveNode.tsx +1 -1
  251. package/src/containers/DeckLayout/DeckLayout.stories.tsx +8 -10
  252. package/src/containers/DeckLayout/Fallback.tsx +2 -2
  253. package/src/containers/DeckLayout/Popover.tsx +31 -26
  254. package/src/containers/DeckLayout/Toast.tsx +19 -29
  255. package/src/containers/Plank/Plank.stories.tsx +3 -3
  256. package/src/containers/Plank/PlankComponent.tsx +3 -2
  257. package/src/containers/Plank/PlankContent.tsx +1 -1
  258. package/src/containers/Plank/PlankError.tsx +6 -3
  259. package/src/containers/Plank/PlankHeading.tsx +5 -5
  260. package/src/containers/Plank/PlankLoading.tsx +1 -1
  261. package/src/containers/Plank/PlankRoot.tsx +1 -1
  262. package/src/containers/Sidebar/ComplementarySidebar.tsx +20 -39
  263. package/src/containers/Sidebar/Sidebar.tsx +5 -10
  264. package/src/containers/Sidebar/SidebarButton.tsx +7 -1
  265. package/src/hooks/index.ts +0 -1
  266. package/src/hooks/useDeckCompanions.ts +1 -1
  267. package/src/index.ts +1 -3
  268. package/src/meta.ts +24 -6
  269. package/src/operations/add-toast.ts +1 -1
  270. package/src/operations/adjust.ts +4 -5
  271. package/src/operations/close.ts +2 -2
  272. package/src/operations/index.ts +1 -4
  273. package/src/operations/open.ts +29 -13
  274. package/src/operations/revert-workspace.ts +1 -1
  275. package/src/operations/scroll-into-view.ts +1 -1
  276. package/src/operations/set-layout-mode.ts +1 -1
  277. package/src/operations/set.ts +2 -2
  278. package/src/operations/switch-workspace.ts +8 -2
  279. package/src/operations/update-companion.ts +1 -1
  280. package/src/operations/update-complementary.ts +1 -1
  281. package/src/operations/update-dialog.ts +1 -1
  282. package/src/operations/update-plank-size.ts +3 -4
  283. package/src/operations/update-popover.ts +1 -1
  284. package/src/operations/update-sidebar.ts +1 -1
  285. package/src/plugin.ts +11 -0
  286. package/src/translations.ts +4 -12
  287. package/src/types/DeckCapabilities.ts +34 -0
  288. package/src/types/DeckEvents.ts +21 -0
  289. package/src/{operations/definitions.ts → types/DeckOperation.ts} +13 -6
  290. package/src/types/Settings.ts +25 -6
  291. package/src/types/index.ts +4 -2
  292. package/src/types/schema.ts +0 -2
  293. package/src/vite-env.d.ts +5 -0
  294. package/dist/lib/browser/adjust-XWB6ZZ6U.mjs.map +0 -7
  295. package/dist/lib/browser/chunk-5LM6A3EC.mjs +0 -208
  296. package/dist/lib/browser/chunk-5LM6A3EC.mjs.map +0 -7
  297. package/dist/lib/browser/chunk-BRZAVPMC.mjs +0 -48
  298. package/dist/lib/browser/chunk-BRZAVPMC.mjs.map +0 -7
  299. package/dist/lib/browser/chunk-FRVCL5NO.mjs +0 -72
  300. package/dist/lib/browser/chunk-FRVCL5NO.mjs.map +0 -7
  301. package/dist/lib/browser/index.mjs +0 -201
  302. package/dist/lib/browser/index.mjs.map +0 -7
  303. package/dist/lib/browser/meta.json +0 -1
  304. package/dist/lib/browser/open-K2JOEW2E.mjs.map +0 -7
  305. package/dist/lib/browser/operations/index.mjs +0 -13
  306. package/dist/lib/browser/operations/index.mjs.map +0 -7
  307. package/dist/lib/browser/set-layout-mode-BEVNGOY2.mjs.map +0 -7
  308. package/dist/lib/browser/show-undo-5RQNREEB.mjs +0 -59
  309. package/dist/lib/browser/show-undo-5RQNREEB.mjs.map +0 -7
  310. package/dist/lib/browser/switch-workspace-ICJJWNFT.mjs.map +0 -7
  311. package/dist/lib/browser/update-companion-VPCBH3YT.mjs.map +0 -7
  312. package/dist/lib/browser/update-complementary-74DEQY6T.mjs.map +0 -7
  313. package/dist/lib/browser/update-plank-size-5VHZOTHE.mjs +0 -28
  314. package/dist/lib/browser/update-plank-size-5VHZOTHE.mjs.map +0 -7
  315. package/dist/lib/node-esm/add-toast-AZM7NFNM.mjs +0 -25
  316. package/dist/lib/node-esm/add-toast-AZM7NFNM.mjs.map +0 -7
  317. package/dist/lib/node-esm/adjust-ICALXQ6F.mjs +0 -96
  318. package/dist/lib/node-esm/adjust-ICALXQ6F.mjs.map +0 -7
  319. package/dist/lib/node-esm/chunk-A63Q53TW.mjs +0 -73
  320. package/dist/lib/node-esm/chunk-A63Q53TW.mjs.map +0 -7
  321. package/dist/lib/node-esm/chunk-B7WZXRW4.mjs +0 -209
  322. package/dist/lib/node-esm/chunk-B7WZXRW4.mjs.map +0 -7
  323. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  324. package/dist/lib/node-esm/chunk-IRWCUYJY.mjs +0 -71
  325. package/dist/lib/node-esm/chunk-IRWCUYJY.mjs.map +0 -7
  326. package/dist/lib/node-esm/chunk-MB4SDDVY.mjs +0 -50
  327. package/dist/lib/node-esm/chunk-MB4SDDVY.mjs.map +0 -7
  328. package/dist/lib/node-esm/chunk-MLVJ2ODW.mjs +0 -32
  329. package/dist/lib/node-esm/chunk-MLVJ2ODW.mjs.map +0 -7
  330. package/dist/lib/node-esm/close-GC5V3GD5.mjs +0 -45
  331. package/dist/lib/node-esm/close-GC5V3GD5.mjs.map +0 -7
  332. package/dist/lib/node-esm/index.mjs +0 -202
  333. package/dist/lib/node-esm/index.mjs.map +0 -7
  334. package/dist/lib/node-esm/meta.json +0 -1
  335. package/dist/lib/node-esm/open-XXEHIR6G.mjs +0 -151
  336. package/dist/lib/node-esm/open-XXEHIR6G.mjs.map +0 -7
  337. package/dist/lib/node-esm/operations/index.mjs +0 -14
  338. package/dist/lib/node-esm/operations/index.mjs.map +0 -7
  339. package/dist/lib/node-esm/revert-workspace-WCXAL5C6.mjs +0 -22
  340. package/dist/lib/node-esm/revert-workspace-WCXAL5C6.mjs.map +0 -7
  341. package/dist/lib/node-esm/scroll-into-view-2ZNU44ZO.mjs +0 -22
  342. package/dist/lib/node-esm/scroll-into-view-2ZNU44ZO.mjs.map +0 -7
  343. package/dist/lib/node-esm/set-5MO2JCUQ.mjs +0 -38
  344. package/dist/lib/node-esm/set-5MO2JCUQ.mjs.map +0 -7
  345. package/dist/lib/node-esm/set-layout-mode-3RK4HIG7.mjs +0 -91
  346. package/dist/lib/node-esm/set-layout-mode-3RK4HIG7.mjs.map +0 -7
  347. package/dist/lib/node-esm/show-undo-WV7SAYGJ.mjs +0 -60
  348. package/dist/lib/node-esm/show-undo-WV7SAYGJ.mjs.map +0 -7
  349. package/dist/lib/node-esm/switch-workspace-VNM75H66.mjs +0 -69
  350. package/dist/lib/node-esm/switch-workspace-VNM75H66.mjs.map +0 -7
  351. package/dist/lib/node-esm/update-companion-SIB3GWH7.mjs +0 -33
  352. package/dist/lib/node-esm/update-companion-SIB3GWH7.mjs.map +0 -7
  353. package/dist/lib/node-esm/update-complementary-CZTIVIXU.mjs +0 -29
  354. package/dist/lib/node-esm/update-complementary-CZTIVIXU.mjs.map +0 -7
  355. package/dist/lib/node-esm/update-dialog-HEDV5XBB.mjs +0 -30
  356. package/dist/lib/node-esm/update-dialog-HEDV5XBB.mjs.map +0 -7
  357. package/dist/lib/node-esm/update-plank-size-JJLU7VE3.mjs +0 -29
  358. package/dist/lib/node-esm/update-plank-size-JJLU7VE3.mjs.map +0 -7
  359. package/dist/lib/node-esm/update-popover-HI5TU2VT.mjs +0 -34
  360. package/dist/lib/node-esm/update-popover-HI5TU2VT.mjs.map +0 -7
  361. package/dist/lib/node-esm/update-sidebar-QB5BA655.mjs +0 -26
  362. package/dist/lib/node-esm/update-sidebar-QB5BA655.mjs.map +0 -7
  363. package/dist/types/src/hooks/useHoistStatusbar.d.ts +0 -3
  364. package/dist/types/src/hooks/useHoistStatusbar.d.ts.map +0 -1
  365. package/dist/types/src/operations/definitions.d.ts +0 -15
  366. package/dist/types/src/operations/definitions.d.ts.map +0 -1
  367. package/dist/types/src/operations/show-undo.d.ts +0 -5
  368. package/dist/types/src/operations/show-undo.d.ts.map +0 -1
  369. package/dist/types/src/types/capabilities.d.ts +0 -191
  370. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  371. package/dist/types/src/types/events.d.ts +0 -7
  372. package/dist/types/src/types/events.d.ts.map +0 -1
  373. package/src/hooks/useHoistStatusbar.ts +0 -24
  374. package/src/operations/show-undo.ts +0 -47
  375. package/src/types/capabilities.ts +0 -35
  376. package/src/types/events.ts +0 -21
  377. /package/dist/lib/{browser/chunk-J5LGTIGS.mjs.map → neutral/check-app-scheme-A7FZVNZO.mjs.map} +0 -0
  378. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  379. /package/dist/lib/{browser/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  380. /package/dist/lib/{node-esm/types → neutral}/index.mjs.map +0 -0
  381. /package/dist/lib/{node-esm/chunk-HSLMI22Q.mjs.map → neutral/meta.mjs.map} +0 -0
@@ -14,10 +14,10 @@ import {
14
14
  getWorkspaceFromPath,
15
15
  toUrlPath,
16
16
  } from '@dxos/app-toolkit';
17
+ import { Operation } from '@dxos/compute';
17
18
  import { runAndForwardErrors } from '@dxos/effect';
18
19
  import { invariant } from '@dxos/invariant';
19
20
  import { log } from '@dxos/log';
20
- import { Operation } from '@dxos/operation';
21
21
  import { Node } from '@dxos/plugin-graph';
22
22
  import { isTauri } from '@dxos/util';
23
23
 
@@ -131,9 +131,35 @@ export default Capability.makeModule(
131
131
 
132
132
  const onPopState = () => void runAndForwardErrors(provideServices(handleNavigation()));
133
133
 
134
- // Initial navigation.
134
+ // Install before handleNavigation()/state-sync push entries on top of the sentinel.
135
+ const sentinelKey = installLeaveTrap();
136
+
137
+ // Landing on the sentinel means a Back is about to leave Composer; confirm and act on it.
138
+ // The guard stops our own back()/forward() from re-entering.
139
+ let handlingSentinel = false;
140
+ const onCurrentEntryChange = () => {
141
+ const current = window.navigation.currentEntry;
142
+ if (handlingSentinel || !current || current.key !== sentinelKey) {
143
+ return;
144
+ }
145
+ handlingSentinel = true;
146
+ queueMicrotask(() => {
147
+ if (window.confirm('Leave Composer?')) {
148
+ history.back(); // Past the sentinel to the prior page.
149
+ } else {
150
+ history.forward(); // Back to where the user was.
151
+ }
152
+ setTimeout(() => {
153
+ handlingSentinel = false;
154
+ });
155
+ });
156
+ };
157
+
135
158
  yield* provideServices(handleNavigation());
136
159
  window.addEventListener('popstate', onPopState);
160
+ if ('navigation' in window) {
161
+ window.navigation.addEventListener('currententrychange', onCurrentEntryChange);
162
+ }
137
163
 
138
164
  // Tauri deep link support.
139
165
  let unlistenDeepLink: (() => void) | undefined;
@@ -192,6 +218,9 @@ export default Capability.makeModule(
192
218
  return Capability.contributes(Capabilities.Null, null, () =>
193
219
  Effect.sync(() => {
194
220
  window.removeEventListener('popstate', onPopState);
221
+ if ('navigation' in window) {
222
+ window.navigation.removeEventListener('currententrychange', onCurrentEntryChange);
223
+ }
195
224
  unsubscribe();
196
225
  unlistenDeepLink?.();
197
226
  }),
@@ -199,6 +228,48 @@ export default Capability.makeModule(
199
228
  }),
200
229
  );
201
230
 
231
+ /**
232
+ * sessionStorage key holding the sentinel history entry's key. The entry is identified by its
233
+ * (reload-stable) Navigation API key rather than by entry state, because the deck overwrites
234
+ * history state via replaceState during URL sync — which would erase a state marker. sessionStorage
235
+ * survives reloads within the tab and the deck never touches it.
236
+ */
237
+ const SENTINEL_STORAGE_KEY = 'dxos.composer.deck.leaveTrap.sentinelKey';
238
+
239
+ /**
240
+ * Insert a "sentinel" history entry beneath the app's working entries, so a Back-press that would
241
+ * leave Composer instead lands on the sentinel — where `onCurrentEntryChange` confirms the exit. A
242
+ * cross-document back is uncancelable and `beforeunload` cannot distinguish reload from leave, so
243
+ * this same-document floor is required; reload fires no traversal and is never trapped. Requires the
244
+ * Navigation API (Chromium); no-op otherwise. Idempotent across reloads via the sessionStorage-held
245
+ * entry key, so the sentinel is not duplicated. Returns the sentinel entry's key, or undefined.
246
+ */
247
+ const installLeaveTrap = (): string | undefined => {
248
+ if (!('navigation' in window)) {
249
+ return undefined;
250
+ }
251
+ const saved = sessionStorage.getItem(SENTINEL_STORAGE_KEY);
252
+ if (saved && window.navigation.entries().some((entry) => entry.key === saved)) {
253
+ // The sentinel survived (reload, or the user returned to Composer after leaving). If we are
254
+ // sitting ON it — e.g. the user left via the sentinel then came back Forward onto it — push a
255
+ // working entry above so the user is above the floor again and the trap re-arms.
256
+ if (window.navigation.currentEntry?.key === saved) {
257
+ history.pushState(null, '', window.location.pathname + window.location.search);
258
+ }
259
+ return saved;
260
+ }
261
+ // history.length > 1 (not navigation.canGoBack, which is false for a cross-origin prior entry)
262
+ // means there is somewhere to leave to; otherwise Back can't exit and no sentinel is needed.
263
+ const key = window.navigation.currentEntry?.key;
264
+ if (key && window.history.length > 1) {
265
+ // Record the current (landing) entry as the sentinel, then push the working entry above it.
266
+ sessionStorage.setItem(SENTINEL_STORAGE_KEY, key);
267
+ history.pushState(null, '', window.location.pathname + window.location.search);
268
+ return key;
269
+ }
270
+ return undefined;
271
+ };
272
+
202
273
  /** Check if a path is a redirect path handled elsewhere (e.g., OAuth). */
203
274
  const isRedirectPath = (pathname: string): boolean => pathname.startsWith('/redirect/');
204
275
 
@@ -6,7 +6,8 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
 
7
7
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
8
8
 
9
- import { translations } from '../../translations';
9
+ import { translations } from '#translations';
10
+
10
11
  import { DeckSettings } from './DeckSettings';
11
12
 
12
13
  const meta = {
@@ -29,7 +30,6 @@ export const Default: Story = {
29
30
  settings: {
30
31
  enableDeck: true,
31
32
  encapsulatedPlanks: false,
32
- enableStatusbar: true,
33
33
  showHints: true,
34
34
  enableNativeRedirect: false,
35
35
  },
@@ -5,7 +5,7 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { type AppSurface } from '@dxos/app-toolkit/ui';
8
- import { Input, useTranslation } from '@dxos/react-ui';
8
+ import { useTranslation } from '@dxos/react-ui';
9
9
  import { Settings as SettingsForm } from '@dxos/react-ui-form';
10
10
 
11
11
  import { meta } from '#meta';
@@ -21,52 +21,13 @@ export const DeckSettings = ({ settings, onSettingsChange }: DeckSettingsProps)
21
21
  return (
22
22
  <SettingsForm.Viewport>
23
23
  <SettingsForm.Section title={t('settings.title', { ns: meta.id })}>
24
- <SettingsForm.Item title={t('settings.enable-deck.label')} description={t('settings.enable-deck.description')}>
25
- <Input.Switch
26
- disabled={!onSettingsChange}
27
- checked={settings.enableDeck}
28
- onCheckedChange={(checked) => onSettingsChange?.((s) => ({ ...s, enableDeck: checked }))}
29
- />
30
- </SettingsForm.Item>
31
- <SettingsForm.Item
32
- title={t('settings.encapsulated-planks.label')}
33
- description={t('settings.encapsulated-planks.description')}
34
- >
35
- <Input.Switch
36
- disabled={!onSettingsChange}
37
- checked={settings.encapsulatedPlanks ?? false}
38
- onCheckedChange={(checked) => onSettingsChange?.((s) => ({ ...s, encapsulatedPlanks: checked }))}
39
- />
40
- </SettingsForm.Item>
41
- <SettingsForm.Item
42
- title={t('settings.enable-statusbar.label')}
43
- description={t('settings.enable-statusbar.description')}
44
- >
45
- <Input.Switch
46
- disabled={!onSettingsChange}
47
- checked={settings.enableStatusbar}
48
- onCheckedChange={(checked) => onSettingsChange?.((s) => ({ ...s, enableStatusbar: checked }))}
49
- />
50
- </SettingsForm.Item>
51
- <SettingsForm.Item title={t('settings.show-hints.label')} description={t('settings.show-hints.description')}>
52
- <Input.Switch
53
- disabled={!onSettingsChange}
54
- checked={settings.showHints}
55
- onCheckedChange={(checked) => onSettingsChange?.((s) => ({ ...s, showHints: checked }))}
56
- />
57
- </SettingsForm.Item>
58
- {!isSocket && (
59
- <SettingsForm.Item
60
- title={t('settings.native-redirect.label')}
61
- description={t('settings.native-redirect.description')}
62
- >
63
- <Input.Switch
64
- disabled={!onSettingsChange}
65
- checked={settings.enableNativeRedirect}
66
- onCheckedChange={(checked) => onSettingsChange?.((s) => ({ ...s, enableNativeRedirect: checked }))}
67
- />
68
- </SettingsForm.Item>
69
- )}
24
+ <SettingsForm.FieldSet
25
+ readonly={!onSettingsChange}
26
+ schema={Settings.Settings}
27
+ visible={(path) => path !== 'enableNativeRedirect' || !isSocket}
28
+ values={settings}
29
+ onValuesChanged={(values) => onSettingsChange?.(() => values)}
30
+ />
70
31
  </SettingsForm.Section>
71
32
  </SettingsForm.Viewport>
72
33
  );
@@ -25,9 +25,9 @@ import { Organization, Person } from '@dxos/types';
25
25
 
26
26
  import { DeckState, OperationHandler } from '#capabilities';
27
27
  import { meta as pluginMeta } from '#meta';
28
+ import { translations } from '#translations';
28
29
 
29
30
  import { Plank } from '../../containers/Plank';
30
- import { translations } from '../../translations';
31
31
  import { Matrix, type MatrixController, type MatrixRootProps } from './Matrix';
32
32
 
33
33
  random.seed(123);
@@ -103,7 +103,7 @@ const PlankTile = (props: MosaicTileProps<Obj.Any>) => {
103
103
  const TestExtension = Capability.contributes(
104
104
  Capabilities.ReactSurface,
105
105
  Surface.create({
106
- id: 'story-article',
106
+ id: 'storyArticle',
107
107
  role: 'article',
108
108
  component: ({ data: { subject } }) => {
109
109
  if (!subject) {
@@ -8,9 +8,9 @@ import React, { forwardRef, type PropsWithChildren, useCallback, useEffect, useI
8
8
 
9
9
  import { Obj } from '@dxos/echo';
10
10
  import { ScrollArea } from '@dxos/react-ui';
11
+ import { composable, composableProps } from '@dxos/react-ui';
11
12
  import { useAttended } from '@dxos/react-ui-attention';
12
13
  import { type MosaicStackTileComponent, Mosaic } from '@dxos/react-ui-mosaic';
13
- import { composable, composableProps } from '@dxos/ui-theme';
14
14
  import { type ComposableProps } from '@dxos/ui-types';
15
15
 
16
16
  //
@@ -27,8 +27,8 @@ export const Banner = ({ variant, classNames }: ThemedClassName<{ variant?: 'top
27
27
  {variant === 'sidebar' ? <CloseSidebarButton /> : <ToggleSidebarButton />}
28
28
  <span className='self-center grow ms-1'>{t('current-app.name', { ns: osTranslations })}</span>
29
29
  {variant === 'topbar' && (
30
- <div role='none' className='absolute inset-0 pointer-events-none'>
31
- <div role='none' className='grid h-full pointer-fine:p-1 max-w-md mx-auto pointer-events-auto'>
30
+ <div className='absolute inset-0 pointer-events-none'>
31
+ <div className='grid h-full pointer-fine:p-1 max-w-md mx-auto pointer-events-auto'>
32
32
  <Surface.Surface role='search-input' limit={1} />
33
33
  </div>
34
34
  </div>
@@ -14,9 +14,9 @@ import { corePlugins } from '@dxos/plugin-testing';
14
14
  import { DeckSettings, DeckState } from '#capabilities';
15
15
  import { useDeckState } from '#hooks';
16
16
  import { meta as pluginMeta } from '#meta';
17
+ import { translations } from '#translations';
17
18
  import { DeckCapabilities, getMode } from '#types';
18
19
 
19
- import { translations } from '../../translations';
20
20
  import { Deck } from './Deck';
21
21
 
22
22
  const TestPlugin = Plugin.define(pluginMeta).pipe(
@@ -4,16 +4,15 @@
4
4
 
5
5
  import React, { type PropsWithChildren, useCallback, useEffect, useRef } from 'react';
6
6
 
7
- import { AttentionCapabilities } from '@dxos/plugin-attention/types';
7
+ import { AttentionCapabilities } from '@dxos/plugin-attention';
8
8
  import { Main, useMediaQuery } from '@dxos/react-ui';
9
9
 
10
- import { useBreakpoints, useHoistStatusbar } from '#hooks';
10
+ import { useBreakpoints } from '#hooks';
11
11
 
12
12
  import { layoutAppliesTopbar } from '../../util';
13
13
  import { ComplementarySidebar, Sidebar } from '../Sidebar';
14
14
  import { Banner } from './Banner';
15
15
  import { useDeckContext } from './DeckRoot';
16
- import { StatusBar } from './StatusBar';
17
16
 
18
17
  const DECK_CONTENT_NAME = 'DeckContent';
19
18
 
@@ -31,7 +30,6 @@ export const DeckContent = ({ children }: DeckContentProps) => {
31
30
  } = useDeckContext(DECK_CONTENT_NAME);
32
31
  const breakpoint = useBreakpoints();
33
32
  const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
34
- const hoistStatusbar = useHoistStatusbar(breakpoint, layoutMode);
35
33
 
36
34
  // Ensure the first plank is attended when the deck is first rendered.
37
35
  useEffect(() => {
@@ -97,7 +95,6 @@ export const DeckContent = ({ children }: DeckContentProps) => {
97
95
  <Main.Overlay />
98
96
  {children}
99
97
  {topbar && <Banner variant='topbar' />}
100
- {hoistStatusbar && <StatusBar showHints={settings?.showHints} />}
101
98
  </Main.Root>
102
99
  );
103
100
  };
@@ -20,12 +20,13 @@ import { addEventListener } from '@dxos/async';
20
20
  import { invariant } from '@dxos/invariant';
21
21
  import { useNode } from '@dxos/plugin-graph';
22
22
  import { IconButton, Main, type MainContentProps, useOnTransition, useTranslation } from '@dxos/react-ui';
23
+ import { mainPaddingTransitions } from '@dxos/react-ui';
23
24
  import { DEFAULT_HORIZONTAL_SIZE, Stack, StackContext } from '@dxos/react-ui-stack';
24
- import { hoverableControls, hoverableFocusedWithinControls, mainPaddingTransitions, mx } from '@dxos/ui-theme';
25
+ import { hoverableControls, hoverableFocusedWithinControls, mx } from '@dxos/ui-theme';
25
26
 
26
- import { useBreakpoints, useCompanions, useDeckState, useHoistStatusbar, useSelectedCompanion } from '#hooks';
27
+ import { useBreakpoints, useCompanions, useDeckState, useSelectedCompanion } from '#hooks';
27
28
  import { meta } from '#meta';
28
- import { DeckOperation } from '#operations';
29
+ import { DeckOperation } from '#types';
29
30
  import { getMode } from '#types';
30
31
 
31
32
  import { layoutAppliesTopbar } from '../../util';
@@ -57,7 +58,6 @@ export const DeckViewport = ({ children }: DeckViewportProps) => {
57
58
 
58
59
  const breakpoint = useBreakpoints();
59
60
  const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
60
- const hoistStatusbar = useHoistStatusbar(breakpoint, layoutMode);
61
61
 
62
62
  return (
63
63
  <Main.Content
@@ -66,7 +66,6 @@ export const DeckViewport = ({ children }: DeckViewportProps) => {
66
66
  classNames={[
67
67
  'grid top-[env(safe-area-inset-top)]!',
68
68
  topbar && 'top-[calc(env(safe-area-inset-top)+var(--dx-rail-size))]!',
69
- hoistStatusbar && 'lg:bottom-(--dx-statusbar-size)',
70
69
  ]}
71
70
  style={
72
71
  {
@@ -105,11 +104,7 @@ export const DeckContentEmpty = () => {
105
104
  const layoutMode = getMode(deck);
106
105
  const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
107
106
  return (
108
- <div
109
- role='none'
110
- className='grid place-items-center p-8 relative bg-deck-surface'
111
- data-testid='layoutPlugin.firstRunMessage'
112
- >
107
+ <div className='grid place-items-center p-8 relative bg-deck-surface' data-testid='layoutPlugin.firstRunMessage'>
113
108
  <Surface.Surface role='keyshortcuts' />
114
109
  {!topbar && <ToggleSidebarButton />}
115
110
  </div>
@@ -149,7 +144,7 @@ export const DeckSoloMode = () => {
149
144
  }, [fullscreen, onLayoutChange]);
150
145
 
151
146
  return (
152
- <div role='none' className='relative overflow-hidden bg-deck-surface'>
147
+ <div className='relative overflow-hidden bg-deck-surface'>
153
148
  <DeckSidebarToggles topbar={topbar} fullscreen={fullscreen} />
154
149
  {fullscreen && <ExitFullscreenButton onExit={() => onLayoutChange({ mode: 'solo--fullscreen' })} />}
155
150
  <StackContext.Provider
@@ -233,7 +228,7 @@ export const DeckMultiMode = () => {
233
228
  }, [active, lastPlankCompanions.length]);
234
229
 
235
230
  return (
236
- <div role='none' className='relative bg-deck-surface overflow-hidden'>
231
+ <div className='relative bg-deck-surface overflow-hidden'>
237
232
  <DeckSidebarToggles topbar={topbar} fullscreen={fullscreen} />
238
233
  <Stack
239
234
  classNames={[
@@ -281,7 +276,6 @@ const ExitFullscreenButton = ({ onExit }: { onExit: () => void }) => {
281
276
  const { t } = useTranslation(meta.id);
282
277
  return (
283
278
  <div
284
- role='none'
285
279
  className={mx(
286
280
  'fixed top-2 right-2 z-[1]',
287
281
  hoverableControls,
@@ -19,7 +19,7 @@ export const ActiveNode = () => {
19
19
  useNodeActionExpander(activeNode);
20
20
 
21
21
  return (
22
- <div role='none' className='sr-only'>
22
+ <div className='sr-only'>
23
23
  {/* TODO(wittjosiah): Weird that this is a surface, feel like it's not really render logic.
24
24
  Probably this lives in React-land currently in order to access translations? */}
25
25
  <Surface.Surface
@@ -24,6 +24,7 @@ import { Loading, withLayout } from '@dxos/react-ui/testing';
24
24
 
25
25
  import { OperationHandler } from '#capabilities';
26
26
  import { meta as pluginMeta } from '#meta';
27
+ import { translations } from '#translations';
27
28
  import {
28
29
  DeckCapabilities,
29
30
  type EphemeralDeckState,
@@ -34,7 +35,6 @@ import {
34
35
  PLANK_COMPANION_TYPE,
35
36
  } from '#types';
36
37
 
37
- import { translations } from '../../translations';
38
38
  import { DeckLayout } from './DeckLayout';
39
39
 
40
40
  random.seed(1234);
@@ -48,7 +48,6 @@ const storyDeckSettings = Capability.makeModule(() =>
48
48
  const settingsAtom = Atom.make<Settings.Settings>({
49
49
  showHints: false,
50
50
  enableDeck: true,
51
- enableStatusbar: false,
52
51
  enableNativeRedirect: false,
53
52
  encapsulatedPlanks: false,
54
53
  }).pipe(Atom.keepAlive);
@@ -167,13 +166,13 @@ const TestPlugin = Plugin.define(pluginMeta).pipe(
167
166
  Effect.succeed(
168
167
  Capability.contributes(Capabilities.ReactSurface, [
169
168
  Surface.create({
170
- id: 'story-navigation',
169
+ id: 'storyNavigation',
171
170
  role: 'navigation',
172
171
  filter: (data): data is { current: string } => typeof (data as any).current === 'string',
173
172
  component: ({ data, ref }) => <NavContainer current={data.current} ref={ref} />,
174
173
  }),
175
174
  Surface.create({
176
- id: 'story-article',
175
+ id: 'storyArticle',
177
176
  role: 'article',
178
177
  filter: (data): data is Record<string, unknown> =>
179
178
  typeof data === 'object' && data !== null && (data as { companionTo?: unknown }).companionTo == null,
@@ -202,7 +201,7 @@ const TestPlugin = Plugin.define(pluginMeta).pipe(
202
201
  },
203
202
  }),
204
203
  Surface.create({
205
- id: 'story-article-companion',
204
+ id: 'storyArticleCompanion',
206
205
  role: 'article',
207
206
  filter: (data): data is AppSurface.ArticleData<unknown, {}, unknown> =>
208
207
  typeof data === 'object' && data !== null && (data as { companionTo?: unknown }).companionTo != null,
@@ -235,12 +234,12 @@ const TestPlugin = Plugin.define(pluginMeta).pipe(
235
234
  activate: Effect.fnUntraced(function* () {
236
235
  const extensions = yield* Effect.all([
237
236
  GraphBuilder.createExtension({
238
- id: 'story-items',
237
+ id: 'storyItems',
239
238
  match: NodeMatcher.whenRoot,
240
239
  connector: () => Effect.succeed(STORY_ITEMS.map((item, index) => toStoryItemNode(item, index, 0))),
241
240
  }),
242
241
  GraphBuilder.createExtension({
243
- id: 'story-item-companions',
242
+ id: 'storyItemCompanions',
244
243
  match: NodeMatcher.whenNodeType('story-item'),
245
244
  connector: (node) =>
246
245
  Effect.succeed([
@@ -249,14 +248,13 @@ const TestPlugin = Plugin.define(pluginMeta).pipe(
249
248
  label: 'Companion Alpha',
250
249
  icon: 'ph--sidebar--regular',
251
250
  data: { variant: 'alpha', parentId: node.id },
252
- position: 'hoist',
251
+ position: 'first',
253
252
  }),
254
253
  AppNode.makeCompanion({
255
254
  id: linkedSegment('beta'),
256
255
  label: 'Companion Beta',
257
256
  icon: 'ph--chat-circle--regular',
258
257
  data: { variant: 'beta', parentId: node.id },
259
- position: 'static',
260
258
  }),
261
259
  ]),
262
260
  }),
@@ -285,7 +283,7 @@ const NavContainer = forwardRef<HTMLDivElement, NavContainerProps>((_props, forw
285
283
  {items.map((node) => (
286
284
  <ListItem.Root
287
285
  key={node.id}
288
- classNames={activeSet.has(node.id) ? 'bg-active-surface' : undefined}
286
+ classNames={activeSet.has(node.id) ? 'bg-current-surface' : undefined}
289
287
  onClick={() => void invokePromise(LayoutOperation.Set, { subject: [node.id] })}
290
288
  >
291
289
  {node.properties.icon && (
@@ -12,10 +12,10 @@ const Fallback = () => {
12
12
  const { t } = useTranslation(meta.id);
13
13
 
14
14
  return (
15
- <div role='none' className='min-h-screen w-full flex items-center justify-center p-8'>
15
+ <div className='min-h-screen w-full flex items-center justify-center p-8'>
16
16
  <p
17
17
  role='alert'
18
- className='flex items-center justify-center p-8 font-normal text-lg text-error-text border border-rose-fill rounded-md'
18
+ className='flex items-center justify-center p-8 font-normal text-lg text-error-text border border-rose-bg rounded-md'
19
19
  >
20
20
  {t('plugin-error.message')}
21
21
  </p>
@@ -3,13 +3,11 @@
3
3
  //
4
4
 
5
5
  import { createContext } from '@radix-ui/react-context';
6
- import * as Function from 'effect/Function';
7
- import * as Option from 'effect/Option';
8
6
  import React, { type PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react';
9
7
 
10
8
  import { Surface } from '@dxos/app-framework/ui';
11
9
  import { AppSurface, useObjectMenuItems } from '@dxos/app-toolkit/ui';
12
- import { Annotation, Obj } from '@dxos/echo';
10
+ import { Obj } from '@dxos/echo';
13
11
  import {
14
12
  Card,
15
13
  Popover,
@@ -75,15 +73,10 @@ export const PopoverContent = () => {
75
73
  const isObjectPopover = Obj.isObject(popoverSubject);
76
74
  const objectMenuItems = useObjectMenuItems(popoverSubject);
77
75
  const title = state.popoverTitle ? toLocalizedString(state.popoverTitle, t) : 'Unknown';
78
- const icon = isObjectPopover
79
- ? Function.pipe(
80
- Obj.getSchema(popoverSubject),
81
- Option.fromNullable,
82
- Option.flatMap(Annotation.IconAnnotation.get),
83
- Option.map(({ icon }) => icon),
84
- Option.getOrElse(() => 'ph--placeholder--regular'),
85
- )
86
- : undefined;
76
+ const icon = isObjectPopover ? (Obj.getIcon(popoverSubject)?.icon ?? 'ph--circle-dashed--regular') : undefined;
77
+ const content = state.popoverContent;
78
+ // A base popover renders a plugin-provided component; everything else falls through to the card.
79
+ const isBasePopover = state.popoverKind === 'base' && !!content && 'component' in content;
87
80
 
88
81
  const handleClose = useCallback(() => {
89
82
  setOpen(false);
@@ -117,27 +110,33 @@ export const PopoverContent = () => {
117
110
  side={state.popoverSide}
118
111
  sticky='always'
119
112
  hideWhenDetached
113
+ onOpenAutoFocus={(event) => event.preventDefault()}
120
114
  onInteractOutside={handleInteractOutside}
121
115
  onEscapeKeyDown={handleInteractOutside}
122
116
  >
123
117
  <Popover.Viewport>
124
- {/* Base popover */}
125
- {state.popoverKind === 'base' && state.popoverContent && 'component' in state.popoverContent && (
126
- <Surface.Surface type={AppSurface.Popover} data={state.popoverContent} limit={1} />
127
- )}
128
-
129
- {/* Card popover */}
130
- {state.popoverKind === 'card' && (
118
+ {isBasePopover && content && 'component' in content ? (
119
+ /* Base popover: a plugin-provided component (e.g. editor link preview). */
120
+ <Surface.Surface type={AppSurface.Popover} data={content} limit={1} />
121
+ ) : (
122
+ /*
123
+ * Card popover (default). Rendered for any open popover that isn't an explicit
124
+ * base-component popover so the popover can never collapse to a bare 1px frame: the
125
+ * header (icon + title + menu) always renders, and the body falls back to a fixed-
126
+ * height "no preview" row when no subject resolves a card Surface (e.g. system-type
127
+ * objects like a raw Feed that have no registered card and no renderable fields).
128
+ */
131
129
  <Menu.Root>
132
130
  <Card.Root border={false} classNames='dx-card-popover'>
133
- <Card.Toolbar>
134
- <Card.IconBlock padding>{icon && <Card.Icon icon={icon} />}</Card.IconBlock>
131
+ <Card.Header>
132
+ <Card.IconBlock>{icon && <Card.Icon icon={icon} />}</Card.IconBlock>
135
133
  <Card.Title>{title}</Card.Title>
136
134
  {/* TODO(wittjosiah): Reconcile with Card.Menu. */}
137
- <Card.IconBlock padding>
135
+ <Card.IconBlock>
138
136
  <Menu.Trigger asChild disabled={!objectMenuItems.length}>
139
137
  <Toolbar.IconButton
140
138
  variant='ghost'
139
+ density='sm'
141
140
  icon='ph--dots-three-vertical--regular'
142
141
  iconOnly
143
142
  label='Actions'
@@ -145,10 +144,16 @@ export const PopoverContent = () => {
145
144
  </Menu.Trigger>
146
145
  <Menu.Content items={objectMenuItems} />
147
146
  </Card.IconBlock>
148
- </Card.Toolbar>
149
-
150
- {state.popoverContent && 'subject' in state.popoverContent && (
151
- <Surface.Surface type={AppSurface.Card} data={state.popoverContent} limit={1} />
147
+ </Card.Header>
148
+
149
+ {content && 'subject' in content ? (
150
+ <Surface.Surface type={AppSurface.Card} data={content} limit={1} />
151
+ ) : (
152
+ <Card.Body classNames='min-bs-8'>
153
+ <Card.Row>
154
+ <Card.Text variant='description'>{t('popover-no-preview.message')}</Card.Text>
155
+ </Card.Row>
156
+ </Card.Body>
152
157
  )}
153
158
  </Card.Root>
154
159
  </Menu.Root>
@@ -2,17 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React from 'react';
5
+ import React, { useState } from 'react';
6
6
 
7
7
  import { type LayoutOperation } from '@dxos/app-toolkit';
8
- import {
9
- Button,
10
- Icon,
11
- Toast as NaturalToast,
12
- type ToastRootProps,
13
- toLocalizedString,
14
- useTranslation,
15
- } from '@dxos/react-ui';
8
+ import { Button, Toast as NaturalToast, type ToastRootProps, toLocalizedString, useTranslation } from '@dxos/react-ui';
16
9
 
17
10
  import { meta } from '#meta';
18
11
 
@@ -25,37 +18,34 @@ export const Toast = ({
25
18
  duration,
26
19
  actionLabel,
27
20
  actionAlt,
28
- closeLabel,
29
21
  onAction,
30
22
  onOpenChange,
31
23
  }: LayoutOperation.Toast & Pick<ToastRootProps, 'onOpenChange'>) => {
32
24
  const { t } = useTranslation(meta.id);
33
25
 
26
+ // Control the open state so closing flips Radix's `open` (playing the exit animation) rather than
27
+ // unmounting abruptly. Both the close button and Radix's own timeout/swipe route through here.
28
+ const [open, setOpen] = useState(true);
29
+ const handleOpenChange = (next: boolean) => {
30
+ setOpen(next);
31
+ onOpenChange?.(next);
32
+ };
33
+
34
34
  return (
35
- <NaturalToast.Root data-testid={id} defaultOpen duration={duration} onOpenChange={onOpenChange}>
36
- <NaturalToast.Body>
37
- <NaturalToast.Title classNames='items-center'>
38
- {icon && <Icon icon={icon} classNames='inline mr-1' />}
39
- {title && <span>{toLocalizedString(title, t)}</span>}
40
- </NaturalToast.Title>
41
- {description && (
42
- <NaturalToast.Description>{description && toLocalizedString(description, t)}</NaturalToast.Description>
43
- )}
44
- </NaturalToast.Body>
45
- <NaturalToast.Actions>
46
- {onAction && actionAlt && actionLabel && (
35
+ <NaturalToast.Root data-testid={id} open={open} duration={duration} onOpenChange={handleOpenChange}>
36
+ <NaturalToast.Title icon={icon} onClose={() => handleOpenChange(false)}>
37
+ {title && <span>{toLocalizedString(title, t)}</span>}
38
+ </NaturalToast.Title>
39
+ {description && <NaturalToast.Description>{toLocalizedString(description, t)}</NaturalToast.Description>}
40
+ {onAction && actionAlt && actionLabel && (
41
+ <NaturalToast.Actions>
47
42
  <NaturalToast.Action altText={toLocalizedString(actionAlt, t)} asChild>
48
43
  <Button data-testid='toast.action' variant='primary' onClick={() => onAction?.()}>
49
44
  {toLocalizedString(actionLabel, t)}
50
45
  </Button>
51
46
  </NaturalToast.Action>
52
- )}
53
- {closeLabel && (
54
- <NaturalToast.Close asChild>
55
- <Button data-testid='toast.close'>{toLocalizedString(closeLabel, t)}</Button>
56
- </NaturalToast.Close>
57
- )}
58
- </NaturalToast.Actions>
47
+ </NaturalToast.Actions>
48
+ )}
59
49
  </NaturalToast.Root>
60
50
  );
61
51
  };