@dxos/react-ui 0.8.4-main.ef1bc66f44 → 0.8.4-main.f466a3d56e

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 (376) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/chunk-A5QCIG5R.mjs +24 -0
  4. package/dist/lib/browser/chunk-A5QCIG5R.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-EJYV4HAH.mjs → chunk-LY5XDQR5.mjs} +189 -117
  6. package/dist/lib/browser/chunk-LY5XDQR5.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +3257 -2048
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/testing/index.mjs +70 -41
  11. package/dist/lib/browser/testing/index.mjs.map +4 -4
  12. package/dist/lib/browser/translations.mjs +9 -0
  13. package/dist/lib/browser/translations.mjs.map +7 -0
  14. package/dist/lib/node-esm/{chunk-YTLZCZ2M.mjs → chunk-NGKLIKP3.mjs} +189 -117
  15. package/dist/lib/node-esm/chunk-NGKLIKP3.mjs.map +7 -0
  16. package/dist/lib/node-esm/chunk-XCFLA74M.mjs +26 -0
  17. package/dist/lib/node-esm/chunk-XCFLA74M.mjs.map +7 -0
  18. package/dist/lib/node-esm/index.mjs +3257 -2048
  19. package/dist/lib/node-esm/index.mjs.map +4 -4
  20. package/dist/lib/node-esm/meta.json +1 -1
  21. package/dist/lib/node-esm/testing/index.mjs +70 -41
  22. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  23. package/dist/lib/node-esm/translations.mjs +10 -0
  24. package/dist/lib/node-esm/translations.mjs.map +7 -0
  25. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  26. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  27. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  30. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Button/Button.d.ts +2 -2
  32. package/dist/types/src/components/Button/Button.d.ts.map +1 -1
  33. package/dist/types/src/components/Button/Button.stories.d.ts +1 -1
  34. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -1
  35. package/dist/types/src/components/Button/IconButton.d.ts +1 -0
  36. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
  37. package/dist/types/src/components/Button/IconButton.stories.d.ts +3 -0
  38. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -1
  39. package/dist/types/src/components/Button/Toggle.d.ts +2 -2
  40. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -1
  41. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -1
  42. package/dist/types/src/components/Button/ToggleGroup.d.ts +6 -6
  43. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
  44. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +2 -2
  45. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/Card/Card.d.ts +124 -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/Carousel/Carousel.d.ts +90 -0
  53. package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -0
  54. package/dist/types/src/components/Carousel/index.d.ts +2 -0
  55. package/dist/types/src/components/Carousel/index.d.ts.map +1 -0
  56. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  57. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  58. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  59. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  60. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  61. package/dist/types/src/components/Dialog/AlertDialog.d.ts +43 -23
  62. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
  63. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
  64. package/dist/types/src/components/Dialog/Dialog.d.ts +48 -30
  65. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  66. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +6 -8
  67. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
  68. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  69. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  70. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  71. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  72. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  73. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +19 -0
  74. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  75. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  76. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  77. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  78. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  79. package/dist/types/src/components/Focus/Focus.d.ts +36 -0
  80. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  81. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  82. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  83. package/dist/types/src/components/Focus/index.d.ts +2 -0
  84. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  85. package/dist/types/src/components/Icon/Icon.d.ts +4 -0
  86. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  87. package/dist/types/src/components/Icon/Icon.stories.d.ts +11 -3
  88. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
  89. package/dist/types/src/components/Image/Image.d.ts +15 -0
  90. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  91. package/dist/types/src/components/Image/Image.stories.d.ts +34 -0
  92. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  93. package/dist/types/src/components/Image/index.d.ts +2 -0
  94. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  95. package/dist/types/src/components/Input/Input.d.ts +16 -22
  96. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  97. package/dist/types/src/components/Input/Input.stories.d.ts +6 -6
  98. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  99. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  100. package/dist/types/src/components/List/List.d.ts +5 -3
  101. package/dist/types/src/components/List/List.d.ts.map +1 -1
  102. package/dist/types/src/components/List/List.stories.d.ts +3 -1
  103. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  104. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -1
  105. package/dist/types/src/components/List/Tree.d.ts +2 -2
  106. package/dist/types/src/components/List/Tree.d.ts.map +1 -1
  107. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -1
  108. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -1
  109. package/dist/types/src/components/List/Treegrid.d.ts +5 -9
  110. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
  111. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -1
  112. package/dist/types/src/components/Main/Main.d.ts +11 -7
  113. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  114. package/dist/types/src/components/Main/Main.stories.d.ts +0 -3
  115. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  116. package/dist/types/src/components/Main/useSwipeToDismiss.d.ts.map +1 -1
  117. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts +46 -0
  118. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts.map +1 -0
  119. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts +16 -0
  120. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts.map +1 -0
  121. package/dist/types/src/components/MediaPlayer/index.d.ts +2 -0
  122. package/dist/types/src/components/MediaPlayer/index.d.ts.map +1 -0
  123. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
  124. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -1
  125. package/dist/types/src/components/Menu/DropdownMenu.d.ts +58 -49
  126. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
  127. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +14 -1
  128. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -1
  129. package/dist/types/src/components/Message/Message.d.ts +1 -1
  130. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  131. package/dist/types/src/components/Message/Message.stories.d.ts +4 -5
  132. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/Popover/Popover.d.ts +39 -22
  134. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  135. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  136. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +12 -11
  137. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  138. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +21 -10
  139. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  140. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +42 -13
  141. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
  142. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +9 -5
  143. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
  144. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  145. package/dist/types/src/components/Select/Select.stories.d.ts +2 -2
  146. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  147. package/dist/types/src/components/Separator/Separator.d.ts +3 -3
  148. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  149. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -1
  150. package/dist/types/src/components/Splitter/Splitter.d.ts +23 -15
  151. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -1
  152. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -1
  153. package/dist/types/src/components/Status/Status.d.ts +3 -4
  154. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  155. package/dist/types/src/components/Status/Status.stories.d.ts +4 -2
  156. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  157. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  158. package/dist/types/src/components/Tag/Tag.stories.d.ts +0 -5
  159. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  160. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +1 -1
  161. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  162. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  163. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  164. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +54 -55
  165. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  166. package/dist/types/src/components/ThemeProvider/index.d.ts +1 -1
  167. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  168. package/dist/types/src/components/Toast/Toast.d.ts +16 -16
  169. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  170. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  171. package/dist/types/src/components/Toolbar/Toolbar.d.ts +32 -15
  172. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  173. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  174. package/dist/types/src/components/Tooltip/Tooltip.d.ts +16 -16
  175. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  176. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -2
  177. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  178. package/dist/types/src/components/index.d.ts +9 -4
  179. package/dist/types/src/components/index.d.ts.map +1 -1
  180. package/dist/types/src/exemplars/generics.stories.d.ts +8 -6
  181. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -1
  182. package/dist/types/src/exemplars/slot.stories.d.ts +1 -0
  183. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -1
  184. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -1
  185. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  186. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  187. package/dist/types/src/hooks/index.d.ts +1 -0
  188. package/dist/types/src/hooks/index.d.ts.map +1 -1
  189. package/dist/types/src/hooks/useDensityContext.d.ts +1 -1
  190. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  191. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  192. package/dist/types/src/hooks/useIconHref.d.ts.map +1 -1
  193. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  194. package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -1
  195. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  196. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  197. package/dist/types/src/playground/Custom.stories.d.ts +1 -1
  198. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  199. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  200. package/dist/types/src/primitives/Column/Column.d.ts +33 -0
  201. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  202. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  203. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  204. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  205. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  206. package/dist/types/src/primitives/Container/Container.d.ts +6 -22
  207. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -1
  208. package/dist/types/src/primitives/Container/Container.stories.d.ts +2 -7
  209. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -1
  210. package/dist/types/src/primitives/Container/index.d.ts +0 -1
  211. package/dist/types/src/primitives/Container/index.d.ts.map +1 -1
  212. package/dist/types/src/primitives/Flex/Flex.d.ts +8 -5
  213. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -1
  214. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  215. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  216. package/dist/types/src/primitives/Grid/Grid.d.ts +10 -0
  217. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  218. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  219. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  220. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  221. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  222. package/dist/types/src/primitives/Panel/Panel.d.ts +35 -0
  223. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  224. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  225. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  226. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  227. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  228. package/dist/types/src/primitives/index.d.ts +3 -0
  229. package/dist/types/src/primitives/index.d.ts.map +1 -1
  230. package/dist/types/src/testing/Loading.d.ts +9 -0
  231. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  232. package/dist/types/src/testing/decorators/withLayout.d.ts +1 -1
  233. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  234. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
  235. package/dist/types/src/testing/decorators/withTheme.d.ts +1 -1
  236. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  237. package/dist/types/src/testing/index.d.ts +1 -0
  238. package/dist/types/src/testing/index.d.ts.map +1 -1
  239. package/dist/types/src/translations.d.ts +16 -0
  240. package/dist/types/src/translations.d.ts.map +1 -0
  241. package/dist/types/src/util/usePx.d.ts.map +1 -1
  242. package/dist/types/tsconfig.tsbuildinfo +1 -1
  243. package/package.json +34 -27
  244. package/src/components/Avatars/Avatar.stories.tsx +5 -7
  245. package/src/components/Avatars/Avatar.tsx +6 -14
  246. package/src/components/Avatars/AvatarGroup.stories.tsx +0 -1
  247. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -2
  248. package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
  249. package/src/components/Button/Button.stories.tsx +1 -2
  250. package/src/components/Button/Button.tsx +11 -25
  251. package/src/components/Button/IconButton.stories.tsx +6 -4
  252. package/src/components/Button/IconButton.tsx +3 -4
  253. package/src/components/Button/Toggle.stories.tsx +0 -1
  254. package/src/components/Button/Toggle.tsx +4 -4
  255. package/src/components/Button/ToggleGroup.stories.tsx +0 -1
  256. package/src/components/Button/ToggleGroup.tsx +12 -16
  257. package/src/components/Card/Card.stories.tsx +151 -0
  258. package/src/components/Card/Card.tsx +514 -0
  259. package/src/components/Card/index.ts +5 -0
  260. package/src/components/Carousel/Carousel.tsx +337 -0
  261. package/src/components/Carousel/index.ts +5 -0
  262. package/src/components/Clipboard/CopyButton.tsx +6 -7
  263. package/src/components/Dialog/AlertDialog.stories.tsx +14 -15
  264. package/src/components/Dialog/AlertDialog.tsx +123 -82
  265. package/src/components/Dialog/Dialog.stories.tsx +90 -14
  266. package/src/components/Dialog/Dialog.tsx +98 -113
  267. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +45 -0
  268. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  269. package/src/components/ErrorFallback/ErrorStack.tsx +114 -0
  270. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  271. package/src/components/ErrorFallback/index.ts +9 -0
  272. package/src/components/Focus/AUDIT.md +43 -0
  273. package/src/components/Focus/Focus.stories.tsx +230 -0
  274. package/src/components/Focus/Focus.tsx +201 -0
  275. package/src/components/Focus/index.ts +5 -0
  276. package/src/components/Icon/Icon.stories.tsx +43 -13
  277. package/src/components/Icon/Icon.tsx +14 -3
  278. package/src/components/Image/Image.stories.tsx +86 -0
  279. package/src/components/Image/Image.tsx +246 -0
  280. package/src/components/Image/index.ts +5 -0
  281. package/src/components/Input/Input.stories.tsx +17 -38
  282. package/src/components/Input/Input.tsx +27 -71
  283. package/src/components/Link/Link.stories.tsx +0 -1
  284. package/src/components/Link/Link.tsx +2 -2
  285. package/src/components/List/List.stories.tsx +14 -22
  286. package/src/components/List/List.tsx +16 -20
  287. package/src/components/List/ListDropIndicator.tsx +7 -8
  288. package/src/components/List/Tree.stories.tsx +4 -5
  289. package/src/components/List/Tree.tsx +0 -1
  290. package/src/components/List/TreeDropIndicator.tsx +6 -6
  291. package/src/components/List/Treegrid.stories.tsx +27 -28
  292. package/src/components/List/Treegrid.tsx +22 -27
  293. package/src/components/Main/Main.stories.tsx +3 -7
  294. package/src/components/Main/Main.tsx +57 -48
  295. package/src/components/MediaPlayer/MediaPlayer.stories.tsx +50 -0
  296. package/src/components/MediaPlayer/MediaPlayer.tsx +153 -0
  297. package/src/components/MediaPlayer/index.ts +5 -0
  298. package/src/components/Menu/ContextMenu.stories.tsx +0 -1
  299. package/src/components/Menu/ContextMenu.tsx +9 -33
  300. package/src/components/Menu/DropdownMenu.stories.tsx +0 -1
  301. package/src/components/Menu/DropdownMenu.tsx +58 -52
  302. package/src/components/Message/Message.stories.tsx +25 -11
  303. package/src/components/Message/Message.tsx +30 -29
  304. package/src/components/Popover/Popover.stories.tsx +5 -6
  305. package/src/components/Popover/Popover.tsx +62 -59
  306. package/src/components/ScrollArea/ScrollArea.stories.tsx +98 -39
  307. package/src/components/ScrollArea/ScrollArea.tsx +45 -33
  308. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +46 -25
  309. package/src/components/ScrollContainer/ScrollContainer.tsx +199 -92
  310. package/src/components/Select/Select.stories.tsx +5 -6
  311. package/src/components/Select/Select.tsx +11 -27
  312. package/src/components/Separator/Separator.tsx +5 -8
  313. package/src/components/Skeleton/Skeleton.stories.tsx +12 -13
  314. package/src/components/Skeleton/Skeleton.tsx +1 -1
  315. package/src/components/Splitter/Splitter.stories.tsx +47 -37
  316. package/src/components/Splitter/Splitter.tsx +44 -40
  317. package/src/components/Status/Status.stories.tsx +19 -16
  318. package/src/components/Status/Status.tsx +10 -7
  319. package/src/components/Tag/Tag.stories.tsx +3 -9
  320. package/src/components/Tag/Tag.tsx +2 -7
  321. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +31 -0
  322. package/src/components/ThemeProvider/ThemeProvider.tsx +8 -7
  323. package/src/components/ThemeProvider/index.ts +1 -1
  324. package/src/components/Toast/Toast.stories.tsx +0 -1
  325. package/src/components/Toast/Toast.tsx +22 -41
  326. package/src/components/Toolbar/Toolbar.stories.tsx +0 -1
  327. package/src/components/Toolbar/Toolbar.tsx +175 -30
  328. package/src/components/Tooltip/Tooltip.stories.tsx +18 -17
  329. package/src/components/Tooltip/Tooltip.tsx +32 -31
  330. package/src/components/index.ts +10 -5
  331. package/src/exemplars/generics.stories.tsx +12 -15
  332. package/src/exemplars/slot.stories.tsx +68 -61
  333. package/src/exemplars/tabster.stories.tsx +5 -5
  334. package/src/exemplars/virtualizer.stories.tsx +136 -0
  335. package/src/hooks/index.ts +1 -0
  336. package/src/hooks/useDensityContext.ts +2 -2
  337. package/src/playground/Controls.stories.tsx +0 -6
  338. package/src/playground/Custom.stories.tsx +13 -16
  339. package/src/playground/Typography.stories.tsx +1 -1
  340. package/src/primitives/Column/AUDIT.md +148 -0
  341. package/src/primitives/Column/Column.stories.tsx +181 -0
  342. package/src/primitives/Column/Column.tsx +165 -0
  343. package/src/primitives/Column/index.ts +5 -0
  344. package/src/primitives/Container/Container.stories.tsx +13 -51
  345. package/src/primitives/Container/Container.tsx +14 -77
  346. package/src/primitives/Container/index.ts +0 -1
  347. package/src/primitives/Flex/Flex.stories.tsx +57 -0
  348. package/src/primitives/Flex/Flex.tsx +20 -19
  349. package/src/primitives/Grid/Grid.stories.tsx +56 -0
  350. package/src/primitives/Grid/Grid.tsx +30 -0
  351. package/src/primitives/Grid/index.ts +5 -0
  352. package/src/primitives/Panel/Panel.stories.tsx +68 -0
  353. package/src/primitives/Panel/Panel.tsx +120 -0
  354. package/src/primitives/Panel/index.ts +5 -0
  355. package/src/primitives/index.ts +3 -0
  356. package/src/testing/Loading.tsx +47 -0
  357. package/src/testing/decorators/withLayout.tsx +15 -11
  358. package/src/testing/decorators/withLayoutVariants.tsx +18 -21
  359. package/src/testing/decorators/withTheme.tsx +10 -7
  360. package/src/testing/index.ts +2 -0
  361. package/src/translations.ts +24 -0
  362. package/src/util/usePx.ts +1 -0
  363. package/dist/lib/browser/chunk-EJYV4HAH.mjs.map +0 -7
  364. package/dist/lib/node-esm/chunk-YTLZCZ2M.mjs.map +0 -7
  365. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -22
  366. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  367. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  368. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  369. package/dist/types/src/primitives/Container/Layout.d.ts +0 -18
  370. package/dist/types/src/primitives/Container/Layout.d.ts.map +0 -1
  371. package/dist/types/src/primitives/Container/Layout.stories.d.ts +0 -10
  372. package/dist/types/src/primitives/Container/Layout.stories.d.ts.map +0 -1
  373. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -67
  374. package/src/components/AnchoredOverflow/index.ts +0 -5
  375. package/src/primitives/Container/Layout.stories.tsx +0 -57
  376. package/src/primitives/Container/Layout.tsx +0 -61
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  // This is based upon `@radix-ui/react-tooltip` fetched 17 March 2025 at https://github.com/radix-ui/primitives at commit 6e75e11.
6
+ // TODO(burdon): Replace with https://ui.shadcn.com/docs/components/radix/tooltip
6
7
 
