@dxos/plugin-deck 0.8.4-main.b97322e → 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 (277) 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-57U62A3A.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-F5BQOOEG.mjs → chunk-ATFPDN6J.mjs} +155 -23
  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 +79 -67
  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/Banner.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 +2 -3
  108. package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
  109. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts +74 -0
  110. package/dist/types/src/components/DeckLayout/DeckLayout.stories.d.ts.map +1 -0
  111. package/dist/types/src/components/DeckLayout/DeckMain.d.ts +3 -0
  112. package/dist/types/src/components/DeckLayout/DeckMain.d.ts.map +1 -0
  113. package/dist/types/src/components/DeckLayout/Dialog.d.ts.map +1 -1
  114. package/dist/types/src/components/DeckLayout/Popover.d.ts.map +1 -1
  115. package/dist/types/src/components/DeckLayout/Toast.d.ts +7 -2
  116. package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
  117. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts +4 -2
  118. package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -1
  119. package/dist/types/src/components/Plank/Plank.d.ts +4 -4
  120. package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
  121. package/dist/types/src/components/Plank/Plank.stories.d.ts +104 -5
  122. package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -1
  123. package/dist/types/src/components/Plank/PlankControls.d.ts +1 -1
  124. package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -1
  125. package/dist/types/src/components/Plank/PlankError.d.ts +1 -1
  126. package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -1
  127. package/dist/types/src/components/Plank/PlankHeading.d.ts +3 -3
  128. package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
  129. package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
  130. package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -1
  131. package/dist/types/src/components/Sidebar/SidebarButton.d.ts.map +1 -1
  132. package/dist/types/src/hooks/index.d.ts +1 -0
  133. package/dist/types/src/hooks/index.d.ts.map +1 -1
  134. package/dist/types/src/hooks/useDeckCompanions.d.ts +3 -3
  135. package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -1
  136. package/dist/types/src/hooks/useDeckState.d.ts +17 -0
  137. package/dist/types/src/hooks/useDeckState.d.ts.map +1 -0
  138. package/dist/types/src/hooks/useHoistStatusbar.d.ts +1 -1
  139. package/dist/types/src/hooks/useHoistStatusbar.d.ts.map +1 -1
  140. package/dist/types/src/hooks/useNodeActionExpander.d.ts +1 -1
  141. package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -1
  142. package/dist/types/src/index.d.ts +1 -2
  143. package/dist/types/src/index.d.ts.map +1 -1
  144. package/dist/types/src/meta.d.ts +2 -3
  145. package/dist/types/src/meta.d.ts.map +1 -1
  146. package/dist/types/src/translations.d.ts +3 -1
  147. package/dist/types/src/translations.d.ts.map +1 -1
  148. package/dist/types/src/{capabilities → types}/capabilities.d.ts +96 -90
  149. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  150. package/dist/types/src/types/events.d.ts +7 -0
  151. package/dist/types/src/types/events.d.ts.map +1 -0
  152. package/dist/types/src/types/index.d.ts +2 -0
  153. package/dist/types/src/types/index.d.ts.map +1 -1
  154. package/dist/types/src/types/schema.d.ts +90 -30
  155. package/dist/types/src/types/schema.d.ts.map +1 -1
  156. package/dist/types/src/util/set-active.d.ts +18 -3
  157. package/dist/types/src/util/set-active.d.ts.map +1 -1
  158. package/dist/types/tsconfig.tsbuildinfo +1 -1
  159. package/package.json +56 -46
  160. package/src/DeckPlugin.ts +45 -61
  161. package/src/capabilities/app-graph-builder/app-graph-builder.ts +118 -0
  162. package/src/capabilities/app-graph-builder/index.ts +7 -0
  163. package/src/capabilities/{check-app-scheme.ts → check-app-scheme/check-app-scheme.ts} +12 -11
  164. package/src/capabilities/check-app-scheme/index.ts +7 -0
  165. package/src/capabilities/index.ts +9 -13
  166. package/src/capabilities/operation-resolver/index.ts +10 -0
  167. package/src/capabilities/operation-resolver/operation-resolver.ts +555 -0
  168. package/src/capabilities/react-root/index.ts +7 -0
  169. package/src/capabilities/react-root/react-root.tsx +47 -0
  170. package/src/capabilities/react-surface/index.ts +7 -0
  171. package/src/capabilities/react-surface/react-surface.tsx +37 -0
  172. package/src/capabilities/settings/index.ts +7 -0
  173. package/src/capabilities/settings/settings.ts +38 -0
  174. package/src/capabilities/state/index.ts +7 -0
  175. package/src/capabilities/state/state.ts +104 -0
  176. package/src/capabilities/toolkit/index.ts +7 -0
  177. package/src/capabilities/toolkit/toolkit.ts +63 -0
  178. package/src/capabilities/tools/index.ts +7 -0
  179. package/src/capabilities/tools/tools.ts +92 -0
  180. package/src/capabilities/url-handler/index.ts +7 -0
  181. package/src/capabilities/url-handler/url-handler.ts +95 -0
  182. package/src/components/DeckLayout/ActiveNode.tsx +1 -1
  183. package/src/components/DeckLayout/Banner.tsx +6 -6
  184. package/src/components/DeckLayout/ContentEmpty.tsx +4 -5
  185. package/src/components/DeckLayout/DeckLayout.stories.tsx +51 -0
  186. package/src/components/DeckLayout/DeckLayout.tsx +18 -285
  187. package/src/components/DeckLayout/DeckMain.tsx +286 -0
  188. package/src/components/DeckLayout/Dialog.tsx +13 -10
  189. package/src/components/DeckLayout/Fallback.tsx +4 -4
  190. package/src/components/DeckLayout/Popover.tsx +44 -32
  191. package/src/components/DeckLayout/StatusBar.tsx +1 -1
  192. package/src/components/DeckLayout/Toast.tsx +30 -5
  193. package/src/components/DeckSettings/DeckSettings.tsx +91 -66
  194. package/src/components/Plank/Plank.stories.tsx +23 -16
  195. package/src/components/Plank/Plank.tsx +89 -56
  196. package/src/components/Plank/PlankControls.tsx +9 -9
  197. package/src/components/Plank/PlankError.tsx +5 -4
  198. package/src/components/Plank/PlankHeading.tsx +38 -42
  199. package/src/components/Sidebar/ComplementarySidebar.tsx +61 -33
  200. package/src/components/Sidebar/Sidebar.tsx +6 -6
  201. package/src/components/Sidebar/SidebarButton.tsx +39 -32
  202. package/src/components/fragments.ts +1 -1
  203. package/src/hooks/index.ts +1 -0
  204. package/src/hooks/useCompanions.ts +1 -1
  205. package/src/hooks/useDeckCompanions.ts +7 -5
  206. package/src/hooks/useDeckState.ts +82 -0
  207. package/src/hooks/useHoistStatusbar.ts +4 -5
  208. package/src/hooks/useNodeActionExpander.ts +4 -4
  209. package/src/index.ts +1 -2
  210. package/src/meta.ts +8 -5
  211. package/src/translations.ts +3 -1
  212. package/src/types/capabilities.ts +33 -0
  213. package/src/types/events.ts +20 -0
  214. package/src/types/index.ts +2 -0
  215. package/src/types/schema.ts +86 -14
  216. package/src/util/layoutAppliesTopbar.ts +1 -1
  217. package/src/util/set-active.ts +49 -29
  218. package/dist/lib/browser/app-graph-builder-JTFSDT2I.mjs +0 -152
  219. package/dist/lib/browser/app-graph-builder-JTFSDT2I.mjs.map +0 -7
  220. package/dist/lib/browser/check-app-scheme-57U62A3A.mjs.map +0 -7
  221. package/dist/lib/browser/chunk-CNTGBCMK.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-D7KTFCUV.mjs +0 -1494
  223. package/dist/lib/browser/chunk-D7KTFCUV.mjs.map +0 -7
  224. package/dist/lib/browser/chunk-F5BQOOEG.mjs.map +0 -7
  225. package/dist/lib/browser/chunk-JFTXENFN.mjs +0 -129
  226. package/dist/lib/browser/chunk-JFTXENFN.mjs.map +0 -7
  227. package/dist/lib/browser/chunk-M57WD3V6.mjs +0 -16
  228. package/dist/lib/browser/chunk-M57WD3V6.mjs.map +0 -7
  229. package/dist/lib/browser/chunk-QDZO4AJ4.mjs +0 -127
  230. package/dist/lib/browser/chunk-QDZO4AJ4.mjs.map +0 -7
  231. package/dist/lib/browser/chunk-Z5KITAZW.mjs +0 -13
  232. package/dist/lib/browser/chunk-Z5KITAZW.mjs.map +0 -7
  233. package/dist/lib/browser/intent-resolver-P2OBK5HK.mjs +0 -521
  234. package/dist/lib/browser/intent-resolver-P2OBK5HK.mjs.map +0 -7
  235. package/dist/lib/browser/react-root-PO64J7ML.mjs +0 -43
  236. package/dist/lib/browser/react-root-PO64J7ML.mjs.map +0 -7
  237. package/dist/lib/browser/react-surface-E45YOVF5.mjs +0 -40
  238. package/dist/lib/browser/react-surface-E45YOVF5.mjs.map +0 -7
  239. package/dist/lib/browser/settings-6AJZPZPM.mjs +0 -29
  240. package/dist/lib/browser/settings-6AJZPZPM.mjs.map +0 -7
  241. package/dist/lib/browser/state-MVDYX77Y.mjs +0 -12
  242. package/dist/lib/browser/tools-TKQDPCHJ.mjs +0 -88
  243. package/dist/lib/browser/tools-TKQDPCHJ.mjs.map +0 -7
  244. package/dist/lib/browser/url-handler-7L7M6IKH.mjs +0 -70
  245. package/dist/lib/browser/url-handler-7L7M6IKH.mjs.map +0 -7
  246. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  247. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  248. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  249. package/dist/types/src/capabilities/check-app-scheme.d.ts +0 -4
  250. package/dist/types/src/capabilities/check-app-scheme.d.ts.map +0 -1
  251. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  252. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  253. package/dist/types/src/capabilities/react-root.d.ts +0 -7
  254. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  255. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  256. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  257. package/dist/types/src/capabilities/settings.d.ts +0 -4
  258. package/dist/types/src/capabilities/settings.d.ts.map +0 -1
  259. package/dist/types/src/capabilities/state.d.ts +0 -101
  260. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  261. package/dist/types/src/capabilities/tools.d.ts +0 -11
  262. package/dist/types/src/capabilities/tools.d.ts.map +0 -1
  263. package/dist/types/src/capabilities/url-handler.d.ts +0 -4
  264. package/dist/types/src/capabilities/url-handler.d.ts.map +0 -1
  265. package/dist/types/src/events.d.ts +0 -4
  266. package/dist/types/src/events.d.ts.map +0 -1
  267. package/src/capabilities/app-graph-builder.ts +0 -141
  268. package/src/capabilities/capabilities.ts +0 -14
  269. package/src/capabilities/intent-resolver.ts +0 -468
  270. package/src/capabilities/react-root.tsx +0 -38
  271. package/src/capabilities/react-surface.tsx +0 -30
  272. package/src/capabilities/settings.ts +0 -26
  273. package/src/capabilities/state.ts +0 -104
  274. package/src/capabilities/tools.ts +0 -81
  275. package/src/capabilities/url-handler.ts +0 -59
  276. package/src/events.ts +0 -11
  277. /package/dist/lib/{browser/state-MVDYX77Y.mjs.map → node-esm/types/index.mjs.map} +0 -0
