@dxos/react-ui 0.8.4-main.2e9d522 → 0.8.4-main.3c1ae3b

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 (280) hide show
  1. package/dist/lib/browser/{chunk-2COVUP44.mjs → chunk-BFCXP6YC.mjs} +656 -319
  2. package/dist/lib/browser/chunk-BFCXP6YC.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +12 -1
  4. package/dist/lib/browser/index.mjs.map +2 -2
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +57 -29
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/{chunk-GHXHND5V.mjs → chunk-F4Z46DD6.mjs} +656 -319
  9. package/dist/lib/node-esm/chunk-F4Z46DD6.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +12 -1
  11. package/dist/lib/node-esm/index.mjs.map +2 -2
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +57 -29
  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 +1 -1
  22. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  23. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts +8 -20
  24. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  25. package/dist/types/src/components/{Buttons → Button}/Button.d.ts +1 -1
  26. package/dist/types/src/components/Button/Button.d.ts.map +1 -0
  27. package/dist/types/src/components/Button/Button.stories.d.ts +17 -0
  28. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -0
  29. package/dist/types/src/components/{Buttons → Button}/IconButton.d.ts +4 -4
  30. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -0
  31. package/dist/types/src/components/Button/IconButton.stories.d.ts +13 -0
  32. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -0
  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/{Buttons → Button}/ToggleGroup.d.ts +7 -8
  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/Clipboard/ClipboardProvider.d.ts.map +1 -1
  42. package/dist/types/src/components/Clipboard/CopyButton.d.ts +1 -1
  43. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  44. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  45. package/dist/types/src/components/{Dialogs → Dialog}/AlertDialog.d.ts +1 -1
  46. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -0
  47. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts +11 -0
  48. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -0
  49. package/dist/types/src/components/{Dialogs → Dialog}/Dialog.d.ts +3 -3
  50. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -0
  51. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +25 -0
  52. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -0
  53. package/dist/types/src/components/Dialog/index.d.ts.map +1 -0
  54. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  55. package/dist/types/src/components/Icon/Icon.d.ts +1 -1
  56. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  57. package/dist/types/src/components/Icon/Icon.stories.d.ts +17 -0
  58. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
  59. package/dist/types/src/components/Input/Input.d.ts +6 -5
  60. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  61. package/dist/types/src/components/Input/Input.stories.d.ts +10 -11
  62. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  63. package/dist/types/src/components/Link/Link.stories.d.ts +8 -8
  64. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/{Lists → List}/List.d.ts +2 -2
  66. package/dist/types/src/components/List/List.d.ts.map +1 -0
  67. package/dist/types/src/components/List/List.stories.d.ts +14 -0
  68. package/dist/types/src/components/List/List.stories.d.ts.map +1 -0
  69. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -0
  70. package/dist/types/src/components/{Lists → List}/Tree.d.ts +1 -1
  71. package/dist/types/src/components/List/Tree.d.ts.map +1 -0
  72. package/dist/types/src/components/List/Tree.stories.d.ts +15 -0
  73. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -0
  74. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -0
  75. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts +1 -1
  76. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts.map +1 -1
  77. package/dist/types/src/components/List/Treegrid.stories.d.ts +12 -0
  78. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -0
  79. package/dist/types/src/components/List/index.d.ts.map +1 -0
  80. package/dist/types/src/components/Main/Main.d.ts +10 -19
  81. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  82. package/dist/types/src/components/Main/Main.stories.d.ts +6 -7
  83. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  84. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +1 -1
  85. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +6 -44
  86. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +1 -1
  87. package/dist/types/src/components/Menus/DropdownMenu.d.ts +8 -8
  88. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +1 -1
  89. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +6 -41
  90. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +1 -1
  91. package/dist/types/src/components/Message/Message.d.ts +1 -1
  92. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  93. package/dist/types/src/components/Message/Message.stories.d.ts +7 -16
  94. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  95. package/dist/types/src/components/Popover/Popover.d.ts +2 -2
  96. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  97. package/dist/types/src/components/Popover/Popover.stories.d.ts +6 -34
  98. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  99. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +1 -1
  100. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  101. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +6 -32
  102. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  103. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +39 -0
  104. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -0
  105. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +19 -0
  106. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -0
  107. package/dist/types/src/components/ScrollContainer/index.d.ts +2 -0
  108. package/dist/types/src/components/ScrollContainer/index.d.ts.map +1 -0
  109. package/dist/types/src/components/Select/Select.d.ts +1 -1
  110. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  111. package/dist/types/src/components/Select/Select.stories.d.ts +4 -9
  112. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  113. package/dist/types/src/components/Status/Status.stories.d.ts +2 -8
  114. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  115. package/dist/types/src/components/Tag/Tag.stories.d.ts +12 -12
  116. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  117. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +1 -1
  118. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  119. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -1
  120. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  121. package/dist/types/src/components/Toast/Toast.d.ts +1 -1
  122. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  123. package/dist/types/src/components/Toast/Toast.stories.d.ts +6 -44
  124. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  125. package/dist/types/src/components/Toolbar/Toolbar.d.ts +12 -12
  126. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  127. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +6 -50
  128. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  129. package/dist/types/src/components/Tooltip/Tooltip.d.ts +2 -4
  130. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  131. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +8 -61
  132. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/index.d.ts +4 -3
  134. package/dist/types/src/components/index.d.ts.map +1 -1
  135. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  136. package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
  137. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  138. package/dist/types/src/index.d.ts +1 -1
  139. package/dist/types/src/index.d.ts.map +1 -1
  140. package/dist/types/src/playground/Controls.stories.d.ts +5 -9
  141. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  142. package/dist/types/src/playground/Custom.stories.d.ts +12 -4
  143. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  144. package/dist/types/src/playground/Typography.stories.d.ts +5 -11
  145. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  146. package/dist/types/src/testing/decorators/index.d.ts +2 -1
  147. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  148. package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
  149. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
  150. package/dist/types/src/testing/decorators/{withSurfaceVariantsLayout.d.ts → withLayoutVariants.d.ts} +2 -2
  151. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
  152. package/dist/types/src/testing/decorators/withTheme.d.ts +3 -0
  153. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  154. package/dist/types/src/util/domino.d.ts +18 -0
  155. package/dist/types/src/util/domino.d.ts.map +1 -0
  156. package/dist/types/src/util/index.d.ts +2 -0
  157. package/dist/types/src/util/index.d.ts.map +1 -1
  158. package/dist/types/src/util/usePx.d.ts +8 -0
  159. package/dist/types/src/util/usePx.d.ts.map +1 -0
  160. package/dist/types/tsconfig.tsbuildinfo +1 -1
  161. package/package.json +26 -23
  162. package/src/components/Avatars/Avatar.stories.tsx +19 -10
  163. package/src/components/Avatars/Avatar.tsx +3 -3
  164. package/src/components/Avatars/AvatarGroup.stories.tsx +10 -6
  165. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +17 -12
  166. package/src/components/Breadcrumb/Breadcrumb.tsx +1 -1
  167. package/src/components/{Buttons → Button}/Button.stories.tsx +8 -9
  168. package/src/components/{Buttons → Button}/IconButton.stories.tsx +11 -8
  169. package/src/components/{Buttons → Button}/IconButton.tsx +19 -15
  170. package/src/components/{Buttons → Button}/Toggle.stories.tsx +13 -9
  171. package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +10 -7
  172. package/src/components/{Buttons → Button}/ToggleGroup.tsx +17 -4
  173. package/src/components/Clipboard/ClipboardProvider.tsx +1 -1
  174. package/src/components/Clipboard/CopyButton.tsx +3 -2
  175. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  176. package/src/components/{Dialogs → Dialog}/AlertDialog.stories.tsx +15 -12
  177. package/src/components/{Dialogs → Dialog}/AlertDialog.tsx +13 -13
  178. package/src/components/{Dialogs → Dialog}/Dialog.stories.tsx +17 -15
  179. package/src/components/{Dialogs → Dialog}/Dialog.tsx +20 -14
  180. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  181. package/src/components/Icon/Icon.stories.tsx +113 -0
  182. package/src/components/Icon/Icon.tsx +1 -1
  183. package/src/components/Input/Input.stories.tsx +12 -14
  184. package/src/components/Input/Input.tsx +27 -18
  185. package/src/components/Link/Link.stories.tsx +10 -6
  186. package/src/components/{Lists → List}/List.stories.tsx +16 -14
  187. package/src/components/{Lists → List}/List.tsx +16 -12
  188. package/src/components/{Lists → List}/ListDropIndicator.tsx +1 -1
  189. package/src/components/{Lists → List}/Tree.stories.tsx +11 -8
  190. package/src/components/{Lists → List}/Tree.tsx +4 -3
  191. package/src/components/{Lists → List}/TreeDropIndicator.tsx +1 -1
  192. package/src/components/{Lists → List}/Treegrid.stories.tsx +12 -6
  193. package/src/components/{Lists → List}/Treegrid.tsx +58 -17
  194. package/src/components/Main/Main.stories.tsx +17 -9
  195. package/src/components/Main/Main.tsx +43 -28
  196. package/src/components/Menus/ContextMenu.stories.tsx +11 -8
  197. package/src/components/Menus/ContextMenu.tsx +1 -0
  198. package/src/components/Menus/DropdownMenu.stories.tsx +12 -9
  199. package/src/components/Menus/DropdownMenu.tsx +45 -16
  200. package/src/components/Message/Message.stories.tsx +11 -7
  201. package/src/components/Message/Message.tsx +3 -1
  202. package/src/components/Popover/Popover.stories.tsx +12 -9
  203. package/src/components/Popover/Popover.tsx +29 -12
  204. package/src/components/ScrollArea/ScrollArea.stories.tsx +12 -9
  205. package/src/components/ScrollArea/ScrollArea.tsx +4 -4
  206. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +70 -0
  207. package/src/components/ScrollContainer/ScrollContainer.tsx +233 -0
  208. package/src/components/ScrollContainer/index.ts +5 -0
  209. package/src/components/Select/Select.stories.tsx +15 -12
  210. package/src/components/Select/Select.tsx +9 -8
  211. package/src/components/Status/Status.stories.tsx +9 -6
  212. package/src/components/Tag/Tag.stories.tsx +18 -9
  213. package/src/components/ThemeProvider/ThemeProvider.tsx +3 -2
  214. package/src/components/ThemeProvider/TranslationsProvider.tsx +3 -3
  215. package/src/components/Toast/Toast.stories.tsx +12 -9
  216. package/src/components/Toast/Toast.tsx +9 -9
  217. package/src/components/Toolbar/Toolbar.stories.tsx +14 -12
  218. package/src/components/Toolbar/Toolbar.tsx +20 -8
  219. package/src/components/Tooltip/Tooltip.stories.tsx +16 -12
  220. package/src/components/Tooltip/Tooltip.tsx +5 -4
  221. package/src/components/index.ts +4 -3
  222. package/src/hooks/useSafeArea.ts +3 -2
  223. package/src/hooks/useVisualViewport.ts +4 -4
  224. package/src/index.ts +1 -1
  225. package/src/playground/Controls.stories.tsx +12 -8
  226. package/src/playground/Custom.stories.tsx +13 -24
  227. package/src/playground/Typography.stories.tsx +8 -6
  228. package/src/testing/decorators/index.ts +2 -1
  229. package/src/testing/decorators/withLayout.tsx +56 -0
  230. package/src/testing/decorators/{withSurfaceVariantsLayout.tsx → withLayoutVariants.tsx} +3 -3
  231. package/src/testing/decorators/withTheme.tsx +31 -0
  232. package/src/util/domino.ts +53 -0
  233. package/src/util/index.ts +2 -0
  234. package/src/util/usePx.ts +61 -0
  235. package/dist/lib/browser/chunk-2COVUP44.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-GHXHND5V.mjs.map +0 -7
  237. package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
  238. package/dist/types/src/components/Buttons/Button.stories.d.ts +0 -12
  239. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
  240. package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
  241. package/dist/types/src/components/Buttons/IconButton.stories.d.ts +0 -22
  242. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
  243. package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
  244. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -19
  245. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
  246. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
  247. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +0 -39
  248. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
  249. package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
  250. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
  251. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +0 -43
  252. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
  253. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
  254. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -48
  255. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
  256. package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
  257. package/dist/types/src/components/Lists/List.d.ts.map +0 -1
  258. package/dist/types/src/components/Lists/List.stories.d.ts +0 -37
  259. package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
  260. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
  261. package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
  262. package/dist/types/src/components/Lists/Tree.stories.d.ts +0 -41
  263. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
  264. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
  265. package/dist/types/src/components/Lists/Treegrid.stories.d.ts +0 -10
  266. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
  267. package/dist/types/src/components/Lists/index.d.ts.map +0 -1
  268. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
  269. package/src/testing/decorators/withTheme.ts +0 -25
  270. /package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +0 -0
  271. /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
  272. /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
  273. /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
  274. /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
  275. /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
  276. /package/src/components/{Buttons → Button}/Button.tsx +0 -0
  277. /package/src/components/{Buttons → Button}/Toggle.tsx +0 -0
  278. /package/src/components/{Buttons → Button}/index.ts +0 -0
  279. /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
  280. /package/src/components/{Lists → List}/index.ts +0 -0
