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

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 (279) hide show
  1. package/dist/lib/browser/{chunk-T6YPS45E.mjs → chunk-N5GDJTT2.mjs} +704 -373
  2. package/dist/lib/browser/chunk-N5GDJTT2.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +11 -1
  4. package/dist/lib/browser/index.mjs.map +1 -1
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +57 -30
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/{chunk-TYVQJ4KW.mjs → chunk-SP7VQH72.mjs} +704 -373
  9. package/dist/lib/node-esm/chunk-SP7VQH72.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +11 -1
  11. package/dist/lib/node-esm/index.mjs.map +1 -1
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +57 -30
  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 +2 -3
  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 +1 -1
  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 +2 -4
  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 +37 -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 +18 -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/playground/Controls.stories.d.ts +5 -9
  139. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  140. package/dist/types/src/playground/Custom.stories.d.ts +12 -4
  141. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  142. package/dist/types/src/playground/Typography.stories.d.ts +5 -11
  143. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  144. package/dist/types/src/testing/decorators/index.d.ts +2 -1
  145. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  146. package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
  147. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
  148. package/dist/types/src/testing/decorators/{withSurfaceVariantsLayout.d.ts → withLayoutVariants.d.ts} +2 -2
  149. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
  150. package/dist/types/src/testing/decorators/withTheme.d.ts +3 -0
  151. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  152. package/dist/types/src/util/domino.d.ts +18 -0
  153. package/dist/types/src/util/domino.d.ts.map +1 -0
  154. package/dist/types/src/util/index.d.ts +3 -1
  155. package/dist/types/src/util/index.d.ts.map +1 -1
  156. package/dist/types/src/util/usePx.d.ts +8 -0
  157. package/dist/types/src/util/usePx.d.ts.map +1 -0
  158. package/dist/types/tsconfig.tsbuildinfo +1 -1
  159. package/package.json +26 -23
  160. package/src/components/Avatars/Avatar.stories.tsx +19 -10
  161. package/src/components/Avatars/Avatar.tsx +3 -3
  162. package/src/components/Avatars/AvatarGroup.stories.tsx +10 -6
  163. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +17 -12
  164. package/src/components/Breadcrumb/Breadcrumb.tsx +3 -3
  165. package/src/components/{Buttons → Button}/Button.stories.tsx +10 -11
  166. package/src/components/{Buttons → Button}/IconButton.stories.tsx +11 -8
  167. package/src/components/{Buttons → Button}/IconButton.tsx +16 -14
  168. package/src/components/Button/Toggle.stories.tsx +37 -0
  169. package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +13 -10
  170. package/src/components/{Buttons → Button}/ToggleGroup.tsx +17 -4
  171. package/src/components/Clipboard/ClipboardProvider.tsx +1 -1
  172. package/src/components/Clipboard/CopyButton.tsx +4 -3
  173. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  174. package/src/components/{Dialogs → Dialog}/AlertDialog.stories.tsx +15 -12
  175. package/src/components/{Dialogs → Dialog}/AlertDialog.tsx +13 -13
  176. package/src/components/{Dialogs → Dialog}/Dialog.stories.tsx +17 -15
  177. package/src/components/{Dialogs → Dialog}/Dialog.tsx +13 -13
  178. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  179. package/src/components/Icon/Icon.stories.tsx +113 -0
  180. package/src/components/Icon/Icon.tsx +1 -1
  181. package/src/components/Input/Input.stories.tsx +12 -14
  182. package/src/components/Input/Input.tsx +16 -16
  183. package/src/components/Link/Link.stories.tsx +10 -6
  184. package/src/components/{Lists → List}/List.stories.tsx +22 -20
  185. package/src/components/{Lists → List}/List.tsx +15 -16
  186. package/src/components/{Lists → List}/ListDropIndicator.tsx +1 -1
  187. package/src/components/{Lists → List}/Tree.stories.tsx +11 -8
  188. package/src/components/{Lists → List}/Tree.tsx +4 -3
  189. package/src/components/{Lists → List}/TreeDropIndicator.tsx +1 -1
  190. package/src/components/{Lists → List}/Treegrid.stories.tsx +12 -6
  191. package/src/components/{Lists → List}/Treegrid.tsx +58 -17
  192. package/src/components/Main/Main.stories.tsx +17 -9
  193. package/src/components/Main/Main.tsx +43 -28
  194. package/src/components/Menus/ContextMenu.stories.tsx +11 -8
  195. package/src/components/Menus/ContextMenu.tsx +1 -0
  196. package/src/components/Menus/DropdownMenu.stories.tsx +12 -9
  197. package/src/components/Menus/DropdownMenu.tsx +45 -16
  198. package/src/components/Message/Message.stories.tsx +11 -7
  199. package/src/components/Message/Message.tsx +1 -1
  200. package/src/components/Popover/Popover.stories.tsx +12 -9
  201. package/src/components/Popover/Popover.tsx +29 -12
  202. package/src/components/ScrollArea/ScrollArea.stories.tsx +12 -9
  203. package/src/components/ScrollArea/ScrollArea.tsx +4 -4
  204. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +69 -0
  205. package/src/components/ScrollContainer/ScrollContainer.tsx +231 -0
  206. package/src/components/ScrollContainer/index.ts +5 -0
  207. package/src/components/Select/Select.stories.tsx +15 -12
  208. package/src/components/Select/Select.tsx +9 -9
  209. package/src/components/Status/Status.stories.tsx +9 -6
  210. package/src/components/Tag/Tag.stories.tsx +18 -9
  211. package/src/components/ThemeProvider/ThemeProvider.tsx +3 -2
  212. package/src/components/ThemeProvider/TranslationsProvider.tsx +3 -3
  213. package/src/components/Toast/Toast.stories.tsx +12 -9
  214. package/src/components/Toast/Toast.tsx +9 -9
  215. package/src/components/Toolbar/Toolbar.stories.tsx +21 -19
  216. package/src/components/Toolbar/Toolbar.tsx +20 -8
  217. package/src/components/Tooltip/Tooltip.stories.tsx +16 -12
  218. package/src/components/Tooltip/Tooltip.tsx +5 -4
  219. package/src/components/index.ts +4 -3
  220. package/src/hooks/useSafeArea.ts +3 -2
  221. package/src/hooks/useSafeCollisionPadding.ts +1 -1
  222. package/src/hooks/useVisualViewport.ts +4 -4
  223. package/src/playground/Controls.stories.tsx +20 -17
  224. package/src/playground/Custom.stories.tsx +13 -24
  225. package/src/playground/Typography.stories.tsx +8 -6
  226. package/src/testing/decorators/index.ts +2 -1
  227. package/src/testing/decorators/withLayout.tsx +56 -0
  228. package/src/testing/decorators/{withSurfaceVariantsLayout.tsx → withLayoutVariants.tsx} +2 -2
  229. package/src/testing/decorators/withTheme.tsx +31 -0
  230. package/src/util/domino.ts +53 -0
  231. package/src/util/index.ts +3 -1
  232. package/src/util/usePx.ts +61 -0
  233. package/dist/lib/browser/chunk-T6YPS45E.mjs.map +0 -7
  234. package/dist/lib/node-esm/chunk-TYVQJ4KW.mjs.map +0 -7
  235. package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
  236. package/dist/types/src/components/Buttons/Button.stories.d.ts +0 -12
  237. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
  238. package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
  239. package/dist/types/src/components/Buttons/IconButton.stories.d.ts +0 -22
  240. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
  241. package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
  242. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -19
  243. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
  244. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
  245. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +0 -39
  246. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
  247. package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
  248. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
  249. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +0 -43
  250. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
  251. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
  252. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -48
  253. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
  254. package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
  255. package/dist/types/src/components/Lists/List.d.ts.map +0 -1
  256. package/dist/types/src/components/Lists/List.stories.d.ts +0 -37
  257. package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
  258. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
  259. package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
  260. package/dist/types/src/components/Lists/Tree.stories.d.ts +0 -41
  261. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
  262. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
  263. package/dist/types/src/components/Lists/Treegrid.stories.d.ts +0 -10
  264. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
  265. package/dist/types/src/components/Lists/index.d.ts.map +0 -1
  266. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
  267. package/src/components/Buttons/Toggle.stories.tsx +0 -33
  268. package/src/testing/decorators/withTheme.ts +0 -22
  269. /package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +0 -0
  270. /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
  271. /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
  272. /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
  273. /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
  274. /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
  275. /package/src/components/{Buttons → Button}/Button.tsx +0 -0
  276. /package/src/components/{Buttons → Button}/Toggle.tsx +0 -0
  277. /package/src/components/{Buttons → Button}/index.ts +0 -0
  278. /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
  279. /package/src/components/{Lists → List}/index.ts +0 -0
