@dxos/react-ui 0.8.4-main.5ea62a8 → 0.8.4-main.60689f5b1c

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 (492) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/chunk-A5QCIG5R.mjs +24 -0
  4. package/dist/lib/browser/chunk-A5QCIG5R.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-LY5XDQR5.mjs +846 -0
  6. package/dist/lib/browser/chunk-LY5XDQR5.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +4427 -60
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/testing/index.mjs +106 -60
  11. package/dist/lib/browser/testing/index.mjs.map +4 -4
  12. package/dist/lib/browser/translations.mjs +9 -0
  13. package/dist/lib/browser/translations.mjs.map +7 -0
  14. package/dist/lib/node-esm/chunk-NGKLIKP3.mjs +848 -0
  15. package/dist/lib/node-esm/chunk-NGKLIKP3.mjs.map +7 -0
  16. package/dist/lib/node-esm/chunk-XCFLA74M.mjs +26 -0
  17. package/dist/lib/node-esm/chunk-XCFLA74M.mjs.map +7 -0
  18. package/dist/lib/node-esm/index.mjs +4427 -60
  19. package/dist/lib/node-esm/index.mjs.map +4 -4
  20. package/dist/lib/node-esm/meta.json +1 -1
  21. package/dist/lib/node-esm/testing/index.mjs +106 -60
  22. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  23. package/dist/lib/node-esm/translations.mjs +10 -0
  24. package/dist/lib/node-esm/translations.mjs.map +7 -0
  25. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  26. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  27. package/dist/types/src/components/Avatars/Avatar.stories.d.ts +0 -6
  28. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts +0 -6
  30. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  32. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts +0 -6
  33. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/{Buttons → Button}/Button.d.ts +4 -4
  35. package/dist/types/src/components/Button/Button.d.ts.map +1 -0
  36. package/dist/types/src/components/{Buttons → Button}/Button.stories.d.ts +2 -8
  37. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -0
  38. package/dist/types/src/components/{Buttons → Button}/IconButton.d.ts +4 -3
  39. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -0
  40. package/dist/types/src/components/{Buttons → Button}/IconButton.stories.d.ts +1 -4
  41. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -0
  42. package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +2 -2
  43. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -0
  44. package/dist/types/src/components/Button/Toggle.stories.d.ts +16 -0
  45. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -0
  46. package/dist/types/src/components/Button/ToggleGroup.d.ts +27 -0
  47. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -0
  48. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +27 -0
  49. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -0
  50. package/dist/types/src/components/Button/index.d.ts.map +1 -0
  51. package/dist/types/src/components/Card/Card.d.ts +124 -0
  52. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  53. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  54. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  55. package/dist/types/src/components/Card/index.d.ts +2 -0
  56. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  57. package/dist/types/src/components/Carousel/Carousel.d.ts +106 -0
  58. package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -0
  59. package/dist/types/src/components/Carousel/index.d.ts +2 -0
  60. package/dist/types/src/components/Carousel/index.d.ts.map +1 -0
  61. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  62. package/dist/types/src/components/Clipboard/CopyButton.d.ts +1 -1
  63. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  64. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  65. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  66. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts +1 -1
  67. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  68. package/dist/types/src/components/Dialog/AlertDialog.d.ts +51 -0
  69. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -0
  70. package/dist/types/src/components/{Dialogs → Dialog}/AlertDialog.stories.d.ts +0 -6
  71. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -0
  72. package/dist/types/src/components/Dialog/Dialog.d.ts +64 -0
  73. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -0
  74. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +25 -0
  75. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -0
  76. package/dist/types/src/components/Dialog/index.d.ts.map +1 -0
  77. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts +1 -1
  78. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  79. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  80. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  81. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  82. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  83. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +19 -0
  84. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  85. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  86. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  87. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  88. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  89. package/dist/types/src/components/Focus/Focus.d.ts +36 -0
  90. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  91. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  92. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  93. package/dist/types/src/components/Focus/index.d.ts +2 -0
  94. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  95. package/dist/types/src/components/Icon/Icon.d.ts +6 -2
  96. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  97. package/dist/types/src/components/Icon/Icon.stories.d.ts +25 -0
  98. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
  99. package/dist/types/src/components/Image/Image.d.ts +15 -0
  100. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  101. package/dist/types/src/components/Image/Image.stories.d.ts +34 -0
  102. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  103. package/dist/types/src/components/Image/index.d.ts +2 -0
  104. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  105. package/dist/types/src/components/Input/Input.d.ts +19 -24
  106. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  107. package/dist/types/src/components/Input/Input.stories.d.ts +8 -14
  108. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  109. package/dist/types/src/components/Link/Link.d.ts.map +1 -1
  110. package/dist/types/src/components/Link/Link.stories.d.ts +0 -6
  111. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  112. package/dist/types/src/components/{Lists → List}/List.d.ts +6 -4
  113. package/dist/types/src/components/List/List.d.ts.map +1 -0
  114. package/dist/types/src/components/{Lists → List}/List.stories.d.ts +3 -7
  115. package/dist/types/src/components/List/List.stories.d.ts.map +1 -0
  116. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -0
  117. package/dist/types/src/components/{Lists → List}/Tree.d.ts +2 -2
  118. package/dist/types/src/components/List/Tree.d.ts.map +1 -0
  119. package/dist/types/src/components/{Lists → List}/Tree.stories.d.ts +0 -6
  120. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -0
  121. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -0
  122. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts +5 -9
  123. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -0
  124. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -0
  125. package/dist/types/src/components/List/index.d.ts.map +1 -0
  126. package/dist/types/src/components/Main/Main.d.ts +24 -30
  127. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  128. package/dist/types/src/components/Main/Main.stories.d.ts +0 -4
  129. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  130. package/dist/types/src/components/Main/useSwipeToDismiss.d.ts.map +1 -1
  131. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts +46 -0
  132. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts.map +1 -0
  133. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts +16 -0
  134. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts.map +1 -0
  135. package/dist/types/src/components/MediaPlayer/index.d.ts +2 -0
  136. package/dist/types/src/components/MediaPlayer/index.d.ts.map +1 -0
  137. package/dist/types/src/components/{Menus → Menu}/ContextMenu.d.ts +6 -6
  138. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -0
  139. package/dist/types/src/components/{Menus → Menu}/ContextMenu.stories.d.ts +0 -6
  140. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -0
  141. package/dist/types/src/components/Menu/DropdownMenu.d.ts +121 -0
  142. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -0
  143. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +28 -0
  144. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -0
  145. package/dist/types/src/components/Menu/index.d.ts.map +1 -0
  146. package/dist/types/src/components/Message/Message.d.ts +2 -2
  147. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  148. package/dist/types/src/components/Message/Message.stories.d.ts +5 -7
  149. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  150. package/dist/types/src/components/Popover/Popover.d.ts +41 -24
  151. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  152. package/dist/types/src/components/Popover/Popover.stories.d.ts +0 -6
  153. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  154. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +27 -27
  155. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  156. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +55 -12
  157. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  158. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +68 -0
  159. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -0
  160. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +23 -0
  161. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -0
  162. package/dist/types/src/components/ScrollContainer/index.d.ts +2 -0
  163. package/dist/types/src/components/ScrollContainer/index.d.ts.map +1 -0
  164. package/dist/types/src/components/Select/Select.d.ts +10 -10
  165. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  166. package/dist/types/src/components/Select/Select.stories.d.ts +2 -8
  167. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  168. package/dist/types/src/components/Separator/Separator.d.ts +4 -4
  169. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  170. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  171. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  172. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  173. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  174. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  175. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  176. package/dist/types/src/components/Splitter/Splitter.d.ts +34 -0
  177. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  178. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  179. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  180. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  181. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  182. package/dist/types/src/components/Status/Status.d.ts +3 -4
  183. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  184. package/dist/types/src/components/Status/Status.stories.d.ts +4 -8
  185. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  186. package/dist/types/src/components/Tag/Tag.d.ts +1 -1
  187. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  188. package/dist/types/src/components/Tag/Tag.stories.d.ts +5 -10
  189. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  190. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +3 -3
  191. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  192. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  193. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  194. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +55 -63
  195. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  196. package/dist/types/src/components/ThemeProvider/index.d.ts +2 -1
  197. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  198. package/dist/types/src/components/Toast/Toast.d.ts +20 -20
  199. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  200. package/dist/types/src/components/Toast/Toast.stories.d.ts +0 -6
  201. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  202. package/dist/types/src/components/Toolbar/Toolbar.d.ts +41 -23
  203. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  204. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +0 -6
  205. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  206. package/dist/types/src/components/Tooltip/Tooltip.d.ts +16 -18
  207. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  208. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -8
  209. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  210. package/dist/types/src/components/index.d.ts +16 -8
  211. package/dist/types/src/components/index.d.ts.map +1 -1
  212. package/dist/types/src/exemplars/generics.stories.d.ts +19 -0
  213. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  214. package/dist/types/src/exemplars/slot.stories.d.ts +15 -0
  215. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  216. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  217. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  218. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  219. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  220. package/dist/types/src/hooks/index.d.ts +1 -0
  221. package/dist/types/src/hooks/index.d.ts.map +1 -1
  222. package/dist/types/src/hooks/useDensityContext.d.ts +2 -2
  223. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  224. package/dist/types/src/hooks/useElevationContext.d.ts +1 -1
  225. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  226. package/dist/types/src/hooks/useIconHref.d.ts.map +1 -1
  227. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  228. package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -1
  229. package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
  230. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  231. package/dist/types/src/index.d.ts +2 -1
  232. package/dist/types/src/index.d.ts.map +1 -1
  233. package/dist/types/src/playground/Controls.stories.d.ts +0 -6
  234. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  235. package/dist/types/src/playground/Custom.stories.d.ts +2 -3
  236. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  237. package/dist/types/src/playground/Typography.stories.d.ts +0 -6
  238. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  239. package/dist/types/src/primitives/Column/Column.d.ts +33 -0
  240. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  241. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  242. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  243. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  244. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  245. package/dist/types/src/primitives/Container/Container.d.ts +7 -0
  246. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  247. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  248. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  249. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  250. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  251. package/dist/types/src/primitives/Flex/Flex.d.ts +11 -0
  252. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  253. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  254. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  255. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  256. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  257. package/dist/types/src/primitives/Grid/Grid.d.ts +10 -0
  258. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  259. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  260. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  261. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  262. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  263. package/dist/types/src/primitives/Panel/Panel.d.ts +35 -0
  264. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  265. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  266. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  267. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  268. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  269. package/dist/types/src/primitives/index.d.ts +6 -0
  270. package/dist/types/src/primitives/index.d.ts.map +1 -0
  271. package/dist/types/src/testing/Loading.d.ts +9 -0
  272. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  273. package/dist/types/src/testing/decorators/index.d.ts +2 -1
  274. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  275. package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
  276. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
  277. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts +12 -0
  278. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
  279. package/dist/types/src/testing/decorators/withTheme.d.ts +5 -1
  280. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  281. package/dist/types/src/testing/index.d.ts +1 -0
  282. package/dist/types/src/testing/index.d.ts.map +1 -1
  283. package/dist/types/src/translations.d.ts +16 -0
  284. package/dist/types/src/translations.d.ts.map +1 -0
  285. package/dist/types/src/util/index.d.ts +2 -1
  286. package/dist/types/src/util/index.d.ts.map +1 -1
  287. package/dist/types/src/util/usePx.d.ts +8 -0
  288. package/dist/types/src/util/usePx.d.ts.map +1 -0
  289. package/dist/types/tsconfig.tsbuildinfo +1 -1
  290. package/package.json +53 -40
  291. package/src/components/Avatars/Avatar.stories.tsx +7 -11
  292. package/src/components/Avatars/Avatar.tsx +7 -15
  293. package/src/components/Avatars/AvatarGroup.stories.tsx +2 -6
  294. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +4 -8
  295. package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
  296. package/src/components/{Buttons → Button}/Button.stories.tsx +5 -8
  297. package/src/components/{Buttons → Button}/Button.tsx +12 -26
  298. package/src/components/{Buttons → Button}/IconButton.stories.tsx +8 -9
  299. package/src/components/{Buttons → Button}/IconButton.tsx +21 -16
  300. package/src/components/{Buttons → Button}/Toggle.stories.tsx +7 -10
  301. package/src/components/{Buttons → Button}/Toggle.tsx +4 -4
  302. package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +2 -6
  303. package/src/components/Button/ToggleGroup.tsx +50 -0
  304. package/src/components/Card/Card.stories.tsx +151 -0
  305. package/src/components/Card/Card.tsx +514 -0
  306. package/src/components/Card/index.ts +5 -0
  307. package/src/components/Carousel/Carousel.tsx +379 -0
  308. package/src/components/Carousel/index.ts +5 -0
  309. package/src/components/Clipboard/CopyButton.tsx +10 -11
  310. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  311. package/src/components/Dialog/AlertDialog.stories.tsx +68 -0
  312. package/src/components/{Dialogs → Dialog}/AlertDialog.tsx +123 -82
  313. package/src/components/Dialog/Dialog.stories.tsx +177 -0
  314. package/src/components/Dialog/Dialog.tsx +285 -0
  315. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  316. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +45 -0
  317. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  318. package/src/components/ErrorFallback/ErrorStack.tsx +114 -0
  319. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  320. package/src/components/ErrorFallback/index.ts +9 -0
  321. package/src/components/Focus/AUDIT.md +43 -0
  322. package/src/components/Focus/Focus.stories.tsx +230 -0
  323. package/src/components/Focus/Focus.tsx +201 -0
  324. package/src/components/Focus/index.ts +5 -0
  325. package/src/components/Icon/Icon.stories.tsx +143 -0
  326. package/src/components/Icon/Icon.tsx +15 -4
  327. package/src/components/Image/Image.stories.tsx +86 -0
  328. package/src/components/Image/Image.tsx +246 -0
  329. package/src/components/Image/index.ts +5 -0
  330. package/src/components/Input/Input.stories.tsx +21 -44
  331. package/src/components/Input/Input.tsx +40 -76
  332. package/src/components/Link/Link.stories.tsx +2 -6
  333. package/src/components/Link/Link.tsx +11 -3
  334. package/src/components/{Lists → List}/List.stories.tsx +31 -39
  335. package/src/components/{Lists → List}/List.tsx +17 -21
  336. package/src/components/{Lists → List}/ListDropIndicator.tsx +7 -8
  337. package/src/components/{Lists → List}/Tree.stories.tsx +6 -10
  338. package/src/components/{Lists → List}/Tree.tsx +0 -1
  339. package/src/components/{Lists → List}/TreeDropIndicator.tsx +6 -6
  340. package/src/components/{Lists → List}/Treegrid.stories.tsx +29 -30
  341. package/src/components/List/Treegrid.tsx +188 -0
  342. package/src/components/Main/Main.stories.tsx +41 -24
  343. package/src/components/Main/Main.tsx +163 -98
  344. package/src/components/MediaPlayer/MediaPlayer.stories.tsx +50 -0
  345. package/src/components/MediaPlayer/MediaPlayer.tsx +153 -0
  346. package/src/components/MediaPlayer/index.ts +5 -0
  347. package/src/components/{Menus → Menu}/ContextMenu.stories.tsx +2 -6
  348. package/src/components/{Menus → Menu}/ContextMenu.tsx +10 -33
  349. package/src/components/{Menus → Menu}/DropdownMenu.stories.tsx +3 -7
  350. package/src/components/{Menus → Menu}/DropdownMenu.tsx +151 -114
  351. package/src/components/Message/Message.stories.tsx +27 -15
  352. package/src/components/Message/Message.tsx +59 -33
  353. package/src/components/Popover/Popover.stories.tsx +8 -12
  354. package/src/components/Popover/Popover.tsx +118 -96
  355. package/src/components/ScrollArea/ScrollArea.stories.tsx +220 -38
  356. package/src/components/ScrollArea/ScrollArea.tsx +97 -79
  357. package/src/components/ScrollArea/index.ts +1 -1
  358. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +91 -0
  359. package/src/components/ScrollContainer/ScrollContainer.tsx +345 -0
  360. package/src/components/ScrollContainer/index.ts +5 -0
  361. package/src/components/Select/Select.stories.tsx +9 -12
  362. package/src/components/Select/Select.tsx +12 -27
  363. package/src/components/Separator/Separator.tsx +5 -8
  364. package/src/components/Skeleton/Skeleton.stories.tsx +51 -0
  365. package/src/components/Skeleton/Skeleton.tsx +26 -0
  366. package/src/components/Skeleton/index.ts +5 -0
  367. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  368. package/src/components/Splitter/Splitter.tsx +127 -0
  369. package/src/components/Splitter/index.ts +5 -0
  370. package/src/components/Status/Status.stories.tsx +21 -21
  371. package/src/components/Status/Status.tsx +10 -7
  372. package/src/components/Tag/Tag.stories.tsx +8 -13
  373. package/src/components/Tag/Tag.tsx +3 -8
  374. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +31 -0
  375. package/src/components/ThemeProvider/ThemeProvider.tsx +10 -10
  376. package/src/components/ThemeProvider/TranslationsProvider.tsx +1 -16
  377. package/src/components/ThemeProvider/index.ts +3 -3
  378. package/src/components/Toast/Toast.stories.tsx +3 -7
  379. package/src/components/Toast/Toast.tsx +22 -41
  380. package/src/components/Toolbar/Toolbar.stories.tsx +4 -10
  381. package/src/components/Toolbar/Toolbar.tsx +188 -12
  382. package/src/components/Tooltip/Tooltip.stories.tsx +21 -23
  383. package/src/components/Tooltip/Tooltip.tsx +56 -52
  384. package/src/components/index.ts +17 -9
  385. package/src/exemplars/generics.stories.tsx +41 -0
  386. package/src/exemplars/slot.stories.tsx +115 -0
  387. package/src/exemplars/tabster.stories.tsx +127 -0
  388. package/src/exemplars/virtualizer.stories.tsx +136 -0
  389. package/src/hooks/index.ts +1 -0
  390. package/src/hooks/useDensityContext.ts +3 -3
  391. package/src/hooks/useElevationContext.ts +1 -1
  392. package/src/hooks/useSafeArea.ts +3 -2
  393. package/src/hooks/useVisualViewport.ts +4 -4
  394. package/src/index.ts +2 -1
  395. package/src/playground/Controls.stories.tsx +3 -12
  396. package/src/playground/Custom.stories.tsx +16 -30
  397. package/src/playground/Typography.stories.tsx +3 -6
  398. package/src/primitives/Column/AUDIT.md +148 -0
  399. package/src/primitives/Column/Column.stories.tsx +181 -0
  400. package/src/primitives/Column/Column.tsx +165 -0
  401. package/src/primitives/Column/index.ts +5 -0
  402. package/src/primitives/Container/Container.stories.tsx +29 -0
  403. package/src/primitives/Container/Container.tsx +19 -0
  404. package/src/primitives/Container/index.ts +5 -0
  405. package/src/primitives/Flex/Flex.stories.tsx +57 -0
  406. package/src/primitives/Flex/Flex.tsx +27 -0
  407. package/src/primitives/Flex/index.ts +5 -0
  408. package/src/primitives/Grid/Grid.stories.tsx +56 -0
  409. package/src/primitives/Grid/Grid.tsx +30 -0
  410. package/src/primitives/Grid/index.ts +5 -0
  411. package/src/primitives/Panel/Panel.stories.tsx +68 -0
  412. package/src/primitives/Panel/Panel.tsx +120 -0
  413. package/src/primitives/Panel/index.ts +5 -0
  414. package/src/primitives/index.ts +9 -0
  415. package/src/testing/Loading.tsx +47 -0
  416. package/src/testing/decorators/index.ts +2 -1
  417. package/src/testing/decorators/withLayout.tsx +67 -0
  418. package/src/testing/decorators/withLayoutVariants.tsx +48 -0
  419. package/src/testing/decorators/withTheme.tsx +37 -0
  420. package/src/testing/index.ts +2 -0
  421. package/src/translations.ts +24 -0
  422. package/src/util/index.ts +3 -1
  423. package/src/util/usePx.ts +62 -0
  424. package/dist/lib/browser/chunk-P333G32W.mjs +0 -4374
  425. package/dist/lib/browser/chunk-P333G32W.mjs.map +0 -7
  426. package/dist/lib/node-esm/chunk-JRCE5UVS.mjs +0 -4376
  427. package/dist/lib/node-esm/chunk-JRCE5UVS.mjs.map +0 -7
  428. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  429. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  430. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  431. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  432. package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
  433. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
  434. package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
  435. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
  436. package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
  437. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -19
  438. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
  439. package/dist/types/src/components/Buttons/ToggleGroup.d.ts +0 -28
  440. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
  441. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +0 -37
  442. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
  443. package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
  444. package/dist/types/src/components/Dialogs/AlertDialog.d.ts +0 -31
  445. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
  446. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
  447. package/dist/types/src/components/Dialogs/Dialog.d.ts +0 -31
  448. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
  449. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -26
  450. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
  451. package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
  452. package/dist/types/src/components/Lists/List.d.ts.map +0 -1
  453. package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
  454. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
  455. package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
  456. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
  457. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
  458. package/dist/types/src/components/Lists/Treegrid.d.ts.map +0 -1
  459. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
  460. package/dist/types/src/components/Lists/index.d.ts.map +0 -1
  461. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +0 -1
  462. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +0 -1
  463. package/dist/types/src/components/Menus/DropdownMenu.d.ts +0 -112
  464. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +0 -1
  465. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +0 -21
  466. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +0 -1
  467. package/dist/types/src/components/Menus/index.d.ts.map +0 -1
  468. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts +0 -12
  469. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
  470. package/dist/types/src/util/ThemedClassName.d.ts +0 -5
  471. package/dist/types/src/util/ThemedClassName.d.ts.map +0 -1
  472. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  473. package/src/components/AnchoredOverflow/index.ts +0 -5
  474. package/src/components/Buttons/ToggleGroup.tsx +0 -41
  475. package/src/components/Dialogs/AlertDialog.stories.tsx +0 -72
  476. package/src/components/Dialogs/Dialog.stories.tsx +0 -65
  477. package/src/components/Dialogs/Dialog.tsx +0 -159
  478. package/src/components/Lists/Treegrid.tsx +0 -152
  479. package/src/testing/decorators/withSurfaceVariantsLayout.tsx +0 -51
  480. package/src/testing/decorators/withTheme.ts +0 -25
  481. package/src/util/ThemedClassName.ts +0 -7
  482. /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
  483. /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
  484. /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
  485. /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
  486. /package/dist/types/src/components/{Lists → List}/Treegrid.stories.d.ts +0 -0
  487. /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
  488. /package/dist/types/src/components/{Menus → Menu}/index.d.ts +0 -0
  489. /package/src/components/{Buttons → Button}/index.ts +0 -0
  490. /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
  491. /package/src/components/{Lists → List}/index.ts +0 -0
  492. /package/src/components/{Menus → Menu}/index.ts +0 -0
