@dxos/react-ui 0.8.4-main.fd6878d → 0.8.4-staging.ac66bdf99f

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 (470) hide show
  1. package/dist/lib/browser/chunk-OCVRIJCH.mjs +848 -0
  2. package/dist/lib/browser/chunk-OCVRIJCH.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +4115 -60
  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 +112 -60
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/chunk-QUD5P3RU.mjs +850 -0
  9. package/dist/lib/node-esm/chunk-QUD5P3RU.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +4115 -60
  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 +112 -60
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  16. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  17. package/dist/types/src/components/Avatars/Avatar.stories.d.ts +5 -31
  18. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts +5 -11
  20. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  22. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts +8 -20
  23. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/{Buttons → Button}/Button.d.ts +4 -4
  25. package/dist/types/src/components/Button/Button.d.ts.map +1 -0
  26. package/dist/types/src/components/Button/Button.stories.d.ts +17 -0
  27. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -0
  28. package/dist/types/src/components/{Buttons → Button}/IconButton.d.ts +3 -3
  29. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -0
  30. package/dist/types/src/components/Button/IconButton.stories.d.ts +16 -0
  31. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -0
  32. package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +2 -2
  33. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -0
  34. package/dist/types/src/components/Button/Toggle.stories.d.ts +16 -0
  35. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -0
  36. package/dist/types/src/components/Button/ToggleGroup.d.ts +27 -0
  37. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -0
  38. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +27 -0
  39. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -0
  40. package/dist/types/src/components/Button/index.d.ts.map +1 -0
  41. package/dist/types/src/components/Card/Card.d.ts +120 -0
  42. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  43. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  44. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  45. package/dist/types/src/components/Card/index.d.ts +2 -0
  46. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  47. package/dist/types/src/components/Clipboard/CopyButton.d.ts +1 -1
  48. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  49. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  50. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  51. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts +1 -1
  52. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  53. package/dist/types/src/components/Dialog/AlertDialog.d.ts +51 -0
  54. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -0
  55. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts +11 -0
  56. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -0
  57. package/dist/types/src/components/Dialog/Dialog.d.ts +64 -0
  58. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -0
  59. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +25 -0
  60. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -0
  61. package/dist/types/src/components/Dialog/index.d.ts.map +1 -0
  62. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts +1 -1
  63. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  64. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  65. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  66. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  67. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  68. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +19 -0
  69. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  70. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  71. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  72. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  73. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  74. package/dist/types/src/components/Focus/Focus.d.ts +36 -0
  75. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  76. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  77. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  78. package/dist/types/src/components/Focus/index.d.ts +2 -0
  79. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  80. package/dist/types/src/components/Icon/Icon.d.ts +5 -2
  81. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  82. package/dist/types/src/components/Icon/Icon.stories.d.ts +25 -0
  83. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
  84. package/dist/types/src/components/Image/Image.d.ts +14 -0
  85. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  86. package/dist/types/src/components/Image/Image.stories.d.ts +33 -0
  87. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  88. package/dist/types/src/components/Image/index.d.ts +2 -0
  89. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  90. package/dist/types/src/components/Input/Input.d.ts +7 -9
  91. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  92. package/dist/types/src/components/Input/Input.stories.d.ts +16 -17
  93. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  94. package/dist/types/src/components/Link/Link.stories.d.ts +8 -8
  95. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  96. package/dist/types/src/components/{Lists → List}/List.d.ts +6 -4
  97. package/dist/types/src/components/List/List.d.ts.map +1 -0
  98. package/dist/types/src/components/List/List.stories.d.ts +16 -0
  99. package/dist/types/src/components/List/List.stories.d.ts.map +1 -0
  100. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -0
  101. package/dist/types/src/components/List/Tree.d.ts.map +1 -0
  102. package/dist/types/src/components/List/Tree.stories.d.ts +15 -0
  103. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -0
  104. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -0
  105. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts +5 -9
  106. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -0
  107. package/dist/types/src/components/List/Treegrid.stories.d.ts +12 -0
  108. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -0
  109. package/dist/types/src/components/List/index.d.ts.map +1 -0
  110. package/dist/types/src/components/Main/Main.d.ts +17 -27
  111. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  112. package/dist/types/src/components/Main/Main.stories.d.ts +6 -10
  113. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  114. package/dist/types/src/components/{Menus → Menu}/ContextMenu.d.ts +6 -6
  115. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -0
  116. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts +12 -0
  117. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -0
  118. package/dist/types/src/components/Menu/DropdownMenu.d.ts +113 -0
  119. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -0
  120. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +28 -0
  121. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -0
  122. package/dist/types/src/components/Menu/index.d.ts.map +1 -0
  123. package/dist/types/src/components/Message/Message.d.ts +1 -1
  124. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  125. package/dist/types/src/components/Message/Message.stories.d.ts +12 -22
  126. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  127. package/dist/types/src/components/Popover/Popover.d.ts +34 -25
  128. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  129. package/dist/types/src/components/Popover/Popover.stories.d.ts +6 -34
  130. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  131. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +27 -27
  132. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  133. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +50 -27
  134. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  135. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +60 -0
  136. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -0
  137. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +23 -0
  138. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -0
  139. package/dist/types/src/components/ScrollContainer/index.d.ts +2 -0
  140. package/dist/types/src/components/ScrollContainer/index.d.ts.map +1 -0
  141. package/dist/types/src/components/Select/Select.d.ts +10 -10
  142. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  143. package/dist/types/src/components/Select/Select.stories.d.ts +6 -11
  144. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  145. package/dist/types/src/components/Separator/Separator.d.ts +4 -4
  146. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  147. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  148. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  149. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  150. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  151. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  152. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  153. package/dist/types/src/components/Splitter/Splitter.d.ts +34 -0
  154. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  155. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  156. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  157. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  158. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  159. package/dist/types/src/components/Status/Status.d.ts +3 -4
  160. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  161. package/dist/types/src/components/Status/Status.stories.d.ts +6 -10
  162. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  163. package/dist/types/src/components/Tag/Tag.d.ts +1 -1
  164. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  165. package/dist/types/src/components/Tag/Tag.stories.d.ts +8 -13
  166. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  167. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +3 -3
  168. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  169. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  170. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  171. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -8
  172. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  173. package/dist/types/src/components/ThemeProvider/index.d.ts +2 -1
  174. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  175. package/dist/types/src/components/Toast/Toast.d.ts +19 -19
  176. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  177. package/dist/types/src/components/Toast/Toast.stories.d.ts +6 -44
  178. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  179. package/dist/types/src/components/Toolbar/Toolbar.d.ts +40 -22
  180. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  181. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +6 -50
  182. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  183. package/dist/types/src/components/Tooltip/Tooltip.d.ts +10 -12
  184. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  185. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +10 -63
  186. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  187. package/dist/types/src/components/index.d.ts +14 -8
  188. package/dist/types/src/components/index.d.ts.map +1 -1
  189. package/dist/types/src/exemplars/generics.stories.d.ts +19 -0
  190. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  191. package/dist/types/src/exemplars/slot.stories.d.ts +15 -0
  192. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  193. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  194. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  195. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  196. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  197. package/dist/types/src/hooks/index.d.ts +1 -0
  198. package/dist/types/src/hooks/index.d.ts.map +1 -1
  199. package/dist/types/src/hooks/useDensityContext.d.ts +2 -2
  200. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  201. package/dist/types/src/hooks/useElevationContext.d.ts +1 -1
  202. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  203. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  204. package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
  205. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  206. package/dist/types/src/index.d.ts +2 -1
  207. package/dist/types/src/index.d.ts.map +1 -1
  208. package/dist/types/src/playground/Controls.stories.d.ts +5 -9
  209. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  210. package/dist/types/src/playground/Custom.stories.d.ts +12 -4
  211. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  212. package/dist/types/src/playground/Typography.stories.d.ts +5 -11
  213. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  214. package/dist/types/src/primitives/Column/Column.d.ts +33 -0
  215. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  216. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  217. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  218. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  219. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  220. package/dist/types/src/primitives/Container/Container.d.ts +7 -0
  221. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  222. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  223. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  224. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  225. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  226. package/dist/types/src/primitives/Flex/Flex.d.ts +11 -0
  227. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  228. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  229. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  230. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  231. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  232. package/dist/types/src/primitives/Grid/Grid.d.ts +10 -0
  233. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  234. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  235. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  236. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  237. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  238. package/dist/types/src/primitives/Panel/Panel.d.ts +35 -0
  239. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  240. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  241. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  242. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  243. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  244. package/dist/types/src/primitives/index.d.ts +6 -0
  245. package/dist/types/src/primitives/index.d.ts.map +1 -0
  246. package/dist/types/src/testing/Loading.d.ts +9 -0
  247. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  248. package/dist/types/src/testing/decorators/index.d.ts +2 -1
  249. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  250. package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
  251. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
  252. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts +12 -0
  253. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
  254. package/dist/types/src/testing/decorators/withTheme.d.ts +5 -1
  255. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  256. package/dist/types/src/testing/index.d.ts +1 -0
  257. package/dist/types/src/testing/index.d.ts.map +1 -1
  258. package/dist/types/src/translations.d.ts +11 -0
  259. package/dist/types/src/translations.d.ts.map +1 -0
  260. package/dist/types/src/util/index.d.ts +2 -1
  261. package/dist/types/src/util/index.d.ts.map +1 -1
  262. package/dist/types/src/util/usePx.d.ts +8 -0
  263. package/dist/types/src/util/usePx.d.ts.map +1 -0
  264. package/dist/types/tsconfig.tsbuildinfo +1 -1
  265. package/package.json +43 -32
  266. package/src/components/Avatars/Avatar.stories.tsx +22 -16
  267. package/src/components/Avatars/Avatar.tsx +7 -15
  268. package/src/components/Avatars/AvatarGroup.stories.tsx +10 -8
  269. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +19 -16
  270. package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
  271. package/src/components/{Buttons → Button}/Button.stories.tsx +7 -10
  272. package/src/components/{Buttons → Button}/Button.tsx +12 -26
  273. package/src/components/{Buttons → Button}/IconButton.stories.tsx +17 -13
  274. package/src/components/{Buttons → Button}/IconButton.tsx +20 -16
  275. package/src/components/Button/Toggle.stories.tsx +36 -0
  276. package/src/components/{Buttons → Button}/Toggle.tsx +4 -4
  277. package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +10 -9
  278. package/src/components/Button/ToggleGroup.tsx +50 -0
  279. package/src/components/Card/Card.stories.tsx +151 -0
  280. package/src/components/Card/Card.tsx +493 -0
  281. package/src/components/Card/index.ts +5 -0
  282. package/src/components/Clipboard/CopyButton.tsx +8 -9
  283. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  284. package/src/components/Dialog/AlertDialog.stories.tsx +68 -0
  285. package/src/components/{Dialogs → Dialog}/AlertDialog.tsx +123 -82
  286. package/src/components/Dialog/Dialog.stories.tsx +177 -0
  287. package/src/components/Dialog/Dialog.tsx +285 -0
  288. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  289. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +45 -0
  290. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  291. package/src/components/ErrorFallback/ErrorStack.tsx +114 -0
  292. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  293. package/src/components/ErrorFallback/index.ts +9 -0
  294. package/src/components/Focus/AUDIT.md +43 -0
  295. package/src/components/Focus/Focus.stories.tsx +230 -0
  296. package/src/components/Focus/Focus.tsx +201 -0
  297. package/src/components/Focus/index.ts +5 -0
  298. package/src/components/Icon/Icon.stories.tsx +143 -0
  299. package/src/components/Icon/Icon.tsx +6 -2
  300. package/src/components/Image/Image.stories.tsx +86 -0
  301. package/src/components/Image/Image.tsx +223 -0
  302. package/src/components/Image/index.ts +5 -0
  303. package/src/components/Input/Input.stories.tsx +25 -48
  304. package/src/components/Input/Input.tsx +40 -76
  305. package/src/components/Link/Link.stories.tsx +10 -8
  306. package/src/components/Link/Link.tsx +2 -2
  307. package/src/components/{Lists → List}/List.stories.tsx +41 -44
  308. package/src/components/{Lists → List}/List.tsx +21 -22
  309. package/src/components/{Lists → List}/ListDropIndicator.tsx +7 -7
  310. package/src/components/{Lists → List}/Tree.stories.tsx +14 -13
  311. package/src/components/{Lists → List}/Tree.tsx +0 -1
  312. package/src/components/{Lists → List}/TreeDropIndicator.tsx +6 -6
  313. package/src/components/{Lists → List}/Treegrid.stories.tsx +39 -35
  314. package/src/components/List/Treegrid.tsx +188 -0
  315. package/src/components/Main/Main.stories.tsx +52 -28
  316. package/src/components/Main/Main.tsx +170 -100
  317. package/src/components/{Menus → Menu}/ContextMenu.stories.tsx +11 -10
  318. package/src/components/{Menus → Menu}/ContextMenu.tsx +10 -33
  319. package/src/components/{Menus → Menu}/DropdownMenu.stories.tsx +12 -11
  320. package/src/components/{Menus → Menu}/DropdownMenu.tsx +151 -114
  321. package/src/components/Message/Message.stories.tsx +35 -18
  322. package/src/components/Message/Message.tsx +43 -34
  323. package/src/components/Popover/Popover.stories.tsx +17 -16
  324. package/src/components/Popover/Popover.tsx +118 -96
  325. package/src/components/ScrollArea/ScrollArea.stories.tsx +223 -32
  326. package/src/components/ScrollArea/ScrollArea.tsx +97 -79
  327. package/src/components/ScrollArea/index.ts +1 -1
  328. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +91 -0
  329. package/src/components/ScrollContainer/ScrollContainer.tsx +347 -0
  330. package/src/components/ScrollContainer/index.ts +5 -0
  331. package/src/components/Select/Select.stories.tsx +19 -18
  332. package/src/components/Select/Select.tsx +16 -31
  333. package/src/components/Separator/Separator.tsx +5 -8
  334. package/src/components/Skeleton/Skeleton.stories.tsx +51 -0
  335. package/src/components/Skeleton/Skeleton.tsx +26 -0
  336. package/src/components/Skeleton/index.ts +5 -0
  337. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  338. package/src/components/Splitter/Splitter.tsx +127 -0
  339. package/src/components/Splitter/index.ts +5 -0
  340. package/src/components/Status/Status.stories.tsx +28 -23
  341. package/src/components/Status/Status.tsx +10 -7
  342. package/src/components/Tag/Tag.stories.tsx +16 -14
  343. package/src/components/Tag/Tag.tsx +3 -8
  344. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +31 -0
  345. package/src/components/ThemeProvider/ThemeProvider.tsx +10 -10
  346. package/src/components/ThemeProvider/TranslationsProvider.tsx +1 -16
  347. package/src/components/ThemeProvider/index.ts +3 -3
  348. package/src/components/Toast/Toast.stories.tsx +12 -11
  349. package/src/components/Toast/Toast.tsx +22 -41
  350. package/src/components/Toolbar/Toolbar.stories.tsx +14 -14
  351. package/src/components/Toolbar/Toolbar.tsx +185 -11
  352. package/src/components/Tooltip/Tooltip.stories.tsx +34 -30
  353. package/src/components/Tooltip/Tooltip.tsx +42 -39
  354. package/src/components/index.ts +15 -9
  355. package/src/exemplars/generics.stories.tsx +41 -0
  356. package/src/exemplars/slot.stories.tsx +117 -0
  357. package/src/exemplars/tabster.stories.tsx +127 -0
  358. package/src/exemplars/virtualizer.stories.tsx +137 -0
  359. package/src/hooks/index.ts +1 -0
  360. package/src/hooks/useDensityContext.ts +3 -3
  361. package/src/hooks/useElevationContext.ts +1 -1
  362. package/src/hooks/useSafeArea.ts +3 -2
  363. package/src/hooks/useVisualViewport.ts +4 -4
  364. package/src/index.ts +2 -1
  365. package/src/playground/Controls.stories.tsx +12 -15
  366. package/src/playground/Custom.stories.tsx +18 -32
  367. package/src/playground/Typography.stories.tsx +11 -9
  368. package/src/primitives/Column/AUDIT.md +148 -0
  369. package/src/primitives/Column/Column.stories.tsx +181 -0
  370. package/src/primitives/Column/Column.tsx +165 -0
  371. package/src/primitives/Column/index.ts +5 -0
  372. package/src/primitives/Container/Container.stories.tsx +29 -0
  373. package/src/primitives/Container/Container.tsx +19 -0
  374. package/src/primitives/Container/index.ts +5 -0
  375. package/src/primitives/Flex/Flex.stories.tsx +57 -0
  376. package/src/primitives/Flex/Flex.tsx +27 -0
  377. package/src/primitives/Flex/index.ts +5 -0
  378. package/src/primitives/Grid/Grid.stories.tsx +56 -0
  379. package/src/primitives/Grid/Grid.tsx +30 -0
  380. package/src/primitives/Grid/index.ts +5 -0
  381. package/src/primitives/Panel/Panel.stories.tsx +68 -0
  382. package/src/primitives/Panel/Panel.tsx +120 -0
  383. package/src/primitives/Panel/index.ts +5 -0
  384. package/src/primitives/index.ts +9 -0
  385. package/src/testing/Loading.tsx +47 -0
  386. package/src/testing/decorators/index.ts +2 -1
  387. package/src/testing/decorators/withLayout.tsx +77 -0
  388. package/src/testing/decorators/withLayoutVariants.tsx +48 -0
  389. package/src/testing/decorators/withTheme.tsx +37 -0
  390. package/src/testing/index.ts +2 -0
  391. package/src/translations.ts +19 -0
  392. package/src/util/index.ts +3 -1
  393. package/src/util/usePx.ts +62 -0
  394. package/dist/lib/browser/chunk-BKNGMGOK.mjs +0 -4373
  395. package/dist/lib/browser/chunk-BKNGMGOK.mjs.map +0 -7
  396. package/dist/lib/node-esm/chunk-D2HZS6F4.mjs +0 -4375
  397. package/dist/lib/node-esm/chunk-D2HZS6F4.mjs.map +0 -7
  398. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  399. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  400. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  401. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  402. package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
  403. package/dist/types/src/components/Buttons/Button.stories.d.ts +0 -12
  404. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
  405. package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
  406. package/dist/types/src/components/Buttons/IconButton.stories.d.ts +0 -22
  407. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
  408. package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
  409. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -19
  410. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
  411. package/dist/types/src/components/Buttons/ToggleGroup.d.ts +0 -28
  412. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
  413. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +0 -39
  414. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
  415. package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
  416. package/dist/types/src/components/Dialogs/AlertDialog.d.ts +0 -31
  417. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
  418. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +0 -43
  419. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
  420. package/dist/types/src/components/Dialogs/Dialog.d.ts +0 -31
  421. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
  422. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -48
  423. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
  424. package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
  425. package/dist/types/src/components/Lists/List.d.ts.map +0 -1
  426. package/dist/types/src/components/Lists/List.stories.d.ts +0 -37
  427. package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
  428. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
  429. package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
  430. package/dist/types/src/components/Lists/Tree.stories.d.ts +0 -41
  431. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
  432. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
  433. package/dist/types/src/components/Lists/Treegrid.d.ts.map +0 -1
  434. package/dist/types/src/components/Lists/Treegrid.stories.d.ts +0 -10
  435. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
  436. package/dist/types/src/components/Lists/index.d.ts.map +0 -1
  437. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +0 -1
  438. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +0 -50
  439. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +0 -1
  440. package/dist/types/src/components/Menus/DropdownMenu.d.ts +0 -112
  441. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +0 -1
  442. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +0 -50
  443. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +0 -1
  444. package/dist/types/src/components/Menus/index.d.ts.map +0 -1
  445. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts +0 -12
  446. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
  447. package/dist/types/src/util/ThemedClassName.d.ts +0 -5
  448. package/dist/types/src/util/ThemedClassName.d.ts.map +0 -1
  449. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  450. package/src/components/AnchoredOverflow/index.ts +0 -5
  451. package/src/components/Buttons/Toggle.stories.tsx +0 -34
  452. package/src/components/Buttons/ToggleGroup.tsx +0 -41
  453. package/src/components/Dialogs/AlertDialog.stories.tsx +0 -67
  454. package/src/components/Dialogs/Dialog.stories.tsx +0 -66
  455. package/src/components/Dialogs/Dialog.tsx +0 -159
  456. package/src/components/Lists/Treegrid.tsx +0 -152
  457. package/src/testing/decorators/withSurfaceVariantsLayout.tsx +0 -51
  458. package/src/testing/decorators/withTheme.ts +0 -25
  459. package/src/util/ThemedClassName.ts +0 -7
  460. /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
  461. /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
  462. /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
  463. /package/dist/types/src/components/{Lists → List}/Tree.d.ts +0 -0
  464. /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
  465. /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
  466. /package/dist/types/src/components/{Menus → Menu}/index.d.ts +0 -0
  467. /package/src/components/{Buttons → Button}/index.ts +0 -0
  468. /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
  469. /package/src/components/{Lists → List}/index.ts +0 -0
  470. /package/src/components/{Menus → Menu}/index.ts +0 -0