@@ -0,0 +1,231 @@
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
+ }>
55
+ >;
56
+
57
+ /**
58
+ * Scroll container that automatically scrolls to the bottom when new content is added.
59
+ */
60
+ const Root = forwardRef<ScrollController, RootProps>(({ children, classNames, pin, fade }, forwardedRef) => {
61
+ const scrollerRef = useRef<HTMLDivElement>(null);
62
+ const autoScrollRef = useRef(false);
63
+ const [overflow, setOverflow] = useState(false);
64
+ const [pinned, setPinned] = useState(pin);
65
+
66
+ const timeoutRef = useRef<NodeJS.Timeout>(undefined);
67
+ const scrollToBottom = useCallback((behavior: ScrollBehavior = 'instant') => {
68
+ if (scrollerRef.current) {
69
+ // Temporarily hide scrollbar to prevent flicker.
70
+ autoScrollRef.current = true;
71
+ scrollerRef.current.classList.add('scrollbar-none');
72
+ scrollerRef.current.scrollTo({
73
+ top: scrollerRef.current.scrollHeight,
74
+ behavior,
75
+ });
76
+
77
+ clearTimeout(timeoutRef.current);
78
+ if (behavior !== 'instant') {
79
+ timeoutRef.current = setTimeout(() => {
80
+ scrollerRef.current?.classList.remove('scrollbar-none');
81
+ autoScrollRef.current = false;
82
+ }, 500);
83
+ }
84
+ setPinned(true);
85
+ }
86
+ }, []);
87
+
88
+ const controller = useMemo(
89
+ () => ({
90
+ viewport: scrollerRef.current,
91
+ scrollToTop: () => {
92
+ invariant(scrollerRef.current);
93
+ scrollerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
94
+ setPinned(false);
95
+ },
96
+ scrollToBottom: () => {
97
+ scrollToBottom('smooth');
98
+ },
99
+ }),
100
+ [scrollToBottom, scrollerRef.current],
101
+ );
102
+
103
+ // Scroll controller imperative ref.
104
+ useImperativeHandle(forwardedRef, () => controller, [controller]);
105
+
106
+ // Listen for scroll events.
107
+ useEffect(() => {
108
+ if (!scrollerRef.current) {
109
+ return;
110
+ }
111
+
112
+ return combine(
113
+ // Check if user scrolls.
114
+ addEventListener(scrollerRef.current, 'wheel', () => {
115
+ setPinned(isBottom(scrollerRef.current));
116
+ }),
117
+ // Check if scrolls.
118
+ addEventListener(scrollerRef.current, 'scroll', () => {
119
+ setOverflow((scrollerRef.current?.scrollTop ?? 0) > 0);
120
+ }),
121
+ );
122
+ }, []);
123
+
124
+ return (
125
+ <ScrollContainerProvider pinned={pinned} controller={controller} scrollToBottom={scrollToBottom}>
126
+ <div className='relative grid flex-1 min-bs-0 overflow-hidden'>
127
+ {fade && (
128
+ <div
129
+ role='none'
130
+ data-visible={overflow}
131
+ className={mx(
132
+ // NOTE: Gradients may not be visible with dark reader extensions.
133
+ 'z-10 absolute block-start-0 inset-inline-0 bs-24 is-full',
134
+ 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
135
+ 'bg-gradient-to-b from-[--surface-bg] to-transparent pointer-events-none',
136
+ )}
137
+ />
138
+ )}
139
+ <div className={mx('flex flex-col min-bs-0 overflow-y-auto scrollbar-thin', classNames)} ref={scrollerRef}>
140
+ {children}
141
+ </div>
142
+ </div>
143
+ </ScrollContainerProvider>
144
+ );
145
+ });
146
+
147
+ Root.displayName = 'ScrollContainer.Root';
148
+
149
+ //
150
+ // Viewport
151
+ //
152
+
153
+ type ViewportProps = ThemedClassName<PropsWithChildren<Omit<HTMLAttributes<HTMLDivElement>, 'className'>>>;
154
+
155
+ const Viewport = forwardRef<HTMLDivElement, ViewportProps>(({ classNames, children, ...props }, forwardedRef) => {
156
+ const contentRef = useForwardedRef(forwardedRef);
157
+ const { pinned, scrollToBottom } = useScrollContainerContext(Viewport.displayName!);
158
+
159
+ useEffect(() => {
160
+ if (!pinned || !contentRef.current) {
161
+ return;
162
+ }
163
+
164
+ // Setup resize observer to detect content changes.
165
+ const resizeObserver = new ResizeObserver(() => scrollToBottom());
166
+ scrollToBottom('instant');
167
+
168
+ resizeObserver.observe(contentRef.current);
169
+ return () => {
170
+ resizeObserver.disconnect();
171
+ };
172
+ }, [pinned, scrollToBottom]);
173
+
174
+ return (
175
+ <div className={mx('is-full', classNames)} {...props} ref={contentRef}>
176
+ {children}
177
+ </div>
178
+ );
179
+ });
180
+
181
+ Viewport.displayName = 'ScrollContainer.Viewport';
182
+
183
+ //
184
+ // ScrollDownButton
185
+ //
186
+
187
+ type ScrollDownButtonProps = ThemedClassName;
188
+
189
+ const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
190
+ const { pinned, scrollToBottom } = useScrollContainerContext(ScrollDownButton.displayName!);
191
+
192
+ return (
193
+ <div
194
+ role='none'
195
+ className={mx(
196
+ 'absolute bottom-2 right-4 opacity-100 transition-opacity duration-300',
197
+ pinned && 'opacity-0',
198
+ classNames,
199
+ )}
200
+ >
201
+ <IconButton
202
+ variant='primary'
203
+ icon='ph--arrow-down--regular'
204
+ iconOnly
205
+ size={4}
206
+ label='Scroll down'
207
+ onClick={() => scrollToBottom()}
208
+ />
209
+ </div>
210
+ );
211
+ };
212
+
213
+ ScrollDownButton.displayName = 'ScrollContainer.ScrollDownButton';
214
+
215
+ //
216
+ // ScrollContainer
217
+ //
218
+
219
+ export { useScrollContainerContext };
220
+
221
+ export const ScrollContainer = {
222
+ Root,
223
+ Viewport,
224
+ ScrollDownButton,
225
+ };
226
+
227
+ export type {
228
+ RootProps as ScrollContainerRootProps,
229
+ ViewportProps as ScrollContainerViewportProps,
230
+ ScrollDownButtonProps as ScrollContainerScrollDownButtonProps,
231
+ };
@@ -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
- };
@@ -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
- <span className='w-1 flex-1' />
42
+ <span className='is-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,6 +59,7 @@ 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
64
  className={tx('select.content', 'select__content', { elevation }, classNames)}
