@dxos/react-ui 0.8.4-main.f9ba587 → 0.8.4-main.fcc0d83b33

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