@dxos/react-ui 0.8.4-main.72ec0f3 → 0.8.4-main.7996785055

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 (365) hide show
  1. package/dist/lib/browser/chunk-LUPEFGHJ.mjs +776 -0
  2. package/dist/lib/browser/chunk-LUPEFGHJ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +4097 -68
  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 +74 -63
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/chunk-EQOBFLZC.mjs +778 -0
  9. package/dist/lib/node-esm/chunk-EQOBFLZC.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +4097 -68
  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 +74 -63
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  16. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  18. package/dist/types/src/components/Button/Button.d.ts +3 -3
  19. package/dist/types/src/components/Button/Button.d.ts.map +1 -1
  20. package/dist/types/src/components/Button/IconButton.d.ts +2 -1
  21. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
  22. package/dist/types/src/components/Button/Toggle.d.ts +2 -2
  23. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -1
  24. package/dist/types/src/components/Button/ToggleGroup.d.ts +10 -10
  25. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
  26. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +4 -4
  27. package/dist/types/src/components/Card/Card.d.ts +145 -0
  28. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  29. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  30. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  31. package/dist/types/src/components/Card/index.d.ts +2 -0
  32. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  33. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  34. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  35. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts +1 -1
  36. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  37. package/dist/types/src/components/Dialog/AlertDialog.d.ts +41 -19
  38. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
  39. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/Dialog/Dialog.d.ts +56 -21
  41. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  42. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +10 -10
  43. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
  44. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts +1 -1
  45. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  46. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  47. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  48. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  49. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  50. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +8 -0
  51. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  52. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  53. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  54. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  55. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  56. package/dist/types/src/components/Focus/Focus.d.ts +44 -0
  57. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  58. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  59. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  60. package/dist/types/src/components/Focus/index.d.ts +2 -0
  61. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  62. package/dist/types/src/components/Icon/Icon.d.ts +4 -1
  63. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  64. package/dist/types/src/components/Icon/Icon.stories.d.ts +11 -3
  65. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
  66. package/dist/types/src/components/Image/Image.d.ts +14 -0
  67. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  68. package/dist/types/src/components/Image/Image.stories.d.ts +33 -0
  69. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  70. package/dist/types/src/components/Image/index.d.ts +2 -0
  71. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  72. package/dist/types/src/components/Input/Input.d.ts +7 -7
  73. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  74. package/dist/types/src/components/Input/Input.stories.d.ts +8 -8
  75. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  76. package/dist/types/src/components/List/List.d.ts +10 -4
  77. package/dist/types/src/components/List/List.d.ts.map +1 -1
  78. package/dist/types/src/components/List/List.stories.d.ts +8 -2
  79. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  80. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
  81. package/dist/types/src/components/Main/Main.d.ts +9 -10
  82. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  83. package/dist/types/src/components/Main/Main.stories.d.ts +0 -3
  84. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  85. package/dist/types/src/components/{Menus → Menu}/ContextMenu.d.ts +6 -6
  86. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -0
  87. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -0
  88. package/dist/types/src/components/Menu/DropdownMenu.d.ts +113 -0
  89. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -0
  90. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +28 -0
  91. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -0
  92. package/dist/types/src/components/Menu/index.d.ts.map +1 -0
  93. package/dist/types/src/components/Message/Message.d.ts +1 -1
  94. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  95. package/dist/types/src/components/Message/Message.stories.d.ts +5 -6
  96. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  97. package/dist/types/src/components/Popover/Popover.d.ts +33 -24
  98. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  99. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +32 -24
  100. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  101. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +65 -8
  102. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  103. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +27 -9
  104. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
  105. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +8 -3
  106. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
  107. package/dist/types/src/components/Select/Select.d.ts +9 -9
  108. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  109. package/dist/types/src/components/Select/Select.stories.d.ts +2 -2
  110. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  111. package/dist/types/src/components/Separator/Separator.d.ts +4 -4
  112. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  113. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  114. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  115. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  116. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  117. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  118. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  119. package/dist/types/src/components/Splitter/Splitter.d.ts +37 -0
  120. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  121. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  122. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  123. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  124. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  125. package/dist/types/src/components/Status/Status.d.ts +3 -4
  126. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  127. package/dist/types/src/components/Status/Status.stories.d.ts +4 -2
  128. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  129. package/dist/types/src/components/Tag/Tag.d.ts +1 -1
  130. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  131. package/dist/types/src/components/Tag/Tag.stories.d.ts +0 -5
  132. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +3 -3
  134. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  135. package/dist/types/src/components/{Menus/DropdownMenu.stories.d.ts → ThemeProvider/ThemeProvider.stories.d.ts} +2 -5
  136. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  137. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -8
  138. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  139. package/dist/types/src/components/ThemeProvider/index.d.ts +2 -1
  140. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  141. package/dist/types/src/components/Toast/Toast.d.ts +19 -19
  142. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  143. package/dist/types/src/components/Toolbar/Toolbar.d.ts +43 -17
  144. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  145. package/dist/types/src/components/Tooltip/Tooltip.d.ts +9 -9
  146. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  147. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -2
  148. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  149. package/dist/types/src/components/index.d.ts +10 -5
  150. package/dist/types/src/components/index.d.ts.map +1 -1
  151. package/dist/types/src/exemplars/generics.stories.d.ts +23 -0
  152. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  153. package/dist/types/src/exemplars/slot.stories.d.ts +15 -0
  154. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  155. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  156. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  157. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  158. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  159. package/dist/types/src/hooks/index.d.ts +1 -0
  160. package/dist/types/src/hooks/index.d.ts.map +1 -1
  161. package/dist/types/src/hooks/useDensityContext.d.ts +2 -2
  162. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  163. package/dist/types/src/hooks/useElevationContext.d.ts +1 -1
  164. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  165. package/dist/types/src/index.d.ts +2 -1
  166. package/dist/types/src/index.d.ts.map +1 -1
  167. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  168. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  169. package/dist/types/src/primitives/Column/Column.d.ts +51 -0
  170. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  171. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  172. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  173. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  174. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  175. package/dist/types/src/primitives/Container/Container.d.ts +11 -0
  176. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  177. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  178. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  179. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  180. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  181. package/dist/types/src/primitives/Flex/Flex.d.ts +15 -0
  182. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  183. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  184. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  185. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  186. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  187. package/dist/types/src/primitives/Grid/Grid.d.ts +14 -0
  188. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  189. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  190. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  191. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  192. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  193. package/dist/types/src/primitives/Panel/Panel.d.ts +46 -0
  194. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  195. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  196. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  197. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  198. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  199. package/dist/types/src/primitives/index.d.ts +6 -0
  200. package/dist/types/src/primitives/index.d.ts.map +1 -0
  201. package/dist/types/src/testing/Loading.d.ts +9 -0
  202. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  203. package/dist/types/src/testing/decorators/withLayout.d.ts +3 -3
  204. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  205. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts +1 -1
  206. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
  207. package/dist/types/src/testing/decorators/withTheme.d.ts +3 -2
  208. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  209. package/dist/types/src/testing/index.d.ts +1 -0
  210. package/dist/types/src/testing/index.d.ts.map +1 -1
  211. package/dist/types/src/translations.d.ts +11 -0
  212. package/dist/types/src/translations.d.ts.map +1 -0
  213. package/dist/types/src/util/index.d.ts +1 -2
  214. package/dist/types/src/util/index.d.ts.map +1 -1
  215. package/dist/types/src/util/usePx.d.ts.map +1 -1
  216. package/dist/types/tsconfig.tsbuildinfo +1 -1
  217. package/package.json +40 -31
  218. package/src/components/Avatars/Avatar.stories.tsx +7 -8
  219. package/src/components/Avatars/Avatar.tsx +6 -13
  220. package/src/components/Avatars/AvatarGroup.stories.tsx +2 -2
  221. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +3 -3
  222. package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
  223. package/src/components/Button/Button.stories.tsx +3 -3
  224. package/src/components/Button/Button.tsx +12 -26
  225. package/src/components/Button/IconButton.stories.tsx +4 -4
  226. package/src/components/Button/IconButton.tsx +9 -5
  227. package/src/components/Button/Toggle.stories.tsx +2 -2
  228. package/src/components/Button/Toggle.tsx +4 -4
  229. package/src/components/Button/ToggleGroup.stories.tsx +2 -2
  230. package/src/components/Button/ToggleGroup.tsx +12 -16
  231. package/src/components/Card/Card.stories.tsx +151 -0
  232. package/src/components/Card/Card.tsx +394 -0
  233. package/src/components/Card/index.ts +5 -0
  234. package/src/components/Clipboard/CopyButton.tsx +6 -6
  235. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  236. package/src/components/Dialog/AlertDialog.stories.tsx +16 -16
  237. package/src/components/Dialog/AlertDialog.tsx +121 -82
  238. package/src/components/Dialog/Dialog.stories.tsx +139 -28
  239. package/src/components/Dialog/Dialog.tsx +192 -71
  240. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  241. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +50 -0
  242. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  243. package/src/components/ErrorFallback/ErrorStack.tsx +80 -0
  244. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  245. package/src/components/ErrorFallback/index.ts +9 -0
  246. package/src/components/Focus/AUDIT.md +43 -0
  247. package/src/components/Focus/Focus.stories.tsx +230 -0
  248. package/src/components/Focus/Focus.tsx +201 -0
  249. package/src/components/Focus/index.ts +5 -0
  250. package/src/components/Icon/Icon.stories.tsx +45 -14
  251. package/src/components/Icon/Icon.tsx +7 -3
  252. package/src/components/Image/Image.stories.tsx +86 -0
  253. package/src/components/Image/Image.tsx +223 -0
  254. package/src/components/Image/index.ts +5 -0
  255. package/src/components/Input/Input.stories.tsx +21 -40
  256. package/src/components/Input/Input.tsx +36 -72
  257. package/src/components/Link/Link.stories.tsx +2 -2
  258. package/src/components/Link/Link.tsx +2 -2
  259. package/src/components/List/List.stories.tsx +30 -33
  260. package/src/components/List/List.tsx +16 -19
  261. package/src/components/List/ListDropIndicator.tsx +7 -7
  262. package/src/components/List/Tree.stories.tsx +5 -5
  263. package/src/components/List/TreeDropIndicator.tsx +6 -6
  264. package/src/components/List/Treegrid.stories.tsx +3 -3
  265. package/src/components/List/Treegrid.tsx +10 -15
  266. package/src/components/Main/Main.stories.tsx +41 -23
  267. package/src/components/Main/Main.tsx +139 -82
  268. package/src/components/{Menus → Menu}/ContextMenu.stories.tsx +2 -2
  269. package/src/components/{Menus → Menu}/ContextMenu.tsx +9 -33
  270. package/src/components/{Menus → Menu}/DropdownMenu.stories.tsx +2 -2
  271. package/src/components/{Menus → Menu}/DropdownMenu.tsx +119 -109
  272. package/src/components/Message/Message.stories.tsx +28 -13
  273. package/src/components/Message/Message.tsx +43 -34
  274. package/src/components/Popover/Popover.stories.tsx +4 -4
  275. package/src/components/Popover/Popover.tsx +97 -92
  276. package/src/components/ScrollArea/ScrollArea.stories.tsx +222 -32
  277. package/src/components/ScrollArea/ScrollArea.tsx +97 -79
  278. package/src/components/ScrollArea/index.ts +1 -1
  279. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +43 -22
  280. package/src/components/ScrollContainer/ScrollContainer.tsx +193 -104
  281. package/src/components/Select/Select.stories.tsx +4 -4
  282. package/src/components/Select/Select.tsx +11 -27
  283. package/src/components/Separator/Separator.tsx +5 -8
  284. package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
  285. package/src/components/Skeleton/Skeleton.tsx +26 -0
  286. package/src/components/Skeleton/index.ts +5 -0
  287. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  288. package/src/components/Splitter/Splitter.tsx +140 -0
  289. package/src/components/Splitter/index.ts +5 -0
  290. package/src/components/Status/Status.stories.tsx +21 -17
  291. package/src/components/Status/Status.tsx +10 -7
  292. package/src/components/Tag/Tag.stories.tsx +6 -11
  293. package/src/components/Tag/Tag.tsx +3 -8
  294. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +32 -0
  295. package/src/components/ThemeProvider/ThemeProvider.tsx +10 -9
  296. package/src/components/ThemeProvider/TranslationsProvider.tsx +1 -16
  297. package/src/components/ThemeProvider/index.ts +3 -3
  298. package/src/components/Toast/Toast.stories.tsx +2 -2
  299. package/src/components/Toast/Toast.tsx +22 -41
  300. package/src/components/Toolbar/Toolbar.stories.tsx +2 -2
  301. package/src/components/Toolbar/Toolbar.tsx +183 -22
  302. package/src/components/Tooltip/Tooltip.stories.tsx +16 -14
  303. package/src/components/Tooltip/Tooltip.tsx +40 -38
  304. package/src/components/index.ts +11 -6
  305. package/src/exemplars/generics.stories.tsx +41 -0
  306. package/src/exemplars/slot.stories.tsx +117 -0
  307. package/src/exemplars/tabster.stories.tsx +127 -0
  308. package/src/exemplars/virtualizer.stories.tsx +137 -0
  309. package/src/hooks/index.ts +1 -0
  310. package/src/hooks/useDensityContext.ts +3 -3
  311. package/src/hooks/useElevationContext.ts +1 -1
  312. package/src/index.ts +2 -1
  313. package/src/playground/Controls.stories.tsx +3 -10
  314. package/src/playground/Custom.stories.tsx +11 -21
  315. package/src/playground/Typography.stories.tsx +3 -3
  316. package/src/primitives/Column/AUDIT.md +354 -0
  317. package/src/primitives/Column/Column.stories.tsx +183 -0
  318. package/src/primitives/Column/Column.tsx +169 -0
  319. package/src/primitives/Column/index.ts +5 -0
  320. package/src/primitives/Container/Container.stories.tsx +30 -0
  321. package/src/primitives/Container/Container.tsx +19 -0
  322. package/src/primitives/Container/index.ts +5 -0
  323. package/src/primitives/Flex/Flex.stories.tsx +58 -0
  324. package/src/primitives/Flex/Flex.tsx +24 -0
  325. package/src/primitives/Flex/index.ts +5 -0
  326. package/src/primitives/Grid/Grid.stories.tsx +57 -0
  327. package/src/primitives/Grid/Grid.tsx +30 -0
  328. package/src/primitives/Grid/index.ts +5 -0
  329. package/src/primitives/Panel/Panel.stories.tsx +67 -0
  330. package/src/primitives/Panel/Panel.tsx +114 -0
  331. package/src/primitives/Panel/index.ts +5 -0
  332. package/src/primitives/index.ts +9 -0
  333. package/src/testing/Loading.tsx +26 -0
  334. package/src/testing/decorators/withLayout.tsx +39 -18
  335. package/src/testing/decorators/withLayoutVariants.tsx +20 -23
  336. package/src/testing/decorators/withTheme.tsx +26 -20
  337. package/src/testing/index.ts +2 -0
  338. package/src/translations.ts +19 -0
  339. package/src/util/index.ts +2 -2
  340. package/src/util/usePx.ts +1 -0
  341. package/dist/lib/browser/chunk-53MI2QCM.mjs +0 -4707
  342. package/dist/lib/browser/chunk-53MI2QCM.mjs.map +0 -7
  343. package/dist/lib/node-esm/chunk-ID67AFFF.mjs +0 -4709
  344. package/dist/lib/node-esm/chunk-ID67AFFF.mjs.map +0 -7
  345. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  346. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  347. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  348. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  349. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +0 -1
  350. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +0 -1
  351. package/dist/types/src/components/Menus/DropdownMenu.d.ts +0 -113
  352. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +0 -1
  353. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +0 -1
  354. package/dist/types/src/components/Menus/index.d.ts.map +0 -1
  355. package/dist/types/src/util/ThemedClassName.d.ts +0 -5
  356. package/dist/types/src/util/ThemedClassName.d.ts.map +0 -1
  357. package/dist/types/src/util/domino.d.ts +0 -18
  358. package/dist/types/src/util/domino.d.ts.map +0 -1
  359. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  360. package/src/components/AnchoredOverflow/index.ts +0 -5
  361. package/src/util/ThemedClassName.ts +0 -7
  362. package/src/util/domino.ts +0 -53
  363. /package/dist/types/src/components/{Menus → Menu}/ContextMenu.stories.d.ts +0 -0
  364. /package/dist/types/src/components/{Menus → Menu}/index.d.ts +0 -0
  365. /package/src/components/{Menus → Menu}/index.ts +0 -0
