@dxos/plugin-deck 0.8.4-main.3c1ae3b → 0.8.4-main.3eb6e50203

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 (277) hide show
  1. package/dist/lib/browser/app-graph-builder-X7LCO5KE.mjs +121 -0
  2. package/dist/lib/browser/app-graph-builder-X7LCO5KE.mjs.map +7 -0
  3. package/dist/lib/browser/check-app-scheme-PGISDJX7.mjs +32 -0
  4. package/dist/lib/browser/check-app-scheme-PGISDJX7.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-F3VCCHVL.mjs → chunk-DONG2FYU.mjs} +152 -19
  6. package/dist/lib/browser/chunk-DONG2FYU.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-JGC4ZLG3.mjs +1469 -0
  8. package/dist/lib/browser/chunk-JGC4ZLG3.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-CNTGBCMK.mjs → chunk-NHABISX2.mjs} +40 -33
  10. package/dist/lib/browser/chunk-NHABISX2.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-YT3AJVUU.mjs +161 -0
  12. package/dist/lib/browser/chunk-YT3AJVUU.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +81 -73
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/operation-resolver-XJFR3PNQ.mjs +597 -0
  17. package/dist/lib/browser/operation-resolver-XJFR3PNQ.mjs.map +7 -0
  18. package/dist/lib/browser/react-root-AJFHKHRL.mjs +47 -0
  19. package/dist/lib/browser/react-root-AJFHKHRL.mjs.map +7 -0
  20. package/dist/lib/browser/react-surface-KBRBGEXY.mjs +43 -0
  21. package/dist/lib/browser/react-surface-KBRBGEXY.mjs.map +7 -0
  22. package/dist/lib/browser/settings-ES42FGLG.mjs +38 -0
  23. package/dist/lib/browser/settings-ES42FGLG.mjs.map +7 -0
  24. package/dist/lib/browser/state-YMI6IDEL.mjs +104 -0
  25. package/dist/lib/browser/state-YMI6IDEL.mjs.map +7 -0
  26. package/dist/lib/browser/{toolkit-L5CFXJCF.mjs → toolkit-VRD54KY3.mjs} +17 -15
  27. package/dist/lib/browser/toolkit-VRD54KY3.mjs.map +7 -0
  28. package/dist/lib/browser/types/index.mjs +11 -4
  29. package/dist/lib/browser/url-handler-37UPOB3U.mjs +94 -0
  30. package/dist/lib/browser/url-handler-37UPOB3U.mjs.map +7 -0
  31. package/dist/lib/node-esm/app-graph-builder-US54I64T.mjs +122 -0
  32. package/dist/lib/node-esm/app-graph-builder-US54I64T.mjs.map +7 -0
  33. package/dist/lib/node-esm/check-app-scheme-CK6EVG5D.mjs +33 -0
  34. package/dist/lib/node-esm/check-app-scheme-CK6EVG5D.mjs.map +7 -0
  35. package/dist/lib/node-esm/chunk-7NPS347C.mjs +1470 -0
  36. package/dist/lib/node-esm/chunk-7NPS347C.mjs.map +7 -0
  37. package/dist/lib/node-esm/chunk-ADPMWKLL.mjs +154 -0
  38. package/dist/lib/node-esm/chunk-ADPMWKLL.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-CVYHPJIN.mjs +297 -0
  40. package/dist/lib/node-esm/chunk-CVYHPJIN.mjs.map +7 -0
  41. package/dist/lib/node-esm/chunk-ZMJPCZ3V.mjs +162 -0
  42. package/dist/lib/node-esm/chunk-ZMJPCZ3V.mjs.map +7 -0
  43. package/dist/lib/node-esm/index.mjs +183 -0
  44. package/dist/lib/node-esm/index.mjs.map +7 -0
  45. package/dist/lib/node-esm/meta.json +1 -0
  46. package/dist/lib/node-esm/operation-resolver-ZQGNATPX.mjs +598 -0
  47. package/dist/lib/node-esm/operation-resolver-ZQGNATPX.mjs.map +7 -0
  48. package/dist/lib/node-esm/react-root-2S77ABBS.mjs +48 -0
  49. package/dist/lib/node-esm/react-root-2S77ABBS.mjs.map +7 -0
  50. package/dist/lib/node-esm/react-surface-FIHMAFXH.mjs +44 -0
  51. package/dist/lib/node-esm/react-surface-FIHMAFXH.mjs.map +7 -0
  52. package/dist/lib/node-esm/settings-E3TH3FAW.mjs +39 -0
  53. package/dist/lib/node-esm/settings-E3TH3FAW.mjs.map +7 -0
  54. package/dist/lib/node-esm/state-WQEFBQMD.mjs +105 -0
  55. package/dist/lib/node-esm/state-WQEFBQMD.mjs.map +7 -0
  56. package/dist/lib/node-esm/toolkit-ME546G5T.mjs +55 -0
  57. package/dist/lib/node-esm/toolkit-ME546G5T.mjs.map +7 -0
  58. package/dist/lib/node-esm/types/index.mjs +40 -0
  59. package/dist/lib/node-esm/url-handler-2KYHXINK.mjs +95 -0
  60. package/dist/lib/node-esm/url-handler-2KYHXINK.mjs.map +7 -0
  61. package/dist/types/src/DeckPlugin.d.ts +2 -1
  62. package/dist/types/src/DeckPlugin.d.ts.map +1 -1
  63. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  64. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  65. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  66. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  67. package/dist/types/src/capabilities/check-app-scheme/check-app-scheme.d.ts +5 -0
  68. package/dist/types/src/capabilities/check-app-scheme/check-app-scheme.d.ts.map +1 -0
  69. package/dist/types/src/capabilities/check-app-scheme/index.d.ts +3 -0
  70. package/dist/types/src/capabilities/check-app-scheme/index.d.ts.map +1 -0
  71. package/dist/types/src/capabilities/index.d.ts +8 -13
  72. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  73. package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
  74. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
  75. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
  76. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/react-root/index.d.ts +6 -0
  78. package/dist/types/src/capabilities/react-root/index.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/react-root/react-root.d.ts +9 -0
  80. package/dist/types/src/capabilities/react-root/react-root.d.ts.map +1 -0
  81. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  82. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  83. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  84. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  85. package/dist/types/src/capabilities/settings/index.d.ts +19 -0
  86. package/dist/types/src/capabilities/settings/index.d.ts.map +1 -0
  87. package/dist/types/src/capabilities/settings/settings.d.ts +22 -0
  88. package/dist/types/src/capabilities/settings/settings.d.ts.map +1 -0
  89. package/dist/types/src/capabilities/state/index.d.ts +174 -0
  90. package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
  91. package/dist/types/src/capabilities/state/state.d.ts +177 -0
  92. package/dist/types/src/capabilities/state/state.d.ts.map +1 -0
  93. package/dist/types/src/capabilities/toolkit/index.d.ts +3 -0
  94. package/dist/types/src/capabilities/toolkit/index.d.ts.map +1 -0
  95. package/dist/types/src/capabilities/{toolkit.d.ts → toolkit/toolkit.d.ts} +5 -3
  96. package/dist/types/src/capabilities/toolkit/toolkit.d.ts.map +1 -0
  97. package/dist/types/src/capabilities/tools/index.d.ts +3 -0
  98. package/dist/types/src/capabilities/tools/index.d.ts.map +1 -0
  99. package/dist/types/src/capabilities/tools/tools.d.ts +12 -0
  100. package/dist/types/src/capabilities/tools/tools.d.ts.map +1 -0
  101. package/dist/types/src/capabilities/url-handler/index.d.ts +3 -0
  102. package/dist/types/src/capabilities/url-handler/index.d.ts.map +1 -0
  103. package/dist/types/src/capabilities/url-handler/url-handler.d.ts +5 -0
  104. package/dist/types/src/capabilities/url-handler/url-handler.d.ts.map +1 -0
  105. package/dist/types/src/components/DeckLayout/ActiveNode.d.ts.map +1 -1
  106. package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts.map +1 -1
  107. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  108. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts +1 -0
  109. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts.map +1 -1
  110. package/dist/types/src/components/DeckLayout/DeckMain.d.ts.map +1 -1
  111. package/dist/types/src/components/DeckLayout/Dialog.d.ts.map +1 -1
  112. package/dist/types/src/components/DeckLayout/Popover.d.ts.map +1 -1
  113. package/dist/types/src/components/DeckLayout/Toast.d.ts +3 -3
  114. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
  115. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts +4 -2
  116. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -1
  117. package/dist/types/src/components/Plank/Plank.d.ts +3 -3
  118. package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
  119. package/dist/types/src/components/Plank/Plank.stories.d.ts +23 -4
  120. package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/Plank/PlankControls.d.ts +1 -1
  122. package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -1
  123. package/dist/types/src/components/Plank/PlankError.d.ts +1 -1
  124. package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -1
  125. package/dist/types/src/components/Plank/PlankHeading.d.ts +2 -2
  126. package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
  127. package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
  128. package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -1
  129. package/dist/types/src/components/Sidebar/SidebarButton.d.ts.map +1 -1
  130. package/dist/types/src/hooks/index.d.ts +1 -0
  131. package/dist/types/src/hooks/index.d.ts.map +1 -1
  132. package/dist/types/src/hooks/useDeckCompanions.d.ts +3 -3
  133. package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
  134. package/dist/types/src/hooks/useDeckState.d.ts +17 -0
  135. package/dist/types/src/hooks/useDeckState.d.ts.map +1 -0
  136. package/dist/types/src/hooks/useHoistStatusbar.d.ts +1 -1
  137. package/dist/types/src/hooks/useHoistStatusbar.d.ts.map +1 -1
  138. package/dist/types/src/hooks/useNodeActionExpander.d.ts +1 -1
  139. package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -1
  140. package/dist/types/src/index.d.ts +1 -2
  141. package/dist/types/src/index.d.ts.map +1 -1
  142. package/dist/types/src/meta.d.ts +2 -2
  143. package/dist/types/src/meta.d.ts.map +1 -1
  144. package/dist/types/src/translations.d.ts +1 -0
  145. package/dist/types/src/translations.d.ts.map +1 -1
  146. package/dist/types/src/{capabilities → types}/capabilities.d.ts +98 -90
  147. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  148. package/dist/types/src/types/events.d.ts +7 -0
  149. package/dist/types/src/types/events.d.ts.map +1 -0
  150. package/dist/types/src/types/index.d.ts +2 -0
  151. package/dist/types/src/types/index.d.ts.map +1 -1
  152. package/dist/types/src/types/schema.d.ts +88 -27
  153. package/dist/types/src/types/schema.d.ts.map +1 -1
  154. package/dist/types/src/util/set-active.d.ts +18 -3
  155. package/dist/types/src/util/set-active.d.ts.map +1 -1
  156. package/dist/types/tsconfig.tsbuildinfo +1 -1
  157. package/package.json +54 -47
  158. package/src/DeckPlugin.ts +28 -48
  159. package/src/capabilities/app-graph-builder/app-graph-builder.ts +119 -0
  160. package/src/capabilities/app-graph-builder/index.ts +7 -0
  161. package/src/capabilities/check-app-scheme/check-app-scheme.ts +45 -0
  162. package/src/capabilities/check-app-scheme/index.ts +7 -0
  163. package/src/capabilities/index.ts +9 -14
  164. package/src/capabilities/operation-resolver/index.ts +10 -0
  165. package/src/capabilities/operation-resolver/operation-resolver.ts +570 -0
  166. package/src/capabilities/react-root/index.ts +7 -0
  167. package/src/capabilities/react-root/react-root.tsx +47 -0
  168. package/src/capabilities/react-surface/index.ts +7 -0
  169. package/src/capabilities/react-surface/react-surface.tsx +38 -0
  170. package/src/capabilities/settings/index.ts +7 -0
  171. package/src/capabilities/settings/settings.ts +39 -0
  172. package/src/capabilities/state/index.ts +7 -0
  173. package/src/capabilities/state/state.ts +105 -0
  174. package/src/capabilities/toolkit/index.ts +7 -0
  175. package/src/capabilities/{toolkit.ts → toolkit/toolkit.ts} +19 -21
  176. package/src/capabilities/tools/index.ts +7 -0
  177. package/src/capabilities/tools/tools.ts +92 -0
  178. package/src/capabilities/url-handler/index.ts +7 -0
  179. package/src/capabilities/url-handler/url-handler.ts +96 -0
  180. package/src/components/DeckLayout/ActiveNode.tsx +3 -2
  181. package/src/components/DeckLayout/Banner.tsx +6 -6
  182. package/src/components/DeckLayout/ContentEmpty.tsx +4 -5
  183. package/src/components/DeckLayout/DeckLayout.stories.tsx +18 -29
  184. package/src/components/DeckLayout/DeckLayout.tsx +13 -11
  185. package/src/components/DeckLayout/DeckMain.tsx +43 -38
  186. package/src/components/DeckLayout/Dialog.tsx +21 -12
  187. package/src/components/DeckLayout/Fallback.tsx +1 -1
  188. package/src/components/DeckLayout/Popover.tsx +59 -22
  189. package/src/components/DeckLayout/StatusBar.tsx +3 -3
  190. package/src/components/DeckLayout/Toast.tsx +4 -4
  191. package/src/components/DeckSettings/DeckSettings.tsx +39 -29
  192. package/src/components/Plank/Plank.stories.tsx +16 -7
  193. package/src/components/Plank/Plank.tsx +21 -20
  194. package/src/components/Plank/PlankControls.tsx +5 -6
  195. package/src/components/Plank/PlankError.tsx +2 -2
  196. package/src/components/Plank/PlankHeading.tsx +31 -36
  197. package/src/components/Sidebar/ComplementarySidebar.tsx +37 -26
  198. package/src/components/Sidebar/Sidebar.tsx +5 -5
  199. package/src/components/Sidebar/SidebarButton.tsx +30 -24
  200. package/src/components/fragments.ts +1 -1
  201. package/src/hooks/index.ts +1 -0
  202. package/src/hooks/useCompanions.ts +1 -1
  203. package/src/hooks/useDeckCompanions.ts +6 -5
  204. package/src/hooks/useDeckState.ts +82 -0
  205. package/src/hooks/useHoistStatusbar.ts +3 -6
  206. package/src/hooks/useNodeActionExpander.ts +4 -4
  207. package/src/index.ts +1 -2
  208. package/src/meta.ts +2 -2
  209. package/src/translations.ts +1 -0
  210. package/src/types/capabilities.ts +33 -0
  211. package/src/types/events.ts +21 -0
  212. package/src/types/index.ts +2 -0
  213. package/src/types/schema.ts +85 -11
  214. package/src/util/layoutAppliesTopbar.ts +1 -1
  215. package/src/util/set-active.ts +49 -29
  216. package/dist/lib/browser/app-graph-builder-D74NTOMK.mjs +0 -128
  217. package/dist/lib/browser/app-graph-builder-D74NTOMK.mjs.map +0 -7
  218. package/dist/lib/browser/check-app-scheme-HIEVFAAX.mjs +0 -32
  219. package/dist/lib/browser/check-app-scheme-HIEVFAAX.mjs.map +0 -7
  220. package/dist/lib/browser/chunk-5KMJPIQC.mjs +0 -16
  221. package/dist/lib/browser/chunk-5KMJPIQC.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-CNTGBCMK.mjs.map +0 -7
  223. package/dist/lib/browser/chunk-F3VCCHVL.mjs.map +0 -7
  224. package/dist/lib/browser/chunk-QKCGZ45E.mjs +0 -128
  225. package/dist/lib/browser/chunk-QKCGZ45E.mjs.map +0 -7
  226. package/dist/lib/browser/chunk-UXLU6CMW.mjs +0 -16
  227. package/dist/lib/browser/chunk-UXLU6CMW.mjs.map +0 -7
  228. package/dist/lib/browser/chunk-VBYJ664A.mjs +0 -132
  229. package/dist/lib/browser/chunk-VBYJ664A.mjs.map +0 -7
  230. package/dist/lib/browser/chunk-VUJ6UNIJ.mjs +0 -1553
  231. package/dist/lib/browser/chunk-VUJ6UNIJ.mjs.map +0 -7
  232. package/dist/lib/browser/intent-resolver-UA4YQGAC.mjs +0 -524
  233. package/dist/lib/browser/intent-resolver-UA4YQGAC.mjs.map +0 -7
  234. package/dist/lib/browser/react-root-JAMHKYWN.mjs +0 -44
  235. package/dist/lib/browser/react-root-JAMHKYWN.mjs.map +0 -7
  236. package/dist/lib/browser/react-surface-6LW337ZT.mjs +0 -40
  237. package/dist/lib/browser/react-surface-6LW337ZT.mjs.map +0 -7
  238. package/dist/lib/browser/settings-SDPTOCCM.mjs +0 -30
  239. package/dist/lib/browser/settings-SDPTOCCM.mjs.map +0 -7
  240. package/dist/lib/browser/state-7IFAGZQO.mjs +0 -12
  241. package/dist/lib/browser/toolkit-L5CFXJCF.mjs.map +0 -7
  242. package/dist/lib/browser/url-handler-QEYGYE2H.mjs +0 -70
  243. package/dist/lib/browser/url-handler-QEYGYE2H.mjs.map +0 -7
  244. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  245. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  246. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  247. package/dist/types/src/capabilities/check-app-scheme.d.ts +0 -4
  248. package/dist/types/src/capabilities/check-app-scheme.d.ts.map +0 -1
  249. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  250. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  251. package/dist/types/src/capabilities/react-root.d.ts +0 -7
  252. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  253. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  254. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  255. package/dist/types/src/capabilities/settings.d.ts +0 -4
  256. package/dist/types/src/capabilities/settings.d.ts.map +0 -1
  257. package/dist/types/src/capabilities/state.d.ts +0 -104
  258. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  259. package/dist/types/src/capabilities/toolkit.d.ts.map +0 -1
  260. package/dist/types/src/capabilities/tools.d.ts +0 -11
  261. package/dist/types/src/capabilities/tools.d.ts.map +0 -1
  262. package/dist/types/src/capabilities/url-handler.d.ts +0 -4
  263. package/dist/types/src/capabilities/url-handler.d.ts.map +0 -1
  264. package/dist/types/src/events.d.ts +0 -4
  265. package/dist/types/src/events.d.ts.map +0 -1
  266. package/src/capabilities/app-graph-builder.ts +0 -143
  267. package/src/capabilities/capabilities.ts +0 -14
  268. package/src/capabilities/check-app-scheme.ts +0 -40
  269. package/src/capabilities/intent-resolver.ts +0 -471
  270. package/src/capabilities/react-root.tsx +0 -40
  271. package/src/capabilities/react-surface.tsx +0 -30
  272. package/src/capabilities/settings.ts +0 -27
  273. package/src/capabilities/state.ts +0 -113
  274. package/src/capabilities/tools.ts +0 -84
  275. package/src/capabilities/url-handler.ts +0 -60
  276. package/src/events.ts +0 -11
  277. /package/dist/lib/{browser/state-7IFAGZQO.mjs.map → node-esm/types/index.mjs.map} +0 -0
