@dxos/plugin-deck 0.8.4-main.406dc2a → 0.8.4-main.52d7546f51

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 (280) 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-7I6H3N4Q.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 +82 -74
  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-VRD54KY3.mjs +54 -0
  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/toolkit.d.ts +27 -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/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 +2 -1
  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 +24 -5
  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 +2 -1
  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/toolkit.ts +64 -0
  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 +20 -32
  184. package/src/components/DeckLayout/DeckLayout.tsx +13 -11
  185. package/src/components/DeckLayout/DeckMain.tsx +46 -45
  186. package/src/components/DeckLayout/Dialog.tsx +21 -12
  187. package/src/components/DeckLayout/Fallback.tsx +2 -2
  188. package/src/components/DeckLayout/Popover.tsx +60 -32
  189. package/src/components/DeckLayout/StatusBar.tsx +3 -3
  190. package/src/components/DeckLayout/Toast.tsx +5 -5
  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 +70 -53
  194. package/src/components/Plank/PlankControls.tsx +6 -6
  195. package/src/components/Plank/PlankError.tsx +2 -2
  196. package/src/components/Plank/PlankHeading.tsx +34 -38
  197. package/src/components/Sidebar/ComplementarySidebar.tsx +63 -32
  198. package/src/components/Sidebar/Sidebar.tsx +5 -5
  199. package/src/components/Sidebar/SidebarButton.tsx +35 -28
  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 -4
  204. package/src/hooks/useDeckState.ts +82 -0
  205. package/src/hooks/useHoistStatusbar.ts +3 -5
  206. package/src/hooks/useNodeActionExpander.ts +4 -4
  207. package/src/index.ts +1 -2
  208. package/src/meta.ts +7 -2
  209. package/src/translations.ts +2 -1
  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-YYP67JHW.mjs +0 -153
  217. package/dist/lib/browser/app-graph-builder-YYP67JHW.mjs.map +0 -7
  218. package/dist/lib/browser/check-app-scheme-GCOL6YDT.mjs +0 -32
  219. package/dist/lib/browser/check-app-scheme-GCOL6YDT.mjs.map +0 -7
  220. package/dist/lib/browser/chunk-7I6H3N4Q.mjs.map +0 -7
  221. package/dist/lib/browser/chunk-CNTGBCMK.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-HUWUYTOI.mjs +0 -16
  223. package/dist/lib/browser/chunk-HUWUYTOI.mjs.map +0 -7
  224. package/dist/lib/browser/chunk-JQKOS2HB.mjs +0 -1531
  225. package/dist/lib/browser/chunk-JQKOS2HB.mjs.map +0 -7
  226. package/dist/lib/browser/chunk-MHP4GPX5.mjs +0 -11
  227. package/dist/lib/browser/chunk-MHP4GPX5.mjs.map +0 -7
  228. package/dist/lib/browser/chunk-RJP5R7PY.mjs +0 -127
  229. package/dist/lib/browser/chunk-RJP5R7PY.mjs.map +0 -7
  230. package/dist/lib/browser/chunk-VX7MMQOW.mjs +0 -129
  231. package/dist/lib/browser/chunk-VX7MMQOW.mjs.map +0 -7
  232. package/dist/lib/browser/intent-resolver-7XNOEPVN.mjs +0 -524
  233. package/dist/lib/browser/intent-resolver-7XNOEPVN.mjs.map +0 -7
  234. package/dist/lib/browser/react-root-OJEF7YCH.mjs +0 -43
  235. package/dist/lib/browser/react-root-OJEF7YCH.mjs.map +0 -7
  236. package/dist/lib/browser/react-surface-XN2NJYHO.mjs +0 -40
  237. package/dist/lib/browser/react-surface-XN2NJYHO.mjs.map +0 -7
  238. package/dist/lib/browser/settings-M3KSKRAP.mjs +0 -30
  239. package/dist/lib/browser/settings-M3KSKRAP.mjs.map +0 -7
  240. package/dist/lib/browser/state-6ZSDTF6Q.mjs +0 -12
  241. package/dist/lib/browser/toolkit-L7C3UAEU.mjs +0 -63
  242. package/dist/lib/browser/toolkit-L7C3UAEU.mjs.map +0 -7
  243. package/dist/lib/browser/url-handler-EHTLXZRR.mjs +0 -70
  244. package/dist/lib/browser/url-handler-EHTLXZRR.mjs.map +0 -7
  245. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  246. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  247. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  248. package/dist/types/src/capabilities/check-app-scheme.d.ts +0 -4
  249. package/dist/types/src/capabilities/check-app-scheme.d.ts.map +0 -1
  250. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  251. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  252. package/dist/types/src/capabilities/react-root.d.ts +0 -7
  253. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  254. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  255. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  256. package/dist/types/src/capabilities/settings.d.ts +0 -4
  257. package/dist/types/src/capabilities/settings.d.ts.map +0 -1
  258. package/dist/types/src/capabilities/state.d.ts +0 -104
  259. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  260. package/dist/types/src/capabilities/toolkit.d.ts +0 -6
  261. package/dist/types/src/capabilities/toolkit.d.ts.map +0 -1
  262. package/dist/types/src/capabilities/tools.d.ts +0 -11
  263. package/dist/types/src/capabilities/tools.d.ts.map +0 -1
  264. package/dist/types/src/capabilities/url-handler.d.ts +0 -4
  265. package/dist/types/src/capabilities/url-handler.d.ts.map +0 -1
  266. package/dist/types/src/events.d.ts +0 -4
  267. package/dist/types/src/events.d.ts.map +0 -1
  268. package/src/capabilities/app-graph-builder.ts +0 -143
  269. package/src/capabilities/capabilities.ts +0 -14
  270. package/src/capabilities/check-app-scheme.ts +0 -40
  271. package/src/capabilities/intent-resolver.ts +0 -472
  272. package/src/capabilities/react-root.tsx +0 -39
  273. package/src/capabilities/react-surface.tsx +0 -30
  274. package/src/capabilities/settings.ts +0 -27
  275. package/src/capabilities/state.ts +0 -108
  276. package/src/capabilities/toolkit.ts +0 -57
  277. package/src/capabilities/tools.ts +0 -84
  278. package/src/capabilities/url-handler.ts +0 -60
  279. package/src/events.ts +0 -11
  280. /package/dist/lib/{browser/state-6ZSDTF6Q.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,18 @@ 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 { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
17
+ import { LayoutOperation } from '@dxos/app-toolkit';
18
+ import { useAppGraph } from '@dxos/app-toolkit/ui';
23
19
  import { debounce } from '@dxos/async';
24
20
  import { type Node, useNode } from '@dxos/plugin-graph';
25
21
  import { ATTENDABLE_PATH_SEPARATOR, useAttentionAttributes } from '@dxos/react-ui-attention';
26
22
  import { StackItem, railGridHorizontal } from '@dxos/react-ui-stack';
27
- import { mainIntrinsicSize, mx } from '@dxos/react-ui-theme';
23
+ import { mainIntrinsicSize, mx } from '@dxos/ui-theme';
28
24
 
29
- import { DeckCapabilities } from '../../capabilities';
30
- import { useCompanions, useMainSize } from '../../hooks';
25
+ import { useCompanions, useDeckState, useMainSize } from '../../hooks';
31
26
  import { parseEntryId } from '../../layout';
32
- import { DeckAction, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
27
+ import { DeckOperation, type DeckSettingsProps, type LayoutMode, type ResolvedPart } from '../../types';
33
28
 
34
29
  import { PlankContentError, PlankError } from './PlankError';
35
30
  import { PlankHeading } from './PlankHeading';
@@ -37,6 +32,10 @@ import { PlankLoading } from './PlankLoading';
37
32
 
38
33
  const UNKNOWN_ID = 'unknown_id';
39
34
 
35
+ //
36
+ // Plank
37
+ //
38
+
40
39
  export type PlankProps = Pick<PlankComponentProps, 'layoutMode' | 'part' | 'path' | 'order' | 'active' | 'settings'> & {
41
40
  id?: string;
42
41
  companionId?: string;
@@ -50,10 +49,10 @@ export type PlankProps = Pick<PlankComponentProps, 'layoutMode' | 'part' | 'path
50
49
  // benefits. I think where we anticipate users will definitely want to quickly switch between showing and hiding entire
51
50
  // articles, over the (again probably large) performance benefit that unmounting them would confer, we can mount and
52
51
  // 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
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
55
54
  // 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
55
+ // "partially-mounted" experiences, like loading skeletons at the simple end, or screenshots of "sleeping" planks at
57
56
  // the advanced end.
58
57
 
59
58
  /**
@@ -96,12 +95,13 @@ export const Plank = memo(({ id = UNKNOWN_ID, companionId, ...props }: PlankProp
96
95
  );
97
96
  });
98
97
 
99
- const PlankContainer = ({
100
- children,
101
- solo,
102
- companion,
103
- encapsulate,
104
- }: PropsWithChildren<{ solo: boolean; companion: boolean; encapsulate: boolean }>) => {
98
+ //
99
+ // PlankContainer
100
+ //
101
+
102
+ type PlankContainerProps = PropsWithChildren<{ solo: boolean; companion: boolean; encapsulate: boolean }>;
103
+
104
+ const PlankContainer = ({ children, solo, companion, encapsulate }: PlankContainerProps) => {
105
105
  const sizeAttrs = useMainSize();
106
106
  if (!solo) {
107
107
  return children;
@@ -111,10 +111,11 @@ const PlankContainer = ({
111
111
  return (
112
112
  <div
113
113
  role='none'
114
+ data-popover-collision-boundary={true}
114
115
  className={mx(
115
116
  'absolute inset-[--main-spacing] grid',
116
117
  encapsulate && 'border border-separator rounded overflow-hidden',
117
- companion && 'grid-cols-[6fr_4fr]',
118
+ companion && 'grid-cols-[6fr_4fr]', // TODO(burdon): Resize.
118
119
  railGridHorizontal,
119
120
  mainIntrinsicSize,
120
121
  )}
@@ -125,6 +126,10 @@ const PlankContainer = ({
125
126
  );
126
127
  };
127
128
 
129
+ //
130
+ // PlankComponent
131
+ //
132
+
128
133
  type PlankComponentProps = {
129
134
  layoutMode: LayoutMode;
130
135
  id: string;
@@ -132,11 +137,10 @@ type PlankComponentProps = {
132
137
  path?: string[];
133
138
  order?: number;
134
139
  active?: string[];
135
- // TODO(burdon): Change to role?
136
140
  companioned?: 'primary' | 'companion';
137
- node?: Node;
138
- primary?: Node;
139
- companions?: Node[];
141
+ node?: Node.Node;
142
+ primary?: Node.Node;
143
+ companions?: Node.Node[];
140
144
  settings?: DeckSettingsProps;
141
145
  };
142
146
 
@@ -154,8 +158,10 @@ const PlankComponent = memo(
154
158
  companions,
155
159
  settings,
156
160
  }: PlankComponentProps) => {
157
- const { dispatchPromise: dispatch } = useIntentDispatcher();
158
- const { deck, popoverAnchorId, scrollIntoView } = useCapability(DeckCapabilities.DeckState);
161
+ const { invokePromise } = useOperationInvoker();
162
+ const { state, deck } = useDeckState();
163
+ const { popoverAnchorId, scrollIntoView } = state;
164
+ const { findFirstFocusable } = useFocusFinders();
159
165
  const canResize = layoutMode === 'deck';
160
166
 
161
167
  const attentionAttrs = useAttentionAttributes(primary?.id ?? id);
@@ -172,15 +178,22 @@ const PlankComponent = memo(
172
178
 
173
179
  const handleSizeChange = useCallback(
174
180
  debounce((nextSize: number) => {
175
- return dispatch(createIntent(DeckAction.UpdatePlankSize, { id: sizeKey, size: nextSize }));
181
+ return invokePromise(DeckOperation.UpdatePlankSize, { id: sizeKey, size: nextSize });
176
182
  }, 200),
177
- [dispatch, sizeKey],
183
+ [invokePromise, sizeKey],
178
184
  );
179
185
 
180
- // 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.
181
187
  const handleKeyDown = useCallback((event: KeyboardEvent) => {
182
- if (event.target === event.currentTarget && event.key === 'Escape') {
183
- rootElement.current?.closest('main')?.focus();
188
+ if (event.target === event.currentTarget) {
189
+ switch (event.key) {
190
+ case 'Escape':
191
+ rootElement.current?.closest('main')?.focus();
192
+ break;
193
+ case 'Enter':
194
+ rootElement.current && findFirstFocusable(rootElement.current)?.focus();
195
+ break;
196
+ }
184
197
  }
185
198
  }, []);
186
199
 
@@ -188,9 +201,9 @@ const PlankComponent = memo(
188
201
  if (scrollIntoView === id) {
189
202
  layoutMode === 'deck' && rootElement.current?.scrollIntoView({ behavior: 'smooth', inline: 'center' });
190
203
  // Clear the scroll into view state once it has been actioned.
191
- void dispatch(createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: undefined }));
204
+ void invokePromise(LayoutOperation.ScrollIntoView, { subject: undefined });
192
205
  }
193
- }, [id, scrollIntoView, layoutMode]);
206
+ }, [id, scrollIntoView, layoutMode, invokePromise]);
194
207
 
195
208
  const isSolo = layoutMode.startsWith('solo') && part === 'solo';
196
209
  const isAttendable =
@@ -216,14 +229,16 @@ const PlankComponent = memo(
216
229
  const placeholder = useMemo(() => <PlankLoading />, []);
217
230
 
218
231
  const Root = part.startsWith('solo') ? 'article' : StackItem.Root;
232
+ const fullscreen = layoutMode === 'solo--fullscreen';
219
233
  const className = mx(
220
234
  'attention-surface relative dx-focus-ring-inset-over-all density-coarse',
221
- isSolo && mainIntrinsicSize,
222
- isSolo && railGridHorizontal,
223
235
  isSolo && 'absolute inset-0',
236
+ isSolo && mainIntrinsicSize,
237
+ railGridHorizontal,
224
238
  part.startsWith('solo') && 'grid',
239
+ part.startsWith('solo-') && 'grid-rows-subgrid row-span-2 min-is-0',
240
+ fullscreen && 'grid-rows-1',
225
241
  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
242
  part === 'solo-companion' && '!border-separator border-is',
228
243
  settings?.encapsulatedPlanks &&
229
244
  !part.startsWith('solo') &&
@@ -234,6 +249,7 @@ const PlankComponent = memo(
234
249
  <Root
235
250
  ref={rootElement}
236
251
  data-testid='deck.plank'
252
+ data-popover-collision-boundary={true}
237
253
  tabIndex={0}
238
254
  {...(part.startsWith('solo')
239
255
  ? ({ ...sizeAttrs, className } as any)
@@ -250,20 +266,22 @@ const PlankComponent = memo(
250
266
  >
251
267
  {node ? (
252
268
  <>
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
- />
266
- <Surface
269
+ {!fullscreen && (
270
+ <PlankHeading
271
+ id={id}
272
+ part={part.startsWith('solo-') ? 'solo' : part}
273
+ node={node}
274
+ layoutMode={layoutMode}
275
+ deckEnabled={settings?.enableDeck}
276
+ canIncrementStart={canIncrementStart}
277
+ canIncrementEnd={canIncrementEnd}
278
+ popoverAnchorId={popoverAnchorId}
279
+ primaryId={primary?.id}
280
+ companioned={companioned}
281
+ companions={companions}
282
+ />
283
+ )}
284
+ <Surface.Surface
267
285
  key={node.id}
268
286
  role='article'
269
287
  data={data}
@@ -275,7 +293,6 @@ const PlankComponent = memo(
275
293
  ) : (
276
294
  <PlankError id={id} part={part} />
277
295
  )}
278
-
279
296
  {canResize && <StackItem.ResizeHandle />}
280
297
  </Root>
281
298
  );
@@ -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/ui';
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,19 @@
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 { 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';
9
11
  import { Icon, IconButton, Popover, toLocalizedString, useTranslation } from '@dxos/react-ui';
10
12
  import { StackItem, type StackItemSigilAction } from '@dxos/react-ui-stack';
11
13
  import { TextTooltip } from '@dxos/react-ui-text-tooltip';
12
- import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/react-ui-theme';
14
+ import { hoverableControls, hoverableFocusedWithinControls } from '@dxos/ui-theme';
13
15
 
14
16
  import { useBreakpoints } from '../../hooks';
15
17
  import { parseEntryId } from '../../layout';
16
18
  import { meta } from '../../meta';
17
- import { DeckAction, type LayoutMode, PLANK_COMPANION_TYPE, type ResolvedPart } from '../../types';
19
+ import { DeckOperation, type LayoutMode, PLANK_COMPANION_TYPE, type ResolvedPart } from '../../types';
18
20
  import { soloInlinePadding } from '../fragments';
19
21
 
20
22
  import { PlankCompanionControls, PlankControls } from './PlankControls';
@@ -25,7 +27,7 @@ export type PlankHeadingProps = {
25
27
  id: string;
26
28
  part: ResolvedPart;
27
29
  layoutMode?: LayoutMode;
28
- node?: Node;
30
+ node?: Node.Node;
29
31
  deckEnabled?: boolean;
30
32
  canIncrementStart?: boolean;
31
33
  canIncrementEnd?: boolean;
@@ -33,7 +35,7 @@ export type PlankHeadingProps = {
33
35
  primaryId?: string;
34
36
  pending?: boolean;
35
37
  companioned?: 'primary' | 'companion';
36
- companions?: Node[];
38
+ companions?: Node.Node[];
37
39
  actions?: StackItemSigilAction[];
38
40
  };
39
41
 
@@ -54,7 +56,8 @@ export const PlankHeading = memo(
54
56
  actions = [],
55
57
  }: PlankHeadingProps) => {
56
58
  const { t } = useTranslation(meta.id);
57
- const { dispatchPromise: dispatch } = useIntentDispatcher();
59
+ const { invokePromise, invokeSync } = useOperationInvoker();
60
+ const runAction = useActionRunner();
58
61
  const { graph } = useAppGraph();
59
62
  const breakpoint = useBreakpoints();
60
63
  const icon = node?.properties?.icon ?? 'ph--placeholder--regular';
@@ -68,7 +71,7 @@ export const PlankHeading = memo(
68
71
  const frame = requestAnimationFrame(() => {
69
72
  // Load actions for the node.
70
73
  if (node) {
71
- void graph.expand(node.id);
74
+ void Graph.expand(graph, node.id);
72
75
  }
73
76
  });
74
77
 
@@ -97,42 +100,37 @@ export const PlankHeading = memo(
97
100
  } else {
98
101
  return [
99
102
  actions,
100
- graph
101
- .getActions(node.id)
102
- .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
+ ),
103
106
  ].filter((a) => a.length > 0);
104
107
  }
105
108
  }, [actions, node, variant, graph]);
106
109
 
107
110
  const handleAction = useCallback(
108
111
  (action: StackItemSigilAction) => {
109
- 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
+ }
110
115
  },
111
- [node],
116
+ [node, runAction],
112
117
  );
113
118
 
114
119
  const handlePlankAction = useCallback(
115
- (eventType: DeckAction.PartAdjustment) => {
120
+ (eventType: DeckOperation.PartAdjustment) => {
116
121
  if (eventType.startsWith('solo')) {
117
- return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
122
+ return invokePromise(DeckOperation.Adjust, { type: eventType, id });
118
123
  } else if (eventType === 'close') {
119
124
  if (part === 'complementary') {
120
- return dispatch(
121
- createIntent(LayoutAction.UpdateComplementary, {
122
- part: 'complementary',
123
- options: { state: 'collapsed' },
124
- }),
125
- );
125
+ return invokeSync(LayoutOperation.UpdateComplementary, { state: 'collapsed' });
126
126
  } else {
127
- return dispatch(
128
- createIntent(LayoutAction.Close, { part: 'main', subject: [id], options: { state: false } }),
129
- );
127
+ return invokeSync(LayoutOperation.Close, { subject: [id] });
130
128
  }
131
129
  } else {
132
- return dispatch(createIntent(DeckAction.Adjust, { type: eventType, id }));
130
+ return invokePromise(DeckOperation.Adjust, { type: eventType, id });
133
131
  }
134
132
  },
135
- [dispatch, id, part],
133
+ [invokePromise, invokeSync, id, part],
136
134
  );
137
135
 
138
136
  const ActionRoot = node && popoverAnchorId === `dxos.org/ui/${meta.id}/${node.id}` ? Popover.Anchor : Fragment;
@@ -142,15 +140,13 @@ export const PlankHeading = memo(
142
140
  const target = (event.target as HTMLElement).closest('[data-id]') as HTMLElement | null;
143
141
  const tabId = target?.dataset?.id;
144
142
  if (primaryId && tabId) {
145
- void dispatch(
146
- createIntent(DeckAction.ChangeCompanion, {
147
- primary: primaryId,
148
- companion: tabId,
149
- }),
150
- );
143
+ void invokePromise(DeckOperation.ChangeCompanion, {
144
+ primary: primaryId,
145
+ companion: tabId,
146
+ });
151
147
  }
152
148
  },
153
- [primaryId],
149
+ [primaryId, invokePromise],
154
150
  );
155
151
 
156
152
  return (
@@ -162,7 +158,8 @@ export const PlankHeading = memo(
162
158
  ? [
163
159
  hoverableControls,
164
160
  hoverableFocusedWithinControls,
165
- '*:transition-opacity *:opacity-[--controls-opacity] bg-transparent border-transparent transition-[background-color,border-color] hover-hover:hover:bg-headerSurface focus-within:bg-headerSurface hover-hover:hover:border-subduedSeparator focus-within:border-subduedSeparator',
161
+ '*:transition-opacity *:opacity-[--controls-opacity] bg-transparent border-transparent transition-[background-color,border-color]',
162
+ 'hover-hover:hover:bg-headerSurface focus-within:bg-headerSurface hover-hover:hover:border-subduedSeparator focus-within:border-subduedSeparator',
166
163
  ]
167
164
  : []),
168
165
  ]}
@@ -178,7 +175,6 @@ export const PlankHeading = memo(
178
175
  icon={icon}
179
176
  iconOnly={companions.length > MAX_COMPANIONS && node?.id !== id}
180
177
  label={toLocalizedString(label, t)}
181
- size={5}
182
178
  variant={node?.id === id ? 'primary' : 'ghost'}
183
179
  onClick={handleTabClick}
184
180
  />
@@ -196,12 +192,12 @@ export const PlankHeading = memo(
196
192
  actions={sigilActions}
197
193
  onAction={handleAction}
198
194
  >
199
- <Surface role='menu-footer' data={{ subject: node.data }} />
195
+ <Surface.Surface role='menu-footer' data={{ subject: node.data }} />
200
196
  </StackItem.Sigil>
201
197
  ) : (
202
198
  <StackItem.SigilButton>
203
199
  <span className='sr-only'>{label}</span>
204
- <Icon icon={icon} size={5} />
200
+ <Icon icon={icon} />
205
201
  </StackItem.SigilButton>
206
202
  )}
207
203
  </ActionRoot>
@@ -216,7 +212,7 @@ export const PlankHeading = memo(
216
212
  </TextTooltip>
217
213
  </>
218
214
  )}
219
- {node && part !== 'complementary' && <Surface role='navbar-end' data={{ subject: node.data }} />}
215
+ {node && part !== 'complementary' && <Surface.Surface role='navbar-end' data={{ subject: node.data }} />}
220
216
  {companioned === 'companion' ? (
221
217
  <PlankCompanionControls primary={primaryId} />
222
218
  ) : (
@@ -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';
16
- 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';
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((state) => ({
65
+ ...state,
66
+ complementarySidebarState: state.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((state) => ({ ...state, complementarySidebarState: 'expanded' }));
71
+ invokeSync(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(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'
@@ -117,7 +129,7 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
117
129
  </Tabs.Tablist>
118
130
  {!hoistStatusbar && (
119
131
  <div role='none' className='grid grid-cols-1 auto-rows-[--rail-item] p-1 overflow-y-auto'>
120
- <Surface role='status-bar--r0-footer' limit={1} />
132
+ <Surface.Surface role='status-bar--r0-footer' limit={1} />
121
133
  </div>
122
134
  )}
123
135
  <div role='none' className='hidden lg:grid grid-cols-1 auto-rows-[--rail-action] p-1'>
@@ -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
 
@@ -166,15 +178,26 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
166
178
  return null;
167
179
  }
168
180
 
169
- const Wrapper = companion.properties.fixed ? Fragment : ScrollArea;
181
+ const Wrapper = companion.properties.fixed ? Fragment : ScrollAreaWrapper;
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
- <Surface
200
+ <Surface.Surface
178
201
  role={`deck-companion--${getCompanionId(companion.id)}`}
179
202
  data={data}
180
203
  fallback={PlankContentError}
@@ -186,9 +209,17 @@ const ComplementarySidebarPanel = ({ companion, activeId, data, hoistStatusbar }
186
209
  role='contentinfo'
187
210
  className='flex flex-wrap justify-center items-center border-bs border-subduedSeparator pbs-1 pbe-[max(env(safe-area-inset-bottom),0.25rem)]'
188
211
  >
189
- <Surface role='status-bar--r1-footer' limit={1} />
212
+ <Surface.Surface role='status-bar--r1-footer' limit={1} />
190
213
  </div>
191
214
  )}
192
215
  </>
193
216
  );
194
217
  };
218
+
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
+ );
225
+ };