@dxos/react-ui 0.8.4-main.406dc2a → 0.8.4-main.422d1c7879

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 (443) hide show
  1. package/dist/lib/browser/chunk-OCVRIJCH.mjs +848 -0
  2. package/dist/lib/browser/chunk-OCVRIJCH.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +4120 -65
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +91 -67
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/chunk-QUD5P3RU.mjs +850 -0
  9. package/dist/lib/node-esm/chunk-QUD5P3RU.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +4120 -65
  11. package/dist/lib/node-esm/index.mjs.map +4 -4
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +91 -67
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  16. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  17. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  20. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/{Buttons → Button}/Button.d.ts +3 -3
  22. package/dist/types/src/components/Button/Button.d.ts.map +1 -0
  23. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -0
  24. package/dist/types/src/components/{Buttons → Button}/IconButton.d.ts +2 -2
  25. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -0
  26. package/dist/types/src/components/{Buttons → Button}/IconButton.stories.d.ts +3 -0
  27. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -0
  28. package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +2 -2
  29. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -0
  30. package/dist/types/src/components/Button/Toggle.stories.d.ts +16 -0
  31. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -0
  32. package/dist/types/src/components/Button/ToggleGroup.d.ts +27 -0
  33. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -0
  34. package/dist/types/src/components/{Buttons → Button}/ToggleGroup.stories.d.ts +4 -4
  35. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -0
  36. package/dist/types/src/components/Button/index.d.ts.map +1 -0
  37. package/dist/types/src/components/Card/Card.d.ts +127 -0
  38. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  39. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  40. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  41. package/dist/types/src/components/Card/index.d.ts +2 -0
  42. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  43. package/dist/types/src/components/Clipboard/CopyButton.d.ts +1 -1
  44. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  45. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  46. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  47. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts +1 -1
  48. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  49. package/dist/types/src/components/Dialog/AlertDialog.d.ts +51 -0
  50. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -0
  51. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -0
  52. package/dist/types/src/components/Dialog/Dialog.d.ts +64 -0
  53. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -0
  54. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +25 -0
  55. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -0
  56. package/dist/types/src/components/Dialog/index.d.ts.map +1 -0
  57. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts +1 -1
  58. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  59. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  60. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  61. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  62. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  63. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +19 -0
  64. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  65. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  66. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  67. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  68. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  69. package/dist/types/src/components/Focus/Focus.d.ts +36 -0
  70. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  71. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  72. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  73. package/dist/types/src/components/Focus/index.d.ts +2 -0
  74. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  75. package/dist/types/src/components/Icon/Icon.d.ts +4 -1
  76. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  77. package/dist/types/src/components/Icon/Icon.stories.d.ts +25 -0
  78. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
  79. package/dist/types/src/components/Image/Image.d.ts +15 -0
  80. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  81. package/dist/types/src/components/Image/Image.stories.d.ts +34 -0
  82. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  83. package/dist/types/src/components/Image/index.d.ts +2 -0
  84. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  85. package/dist/types/src/components/Input/Input.d.ts +7 -7
  86. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  87. package/dist/types/src/components/Input/Input.stories.d.ts +8 -8
  88. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  89. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  90. package/dist/types/src/components/{Lists → List}/List.d.ts +6 -4
  91. package/dist/types/src/components/List/List.d.ts.map +1 -0
  92. package/dist/types/src/components/{Lists → List}/List.stories.d.ts +3 -1
  93. package/dist/types/src/components/List/List.stories.d.ts.map +1 -0
  94. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -0
  95. package/dist/types/src/components/List/Tree.d.ts.map +1 -0
  96. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -0
  97. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -0
  98. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts +5 -9
  99. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -0
  100. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -0
  101. package/dist/types/src/components/List/index.d.ts.map +1 -0
  102. package/dist/types/src/components/Main/Main.d.ts +17 -18
  103. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  104. package/dist/types/src/components/Main/Main.stories.d.ts +0 -3
  105. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  106. package/dist/types/src/components/{Menus → Menu}/ContextMenu.d.ts +6 -6
  107. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -0
  108. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -0
  109. package/dist/types/src/components/Menu/DropdownMenu.d.ts +113 -0
  110. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -0
  111. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +28 -0
  112. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -0
  113. package/dist/types/src/components/Menu/index.d.ts.map +1 -0
  114. package/dist/types/src/components/Message/Message.d.ts +1 -1
  115. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  116. package/dist/types/src/components/Message/Message.stories.d.ts +5 -6
  117. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  118. package/dist/types/src/components/Popover/Popover.d.ts +33 -24
  119. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  120. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +27 -27
  122. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  123. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +57 -8
  124. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  125. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +60 -0
  126. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -0
  127. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +23 -0
  128. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -0
  129. package/dist/types/src/components/ScrollContainer/index.d.ts +2 -0
  130. package/dist/types/src/components/ScrollContainer/index.d.ts.map +1 -0
  131. package/dist/types/src/components/Select/Select.d.ts +10 -10
  132. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  133. package/dist/types/src/components/Select/Select.stories.d.ts +2 -2
  134. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  135. package/dist/types/src/components/Separator/Separator.d.ts +4 -4
  136. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  137. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  138. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  139. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  140. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  141. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  142. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  143. package/dist/types/src/components/Splitter/Splitter.d.ts +34 -0
  144. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  145. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  146. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  147. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  148. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  149. package/dist/types/src/components/Status/Status.d.ts +3 -4
  150. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  151. package/dist/types/src/components/Status/Status.stories.d.ts +4 -2
  152. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  153. package/dist/types/src/components/Tag/Tag.d.ts +1 -1
  154. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  155. package/dist/types/src/components/Tag/Tag.stories.d.ts +0 -5
  156. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  157. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +3 -3
  158. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  159. package/dist/types/src/components/{Menus/DropdownMenu.stories.d.ts → ThemeProvider/ThemeProvider.stories.d.ts} +2 -5
  160. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  161. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -8
  162. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  163. package/dist/types/src/components/ThemeProvider/index.d.ts +2 -1
  164. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  165. package/dist/types/src/components/Toast/Toast.d.ts +19 -19
  166. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  167. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  168. package/dist/types/src/components/Toolbar/Toolbar.d.ts +37 -17
  169. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  170. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  171. package/dist/types/src/components/Tooltip/Tooltip.d.ts +9 -9
  172. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  173. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -2
  174. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  175. package/dist/types/src/components/index.d.ts +14 -8
  176. package/dist/types/src/components/index.d.ts.map +1 -1
  177. package/dist/types/src/exemplars/generics.stories.d.ts +19 -0
  178. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  179. package/dist/types/src/exemplars/slot.stories.d.ts +15 -0
  180. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  181. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  182. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  183. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  184. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  185. package/dist/types/src/hooks/index.d.ts +1 -0
  186. package/dist/types/src/hooks/index.d.ts.map +1 -1
  187. package/dist/types/src/hooks/useDensityContext.d.ts +2 -2
  188. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  189. package/dist/types/src/hooks/useElevationContext.d.ts +1 -1
  190. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  191. package/dist/types/src/index.d.ts +2 -1
  192. package/dist/types/src/index.d.ts.map +1 -1
  193. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  194. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  195. package/dist/types/src/primitives/Column/Column.d.ts +33 -0
  196. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  197. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  198. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  199. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  200. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  201. package/dist/types/src/primitives/Container/Container.d.ts +7 -0
  202. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  203. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  204. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  205. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  206. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  207. package/dist/types/src/primitives/Flex/Flex.d.ts +11 -0
  208. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  209. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  210. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  211. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  212. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  213. package/dist/types/src/primitives/Grid/Grid.d.ts +10 -0
  214. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  215. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  216. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  217. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  218. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  219. package/dist/types/src/primitives/Panel/Panel.d.ts +35 -0
  220. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  221. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  222. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  223. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  224. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  225. package/dist/types/src/primitives/index.d.ts +6 -0
  226. package/dist/types/src/primitives/index.d.ts.map +1 -0
  227. package/dist/types/src/testing/Loading.d.ts +9 -0
  228. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  229. package/dist/types/src/testing/decorators/index.d.ts +1 -1
  230. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  231. package/dist/types/src/testing/decorators/withLayout.d.ts +3 -3
  232. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  233. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts +12 -0
  234. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
  235. package/dist/types/src/testing/decorators/withTheme.d.ts +3 -2
  236. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  237. package/dist/types/src/testing/index.d.ts +1 -0
  238. package/dist/types/src/testing/index.d.ts.map +1 -1
  239. package/dist/types/src/translations.d.ts +11 -0
  240. package/dist/types/src/translations.d.ts.map +1 -0
  241. package/dist/types/src/util/index.d.ts +1 -2
  242. package/dist/types/src/util/index.d.ts.map +1 -1
  243. package/dist/types/src/util/usePx.d.ts.map +1 -1
  244. package/dist/types/tsconfig.tsbuildinfo +1 -1
  245. package/package.json +43 -37
  246. package/src/components/Avatars/Avatar.stories.tsx +7 -9
  247. package/src/components/Avatars/Avatar.tsx +7 -15
  248. package/src/components/Avatars/AvatarGroup.stories.tsx +2 -3
  249. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +4 -5
  250. package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
  251. package/src/components/{Buttons → Button}/Button.stories.tsx +4 -5
  252. package/src/components/{Buttons → Button}/Button.tsx +12 -26
  253. package/src/components/{Buttons → Button}/IconButton.stories.tsx +8 -6
  254. package/src/components/{Buttons → Button}/IconButton.tsx +19 -15
  255. package/src/components/{Buttons → Button}/Toggle.stories.tsx +7 -7
  256. package/src/components/{Buttons → Button}/Toggle.tsx +4 -4
  257. package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +2 -3
  258. package/src/components/{Buttons → Button}/ToggleGroup.tsx +12 -16
  259. package/src/components/Card/Card.stories.tsx +151 -0
  260. package/src/components/Card/Card.tsx +505 -0
  261. package/src/components/Card/index.ts +5 -0
  262. package/src/components/Clipboard/CopyButton.tsx +8 -9
  263. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  264. package/src/components/Dialog/AlertDialog.stories.tsx +68 -0
  265. package/src/components/{Dialogs → Dialog}/AlertDialog.tsx +123 -82
  266. package/src/components/Dialog/Dialog.stories.tsx +177 -0
  267. package/src/components/Dialog/Dialog.tsx +285 -0
  268. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  269. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +45 -0
  270. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  271. package/src/components/ErrorFallback/ErrorStack.tsx +114 -0
  272. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  273. package/src/components/ErrorFallback/index.ts +9 -0
  274. package/src/components/Focus/AUDIT.md +43 -0
  275. package/src/components/Focus/Focus.stories.tsx +230 -0
  276. package/src/components/Focus/Focus.tsx +201 -0
  277. package/src/components/Focus/index.ts +5 -0
  278. package/src/components/Icon/Icon.stories.tsx +143 -0
  279. package/src/components/Icon/Icon.tsx +6 -2
  280. package/src/components/Image/Image.stories.tsx +86 -0
  281. package/src/components/Image/Image.tsx +236 -0
  282. package/src/components/Image/index.ts +5 -0
  283. package/src/components/Input/Input.stories.tsx +21 -41
  284. package/src/components/Input/Input.tsx +38 -74
  285. package/src/components/Link/Link.stories.tsx +2 -3
  286. package/src/components/Link/Link.tsx +2 -2
  287. package/src/components/{Lists → List}/List.stories.tsx +30 -34
  288. package/src/components/{Lists → List}/List.tsx +17 -21
  289. package/src/components/{Lists → List}/ListDropIndicator.tsx +7 -7
  290. package/src/components/{Lists → List}/Tree.stories.tsx +5 -6
  291. package/src/components/{Lists → List}/Tree.tsx +0 -1
  292. package/src/components/{Lists → List}/TreeDropIndicator.tsx +6 -6
  293. package/src/components/{Lists → List}/Treegrid.stories.tsx +29 -30
  294. package/src/components/{Lists → List}/Treegrid.tsx +23 -28
  295. package/src/components/Main/Main.stories.tsx +41 -24
  296. package/src/components/Main/Main.tsx +150 -94
  297. package/src/components/{Menus → Menu}/ContextMenu.stories.tsx +2 -3
  298. package/src/components/{Menus → Menu}/ContextMenu.tsx +9 -33
  299. package/src/components/{Menus → Menu}/DropdownMenu.stories.tsx +3 -4
  300. package/src/components/{Menus → Menu}/DropdownMenu.tsx +137 -110
  301. package/src/components/Message/Message.stories.tsx +27 -13
  302. package/src/components/Message/Message.tsx +43 -34
  303. package/src/components/Popover/Popover.stories.tsx +8 -9
  304. package/src/components/Popover/Popover.tsx +114 -92
  305. package/src/components/ScrollArea/ScrollArea.stories.tsx +223 -34
  306. package/src/components/ScrollArea/ScrollArea.tsx +97 -79
  307. package/src/components/ScrollArea/index.ts +1 -1
  308. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +91 -0
  309. package/src/components/ScrollContainer/ScrollContainer.tsx +347 -0
  310. package/src/components/ScrollContainer/index.ts +5 -0
  311. package/src/components/Select/Select.stories.tsx +8 -9
  312. package/src/components/Select/Select.tsx +11 -27
  313. package/src/components/Separator/Separator.tsx +5 -8
  314. package/src/components/Skeleton/Skeleton.stories.tsx +51 -0
  315. package/src/components/Skeleton/Skeleton.tsx +26 -0
  316. package/src/components/Skeleton/index.ts +5 -0
  317. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  318. package/src/components/Splitter/Splitter.tsx +127 -0
  319. package/src/components/Splitter/index.ts +5 -0
  320. package/src/components/Status/Status.stories.tsx +21 -18
  321. package/src/components/Status/Status.tsx +10 -7
  322. package/src/components/Tag/Tag.stories.tsx +6 -12
  323. package/src/components/Tag/Tag.tsx +3 -8
  324. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +31 -0
  325. package/src/components/ThemeProvider/ThemeProvider.tsx +10 -10
  326. package/src/components/ThemeProvider/TranslationsProvider.tsx +1 -16
  327. package/src/components/ThemeProvider/index.ts +3 -3
  328. package/src/components/Toast/Toast.stories.tsx +3 -4
  329. package/src/components/Toast/Toast.tsx +22 -41
  330. package/src/components/Toolbar/Toolbar.stories.tsx +4 -7
  331. package/src/components/Toolbar/Toolbar.tsx +186 -23
  332. package/src/components/Tooltip/Tooltip.stories.tsx +21 -20
  333. package/src/components/Tooltip/Tooltip.tsx +40 -38
  334. package/src/components/index.ts +15 -9
  335. package/src/exemplars/generics.stories.tsx +41 -0
  336. package/src/exemplars/slot.stories.tsx +117 -0
  337. package/src/exemplars/tabster.stories.tsx +127 -0
  338. package/src/exemplars/virtualizer.stories.tsx +137 -0
  339. package/src/hooks/index.ts +1 -0
  340. package/src/hooks/useDensityContext.ts +3 -3
  341. package/src/hooks/useElevationContext.ts +1 -1
  342. package/src/index.ts +2 -1
  343. package/src/playground/Controls.stories.tsx +3 -10
  344. package/src/playground/Custom.stories.tsx +13 -18
  345. package/src/playground/Typography.stories.tsx +3 -3
  346. package/src/primitives/Column/AUDIT.md +148 -0
  347. package/src/primitives/Column/Column.stories.tsx +181 -0
  348. package/src/primitives/Column/Column.tsx +165 -0
  349. package/src/primitives/Column/index.ts +5 -0
  350. package/src/primitives/Container/Container.stories.tsx +29 -0
  351. package/src/primitives/Container/Container.tsx +19 -0
  352. package/src/primitives/Container/index.ts +5 -0
  353. package/src/primitives/Flex/Flex.stories.tsx +57 -0
  354. package/src/primitives/Flex/Flex.tsx +27 -0
  355. package/src/primitives/Flex/index.ts +5 -0
  356. package/src/primitives/Grid/Grid.stories.tsx +56 -0
  357. package/src/primitives/Grid/Grid.tsx +30 -0
  358. package/src/primitives/Grid/index.ts +5 -0
  359. package/src/primitives/Panel/Panel.stories.tsx +68 -0
  360. package/src/primitives/Panel/Panel.tsx +120 -0
  361. package/src/primitives/Panel/index.ts +5 -0
  362. package/src/primitives/index.ts +9 -0
  363. package/src/testing/Loading.tsx +47 -0
  364. package/src/testing/decorators/index.ts +1 -1
  365. package/src/testing/decorators/withLayout.tsx +39 -18
  366. package/src/testing/decorators/withLayoutVariants.tsx +48 -0
  367. package/src/testing/decorators/withTheme.tsx +26 -20
  368. package/src/testing/index.ts +2 -0
  369. package/src/translations.ts +19 -0
  370. package/src/util/index.ts +2 -2
  371. package/src/util/usePx.ts +1 -0
  372. package/dist/lib/browser/chunk-KX5JDELJ.mjs +0 -4521
  373. package/dist/lib/browser/chunk-KX5JDELJ.mjs.map +0 -7
  374. package/dist/lib/node-esm/chunk-3HDQYL5S.mjs +0 -4523
  375. package/dist/lib/node-esm/chunk-3HDQYL5S.mjs.map +0 -7
  376. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  377. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  378. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  379. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  380. package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
  381. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
  382. package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
  383. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
  384. package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
  385. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -13
  386. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
  387. package/dist/types/src/components/Buttons/ToggleGroup.d.ts +0 -27
  388. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
  389. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
  390. package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
  391. package/dist/types/src/components/Dialogs/AlertDialog.d.ts +0 -31
  392. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
  393. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
  394. package/dist/types/src/components/Dialogs/Dialog.d.ts +0 -31
  395. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
  396. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -25
  397. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
  398. package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
  399. package/dist/types/src/components/Lists/List.d.ts.map +0 -1
  400. package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
  401. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
  402. package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
  403. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
  404. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
  405. package/dist/types/src/components/Lists/Treegrid.d.ts.map +0 -1
  406. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
  407. package/dist/types/src/components/Lists/index.d.ts.map +0 -1
  408. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +0 -1
  409. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +0 -1
  410. package/dist/types/src/components/Menus/DropdownMenu.d.ts +0 -113
  411. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +0 -1
  412. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +0 -1
  413. package/dist/types/src/components/Menus/index.d.ts.map +0 -1
  414. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts +0 -12
  415. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
  416. package/dist/types/src/util/ThemedClassName.d.ts +0 -5
  417. package/dist/types/src/util/ThemedClassName.d.ts.map +0 -1
  418. package/dist/types/src/util/domino.d.ts +0 -18
  419. package/dist/types/src/util/domino.d.ts.map +0 -1
  420. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  421. package/src/components/AnchoredOverflow/index.ts +0 -5
  422. package/src/components/Dialogs/AlertDialog.stories.tsx +0 -69
  423. package/src/components/Dialogs/Dialog.stories.tsx +0 -67
  424. package/src/components/Dialogs/Dialog.tsx +0 -159
  425. package/src/testing/decorators/withSurfaceVariantsLayout.tsx +0 -51
  426. package/src/util/ThemedClassName.ts +0 -7
  427. package/src/util/domino.ts +0 -53
  428. /package/dist/types/src/components/{Buttons → Button}/Button.stories.d.ts +0 -0
  429. /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
  430. /package/dist/types/src/components/{Dialogs → Dialog}/AlertDialog.stories.d.ts +0 -0
  431. /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
  432. /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
  433. /package/dist/types/src/components/{Lists → List}/Tree.d.ts +0 -0
  434. /package/dist/types/src/components/{Lists → List}/Tree.stories.d.ts +0 -0
  435. /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
  436. /package/dist/types/src/components/{Lists → List}/Treegrid.stories.d.ts +0 -0
  437. /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
  438. /package/dist/types/src/components/{Menus → Menu}/ContextMenu.stories.d.ts +0 -0
  439. /package/dist/types/src/components/{Menus → Menu}/index.d.ts +0 -0
  440. /package/src/components/{Buttons → Button}/index.ts +0 -0
  441. /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
  442. /package/src/components/{Lists → List}/index.ts +0 -0
  443. /package/src/components/{Menus → Menu}/index.ts +0 -0