@@ -0,0 +1,347 @@
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
+ role='none'
280
+ data-visible={overflow}
281
+ className={mx(
282
+ // NOTE: Gradients may not be visible with dark reader extensions.
283
+ 'z-10 absolute top-0 inset-x-0 h-24 w-full',
284
+ 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
285
+ 'bg-gradient-to-b from-(--surface-bg) to-transparent pointer-events-none',
286
+ )}
287
+ />
288
+ );
289
+ };
290
+
291
+ Fade.displayName = FADE_NAME;
292
+
293
+ //
294
+ // ScrollDownButton
295
+ //
296
+
297
+ const SCROLL_DOWN_BUTTON_NAME = 'ScrollContainer.ScrollDownButton';
298
+
299
+ type ScrollDownButtonProps = ThemedClassName;
300
+
301
+ const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
302
+ const { pinned, controller } = useScrollContainerContext(SCROLL_DOWN_BUTTON_NAME);
303
+
304
+ return (
305
+ <div
306
+ role='none'
307
+ className={mx(
308
+ 'absolute bottom-2 right-4 opacity-100 transition-opacity duration-300',
309
+ pinned && 'opacity-0',
310
+ classNames,
311
+ )}
312
+ >
313
+ <IconButton
314
+ variant='primary'
315
+ icon='ph--arrow-down--regular'
316
+ iconOnly
317
+ size={4}
318
+ label='Scroll down'
319
+ onClick={() => controller?.scrollToBottom()}
320
+ />
321
+ </div>
322
+ );
323
+ };
324
+
325
+ ScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
326
+
327
+ //
328
+ // ScrollContainer
329
+ //
330
+
331
+ export { useScrollContainerContext };
332
+
333
+ export const ScrollContainer = {
334
+ Root,
335
+ Content,
336
+ Viewport,
337
+ Fade,
338
+ ScrollDownButton,
339
+ };
340
+
341
+ export type {
342
+ RootProps as ScrollContainerRootProps,
343
+ ContentProps as ScrollContainerContentProps,
344
+ ViewportProps as ScrollContainerViewportProps,
345
+ FadeProps as ScrollContainerFadeProps,
346
+ ScrollDownButtonProps as ScrollContainerScrollDownButtonProps,
347
+ };
@@ -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
- import { type StoryObj } from '@storybook/react-vite';
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}>
@@ -42,15 +40,18 @@ const DefaultStory = ({ items = [] }: StoryProps) => {
42
40
  );