7
8
  import { composeEventHandlers } from '@radix-ui/primitive';
8
9
  import { useComposedRefs } from '@radix-ui/react-compose-refs';
@@ -21,9 +22,8 @@ import { useControllableState } from '@radix-ui/react-use-controllable-state';
21
22
  import * as VisuallyHiddenPrimitive from '@radix-ui/react-visually-hidden';
22
23
  import React, {
23
24
  type ComponentPropsWithoutRef,
24
- type ElementRef,
25
+ type ComponentRef,
25
26
  type FC,
26
- type MutableRefObject,
27
27
  type ReactNode,
28
28
  type RefObject,
29
29
  type SyntheticEvent,
@@ -54,19 +54,19 @@ type TooltipContextValue = {
54
54
  open: boolean;
55
55
  stateAttribute: 'closed' | 'delayed-open' | 'instant-open';
56
56
  trigger: TooltipTriggerElement | null;
57
- onTriggerChange(trigger: TooltipTriggerElement | null): void;
57
+ onTriggerChange(trigger: TooltipTriggerElement | null, content?: ReactNode, side?: TooltipSide): void;
58
58
  onTriggerEnter(): void;
59
59
  onTriggerLeave(): void;
60
60
  onOpen(): void;
61
61
  onClose(): void;
62
62
  onPointerInTransitChange(inTransit: boolean): void;
63
- isPointerInTransitRef: MutableRefObject<boolean>;
63
+ isPointerInTransitRef: RefObject<boolean>;
64
64
  disableHoverableContent: boolean;
65
65
  };
66
66
 
67
67
  const [TooltipContextProvider, useTooltipContext] = createTooltipContext<TooltipContextValue>(TOOLTIP_NAME);
68
68
 
69
- interface TooltipProviderProps {
69
+ type TooltipProviderProps = {
70
70
  children?: ReactNode;
71
71
  open?: boolean;
72
72
  defaultOpen?: boolean;
@@ -87,7 +87,7 @@ interface TooltipProviderProps {
87
87
  * @defaultValue 300
88
88
  */
89
89
  skipDelayDuration?: number;
90
- }
90
+ };
91
91
 
92
92
  const TooltipProvider: FC<TooltipProviderProps> = (props: TooltipScopedProps<TooltipProviderProps>) => {
93
93
  const {
@@ -111,15 +111,18 @@ const TooltipProvider: FC<TooltipProviderProps> = (props: TooltipScopedProps<Too
111
111
 
112
112
  const popperScope = usePopperScope(__scopeTooltip);
113
113
  const [trigger, setTrigger] = useState<HTMLButtonElement | null>(null);
114
- const [content, setContent] = useState<string>('');
114
+ const [content, setContent] = useState<ReactNode>(null);
115
115
  const [side, setSide] = useState<TooltipSide | undefined>(undefined);
116
116
  const triggerRef = useRef<HTMLButtonElement | null>(trigger);
117
- const handleTriggerChange = useCallback((nextTrigger: HTMLButtonElement | null) => {
118
- setTrigger(nextTrigger);
119
- triggerRef.current = nextTrigger;
120
- setContent(nextTrigger?.getAttribute('data-tooltip-content') ?? '');
121
- setSide((nextTrigger?.getAttribute('data-tooltip-side') as TooltipSide | null) ?? undefined);
122
- }, []);
117
+ const handleTriggerChange = useCallback(
118
+ (nextTrigger: HTMLButtonElement | null, nextContent?: ReactNode, nextSide?: TooltipSide) => {
119
+ setTrigger(nextTrigger);
120
+ triggerRef.current = nextTrigger;
121
+ setContent(nextContent ?? null);
122
+ setSide(nextSide);
123
+ },
124
+ [],
125
+ );
123
126
  const contentId = useId();
124
127
  const openTimerRef = useRef(0);
125
128
  const wasOpenDelayedRef = useRef(false);
@@ -215,9 +218,9 @@ const TooltipProvider: FC<TooltipProviderProps> = (props: TooltipScopedProps<Too
215
218
  isPointerInTransitRef.current = inTransit;
216
219
  }, [])}
217
220
  >
218
- <TooltipContent side={side} className={tx('tooltip.content', 'tooltip', { elevation })}>
221
+ <TooltipContent side={side} className={tx('tooltip.content', { elevation })}>
219
222
  {content}
220
- <TooltipArrow className={tx('tooltip.arrow', 'tooltip__arrow')} />
223
+ <TooltipArrow className={tx('tooltip.arrow')} />
221
224
  </TooltipContent>
222
225
  <TooltipVirtualTrigger virtualRef={triggerRef as RefObject<HTMLButtonElement>} />
223
226
  {children}
@@ -246,11 +249,11 @@ const TooltipVirtualTrigger = ({
246
249
 
247
250
  const TRIGGER_NAME = 'TooltipTrigger';
248
251
 
249
- type TooltipTriggerElement = ElementRef<typeof Primitive.button>;
252
+ type TooltipTriggerElement = ComponentRef<typeof Primitive.button>;
250
253
  type PrimitiveButtonProps = ComponentPropsWithoutRef<typeof Primitive.button>;
251
- type TooltipTriggerProps = PrimitiveButtonProps &
254
+ type TooltipTriggerProps = Omit<PrimitiveButtonProps, 'content'> &
252
255
  Pick<TooltipProps, 'delayDuration'> & {
253
- content?: string;
256
+ content?: ReactNode;
254
257
  side?: TooltipSide;
255
258
  onInteract?: (event: SyntheticEvent) => void;
256
259
  };
@@ -283,8 +286,6 @@ const TooltipTrigger = forwardRef<TooltipTriggerElement, TooltipTriggerProps>(
283
286
  // commonly anchors and the anchor `type` attribute signifies MIME type.
284
287
  aria-describedby={context.open ? context.contentId : undefined}
285
288
  data-state={context.stateAttribute}
286
- data-tooltip-content={content}
287
- data-tooltip-side={side}
288
289
  {...triggerProps}
289
290
  ref={composedRefs}
290
291
  onPointerMove={composeEventHandlers(props.onPointerMove, (event) => {
@@ -296,7 +297,7 @@ const TooltipTrigger = forwardRef<TooltipTriggerElement, TooltipTriggerProps>(
296
297
  if (event.defaultPrevented) {
297
298
  return;
298
299
  }
299
- context.onTriggerChange(ref.current);
300
+ context.onTriggerChange(ref.current, content, side);
300
301
  context.onTriggerEnter();
301
302
  hasPointerMoveOpenedRef.current = true;
302
303
  }
@@ -334,7 +335,7 @@ const [PortalProvider, usePortalContext] = createTooltipContext<PortalContextVal
334
335
  });
335
336
 
336
337
  type PortalProps = ComponentPropsWithoutRef<typeof PortalPrimitive>;
337
- interface TooltipPortalProps {
338
+ type TooltipPortalProps = {
338
339
  children?: ReactNode;
339
340
  /**
340
341
  * Specify a container element to portal the content into.
@@ -345,7 +346,7 @@ interface TooltipPortalProps {
345
346
  * controlling animation with React animation libraries.
346
347
  */
347
348
  forceMount?: true;
348
- }
349
+ };
349
350
 
350
351
  const TooltipPortal: FC<TooltipPortalProps> = (props: TooltipScopedProps<TooltipPortalProps>) => {
351
352
  const { __scopeTooltip, forceMount, children, container } = props;
@@ -370,13 +371,13 @@ TooltipPortal.displayName = PORTAL_NAME;
370
371
  const CONTENT_NAME = 'TooltipContent';
371
372
 
372
373
  type TooltipContentElement = TooltipContentImplElement;
373
- interface TooltipContentProps extends TooltipContentImplProps {
374
+ type TooltipContentProps = TooltipContentImplProps & {
374
375
  /**
375
376
  * Used to force mounting when more control is needed. Useful when
376
377
  * controlling animation with React animation libraries.
377
378
  */
378
379
  forceMount?: true;
379
- }
380
+ };
380
381
 
381
382
  const TooltipContent = forwardRef<TooltipContentElement, TooltipContentProps>(
382
383
  (props: TooltipScopedProps<TooltipContentProps>, forwardedRef) => {
@@ -400,7 +401,7 @@ type Point = { x: number; y: number };
400
401
  type Polygon = Point[];
401
402
 
402
403
  type TooltipContentHoverableElement = TooltipContentImplElement;
403
- interface TooltipContentHoverableProps extends TooltipContentImplProps {}
404
+ type TooltipContentHoverableProps = TooltipContentImplProps;
404
405
 
405
406
  const TooltipContentHoverable = forwardRef<TooltipContentHoverableElement, TooltipContentHoverableProps>(
406
407
  (props: TooltipScopedProps<TooltipContentHoverableProps>, forwardedRef) => {
@@ -479,10 +480,10 @@ const [VisuallyHiddenContentContextProvider, useVisuallyHiddenContentContext] =
479
480
  isInside: false,
480
481
  });
481
482
 
482
- type TooltipContentImplElement = ElementRef<typeof PopperPrimitive.Content>;
483
+ type TooltipContentImplElement = ComponentRef<typeof PopperPrimitive.Content>;
483
484
  type DismissableLayerProps = ComponentPropsWithoutRef<typeof DismissableLayer>;
484
485
  type PopperContentProps = ComponentPropsWithoutRef<typeof PopperPrimitive.Content>;
485
- interface TooltipContentImplProps extends Omit<PopperContentProps, 'onPlaced'> {
486
+ type TooltipContentImplProps = Omit<PopperContentProps, 'onPlaced'> & {
486
487
  /**
487
488
  * A more descriptive label for accessibility purpose
488
489
  */
@@ -498,7 +499,7 @@ interface TooltipContentImplProps extends Omit<PopperContentProps, 'onPlaced'> {
498
499
  * Can be prevented.
499
500
  */
500
501
  onPointerDownOutside?: DismissableLayerProps['onPointerDownOutside'];
501
- }
502
+ };
502
503
 
503
504
  const TooltipContentImpl = forwardRef<TooltipContentImplElement, TooltipContentImplProps>(
504
505
  (props: TooltipScopedProps<TooltipContentImplProps>, forwardedRef) => {
@@ -580,9 +581,9 @@ TooltipContent.displayName = CONTENT_NAME;
580
581
 
581
582
  const ARROW_NAME = 'TooltipArrow';
582
583
 
583
- type TooltipArrowElement = ElementRef<typeof PopperPrimitive.Arrow>;
584
+ type TooltipArrowElement = ComponentRef<typeof PopperPrimitive.Arrow>;
584
585
  type PopperArrowProps = ComponentPropsWithoutRef<typeof PopperPrimitive.Arrow>;
585
- interface TooltipArrowProps extends PopperArrowProps {}
586
+ type TooltipArrowProps = PopperArrowProps;
586
587
 
587
588
  const TooltipArrow = forwardRef<TooltipArrowElement, TooltipArrowProps>(
588
589
  (props: TooltipScopedProps<TooltipArrowProps>, forwardedRef) => {
@@ -2,17 +2,26 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- export * from './AnchoredOverflow';
5
+ export * from './DensityProvider';
6
+ export * from './ElevationProvider';
7
+ export * from './ThemeProvider';
8
+
6
9
  export * from './Avatars';
7
10
  export * from './Breadcrumb';
8
11
  export * from './Button';
12
+ export * from './Card';
13
+ export * from './Carousel';
9
14
  export * from './Clipboard';
10
15
  export * from './Dialog';
16
+ export * from './ErrorFallback';
17
+ export * from './Focus';
11
18
  export * from './Icon';
19
+ export * from './Image';
12
20
  export * from './Input';
13
21
  export * from './Link';
14
22
  export * from './List';
15
23
  export * from './Main';
24
+ export * from './MediaPlayer';
16
25
  export * from './Menu';
17
26
  export * from './Message';
18
27
  export * from './Popover';
@@ -27,7 +36,3 @@ export * from './Tag';
27
36
  export * from './Toast';
28
37
  export * from './Toolbar';
29
38
  export * from './Tooltip';
30
-
31
- export * from './DensityProvider';
32
- export * from './ElevationProvider';
33
- export * from './ThemeProvider';
@@ -3,13 +3,16 @@
3
3
  //
4
4
 
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
- import React, { type ReactElement, type Ref, forwardRef } from 'react';
6
+ import React from 'react';
7
7
 
8
- import { type SlottableProps } from '@dxos/ui-types';
8
+ import { slottable } from '@dxos/ui-theme';
9
9
 
10
10
  import { withTheme } from '../testing';
11
11
 
12
- const ComponentInner = forwardRef<HTMLDivElement, ComponentProps>(({ children, ...props }, forwardedRef) => {
12
+ /**
13
+ * Generic component pattern using the slottable factory.
14
+ */
15
+ const Component = slottable<HTMLDivElement>(({ children, ...props }, forwardedRef) => {
13
16
  return (
14
17
  <div {...props} ref={forwardedRef}>
15
18
  {children}
@@ -17,20 +20,10 @@ const ComponentInner = forwardRef<HTMLDivElement, ComponentProps>(({ children, .
17
20
  );
18
21
  });
19
22
 
20
- ComponentInner.displayName = 'Component';
21
-
22
- /**
23
- * Generic component pattern.
24
- */
25
- type ComponentProps<P extends HTMLElement = any> = SlottableProps<P>;
26
-
27
- const Component = ComponentInner as <P extends HTMLElement>(
28
- props: SlottableProps<P> & { ref?: Ref<P> },
29
- ) => ReactElement;
30
-
31
23
  const meta = {
32
24
  title: 'ui/react-ui-core/exemplars/generics',
33
25
  component: Component,
26
+ render: (props) => <Component {...props} />,
34
27
  decorators: [withTheme()],
35
28
  parameters: {
36
29
  layout: 'centered',
@@ -41,4 +34,8 @@ export default meta;
41
34
 
42
35
  type Story = StoryObj<typeof meta>;
43
36
 
44
- export const Single: Story = {};
37
+ export const Default: Story = {
38
+ args: {
39
+ children: 'Hello',
40
+ },
41
+ };
@@ -2,85 +2,64 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { Primitive } from '@radix-ui/react-primitive';
5
6
  import { Slot } from '@radix-ui/react-slot';
6
7
  import { type Meta, type StoryObj } from '@storybook/react-vite';
7
- import React, { type PropsWithChildren, forwardRef } from 'react';
8
+ import React, { PropsWithChildren } from 'react';
8
9
 
9
- import { mx } from '@dxos/ui-theme';
10
- import { type SlottableClassName, type SlottableProps, type ThemedClassName } from '@dxos/ui-types';
10
+ import { composable, composableProps, mx, slottable } from '@dxos/ui-theme';
11
11
 
12
12
  import { withTheme } from '../testing';
13
+ import { ThemedClassName } from '../util';
13
14
 
14
15
  /**
15
- * Composition
16
- *
16
+ * Radix-style composition.
17
17
  * All Radix primitive parts that render a DOM element accept an asChild prop.
18
- * When asChild is set to true, Radix will not render a default DOM element, instead cloning the part's child and passing it the props and behavior required to make it functional.
18
+ * When asChild is set to true, Radix will not render a default DOM element,
19
+ * instead cloning the part's child and passing it the props and behavior required to make it functional.
19
20
  * https://www.radix-ui.com/primitives/docs/guides/composition
20
21
  */
21
22
 
22
- // Outer primitive (like Tooltip.Trigger or Focus.Group).
23
- const Outer = forwardRef<HTMLDivElement, SlottableProps<HTMLDivElement>>(
24
- ({ children, className, classNames, asChild, ...props }, forwardedRef) => {
25
- const Root = asChild ? Slot : 'div';
23
+ const Outer = slottable<HTMLDivElement, { priority?: number }>(
24
+ ({ children, asChild, priority, ...props }, forwardedRef) => {
25
+ const Comp = asChild ? Slot : Primitive.div;
26
26
  return (
27
- <Root {...props} className={mx(className, classNames)} data-outer='true' ref={forwardedRef}>
27
+ <Comp
28
+ {...composableProps<HTMLDivElement>(props, { classNames: 'p-2 border border-red-500 rounded' })}
29
+ ref={forwardedRef}
30
+ >
28
31
  {children}
29
- </Root>
32
+ </Comp>
30
33
  );
31
34
  },
32
35
  );
33
36
 
34
- // Middle primitive (like Dialog.Trigger or Mosaic.Cell).
35
- const Middle = forwardRef<HTMLDivElement, SlottableProps<HTMLDivElement>>(
36
- ({ children, className, classNames, asChild, ...props }, forwardedRef) => {
37
- const Root = asChild ? Slot : 'div';
38
- return (
39
- <Root {...props} className={mx(className, classNames)} data-middle='true' ref={forwardedRef}>
40
- {children}
41
- </Root>
42
- );
43
- },
44
- );
45
-
46
- // Leaf component (like Card.Root).
47
- const Leaf = forwardRef<HTMLButtonElement, SlottableClassName<PropsWithChildren>>(
48
- ({ className, classNames, children, ...props }, forwardedRef) => {
49
- return (
50
- <button {...props} className={mx('p-2 outline-none border rounded', className, classNames)} ref={forwardedRef}>
51
- {children}
52
- </button>
53
- );
54
- },
55
- );
56
-
57
- // Test 1: Single asChild.
58
- const TestSingle = ({ classNames, ...props }: ThemedClassName<{ role?: string }>) => (
59
- <Outer asChild {...props} className={mx('p-2', classNames)}>
60
- <Leaf>Single asChild</Leaf>
61
- </Outer>
62
- );
37
+ const Middle = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
38
+ const Comp = asChild ? Slot : Primitive.div;
39
+ return (
40
+ <Comp
41
+ {...composableProps<HTMLDivElement>(props, { classNames: 'p-2 border border-red-500 rounded' })}
42
+ ref={forwardedRef}
43
+ >
44
+ {children}
45
+ </Comp>
46
+ );
47
+ });
63
48
 
64
- // Test 2: Nested asChild.
65
- const TestNested = ({ classNames, ...props }: ThemedClassName<{ role?: string }>) => {
49
+ const Leaf = composable<HTMLButtonElement>(({ children, ...props }, forwardedRef) => {
66
50
  return (
67
- <Outer asChild {...props} className={mx('p-2', classNames)}>
68
- <Middle asChild>
69
- <Leaf>Nested asChild</Leaf>
70
- </Middle>
71
- </Outer>
51
+ <button
52
+ {...composableProps<HTMLButtonElement>(props, { classNames: 'p-2 border border-red-500 rounded' })}
53
+ ref={forwardedRef}
54
+ >
55
+ {children}
56
+ </button>
72
57
  );
73
- };
58
+ });
74
59
 
75
- // Test 3: Complex.
76
- const TestInner = ({ classNames, ...props }: ThemedClassName<{ role?: string }>) => (
77
- <Outer asChild {...props} className={mx('p-2', classNames)}>
78
- <Middle asChild>
79
- <Leaf>
80
- <div role='none'>Leaf</div>
81
- </Leaf>
82
- </Middle>
83
- </Outer>
60
+ /** This isn't a valid child for a `slottable` component. */
61
+ const Simple = ({ children, classNames }: ThemedClassName<PropsWithChildren>) => (
62
+ <div className={mx(classNames)}>{children}</div>
84
63
  );
85
64
 
86
65
  const meta = {
@@ -96,13 +75,41 @@ export default meta;
96
75
  type Story = StoryObj<typeof meta>;
97
76
 
98
77
  export const Single: Story = {
99
- render: () => <TestSingle role='listitem' classNames='border-red-500' />,
78
+ render: () => (
79
+ <Outer asChild role='article' classNames='border-green-500' priority={1}>
80
+ <Leaf>Single asChild (non-compliant — see console)</Leaf>
81
+ </Outer>
82
+ ),
100
83
  };
101
84
 
102
85
  export const Nested: Story = {
103
- render: () => <TestNested role='listitem' classNames='border-green-500' />,
86
+ render: () => (
87
+ <Outer asChild role='article' classNames='border-blue-500'>
88
+ <Middle asChild>
89
+ <Leaf>Nested asChild</Leaf>
90
+ </Middle>
91
+ </Outer>
92
+ ),
104
93
  };
105
94
 
106
95
  export const Inner: Story = {
107
- render: () => <TestInner role='listitem' classNames='border-blue-500' />,
96
+ render: () => (
97
+ <Outer asChild role='article' classNames='border-orange-500'>
98
+ <Middle asChild>
99
+ <Leaf>
100
+ <div>Leaf</div>
101
+ </Leaf>
102
+ </Middle>
103
+ </Outer>
104
+ ),
105
+ };
106
+
107
+ export const Error: Story = {
108
+ render: () => (
109
+ <Outer asChild role='none' classNames='p-2 border border-green-500 rounded'>
110
+ <Middle asChild>
111
+ <Simple>Simple</Simple>
112
+ </Middle>
113
+ </Outer>
114
+ ),
108
115
  };
@@ -21,14 +21,14 @@ import { mx } from '@dxos/ui-theme';
21
21
  // TODO(burdon): Prevent tab out of app.
22
22
 
23
23
  const border =
24
- 'rounded-sm outline-none border border-subduedSeparator focus:border-primary-500 focus-within:border-rose-500';
24
+ 'rounded-xs outline-hidden border border-subdued-separator focus:border-primary-500 focus-within:border-rose-500';
25
25
 
26
26
  const Board = forwardRef<HTMLDivElement, { columns: string[][] }>(({ columns }, ref) => {
27
27
  const arrowNavigationAttrs = useArrowNavigationGroup({ axis: 'horizontal', memorizeCurrent: true, tabbable: true });
28
28
 
29
29
  return (
30
- <div ref={ref} tabIndex={0} {...arrowNavigationAttrs} className='flex bs-full is-full overflow-hidden'>
31
- <div className={mx('flex bs-full overflow-x-auto p-4 gap-4')}>
30
+ <div ref={ref} tabIndex={0} {...arrowNavigationAttrs} className='flex h-full w-full overflow-hidden'>
31
+ <div className={mx('flex h-full overflow-x-auto p-4 gap-4')}>
32
32
  {columns.map((column) => (
33
33
  <Column key={column[0]} items={column} />
34
34
  ))}
@@ -43,7 +43,7 @@ const Column = forwardRef<HTMLDivElement, { items: string[] }>(({ items }, ref)
43
43
  const tabsterAttrs = useMergedTabsterAttributes_unstable(focusableGroupAttrs, arrowNavigationAttrs);
44
44
 
45
45
  return (
46
- <ScrollArea.Root tabIndex={0} orientation='vertical' classNames={mx('shrink-0 bs-full is-[25rem]', border)}>
46
+ <ScrollArea.Root orientation='vertical' classNames={mx('w-[25rem]', border)}>
47
47
  <ScrollArea.Viewport {...tabsterAttrs} classNames='p-4 gap-4' ref={ref}>
48
48
  {items.map((item) => (
49
49
  <Item key={item} value={item} />
@@ -61,7 +61,7 @@ const Item = forwardRef<HTMLDivElement, { value: string }>(({ value }, ref) => {
61
61
  ref={ref}
62
62
  tabIndex={0}
63
63
  {...focusableGroupAttrs}
64
- className={mx('flex shrink-0 is-full gap-4 p-4 items-center', border)}
64
+ className={mx('flex shrink-0 w-full gap-4 p-4 items-center', border)}
65
65
  >
66
66
  <Input.Root>
67
67
  <Input.Checkbox />
@@ -0,0 +1,136 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Meta } from '@storybook/react-vite';
6
+ import { useVirtualizer } from '@tanstack/react-virtual';
7
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
8
+
9
+ import { random } from '@dxos/random';
10
+ import { Panel, ScrollArea, Toolbar } from '@dxos/react-ui';
11
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
+
13
+ random.seed(999);
14
+
15
+ type TestItem = {
16
+ name: string;
17
+ };
18
+
19
+ const meta: Meta = {
20
+ title: 'ui/react-ui-core/exemplars/virtualizer',
21
+ decorators: [withLayout({ layout: 'column' }), withTheme()],
22
+ parameters: {
23
+ layout: 'fullscreen',
24
+ },
25
+ };
26
+
27
+ export default meta;
28
+
29
+ const NUM_ITEMS = 500;
30
+
31
+ /**
32
+ * https://tanstack.com/virtual/latest/docs/introduction
33
+ */
34
+ export const Default = {
35
+ render: () => {
36
+ const [index, setIndex] = useState(0);
37
+ const items = useMemo<TestItem[]>(
38
+ () =>
39
+ Array.from({ length: NUM_ITEMS }, () => ({
40
+ name: random.lorem.paragraph(),
41
+ })),
42
+ [],
43
+ );
44
+
45
+ const parentRef = useRef(null);
46
+ const [viewport, setViewport] = useState<HTMLElement | null>(null);
47
+ const virtualizer = useVirtualizer({
48
+ getScrollElement: () => viewport,
49
+ estimateSize: () => 40,
50
+ count: items.length,
51
+ gap: 8,
52
+ });
53
+
54
+ useEffect(() => {
55
+ virtualizer.scrollToIndex(index, { align: 'start' });
56
+ }, [virtualizer, index]);
57
+
58
+ const virtualItems = virtualizer.getVirtualItems();
59
+
60
+ return (
61
+ <Panel.Root>
62
+ <Panel.Toolbar asChild>
63
+ <ScrollToolbar items={items} index={index} setIndex={setIndex} />
64
+ </Panel.Toolbar>
65
+ <Panel.Content asChild>
66
+ <ScrollArea.Root orientation='vertical' centered>
67
+ <ScrollArea.Viewport classNames='p-2' ref={setViewport}>
68
+ <div
69
+ style={{
70
+ position: 'relative',
71
+ height: virtualizer.getTotalSize(),
72
+ width: '100%',
73
+ }}
74
+ ref={parentRef}
75
+ >
76
+ {virtualItems.map((virtualItem) => (
77
+ <div
78
+ key={virtualItem.key}
79
+ role='list'
80
+ className='grid grid-cols-[3rem_1fr] overflow-hidden border border-separator rounded-xs'
81
+ style={{
82
+ position: 'absolute',
83
+ top: 0,
84
+ left: 0,
85
+ width: '100%',
86
+ transform: `translateY(${virtualItem.start}px)`,
87
+ }}
88
+ data-index={virtualItem.index}
89
+ ref={virtualizer.measureElement}
90
+ >
91
+ <div className='p-1'>{virtualItem.index + 1}</div>
92
+ <div className='p-1'>{items[virtualItem.index].name}</div>
93
+ </div>
94
+ ))}
95
+ </div>
96
+ </ScrollArea.Viewport>
97
+ </ScrollArea.Root>
98
+ </Panel.Content>
99
+ </Panel.Root>
100
+ );
101
+ },
102
+ };
103
+
104
+ const ScrollToolbar = ({
105
+ items,
106
+ index,
107
+ setIndex,
108
+ }: {
109
+ items: any[];
110
+ index: number;
111
+ setIndex: (index: number) => void;
112
+ }) => {
113
+ return (
114
+ <Toolbar.Root classNames='grid grid-cols-3'>
115
+ <div />
116
+ <div className='flex justify-center gap-1'>
117
+ <Toolbar.IconButton icon='ph--arrow-line-left--regular' iconOnly label='start' onClick={() => setIndex(0)} />
118
+ <Toolbar.IconButton
119
+ icon='ph--arrows-out-line-horizontal--regular'
120
+ iconOnly
121
+ label='random'
122
+ onClick={() => setIndex(Math.floor(Math.random() * items.length))}
123
+ />
124
+ <Toolbar.IconButton
125
+ icon='ph--arrow-line-right--regular'
126
+ iconOnly
127
+ label='end'
128
+ onClick={() => setIndex(items.length - 1)}
129
+ />
130
+ </div>
131
+ <div className='p-1 text-right'>
132
+ {index + 1}/{items.length}
133
+ </div>
134
+ </Toolbar.Root>
135
+ );
136
+ };
@@ -6,6 +6,7 @@ export * from './useDensityContext';
6
6
  export * from './useElevationContext';
7
7
  export * from './useIconHref';
8
8
  export * from './useSafeArea';
9
+ export * from './useSafeCollisionPadding';
9
10
  export * from './useTranslationsContext';
10
11
  export * from './useThemeContext';
11
12
  export * from './useVisualViewport';
@@ -8,7 +8,7 @@ import { type Density } from '@dxos/ui-types';
8
8
 
9
9
  import { DensityContext } from '../components';
10
10
 
11
- export const useDensityContext = (propsDensity?: Density) => {
11
+ export const useDensityContext = (densityProp?: Density): Density | undefined => {
12
12
  const { density } = useContext(DensityContext);
13
- return propsDensity ?? density;
13
+ return densityProp ?? density;
14
14
  };
@@ -31,9 +31,6 @@ const DefaultStory = () => {
31
31
  </Select.Content>
32
32
  </Select.Portal>
33
33
  </Select.Root>
34
- {/* TODO(burdon): Highlight is cyan. */}
35
- {/* TODO(burdon): Show vertical divider by default. */}
36
- {/* TODO(burdon): Icon sizes should adapt to density. */}
37
34
  <Toolbar.ToggleGroup type='multiple'>
38
35
  <Toolbar.ToggleGroupItem value='a'>
39
36
  <Icon icon='ph--text-b--regular' />
@@ -45,7 +42,6 @@ const DefaultStory = () => {
45
42
  <Icon icon='ph--text-underline--regular' />
46
43
  </Toolbar.ToggleGroupItem>
47
44
  </Toolbar.ToggleGroup>
48
- {/* TODO(burdon): Highlight isn't shown. */}
49
45
  <Toolbar.ToggleGroup type='single' defaultValue='a'>
50
46
  <Toolbar.ToggleGroupItem value='a'>
51
47
  <Icon icon='ph--file-ts--regular' />
@@ -59,11 +55,9 @@ const DefaultStory = () => {
59
55
  <Icon icon='ph--bug--regular' />
60
56
  </Toggle>
61
57
  </Toolbar.Button>
62
- {/* TODO(burdon): Should not be 'is-full' by default. */}
63
58
  <Input.Root>
64
59
  <Input.TextInput placeholder='Enter text...' />
65
60
  </Input.Root>
66
- {/* TODO(burdon): Checkbox collapsed. */}
67
61
  <Input.Root>
68
62
  <Input.Checkbox checked={checked} onCheckedChange={(value) => setChecked(!!value)} />
69
63
  <Input.Label>Checkbox</Input.Label>