@@ -0,0 +1,285 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { createContext } from '@radix-ui/react-context';
6
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
7
+ import { Primitive } from '@radix-ui/react-primitive';
8
+ import { Slot } from '@radix-ui/react-slot';
9
+ import React, {
10
+ type ComponentPropsWithRef,
11
+ type ForwardRefExoticComponent,
12
+ type FunctionComponent,
13
+ forwardRef,
14
+ } from 'react';
15
+ import { useTranslation } from 'react-i18next';
16
+
17
+ import { composableProps, type DialogSize, osTranslations, slottable } from '@dxos/ui-theme';
18
+ import { type SlottableProps } from '@dxos/ui-types';
19
+
20
+ import { useThemeContext } from '../../hooks';
21
+ import { Column } from '../../primitives';
22
+ import { type ThemedClassName } from '../../util';
23
+ import { IconButton } from '../Button';
24
+ import { ElevationProvider } from '../ElevationProvider';
25
+
26
+ //
27
+ // Root
28
+ //
29
+
30
+ type DialogRootProps = DialogPrimitive.DialogProps;
31
+
32
+ const DialogRoot: FunctionComponent<DialogRootProps> = (props) => (
33
+ <ElevationProvider elevation='dialog'>
34
+ <DialogPrimitive.Root
35
+ // NOTE: Radix warning unless set to undefined.
36
+ // https://www.radix-ui.com/primitives/docs/components/dialog#description
37
+ aria-describedby={undefined}
38
+ {...props}
39
+ />
40
+ </ElevationProvider>
41
+ );
42
+
43
+ //
44
+ // Trigger
45
+ //
46
+
47
+ type DialogTriggerProps = DialogPrimitive.DialogTriggerProps;
48
+
49
+ const DialogTrigger: FunctionComponent<DialogTriggerProps> = DialogPrimitive.Trigger;
50
+
51
+ //
52
+ // Portal
53
+ //
54
+
55
+ type DialogPortalProps = DialogPrimitive.DialogPortalProps;
56
+
57
+ const DialogPortal: FunctionComponent<DialogPortalProps> = DialogPrimitive.Portal;
58
+
59
+ //
60
+ // Overlay
61
+ //
62
+
63
+ const DIALOG_OVERLAY_NAME = 'DialogOverlay';
64
+
65
+ type OverlayLayoutContextValue = { inOverlayLayout?: boolean };
66
+
67
+ const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLayoutContextValue>(
68
+ DIALOG_OVERLAY_NAME,
69
+ {},
70
+ );
71
+
72
+ type DialogOverlayProps = ThemedClassName<
73
+ DialogPrimitive.DialogOverlayProps & { blockAlign?: 'center' | 'start' | 'end' }
74
+ >;
75
+
76
+ const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<HTMLDivElement, DialogOverlayProps>(
77
+ ({ classNames, children, blockAlign, ...props }, forwardedRef) => {
78
+ const { tx } = useThemeContext();
79
+
80
+ return (
81
+ <DialogPrimitive.Overlay
82
+ {...props}
83
+ data-block-align={blockAlign}
84
+ className={tx('dialog.overlay', {}, classNames)}
85
+ ref={forwardedRef}
86
+ >
87
+ <OverlayLayoutProvider inOverlayLayout>{children}</OverlayLayoutProvider>
88
+ </DialogPrimitive.Overlay>
89
+ );
90
+ },
91
+ );
92
+
93
+ DialogOverlay.displayName = DIALOG_OVERLAY_NAME;
94
+
95
+ //
96
+ // Content
97
+ //
98
+
99
+ const DIALOG_CONTENT_NAME = 'DialogContent';
100
+
101
+ type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof DialogPrimitive.Content>> & {
102
+ size?: DialogSize;
103
+ inOverlayLayout?: boolean;
104
+ };
105
+
106
+ const DialogContent: ForwardRefExoticComponent<DialogContentProps> = forwardRef<HTMLDivElement, DialogContentProps>(
107
+ ({ classNames, children, size = 'md', inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
108
+ const { tx } = useThemeContext();
109
+ const { inOverlayLayout } = useOverlayLayoutContext(DIALOG_CONTENT_NAME);
110
+
111
+ return (
112
+ <DialogPrimitive.Content
113
+ {...props}
114
+ // NOTE: Radix warning unless set to undefined.
115
+ // https://www.radix-ui.com/primitives/docs/components/dialog#description
116
+ aria-describedby={undefined}
117
+ className={tx(
118
+ 'dialog.content',
119
+ {
120
+ size,
121
+ inOverlayLayout: propsInOverlayLayout || inOverlayLayout,
122
+ },
123
+ classNames,
124
+ )}
125
+ ref={forwardedRef}
126
+ >
127
+ <Column.Root classNames='dx-expander' gutter='sm'>
128
+ {children}
129
+ </Column.Root>
130
+ </DialogPrimitive.Content>
131
+ );
132
+ },
133
+ );
134
+
135
+ DialogContent.displayName = DIALOG_CONTENT_NAME;
136
+
137
+ //
138
+ // Header
139
+ //
140
+
141
+ type DialogHeaderProps = SlottableProps;
142
+
143
+ const DialogHeader = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
144
+ const { className, ...rest } = composableProps(props);
145
+ const Comp = asChild ? Slot : Primitive.div;
146
+ const { tx } = useThemeContext();
147
+ return (
148
+ <Comp {...rest} className={tx('dialog.header', {}, className)} ref={forwardedRef}>
149
+ {children}
150
+ </Comp>
151
+ );
152
+ });
153
+
154
+ //
155
+ // CloseIconButton
156
+ //
157
+
158
+ type DialogCloseIconButtonProps = { label?: string };
159
+
160
+ const DialogCloseIconButton = forwardRef<HTMLButtonElement, DialogCloseIconButtonProps>(
161
+ ({ label, ...props }, forwardedRef) => {
162
+ const { t } = useTranslation(osTranslations);
163
+ return (
164
+ <IconButton
165
+ {...props}
166
+ label={label ?? t('close-dialog.label')}
167
+ icon='ph--x--regular'
168
+ iconOnly
169
+ size={4}
170
+ variant='ghost'
171
+ ref={forwardedRef}
172
+ />
173
+ );
174
+ },
175
+ );
176
+
177
+ //
178
+ // Body
179
+ //
180
+
181
+ type DialogBodyProps = SlottableProps;
182
+
183
+ const DialogBody = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
184
+ const { className, ...rest } = composableProps(props);
185
+ const Comp = asChild ? Slot : Primitive.div;
186
+ const { tx } = useThemeContext();
187
+ return (
188
+ <Comp {...rest} className={tx('dialog.body', {}, className)} ref={forwardedRef}>
189
+ {children}
190
+ </Comp>
191
+ );
192
+ });
193
+
194
+ //
195
+ // Title
196
+ //
197
+
198
+ type DialogTitleProps = ThemedClassName<DialogPrimitive.DialogTitleProps> & { srOnly?: boolean };
199
+
200
+ const DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(
201
+ ({ classNames, srOnly, ...props }, forwardedRef) => {
202
+ const { tx } = useThemeContext();
203
+ return (
204
+ <DialogPrimitive.Title {...props} className={tx('dialog.title', { srOnly }, classNames)} ref={forwardedRef} />
205
+ );
206
+ },
207
+ );
208
+
209
+ //
210
+ // Description
211
+ //
212
+
213
+ type DialogDescriptionProps = ThemedClassName<DialogPrimitive.DialogDescriptionProps> & { srOnly?: boolean };
214
+
215
+ const DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(
216
+ ({ classNames, srOnly, ...props }, forwardedRef) => {
217
+ const { tx } = useThemeContext();
218
+ return (
219
+ <DialogPrimitive.Description
220
+ {...props}
221
+ className={tx('dialog.description', { srOnly }, classNames)}
222
+ ref={forwardedRef}
223
+ />
224
+ );
225
+ },
226
+ );
227
+
228
+ //
229
+ // ActionBar
230
+ //
231
+
232
+ type DialogActionBarProps = SlottableProps;
233
+
234
+ const DialogActionBar = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
235
+ const { className: classNames, ...rest } = composableProps(props);
236
+ const Comp = asChild ? Slot : Primitive.div;
237
+ const { tx } = useThemeContext();
238
+ return (
239
+ <Comp {...rest} className={tx('dialog.actionbar', {}, classNames)} ref={forwardedRef}>
240
+ {children}
241
+ </Comp>
242
+ );
243
+ });
244
+
245
+ //
246
+ // Close
247
+ //
248
+
249
+ type DialogCloseProps = DialogPrimitive.DialogCloseProps;
250
+
251
+ const DialogClose: FunctionComponent<DialogCloseProps> = DialogPrimitive.Close;
252
+
253
+ //
254
+ // Dialog
255
+ //
256
+
257
+ export const Dialog = {
258
+ Root: DialogRoot,
259
+ Trigger: DialogTrigger,
260
+ Portal: DialogPortal,
261
+ Overlay: DialogOverlay,
262
+ Content: DialogContent,
263
+ Header: DialogHeader,
264
+ Body: DialogBody,
265
+ Title: DialogTitle,
266
+ Description: DialogDescription,
267
+ ActionBar: DialogActionBar,
268
+ Close: DialogClose,
269
+ CloseIconButton: DialogCloseIconButton,
270
+ };
271
+
272
+ export type {
273
+ DialogRootProps,
274
+ DialogTriggerProps,
275
+ DialogPortalProps,
276
+ DialogOverlayProps,
277
+ DialogContentProps,
278
+ DialogHeaderProps,
279
+ DialogBodyProps,
280
+ DialogTitleProps,
281
+ DialogDescriptionProps,
282
+ DialogActionBarProps,
283
+ DialogCloseProps,
284
+ DialogCloseIconButtonProps,
285
+ };
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React, { type PropsWithChildren, createContext } from 'react';
6
6
 