43
41
  };
44
42
 
45
- export const Default: StoryObj<StoryProps> = {
43
+ const meta = {
44
+ title: 'ui/react-ui-core/components/Select',
45
+ render: DefaultStory,
46
+ decorators: [withTheme(), withLayoutVariants()],
47
+ } satisfies Meta<typeof DefaultStory>;
48
+
49
+ export default meta;
50
+
51
+ type Story = StoryObj<typeof meta>;
52
+
53
+ export const Default: Story = {
46
54
  args: {
47
- 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() })),
48
56
  },
49
57
  };
50
-
51
- export default {
52
- title: 'ui/react-ui-core/Select',
53
- render: DefaultStory,
54
- decorators: [withSurfaceVariantsLayout(), withTheme],
55
- parameters: { chromatic: { disableSnapshot: false } },
56
- };
@@ -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;
@@ -35,14 +35,13 @@ type SelectTriggerButtonProps = Omit<ButtonProps, 'children'> & Pick<SelectValue
35
35
 
36
36
  const SelectTriggerButton = forwardRef<HTMLButtonElement, SelectTriggerButtonProps>(
37
37
  ({ children, placeholder, ...props }, forwardedRef) => {
38
- const { tx } = useThemeContext();
39
38
  return (
40
39
  <SelectPrimitive.Trigger asChild ref={forwardedRef}>
41
40
  <Button {...props}>
42
41
  <SelectPrimitive.Value placeholder={placeholder}>{children}</SelectPrimitive.Value>
43
42
  <span className='w-1 flex-1' />
44
43
  <SelectPrimitive.Icon asChild>
45
- <Icon icon='ph--caret-down--bold' classNames={tx('select.triggerIcon', 'select__trigger__icon', {})} />
44
+ <Icon size={3} icon='ph--caret-down--bold' />
46
45
  </SelectPrimitive.Icon>
47
46
  </Button>
48
47
  </SelectPrimitive.Trigger>
@@ -60,8 +59,9 @@ const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
60
59
  return (
61
60
  <SelectPrimitive.Content
62
61
  {...props}
62
+ data-arrow-keys='up down'
63
63
  collisionPadding={safeCollisionPadding}
64
- className={tx('select.content', 'select__content', { elevation }, classNames)}
64
+ className={tx('select.content', { elevation }, classNames)}
65
65
  position='popper'
66
66
  ref={forwardedRef}
67
67
  >
@@ -79,10 +79,10 @@ const SelectScrollUpButton = forwardRef<HTMLDivElement, SelectScrollUpButtonProp
79
79
  return (
80
80
  <SelectPrimitive.SelectScrollUpButton
81
81
  {...props}
82
- className={tx('select.scrollButton', 'select__scroll-button--up', {}, classNames)}
82
+ className={tx('select.scrollButton', {}, classNames)}
83
83
  ref={forwardedRef}
84
84
  >
85
- {children ?? <Icon icon='ph--caret-up--bold' />}
85
+ {children ?? <Icon size={3} icon='ph--caret-up--bold' />}
86
86
  </SelectPrimitive.SelectScrollUpButton>
87
87
  );
88
88
  },
@@ -96,10 +96,10 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
96
96
  return (
97
97
  <SelectPrimitive.SelectScrollDownButton
98
98
  {...props}
99
- className={tx('select.scrollButton', 'select__scroll-button--down', {}, classNames)}
99
+ className={tx('select.scrollButton', {}, classNames)}
100
100
  ref={forwardedRef}
101
101
  >
102
- {children ?? <Icon icon='ph--caret-down--bold' />}
102
+ {children ?? <Icon size={3} icon='ph--caret-down--bold' />}
103
103
  </SelectPrimitive.SelectScrollDownButton>
104
104
  );
105
105
  },
@@ -108,14 +108,10 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
108
108
  type SelectViewportProps = ThemedClassName<SelectPrimitive.SelectViewportProps>;
109
109
 
110
110
  const SelectViewport = forwardRef<HTMLDivElement, SelectViewportProps>(
111
- ({ classNames, asChild, children, ...props }, forwardedRef) => {
111
+ ({ classNames, children, ...props }, forwardedRef) => {
112
112
  const { tx } = useThemeContext();
113
113
  return (
114
- <SelectPrimitive.SelectViewport
115
- {...props}
116
- className={tx('select.viewport', 'select__viewport', {}, classNames)}
117
- ref={forwardedRef}
118
- >
114
+ <SelectPrimitive.SelectViewport {...props} className={tx('select.viewport', {}, classNames)} ref={forwardedRef}>
119
115
  {children}
120
116
  </SelectPrimitive.SelectViewport>
121
117
  );
@@ -126,7 +122,7 @@ type SelectItemProps = ThemedClassName<SelectPrimitive.SelectItemProps>;
126
122
 
127
123
  const SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(({ classNames, ...props }, forwardedRef) => {
128
124
  const { tx } = useThemeContext();
129
- return <SelectPrimitive.Item {...props} className={tx('select.item', 'option', {}, classNames)} ref={forwardedRef} />;
125
+ return <SelectPrimitive.Item {...props} className={tx('select.item', {}, classNames)} ref={forwardedRef} />;
130
126
  });
131
127
 
132
128
  type SelectItemTextProps = SelectPrimitive.SelectItemTextProps;
@@ -141,7 +137,7 @@ const SelectItemIndicator = forwardRef<HTMLDivElement, SelectItemIndicatorProps>
141
137
  return (
142
138
  <SelectPrimitive.ItemIndicator
143
139
  {...props}
144
- className={tx('select.itemIndicator', 'option__indicator', {}, classNames)}
140
+ className={tx('select.itemIndicator', {}, classNames)}
145
141
  ref={forwardedRef}
146
142
  >
147
143
  {children}
@@ -152,10 +148,11 @@ const SelectItemIndicator = forwardRef<HTMLDivElement, SelectItemIndicatorProps>
152
148
 
153
149
  type SelectOptionProps = SelectItemProps;
154
150
 
151
+ // TODO(burdon): Option to show icon on left/right.
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';