@dxos/plugin-deck 0.8.4-main.ae835ea → 0.8.4-main.bc674ce

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 (276) hide show
  1. package/dist/lib/browser/app-graph-builder-DTVCULQ4.mjs +120 -0
  2. package/dist/lib/browser/app-graph-builder-DTVCULQ4.mjs.map +7 -0
  3. package/dist/lib/browser/{check-app-scheme-HIEVFAAX.mjs → check-app-scheme-JSRXXIYF.mjs} +9 -9
  4. package/dist/lib/browser/check-app-scheme-JSRXXIYF.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-F3VCCHVL.mjs → chunk-ATFPDN6J.mjs} +149 -19
  6. package/dist/lib/browser/chunk-ATFPDN6J.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-CNTGBCMK.mjs → chunk-NHABISX2.mjs} +40 -33
  8. package/dist/lib/browser/chunk-NHABISX2.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-S4A5UO4K.mjs +1448 -0
  10. package/dist/lib/browser/chunk-S4A5UO4K.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-UNG4CLLP.mjs +161 -0
  12. package/dist/lib/browser/chunk-UNG4CLLP.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +72 -66
  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-CDYBLZJ4.mjs +595 -0
  17. package/dist/lib/browser/operation-resolver-CDYBLZJ4.mjs.map +7 -0
  18. package/dist/lib/browser/react-root-XDCMNENQ.mjs +47 -0
  19. package/dist/lib/browser/react-root-XDCMNENQ.mjs.map +7 -0
  20. package/dist/lib/browser/react-surface-HODERLOL.mjs +42 -0
  21. package/dist/lib/browser/react-surface-HODERLOL.mjs.map +7 -0
  22. package/dist/lib/browser/settings-OMHVGZ6V.mjs +37 -0
  23. package/dist/lib/browser/settings-OMHVGZ6V.mjs.map +7 -0
  24. package/dist/lib/browser/state-OC3BSB6E.mjs +103 -0
  25. package/dist/lib/browser/state-OC3BSB6E.mjs.map +7 -0
  26. package/dist/lib/browser/toolkit-R53LD3EA.mjs +53 -0
  27. package/dist/lib/browser/toolkit-R53LD3EA.mjs.map +7 -0
  28. package/dist/lib/browser/types/index.mjs +11 -4
  29. package/dist/lib/browser/url-handler-53TE6JZO.mjs +93 -0
  30. package/dist/lib/browser/url-handler-53TE6JZO.mjs.map +7 -0
  31. package/dist/lib/node-esm/app-graph-builder-473BNZDJ.mjs +121 -0
  32. package/dist/lib/node-esm/app-graph-builder-473BNZDJ.mjs.map +7 -0
  33. package/dist/lib/node-esm/check-app-scheme-IVYRHKRH.mjs +33 -0
  34. package/dist/lib/node-esm/check-app-scheme-IVYRHKRH.mjs.map +7 -0
  35. package/dist/lib/node-esm/chunk-ADPMWKLL.mjs +154 -0
  36. package/dist/lib/node-esm/chunk-ADPMWKLL.mjs.map +7 -0
  37. package/dist/lib/node-esm/chunk-D34L3ECT.mjs +1449 -0
  38. package/dist/lib/node-esm/chunk-D34L3ECT.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-SKEVPQ7E.mjs +162 -0
  40. package/dist/lib/node-esm/chunk-SKEVPQ7E.mjs.map +7 -0
  41. package/dist/lib/node-esm/chunk-XAKTY3EB.mjs +294 -0
  42. package/dist/lib/node-esm/chunk-XAKTY3EB.mjs.map +7 -0
  43. package/dist/lib/node-esm/index.mjs +181 -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-WUOE33ID.mjs +596 -0
  47. package/dist/lib/node-esm/operation-resolver-WUOE33ID.mjs.map +7 -0
  48. package/dist/lib/node-esm/react-root-O6GZO62Z.mjs +48 -0
  49. package/dist/lib/node-esm/react-root-O6GZO62Z.mjs.map +7 -0
  50. package/dist/lib/node-esm/react-surface-IHDJDGC5.mjs +43 -0
  51. package/dist/lib/node-esm/react-surface-IHDJDGC5.mjs.map +7 -0
  52. package/dist/lib/node-esm/settings-2HB6FKIK.mjs +38 -0
  53. package/dist/lib/node-esm/settings-2HB6FKIK.mjs.map +7 -0
  54. package/dist/lib/node-esm/state-JRQ45ACJ.mjs +104 -0
  55. package/dist/lib/node-esm/state-JRQ45ACJ.mjs.map +7 -0
  56. package/dist/lib/node-esm/toolkit-JLPZNNKB.mjs +54 -0
  57. package/dist/lib/node-esm/toolkit-JLPZNNKB.mjs.map +7 -0
  58. package/dist/lib/node-esm/types/index.mjs +40 -0
  59. package/dist/lib/node-esm/url-handler-QGF2R24T.mjs +94 -0
  60. package/dist/lib/node-esm/url-handler-QGF2R24T.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 +21 -0
  88. package/dist/types/src/capabilities/settings/settings.d.ts.map +1 -0
  89. package/dist/types/src/capabilities/state/index.d.ts +172 -0
  90. package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
  91. package/dist/types/src/capabilities/state/state.d.ts +175 -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/toolkit.d.ts +26 -0
  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/ContentEmpty.d.ts.map +1 -1
  106. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  107. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts +1 -1
  108. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts.map +1 -1
  109. package/dist/types/src/components/DeckLayout/DeckMain.d.ts.map +1 -1
  110. package/dist/types/src/components/DeckLayout/Dialog.d.ts.map +1 -1
  111. package/dist/types/src/components/DeckLayout/Popover.d.ts.map +1 -1
  112. package/dist/types/src/components/DeckLayout/Toast.d.ts +3 -3
  113. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
  114. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts +4 -2
  115. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -1
  116. package/dist/types/src/components/Plank/Plank.d.ts +3 -3
  117. package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
  118. package/dist/types/src/components/Plank/Plank.stories.d.ts +23 -5
  119. package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -1
  120. package/dist/types/src/components/Plank/PlankControls.d.ts +1 -1
  121. package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -1
  122. package/dist/types/src/components/Plank/PlankError.d.ts +1 -1
  123. package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -1
  124. package/dist/types/src/components/Plank/PlankHeading.d.ts +2 -2
  125. package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
  126. package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
  127. package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -1
  128. package/dist/types/src/components/Sidebar/SidebarButton.d.ts.map +1 -1
  129. package/dist/types/src/hooks/index.d.ts +1 -0
  130. package/dist/types/src/hooks/index.d.ts.map +1 -1
  131. package/dist/types/src/hooks/useDeckCompanions.d.ts +3 -3
  132. package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
  133. package/dist/types/src/hooks/useDeckState.d.ts +17 -0
  134. package/dist/types/src/hooks/useDeckState.d.ts.map +1 -0
  135. package/dist/types/src/hooks/useHoistStatusbar.d.ts +1 -1
  136. package/dist/types/src/hooks/useHoistStatusbar.d.ts.map +1 -1
  137. package/dist/types/src/hooks/useNodeActionExpander.d.ts +1 -1
  138. package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -1
  139. package/dist/types/src/index.d.ts +1 -2
  140. package/dist/types/src/index.d.ts.map +1 -1
  141. package/dist/types/src/meta.d.ts +2 -2
  142. package/dist/types/src/meta.d.ts.map +1 -1
  143. package/dist/types/src/translations.d.ts +1 -1
  144. package/dist/types/src/{capabilities → types}/capabilities.d.ts +96 -90
  145. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  146. package/dist/types/src/types/events.d.ts +7 -0
  147. package/dist/types/src/types/events.d.ts.map +1 -0
  148. package/dist/types/src/types/index.d.ts +2 -0
  149. package/dist/types/src/types/index.d.ts.map +1 -1
  150. package/dist/types/src/types/schema.d.ts +86 -27
  151. package/dist/types/src/types/schema.d.ts.map +1 -1
  152. package/dist/types/src/util/set-active.d.ts +18 -3
  153. package/dist/types/src/util/set-active.d.ts.map +1 -1
  154. package/dist/types/tsconfig.tsbuildinfo +1 -1
  155. package/package.json +53 -47
  156. package/src/DeckPlugin.ts +27 -48
  157. package/src/capabilities/app-graph-builder/app-graph-builder.ts +118 -0
  158. package/src/capabilities/app-graph-builder/index.ts +7 -0
  159. package/src/capabilities/{check-app-scheme.ts → check-app-scheme/check-app-scheme.ts} +12 -11
  160. package/src/capabilities/check-app-scheme/index.ts +7 -0
  161. package/src/capabilities/index.ts +9 -14
  162. package/src/capabilities/operation-resolver/index.ts +10 -0
  163. package/src/capabilities/operation-resolver/operation-resolver.ts +555 -0
  164. package/src/capabilities/react-root/index.ts +7 -0
  165. package/src/capabilities/react-root/react-root.tsx +47 -0
  166. package/src/capabilities/react-surface/index.ts +7 -0
  167. package/src/capabilities/react-surface/react-surface.tsx +37 -0
  168. package/src/capabilities/settings/index.ts +7 -0
  169. package/src/capabilities/settings/settings.ts +38 -0
  170. package/src/capabilities/state/index.ts +7 -0
  171. package/src/capabilities/state/state.ts +104 -0
  172. package/src/capabilities/toolkit/index.ts +7 -0
  173. package/src/capabilities/toolkit/toolkit.ts +63 -0
  174. package/src/capabilities/tools/index.ts +7 -0
  175. package/src/capabilities/tools/tools.ts +92 -0
  176. package/src/capabilities/url-handler/index.ts +7 -0
  177. package/src/capabilities/url-handler/url-handler.ts +95 -0
  178. package/src/components/DeckLayout/ActiveNode.tsx +1 -1
  179. package/src/components/DeckLayout/Banner.tsx +3 -3
  180. package/src/components/DeckLayout/ContentEmpty.tsx +3 -4
  181. package/src/components/DeckLayout/DeckLayout.stories.tsx +18 -31
  182. package/src/components/DeckLayout/DeckLayout.tsx +13 -11
  183. package/src/components/DeckLayout/DeckMain.tsx +45 -44
  184. package/src/components/DeckLayout/Dialog.tsx +13 -10
  185. package/src/components/DeckLayout/Fallback.tsx +2 -2
  186. package/src/components/DeckLayout/Popover.tsx +44 -32
  187. package/src/components/DeckLayout/StatusBar.tsx +1 -1
  188. package/src/components/DeckLayout/Toast.tsx +5 -5
  189. package/src/components/DeckSettings/DeckSettings.tsx +18 -8
  190. package/src/components/Plank/Plank.stories.tsx +14 -6
  191. package/src/components/Plank/Plank.tsx +66 -49
  192. package/src/components/Plank/PlankControls.tsx +6 -6
  193. package/src/components/Plank/PlankError.tsx +2 -2
  194. package/src/components/Plank/PlankHeading.tsx +29 -35
  195. package/src/components/Sidebar/ComplementarySidebar.tsx +54 -27
  196. package/src/components/Sidebar/Sidebar.tsx +4 -4
  197. package/src/components/Sidebar/SidebarButton.tsx +35 -28
  198. package/src/components/fragments.ts +1 -1
  199. package/src/hooks/index.ts +1 -0
  200. package/src/hooks/useCompanions.ts +1 -1
  201. package/src/hooks/useDeckCompanions.ts +6 -4
  202. package/src/hooks/useDeckState.ts +82 -0
  203. package/src/hooks/useHoistStatusbar.ts +3 -5
  204. package/src/hooks/useNodeActionExpander.ts +4 -4
  205. package/src/index.ts +1 -2
  206. package/src/meta.ts +2 -2
  207. package/src/translations.ts +1 -1
  208. package/src/types/capabilities.ts +33 -0
  209. package/src/types/events.ts +20 -0
  210. package/src/types/index.ts +2 -0
  211. package/src/types/schema.ts +81 -11
  212. package/src/util/layoutAppliesTopbar.ts +1 -1
  213. package/src/util/set-active.ts +49 -29
  214. package/dist/lib/browser/app-graph-builder-PCMSER2O.mjs +0 -153
  215. package/dist/lib/browser/app-graph-builder-PCMSER2O.mjs.map +0 -7
  216. package/dist/lib/browser/check-app-scheme-HIEVFAAX.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-27I7DJUG.mjs +0 -129
  218. package/dist/lib/browser/chunk-27I7DJUG.mjs.map +0 -7
  219. package/dist/lib/browser/chunk-5KMJPIQC.mjs +0 -16
  220. package/dist/lib/browser/chunk-5KMJPIQC.mjs.map +0 -7
  221. package/dist/lib/browser/chunk-CNTGBCMK.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-F3VCCHVL.mjs.map +0 -7
  223. package/dist/lib/browser/chunk-MFFZK4LT.mjs +0 -127
  224. package/dist/lib/browser/chunk-MFFZK4LT.mjs.map +0 -7
  225. package/dist/lib/browser/chunk-SBJLGRJV.mjs +0 -1532
  226. package/dist/lib/browser/chunk-SBJLGRJV.mjs.map +0 -7
  227. package/dist/lib/browser/chunk-UXLU6CMW.mjs +0 -16
  228. package/dist/lib/browser/chunk-UXLU6CMW.mjs.map +0 -7
  229. package/dist/lib/browser/intent-resolver-Q3KETDSS.mjs +0 -524
  230. package/dist/lib/browser/intent-resolver-Q3KETDSS.mjs.map +0 -7
  231. package/dist/lib/browser/react-root-LU3662ME.mjs +0 -43
  232. package/dist/lib/browser/react-root-LU3662ME.mjs.map +0 -7
  233. package/dist/lib/browser/react-surface-TDBFPN5T.mjs +0 -40
  234. package/dist/lib/browser/react-surface-TDBFPN5T.mjs.map +0 -7
  235. package/dist/lib/browser/settings-SDPTOCCM.mjs +0 -30
  236. package/dist/lib/browser/settings-SDPTOCCM.mjs.map +0 -7
  237. package/dist/lib/browser/state-QTVNH7N6.mjs +0 -12
  238. package/dist/lib/browser/toolkit-TM2Y6YL2.mjs +0 -53
  239. package/dist/lib/browser/toolkit-TM2Y6YL2.mjs.map +0 -7
  240. package/dist/lib/browser/url-handler-QEYGYE2H.mjs +0 -70
  241. package/dist/lib/browser/url-handler-QEYGYE2H.mjs.map +0 -7
  242. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  243. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  244. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  245. package/dist/types/src/capabilities/check-app-scheme.d.ts +0 -4
  246. package/dist/types/src/capabilities/check-app-scheme.d.ts.map +0 -1
  247. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  248. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  249. package/dist/types/src/capabilities/react-root.d.ts +0 -7
  250. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  251. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  252. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  253. package/dist/types/src/capabilities/settings.d.ts +0 -4
  254. package/dist/types/src/capabilities/settings.d.ts.map +0 -1
  255. package/dist/types/src/capabilities/state.d.ts +0 -104
  256. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  257. package/dist/types/src/capabilities/toolkit.d.ts +0 -23
  258. package/dist/types/src/capabilities/toolkit.d.ts.map +0 -1
  259. package/dist/types/src/capabilities/tools.d.ts +0 -11
  260. package/dist/types/src/capabilities/tools.d.ts.map +0 -1
  261. package/dist/types/src/capabilities/url-handler.d.ts +0 -4
  262. package/dist/types/src/capabilities/url-handler.d.ts.map +0 -1
  263. package/dist/types/src/events.d.ts +0 -4
  264. package/dist/types/src/events.d.ts.map +0 -1
  265. package/src/capabilities/app-graph-builder.ts +0 -143
  266. package/src/capabilities/capabilities.ts +0 -14
  267. package/src/capabilities/intent-resolver.ts +0 -472
  268. package/src/capabilities/react-root.tsx +0 -39
  269. package/src/capabilities/react-surface.tsx +0 -30
  270. package/src/capabilities/settings.ts +0 -27
  271. package/src/capabilities/state.ts +0 -108
  272. package/src/capabilities/toolkit.ts +0 -68
  273. package/src/capabilities/tools.ts +0 -84
  274. package/src/capabilities/url-handler.ts +0 -60
  275. package/src/events.ts +0 -11
  276. /package/dist/lib/{browser/state-QTVNH7N6.mjs.map → node-esm/types/index.mjs.map} +0 -0
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { useFocusFinders } from '@fluentui/react-tabster';
5
6
  import React, {
6
7
  type KeyboardEvent,
7
8
  type PropsWithChildren,
@@ -12,24 +13,17 @@ import React, {
12
13
  useRef,
13
14
  } from 'react';
14
15
 
15
- import {
16
- LayoutAction,
17
- Surface,
18
- createIntent,
19
- useAppGraph,
20
- useCapability,
21
- useIntentDispatcher,
22
- } from '@dxos/app-framework';
16
+ import { Common } from '@dxos/app-framework';
17
+ import { Surface, useAppGraph, useOperationInvoker } from '@dxos/app-framework/react';
23
18
  import { debounce } from '@dxos/async';
24
19
  import { type Node, useNode } from '@dxos/plugin-graph';
25
20
  import { ATTENDABLE_PATH_SEPARATOR, useAttentionAttributes } from '@dxos/react-ui-attention';
26
21
  import { StackItem, railGridHorizontal } from '@dxos/react-ui-stack';
27
- import { mainIntrinsicSize, mx } from '@dxos/react-ui-theme';
22
+ import { mainIntrinsicSize, mx } from '@dxos/ui-theme';
28
23
 
29
- import { DeckCapabilities } from '../../capabilities';
30
- import { useCompanions, useMainSize } from '../../hooks';
24
+ import { useCompanions, useDeckState, useMainSize } from '../../hooks';
31
25
  import { parseEntryId } from '../../layout';
32
- import { DeckAction, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
26
+ import { DeckOperation, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
33
27
 
34
28
  import { PlankContentError, PlankError } from './PlankError';
35
29
  import { PlankHeading } from './PlankHeading';
@@ -37,6 +31,10 @@ import { PlankLoading } from './PlankLoading';
37
31
 
38
32
  const UNKNOWN_ID = 'unknown_id';
39
33
 
34
+ //
35
+ // Plank
36
+ //
37
+
40
38
  export type PlankProps = Pick<PlankComponentProps, 'layoutMode' | 'part' | 'path' | 'order' | 'active' | 'settings'> & {
41
39
  id?: string;
42
40
  companionId?: string;
@@ -50,10 +48,10 @@ export type PlankProps = Pick<PlankComponentProps, 'layoutMode' | 'part' | 'path
50
48
  // benefits. I think where we anticipate users will definitely want to quickly switch between showing and hiding entire
51
49
  // articles, over the (again probably large) performance benefit that unmounting them would confer, we can mount and
52
50
  // hide them, but I think that scenario in its most unambiguous form is probably rare. You could extrapolate
53
- // the scenario to include all potential planks such as companions, which we could keep mounted and hidden, but I
54
- // dont think the resulting performance would be acceptable. I think the real issue is perceived performance which
51
+ // the scenario to include all "potential" planks such as companions, which we could keep mounted and hidden, but I
52
+ // don't think the resulting performance would be acceptable. I think the real issue is "perceived performance" which
55
53
  // has mitigations that are in between mounting and un-mounting since both of those have tradeoffs; we may need one or more
56
- // partially-mounted experiences, like loading skeletons at the simple end, or screenshots of sleeping planks at
54
+ // "partially-mounted" experiences, like loading skeletons at the simple end, or screenshots of "sleeping" planks at
57
55
  // the advanced end.
58
56
 
59
57
  /**
@@ -96,12 +94,13 @@ export const Plank = memo(({ id = UNKNOWN_ID, companionId, ...props }: PlankProp
96
94
  );
97
95
  });
98
96
 
99
- const PlankContainer = ({
100
- children,
101
- solo,
102
- companion,
103
- encapsulate,
104
- }: PropsWithChildren<{ solo: boolean; companion: boolean; encapsulate: boolean }>) => {
97
+ //
98
+ // PlankContainer
99
+ //
100
+
101
+ type PlankContainerProps = PropsWithChildren<{ solo: boolean; companion: boolean; encapsulate: boolean }>;
102
+
103
+ const PlankContainer = ({ children, solo, companion, encapsulate }: PlankContainerProps) => {
105
104
  const sizeAttrs = useMainSize();
106
105
  if (!solo) {
107
106
  return children;
@@ -111,10 +110,11 @@ const PlankContainer = ({
111
110
  return (
112
111
  <div
113
112
  role='none'
113
+ data-popover-collision-boundary={true}
114
114
  className={mx(
115
115
  'absolute inset-[--main-spacing] grid',
116
116
  encapsulate && 'border border-separator rounded overflow-hidden',
117
- companion && 'grid-cols-[6fr_4fr]',
117
+ companion && 'grid-cols-[6fr_4fr]', // TODO(burdon): Resize.
118
118
  railGridHorizontal,
119
119
  mainIntrinsicSize,
120
120
  )}
@@ -125,6 +125,10 @@ const PlankContainer = ({
125
125
  );
126
126
  };
127
127
 
128
+ //
129
+ // PlankComponent
130
+ //
131
+
128
132
  type PlankComponentProps = {
129
133
  layoutMode: LayoutMode;
130
134
  id: string;
@@ -132,11 +136,10 @@ type PlankComponentProps = {
132
136
  path?: string[];
133
137
  order?: number;
134
138
  active?: string[];
135
- // TODO(burdon): Change to role?
136
139
  companioned?: 'primary' | 'companion';
137
- node?: Node;
138
- primary?: Node;
139
- companions?: Node[];
140
+ node?: Node.Node;
141
+ primary?: Node.Node;
142
+ companions?: Node.Node[];
140
143
  settings?: DeckSettingsProps;
141
144
  };
142
145
 
@@ -154,8 +157,10 @@ const PlankComponent = memo(
154
157
  companions,
155
158
  settings,
156
159
  }: PlankComponentProps) => {
157
- const { dispatchPromise: dispatch } = useIntentDispatcher();
158
- const { deck, popoverAnchorId, scrollIntoView } = useCapability(DeckCapabilities.DeckState);
160
+ const { invokePromise } = useOperationInvoker();
161
+ const { state, deck } = useDeckState();
162
+ const { popoverAnchorId, scrollIntoView } = state;
163
+ const { findFirstFocusable } = useFocusFinders();
159
164
  const canResize = layoutMode === 'deck';
160
165
 
161
166
  const attentionAttrs = useAttentionAttributes(primary?.id ?? id);
@@ -172,15 +177,22 @@ const PlankComponent = memo(
172
177
 
173
178
  const handleSizeChange = useCallback(
174
179
  debounce((nextSize: number) => {
175
- return dispatch(createIntent(DeckAction.UpdatePlankSize, { id: sizeKey, size: nextSize }));
180
+ return invokePromise(DeckOperation.UpdatePlankSize, { id: sizeKey, size: nextSize });
176
181
  }, 200),
177
- [dispatch, sizeKey],
182
+ [invokePromise, sizeKey],
178
183
  );
179
184
 
180
- // TODO(thure): Tabsters focus group should handle moving focus to Main, but something is blocking it.
185
+ // TODO(thure): Tabster's focus group should handle moving focus to Main, but something is blocking it.
181
186
  const handleKeyDown = useCallback((event: KeyboardEvent) => {
182
- if (event.target === event.currentTarget && event.key === 'Escape') {
183
- rootElement.current?.closest('main')?.focus();
187
+ if (event.target === event.currentTarget) {
188
+ switch (event.key) {
189
+ case 'Escape':
190
+ rootElement.current?.closest('main')?.focus();
191
+ break;
192
+ case 'Enter':
193
+ rootElement.current && findFirstFocusable(rootElement.current)?.focus();
194
+ break;
195
+ }
184
196
  }
185
197
  }, []);
186
198
 
@@ -188,9 +200,9 @@ const PlankComponent = memo(
188
200
  if (scrollIntoView === id) {
189
201
  layoutMode === 'deck' && rootElement.current?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
190
202
  // Clear the scroll into view state once it has been actioned.
191
- void dispatch(createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: undefined }));
203
+ void invokePromise(Common.LayoutOperation.ScrollIntoView, { subject: undefined });
192
204
  }
193
- }, [id, scrollIntoView, layoutMode]);
205
+ }, [id, scrollIntoView, layoutMode, invokePromise]);
194
206
 
195
207
  const isSolo = layoutMode.startsWith('solo') && part === 'solo';
196
208
  const isAttendable =
@@ -216,14 +228,16 @@ const PlankComponent = memo(
216
228
  const placeholder = useMemo(() => <PlankLoading />, []);
217
229
 
218
230
  const Root = part.startsWith('solo') ? 'article' : StackItem.Root;
231
+ const fullscreen = layoutMode === 'solo--fullscreen';
219
232
  const className = mx(
220
233
  'attention-surface relative dx-focus-ring-inset-over-all density-coarse',
221
234
  isSolo && 'absolute inset-0',
222
235
  isSolo && mainIntrinsicSize,
223
236
  railGridHorizontal,
224
237
  part.startsWith('solo') && 'grid',
238
+ part.startsWith('solo-') && 'grid-rows-subgrid row-span-2 min-is-0',
239
+ fullscreen && 'grid-rows-1',
225
240
  part === 'deck' && (companioned === 'companion' ? '!border-separator border-ie' : '!border-separator border-li'),
226
- part.startsWith('solo-') && 'row-span-2 grid-rows-subgrid min-is-0',
227
241
  part === 'solo-companion' && '!border-separator border-is',
228
242
  settings?.encapsulatedPlanks &&
229
243
  !part.startsWith('solo') &&
@@ -234,6 +248,7 @@ const PlankComponent = memo(
234
248
  <Root
235
249
  ref={rootElement}
236
250
  data-testid='deck.plank'
251
+ data-popover-collision-boundary={true}
237
252
  tabIndex={0}
238
253
  {...(part.startsWith('solo')
239
254
  ? ({ ...sizeAttrs, className } as any)
@@ -250,19 +265,21 @@ const PlankComponent = memo(
250
265
  >
251
266
  {node ? (
252
267
  <>
253
- <PlankHeading
254
- id={id}
255
- part={part.startsWith('solo-') ? 'solo' : part}
256
- node={node}
257
- layoutMode={layoutMode}
258
- deckEnabled={settings?.enableDeck}
259
- canIncrementStart={canIncrementStart}
260
- canIncrementEnd={canIncrementEnd}
261
- popoverAnchorId={popoverAnchorId}
262
- primaryId={primary?.id}
263
- companioned={companioned}
264
- companions={companions}
265
- />
268
+ {!fullscreen && (
269
+ <PlankHeading
270
+ id={id}
271
+ part={part.startsWith('solo-') ? 'solo' : part}
272
+ node={node}
273
+ layoutMode={layoutMode}
274
+ deckEnabled={settings?.enableDeck}
275
+ canIncrementStart={canIncrementStart}
276
+ canIncrementEnd={canIncrementEnd}
277
+ popoverAnchorId={popoverAnchorId}
278
+ primaryId={primary?.id}
279
+ companioned={companioned}
280
+ companions={companions}
281
+ />
282
+ )}
266
283
  <Surface
267
284
  key={node.id}
268
285
  role='article'
@@ -4,12 +4,12 @@
4
4
 
5
5
  import React, { forwardRef, useCallback } from 'react';
6
6
 
7
- import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
7
+ import { useOperationInvoker } from '@dxos/app-framework/react';
8
8
  import { invariant } from '@dxos/invariant';
9
9
  import { ButtonGroup, type ButtonGroupProps, type ButtonProps, IconButton, useTranslation } from '@dxos/react-ui';
10
10
 
11
11
  import { meta } from '../../meta';
12
- import { DeckAction, type LayoutMode } from '../../types';
12
+ import { type DeckAction, DeckOperation, type LayoutMode } from '../../types';
13
13
 
14
14
  export type PlankControlHandler = (event: DeckAction.PartAdjustment) => void;
15
15
 
@@ -32,7 +32,7 @@ export type PlankControlsProps = Omit<ButtonGroupProps, 'onClick'> & {
32
32
  };
33
33
 
34
34
  const PlankControl = ({ icon, label, ...props }: Omit<ButtonProps, 'children'> & { label: string; icon: string }) => {
35
- return <IconButton iconOnly label={label} icon={icon} size={5} variant='ghost' tooltipSide='bottom' {...props} />;
35
+ return <IconButton label={label} icon={icon} iconOnly variant='ghost' tooltipSide='bottom' {...props} />;
36
36
  };
37
37
 
38
38
  const plankControlSpacing = 'pli-2';
@@ -44,11 +44,11 @@ type PlankComplimentControlsProps = {
44
44
  export const PlankCompanionControls = forwardRef<HTMLDivElement, PlankComplimentControlsProps>(
45
45
  ({ primary }, forwardedRef) => {
46
46
  const { t } = useTranslation(meta.id);
47
- const { dispatchPromise: dispatch } = useIntentDispatcher();
47
+ const { invokePromise } = useOperationInvoker();
48
48
  const handleCloseCompanion = useCallback(() => {
49
49
  invariant(primary);
50
- return dispatch(createIntent(DeckAction.ChangeCompanion, { primary, companion: null }));
51
- }, []);
50
+ return invokePromise(DeckOperation.ChangeCompanion, { primary, companion: null });
51
+ }, [invokePromise, primary]);
52
52
  return (
53
53
  <div ref={forwardedRef} className='contents app-no-drag'>
54
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,17 +4,18 @@
4
4
 
5
5
  import React, { Fragment, type MouseEvent, memo, useCallback, useEffect, useMemo } from 'react';
6
6
 
7
- import { LayoutAction, Surface, createIntent, useAppGraph, useIntentDispatcher } from '@dxos/app-framework';
8
- import { type Node } from '@dxos/plugin-graph';
7
+ import { Common } from '@dxos/app-framework';
8
+ import { Surface, useAppGraph, useOperationInvoker } from '@dxos/app-framework/react';
9
+ import { Graph, type Node, useActionRunner } from '@dxos/plugin-graph';
9
10
  import { Icon, IconButton, Popover, toLocalizedString, useTranslation } from '@dxos/react-ui';
10
11
  import { StackItem, type StackItemSigilAction } from '@dxos/react-ui-stack';
11
12
  import { TextTooltip } from '@dxos/react-ui-text-tooltip';
12
- import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
13
+ import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/ui-theme';
13
14
 
14
15
  import { useBreakpoints } from '../../hooks';
15
16
  import { parseEntryId } from '../../layout';
16
17
  import { meta } from '../../meta';
17
- import { DeckAction, type LayoutMode, PLANK_COMPANION_TYPE, type ResolvedPart } from '../../types';
18
+ import { DeckOperation, type LayoutMode, PLANK_COMPANION_TYPE, type ResolvedPart } from '../../types';
18
19
  import { soloInlinePadding } from '../fragments';
19
20
 
20
21
  import { PlankCompanionControls, PlankControls } from './PlankControls';
@@ -25,7 +26,7 @@ export type PlankHeadingProps = {
25
26
  id: string;
26
27
  part: ResolvedPart;
27
28
  layoutMode?: LayoutMode;
28
- node?: Node;
29
+ node?: Node.Node;
29
30
  deckEnabled?: boolean;
30
31
  canIncrementStart?: boolean;
31
32
  canIncrementEnd?: boolean;
@@ -33,7 +34,7 @@ export type PlankHeadingProps = {
33
34
  primaryId?: string;
34
35
  pending?: boolean;
35
36
  companioned?: 'primary' | 'companion';
36
- companions?: Node[];
37
+ companions?: Node.Node[];
37
38
  actions?: StackItemSigilAction[];
38
39
  };
39
40
 
@@ -54,7 +55,8 @@ export const PlankHeading = memo(
54
55
  actions = [],
55
56
  }: PlankHeadingProps) => {
56
57
  const { t } = useTranslation(meta.id);
57
- const { dispatchPromise: dispatch } = useIntentDispatcher();
58
+ const { invokePromise, invokeSync } = useOperationInvoker();
59
+ const runAction = useActionRunner();
58
60
  const { graph } = useAppGraph();
59
61
  const breakpoint = useBreakpoints();
60
62
  const icon = node?.properties?.icon ?? 'ph--placeholder--regular';
@@ -68,7 +70,7 @@ export const PlankHeading = memo(
68
70
  const frame = requestAnimationFrame(() => {
69
71
  // Load actions for the node.
70
72
  if (node) {
71
- void graph.expand(node.id);
73
+ void Graph.expand(graph, node.id);
72
74
  }
73
75
  });
74
76
 
@@ -97,42 +99,37 @@ export const PlankHeading = memo(
97
99
  } else {
98
100
  return [
99
101
  actions,
100
- graph
101
- .getActions(node.id)
102
- .filter((a) => ['list-item', 'list-item-primary', 'heading-list-item'].includes(a.properties.disposition)),
102
+ Graph.getActions(graph, node.id).filter((a) =>
103
+ ['list-item', 'list-item-primary', 'heading-list-item'].includes(a.properties.disposition),
104
+ ),
103
105
  ].filter((a) => a.length > 0);
104
106
  }
105
107
  }, [actions, node, variant, graph]);
106
108
 
107
109
  const handleAction = useCallback(
108
110
  (action: StackItemSigilAction) => {
109
- typeof action.data === 'function' && void action.data?.({ parent: node, caller: meta.id });
111
+ if (typeof action.data === 'function') {
112
+ void runAction(action as Node.Action, { parent: node, caller: meta.id });
113
+ }
110
114
  },
111
- [node],
115
+ [node, runAction],
112
116
  );
113
117
 
114
118
  const handlePlankAction = useCallback(
115
- (eventType: DeckAction.PartAdjustment) => {
119
+ (eventType: DeckOperation.PartAdjustment) => {
116
120
  if (eventType.startsWith('solo')) {
117
- return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
121
+ return invokePromise(DeckOperation.Adjust, { type: eventType, id });
118
122
  } else if (eventType === 'close') {
119
123
  if (part === 'complementary') {
120
- return dispatch(
121
- createIntent(LayoutAction.UpdateComplementary, {
122
- part: 'complementary',
123
- options: { state: 'collapsed' },
124
- }),
125
- );
124
+ return invokeSync(Common.LayoutOperation.UpdateComplementary, { state: 'collapsed' });
126
125
  } else {
127
- return dispatch(
128
- createIntent(LayoutAction.Close, { part: 'main', subject: [id], options: { state: false } }),
129
- );
126
+ return invokeSync(Common.LayoutOperation.Close, { subject: [id] });
130
127
  }
131
128
  } else {
132
- return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
129
+ return invokePromise(DeckOperation.Adjust, { type: eventType, id });
133
130
  }
134
131
  },
135
- [dispatch, id, part],
132
+ [invokePromise, invokeSync, id, part],
136
133
  );
137
134
 
138
135
  const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${meta.id}/${node.id}` ? Popover.Anchor : Fragment;
@@ -142,15 +139,13 @@ export const PlankHeading = memo(
142
139
  const target = (event.target as HTMLElement).closest('[data-id]') as HTMLElement | null;
143
140
  const tabId = target?.dataset?.id;
144
141
  if (primaryId && tabId) {
145
- void dispatch(
146
- createIntent(DeckAction.ChangeCompanion, {
147
- primary: primaryId,
148
- companion: tabId,
149
- }),
150
- );
142
+ void invokePromise(DeckOperation.ChangeCompanion, {
143
+ primary: primaryId,
144
+ companion: tabId,
145
+ });
151
146
  }
152
147
  },
153
- [primaryId],
148
+ [primaryId, invokePromise],
154
149
  );
155
150
 
156
151
  return (
@@ -179,7 +174,6 @@ export const PlankHeading = memo(
179
174
  icon={icon}
180
175
  iconOnly={companions.length > MAX_COMPANIONS && node?.id !== id}
181
176
  label={toLocalizedString(label, t)}
182
- size={5}
183
177
  variant={node?.id === id ? 'primary' : 'ghost'}
184
178
  onClick={handleTabClick}
185
179
  />
@@ -202,7 +196,7 @@ export const PlankHeading = memo(
202
196
  ) : (
203
197
  <StackItem.SigilButton>
204
198
  <span className='sr-only'>{label}</span>
205
- <Icon icon={icon} size={5} />
199
+ <Icon icon={icon} />
206
200
  </StackItem.SigilButton>
207
201
  )}
208
202
  </ActionRoot>
@@ -12,12 +12,20 @@ import React, {
12
12
  useState,
13
13
  } from 'react';
14
14
 
15
- import { LayoutAction, Surface, createIntent, useCapability, useIntentDispatcher } from '@dxos/app-framework';
15
+ import { Common } from '@dxos/app-framework';
16
+ import { Surface, useOperationInvoker } from '@dxos/app-framework/react';
16
17
  import { IconButton, type Label, Main, toLocalizedString, useTranslation } from '@dxos/react-ui';
17
18
  import { Tabs } from '@dxos/react-ui-tabs';
18
-
19
- import { DeckCapabilities } from '../../capabilities';
20
- 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';
21
29
  import { meta } from '../../meta';
22
30
  import { getMode } from '../../types';
23
31
  import { layoutAppliesTopbar } from '../../util';
@@ -33,9 +41,9 @@ export type ComplementarySidebarProps = {
33
41
 
34
42
  export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) => {
35
43
  const { t } = useTranslation(meta.id);
36
- const { dispatchPromise: dispatch } = useIntentDispatcher();
37
- const layout = useCapability(DeckCapabilities.MutableDeckState);
38
- const layoutMode = getMode(layout.deck);
44
+ const { invokeSync } = useOperationInvoker();
45
+ const { state, deck, updateState } = useDeckState();
46
+ const layoutMode = getMode(deck);
39
47
  const breakpoint = useBreakpoints();
40
48
  const topbar = layoutAppliesTopbar(breakpoint, layoutMode);
41
49
  const hoistStatusbar = useHoistStatusbar(breakpoint, layoutMode);
@@ -53,14 +61,17 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
53
61
  (event: MouseEvent) => {
54
62
  const nextValue = event.currentTarget.getAttribute('data-value') as string;
55
63
  if (nextValue === activeId) {
56
- layout.complementarySidebarState = layout.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded';
64
+ updateState((s) => ({
65
+ ...s,
66
+ complementarySidebarState: s.complementarySidebarState === 'expanded' ? 'collapsed' : 'expanded',
67
+ }));
57
68
  } else {
58
69
  setInternalValue(nextValue);
59
- layout.complementarySidebarState = 'expanded';
60
- void dispatch(createIntent(LayoutAction.UpdateComplementary, { part: 'complementary', subject: nextValue }));
70
+ updateState((s) => ({ ...s, complementarySidebarState: 'expanded' }));
71
+ invokeSync(Common.LayoutOperation.UpdateComplementary, { subject: nextValue });
61
72
  }
62
73
  },
63
- [layout, activeId, dispatch],
74
+ [state.complementarySidebarState, activeId, invokeSync, updateState],
64
75
  );
65
76
 
66
77
  const data = useMemo(
@@ -74,11 +85,9 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
74
85
 
75
86
  useEffect(() => {
76
87
  if (!activeId) {
77
- void dispatch(
78
- createIntent(LayoutAction.UpdateComplementary, { part: 'complementary', options: { state: 'collapsed' } }),
79
- );
88
+ invokeSync(Common.LayoutOperation.UpdateComplementary, { state: 'collapsed' });
80
89
  }
81
- }, [activeId, dispatch]);
90
+ }, [activeId, invokeSync]);
82
91
 
83
92
  return (
84
93
  <Main.ComplementarySidebar
@@ -91,7 +100,11 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
91
100
  <Tabs.Root orientation='vertical' verticalVariant='stateless' value={internalValue} classNames='contents'>
92
101
  <div
93
102
  role='none'
94
- className='absolute z-[1] inset-block-0 inline-end-0 !is-[--r0-size] pbs-[env(safe-area-inset-top)] pbe-[env(safe-area-inset-bottom)] border-is border-subduedSeparator grid grid-cols-1 grid-rows-[1fr_min-content] bg-baseSurface contain-layout app-drag'
103
+ className={mx(
104
+ 'absolute z-[1] inset-block-0 inline-end-0 !is-[--r0-size]',
105
+ 'pbs-[env(safe-area-inset-top)] pbe-[env(safe-area-inset-bottom)] border-is border-subduedSeparator',
106
+ 'grid grid-cols-1 grid-rows-[1fr_min-content] bg-baseSurface contain-layout app-drag',
107
+ )}
95
108
  >
96
109
  <Tabs.Tablist classNames='grid grid-cols-1 auto-rows-[--rail-action] p-1 gap-1 !overflow-y-auto'>
97
110
  {companions.map((companion) => (
@@ -99,13 +112,12 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
99
112
  <IconButton
100
113
  label={toLocalizedString(companion.properties.label, t)}
101
114
  icon={companion.properties.icon}
102
- size={5}
103
115
  iconOnly
104
116
  tooltipSide='left'
105
117
  data-value={getCompanionId(companion.id)}
106
118
  variant={
107
119
  activeId === getCompanionId(companion.id)
108
- ? layout.complementarySidebarState === 'expanded'
120
+ ? state.complementarySidebarState === 'expanded'
109
121
  ? 'primary'
110
122
  : 'default'
111
123
  : 'ghost'
@@ -129,8 +141,12 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
129
141
  <Tabs.Tabpanel
130
142
  key={getCompanionId(companion.id)}
131
143
  value={getCompanionId(companion.id)}
132
- classNames='absolute data-[state="inactive"]:-z-[1] inset-block-0 inline-start-0 is-[calc(100%-var(--r0-size))] lg:is-[--r1-size] grid grid-cols-1 grid-rows-[var(--rail-size)_1fr_min-content] pbs-[env(safe-area-inset-top)]'
133
- {...(layout.complementarySidebarState !== 'expanded' && { inert: true })}
144
+ classNames={[
145
+ 'absolute data-[state="inactive"]:-z-[1] overflow-hidden',
146
+ 'inset-block-0 inline-start-0 is-[calc(100%-var(--r0-size))] lg:is-[--r1-size]',
147
+ 'grid grid-cols-1 grid-rows-[var(--rail-size)_1fr_min-content] pbs-[env(safe-area-inset-top)]',
148
+ ]}
149
+ {...(state.complementarySidebarState !== 'expanded' && { inert: true })}
134
150
  >
135
151
  <ComplementarySidebarPanel
136
152
  companion={companion}
@@ -155,10 +171,6 @@ type ComplementarySidebarPanelProps = {
155
171
  hoistStatusbar: boolean;
156
172
  };
157
173
 
158
- const ScrollArea = ({ children }: PropsWithChildren) => {
159
- return <div className='flex flex-col grow overflow-x-hidden overflow-y-auto scrollbar-thin'>{children}</div>;
160
- };
161
-
162
174
  const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }: ComplementarySidebarPanelProps) => {
163
175
  const { t } = useTranslation(meta.id);
164
176
 
@@ -170,9 +182,20 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
170
182
 
171
183
  return (
172
184
  <>
173
- <h2 className='flex items-center pli-2 border-subduedSeparator border-be font-medium'>
174
- {toLocalizedString(companion.properties.label, t)}
175
- </h2>
185
+ <div role='none' className='flex items-center p-1 gap-1 border-be border-subduedSeparator'>
186
+ <IconButton
187
+ label={toLocalizedString(companion.properties.label, t)}
188
+ icon={companion.properties.icon}
189
+ iconOnly
190
+ tooltipSide='left'
191
+ data-value={getCompanionId(companion.id)}
192
+ classNames='bs-10 is-10'
193
+ variant='default'
194
+ />
195
+ <div role='none' className='pli-1'>
196
+ {toLocalizedString(companion.properties.label, t)}
197
+ </div>
198
+ </div>
176
199
  <Wrapper>
177
200
  <Surface
178
201
  role={`deck-companion--${getCompanionId(companion.id)}`}
@@ -192,3 +215,7 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
192
215
  </>
193
216
  );
194
217
  };
218
+
219
+ const ScrollArea = ({ children }: PropsWithChildren) => {
220
+ return <div className='flex flex-col grow overflow-x-hidden overflow-y-auto scrollbar-thin'>{children}</div>;
221
+ };
@@ -4,11 +4,10 @@
4
4
 
5
5
  import React, { useMemo } from 'react';
6
6
 
7
- import { Surface, useCapability } from '@dxos/app-framework';
7
+ import { Surface } from '@dxos/app-framework/react';
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);