66
65
  position='popper'
@@ -83,7 +82,7 @@ const SelectScrollUpButton = forwardRef<HTMLDivElement, SelectScrollUpButtonProp
83
82
  className={tx('select.scrollButton', 'select__scroll-button--up', {}, 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
  },
@@ -100,7 +99,7 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
100
99
  className={tx('select.scrollButton', 'select__scroll-button--down', {}, 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,7 +108,7 @@ 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
114
  <SelectPrimitive.SelectViewport
@@ -153,12 +152,13 @@ const SelectItemIndicator = forwardRef<HTMLDivElement, SelectItemIndicatorProps>
153
152
 
154
153
  type SelectOptionProps = SelectItemProps;
155
154
 
155
+ // TODO(burdon): Option to show icon on left/right.
156
156
  const SelectOption = forwardRef<HTMLDivElement, SelectItemProps>(({ children, classNames, ...props }, forwardedRef) => {
157
157
  const { tx } = useThemeContext();
158
158
  return (
159
159
  <SelectPrimitive.Item {...props} className={tx('select.item', 'option', {}, classNames)} ref={forwardedRef}>
160
160
  <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
161
- <span className='grow w-1' />
161
+ <span className='grow is-1' />
162
162
  {/* <SelectPrimitive.ItemIndicator className={tx('select.itemIndicator', 'option__indicator', {})}> */}
163
163
  <Icon icon='ph--check--regular' />
164
164
  {/* </SelectPrimitive.ItemIndicator> */}
@@ -2,19 +2,22 @@
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 from 'react';
8
7
 
9
- import { Status } from './Status';
10
8
  import { withTheme } from '../../testing';
11
9
 
12
- export default {
10
+ import { Status } from './Status';
11
+
12
+ const meta = {
13
13
  title: 'ui/react-ui-core/Status',
14
14
  component: Status,
15
15
  decorators: [withTheme],
16
- parameters: { chromatic: { disableSnapshot: false } },
17
- };
16
+ } satisfies Meta<typeof Status>;
17
+
18
+ export default meta;
19
+
20
+ type Story = StoryObj<typeof meta>;
18
21
 
19
22
  export const Normal = (props: any) => {
20
23
  return (
@@ -1,25 +1,22 @@
1
1
  //
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
4
6
  import React from 'react';
5
7
 
6
8
  import { hues } from '@dxos/react-ui-theme';
7
- import '@dxos-theme';
8
9
  import { type ChromaticPalette, type MessageValence } from '@dxos/react-ui-types';
9
10
 
10
- import { Tag } from './Tag';
11
11
  import { withTheme } from '../../testing';
12
12
 
13
+ import { Tag } from './Tag';
14
+
13
15
  const palettes = ['neutral', 'success', 'info', 'warning', 'error', ...hues] as (ChromaticPalette | MessageValence)[];
14
16
 
15
- export default {
17
+ const meta = {
16
18
  title: 'ui/react-ui-core/Tag',
17
19
  component: Tag,
18
- decorators: [withTheme],
19
- parameters: { chromatic: { disableSnapshot: false } },
20
- } as const;
21
-
22
- export const Default = {
23
20
  render: () => (
24
21
  <div role='grid' className='grid grid-cols-5 gap-2 max-is-screen-md'>
25
22
  {palettes.map((palette) => (
@@ -29,4 +26,16 @@ export const Default = {
29
26
  ))}
30
27
  </div>
31
28
  ),
32
- };
29
+ decorators: [withTheme],
30
+ parameters: {
31
+ chromatic: {
32
+ disableSnapshot: false,
33
+ },
34
+ },
35
+ } satisfies Meta<typeof Tag>;
36
+
37
+ export default meta;
38
+
39
+ type Story = StoryObj<typeof meta>;
40
+
41
+ export const Default: Story = {};
@@ -3,16 +3,17 @@
3
3
  //
4
4
 
5
5
  import { createKeyborg } from 'keyborg';
6
- import React, { createContext, type PropsWithChildren, useEffect, useMemo } from 'react';
6
+ import React, { type PropsWithChildren, createContext, useEffect, useMemo } from 'react';
7
7
 
8
8
  import { type Density, type Elevation, type ThemeFunction } from '@dxos/react-ui-types';
9
9
 
10
- import { TranslationsProvider, type TranslationsProviderProps } from './TranslationsProvider';
11
10
  import { type SafeAreaPadding, useSafeArea } from '../../hooks';
12
11
  import { hasIosKeyboard } from '../../util';
13
12
  import { DensityProvider } from '../DensityProvider';
14
13
  import { ElevationProvider } from '../ElevationProvider';
15
14
 
15
+ import { TranslationsProvider, type TranslationsProviderProps } from './TranslationsProvider';
16
+
16
17
  export type ThemeMode = 'dark' | 'light';
17
18
 
18
19
  export type ThemeContextValue = {
@@ -2,9 +2,9 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { enUS as dtLocaleEnUs, type Locale } from 'date-fns/locale';
6
- import i18Next, { type TFunction, type Resource } from 'i18next';
7
- import React, { type ReactNode, useEffect, createContext, useState, Suspense, useContext } from 'react';
5
+ import { type Locale, enUS as dtLocaleEnUs } from 'date-fns/locale';
6
+ import i18Next, { type Resource, type TFunction } from 'i18next';
7
+ import React, { type ReactNode, Suspense, createContext, useContext, useEffect, useState } from 'react';
8
8
  import { initReactI18next, useTranslation as useI18NextTranslation } from 'react-i18next';
9
9
 
10
10
  const initialLng = 'en-US';
@@ -2,13 +2,13 @@
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 ReactNode, useState } from 'react';
8
7
 
9
- import { Toast } from './Toast';
10
8
  import { withTheme } from '../../testing';
11
- import { Button } from '../Buttons';
9
+ import { Button } from '../Button';
10
+
11
+ import { Toast } from './Toast';
12
12
 
13
13
  type ActionTriggerProps = { altText: string; trigger: ReactNode };
14
14
 
@@ -44,15 +44,18 @@ const DefaultStory = ({ title, description, actionTriggers, openTrigger, closeTr
44
44
  );
45
45
  };
46
46
 
47
- export default {
47
+ const meta = {
48
48
  title: 'ui/react-ui-core/Toast',
49
- component: Toast,
49
+ component: Toast as any,
50
50
  render: DefaultStory,
51
51
  decorators: [withTheme],
52
- parameters: { chromatic: { disableSnapshot: false } },
53
- };
52
+ } satisfies Meta<typeof DefaultStory>;
53
+
54
+ export default meta;
55
+
56
+ type Story = StoryObj<typeof meta>;
54
57
 
55
- export const Default = {
58
+ export const Default: Story = {
56
59
  args: {
57
60
  openTrigger: 'Open toast',
58
61
  title: 'This is a toast',
@@ -5,22 +5,22 @@
5
5
  import { Primitive } from '@radix-ui/react-primitive';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
7
  import {
8
+ ToastAction as ToastActionPrimitive,
9
+ type ToastActionProps as ToastActionPrimitiveProps,
10
+ ToastClose as ToastClosePrimitive,
11
+ type ToastCloseProps as ToastClosePrimitiveProps,
12
+ ToastDescription as ToastDescriptionPrimitive,
13
+ type ToastDescriptionProps as ToastDescriptionPrimitiveProps,
8
14
  ToastProvider as ToastProviderPrimitive,
9
15
  type ToastProviderProps as ToastProviderPrimitiveProps,
10
- ToastViewport as ToastViewportPrimitive,
11
- type ToastViewportProps as ToastViewportPrimitiveProps,
12
16
  Root as ToastRootPrimitive,
13
17
  type ToastProps as ToastRootPrimitiveProps,
14
18
  ToastTitle as ToastTitlePrimitive,
15
19
  type ToastTitleProps as ToastTitlePrimitiveProps,
16
- ToastDescription as ToastDescriptionPrimitive,
17
- type ToastDescriptionProps as ToastDescriptionPrimitiveProps,
18
- ToastAction as ToastActionPrimitive,
19
- type ToastActionProps as ToastActionPrimitiveProps,
20
- ToastClose as ToastClosePrimitive,
21
- type ToastCloseProps as ToastClosePrimitiveProps,
20
+ ToastViewport as ToastViewportPrimitive,
21
+ type ToastViewportProps as ToastViewportPrimitiveProps,
22
22
  } from '@radix-ui/react-toast';
23
- import React, { type ComponentPropsWithRef, forwardRef, type FunctionComponent } from 'react';
23
+ import React, { type ComponentPropsWithRef, type FunctionComponent, forwardRef } from 'react';
24
24
 
25
25
  import { useThemeContext } from '../../hooks';
26
26
  import { type ThemedClassName } from '../../util';
@@ -2,16 +2,16 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { ArrowClockwise, Bug, FileJs, FileTs, TextB, TextItalic, TextUnderline } from '@phosphor-icons/react';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
- import { Toolbar } from './Toolbar';
11
8
  import { withTheme } from '../../testing';
12
- import { Toggle } from '../Buttons';
9
+ import { Toggle } from '../Button';
10
+ import { Icon } from '../Icon';
13
11
  import { Select } from '../Select';
14
12
 
13
+ import { Toolbar } from './Toolbar';
14
+
15
15
  type StorybookToolbarProps = {};
16
16
 
17
17
  const DefaultStory = (props: StorybookToolbarProps) => {
@@ -29,6 +29,7 @@ const DefaultStory = (props: StorybookToolbarProps) => {
29
29
  <Select.Option value={'b'}>B</Select.Option>
30
30
  <Select.Option value={'c'}>C</Select.Option>
31
31
  </Select.Viewport>
32
+ <Select.Arrow />
32
33
  </Select.Content>
33
34
  </Select.Portal>
34
35
  </Select.Root>
@@ -37,46 +38,47 @@ const DefaultStory = (props: StorybookToolbarProps) => {
37
38
  {/* TODO(burdon): Icon sizes should adapt to density. */}
38
39
  <Toolbar.ToggleGroup type='multiple'>
39
40
  <Toolbar.ToggleGroupItem value='a'>
40
- <TextB />
41
+ <Icon icon='ph--text-b--regular' />
41
42
  </Toolbar.ToggleGroupItem>
42
43
  <Toolbar.ToggleGroupItem value='b'>
43
- <TextItalic />
44
+ <Icon icon='ph--text-italic--regular' />
44
45
  </Toolbar.ToggleGroupItem>
45
46
  <Toolbar.ToggleGroupItem value='c'>
46
- <TextUnderline />
47
+ <Icon icon='ph--text-underline--regular' />
47
48
  </Toolbar.ToggleGroupItem>
48
49
  </Toolbar.ToggleGroup>
49
50
  {/* TODO(burdon): Highlight isn't shown. */}
50
51
  <Toolbar.ToggleGroup type='single' defaultValue='a'>
51
52
  <Toolbar.ToggleGroupItem value='a'>
52
- <FileTs />
53
+ <Icon icon='ph--file-ts--regular' />
53
54
  </Toolbar.ToggleGroupItem>
54
55
  <Toolbar.ToggleGroupItem value='b'>
55
- <FileJs />
56
+ <Icon icon='ph--file-js--regular' />
56
57
  </Toolbar.ToggleGroupItem>
57
58
  </Toolbar.ToggleGroup>
58
59
  <Toolbar.Button asChild>
59
60
  <Toggle>
60
- <Bug />
61
+ <Icon icon='ph--bug--regular' />
61
62
  </Toggle>
62
63
  </Toolbar.Button>
63
64
  <Toolbar.Separator />
64
65
  <Toolbar.Button>Test</Toolbar.Button>
65
- <Toolbar.Button>
66
- <ArrowClockwise />
67
- </Toolbar.Button>
66
+ <Toolbar.IconButton icon='ph--arrow-clockwise--regular' label='Refresh' iconOnly />
68
67
  </Toolbar.Root>
69
68
  );
70
69
  };
71
70
 
72
- export default {
71
+ const meta = {
73
72
  title: 'ui/react-ui-core/Toolbar',
74
- component: Toolbar,
73
+ component: Toolbar as any,
75
74
  render: DefaultStory,
76
75
  decorators: [withTheme],
77
- parameters: { chromatic: { disableSnapshot: false } },
78
- };
76
+ } satisfies Meta<typeof DefaultStory>;
77
+
78
+ export default meta;
79
+
80
+ type Story = StoryObj<typeof meta>;
79
81
 
80
- export const Default = {
82
+ export const Default: Story = {
81
83
  args: {},
82
84
  };