@@ -3,12 +3,14 @@
3
3
  //
4
4
 
5
5
  import { createContext } from '@radix-ui/react-context';
6
- import React, { type PropsWithChildren, useCallback, useEffect, useMemo, useRef, useState } from 'react';
6
+ import React, { type PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react';
7
7
 
8
- import { Surface, useCapability } from '@dxos/app-framework';
9
- import { Popover, type PopoverContentInteractOutsideEvent } from '@dxos/react-ui';
8
+ import { Surface } from '@dxos/app-framework/react';
9
+ import { Popover, type PopoverContentInteractOutsideEvent, toLocalizedString, useTranslation } from '@dxos/react-ui';
10
+ import { Card } from '@dxos/react-ui-mosaic';
10
11
 
11
- import { DeckCapabilities } from '../../capabilities';
12
+ import { useDeckState } from '../../hooks';
13
+ import { meta } from '../../meta';
12
14
 
13
15
  export type DeckPopoverRootProps = PropsWithChildren<{}>;
14
16
 
@@ -21,32 +23,32 @@ type DeckPopoverContextValue = {
21
23
  const [DeckPopoverProvider, useDeckPopoverContext] = createContext<DeckPopoverContextValue>('DeckPopover');
22
24
 
23
25
  export const PopoverRoot = ({ children }: DeckPopoverRootProps) => {
24
- const layout = useCapability(DeckCapabilities.MutableDeckState);
26
+ const { state } = useDeckState();
25
27
  const virtualRef = useRef<HTMLButtonElement | null>(null);
26
28
  const [virtualIter, setVirtualIter] = useState(0);
27
29
  const [open, setOpen] = useState(false);
28
30
  const debounceRef = useRef<NodeJS.Timeout | null>(null);
29
31
 
30
32
  // TODO(thure): This is a workaround for the race condition between displaying a Popover and either rendering
31
- // the anchor further down the tree or measuring the virtual triggers client rect.
33
+ // the anchor further down the tree or measuring the virtual trigger's client rect.
32
34
  useEffect(() => {
33
35
  setOpen(false);
34
- if (layout.popoverOpen) {
36
+ if (state.popoverOpen) {
35
37
  if (debounceRef.current) {
36
38
  clearTimeout(debounceRef.current);
37
39
  }
38
- if (layout.popoverAnchor && virtualRef.current !== layout.popoverAnchor) {
39
- virtualRef.current = layout.popoverAnchor ?? null;
40
+ if (state.popoverAnchor && virtualRef.current !== state.popoverAnchor) {
41
+ virtualRef.current = state.popoverAnchor ?? null;
40
42
  setVirtualIter((iter) => iter + 1);
41
43
  }
42
44
  debounceRef.current = setTimeout(() => setOpen(true), DEBOUNCE_DELAY);
43
45
  }
44
- }, [layout.popoverOpen, layout.popoverAnchorId, layout.popoverAnchor, layout.popoverContent]);
46
+ }, [state.popoverOpen, state.popoverAnchorId, state.popoverAnchor, state.popoverContent]);
45
47
 
46
48
  return (
47
49
  <DeckPopoverProvider setOpen={setOpen}>
48
50
  <Popover.Root modal={false} open={open}>
49
- {layout.popoverAnchor && <Popover.VirtualTrigger key={virtualIter} virtualRef={virtualRef} />}
51
+ {state.popoverAnchor && <Popover.VirtualTrigger key={virtualIter} virtualRef={virtualRef} />}
50
52
  {children}
51
53
  </Popover.Root>
52
54
  </DeckPopoverProvider>
@@ -54,10 +56,22 @@ export const PopoverRoot = ({ children }: DeckPopoverRootProps) => {
54
56
  };
55
57
 
56
58
  export const PopoverContent = () => {
57
- const layout = useCapability(DeckCapabilities.MutableDeckState);
59
+ const { t } = useTranslation(meta.id);
60
+ const { state, updateEphemeral } = useDeckState();
58
61
  const { setOpen } = useDeckPopoverContext('PopoverContent');
59
62
 
60
- const handleClose = useCallback(
63
+ const handleClose = useCallback(() => {
64
+ setOpen(false);
65
+ updateEphemeral((state) => ({
66
+ ...state,
67
+ popoverOpen: false,
68
+ popoverAnchor: undefined,
69
+ popoverAnchorId: undefined,
70
+ popoverSide: undefined,
71
+ }));
72
+ }, [updateEphemeral]);
73
+
74
+ const handleInteractOutside = useCallback(
61
75
  (event: KeyboardEvent | PopoverContentInteractOutsideEvent) => {
62
76
  if (
63
77
  // TODO(thure): CodeMirror should not focus itself when it updates.
@@ -66,36 +80,34 @@ export const PopoverContent = () => {
66
80
  ) {
67
81
  event.preventDefault();
68
82
  } else {
69
- setOpen(false);
70
- layout.popoverOpen = false;
71
- layout.popoverAnchor = undefined;
72
- layout.popoverAnchorId = undefined;
73
- layout.popoverSide = undefined;
83
+ handleClose();
74
84
  }
75
85
  },
76
- [setOpen],
86
+ [handleClose],
77
87
  );
78
88
 
79
- const collisionBoundaries: HTMLElement[] = useMemo(() => {
80
- const closest = layout.popoverAnchor?.closest('[data-popover-collision-boundary]') as
81
- | HTMLElement
82
- | null
83
- | undefined;
84
- return closest ? [closest] : [];
85
- }, [layout.popoverAnchor]);
86
-
87
89
  return (
88
90
  <Popover.Portal>
89
91
  <Popover.Content
90
- side={layout.popoverSide}
91
- onInteractOutside={handleClose}
92
- onEscapeKeyDown={handleClose}
93
- collisionBoundary={collisionBoundaries}
92
+ side={state.popoverSide}
94
93
  sticky='always'
95
94
  hideWhenDetached
95
+ onInteractOutside={handleInteractOutside}
96
+ onEscapeKeyDown={handleInteractOutside}
96
97
  >
97
98
  <Popover.Viewport>
98
- <Surface role='card--popover' data={layout.popoverContent} limit={1} />
99
+ {state.popoverKind === 'card' && (
100
+ <Card.Root>
101
+ <Card.Toolbar>
102
+ {/* TODO(wittjosiah): Cleaner way to handle no drag handle in toolbar? */}
103
+ <span />
104
+ {state.popoverTitle ? <Card.Title>{toLocalizedString(state.popoverTitle, t)}</Card.Title> : <span />}
105
+ <Card.Close onClick={handleClose} />
106
+ </Card.Toolbar>
107
+ <Surface role='card--content' data={state.popoverContent} limit={1} />
108
+ </Card.Root>
109
+ )}
110
+ {state.popoverKind === 'base' && <Surface role='popover' data={state.popoverContent} limit={1} />}
99
111
  </Popover.Viewport>
100
112
  <Popover.Arrow />
101
113
  </Popover.Content>
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { Surface } from '@dxos/app-framework';
7
+ import { Surface } from '@dxos/app-framework/react';
8
8
  import { useLandmarkMover } from '@dxos/react-ui';
9
9
 
10
10
  export const StatusBar = ({ showHints }: { showHints?: boolean }) => {
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { type LayoutAction } from '@dxos/app-framework';
7
+ import { type Common } from '@dxos/app-framework';
8
8
  import {
9
9
  Button,
10
10
  Icon,
@@ -14,7 +14,7 @@ import {
14
14
  useTranslation,
15
15
  } from '@dxos/react-ui';
16
16
 
17
- import { DECK_PLUGIN } from '../../meta';
17
+ import { meta } from '../../meta';
18
18
 
19
19
  // TODO(wittjosiah): Render remaining duration as a progress bar within the toast.
20
20
  export const Toast = ({
@@ -28,14 +28,14 @@ export const Toast = ({
28
28
  closeLabel,
29
29
  onAction,
30
30
  onOpenChange,
31
- }: LayoutAction.Toast & Pick<ToastRootProps, 'onOpenChange'>) => {
32
- const { t } = useTranslation(DECK_PLUGIN);
31
+ }: Common.LayoutOperation.Toast & Pick<ToastRootProps, 'onOpenChange'>) => {
32
+ const { t } = useTranslation(meta.id);
33
33
 
34
34
  return (
35
35
  <NaturalToast.Root data-testid={id} defaultOpen duration={duration} onOpenChange={onOpenChange}>
36
36
  <NaturalToast.Body>
37
37
  <NaturalToast.Title classNames='items-center'>
38
- {icon && <Icon icon={icon} size={5} classNames='inline mr-1' />}
38
+ {icon && <Icon icon={icon} classNames='inline mr-1' />}
39
39
  {title && <span>{toLocalizedString(title, t)}</span>}
40
40
  </NaturalToast.Title>
41
41
  {description && (
@@ -59,3 +59,28 @@ export const Toast = ({
59
59
  </NaturalToast.Root>
60
60
  );
61
61
  };
62
+
63
+ export type ToasterProps = {
64
+ toasts?: Common.LayoutOperation.Toast[];
65
+ onDismissToast?: (id: string) => void;
66
+ };
67
+
68
+ export const Toaster = ({ toasts, onDismissToast }: ToasterProps) => {
69
+ return (
70
+ <>
71
+ {toasts?.map((toast) => (
72
+ <Toast
73
+ {...toast}
74
+ key={toast.id}
75
+ onOpenChange={(open: boolean) => {
76
+ if (!open) {
77
+ onDismissToast?.(toast.id);
78
+ }
79
+
80
+ return open;
81
+ }}
82
+ />
83
+ ))}
84
+ </>
85
+ );
86
+ };
@@ -5,9 +5,9 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { Input, Select, useTranslation } from '@dxos/react-ui';
8
- import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
8
+ import { ControlGroup, ControlItemInput, ControlPage, ControlSection } from '@dxos/react-ui-form';
9
9
 
10
- import { DECK_PLUGIN } from '../../meta';
10
+ import { meta } from '../../meta';
11
11
  import {
12
12
  type DeckSettingsProps,
13
13
  type NewPlankPositioning,
@@ -18,71 +18,96 @@ import {
18
18
 
19
19
  const isSocket = !!(globalThis as any).__args;
20
20
 
21
- export const DeckSettings = ({ settings }: { settings: DeckSettingsProps }) => {
22
- const { t } = useTranslation(DECK_PLUGIN);
21
+ export type DeckSettingsComponentProps = {
22
+ settings: DeckSettingsProps;
23
+ onSettingsChange: (fn: (current: DeckSettingsProps) => DeckSettingsProps) => void;
24
+ };
25
+
26
+ export const DeckSettings = ({ settings, onSettingsChange }: DeckSettingsComponentProps) => {
27
+ const { t } = useTranslation(meta.id);
23
28
 
24
29
  return (
25
- <DeprecatedFormContainer>
26
- <DeprecatedFormInput label={t('settings enable deck label')}>
27
- <Input.Switch checked={settings.enableDeck} onCheckedChange={(checked) => (settings.enableDeck = checked)} />
28
- </DeprecatedFormInput>
29
- <DeprecatedFormInput label={t('select new plank positioning label')}>
30
- <Select.Root
31
- disabled={!settings.enableDeck}
32
- value={settings.newPlankPositioning ?? 'start'}
33
- onValueChange={(value) => (settings.newPlankPositioning = value as NewPlankPositioning)}
34
- >
35
- <Select.TriggerButton placeholder={t('select new plank positioning placeholder')} />
36
- <Select.Portal>
37
- <Select.Content>
38
- <Select.Viewport>
39
- {NewPlankPositions.map((position) => (
40
- <Select.Option key={position} value={position}>
41
- {t(`settings new plank position ${position} label`)}
42
- </Select.Option>
43
- ))}
44
- </Select.Viewport>
45
- </Select.Content>
46
- </Select.Portal>
47
- </Select.Root>
48
- </DeprecatedFormInput>
49
- <DeprecatedFormInput label={t('settings overscroll label')}>
50
- <Select.Root
51
- disabled={!settings.enableDeck}
52
- value={settings.overscroll ?? 'none'}
53
- onValueChange={(value) => (settings.overscroll = value as Overscroll)}
54
- >
55
- <Select.TriggerButton placeholder={t('select overscroll placeholder')} />
56
- <Select.Portal>
57
- <Select.Content>
58
- <Select.Viewport>
59
- {OverscrollOptions.map((option) => (
60
- <Select.Option key={option} value={option}>
61
- {t(`settings overscroll ${option} label`)}
62
- </Select.Option>
63
- ))}
64
- </Select.Viewport>
65
- </Select.Content>
66
- </Select.Portal>
67
- </Select.Root>
68
- </DeprecatedFormInput>
69
- <DeprecatedFormInput label={t('settings enable statusbar label')}>
70
- <Input.Switch
71
- checked={settings.enableStatusbar}
72
- onCheckedChange={(checked) => (settings.enableStatusbar = checked)}
73
- />
74
- </DeprecatedFormInput>
75
- <DeprecatedFormInput label={t('settings show hints label')}>
76
- <Input.Switch checked={settings.showHints} onCheckedChange={(checked) => (settings.showHints = checked)} />
77
- </DeprecatedFormInput>
78
- {!isSocket && (
79
- <DeprecatedFormInput label={t('settings native redirect label')}>
80
- <Input.Switch
81
- checked={settings.enableNativeRedirect}
82
- onCheckedChange={(checked) => (settings.enableNativeRedirect = checked)}
83
- />
84
- </DeprecatedFormInput>
85
- )}
86
- </DeprecatedFormContainer>
30
+ <ControlPage>
31
+ <ControlSection title={t('settings title', { ns: meta.id })}>
32
+ <ControlGroup>
33
+ <ControlItemInput title={t('settings enable deck label')}>
34
+ <Input.Switch
35
+ checked={settings.enableDeck}
36
+ onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, enableDeck: checked }))}
37
+ />
38
+ </ControlItemInput>
39
+ <ControlItemInput title={t('settings encapsulated planks label')}>
40
+ <Input.Switch
41
+ checked={settings.encapsulatedPlanks ?? false}
42
+ onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, encapsulatedPlanks: checked }))}
43
+ />
44
+ </ControlItemInput>
45
+ <ControlItemInput title={t('select new plank positioning label')}>
46
+ <Select.Root
47
+ disabled={!settings.enableDeck}
48
+ value={settings.newPlankPositioning ?? 'start'}
49
+ onValueChange={(value) =>
50
+ onSettingsChange((s) => ({ ...s, newPlankPositioning: value as NewPlankPositioning }))
51
+ }
52
+ >
53
+ <Select.TriggerButton placeholder={t('select new plank positioning placeholder')} />
54
+ <Select.Portal>
55
+ <Select.Content>
56
+ <Select.Viewport>
57
+ {NewPlankPositions.map((position) => (
58
+ <Select.Option key={position} value={position}>
59
+ {t(`settings new plank position ${position} label`)}
60
+ </Select.Option>
61
+ ))}
62
+ </Select.Viewport>
63
+ <Select.Arrow />
64
+ </Select.Content>
65
+ </Select.Portal>
66
+ </Select.Root>
67
+ </ControlItemInput>
68
+ <ControlItemInput title={t('settings overscroll label')}>
69
+ <Select.Root
70
+ disabled={!settings.enableDeck}
71
+ value={settings.overscroll ?? 'none'}
72
+ onValueChange={(value) => onSettingsChange((s) => ({ ...s, overscroll: value as Overscroll }))}
73
+ >
74
+ <Select.TriggerButton placeholder={t('select overscroll placeholder')} />
75
+ <Select.Portal>
76
+ <Select.Content>
77
+ <Select.Viewport>
78
+ {OverscrollOptions.map((option) => (
79
+ <Select.Option key={option} value={option}>
80
+ {t(`settings overscroll ${option} label`)}
81
+ </Select.Option>
82
+ ))}
83
+ </Select.Viewport>
84
+ <Select.Arrow />
85
+ </Select.Content>
86
+ </Select.Portal>
87
+ </Select.Root>
88
+ </ControlItemInput>
89
+ <ControlItemInput title={t('settings enable statusbar label')}>
90
+ <Input.Switch
91
+ checked={settings.enableStatusbar}
92
+ onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, enableStatusbar: checked }))}
93
+ />
94
+ </ControlItemInput>
95
+ <ControlItemInput title={t('settings show hints label')}>
96
+ <Input.Switch
97
+ checked={settings.showHints}
98
+ onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, showHints: checked }))}
99
+ />
100
+ </ControlItemInput>
101
+ {!isSocket && (
102
+ <ControlItemInput title={t('settings native redirect label')}>
103
+ <Input.Switch
104
+ checked={settings.enableNativeRedirect}
105
+ onCheckedChange={(checked) => onSettingsChange((s) => ({ ...s, enableNativeRedirect: checked }))}
106
+ />
107
+ </ControlItemInput>
108
+ )}
109
+ </ControlGroup>
110
+ </ControlSection>
111
+ </ControlPage>
87
112
  );
88
113
  };
@@ -2,23 +2,31 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { type StoryObj, type Meta } from '@storybook/react-vite';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
- import { IntentPlugin, SettingsPlugin } from '@dxos/app-framework';
8
+ import { Capability, Common, Plugin } from '@dxos/app-framework';
11
9
  import { withPluginManager } from '@dxos/app-framework/testing';
12
- import { AttentionPlugin } from '@dxos/plugin-attention';
13
- import { GraphPlugin } from '@dxos/plugin-graph';
10
+ import { corePlugins } from '@dxos/plugin-testing';
11
+ import { withTheme } from '@dxos/react-ui/testing';
14
12
  import { Stack } from '@dxos/react-ui-stack';
15
- import { withTheme, withLayout } from '@dxos/storybook-utils';
16
13
 
17
- import { Plank, type PlankProps } from './Plank';
18
- import { DeckStateFactory } from '../../capabilities';
14
+ import { DeckState } from '../../capabilities';
15
+ import { meta as pluginMeta } from '../../meta';
19
16
  import { translations } from '../../translations';
20
17
 
21
- const meta: Meta<PlankProps> = {
18
+ import { Plank } from './Plank';
19
+
20
+ const TestPlugin = Plugin.define(pluginMeta).pipe(
21
+ Plugin.addModule({
22
+ id: Capability.getModuleTag(DeckState),
23
+ activatesOn: Common.ActivationEvent.AppGraphReady,
24
+ activate: () => DeckState(),
25
+ }),
26
+ Plugin.make,
27
+ );
28
+
29
+ const meta = {
22
30
  title: 'plugins/plugin-deck/Plank',
23
31
  component: Plank,
24
32
  render: (args) => {
@@ -29,21 +37,20 @@ const meta: Meta<PlankProps> = {
29
37
  );
30
38
  },
31
39
  decorators: [
40
+ withTheme,
32
41
  withPluginManager({
33
- plugins: [AttentionPlugin(), SettingsPlugin(), IntentPlugin(), GraphPlugin()],
34
- capabilities: () => DeckStateFactory(),
42
+ plugins: [...corePlugins(), TestPlugin()],
35
43
  }),
36
- withTheme,
37
- withLayout({ fullscreen: true }),
38
44
  ],
39
45
  parameters: {
46
+ layout: 'fullscreen',
40
47
  translations,
41
48
  },
42
- };
49
+ } satisfies Meta<typeof Plank>;
43
50
 
44
51
  export default meta;
45
52
 
46
- type Story = StoryObj<PlankProps>;
53
+ type Story = StoryObj<typeof meta>;
47
54
 
48
55
  // TODO(burdon): Need to define surface provider?
49
56
  export const Default: Story = {