@@ -2,149 +2,266 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
5
6
  import { createContext } from '@radix-ui/react-context';
6
- import {
7
- DialogClose as DialogClosePrimitive,
8
- type DialogCloseProps as DialogClosePrimitiveProps,
9
- DialogContent as DialogContentPrimitive,
10
- type DialogContentProps as DialogContentPrimitiveProps,
11
- DialogDescription as DialogDescriptionPrimitive,
12
- type DialogDescriptionProps as DialogDescriptionPrimitiveProps,
13
- DialogOverlay as DialogOverlayPrimitive,
14
- type DialogOverlayProps as DialogOverlayPrimitiveProps,
15
- DialogPortal as DialogPortalPrimitive,
16
- type DialogPortalProps as DialogPortalPrimitiveProps,
17
- Root as DialogRootPrimitive,
18
- type DialogProps as DialogRootPrimitiveProps,
19
- DialogTitle as DialogTitlePrimitive,
20
- type DialogTitleProps as DialogTitlePrimitiveProps,
21
- DialogTrigger as DialogTriggerPrimitive,
22
- type DialogTriggerProps as DialogTriggerPrimitiveProps,
23
- } from '@radix-ui/react-dialog';
24
- import React, { type ForwardRefExoticComponent, type FunctionComponent, forwardRef } from 'react';
7
+ import React, {
8
+ type ComponentPropsWithRef,
9
+ type ForwardRefExoticComponent,
10
+ type FunctionComponent,
11
+ type PropsWithChildren,
12
+ forwardRef,
13
+ } from 'react';
14
+ import { useTranslation } from 'react-i18next';
15
+
16
+ import { type DialogSize, osTranslations } from '@dxos/ui-theme';
25
17
 