@@ -13,18 +13,18 @@ import React, {
13
13
  useRef,
14
14
  } from 'react';
15
15
 
16
- import { LayoutAction, createIntent } from '@dxos/app-framework';
17
- import { Surface, useAppGraph, useCapability, useIntentDispatcher } from '@dxos/app-framework/react';
16
+ import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
17
+ import { LayoutOperation } from '@dxos/app-toolkit';
18
+ import { useAppGraph } from '@dxos/app-toolkit/ui';
18
19
  import { debounce } from '@dxos/async';
19
20
  import { type Node, useNode } from '@dxos/plugin-graph';
20
21
  import { ATTENDABLE_PATH_SEPARATOR, useAttentionAttributes } from '@dxos/react-ui-attention';
21
22
  import { StackItem, railGridHorizontal } from '@dxos/react-ui-stack';
22
- import { mainIntrinsicSize, mx } from '@dxos/react-ui-theme';
23
+ import { mainIntrinsicSize, mx } from '@dxos/ui-theme';
23
24
 
24
- import { DeckCapabilities } from '../../capabilities';
25
- import { useCompanions, useMainSize } from '../../hooks';
25
+ import { useCompanions, useDeckState, useMainSize } from '../../hooks';
26
26
  import { parseEntryId } from '../../layout';