@@ -2,15 +2,15 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
6
  import React from 'react';
8
7
 
9
8
  import { type MessageValence } from '@dxos/react-ui-types';
10
9
 
11
- import { Callout } from './Message';
12
10
  import { withTheme } from '../../testing';
13
11
 
12
+ import { Callout } from './Message';
13
+
14
14
  type StoryProps = {
15
15
  valence: MessageValence;
16
16
  title: string;
@@ -24,9 +24,9 @@ const DefaultStory = ({ valence, title, body }: StoryProps) => (
24
24
  </Callout.Root>
25
25
  );
26
26
 
27
- export default {
27
+ const meta = {
28
28
  title: 'ui/react-ui-core/Callout',
29
- component: Callout,
29
+ component: Callout.Root as any,
30
30
  render: DefaultStory,
31
31
  decorators: [withTheme],
32
32
  parameters: { chromatic: { disableSnapshot: false } },
@@ -36,9 +36,13 @@ export default {
36
36
  options: ['success', 'info', 'warning', 'error', 'neutral'],
37
37
  },
38
38
  },
39
- };
39
+ } satisfies Meta<typeof DefaultStory>;
40
+
41
+ export default meta;
42
+
43
+ type Story = StoryObj<typeof meta>;
40
44
 
41
- export const Default = {
45
+ export const Default: Story = {
42
46
  args: {
43
47
  valence: 'neutral',
44
48
  title: 'Alert title',
@@ -8,7 +8,7 @@ import { Slot } from '@radix-ui/react-slot';
8
8
  import React, { type ComponentPropsWithRef, forwardRef } from 'react';
9
9
 
10
10
  import { useId } from '@dxos/react-hooks';
11
- import { type MessageValence, type Elevation } from '@dxos/react-ui-types';
11
+ import { type Elevation, type MessageValence } from '@dxos/react-ui-types';
12
12
 
13
13
  import { useElevationContext, useThemeContext } from '../../hooks';
14
14
  import { type ThemedClassName } from '../../util';
@@ -53,6 +53,7 @@ const MessageRoot = forwardRef<HTMLDivElement, MessageRootProps>(
53
53
  const descriptionId = useId('message__description', propsDescriptionId);
54
54
  const elevation = useElevationContext(propsElevation);
55
55
  const Root = asChild ? Slot : Primitive.div;
56
+
56
57
  return (
57
58
  <MessageProvider {...{ titleId, descriptionId, valence }}>
58
59
  <Root
@@ -84,6 +85,7 @@ const MessageTitle = forwardRef<HTMLHeadingElement, MessageTitleProps>(
84
85
  const { tx } = useThemeContext();
85
86
  const { titleId, valence } = useMessageContext(MESSAGE_TITLE_NAME);
86
87
  const Root = asChild ? Slot : Primitive.h2;
88
+
87
89
  return (
88
90
  <Root
89
91
  {...props}
@@ -2,15 +2,15 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
6
  import React, { type PropsWithChildren, type ReactNode, useRef, useState } from 'react';
8
7
 
9
8
  import { faker } from '@dxos/random';
10
9
 
11
- import { Popover } from './Popover';
12
10
  import { withTheme } from '../../testing';
13
- import { Button } from '../Buttons';
11
+ import { Button } from '../Button';
12
+
13
+ import { Popover } from './Popover';
14
14
 
15
15
  faker.seed(1234);
16
16
 
@@ -28,15 +28,18 @@ const DefaultStory = ({ openTrigger, children }: PropsWithChildren<{ openTrigger
28
28
  );
29
29
  };
30
30
 
31
- export default {
31
+ const meta = {
32
32
  title: 'ui/react-ui-core/Popover',
33
- component: Popover,
33
+ component: Popover.Root,
34
34
  render: DefaultStory,
35
35
  decorators: [withTheme],
36
- parameters: { chromatic: { disableSnapshot: false } },
37
- };
36
+ } satisfies Meta<typeof DefaultStory>;
37
+
38
+ export default meta;
39
+
40
+ type Story = StoryObj<typeof meta>;
38
41
 
39
- export const Default = {
42
+ export const Default: Story = {
40
43
  args: {
41
44
  openTrigger: <Button>Open popover</Button>,
42
45
  children: faker.lorem.paragraphs(3),
@@ -22,17 +22,18 @@ import { useControllableState } from '@radix-ui/react-use-controllable-state';
22
22
  import { hideOthers } from 'aria-hidden';
23
23
  import React, {
24
24
  type ComponentPropsWithRef,
25
- forwardRef,
25
+ type ComponentPropsWithoutRef,
26
26
  type ElementRef,
27
- type RefObject,
27
+ type FC,
28
+ type MutableRefObject,
28
29
  type ReactNode,
29
- useRef,
30
+ type RefObject,
31
+ forwardRef,
30
32
  useCallback,
31
- type ComponentPropsWithoutRef,
32
- type FC,
33
- useState,
34
33
  useEffect,
35
- type MutableRefObject,
34
+ useMemo,
35
+ useRef,
36
+ useState,
36
37
  } from 'react';
37
38
  import { RemoveScroll } from 'react-remove-scroll';
38
39
 
@@ -182,7 +183,7 @@ PopoverTrigger.displayName = TRIGGER_NAME;
182
183
  const VIRTUAL_TRIGGER_NAME = 'PopoverVirtualTrigger';
183
184
 
184
185
  interface PopoverVirtualTriggerProps {
185
- virtualRef: RefObject<PopoverTriggerElement>;
186
+ virtualRef: RefObject<PopoverTriggerElement | null>;
186
187
  }
187
188
 
188
189
  const PopoverVirtualTrigger = (props: ScopedProps<PopoverVirtualTriggerProps>) => {
@@ -194,7 +195,7 @@ const PopoverVirtualTrigger = (props: ScopedProps<PopoverVirtualTriggerProps>) =
194
195
  context.triggerRef.current = virtualRef.current;
195
196
  }
196
197
  });
197
- return <PopperPrimitive.Anchor {...popperScope} virtualRef={virtualRef} />;
198
+ return <PopperPrimitive.Anchor {...popperScope} virtualRef={virtualRef as RefObject<PopoverTriggerElement>} />;
198
199
  };
199
200
 
200
201
  PopoverVirtualTrigger.displayName = VIRTUAL_TRIGGER_NAME;
@@ -396,6 +397,7 @@ type PopoverContentImplElement = ElementRef<typeof PopperPrimitive.Content>;
396
397
  type FocusScopeProps = ComponentPropsWithoutRef<typeof FocusScope>;
397
398
  type DismissableLayerProps = ComponentPropsWithoutRef<typeof DismissableLayer>;
398
399
  type PopperContentProps = ThemedClassName<ComponentPropsWithoutRef<typeof PopperPrimitive.Content>>;
400
+
399
401
  interface PopoverContentImplProps
400
402
  extends Omit<PopperContentProps, 'onPlaced'>,
401
403
  Omit<DismissableLayerProps, 'onDismiss'> {
@@ -431,6 +433,7 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
431
433
  onFocusOutside,
432
434
  onInteractOutside,
433
435
  collisionPadding = 8,
436
+ collisionBoundary,
434
437
  classNames,
435
438
  ...contentProps
436
439
  } = props;
@@ -440,10 +443,23 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
440
443
  const elevation = useElevationContext();
441
444
  const safeCollisionPadding = useSafeCollisionPadding(collisionPadding);
442
445
 
443
- // Make sure the whole tree has focus guards as our `Popover` may be
444
- // the last element in the DOM (because of the `Portal`)
446
+ // Make sure the whole tree has focus guards as our `Popover` may be the last element in the DOM (because of the `Portal`)
445
447
  useFocusGuards();
446
448
 
449
+ // Check for the closest annotated collision boundary in the DOM tree.
450
+ const computedCollisionBoundary = useMemo(() => {
451
+ const closestBoundary = context.triggerRef.current?.closest(
452
+ '[data-popover-collision-boundary]',
453
+ ) as HTMLElement | null;
454
+ return closestBoundary
455
+ ? Array.isArray(collisionBoundary)
456
+ ? [closestBoundary, ...collisionBoundary]
457
+ : collisionBoundary
458
+ ? [closestBoundary, collisionBoundary]
459
+ : [closestBoundary]
460
+ : collisionBoundary;
461
+ }, [context.open, collisionBoundary, context.triggerRef.current]);
462
+
447
463
  return (
448
464
  <FocusScope
449
465
  asChild
@@ -468,11 +484,12 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
468
484
  {...popperScope}
469
485
  {...contentProps}
470
486
  collisionPadding={safeCollisionPadding}
487
+ collisionBoundary={computedCollisionBoundary}
471
488
  className={tx('popover.content', 'popover', { elevation }, classNames)}
472
489
  ref={forwardedRef}
473
490
  style={{
474
491
  ...contentProps.style,
475
- // re-namespace exposed content custom properties
492
+ // Re-namespace exposed content custom properties.
476
493
  ...{
477
494
  '--radix-popover-content-transform-origin': 'var(--radix-popper-transform-origin)',
478
495
  '--radix-popover-content-available-width': 'var(--radix-popper-available-width)',
@@ -2,16 +2,16 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
6
  import React, { type PropsWithChildren } from 'react';
8
7
 
9
8
  import { faker } from '@dxos/random';
10
9
  import { activeSurface, surfaceShadow } from '@dxos/react-ui-theme';
11
10
 
12
- import { ScrollArea } from './ScrollArea';
13
11
  import { withTheme } from '../../testing';
14
12
 
13
+ import { ScrollArea } from './ScrollArea';
14
+
15
15
  faker.seed(1234);
16
16
 
17
17
  const DefaultStory = ({ children }: PropsWithChildren<{}>) => {
@@ -33,15 +33,18 @@ const DefaultStory = ({ children }: PropsWithChildren<{}>) => {
33
33
  );
34
34
  };
35
35
 
36
- export default {
37
- title: 'ui/react-ui-core/Scroll area',
38
- component: ScrollArea,
36
+ const meta = {
37
+ title: 'ui/react-ui-core/ScrollArea',
38
+ component: ScrollArea as any,
39
39
  render: DefaultStory,
40
40
  decorators: [withTheme],
41
- parameters: { chromatic: { disableSnapshot: false } },
42
- };
41
+ } satisfies Meta<typeof DefaultStory>;
42
+
43
+ export default meta;
44
+
45
+ type Story = StoryObj<typeof meta>;
43
46
 
44
- export const Default = {
47
+ export const Default: Story = {
45
48
  args: {
46
49
  children: faker.lorem.paragraphs(5),
47
50
  },
@@ -3,16 +3,16 @@
3
3
  //
4
4
 
5
5
  import {
6
+ Corner as ScrollAreaPrimitiveCorner,
7
+ type ScrollAreaCornerProps as ScrollAreaPrimitiveCornerProps,
6
8
  Root as ScrollAreaPrimitiveRoot,
7
9
  type ScrollAreaProps as ScrollAreaPrimitiveRootProps,
8
- Viewport as ScrollAreaPrimitiveViewport,
9
- type ScrollAreaViewportProps as ScrollAreaPrimitiveViewportProps,
10
10
  Scrollbar as ScrollAreaPrimitiveScrollbar,
11
11
  type ScrollAreaScrollbarProps as ScrollAreaPrimitiveScrollbarProps,
12
12
  Thumb as ScrollAreaPrimitiveThumb,
13
13
  type ScrollAreaThumbProps as ScrollAreaPrimitiveThumbProps,
14
- Corner as ScrollAreaPrimitiveCorner,
15
- type ScrollAreaCornerProps as ScrollAreaPrimitiveCornerProps,
14
+ Viewport as ScrollAreaPrimitiveViewport,
15
+ type ScrollAreaViewportProps as ScrollAreaPrimitiveViewportProps,
16
16
  } from '@radix-ui/react-scroll-area';
17
17
  import React, { forwardRef } from 'react';
18
18
 
@@ -0,0 +1,70 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useEffect, useRef, useState } from 'react';
7
+
8
+ import { faker } from '@dxos/random';
9
+
10
+ import { withLayout, withTheme } from '../../testing';
11
+ import { Button } from '../Button';
12
+ import { Toolbar } from '../Toolbar';
13
+
14
+ import { ScrollContainer, type ScrollContainerRootProps, type ScrollController } from './ScrollContainer';
15
+
16
+ const DefaultStory = (props: ScrollContainerRootProps) => {
17
+ const [lines, setLines] = useState<string[]>([]);
18
+ const [running, setRunning] = useState(true);
19
+ const scroller = useRef<ScrollController>(null);
20
+ useEffect(() => {
21
+ if (!running) {
22
+ return;
23
+ }
24
+
25
+ const i = setInterval(() => {
26
+ setLines((lines) => [...lines, faker.lorem.paragraph()]);
27
+ }, 500);
28
+
29
+ return () => clearInterval(i);
30
+ }, [running]);
31
+
32
+ return (
33
+ <div className='flex flex-col bs-full overflow-hidden'>
34
+ <Toolbar.Root>
35
+ <Button onClick={() => setRunning((running) => !running)}>{running ? 'Stop' : 'Start'}</Button>
36
+ <Button onClick={() => scroller.current?.scrollToBottom()}>Scroll to bottom</Button>
37
+ <div className='flex-1' />
38
+ <div>{lines.length}</div>
39
+ </Toolbar.Root>
40
+ <ScrollContainer.Root {...props} ref={scroller}>
41
+ <ScrollContainer.Viewport>
42
+ {lines.map((line, index) => (
43
+ <div key={index} className='p-2'>
44
+ {line}
45
+ </div>
46
+ ))}
47
+ </ScrollContainer.Viewport>
48
+ <ScrollContainer.ScrollDownButton />
49
+ </ScrollContainer.Root>
50
+ </div>
51
+ );
52
+ };
53
+
54
+ const meta = {
55
+ title: 'ui/react-ui-core/ScrollContainer',
56
+ component: ScrollContainer.Root,
57
+ render: DefaultStory,
58
+ decorators: [withTheme, withLayout({ container: 'column', classNames: 'is-[30rem]' })],
59
+ } satisfies Meta<typeof DefaultStory>;
60
+
61
+ export default meta;
62
+
63
+ type Story = StoryObj<typeof meta>;
64
+
65
+ export const Default: Story = {
66
+ args: {
67
+ pin: true,
68
+ fade: true,
69
+ },
70
+ };
@@ -0,0 +1,233 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useState } from '@preact-signals/safe-react/react';
6
+ import { createContext } from '@radix-ui/react-context';
7
+ import React, {
8
+ type HTMLAttributes,
9
+ type PropsWithChildren,
10
+ forwardRef,
11
+ useCallback,
12
+ useEffect,
13
+ useImperativeHandle,
14
+ useMemo,
15
+ useRef,
16
+ } from 'react';
17
+
18
+ // TODO(burdon): Move these deps to @dxos/dom-util.
19
+ import { addEventListener, combine } from '@dxos/async';
20
+ import { invariant } from '@dxos/invariant';
21
+ import { useForwardedRef } from '@dxos/react-hooks';
22
+ import { mx } from '@dxos/react-ui-theme';
23
+
24
+ import { type ThemedClassName } from '../../util';
25
+ import { IconButton } from '../Button';
26
+
27
+ const isBottom = (el: HTMLElement | null) => {
28
+ return !!(el && el.scrollHeight - el.scrollTop === el.clientHeight);
29
+ };
30
+
31
+ export interface ScrollController {
32
+ viewport: HTMLDivElement | null;
33
+ scrollToTop: (behavior?: ScrollBehavior) => void;
34
+ scrollToBottom: (behavior?: ScrollBehavior) => void;
35
+ }
36
+
37
+ type ScrollContainerContextValue = {
38
+ scrollToBottom: (behavior?: ScrollBehavior) => void;
39
+ controller?: ScrollController;
40
+ pinned?: boolean;
41
+ };
42
+
43
+ const [ScrollContainerProvider, useScrollContainerContext] =
44
+ createContext<ScrollContainerContextValue>('ScrollContainer');
45
+
46
+ //
47
+ // Root
48
+ //
49
+
50
+ type RootProps = ThemedClassName<
51
+ PropsWithChildren<{
52
+ pin?: boolean;
53
+ fade?: boolean;
54
+ behavior?: ScrollBehavior;
55
+ }>
56
+ >;
57
+
58
+ /**
59
+ * Scroll container that automatically scrolls to the bottom when new content is added.
60
+ */
61
+ const Root = forwardRef<ScrollController, RootProps>(
62
+ ({ children, classNames, pin, fade, behavior: behaviorProp = 'smooth' }, forwardedRef) => {
63
+ const scrollerRef = useRef<HTMLDivElement>(null);
64
+ const autoScrollRef = useRef(false);
65
+ const [overflow, setOverflow] = useState(false);
66
+ const [pinned, setPinned] = useState(pin);
67
+
68
+ const timeoutRef = useRef<NodeJS.Timeout>(undefined);
69
+ const scrollToBottom = useCallback((behavior: ScrollBehavior = behaviorProp) => {
70
+ if (scrollerRef.current) {
71
+ // Temporarily hide scrollbar to prevent flicker.
72
+ autoScrollRef.current = true;
73
+ scrollerRef.current.classList.add('scrollbar-none');
74
+ scrollerRef.current.scrollTo({
75
+ top: scrollerRef.current.scrollHeight,
76
+ behavior,
77
+ });
78
+
79
+ clearTimeout(timeoutRef.current);
80
+ if (behavior !== 'instant') {
81
+ timeoutRef.current = setTimeout(() => {
82
+ scrollerRef.current?.classList.remove('scrollbar-none');
83
+ autoScrollRef.current = false;
84
+ }, 500);
85
+ }
86
+ setPinned(true);
87
+ }
88
+ }, []);
89
+
90
+ const controller = useMemo(
91
+ () => ({
92
+ viewport: scrollerRef.current,
93
+ scrollToTop: () => {
94
+ invariant(scrollerRef.current);
95
+ scrollerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
96
+ setPinned(false);
97
+ },
98
+ scrollToBottom: () => {
99
+ scrollToBottom('smooth');
100
+ },
101
+ }),
102
+ [scrollToBottom, scrollerRef.current],
103
+ );
104
+
105
+ // Scroll controller imperative ref.
106
+ useImperativeHandle(forwardedRef, () => controller, [controller]);
107
+
108
+ // Listen for scroll events.
109
+ useEffect(() => {
110
+ if (!scrollerRef.current) {
111
+ return;
112
+ }
113
+
114
+ return combine(
115
+ // Check if user scrolls.
116
+ addEventListener(scrollerRef.current, 'wheel', () => {
117
+ setPinned(isBottom(scrollerRef.current));
118
+ }),
119
+ // Check if scrolls.
120
+ addEventListener(scrollerRef.current, 'scroll', () => {
121
+ setOverflow((scrollerRef.current?.scrollTop ?? 0) > 0);
122
+ }),
123
+ );
124
+ }, []);
125
+
126
+ return (
127
+ <ScrollContainerProvider pinned={pinned} controller={controller} scrollToBottom={scrollToBottom}>
128
+ <div className='relative grid flex-1 min-bs-0 overflow-hidden'>
129
+ {fade && (
130
+ <div
131
+ role='none'
132
+ data-visible={overflow}
133
+ className={mx(
134
+ // NOTE: Gradients may not be visible with dark reader extensions.
135
+ 'z-10 absolute block-start-0 inset-inline-0 bs-24 is-full',
136
+ 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
137
+ 'bg-gradient-to-b from-[--surface-bg] to-transparent pointer-events-none',
138
+ )}
139
+ />
140
+ )}
141
+ <div className={mx('flex flex-col min-bs-0 overflow-y-auto scrollbar-thin', classNames)} ref={scrollerRef}>
142
+ {children}
143
+ </div>
144
+ </div>
145
+ </ScrollContainerProvider>
146
+ );
147
+ },
148
+ );
149
+
150
+ Root.displayName = 'ScrollContainer.Root';
151
+
152
+ //
153
+ // Viewport
154
+ //
155
+
156
+ type ViewportProps = ThemedClassName<PropsWithChildren<Omit<HTMLAttributes<HTMLDivElement>, 'className'>>>;
157
+
158
+ const Viewport = forwardRef<HTMLDivElement, ViewportProps>(({ classNames, children, ...props }, forwardedRef) => {
159
+ const contentRef = useForwardedRef(forwardedRef);
160
+ const { pinned, scrollToBottom } = useScrollContainerContext(Viewport.displayName!);
161
+
162
+ useEffect(() => {
163
+ if (!pinned || !contentRef.current) {
164
+ return;
165
+ }
166
+
167
+ // Scroll instantly otherwise it might move while we're scrolling.
168
+ scrollToBottom();
169
+
170
+ // Setup resize observer to detect content changes.
171
+ const resizeObserver = new ResizeObserver(() => scrollToBottom());
172
+ resizeObserver.observe(contentRef.current);
173
+ return () => resizeObserver.disconnect();
174
+ }, [pinned, scrollToBottom]);
175
+
176
+ return (
177
+ <div className={mx('is-full', classNames)} {...props} ref={contentRef}>
178
+ {children}
179
+ </div>
180
+ );
181
+ });
182
+
183
+ Viewport.displayName = 'ScrollContainer.Viewport';
184
+
185
+ //
186
+ // ScrollDownButton
187
+ //
188
+
189
+ type ScrollDownButtonProps = ThemedClassName;
190
+
191
+ const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
192
+ const { pinned, scrollToBottom } = useScrollContainerContext(ScrollDownButton.displayName!);
193
+
194
+ return (
195
+ <div
196
+ role='none'
197
+ className={mx(
198
+ 'absolute bottom-2 right-4 opacity-100 transition-opacity duration-300',
199
+ pinned && 'opacity-0',
200
+ classNames,
201
+ )}
202
+ >
203
+ <IconButton
204
+ variant='primary'
205
+ icon='ph--arrow-down--regular'
206
+ iconOnly
207
+ size={4}
208
+ label='Scroll down'
209
+ onClick={() => scrollToBottom()}
210
+ />
211
+ </div>
212
+ );
213
+ };
214
+
215
+ ScrollDownButton.displayName = 'ScrollContainer.ScrollDownButton';
216
+
217
+ //
218
+ // ScrollContainer
219
+ //
220
+
221
+ export { useScrollContainerContext };
222
+
223
+ export const ScrollContainer = {
224
+ Root,
225
+ Viewport,
226
+ ScrollDownButton,
227
+ };
228
+
229
+ export type {
230
+ RootProps as ScrollContainerRootProps,
231
+ ViewportProps as ScrollContainerViewportProps,
232
+ ScrollDownButtonProps as ScrollContainerScrollDownButtonProps,
233
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './ScrollContainer';
@@ -2,15 +2,15 @@
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
8
  import { faker } from '@dxos/random';
11
9
 
10
+ import { withTheme } from '../../testing';
11
+ import { withLayoutVariants } from '../../testing';
12
+
12
13
  import { Select } from './Select';
13
- import { withSurfaceVariantsLayout, withTheme } from '../../testing';
14
14
 
15
15
  faker.seed(1234);
16
16
 
@@ -41,15 +41,18 @@ const DefaultStory = ({ items = [] }: StoryProps) => {
41
41
  );
42
42
  };
43
43
 
44
- export const Default: StoryObj<StoryProps> = {
44
+ const meta = {
45
+ title: 'ui/react-ui-core/Select',
46
+ render: DefaultStory,
47
+ decorators: [withTheme, withLayoutVariants()],
48
+ } satisfies Meta<typeof DefaultStory>;
49
+
50
+ export default meta;
51
+
52
+ type Story = StoryObj<typeof meta>;
53
+
54
+ export const Default: Story = {
45
55
  args: {
46
56
  items: Array.from({ length: 16 }).map((_, i) => ({ id: `item-${i}`, text: faker.lorem.word() })),
47
57
  },
48
58
  };
49
-
50
- export default {
51
- title: 'ui/react-ui-core/Select',
52
- render: DefaultStory,
53
- decorators: [withSurfaceVariantsLayout(), withTheme],
54
- parameters: { chromatic: { disableSnapshot: false } },
55
- };