26
18
  import { useThemeContext } from '../../hooks';
19
+ import { Column } from '../../primitives';
27
20
  import { type ThemedClassName } from '../../util';
21
+ import { IconButton } from '../Button';
28
22
  import { ElevationProvider } from '../ElevationProvider';
23
+ import { slottable } from '@dxos/ui-theme';
24
+ import { type SlottableProps } from '@dxos/ui-types';
25
+
26
+ //
27
+ // Root
28
+ //
29
29
 
30
- type DialogRootProps = DialogRootPrimitiveProps;
30
+ type DialogRootProps = DialogPrimitive.DialogProps;
31
31
 
32
32
  const DialogRoot: FunctionComponent<DialogRootProps> = (props) => (
33
33
  <ElevationProvider elevation='dialog'>
34
- <DialogRootPrimitive {...props} />
34
+ <DialogPrimitive.Root {...props} />
35
35
  </ElevationProvider>
36
36
  );
37
37
 
38
- type DialogTriggerProps = DialogTriggerPrimitiveProps;
39
-
40
- const DialogTrigger: FunctionComponent<DialogTriggerProps> = DialogTriggerPrimitive;
41
-
42
- type DialogPortalProps = DialogPortalPrimitiveProps;
38
+ //
39
+ // Trigger
40
+ //
43
41
 