27
- import { DeckAction, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
27
+ import { DeckOperation, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
28
28
 
29
29
  import { PlankContentError, PlankError } from './PlankError';
30
30
  import { PlankHeading } from './PlankHeading';
@@ -49,10 +49,10 @@ export type PlankProps = Pick<PlankComponentProps, 'layoutMode' | 'part' | 'path
49
49
  // benefits. I think where we anticipate users will definitely want to quickly switch between showing and hiding entire
50
50
  // articles, over the (again probably large) performance benefit that unmounting them would confer, we can mount and
51
51
  // hide them, but I think that scenario in its most unambiguous form is probably rare. You could extrapolate
52
- // the scenario to include all potential planks such as companions, which we could keep mounted and hidden, but I
53
- // dont think the resulting performance would be acceptable. I think the real issue is perceived performance which
52
+ // the scenario to include all "potential" planks such as companions, which we could keep mounted and hidden, but I
53
+ // don't think the resulting performance would be acceptable. I think the real issue is "perceived performance" which
54
54
  // has mitigations that are in between mounting and un-mounting since both of those have tradeoffs; we may need one or more
55
- // partially-mounted experiences, like loading skeletons at the simple end, or screenshots of sleeping planks at
55
+ // "partially-mounted" experiences, like loading skeletons at the simple end, or screenshots of "sleeping" planks at
56
56
  // the advanced end.
57
57
 
58
58
  /**
@@ -138,9 +138,9 @@ type PlankComponentProps = {
138
138
  order?: number;
139
139
  active?: string[];
140
140
  companioned?: 'primary' | 'companion';
141
- node?: Node;
142
- primary?: Node;
143
- companions?: Node[];
141
+ node?: Node.Node;
142
+ primary?: Node.Node;
143
+ companions?: Node.Node[];
144
144
  settings?: DeckSettingsProps;
145
145
  };
146
146
 
@@ -158,8 +158,9 @@ const PlankComponent = memo(
158
158
  companions,
159
159
  settings,
160
160
  }: PlankComponentProps) => {
161
- const { dispatchPromise: dispatch } = useIntentDispatcher();
162
- const { deck, popoverAnchorId, scrollIntoView } = useCapability(DeckCapabilities.DeckState);
161
+ const { invokePromise } = useOperationInvoker();
162
+ const { state, deck } = useDeckState();
163
+ const { popoverAnchorId, scrollIntoView } = state;
163
164
  const { findFirstFocusable } = useFocusFinders();
164
165
  const canResize = layoutMode === 'deck';
165
166
 
@@ -177,12 +178,12 @@ const PlankComponent = memo(
177
178
 
178
179
  const handleSizeChange = useCallback(
179
180
  debounce((nextSize: number) => {
180
- return dispatch(createIntent(DeckAction.UpdatePlankSize, { id: sizeKey, size: nextSize }));
181
+ return invokePromise(DeckOperation.UpdatePlankSize, { id: sizeKey, size: nextSize });
181
182
  }, 200),
182
- [dispatch, sizeKey],
183
+ [invokePromise, sizeKey],
183
184
  );
184
185
 
185
- // TODO(thure): Tabsters focus group should handle moving focus to Main, but something is blocking it.
186
+ // TODO(thure): Tabster's focus group should handle moving focus to Main, but something is blocking it.
186
187
  const handleKeyDown = useCallback((event: KeyboardEvent) => {
187
188
  if (event.target === event.currentTarget) {
188
189
  switch (event.key) {
@@ -200,9 +201,9 @@ const PlankComponent = memo(
200
201
  if (scrollIntoView === id) {
201
202
  layoutMode === 'deck' && rootElement.current?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
202
203
  // Clear the scroll into view state once it has been actioned.
203
- void dispatch(createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: undefined }));
204
+ void invokePromise(LayoutOperation.ScrollIntoView, { subject: undefined });
204
205
  }
205
- }, [id, scrollIntoView, layoutMode]);
206
+ }, [id, scrollIntoView, layoutMode, invokePromise]);
206
207
 
207
208
  const isSolo = layoutMode.startsWith('solo') && part === 'solo';
208
209
  const isAttendable =
@@ -280,7 +281,7 @@ const PlankComponent = memo(
280
281
  companions={companions}
281
282
  />
282
283
  )}
283
- <Surface
284
+ <Surface.Surface
284
285
  key={node.id}
285
286
  role='article'
286
287
  data={data}
@@ -4,13 +4,12 @@
4
4
 
5
5
  import React, { forwardRef, useCallback } from 'react';
6
6
 
7
- import { createIntent } from '@dxos/app-framework';
8
- import { useIntentDispatcher } from '@dxos/app-framework/react';
7
+ import { useOperationInvoker } from '@dxos/app-framework/ui';
9
8
  import { invariant } from '@dxos/invariant';
10
9
  import { ButtonGroup, type ButtonGroupProps, type ButtonProps, IconButton, useTranslation } from '@dxos/react-ui';
11
10
 
12
11
  import { meta } from '../../meta';
13
- import { DeckAction, type LayoutMode } from '../../types';
12
+ import { type DeckAction, DeckOperation, type LayoutMode } from '../../types';
14
13
 
15
14
  export type PlankControlHandler = (event: DeckAction.PartAdjustment) => void;
16
15
 
@@ -45,11 +44,11 @@ type PlankComplimentControlsProps = {
45
44
  export const PlankCompanionControls = forwardRef<HTMLDivElement, PlankComplimentControlsProps>(
46
45
  ({ primary }, forwardedRef) => {
47
46
  const { t } = useTranslation(meta.id);
48
- const { dispatchPromise: dispatch } = useIntentDispatcher();
47
+ const { invokePromise } = useOperationInvoker();
49
48
  const handleCloseCompanion = useCallback(() => {
50
49
  invariant(primary);
51
- return dispatch(createIntent(DeckAction.ChangeCompanion, { primary, companion: null }));
52
- }, []);
50
+ return invokePromise(DeckOperation.ChangeCompanion, { primary, companion: null });
51
+ }, [invokePromise, primary]);
53
52
  return (
54
53
  <div ref={forwardedRef} className='contents app-no-drag'>
55
54
  <PlankControl
@@ -6,7 +6,7 @@ import React, { useEffect, useState } from 'react';
6
6
 
7
7
  import { type Node } from '@dxos/plugin-graph';
8
8
  import { useTranslation } from '@dxos/react-ui';
9
- import { descriptionMessage, mx } from '@dxos/react-ui-theme';
9
+ import { descriptionMessage, mx } from '@dxos/ui-theme';
10
10
 
11
11
  import { meta } from '../../meta';
12
12
 
@@ -33,7 +33,7 @@ export const PlankError = ({
33
33
  }: {
34
34
  id: string;
35
35
  part: PlankHeadingProps['part'];
36
- node?: Node;
36
+ node?: Node.Node;
37
37
  error?: Error;
38
38
  }) => {
39
39
  const [timedOut, setTimedOut] = useState(false);
@@ -4,18 +4,19 @@
4
4
 
5
5
  import React, { Fragment, type MouseEvent, memo, useCallback, useEffect, useMemo } from 'react';
6
6
 
7
- import { LayoutAction, createIntent } from '@dxos/app-framework';
8
- import { Surface, useAppGraph, useIntentDispatcher } from '@dxos/app-framework/react';
9
- import { type Node } from '@dxos/plugin-graph';
7
+ import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
8
+ import { LayoutOperation } from '@dxos/app-toolkit';
9
+ import { useAppGraph } from '@dxos/app-toolkit/ui';
10
+ import { Graph, type Node, useActionRunner } from '@dxos/plugin-graph';
10
11
  import { Icon, IconButton, Popover, toLocalizedString, useTranslation } from '@dxos/react-ui';
11
12
  import { StackItem, type StackItemSigilAction } from '@dxos/react-ui-stack';
12
13
  import { TextTooltip } from '@dxos/react-ui-text-tooltip';
13
- import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
14
+ import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/ui-theme';
14
15
 
15
16
  import { useBreakpoints } from '../../hooks';
16
17
  import { parseEntryId } from '../../layout';
17
18
  import { meta } from '../../meta';
18
- import { DeckAction, type LayoutMode, PLANK_COMPANION_TYPE, type ResolvedPart } from '../../types';
19
+ import { DeckOperation, type LayoutMode, PLANK_COMPANION_TYPE, type ResolvedPart } from '../../types';
19
20
  import { soloInlinePadding } from '../fragments';
20
21
 
21
22
  import { PlankCompanionControls, PlankControls } from './PlankControls';
@@ -26,7 +27,7 @@ export type PlankHeadingProps = {
26
27
  id: string;
27
28
  part: ResolvedPart;
28
29
  layoutMode?: LayoutMode;
29
- node?: Node;
30
+ node?: Node.Node;
30
31
  deckEnabled?: boolean;
31
32
  canIncrementStart?: boolean;
32
33
  canIncrementEnd?: boolean;
@@ -34,7 +35,7 @@ export type PlankHeadingProps = {
34
35
  primaryId?: string;
35
36
  pending?: boolean;
36
37
  companioned?: 'primary' | 'companion';
37
- companions?: Node[];
38
+ companions?: Node.Node[];
38
39
  actions?: StackItemSigilAction[];
39
40
  };
40
41
 
@@ -55,7 +56,8 @@ export const PlankHeading = memo(
55
56
  actions = [],
56
57
  }: PlankHeadingProps) => {
57
58
  const { t } = useTranslation(meta.id);
58
- const { dispatchPromise: dispatch } = useIntentDispatcher();
59
+ const { invokePromise, invokeSync } = useOperationInvoker();
60
+ const runAction = useActionRunner();
59
61
  const { graph } = useAppGraph();
60
62
  const breakpoint = useBreakpoints();
61
63
  const icon = node?.properties?.icon ?? 'ph--placeholder--regular';
@@ -69,7 +71,7 @@ export const PlankHeading = memo(
69
71
  const frame = requestAnimationFrame(() => {
70
72
  // Load actions for the node.
71
73
  if (node) {
72
- void graph.expand(node.id);
74
+ void Graph.expand(graph, node.id);
73
75
  }
74
76
  });
75
77
 
@@ -98,42 +100,37 @@ export const PlankHeading = memo(
98
100
  } else {
99
101
  return [
100
102
  actions,
101
- graph
102
- .getActions(node.id)
103
- .filter((a) => ['list-item', 'list-item-primary', 'heading-list-item'].includes(a.properties.disposition)),
103
+ Graph.getActions(graph, node.id).filter((a) =>
104
+ ['list-item', 'list-item-primary', 'heading-list-item'].includes(a.properties.disposition),
105
+ ),
104
106
  ].filter((a) => a.length > 0);
105
107
  }
106
108
  }, [actions, node, variant, graph]);
107
109
 
108
110
  const handleAction = useCallback(
109
111
  (action: StackItemSigilAction) => {
110
- typeof action.data === 'function' && void action.data?.({ parent: node, caller: meta.id });
112
+ if (typeof action.data === 'function') {
113
+ void runAction(action as Node.Action, { parent: node, caller: meta.id });
114
+ }
111
115
  },
112
- [node],
116
+ [node, runAction],
113
117
  );
114
118
 
115
119
  const handlePlankAction = useCallback(
116
- (eventType: DeckAction.PartAdjustment) => {
120
+ (eventType: DeckOperation.PartAdjustment) => {
117
121
  if (eventType.startsWith('solo')) {
118
- return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
122
+ return invokePromise(DeckOperation.Adjust, { type: eventType, id });
119
123
  } else if (eventType === 'close') {
120
124
  if (part === 'complementary') {
121
- return dispatch(
122
- createIntent(LayoutAction.UpdateComplementary, {
123
- part: 'complementary',
124
- options: { state: 'collapsed' },
125
- }),
126
- );
125
+ return invokeSync(LayoutOperation.UpdateComplementary, { state: 'collapsed' });
127
126
  } else {
128
- return dispatch(
129
- createIntent(LayoutAction.Close, { part: 'main', subject: [id], options: { state: false } }),
130
- );
127
+ return invokeSync(LayoutOperation.Close, { subject: [id] });
131
128
  }
132
129
  } else {
133
- return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
130
+ return invokePromise(DeckOperation.Adjust, { type: eventType, id });
134
131
  }
135
132
  },
136
- [dispatch, id, part],
133
+ [invokePromise, invokeSync, id, part],
137
134
  );
138
135
 
139
136
  const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${meta.id}/${node.id}` ? Popover.Anchor : Fragment;
@@ -143,15 +140,13 @@ export const PlankHeading = memo(
143
140
  const target = (event.target as HTMLElement).closest('[data-id]') as HTMLElement | null;
144
141
  const tabId = target?.dataset?.id;
145
142
  if (primaryId && tabId) {
146
- void dispatch(
147
- createIntent(DeckAction.ChangeCompanion, {
148
- primary: primaryId,
149
- companion: tabId,
150
- }),
151
- );
143
+ void invokePromise(DeckOperation.ChangeCompanion, {
144
+ primary: primaryId,
145
+ companion: tabId,
146
+ });
152
147
  }
153
148
  },
154
- [primaryId],
149
+ [primaryId, invokePromise],
155
150
  );
156
151
 
157
152
  return (
@@ -197,7 +192,7 @@ export const PlankHeading = memo(
197
192
  actions={sigilActions}
198
193
  onAction={handleAction}
199
194
  >
200
- <Surface role='menu-footer' data={{ subject: node.data }} />
195
+ <Surface.Surface role='menu-footer' data={{ subject: node.data }} />
201
196
  </StackItem.Sigil>
202
197
  ) : (
203
198
  <StackItem.SigilButton>
@@ -217,7 +212,7 @@ export const PlankHeading = memo(
217
212
  </TextTooltip>
218
213
  </>
219
214
  )}
220
- {node && part !== 'complementary' && <Surface role='navbar-end' data={{ subject: node.data }} />}
215
+ {node && part !== 'complementary' && <Surface.Surface role='navbar-end' data={{ subject: node.data }} />}
221
216
  {companioned === 'companion' ? (
222
217
  <PlankCompanionControls primary={primaryId} />
223
218
  ) : (
@@ -12,14 +12,20 @@ import React, {
12
12
  useState,
13
13
  } from 'react';
14
14
 
15
- import { LayoutAction, createIntent } from '@dxos/app-framework';
16
- import { Surface, useCapability, useIntentDispatcher } from '@dxos/app-framework/react';
17
- import { IconButton, type Label, Main, toLocalizedString, useTranslation } from '@dxos/react-ui';
15
+ import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
16
+ import { LayoutOperation } from '@dxos/app-toolkit';
17
+ import { IconButton, type Label, Main, ScrollArea, toLocalizedString, useTranslation } from '@dxos/react-ui';
18
18
  import { Tabs } from '@dxos/react-ui-tabs';
19
- import { mx } from '@dxos/react-ui-theme';
20
-
21
- import { DeckCapabilities } from '../../capabilities';
22
- import { type DeckCompanion, getCompanionId, useBreakpoints, useDeckCompanions, useHoistStatusbar } from '../../hooks';
19
+ import { mx } from '@dxos/ui-theme';
20
+
21
+ import {
22
+ type DeckCompanion,
23
+ getCompanionId,
24
+ useBreakpoints,
25
+ useDeckCompanions,
26
+ useDeckState,
27
+ useHoistStatusbar,
28
+ } from '../../hooks';
23
29
  import { meta } from '../../meta';
24
30
  import { getMode } from '../../types';
25
31
  import { layoutAppliesTopbar } from '../../util';
@@ -35,9 +41,9 @@ export type ComplementarySidebarProps = {
35
41
 
36
42
  export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) => {
37
43
  const { t } = useTranslation(meta.id);
38
- const { dispatchPromise: dispatch } = useIntentDispatcher();
39
- const layout = useCapability(DeckCapabilities.MutableDeckState);
40
- const layoutMode = getMode(layout.deck);
44
+ const { invokeSync } = useOperationInvoker();
45
+ const { state, deck, updateState } = useDeckState();
46
+ const layoutMode = getMode(deck);
41
47
  const breakpoint = useBreakpoints();
42
48
  const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
43
49
  const hoistStatusbar = useHoistStatusbar(breakpoint, layoutMode);
@@ -55,14 +61,17 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
55
61
  (event: MouseEvent) => {
56
62
  const nextValue = event.currentTarget.getAttribute('data-value') as string;
57
63
  if (nextValue === activeId) {
58
- layout.complementarySidebarState = layout.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded';
64
+ updateState((state) => ({
65
+ ...state,
66
+ complementarySidebarState: state.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded',
67
+ }));
59
68
  } else {
60
69
  setInternalValue(nextValue);
61
- layout.complementarySidebarState = 'expanded';
62
- void dispatch(createIntent(LayoutAction.UpdateComplementary, { part: 'complementary', subject: nextValue }));
70
+ updateState((state) => ({ ...state, complementarySidebarState: 'expanded' }));
71
+ invokeSync(LayoutOperation.UpdateComplementary, { subject: nextValue });
63
72
  }
64
73
  },
65
- [layout, activeId, dispatch],
74
+ [state.complementarySidebarState, activeId, invokeSync, updateState],
66
75
  );
67
76
 
68
77
  const data = useMemo(
@@ -76,11 +85,9 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
76
85
 
77
86
  useEffect(() => {
78
87
  if (!activeId) {
79
- void dispatch(
80
- createIntent(LayoutAction.UpdateComplementary, { part: 'complementary', options: { state: 'collapsed' } }),
81
- );
88
+ invokeSync(LayoutOperation.UpdateComplementary, { state: 'collapsed' });
82
89
  }
83
- }, [activeId, dispatch]);
90
+ }, [activeId, invokeSync]);
84
91
 
85
92
  return (
86
93
  <Main.ComplementarySidebar
@@ -110,7 +117,7 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
110
117
  data-value={getCompanionId(companion.id)}
111
118
  variant={
112
119
  activeId === getCompanionId(companion.id)
113
- ? layout.complementarySidebarState === 'expanded'
120
+ ? state.complementarySidebarState === 'expanded'
114
121
  ? 'primary'
115
122
  : 'default'
116
123
  : 'ghost'
@@ -122,7 +129,7 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
122
129
  </Tabs.Tablist>
123
130
  {!hoistStatusbar && (
124
131
  <div role='none' className='grid grid-cols-1 auto-rows-[--rail-item] p-1 overflow-y-auto'>
125
- <Surface role='status-bar--r0-footer' limit={1} />
132
+ <Surface.Surface role='status-bar--r0-footer' limit={1} />
126
133
  </div>
127
134
  )}
128
135
  <div role='none' className='hidden lg:grid grid-cols-1 auto-rows-[--rail-action] p-1'>
@@ -139,7 +146,7 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
139
146
  'inset-block-0 inline-start-0 is-[calc(100%-var(--r0-size))] lg:is-[--r1-size]',
140
147
  'grid grid-cols-1 grid-rows-[var(--rail-size)_1fr_min-content] pbs-[env(safe-area-inset-top)]',
141
148
  ]}
142
- {...(layout.complementarySidebarState !== 'expanded' && { inert: true })}
149
+ {...(state.complementarySidebarState !== 'expanded' && { inert: true })}
143
150
  >
144
151
  <ComplementarySidebarPanel
145
152
  companion={companion}
@@ -171,7 +178,7 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
171
178
  return null;
172
179
  }
173
180
 
174
- const Wrapper = companion.properties.fixed ? Fragment : ScrollArea;
181
+ const Wrapper = companion.properties.fixed ? Fragment : ScrollAreaWrapper;
175
182
 
176
183
  return (
177
184
  <>
@@ -190,7 +197,7 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
190
197
  </div>
191
198
  </div>
192
199
  <Wrapper>
193
- <Surface
200
+ <Surface.Surface
194
201
  role={`deck-companion--${getCompanionId(companion.id)}`}
195
202
  data={data}
196
203
  fallback={PlankContentError}
@@ -202,13 +209,17 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
202
209
  role='contentinfo'
203
210
  className='flex flex-wrap justify-center items-center border-bs border-subduedSeparator pbs-1 pbe-[max(env(safe-area-inset-bottom),0.25rem)]'
204
211
  >
205
- <Surface role='status-bar--r1-footer' limit={1} />
212
+ <Surface.Surface role='status-bar--r1-footer' limit={1} />
206
213
  </div>
207
214
  )}
208
215
  </>
209
216
  );
210
217
  };
211
218
 
212
- const ScrollArea = ({ children }: PropsWithChildren) => {
213
- return <div className='flex flex-col grow overflow-x-hidden overflow-y-auto scrollbar-thin'>{children}</div>;
219
+ const ScrollAreaWrapper = ({ children }: PropsWithChildren) => {
220
+ return (
221
+ <ScrollArea.Root thin orientation='vertical' classNames='grow'>
222
+ <ScrollArea.Viewport>{children}</ScrollArea.Viewport>
223
+ </ScrollArea.Root>
224
+ );
214
225
  };
@@ -4,11 +4,10 @@
4
4
 
5
5
  import React, { useMemo } from 'react';
6
6
 
7
- import { Surface, useCapability } from '@dxos/app-framework/react';
7
+ import { Surface } from '@dxos/app-framework/ui';
8
8
  import { type Label, Main } from '@dxos/react-ui';
9
9
 
10
- import { DeckCapabilities } from '../../capabilities';
11
- import { useBreakpoints, useHoistStatusbar } from '../../hooks';
10
+ import { useBreakpoints, useDeckState, useHoistStatusbar } from '../../hooks';
12
11
  import { meta } from '../../meta';
13
12
  import { getMode } from '../../types';
14
13
  import { layoutAppliesTopbar } from '../../util';
@@ -16,7 +15,8 @@ import { layoutAppliesTopbar } from '../../util';
16
15
  const label = ['sidebar title', { ns: meta.id }] satisfies Label;
17
16
 
18
17
  export const Sidebar = () => {
19
- const { popoverAnchorId, activeDeck: current, deck } = useCapability(DeckCapabilities.DeckState);
18
+ const { state, deck } = useDeckState();
19
+ const { popoverAnchorId, activeDeck: current } = state;
20
20
  const breakpoint = useBreakpoints();
21
21
  const layoutMode = getMode(deck);
22
22
  const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
@@ -36,7 +36,7 @@ export const Sidebar = () => {
36
36
  hoistStatusbar && 'block-end-[--statusbar-size]',
37
37
  ]}
38
38
  >
39
- <Surface role='navigation' data={navigationData} limit={1} />
39
+ <Surface.Surface role='navigation' data={navigationData} limit={1} />
40
40
  </Main.NavigationSidebar>
41
41
  );
42
42
  };
@@ -4,20 +4,27 @@
4
4
 
5
5
  import React, { useCallback } from 'react';
6
6
 
7
- import { LayoutAction, createIntent } from '@dxos/app-framework';
8
- import { useCapability, useIntentDispatcher } from '@dxos/app-framework/react';
7
+ import { useOperationInvoker } from '@dxos/app-framework/ui';
8
+ import { LayoutOperation } from '@dxos/app-toolkit';
9
9
  import { IconButton, type IconButtonProps, type ThemedClassName, useTranslation } from '@dxos/react-ui';
10
10
 
11
- import { DeckCapabilities } from '../../capabilities';
12
- import { getCompanionId, useDeckCompanions } from '../../hooks';
11
+ import { getCompanionId, useDeckCompanions, useDeckState } from '../../hooks';
13
12
  import { meta } from '../../meta';
14
13
 
15
14
  export const ToggleSidebarButton = ({
16
15
  classNames,
17
16
  variant = 'ghost',
18
17
  }: ThemedClassName<Pick<IconButtonProps, 'variant'>>) => {
19
- const layoutContext = useCapability(DeckCapabilities.MutableDeckState);
18
+ const { updateState } = useDeckState();
20
19
  const { t } = useTranslation(meta.id);
20
+
21
+ const handleClick = useCallback(() => {
22
+ updateState((state) => ({
23
+ ...state,
24
+ sidebarState: state.sidebarState === 'expanded' ? 'collapsed' : 'expanded',
25
+ }));
26
+ }, [updateState]);
27
+
21
28
  return (
22
29
  <IconButton
23
30
  variant={variant}
@@ -25,17 +32,20 @@ export const ToggleSidebarButton = ({
25
32
  iconOnly
26
33
  size={4}
27
34
  label={t('open navigation sidebar label')}
28
- onClick={() =>
29
- (layoutContext.sidebarState = layoutContext.sidebarState === 'expanded' ? 'collapsed' : 'expanded')
30
- }
35
+ onClick={handleClick}
31
36
  classNames={classNames}
32
37
  />
33
38
  );
34
39
  };
35
40
 
36
41
  export const CloseSidebarButton = () => {
37
- const layoutContext = useCapability(DeckCapabilities.MutableDeckState);
42
+ const { updateState } = useDeckState();
38
43
  const { t } = useTranslation(meta.id);
44
+
45
+ const handleClick = useCallback(() => {
46
+ updateState((state) => ({ ...state, sidebarState: 'collapsed' }));
47
+ }, [updateState]);
48
+
39
49
  return (
40
50
  <IconButton
41
51
  variant='ghost'
@@ -43,7 +53,7 @@ export const CloseSidebarButton = () => {
43
53
  iconOnly
44
54
  size={4}
45
55
  label={t('close navigation sidebar label')}
46
- onClick={() => (layoutContext.sidebarState = 'collapsed')}
56
+ onClick={handleClick}
47
57
  classNames='rounded-none pli-1 dx-focus-ring-inset pie-[max(.5rem,env(safe-area-inset-left))]'
48
58
  />
49
59
  );
@@ -54,24 +64,20 @@ export const ToggleComplementarySidebarButton = ({
54
64
  classNames,
55
65
  current,
56
66
  }: ThemedClassName<{ inR0?: boolean; current?: string }>) => {
57
- const { dispatchPromise: dispatch } = useIntentDispatcher();
58
- const layoutContext = useCapability(DeckCapabilities.MutableDeckState);
67
+ const { invokeSync } = useOperationInvoker();
68
+ const { state, updateState } = useDeckState();
59
69
  const { t } = useTranslation(meta.id);
60
70
 
61
71
  const companions = useDeckCompanions();
62
- const handleClick = useCallback(async () => {
63
- layoutContext.complementarySidebarState =
64
- layoutContext.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded';
65
- const subject = layoutContext.complementarySidebarPanel ?? (companions[0] && getCompanionId(companions[0].id));
66
- if (layoutContext.complementarySidebarState === 'expanded' && !current && subject) {
67
- await dispatch(
68
- createIntent(LayoutAction.UpdateComplementary, {
69
- part: 'complementary',
70
- subject,
71
- }),
72
- );
72
+ const handleClick = useCallback(() => {
73
+ const nextState = state.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded';
74
+ updateState((state) => ({ ...state, complementarySidebarState: nextState }));
75
+
76
+ const subject = state.complementarySidebarPanel ?? (companions[0] && getCompanionId(companions[0].id));
77
+ if (nextState === 'expanded' && !current && subject) {
78
+ invokeSync(LayoutOperation.UpdateComplementary, { subject });
73
79
  }
74
- }, [layoutContext, current, companions, dispatch]);
80
+ }, [state, updateState, current, companions, invokeSync]);
75
81
 
76
82
  return (
77
83
  <IconButton
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { mx } from '@dxos/react-ui-theme';
5
+ import { mx } from '@dxos/ui-theme';
6
6
 
7
7
  export const soloInlinePadding =
8
8
  'pis-[calc(env(safe-area-inset-left)+.25rem)] pie-[calc(env(safe-area-inset-left)+.25rem)]';
@@ -5,6 +5,7 @@
5
5
  export * from './useBreakpoints';
6
6
  export * from './useCompanions';
7
7
  export * from './useDeckCompanions';
8
+ export * from './useDeckState';
8
9
  export * from './useHoistStatusbar';
9
10
  export * from './useMainSize';
10
11
  export * from './useNodeActionExpander';
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { useMemo } from 'react';
6
6
 
7
- import { useAppGraph } from '@dxos/app-framework/react';
7
+ import { useAppGraph } from '@dxos/app-toolkit/ui';
8
8
  import { useConnections } from '@dxos/plugin-graph';
9
9
  import { byPosition } from '@dxos/util';
10
10
 
@@ -2,9 +2,10 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Label } from '@dxos/app-framework';
6
- import { useAppGraph } from '@dxos/app-framework/react';
7
- import { type Node, ROOT_ID, useConnections } from '@dxos/plugin-graph';
5
+ import { useAppGraph } from '@dxos/app-toolkit/ui';
6
+ import { Node, type Node as NodeType } from '@dxos/plugin-graph';
7
+ import { useConnections } from '@dxos/plugin-graph';
8
+ import { type Label } from '@dxos/ui-types';
8
9
  import { type Position, byPosition } from '@dxos/util';
9
10
 
10
11
  import { ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE } from '../types';
@@ -14,7 +15,7 @@ export const getCompanionId = (id: string) => {
14
15
  return companionId ?? 'never';
15
16
  };
16
17
 
17
- export type DeckCompanion = Node<
18
+ export type DeckCompanion = NodeType.Node<
18
19
  any,
19
20
  {
20
21
  label: Label;
@@ -28,7 +29,7 @@ export type DeckCompanion = Node<
28
29
 
29
30
  export const useDeckCompanions = (): DeckCompanion[] => {
30
31
  const { graph } = useAppGraph();
31
- const connections = useConnections(graph, ROOT_ID);
32
+ const connections = useConnections(graph, Node.RootId);
32
33
  const companions = connections.filter((node) => node.type === DECK_COMPANION_TYPE) as DeckCompanion[];
33
34
  return companions.toSorted((a, b) => byPosition(a.properties, b.properties));
34
35
  };