@@ -0,0 +1,345 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { createContext } from '@radix-ui/react-context';
6
+ import React, {
7
+ type PropsWithChildren,
8
+ type RefObject,
9
+ forwardRef,
10
+ useCallback,
11
+ useEffect,
12
+ useImperativeHandle,
13
+ useMemo,
14
+ useRef,
15
+ useState,
16
+ } from 'react';
17
+
18
+ import { addEventListener, combine } from '@dxos/async';
19
+ import { invariant } from '@dxos/invariant';
20
+ import { useMergeRefs } from '@dxos/react-hooks';
21
+ import { composable, composableProps, slottable } from '@dxos/ui-theme';
22
+ import { mx } from '@dxos/ui-theme';
23
+ import { type SlottableProps } from '@dxos/ui-types';
24
+
25
+ import { type ThemedClassName } from '../../util';
26
+ import { IconButton } from '../Button';
27
+ import { ScrollArea, type ScrollAreaRootProps } from '../ScrollArea';
28
+
29
+ const isBottom = (el: HTMLElement | null) => {
30
+ return !!(el && el.scrollHeight - el.scrollTop === el.clientHeight);
31
+ };
32
+
33
+ export interface ScrollController {
34
+ viewport: HTMLDivElement | null;
35
+ scrollToTop: (behavior?: ScrollBehavior) => void;
36
+ scrollToBottom: (behavior?: ScrollBehavior) => void;
37
+ }
38
+
39
+ type ScrollContainerContextValue = {
40
+ controller?: ScrollController;
41
+ pinned?: boolean;
42
+ overflow?: boolean;
43
+ /** Called by Viewport to register/unregister the scroll element. */
44
+ setViewport: (el: HTMLDivElement | null) => void;
45
+ /** Called by Viewport on wheel events to update pinned state. */
46
+ setPinned: (value: boolean) => void;
47
+ /** Called by Viewport on scroll events to update overflow state. */
48
+ setOverflow: (value: boolean) => void;
49
+ };
50
+
51
+ const [ScrollContainerProvider, useScrollContainerContext] =
52
+ createContext<ScrollContainerContextValue>('ScrollContainer');
53
+
54
+ //
55
+ // Root
56
+ //
57
+
58
+ type RootProps = PropsWithChildren<{
59
+ pin?: boolean;
60
+ behavior?: ScrollBehavior;
61
+ }>;
62
+
63
+ /**
64
+ * Headless scroll container that provides context for scroll state.
65
+ * Render ScrollContainer.Content and ScrollContainer.Viewport as children.
66
+ */
67
+ const Root = forwardRef<ScrollController, RootProps>(
68
+ ({ children, pin, behavior: behaviorProp = 'smooth' }, forwardedRef) => {
69
+ const scrollerRef = useRef<HTMLDivElement | null>(null);
70
+ const autoScrollRef = useRef(false);
71
+ const [pinned, setPinned] = useState(pin);
72
+ const [overflow, setOverflow] = useState(false);
73
+
74
+ const timeoutRef = useRef<NodeJS.Timeout>(undefined);
75
+ const scrollToBottom = useCallback(
76
+ (behavior: ScrollBehavior = behaviorProp) => {
77
+ if (scrollerRef.current) {
78
+ if (behavior !== 'instant') {
79
+ // Temporarily hide scrollbar to prevent flickering during smooth scroll.
80
+ // For instant scrolling we skip this — there's no animation to hide,
81
+ // and adding the class changes element size which re-fires the ResizeObserver.
82
+ autoScrollRef.current = true;
83
+ scrollerRef.current.classList.add('scrollbar-none');
84
+ clearTimeout(timeoutRef.current);
85
+ timeoutRef.current = setTimeout(() => {
86
+ scrollerRef.current?.classList.remove('scrollbar-none');
87
+ autoScrollRef.current = false;
88
+ }, 500);
89
+ }
90
+
91
+ scrollerRef.current.scrollTo({
92
+ top: scrollerRef.current.scrollHeight,
93
+ behavior,
94
+ });
95
+
96
+ setPinned(true);
97
+ }
98
+ },
99
+ [behaviorProp],
100
+ );
101
+
102
+ const controller = useMemo<ScrollController>(
103
+ () => ({
104
+ get viewport() {
105
+ return scrollerRef.current;
106
+ },
107
+ scrollToTop: () => {
108
+ invariant(scrollerRef.current);
109
+ scrollerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
110
+ setPinned(false);
111
+ },
112
+ scrollToBottom: (behavior = 'smooth' as ScrollBehavior) => {
113
+ scrollToBottom(behavior);
114
+ },
115
+ }),
116
+ [scrollToBottom],
117
+ );
118
+
119
+ // Scroll controller imperative ref.
120
+ useImperativeHandle(forwardedRef, () => controller, [controller]);
121
+
122
+ // Called by Viewport when the scroll element mounts/unmounts.
123
+ const setViewport = useCallback((el: HTMLDivElement | null) => {
124
+ scrollerRef.current = el;
125
+ }, []);
126
+
127
+ return (
128
+ <ScrollContainerProvider
129
+ pinned={pinned}
130
+ overflow={overflow}
131
+ controller={controller}
132
+ setViewport={setViewport}
133
+ setPinned={setPinned}
134
+ setOverflow={setOverflow}
135
+ >
136
+ {children}
137
+ </ScrollContainerProvider>
138
+ );
139
+ },
140
+ );
141
+
142
+ Root.displayName = 'ScrollContainer.Root';
143
+
144
+ //
145
+ // Content
146
+ //
147
+
148
+ type ContentProps = Pick<ScrollAreaRootProps, 'thin' | 'padding' | 'centered'>;
149
+
150
+ /**
151
+ * Composable wrapper around ScrollArea.Root.
152
+ * Provides the DOM structure for the scroll container.
153
+ */
154
+ const Content = composable<HTMLDivElement, ContentProps>(
155
+ ({ children, thin, padding, centered, ...props }, forwardedRef) => {
156
+ return (
157
+ <ScrollArea.Root
158
+ {...composableProps(props, { classNames: 'relative' })}
159
+ thin={thin}
160
+ padding={padding}
161
+ centered={centered}
162
+ ref={forwardedRef}
163
+ >
164
+ {children}
165
+ </ScrollArea.Root>
166
+ );
167
+ },
168
+ );
169
+
170
+ Content.displayName = 'ScrollContainer.Content';
171
+
172
+ //
173
+ // Viewport
174
+ //
175
+
176
+ const VIEWPORT_NAME = 'ScrollContainer.Viewport';
177
+
178
+ type ViewportProps = SlottableProps;
179
+
180
+ const Viewport = slottable<HTMLDivElement, ViewportProps>(({ children, asChild, ...props }, forwardedRef) => {
181
+ const scrollerRef = useRef<HTMLDivElement>(null);
182
+ const mergedRef = useMergeRefs([forwardedRef, scrollerRef]);
183
+ const { setViewport, setPinned, setOverflow } = useScrollContainerContext(VIEWPORT_NAME);
184
+
185
+ // Register the scroll element with Root and set up wheel/scroll listeners.
186
+ useEffect(() => {
187
+ const el = scrollerRef.current;
188
+ if (!el) {
189
+ return;
190
+ }
191
+
192
+ setViewport(el);
193
+
194
+ return combine(
195
+ addEventListener(el, 'wheel', () => setPinned(isBottom(el))),
196
+ addEventListener(el, 'scroll', () => setOverflow((el.scrollTop ?? 0) > 0)),
197
+ () => setViewport(null),
198
+ );
199
+ }, [setViewport, setPinned, setOverflow]);
200
+
201
+ return (
202
+ <>
203
+ <ScrollArea.Viewport asChild={asChild} {...composableProps(props)} ref={mergedRef}>
204
+ {children}
205
+ </ScrollArea.Viewport>
206
+ <PinEffect scrollerRef={scrollerRef} />
207
+ </>
208
+ );
209
+ });
210
+
211
+ Viewport.displayName = VIEWPORT_NAME;
212
+
213
+ /**
214
+ * Isolated component that consumes pinned/controller from context.
215
+ * Kept separate so that Viewport does not re-render when pinned changes.
216
+ */
217
+ const PIN_EFFECT_NAME = 'ScrollContainer.PinEffect';
218
+
219
+ const PinEffect = ({ scrollerRef }: { scrollerRef: RefObject<HTMLDivElement | null> }) => {
220
+ const { pinned, controller } = useScrollContainerContext(PIN_EFFECT_NAME);
221
+
222
+ // Pin scroll to bottom when content changes.
223
+ useEffect(() => {
224
+ const viewport = scrollerRef.current;
225
+ if (!pinned || !viewport) {
226
+ return;
227
+ }
228
+
229
+ // Scroll instantly so we don't visually jump while content is being added.
230
+ controller?.scrollToBottom('instant');
231
+
232
+ // Setup resize observer on content children to detect size changes (e.g. streaming).
233
+ // We observe children rather than the viewport itself, because the viewport's size
234
+ // stays fixed — only its content grows.
235
+ // Use instant scroll in the callback — smooth scrolling adds/removes the
236
+ // scrollbar-none class, which changes the element size and re-fires the
237
+ // observer, creating an infinite loop.
238
+ const resizeObserver = new ResizeObserver(() => controller?.scrollToBottom('smooth'));
239
+ Array.from(viewport.children).forEach((child) => {
240
+ resizeObserver.observe(child);
241
+ });
242
+
243
+ // Watch for added/removed children.
244
+ const mutationObserver = new MutationObserver((mutations) => {
245
+ mutations.forEach((mutation) => {
246
+ mutation.addedNodes.forEach((node) => {
247
+ if (node instanceof Element) {
248
+ resizeObserver.observe(node);
249
+ }
250
+ });
251
+ });
252
+
253
+ controller?.scrollToBottom('smooth');
254
+ });
255
+ mutationObserver.observe(viewport, { childList: true });
256
+
257
+ return () => {
258
+ resizeObserver.disconnect();
259
+ mutationObserver.disconnect();
260
+ };
261
+ }, [pinned, controller, scrollerRef]);
262
+
263
+ return null;
264
+ };
265
+
266
+ //
267
+ // Fade
268
+ //
269
+
270
+ const FADE_NAME = 'ScrollContainer.Fade';
271
+
272
+ type FadeProps = {};
273
+
274
+ const Fade = () => {
275
+ const { overflow } = useScrollContainerContext(FADE_NAME);
276
+
277
+ return (
278
+ <div
279
+ data-visible={overflow}
280
+ className={mx(
281
+ // NOTE: Gradients may not be visible with dark reader extensions.
282
+ 'z-10 absolute top-0 inset-x-0 h-24 w-full',
283
+ 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
284
+ 'bg-gradient-to-b from-(--color-base-surface) to-transparent pointer-events-none',
285
+ )}
286
+ />
287
+ );
288
+ };
289
+
290
+ Fade.displayName = FADE_NAME;
291
+
292
+ //
293
+ // ScrollDownButton
294
+ //
295
+
296
+ const SCROLL_DOWN_BUTTON_NAME = 'ScrollContainer.ScrollDownButton';
297
+
298
+ type ScrollDownButtonProps = ThemedClassName;
299
+
300
+ const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
301
+ const { pinned, controller } = useScrollContainerContext(SCROLL_DOWN_BUTTON_NAME);
302
+
303
+ return (
304
+ <div
305
+ className={mx(
306
+ 'absolute bottom-2 right-4 opacity-100 transition-opacity duration-300',
307
+ pinned && 'opacity-0',
308
+ classNames,
309
+ )}
310
+ >
311
+ <IconButton
312
+ variant='primary'
313
+ icon='ph--arrow-down--regular'
314
+ iconOnly
315
+ size={4}
316
+ label='Scroll down'
317
+ onClick={() => controller?.scrollToBottom()}
318
+ />
319
+ </div>
320
+ );
321
+ };
322
+
323
+ ScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
324
+
325
+ //
326
+ // ScrollContainer
327
+ //
328
+
329
+ export { useScrollContainerContext };
330
+
331
+ export const ScrollContainer = {
332
+ Root,
333
+ Content,
334
+ Viewport,
335
+ Fade,
336
+ ScrollDownButton,
337
+ };
338
+
339
+ export type {
340
+ RootProps as ScrollContainerRootProps,
341
+ ContentProps as ScrollContainerContentProps,
342
+ ViewportProps as ScrollContainerViewportProps,
343
+ FadeProps as ScrollContainerFadeProps,
344
+ ScrollDownButtonProps as ScrollContainerScrollDownButtonProps,
345
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './ScrollContainer';
@@ -2,24 +2,22 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React, { useState } from 'react';
9
7
 
10
- import { faker } from '@dxos/random';
11
-
12
- import { withSurfaceVariantsLayout, withTheme } from '../../testing';
8
+ import { random } from '@dxos/random';
13
9
 
10
+ import { withTheme } from '../../testing';
11
+ import { withLayoutVariants } from '../../testing';
14
12
  import { Select } from './Select';
15
13
 
16
- faker.seed(1234);
14
+ random.seed(1234);
17
15
 
18
16
  type ItemProps = { id: string; text: string };
19
17
 
20
- type StoryProps = { items: ItemProps[] };
18
+ type DefaultStoryProps = { items: ItemProps[] };
21
19
 
22
- const DefaultStory = ({ items = [] }: StoryProps) => {
20
+ const DefaultStory = ({ items = [] }: DefaultStoryProps) => {
23
21
  const [value, setValue] = useState<string>();
24
22
  return (
25
23
  <Select.Root value={value} onValueChange={setValue}>
@@ -43,10 +41,9 @@ const DefaultStory = ({ items = [] }: StoryProps) => {
43
41
  };
44
42
 
45
43
  const meta = {
46
- title: 'ui/react-ui-core/Select',
44
+ title: 'ui/react-ui-core/components/Select',
47
45
  render: DefaultStory,
48
- decorators: [withSurfaceVariantsLayout(), withTheme],
49
- parameters: { chromatic: { disableSnapshot: false } },
46
+ decorators: [withTheme(), withLayoutVariants()],
50
47
  } satisfies Meta<typeof DefaultStory>;
51
48
 
52
49
  export default meta;
@@ -55,6 +52,6 @@ type Story = StoryObj<typeof meta>;
55
52
 
56
53
  export const Default: Story = {
57
54
  args: {
58
- items: Array.from({ length: 16 }).map((_, i) => ({ id: `item-${i}`, text: faker.lorem.word() })),
55
+ items: Array.from({ length: 16 }).map((_, i) => ({ id: `item-${i}`, text: random.lorem.word() })),
59
56
  },
60
57
  };
@@ -8,7 +8,7 @@ import React, { forwardRef } from 'react';
8
8
  import { useElevationContext, useThemeContext } from '../../hooks';
9
9
  import { useSafeCollisionPadding } from '../../hooks/useSafeCollisionPadding';
10
10
  import { type ThemedClassName } from '../../util';
11
- import { Button, type ButtonProps } from '../Buttons';
11
+ import { Button, type ButtonProps } from '../Button';
12
12
  import { Icon } from '../Icon';
13
13
 
14
14
  type SelectRootProps = SelectPrimitive.SelectProps;
@@ -59,8 +59,9 @@ const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
59
59
  return (
60
60
  <SelectPrimitive.Content
61
61
  {...props}
62
+ data-arrow-keys='up down'
62
63
  collisionPadding={safeCollisionPadding}
63
- className={tx('select.content', 'select__content', { elevation }, classNames)}
64
+ className={tx('select.content', { elevation }, classNames)}
64
65
  position='popper'
65
66
  ref={forwardedRef}
66
67
  >
@@ -78,7 +79,7 @@ const SelectScrollUpButton = forwardRef<HTMLDivElement, SelectScrollUpButtonProp
78
79
  return (
79
80
  <SelectPrimitive.SelectScrollUpButton
80
81
  {...props}
81
- className={tx('select.scrollButton', 'select__scroll-button--up', {}, classNames)}
82
+ className={tx('select.scrollButton', {}, classNames)}
82
83
  ref={forwardedRef}
83
84
  >
84
85
  {children ?? <Icon size={3} icon='ph--caret-up--bold' />}
@@ -95,7 +96,7 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
95
96
  return (
96
97
  <SelectPrimitive.SelectScrollDownButton
97
98
  {...props}
98
- className={tx('select.scrollButton', 'select__scroll-button--down', {}, classNames)}
99
+ className={tx('select.scrollButton', {}, classNames)}
99
100
  ref={forwardedRef}
100
101
  >
101
102
  {children ?? <Icon size={3} icon='ph--caret-down--bold' />}
@@ -107,14 +108,10 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
107
108
  type SelectViewportProps = ThemedClassName<SelectPrimitive.SelectViewportProps>;
108
109
 
109
110
  const SelectViewport = forwardRef<HTMLDivElement, SelectViewportProps>(
110
- ({ classNames, asChild, children, ...props }, forwardedRef) => {
111
+ ({ classNames, children, ...props }, forwardedRef) => {
111
112
  const { tx } = useThemeContext();
112
113
  return (
113
- <SelectPrimitive.SelectViewport
114
- {...props}
115
- className={tx('select.viewport', 'select__viewport', {}, classNames)}
116
- ref={forwardedRef}
117
- >
114
+ <SelectPrimitive.SelectViewport {...props} className={tx('select.viewport', {}, classNames)} ref={forwardedRef}>
118
115
  {children}
119
116
  </SelectPrimitive.SelectViewport>
120
117
  );
@@ -125,7 +122,7 @@ type SelectItemProps = ThemedClassName<SelectPrimitive.SelectItemProps>;
125
122
 
126
123
  const SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(({ classNames, ...props }, forwardedRef) => {
127
124
  const { tx } = useThemeContext();
128
- return <SelectPrimitive.Item {...props} className={tx('select.item', 'option', {}, classNames)} ref={forwardedRef} />;
125
+ return <SelectPrimitive.Item {...props} className={tx('select.item', {}, classNames)} ref={forwardedRef} />;
129
126
  });
130
127
 
131
128
  type SelectItemTextProps = SelectPrimitive.SelectItemTextProps;
@@ -140,7 +137,7 @@ const SelectItemIndicator = forwardRef<HTMLDivElement, SelectItemIndicatorProps>
140
137
  return (
141
138
  <SelectPrimitive.ItemIndicator
142
139
  {...props}
143
- className={tx('select.itemIndicator', 'option__indicator', {}, classNames)}
140
+ className={tx('select.itemIndicator', {}, classNames)}
144
141
  ref={forwardedRef}
145
142
  >
146
143
  {children}
@@ -155,7 +152,7 @@ type SelectOptionProps = SelectItemProps;
155
152
  const SelectOption = forwardRef<HTMLDivElement, SelectItemProps>(({ children, classNames, ...props }, forwardedRef) => {
156
153
  const { tx } = useThemeContext();
157
154
  return (
158
- <SelectPrimitive.Item {...props} className={tx('select.item', 'option', {}, classNames)} ref={forwardedRef}>
155
+ <SelectPrimitive.Item {...props} className={tx('select.item', {}, classNames)} ref={forwardedRef}>
159
156
  <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
160
157
  <span className='grow w-1' />
161
158
  {/* <SelectPrimitive.ItemIndicator className={tx('select.itemIndicator', 'option__indicator', {})}> */}
@@ -177,26 +174,14 @@ type SelectSeparatorProps = ThemedClassName<SelectPrimitive.SelectSeparatorProps
177
174
 
178
175
  const SelectSeparator = forwardRef<HTMLDivElement, SelectSeparatorProps>(({ classNames, ...props }, forwardedRef) => {
179
176
  const { tx } = useThemeContext();
180
- return (
181
- <SelectPrimitive.Separator
182
- {...props}
183
- className={tx('select.separator', 'select__separator', {}, classNames)}
184
- ref={forwardedRef}
185
- />
186
- );
177
+ return <SelectPrimitive.Separator {...props} className={tx('select.separator', {}, classNames)} ref={forwardedRef} />;
187
178
  });
188
179
 
189
180
  type SelectArrowProps = ThemedClassName<SelectPrimitive.SelectArrowProps>;
190
181
 
191
182
  const SelectArrow = forwardRef<SVGSVGElement, SelectArrowProps>(({ classNames, ...props }, forwardedRef) => {
192
183
  const { tx } = useThemeContext();
193
- return (
194
- <SelectPrimitive.Arrow
195
- {...props}
196
- className={tx('select.arrow', 'select__arrow', {}, classNames)}
197
- ref={forwardedRef}
198
- />
199
- );
184
+ return <SelectPrimitive.Arrow {...props} className={tx('select.arrow', {}, classNames)} ref={forwardedRef} />;
200
185
  });
201
186
 
202
187
  export const Select = {
@@ -1,25 +1,22 @@
1
1
  //
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
- import {
5
- Separator as SeparatorPrimitive,
6
- type SeparatorProps as SeparatorPrimitiveProps,
7
- } from '@radix-ui/react-separator';
4
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
8
5
  import React, { forwardRef } from 'react';
9
6
 
10
7
  import { useThemeContext } from '../../hooks';
11
8
  import { type ThemedClassName } from '../../util';
12
9
 
13
- type SeparatorProps = ThemedClassName<SeparatorPrimitiveProps> & { subdued?: boolean };
10
+ type SeparatorProps = ThemedClassName<SeparatorPrimitive.SeparatorProps> & { subdued?: boolean };
14
11
 
15
12
  const Separator = forwardRef<HTMLDivElement, SeparatorProps>(
16
13
  ({ classNames, orientation = 'horizontal', subdued, ...props }, forwardedRef) => {
17
14
  const { tx } = useThemeContext();
18
15
  return (
19
- <SeparatorPrimitive
20
- orientation={orientation}
16
+ <SeparatorPrimitive.Root
21
17
  {...props}
22
- className={tx('separator.root', 'separator', { orientation, subdued }, classNames)}
18
+ orientation={orientation}
19
+ className={tx('separator.root', { orientation, subdued }, classNames)}
23
20
  ref={forwardedRef}
24
21
  />
25
22
  );
@@ -0,0 +1,51 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { withTheme } from '../../testing';
8
+ import { Skeleton } from './Skeleton';
9
+
10
+ export default {
11
+ title: 'ui/react-ui-core/components/Skeleton',
12
+ component: Skeleton,
13
+ decorators: [withTheme()],
14
+ parameters: {
15
+ layout: 'centered',
16
+ },
17
+ };
18
+
19
+ export const Default = {
20
+ render: () => (
21
+ <div className='flex flex-col gap-4 p-4 border border-separator rounded-xs'>
22
+ <div className='flex w-fit items-center gap-4'>
23
+ <Skeleton classNames='size-10 shrink-0 rounded-full' />
24
+ <div className='grid gap-2'>
25
+ <Skeleton classNames='h-4 w-[150px]' />
26
+ <Skeleton classNames='h-4 w-[100px]' />
27
+ </div>
28
+ </div>
29
+ </div>
30
+ ),
31
+ };
32
+
33
+ export const Card = {
34
+ render: () => (
35
+ <div className='flex flex-col gap-3 w-96 p-4 border border-separator rounded-xs'>
36
+ <div className='flex items-center gap-3'>
37
+ <Skeleton variant='circle' classNames='h-12 w-12 rounded-full' />
38
+ <div className='flex flex-col gap-2 flex-1'>
39
+ <Skeleton classNames='h-4 w-24' />
40
+ <Skeleton classNames='h-3 w-32' />
41
+ </div>
42
+ </div>
43
+ <Skeleton classNames='h-32 w-full rounded-sm' />
44
+ <div className='flex flex-col gap-2'>
45
+ <Skeleton classNames='h-3 w-full' />
46
+ <Skeleton classNames='h-3 w-5/6' />
47
+ <Skeleton classNames='h-3 w-4/6' />
48
+ </div>
49
+ </div>
50
+ ),
51
+ };
@@ -0,0 +1,26 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { type ComponentPropsWithRef, forwardRef } from 'react';
6
+
7
+ import { useThemeContext } from '../../hooks';
8
+ import { type ThemedClassName } from '../../util';
9
+
10
+ type SkeletonProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
11
+ variant?: 'default' | 'circle' | 'text';
12
+ };
13
+
14
+ /**
15
+ * A skeleton loading component that displays a placeholder while content is loading.
16
+ */
17
+ const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(
18
+ ({ classNames, variant = 'default', ...props }, forwardedRef) => {
19
+ const { tx } = useThemeContext();
20
+ return <div {...props} className={tx('skeleton.root', { variant }, classNames)} ref={forwardedRef} />;
21
+ },
22
+ );
23
+
24
+ export { Skeleton };
25
+
26
+ export type { SkeletonProps };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './Skeleton';