44
- const DialogPortal: FunctionComponent<DialogPortalProps> = DialogPortalPrimitive;
42
+ type DialogTriggerProps = DialogPrimitive.DialogTriggerProps;
45
43
 
46
- type DialogTitleProps = ThemedClassName<DialogTitlePrimitiveProps> & { srOnly?: boolean };
44
+ const DialogTrigger: FunctionComponent<DialogTriggerProps> = DialogPrimitive.Trigger;
47
45
 
48
- const DialogTitle: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<HTMLHeadingElement, DialogTitleProps>(
49
- ({ classNames, srOnly, ...props }, forwardedRef) => {
50
- const { tx } = useThemeContext();
51
- return (
52
- <DialogTitlePrimitive
53
- {...props}
54
- className={tx('dialog.title', 'dialog__title', { srOnly }, classNames)}
55
- ref={forwardedRef}
56
- />
57
- );
58
- },
59
- );
46
+ //
47
+ // Portal
48
+ //
60
49
 
61
- type DialogDescriptionProps = ThemedClassName<DialogDescriptionPrimitiveProps> & { srOnly?: boolean };
50
+ type DialogPortalProps = DialogPrimitive.DialogPortalProps;
62
51
 
63
- const DialogDescription: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<
64
- HTMLParagraphElement,
65
- DialogDescriptionProps
66
- >(({ classNames, srOnly, ...props }, forwardedRef) => {
67
- const { tx } = useThemeContext();
68
- return (
69
- <DialogDescriptionPrimitive
70
- {...props}
71
- className={tx('dialog.description', 'dialog__description', { srOnly }, classNames)}
72
- ref={forwardedRef}
73
- />
74
- );
75
- });
52
+ const DialogPortal: FunctionComponent<DialogPortalProps> = DialogPrimitive.Portal;
76
53
 