7
- import { type Elevation } from '@dxos/react-ui-types';
7
+ import { type Elevation } from '@dxos/ui-types';
8
8
 
9
9
  export interface ElevationContextValue {
10
10
  elevation?: Elevation;
@@ -0,0 +1,45 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { ErrorBoundary } from '@dxos/react-error-boundary';
9
+
10
+ import { withLayout, withTheme } from '../../testing';
11
+ import { ErrorFallback } from './ErrorFallback';
12
+ import { ThrowError } from './ThrowError';
13
+
14
+ const DefaultStory = () => {
15
+ return (
16
+ <ErrorBoundary name='story' FallbackComponent={ErrorFallback}>
17
+ <ThrowError />
18
+ </ErrorBoundary>
19
+ );
20
+ };
21
+
22
+ const meta: Meta = {
23
+ title: 'ui/react-ui-core/components/ErrorFallback',
24
+ component: ErrorFallback,
25
+ decorators: [withTheme(), withLayout({ layout: 'column' })],
26
+ parameters: {
27
+ layout: 'fullscreen',
28
+ },
29
+ };
30
+
31
+ export default meta;
32
+
33
+ type Story = StoryObj<typeof meta>;
34
+
35
+ export const Default: Story = {
36
+ render: DefaultStory,
37
+ play: async () => {
38
+ // This story intentionally renders an ErrorBoundary fallback; clear the smoke-test error flag.
39
+ (window as any).__ERROR_BOUNDARY_ERRORS__ = [];
40
+ },
41
+ };
42
+
43
+ export const StringError: Story = {
44
+ render: () => <ErrorFallback error='This is a string error message' data={{ context: 'story' }} />,
45
+ };
@@ -0,0 +1,70 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import React, { type PropsWithChildren } from 'react';
6
+ import { type FallbackProps } from 'react-error-boundary';
7
+
8
+ import { safeStringify } from '@dxos/util';
9
+
10
+ import { ErrorStack } from './ErrorStack';
11
+
12
+ export type ErrorFallbackProps = PropsWithChildren<Pick<FallbackProps, 'error'> & { title?: string; data?: any }>;
13
+
14
+ /**
15
+ * Themed fallback component for `ErrorBoundary`.
16
+ */
17
+ export const ErrorFallback = ({ children, error, title, data }: ErrorFallbackProps) => {
18
+ const isDev = process.env.NODE_ENV === 'development';
19
+ const message = error instanceof Error ? error.message : String(error);
20
+
21
+ return (
22
+ <div role='alert' data-testid='error-boundary-fallback' className='flex flex-col p-4 gap-4 overflow-auto'>
23
+ <h1 className='text-lg text-info-text'>{title ?? 'Runtime Error'}</h1>
24
+ <p>{message}</p>
25
+
26
+ {isDev && error instanceof Error && (
27
+ <Section
28
+ title='Stack'
29
+ onClick={() => {
30
+ const text = error instanceof Error ? (error.stack ?? error.message) : String(error);
31
+ void navigator.clipboard.writeText(text);
32
+ }}
33
+ >
34
+ <ErrorStack error={error} />
35
+ </Section>
36
+ )}
37
+
38
+ {data && (
39
+ <Section
40
+ title='Data'
41
+ onClick={() => {
42
+ void navigator.clipboard.writeText(JSON.stringify(data, undefined, 2));
43
+ }}
44
+ >
45
+ <pre className='overflow-x-auto text-xs'>{safeStringify(data, undefined, 2)}</pre>
46
+ </Section>
47
+ )}
48
+
49
+ {children}
50
+ </div>
51
+ );
52
+ };
53
+
54
+ const Section = ({ children, title, onClick }: PropsWithChildren<{ title?: string; onClick?: () => void }>) => {
55
+ return (
56
+ <div className='flex flex-col gap-1'>
57
+ {onClick && (
58
+ <button
59
+ type='button'
60
+ onClick={onClick}
61
+ className='flex items-center gap-1 text-xs text-subdued hover:text-primary-500 transition-colors'
62
+ title={`Copy ${title}`}
63
+ >
64
+ <h2 className='text-xs uppercase text-subdued'>{title}</h2>
65
+ </button>
66
+ )}
67
+ {children}
68
+ </div>
69
+ );
70
+ };
@@ -0,0 +1,114 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import ErrorStackParser from 'error-stack-parser';
6
+ import React from 'react';
7
+
8
+ import { mx } from '@dxos/ui-theme';
9
+
10
+ type LocalFrame = { href: string; fileName: string };
11
+
12
+ export type ParsedStackFrame = ReturnType<typeof ErrorStackParser.parse>[number];
13
+
14
+ export type ErrorStackProps = {
15
+ /** When set, these frames are shown instead of parsing `error`. */
16
+ frames?: ParsedStackFrame[];
17
+ /** Used when `frames` is omitted. */
18
+ error?: Error;
19
+ };
20
+
21
+ /**
22
+ * Parses `captureOwnerStack()` output (React dev) into frames for {@link ErrorStack}.
23
+ * Prefixes a synthetic Error line when needed so `error-stack-parser` can read V8-style stacks.
24
+ */
25
+ export const parseCaptureOwnerStack = (stack: string | null): ParsedStackFrame[] | null => {
26
+ if (stack == null || stack.length === 0) {
27
+ return null;
28
+ }
29
+ const err = new Error();
30
+ err.stack = stack;
31
+ try {
32
+ return ErrorStackParser.parse(err);
33
+ } catch {
34
+ err.stack = `Error\n${stack}`;
35
+ try {
36
+ return ErrorStackParser.parse(err);
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+ };
42
+
43
+ /**
44
+ * Renders a parsed error stack trace with tree connector symbols and clickable vscode:// links for local frames.
45
+ */
46
+ export const ErrorStack = ({ error, frames: framesProp }: ErrorStackProps) => {
47
+ const frames = framesProp ?? (error ? ErrorStackParser.parse(error) : []);
48
+ if (frames.length === 0) {
49
+ return null;
50
+ }
51
+
52
+ return (
53
+ <div className='font-mono text-sm'>
54
+ {frames.map((frame, i) => {
55
+ const isLast = i === frames.length - 1;
56
+ const local = frame.fileName
57
+ ? parseLocalFrame(frame.fileName, frame.lineNumber, frame.columnNumber)
58
+ : undefined;
59
+ const name = frame.functionName ?? '<anonymous>';
60
+ return (
61
+ <div
62
+ key={i}
63
+ className={mx(
64
+ 'grid grid-cols-[16px_1fr_auto_auto] items-stretch gap-x-2',
65
+ local && 'cursor-pointer hover:bg-hover-surface',
66
+ )}
67
+ >
68
+ {/* Tree connector: vertical line full-height + horizontal branch at midpoint */}
69
+ <div className='relative'>
70
+ <div
71
+ className={mx(
72
+ 'absolute left-1/2 -translate-x-1/2 w-px bg-neutral-500',
73
+ isLast ? 'top-0 h-1/2' : 'inset-y-0',
74
+ )}
75
+ />
76
+ <div className='absolute top-1/2 -translate-y-1/2 left-1/2 right-0 h-px bg-neutral-500' />
77
+ </div>
78
+ {local ? (
79
+ <a href={local.href} className='truncate self-center'>
80
+ {name}
81
+ </a>
82
+ ) : (
83
+ <span className='text-subdued truncate self-center'>{name}</span>
84
+ )}
85
+ <span className='text-xs text-subdued truncate self-center'>{local?.fileName ?? ''}</span>
86
+ <span className='text-xs text-subdued text-right self-center'>
87
+ {local ? `${frame.lineNumber}:${frame.columnNumber}` : ''}
88
+ </span>
89
+ </div>
90
+ );
91
+ })}
92
+ </div>
93
+ );
94
+ };
95
+
96
+ /**
97
+ * Parses a Vite `/@fs/` URL into a `vscode://` deep link and short filename.
98
+ * Returns undefined if the URL cannot be resolved to a local file.
99
+ */
100
+ const parseLocalFrame = (fileUrl: string, line?: number, col?: number): LocalFrame | undefined => {
101
+ try {
102
+ const { pathname } = new URL(fileUrl);
103
+ if (!pathname.startsWith('/@fs/')) {
104
+ return undefined;
105
+ }
106
+ const localPath = pathname.slice(4); // /@fs/Users/... → /Users/...
107
+ return {
108
+ href: `vscode://file/${localPath}:${line ?? 1}:${col ?? 1}`,
109
+ fileName: pathname.split('/').pop() ?? localPath,
110
+ };
111
+ } catch {
112
+ return undefined;
113
+ }
114
+ };
@@ -0,0 +1,37 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { useEffect, useState } from 'react';
6
+
7
+ export type ThrowErrorProps = {
8
+ error?: () => Error;
9
+ delay?: number;
10
+ };
11
+
12
+ /**
13
+ * Use this to debug the error boundary.
14
+ */
15
+ export const ThrowError = ({ delay = 1_000, ...props }: ThrowErrorProps) => {
16
+ const [error, setError] = useState<Error>();
17
+ useEffect(() => {
18
+ if (delay < 0) {
19
+ return;
20
+ }
21
+
22
+ const t = setTimeout(() => {
23
+ setError(generator({ delay, ...props }));
24
+ }, delay);
25
+ return () => clearTimeout(t);
26
+ }, [delay, generator]);
27
+
28
+ if (error) {
29
+ throw error;
30
+ }
31
+
32
+ return null;
33
+ };
34
+
35
+ const generator = ({ error, delay }: ThrowErrorProps) => {
36
+ return error?.() ?? new Error(`Error generated after ${delay}ms`);
37
+ };
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export { ErrorBoundary, type ErrorBoundaryProps, type FallbackProps } from '@dxos/react-error-boundary';
6
+
7
+ export * from './ErrorFallback';
8
+ export * from './ErrorStack';
9
+ export * from './ThrowError';
@@ -0,0 +1,43 @@
1
+ # Focus
2
+
3
+ ## Problem
4
+
5
+ Grid cells use `overflow-hidden` which clips outward CSS `ring` (box-shadow) and `outline` styles.
6
+ Using `border` for focus indicators creates doubled lines at grid cell boundaries.
7
+ Inset `box-shadow` alone is obscured by child elements with backgrounds (e.g., toolbar headers).
8
+
9
+ ## Solution
10
+
11
+ Uses a `::after` pseudo-element overlay with `ring-inset` to paint the focus ring above all child content.
12
+ The pseudo-element is absolutely positioned, `pointer-events-none`, and inherits `border-radius`.
13
+
14
+ - **Default**: ring is transparent (invisible until focused).
15
+ - **`border` prop**: shows a CSS `border-separator` when unfocused (e.g., for grid cell edges).
16
+ - **Focus/active/error states**: ring color changes to the appropriate indicator color.
17
+
18
+ Both `Focus.Group` and `Focus.Item` support the `border` prop.
19
+
20
+ ## Why `::after` overlay
21
+
22
+ | Approach | Clipped? | Obscured by children? | Notes |
23
+ | ------------------------ | -------- | --------------------- | --------------------------------------------------------------------- |
24
+ | `ring` (outward) | Yes | N/A | Extends outside bounds, clipped by parent `overflow-hidden`. |
25
+ | `ring-inset` | No | Yes | Inset box-shadow is part of background layer; children paint over it. |
26
+ | `::after` + `ring-inset` | No | No | Pseudo-element paints above children. Requires `position: relative`. |
27
+
28
+ ## Relationship to `dx-focus-ring-inset-over-all`
29
+
30
+ The CSS class `dx-focus-ring-inset-over-all` (in `focus-ring.css`) uses the same `::after` technique
31
+ but only reacts to `:focus-visible`. `Focus.Group/Item` additionally support programmatic states
32
+ via `data-focus-state` (`active`, `error`).
33
+
34
+ ## Clean-up
35
+
36
+ - [ ] Unify: extend `dx-focus-ring-inset-over-all` to support `data-focus-state` attributes,
37
+ then have `Focus.Group/Item` use the CSS class instead of inline Tailwind utilities.
38
+ Consumers: Plank, StackItem, Tabs, AttentionProvider, main sidebar.
39
+
40
+ ## Audit
41
+
42
+ - [ ] Create a list of all container components (outside of `react-ui`) that directly use `overflow-hidden`;
43
+ Consider containers to be components that have `children` and expand (e.g., `grid`, `grow`, `h-full`, `w-full`).