77
- type DialogCloseProps = DialogClosePrimitiveProps;
54
+ //
55
+ // Overlay
56
+ //
78
57
 
79
- const DialogClose: FunctionComponent<DialogCloseProps> = DialogClosePrimitive;
58
+ const DIALOG_OVERLAY_NAME = 'DialogOverlay';
80
59
 
81
60
  type OverlayLayoutContextValue = { inOverlayLayout?: boolean };
82
- const DIALOG_OVERLAY_NAME = 'DialogOverlay';
83
- const DIALOG_CONTENT_NAME = 'DialogContent';
61
+
84
62
  const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLayoutContextValue>(
85
63
  DIALOG_OVERLAY_NAME,
86
64
  {},
87
65
  );
88
66
 
89
- type DialogOverlayProps = ThemedClassName<DialogOverlayPrimitiveProps & { blockAlign?: 'center' | 'start' | 'end' }>;
67
+ type DialogOverlayProps = ThemedClassName<
68
+ DialogPrimitive.DialogOverlayProps & { blockAlign?: 'center' | 'start' | 'end' }
69
+ >;
90
70
 
91
71
  const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<HTMLDivElement, DialogOverlayProps>(
92
72
  ({ classNames, children, blockAlign, ...props }, forwardedRef) => {
93
73
  const { tx } = useThemeContext();
94
74
 
95
75
  return (
96
- <DialogOverlayPrimitive
76
+ <DialogPrimitive.Overlay
97
77
  {...props}
98
- className={tx('dialog.overlay', 'dialog__overlay', {}, classNames)}
99
- ref={forwardedRef}
100
78
  data-block-align={blockAlign}
79
+ className={tx('dialog.overlay', {}, classNames)}
80
+ ref={forwardedRef}
101
81
  >
102
82
  <OverlayLayoutProvider inOverlayLayout>{children}</OverlayLayoutProvider>
103
- </DialogOverlayPrimitive>
83
+ </DialogPrimitive.Overlay>
104
84
  );
105
85
  },
106
86
  );
107
87
 
108
88
  DialogOverlay.displayName = DIALOG_OVERLAY_NAME;
109
89
 
110
- type DialogContentProps = ThemedClassName<DialogContentPrimitiveProps> & { inOverlayLayout?: boolean };
90
+ //
91
+ // Content
92
+ //
93
+
94
+ const DIALOG_CONTENT_NAME = 'DialogContent';
95
+
96
+ type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof DialogPrimitive.Content>> & {
97
+ size?: DialogSize;
98
+ inOverlayLayout?: boolean;
99
+ };
111
100
 
112
101
  const DialogContent: ForwardRefExoticComponent<DialogContentProps> = forwardRef<HTMLDivElement, DialogContentProps>(
113
- ({ classNames, children, inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
102
+ ({ classNames, children, size = 'md', inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
114
103
  const { tx } = useThemeContext();
115
104
  const { inOverlayLayout } = useOverlayLayoutContext(DIALOG_CONTENT_NAME);
116
105
 
117
106
  return (
118
- <DialogContentPrimitive
107
+ <DialogPrimitive.Content
108
+ {...props}
119
109
  // NOTE: Radix warning unless set to undefined.
120
110
  // https://www.radix-ui.com/primitives/docs/components/dialog#description
121
111
  aria-describedby={undefined}
122
- {...props}
123
112
  className={tx(
124
113
  'dialog.content',
125
- 'dialog',
126
- { inOverlayLayout: propsInOverlayLayout || inOverlayLayout },
114
+ {
115
+ size,
116
+ inOverlayLayout: propsInOverlayLayout || inOverlayLayout,
117
+ },
127
118
  classNames,
128
119
  )}
129
120
  ref={forwardedRef}
130
121
  >
131
- {children}
132
- </DialogContentPrimitive>
122
+ <Column.Root classNames='dx-expander' gutter='sm'>
123
+ {children}
124
+ </Column.Root>
125
+ </DialogPrimitive.Content>
133
126
  );
134
127
  },
135
128
  );
136
129
 
137
130
  DialogContent.displayName = DIALOG_CONTENT_NAME;
138
131
 
132
+ //
133
+ // Header
134
+ //
135
+
136
+ type DialogHeaderProps = PropsWithChildren;
137
+
138
+ const DialogHeader: ForwardRefExoticComponent<DialogHeaderProps> = forwardRef<HTMLHeadingElement, DialogHeaderProps>(
139
+ ({ children }, forwardedRef) => {
140
+ const { tx } = useThemeContext();
141
+ return (
142
+ <Column.Row className={tx('dialog.header')} center ref={forwardedRef}>
143
+ {children}
144
+ </Column.Row>
145
+ );
146
+ },
147
+ );
148
+
149
+ //
150
+ // CloseIconButton
151
+ //
152
+
153
+ type DialogCloseIconButtonProps = { label?: string };
154
+
155
+ const DialogCloseIconButton = forwardRef<HTMLButtonElement, DialogCloseIconButtonProps>(
156
+ ({ label, ...props }, forwardedRef) => {
157
+ const { t } = useTranslation(osTranslations);
158
+ return (
159
+ <IconButton
160
+ {...props}
161
+ label={label ?? t('close dialog label')}
162
+ icon='ph--x--regular'
163
+ iconOnly
164
+ size={4}
165
+ variant='ghost'
166
+ ref={forwardedRef}
167
+ />
168
+ );
169
+ },
170
+ );
171
+
172
+ //
173
+ // Body
174
+ //
175
+
176
+ type DialogBodyProps = SlottableProps;
177
+
178
+ const DialogBody = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
179
+ const { tx } = useThemeContext();
180
+ return (
181
+ <Column.Content {...props} asChild={asChild} className={tx('dialog.body', {})} ref={forwardedRef}>
182
+ {children}
183
+ </Column.Content>
184
+ );
185
+ });
186
+
187
+ //
188
+ // Title
189
+ //
190
+
191
+ type DialogTitleProps = ThemedClassName<DialogPrimitive.DialogTitleProps> & { srOnly?: boolean };
192
+
193
+ const DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(
194
+ ({ classNames, srOnly, ...props }, forwardedRef) => {
195
+ const { tx } = useThemeContext();
196
+ return (
197
+ <DialogPrimitive.Title {...props} className={tx('dialog.title', { srOnly }, classNames)} ref={forwardedRef} />
198
+ );
199
+ },
200
+ );
201
+
202
+ //
203
+ // Description
204
+ //
205
+
206
+ type DialogDescriptionProps = ThemedClassName<DialogPrimitive.DialogDescriptionProps> & { srOnly?: boolean };
207
+
208
+ const DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(
209
+ ({ classNames, srOnly, ...props }, forwardedRef) => {
210
+ const { tx } = useThemeContext();
211
+ return (
212
+ <DialogPrimitive.Description
213
+ {...props}
214
+ className={tx('dialog.description', { srOnly }, classNames)}
215
+ ref={forwardedRef}
216
+ />
217
+ );
218
+ },
219
+ );
220
+
221
+ //
222
+ // ActionBar
223
+ //
224
+
225
+ type DialogActionBarProps = ThemedClassName<PropsWithChildren>;
226
+
227
+ const DialogActionBar = forwardRef<HTMLDivElement, DialogActionBarProps>(
228
+ ({ children, classNames, ...props }, forwardedRef) => {
229
+ const { tx } = useThemeContext();
230
+ return (
231
+ <Column.Row center>
232
+ <div {...props} className={tx('dialog.actionbar', {}, classNames)} ref={forwardedRef}>
233
+ {children}
234
+ </div>
235
+ </Column.Row>
236
+ );
237
+ },
238
+ );
239
+
240
+ //
241
+ // Close
242
+ //
243
+
244
+ type DialogCloseProps = DialogPrimitive.DialogCloseProps;
245
+
246
+ const DialogClose: FunctionComponent<DialogCloseProps> = DialogPrimitive.Close;
247
+
248
+ //
249
+ // Dialog
250
+ //
251
+
139
252
  export const Dialog = {
140
253
  Root: DialogRoot,
141
254
  Trigger: DialogTrigger,
142
255
  Portal: DialogPortal,
143
256
  Overlay: DialogOverlay,
144
257
  Content: DialogContent,
258
+ Header: DialogHeader,
259
+ Body: DialogBody,
145
260
  Title: DialogTitle,
146
261
  Description: DialogDescription,
262
+ ActionBar: DialogActionBar,
147
263
  Close: DialogClose,
264
+ CloseIconButton: DialogCloseIconButton,
148
265
  };
149
266
 
150
267
  export type {
@@ -153,7 +270,11 @@ export type {
153
270
  DialogPortalProps,
154
271
  DialogOverlayProps,
155
272
  DialogContentProps,
273
+ DialogHeaderProps,
274
+ DialogBodyProps,
156
275
  DialogTitleProps,
157
276
  DialogDescriptionProps,
277
+ DialogActionBarProps,
158
278
  DialogCloseProps,
279
+ DialogCloseIconButtonProps,
159
280
  };
@@ -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,50 @@
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
+
12
+ import { ErrorFallback } from './ErrorFallback';
13
+ import { ThrowError } from './ThrowError';
14
+
15
+ const BasicStory = () => {
16
+ return (
17
+ <ErrorBoundary name='story' FallbackComponent={ErrorFallback}>
18
+ <ThrowError />
19
+ </ErrorBoundary>
20
+ );
21
+ };
22
+
23
+ const StringErrorStory = () => {
24
+ return <ErrorFallback error='This is a string error message' data={{ context: 'story' }} />;
25
+ };
26
+
27
+ const meta: Meta = {
28
+ title: 'ui/react-ui-core/components/ErrorFallback',
29
+ component: ErrorFallback,
30
+ decorators: [withTheme(), withLayout({ layout: 'column' })],
31
+ parameters: {
32
+ layout: 'fullscreen',
33
+ },
34
+ };
35
+
36
+ export default meta;
37
+
38
+ type Story = StoryObj<typeof meta>;
39
+
40
+ export const Default: Story = {
41
+ render: BasicStory,
42
+ play: async () => {
43
+ // This story intentionally renders an ErrorBoundary fallback; clear the smoke-test error flag.
44
+ (window as any).__ERROR_BOUNDARY_ERRORS__ = [];
45
+ },
46
+ };
47
+
48
+ export const StringError: Story = {
49
+ render: StringErrorStory,
50
+ };
@@ -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,80 @@
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
+ /**
13
+ * Renders a parsed error stack trace with tree connector symbols and clickable vscode:// links for local frames.
14
+ */
15
+ export const ErrorStack = ({ error }: { error: Error }) => {
16
+ const frames = ErrorStackParser.parse(error);
17
+
18
+ return (
19
+ <div className='font-mono text-sm'>
20
+ {frames.map((frame, i) => {
21
+ const isLast = i === frames.length - 1;
22
+ const local = frame.fileName
23
+ ? parseLocalFrame(frame.fileName, frame.lineNumber, frame.columnNumber)
24
+ : undefined;
25
+ const name = frame.functionName ?? '<anonymous>';
26
+ return (
27
+ <div
28
+ key={i}
29
+ className={mx(
30
+ 'grid grid-cols-[16px_1fr_auto_auto] items-stretch gap-x-2',
31
+ local && 'cursor-pointer hover:bg-hover-surface',
32
+ )}
33
+ >
34
+ {/* Tree connector: vertical line full-height + horizontal branch at midpoint */}
35
+ <div className='relative'>
36
+ <div
37
+ className={mx(
38
+ 'absolute left-1/2 -translate-x-1/2 w-px bg-neutral-500',
39
+ isLast ? 'top-0 h-1/2' : 'inset-y-0',
40
+ )}
41
+ />
42
+ <div className='absolute top-1/2 -translate-y-1/2 left-1/2 right-0 h-px bg-neutral-500' />
43
+ </div>
44
+ {local ? (
45
+ <a href={local.href} className='truncate self-center'>
46
+ {name}
47
+ </a>
48
+ ) : (
49
+ <span className='text-subdued truncate self-center'>{name}</span>
50
+ )}
51
+ <span className='text-xs text-subdued truncate self-center'>{local?.fileName ?? ''}</span>
52
+ <span className='text-xs text-subdued text-right self-center'>
53
+ {local ? `${frame.lineNumber}:${frame.columnNumber}` : ''}
54
+ </span>
55
+ </div>
56
+ );
57
+ })}
58
+ </div>
59
+ );
60
+ };
61
+
62
+ /**
63
+ * Parses a Vite `/@fs/` URL into a `vscode://` deep link and short filename.
64
+ * Returns undefined if the URL cannot be resolved to a local file.
65
+ */
66
+ const parseLocalFrame = (fileUrl: string, line?: number, col?: number): LocalFrame | undefined => {
67
+ try {
68
+ const { pathname } = new URL(fileUrl);
69
+ if (!pathname.startsWith('/@fs/')) {
70
+ return undefined;
71
+ }
72
+ const localPath = pathname.slice(4); // /@fs/Users/... → /Users/...
73
+ return {
74
+ href: `vscode://file/${localPath}:${line ?? 1}:${col ?? 1}`,
75
+ fileName: pathname.split('/').pop() ?? localPath,
76
+ };
77
+ } catch {
78
+ return undefined;
79
+ }
80
+ };
@@ -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`).