@dxos/react-ui 0.8.4-main.bc674ce → 0.8.4-main.bd9b33e6c8

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 (321) hide show
  1. package/dist/lib/browser/{chunk-CEKVHJ27.mjs → chunk-LUPEFGHJ.mjs} +119 -117
  2. package/dist/lib/browser/chunk-LUPEFGHJ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +3021 -2087
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +59 -36
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/{chunk-2NHEX4AD.mjs → chunk-EQOBFLZC.mjs} +119 -117
  9. package/dist/lib/node-esm/chunk-EQOBFLZC.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +3021 -2087
  11. package/dist/lib/node-esm/index.mjs.map +4 -4
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +59 -36
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  16. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  18. package/dist/types/src/components/Button/Button.d.ts +2 -2
  19. package/dist/types/src/components/Button/Button.d.ts.map +1 -1
  20. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
  21. package/dist/types/src/components/Button/Toggle.d.ts +2 -2
  22. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -1
  23. package/dist/types/src/components/Button/ToggleGroup.d.ts +6 -6
  24. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
  25. package/dist/types/src/components/Card/Card.d.ts +145 -0
  26. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  27. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  28. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  29. package/dist/types/src/components/Card/index.d.ts +2 -0
  30. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  31. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  32. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  33. package/dist/types/src/components/Dialog/AlertDialog.d.ts +41 -19
  34. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
  35. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/Dialog/Dialog.d.ts +48 -22
  37. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  38. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +6 -8
  39. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  41. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  42. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  43. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  44. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +8 -0
  45. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  46. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  47. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  48. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  49. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  50. package/dist/types/src/components/Focus/Focus.d.ts +44 -0
  51. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  52. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  53. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  54. package/dist/types/src/components/Focus/index.d.ts +2 -0
  55. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  56. package/dist/types/src/components/Icon/Icon.d.ts +3 -0
  57. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  58. package/dist/types/src/components/Icon/Icon.stories.d.ts +11 -3
  59. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
  60. package/dist/types/src/components/Image/Image.d.ts +14 -0
  61. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  62. package/dist/types/src/components/Image/Image.stories.d.ts +33 -0
  63. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  64. package/dist/types/src/components/Image/index.d.ts +2 -0
  65. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  66. package/dist/types/src/components/Input/Input.d.ts +4 -7
  67. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  68. package/dist/types/src/components/Input/Input.stories.d.ts +7 -7
  69. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  70. package/dist/types/src/components/List/List.d.ts +9 -3
  71. package/dist/types/src/components/List/List.d.ts.map +1 -1
  72. package/dist/types/src/components/List/List.stories.d.ts +8 -2
  73. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  74. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
  75. package/dist/types/src/components/Main/Main.d.ts +6 -32
  76. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  77. package/dist/types/src/components/Main/Main.stories.d.ts +1 -5
  78. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  79. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
  80. package/dist/types/src/components/Menu/DropdownMenu.d.ts +51 -50
  81. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
  82. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +14 -1
  83. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -1
  84. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  85. package/dist/types/src/components/Message/Message.stories.d.ts +4 -5
  86. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  87. package/dist/types/src/components/Popover/Popover.d.ts +32 -23
  88. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  89. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +31 -25
  90. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  91. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +62 -9
  92. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +23 -7
  94. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
  95. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +6 -2
  96. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
  97. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  98. package/dist/types/src/components/Select/Select.stories.d.ts +2 -2
  99. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  100. package/dist/types/src/components/Separator/Separator.d.ts +3 -3
  101. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  102. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  103. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  104. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  105. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  106. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  107. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  108. package/dist/types/src/components/Splitter/Splitter.d.ts +37 -0
  109. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  110. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  111. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  112. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  113. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  114. package/dist/types/src/components/Status/Status.d.ts +3 -4
  115. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  116. package/dist/types/src/components/Status/Status.stories.d.ts +4 -2
  117. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  118. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  119. package/dist/types/src/components/Tag/Tag.stories.d.ts +0 -5
  120. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +2 -1
  122. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  123. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  124. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  125. package/dist/types/src/components/Toast/Toast.d.ts +15 -15
  126. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  127. package/dist/types/src/components/Toolbar/Toolbar.d.ts +37 -11
  128. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  129. package/dist/types/src/components/Tooltip/Tooltip.d.ts +9 -9
  130. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  131. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -2
  132. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/index.d.ts +9 -4
  134. package/dist/types/src/components/index.d.ts.map +1 -1
  135. package/dist/types/src/exemplars/generics.stories.d.ts +23 -0
  136. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  137. package/dist/types/src/exemplars/slot.stories.d.ts +15 -0
  138. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  139. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  140. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  141. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  142. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  143. package/dist/types/src/hooks/index.d.ts +1 -0
  144. package/dist/types/src/hooks/index.d.ts.map +1 -1
  145. package/dist/types/src/hooks/useDensityContext.d.ts +1 -1
  146. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  147. package/dist/types/src/index.d.ts +1 -0
  148. package/dist/types/src/index.d.ts.map +1 -1
  149. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  150. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  151. package/dist/types/src/primitives/Column/Column.d.ts +51 -0
  152. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  153. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  154. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  155. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  156. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  157. package/dist/types/src/primitives/Container/Container.d.ts +11 -0
  158. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  159. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  160. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  161. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  162. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  163. package/dist/types/src/primitives/Flex/Flex.d.ts +15 -0
  164. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  165. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  166. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  167. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  168. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  169. package/dist/types/src/primitives/Grid/Grid.d.ts +14 -0
  170. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  171. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  172. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  173. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  174. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  175. package/dist/types/src/primitives/Panel/Panel.d.ts +46 -0
  176. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  177. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  178. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  179. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  180. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  181. package/dist/types/src/primitives/index.d.ts +6 -0
  182. package/dist/types/src/primitives/index.d.ts.map +1 -0
  183. package/dist/types/src/testing/Loading.d.ts +9 -0
  184. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  185. package/dist/types/src/testing/decorators/withLayout.d.ts +1 -1
  186. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  187. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
  188. package/dist/types/src/testing/decorators/withTheme.d.ts +3 -2
  189. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  190. package/dist/types/src/testing/index.d.ts +1 -0
  191. package/dist/types/src/testing/index.d.ts.map +1 -1
  192. package/dist/types/src/translations.d.ts +11 -0
  193. package/dist/types/src/translations.d.ts.map +1 -0
  194. package/dist/types/src/util/usePx.d.ts.map +1 -1
  195. package/dist/types/tsconfig.tsbuildinfo +1 -1
  196. package/package.json +25 -21
  197. package/src/components/Avatars/Avatar.stories.tsx +7 -8
  198. package/src/components/Avatars/Avatar.tsx +5 -12
  199. package/src/components/Avatars/AvatarGroup.stories.tsx +2 -2
  200. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +3 -3
  201. package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
  202. package/src/components/Button/Button.stories.tsx +3 -3
  203. package/src/components/Button/Button.tsx +11 -25
  204. package/src/components/Button/IconButton.stories.tsx +4 -4
  205. package/src/components/Button/IconButton.tsx +2 -3
  206. package/src/components/Button/Toggle.stories.tsx +2 -2
  207. package/src/components/Button/Toggle.tsx +4 -4
  208. package/src/components/Button/ToggleGroup.stories.tsx +2 -2
  209. package/src/components/Button/ToggleGroup.tsx +12 -16
  210. package/src/components/Card/Card.stories.tsx +151 -0
  211. package/src/components/Card/Card.tsx +394 -0
  212. package/src/components/Card/index.ts +5 -0
  213. package/src/components/Clipboard/CopyButton.tsx +3 -3
  214. package/src/components/Dialog/AlertDialog.stories.tsx +16 -16
  215. package/src/components/Dialog/AlertDialog.tsx +121 -82
  216. package/src/components/Dialog/Dialog.stories.tsx +98 -17
  217. package/src/components/Dialog/Dialog.tsx +108 -87
  218. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +50 -0
  219. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  220. package/src/components/ErrorFallback/ErrorStack.tsx +80 -0
  221. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  222. package/src/components/ErrorFallback/index.ts +9 -0
  223. package/src/components/Focus/AUDIT.md +43 -0
  224. package/src/components/Focus/Focus.stories.tsx +230 -0
  225. package/src/components/Focus/Focus.tsx +201 -0
  226. package/src/components/Focus/index.ts +5 -0
  227. package/src/components/Icon/Icon.stories.tsx +45 -14
  228. package/src/components/Icon/Icon.tsx +6 -2
  229. package/src/components/Image/Image.stories.tsx +86 -0
  230. package/src/components/Image/Image.tsx +223 -0
  231. package/src/components/Image/index.ts +5 -0
  232. package/src/components/Input/Input.stories.tsx +20 -39
  233. package/src/components/Input/Input.tsx +24 -69
  234. package/src/components/Link/Link.stories.tsx +2 -2
  235. package/src/components/Link/Link.tsx +2 -2
  236. package/src/components/List/List.stories.tsx +15 -22
  237. package/src/components/List/List.tsx +15 -18
  238. package/src/components/List/ListDropIndicator.tsx +7 -7
  239. package/src/components/List/Tree.stories.tsx +5 -5
  240. package/src/components/List/TreeDropIndicator.tsx +6 -6
  241. package/src/components/List/Treegrid.stories.tsx +3 -3
  242. package/src/components/List/Treegrid.tsx +10 -15
  243. package/src/components/Main/Main.stories.tsx +6 -95
  244. package/src/components/Main/Main.tsx +61 -211
  245. package/src/components/Menu/ContextMenu.stories.tsx +2 -2
  246. package/src/components/Menu/ContextMenu.tsx +9 -33
  247. package/src/components/Menu/DropdownMenu.stories.tsx +2 -2
  248. package/src/components/Menu/DropdownMenu.tsx +58 -52
  249. package/src/components/Message/Message.stories.tsx +27 -12
  250. package/src/components/Message/Message.tsx +14 -30
  251. package/src/components/Popover/Popover.stories.tsx +4 -4
  252. package/src/components/Popover/Popover.tsx +62 -59
  253. package/src/components/ScrollArea/ScrollArea.stories.tsx +213 -73
  254. package/src/components/ScrollArea/ScrollArea.tsx +85 -113
  255. package/src/components/ScrollArea/index.ts +1 -1
  256. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +43 -23
  257. package/src/components/ScrollContainer/ScrollContainer.tsx +174 -87
  258. package/src/components/Select/Select.stories.tsx +4 -4
  259. package/src/components/Select/Select.tsx +11 -27
  260. package/src/components/Separator/Separator.tsx +5 -8
  261. package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
  262. package/src/components/Skeleton/Skeleton.tsx +26 -0
  263. package/src/components/Skeleton/index.ts +5 -0
  264. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  265. package/src/components/Splitter/Splitter.tsx +140 -0
  266. package/src/components/Splitter/index.ts +5 -0
  267. package/src/components/Status/Status.stories.tsx +21 -17
  268. package/src/components/Status/Status.tsx +10 -7
  269. package/src/components/Tag/Tag.stories.tsx +4 -9
  270. package/src/components/Tag/Tag.tsx +2 -7
  271. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +32 -0
  272. package/src/components/ThemeProvider/ThemeProvider.tsx +9 -6
  273. package/src/components/Toast/Toast.stories.tsx +2 -2
  274. package/src/components/Toast/Toast.tsx +22 -41
  275. package/src/components/Toolbar/Toolbar.stories.tsx +2 -2
  276. package/src/components/Toolbar/Toolbar.tsx +171 -25
  277. package/src/components/Tooltip/Tooltip.stories.tsx +16 -14
  278. package/src/components/Tooltip/Tooltip.tsx +18 -18
  279. package/src/components/index.ts +10 -5
  280. package/src/exemplars/generics.stories.tsx +41 -0
  281. package/src/exemplars/slot.stories.tsx +117 -0
  282. package/src/exemplars/tabster.stories.tsx +127 -0
  283. package/src/exemplars/virtualizer.stories.tsx +137 -0
  284. package/src/hooks/index.ts +1 -0
  285. package/src/hooks/useDensityContext.ts +2 -2
  286. package/src/index.ts +1 -0
  287. package/src/playground/Controls.stories.tsx +3 -10
  288. package/src/playground/Custom.stories.tsx +11 -21
  289. package/src/playground/Typography.stories.tsx +3 -3
  290. package/src/primitives/Column/AUDIT.md +354 -0
  291. package/src/primitives/Column/Column.stories.tsx +183 -0
  292. package/src/primitives/Column/Column.tsx +169 -0
  293. package/src/primitives/Column/index.ts +5 -0
  294. package/src/primitives/Container/Container.stories.tsx +30 -0
  295. package/src/primitives/Container/Container.tsx +19 -0
  296. package/src/primitives/Container/index.ts +5 -0
  297. package/src/primitives/Flex/Flex.stories.tsx +58 -0
  298. package/src/primitives/Flex/Flex.tsx +24 -0
  299. package/src/primitives/Flex/index.ts +5 -0
  300. package/src/primitives/Grid/Grid.stories.tsx +57 -0
  301. package/src/primitives/Grid/Grid.tsx +30 -0
  302. package/src/primitives/Grid/index.ts +5 -0
  303. package/src/primitives/Panel/Panel.stories.tsx +67 -0
  304. package/src/primitives/Panel/Panel.tsx +114 -0
  305. package/src/primitives/Panel/index.ts +5 -0
  306. package/src/primitives/index.ts +9 -0
  307. package/src/testing/Loading.tsx +26 -0
  308. package/src/testing/decorators/withLayout.tsx +21 -7
  309. package/src/testing/decorators/withLayoutVariants.tsx +18 -21
  310. package/src/testing/decorators/withTheme.tsx +24 -19
  311. package/src/testing/index.ts +2 -0
  312. package/src/translations.ts +19 -0
  313. package/src/util/usePx.ts +1 -0
  314. package/dist/lib/browser/chunk-CEKVHJ27.mjs.map +0 -7
  315. package/dist/lib/node-esm/chunk-2NHEX4AD.mjs.map +0 -7
  316. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  317. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  318. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  319. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  320. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  321. package/src/components/AnchoredOverflow/index.ts +0 -5
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { createContext } from '@radix-ui/react-context';
6
6
  import React, {
7
- type HTMLAttributes,
8
7
  type PropsWithChildren,
8
+ type RefObject,
9
9
  forwardRef,
10
10
  useCallback,
11
11
  useEffect,
@@ -15,14 +15,15 @@ import React, {
15
15
  useState,
16
16
  } from 'react';
17
17
 
18
- // TODO(burdon): Move these deps to @dxos/dom-util.
19
18
  import { addEventListener, combine } from '@dxos/async';
20
19
  import { invariant } from '@dxos/invariant';
21
- import { useForwardedRef } from '@dxos/react-hooks';
22
- import { mx } from '@dxos/ui-theme';
20
+ import { useMergeRefs } from '@dxos/react-hooks';
21
+ import { composableProps, mx } from '@dxos/ui-theme';
22
+ import { SlottableProps } from '@dxos/ui-types';
23
23
 
24
24
  import { type ThemedClassName } from '../../util';
25
25
  import { IconButton } from '../Button';
26
+ import { ScrollArea } from '../ScrollArea';
26
27
 
27
28
  const isBottom = (el: HTMLElement | null) => {
28
29
  return !!(el && el.scrollHeight - el.scrollTop === el.clientHeight);
@@ -35,9 +36,15 @@ export interface ScrollController {
35
36
  }
36
37
 
37
38
  type ScrollContainerContextValue = {
38
- scrollToBottom: (behavior?: ScrollBehavior) => void;
39
39
  controller?: ScrollController;
40
40
  pinned?: boolean;
41
+ overflow?: boolean;
42
+ /** Called by Viewport to register/unregister the scroll element. */
43
+ setViewport: (el: HTMLDivElement | null) => void;
44
+ /** Called by Viewport on wheel events to update pinned state. */
45
+ setPinned: (value: boolean) => void;
46
+ /** Called by Viewport on scroll events to update overflow state. */
47
+ setOverflow: (value: boolean) => void;
41
48
  };
42
49
 
43
50
  const [ScrollContainerProvider, useScrollContainerContext] =
@@ -50,98 +57,86 @@ const [ScrollContainerProvider, useScrollContainerContext] =
50
57
  type RootProps = ThemedClassName<
51
58
  PropsWithChildren<{
52
59
  pin?: boolean;
53
- fade?: boolean;
54
60
  behavior?: ScrollBehavior;
55
61
  }>
56
62
  >;
57
63
 
58
64
  /**
59
- * Scroll container that automatically scrolls to the bottom when new content is added.
65
+ * Headless scroll container that provides context for scroll state.
66
+ * Render ScrollContainer.Viewport as a child to provide the scrollable area.
60
67
  */
61
68
  const Root = forwardRef<ScrollController, RootProps>(
62
- ({ children, classNames, pin, fade, behavior: behaviorProp = 'smooth' }, forwardedRef) => {
63
- const scrollerRef = useRef<HTMLDivElement>(null);
69
+ ({ children, pin, behavior: behaviorProp = 'smooth' }, forwardedRef) => {
70
+ const scrollerRef = useRef<HTMLDivElement | null>(null);
64
71
  const autoScrollRef = useRef(false);
65
- const [overflow, setOverflow] = useState(false);
66
72
  const [pinned, setPinned] = useState(pin);
73
+ const [overflow, setOverflow] = useState(false);
67
74
 
68
75
  const timeoutRef = useRef<NodeJS.Timeout>(undefined);
69
- const scrollToBottom = useCallback((behavior: ScrollBehavior = behaviorProp) => {
70
- if (scrollerRef.current) {
71
- // Temporarily hide scrollbar to prevent flicker.
72
- autoScrollRef.current = true;
73
- scrollerRef.current.classList.add('scrollbar-none');
74
- scrollerRef.current.scrollTo({
75
- top: scrollerRef.current.scrollHeight,
76
- behavior,
77
- });
78
-
79
- clearTimeout(timeoutRef.current);
80
- if (behavior !== 'instant') {
81
- timeoutRef.current = setTimeout(() => {
82
- scrollerRef.current?.classList.remove('scrollbar-none');
83
- autoScrollRef.current = false;
84
- }, 500);
76
+ const scrollToBottom = useCallback(
77
+ (behavior: ScrollBehavior = behaviorProp) => {
78
+ if (scrollerRef.current) {
79
+ if (behavior !== 'instant') {
80
+ // Temporarily hide scrollbar to prevent flickering during smooth scroll.
81
+ // For instant scrolling we skip this — there's no animation to hide,
82
+ // and adding the class changes element size which re-fires the ResizeObserver.
83
+ autoScrollRef.current = true;
84
+ scrollerRef.current.classList.add('scrollbar-none');
85
+ clearTimeout(timeoutRef.current);
86
+ timeoutRef.current = setTimeout(() => {
87
+ scrollerRef.current?.classList.remove('scrollbar-none');
88
+ autoScrollRef.current = false;
89
+ }, 500);
90
+ }
91
+
92
+ scrollerRef.current.scrollTo({
93
+ top: scrollerRef.current.scrollHeight,
94
+ behavior,
95
+ });
96
+
97
+ setPinned(true);
85
98
  }
86
- setPinned(true);
87
- }
88
- }, []);
99
+ },
100
+ [behaviorProp],
101
+ );
89
102
 
90
- const controller = useMemo(
103
+ const controller = useMemo<ScrollController>(
91
104
  () => ({
92
- viewport: scrollerRef.current,
105
+ get viewport() {
106
+ return scrollerRef.current;
107
+ },
93
108
  scrollToTop: () => {
94
109
  invariant(scrollerRef.current);
95
110
  scrollerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
96
111
  setPinned(false);
97
112
  },
98
- scrollToBottom: () => {
99
- scrollToBottom('smooth');
113
+ scrollToBottom: (behavior = 'smooth' as ScrollBehavior) => {
114
+ scrollToBottom(behavior);
100
115
  },
101
116
  }),
102
- [scrollToBottom, scrollerRef.current],
117
+ [scrollToBottom],
103
118
  );
104
119
 
105
120
  // Scroll controller imperative ref.
106
121
  useImperativeHandle(forwardedRef, () => controller, [controller]);
107
122
 
108
- // Listen for scroll events.
109
- useEffect(() => {
110
- if (!scrollerRef.current) {
111
- return;
112
- }
113
-
114
- return combine(
115
- // Check if user scrolls.
116
- addEventListener(scrollerRef.current, 'wheel', () => {
117
- setPinned(isBottom(scrollerRef.current));
118
- }),
119
- // Check if scrolls.
120
- addEventListener(scrollerRef.current, 'scroll', () => {
121
- setOverflow((scrollerRef.current?.scrollTop ?? 0) > 0);
122
- }),
123
- );
123
+ // Called by Viewport when the scroll element mounts/unmounts.
124
+ const setViewport = useCallback((el: HTMLDivElement | null) => {
125
+ scrollerRef.current = el;
124
126
  }, []);
125
127
 
126
128
  return (
127
- <ScrollContainerProvider pinned={pinned} controller={controller} scrollToBottom={scrollToBottom}>
128
- <div className='relative grid flex-1 min-bs-0 overflow-hidden'>
129
- {fade && (
130
- <div
131
- role='none'
132
- data-visible={overflow}
133
- className={mx(
134
- // NOTE: Gradients may not be visible with dark reader extensions.
135
- 'z-10 absolute block-start-0 inset-inline-0 bs-24 is-full',
136
- 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
137
- 'bg-gradient-to-b from-[--surface-bg] to-transparent pointer-events-none',
138
- )}
139
- />
140
- )}
141
- <div className={mx('flex flex-col min-bs-0 overflow-y-auto scrollbar-thin', classNames)} ref={scrollerRef}>
142
- {children}
143
- </div>
144
- </div>
129
+ <ScrollContainerProvider
130
+ pinned={pinned}
131
+ overflow={overflow}
132
+ controller={controller}
133
+ setViewport={setViewport}
134
+ setPinned={setPinned}
135
+ setOverflow={setOverflow}
136
+ >
137
+ <ScrollArea.Root thin centered padding className='relative'>
138
+ {children}
139
+ </ScrollArea.Root>
145
140
  </ScrollContainerProvider>
146
141
  );
147
142
  },
@@ -153,43 +148,133 @@ Root.displayName = 'ScrollContainer.Root';
153
148
  // Viewport
154
149
  //
155
150
 
156
- type ViewportProps = ThemedClassName<PropsWithChildren<Omit<HTMLAttributes<HTMLDivElement>, 'className'>>>;
151
+ const VIEWPORT_NAME = 'ScrollContainer.Viewport';
152
+
153
+ type ViewportProps = SlottableProps;
157
154
 
158
- const Viewport = forwardRef<HTMLDivElement, ViewportProps>(({ classNames, children, ...props }, forwardedRef) => {
159
- const contentRef = useForwardedRef(forwardedRef);
160
- const { pinned, scrollToBottom } = useScrollContainerContext(Viewport.displayName!);
155
+ const Viewport = forwardRef<HTMLDivElement, ViewportProps>(({ children, ...props }, forwardedRef) => {
156
+ const scrollerRef = useRef<HTMLDivElement>(null);
157
+ const mergedRef = useMergeRefs([forwardedRef, scrollerRef]);
158
+ const { setViewport, setPinned, setOverflow } = useScrollContainerContext(VIEWPORT_NAME);
161
159
 
160
+ // Register the scroll element with Root and set up wheel/scroll listeners.
162
161
  useEffect(() => {
163
- if (!pinned || !contentRef.current) {
162
+ const el = scrollerRef.current;
163
+ if (!el) {
164
164
  return;
165
165
  }
166
166
 
167
- // Scroll instantly otherwise it might move while we're scrolling.
168
- scrollToBottom();
167
+ setViewport(el);
169
168
 
170
- // Setup resize observer to detect content changes.
171
- const resizeObserver = new ResizeObserver(() => scrollToBottom());
172
- resizeObserver.observe(contentRef.current);
173
- return () => resizeObserver.disconnect();
174
- }, [pinned, scrollToBottom]);
169
+ return combine(
170
+ addEventListener(el, 'wheel', () => setPinned(isBottom(el))),
171
+ addEventListener(el, 'scroll', () => setOverflow((el.scrollTop ?? 0) > 0)),
172
+ () => setViewport(null),
173
+ );
174
+ }, [setViewport, setPinned, setOverflow]);
175
175
 
176
176
  return (
177
- <div className={mx('is-full', classNames)} {...props} ref={contentRef}>
178
- {children}
179
- </div>
177
+ <>
178
+ <ScrollArea.Viewport {...composableProps(props)} ref={mergedRef}>
179
+ {children}
180
+ </ScrollArea.Viewport>
181
+ <PinEffect scrollerRef={scrollerRef} />
182
+ </>
180
183
  );
181
184
  });
182
185
 
183
- Viewport.displayName = 'ScrollContainer.Viewport';
186
+ Viewport.displayName = VIEWPORT_NAME;
187
+
188
+ /**
189
+ * Isolated component that consumes pinned/controller from context.
190
+ * Kept separate so that Viewport does not re-render when pinned changes.
191
+ */
192
+ const PIN_EFFECT_NAME = 'ScrollContainer.PinEffect';
193
+
194
+ const PinEffect = ({ scrollerRef }: { scrollerRef: RefObject<HTMLDivElement | null> }) => {
195
+ const { pinned, controller } = useScrollContainerContext(PIN_EFFECT_NAME);
196
+
197
+ // Pin scroll to bottom when content changes.
198
+ useEffect(() => {
199
+ const viewport = scrollerRef.current;
200
+ if (!pinned || !viewport) {
201
+ return;
202
+ }
203
+
204
+ // Scroll instantly so we don't visually jump while content is being added.
205
+ controller?.scrollToBottom('instant');
206
+
207
+ // Setup resize observer on content children to detect size changes (e.g. streaming).
208
+ // We observe children rather than the viewport itself, because the viewport's size
209
+ // stays fixed — only its content grows.
210
+ // Use instant scroll in the callback — smooth scrolling adds/removes the
211
+ // scrollbar-none class, which changes the element size and re-fires the
212
+ // observer, creating an infinite loop.
213
+ const resizeObserver = new ResizeObserver(() => controller?.scrollToBottom('smooth'));
214
+ Array.from(viewport.children).forEach((child) => {
215
+ resizeObserver.observe(child);
216
+ });
217
+
218
+ // Watch for added/removed children.
219
+ const mutationObserver = new MutationObserver((mutations) => {
220
+ mutations.forEach((mutation) => {
221
+ mutation.addedNodes.forEach((node) => {
222
+ if (node instanceof Element) {
223
+ resizeObserver.observe(node);
224
+ }
225
+ });
226
+ });
227
+
228
+ controller?.scrollToBottom('smooth');
229
+ });
230
+ mutationObserver.observe(viewport, { childList: true });
231
+
232
+ return () => {
233
+ resizeObserver.disconnect();
234
+ mutationObserver.disconnect();
235
+ };
236
+ }, [pinned, controller, scrollerRef]);
237
+
238
+ return null;
239
+ };
240
+
241
+ //
242
+ // Fade
243
+ //
244
+
245
+ const FADE_NAME = 'ScrollContainer.Fade';
246
+
247
+ type FadeProps = {};
248
+
249
+ const Fade = () => {
250
+ const { overflow } = useScrollContainerContext(FADE_NAME);
251
+
252
+ return (
253
+ <div
254
+ role='none'
255
+ data-visible={overflow}
256
+ className={mx(
257
+ // NOTE: Gradients may not be visible with dark reader extensions.
258
+ 'z-10 absolute top-0 inset-x-0 h-24 w-full',
259
+ 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
260
+ 'bg-gradient-to-b from-(--surface-bg) to-transparent pointer-events-none',
261
+ )}
262
+ />
263
+ );
264
+ };
265
+
266
+ Fade.displayName = FADE_NAME;
184
267
 
185
268
  //
186
269
  // ScrollDownButton
187
270
  //
188
271
 
272
+ const SCROLL_DOWN_BUTTON_NAME = 'ScrollContainer.ScrollDownButton';
273
+
189
274
  type ScrollDownButtonProps = ThemedClassName;
190
275
 
191
276
  const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
192
- const { pinned, scrollToBottom } = useScrollContainerContext(ScrollDownButton.displayName!);
277
+ const { pinned, controller } = useScrollContainerContext(SCROLL_DOWN_BUTTON_NAME);
193
278
 
194
279
  return (
195
280
  <div
@@ -206,13 +291,13 @@ const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
206
291
  iconOnly
207
292
  size={4}
208
293
  label='Scroll down'
209
- onClick={() => scrollToBottom()}
294
+ onClick={() => controller?.scrollToBottom()}
210
295
  />
211
296
  </div>
212
297
  );
213
298
  };
214
299
 
215
- ScrollDownButton.displayName = 'ScrollContainer.ScrollDownButton';
300
+ ScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
216
301
 
217
302
  //
218
303
  // ScrollContainer
@@ -223,11 +308,13 @@ export { useScrollContainerContext };
223
308
  export const ScrollContainer = {
224
309
  Root,
225
310
  Viewport,
311
+ Fade,
226
312
  ScrollDownButton,
227
313
  };
228
314
 
229
315
  export type {
230
316
  RootProps as ScrollContainerRootProps,
231
317
  ViewportProps as ScrollContainerViewportProps,
318
+ FadeProps as ScrollContainerFadeProps,
232
319
  ScrollDownButtonProps as ScrollContainerScrollDownButtonProps,
233
320
  };
@@ -16,9 +16,9 @@ faker.seed(1234);
16
16
 
17
17
  type ItemProps = { id: string; text: string };
18
18
 
19
- type StoryProps = { items: ItemProps[] };
19
+ type DefaultStoryProps = { items: ItemProps[] };
20
20
 
21
- const DefaultStory = ({ items = [] }: StoryProps) => {
21
+ const DefaultStory = ({ items = [] }: DefaultStoryProps) => {
22
22
  const [value, setValue] = useState<string>();
23
23
  return (
24
24
  <Select.Root value={value} onValueChange={setValue}>
@@ -42,9 +42,9 @@ const DefaultStory = ({ items = [] }: StoryProps) => {
42
42
  };
43
43
 
44
44
  const meta = {
45
- title: 'ui/react-ui-core/Select',
45
+ title: 'ui/react-ui-core/components/Select',
46
46
  render: DefaultStory,
47
- decorators: [withTheme, withLayoutVariants()],
47
+ decorators: [withTheme(), withLayoutVariants()],
48
48
  } satisfies Meta<typeof DefaultStory>;
49
49
 
50
50
  export default meta;
@@ -39,7 +39,7 @@ const SelectTriggerButton = forwardRef<HTMLButtonElement, SelectTriggerButtonPro
39
39
  <SelectPrimitive.Trigger asChild ref={forwardedRef}>
40
40
  <Button {...props}>
41
41
  <SelectPrimitive.Value placeholder={placeholder}>{children}</SelectPrimitive.Value>
42
- <span className='is-1 flex-1' />
42
+ <span className='w-1 flex-1' />
43
43
  <SelectPrimitive.Icon asChild>
44
44
  <Icon size={3} icon='ph--caret-down--bold' />
45
45
  </SelectPrimitive.Icon>
@@ -61,7 +61,7 @@ const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
61
61
  {...props}
62
62
  data-arrow-keys='up down'
63
63
  collisionPadding={safeCollisionPadding}
64
- className={tx('select.content', 'select__content', { elevation }, classNames)}
64
+ className={tx('select.content', { elevation }, classNames)}
65
65
  position='popper'
66
66
  ref={forwardedRef}
67
67
  >
@@ -79,7 +79,7 @@ const SelectScrollUpButton = forwardRef<HTMLDivElement, SelectScrollUpButtonProp
79
79
  return (
80
80
  <SelectPrimitive.SelectScrollUpButton
81
81
  {...props}
82
- className={tx('select.scrollButton', 'select__scroll-button--up', {}, classNames)}
82
+ className={tx('select.scrollButton', {}, classNames)}
83
83
  ref={forwardedRef}
84
84
  >
85
85
  {children ?? <Icon size={3} icon='ph--caret-up--bold' />}
@@ -96,7 +96,7 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
96
96
  return (
97
97
  <SelectPrimitive.SelectScrollDownButton
98
98
  {...props}
99
- className={tx('select.scrollButton', 'select__scroll-button--down', {}, classNames)}
99
+ className={tx('select.scrollButton', {}, classNames)}
100
100
  ref={forwardedRef}
101
101
  >
102
102
  {children ?? <Icon size={3} icon='ph--caret-down--bold' />}
@@ -111,11 +111,7 @@ const SelectViewport = forwardRef<HTMLDivElement, SelectViewportProps>(
111
111
  ({ classNames, children, ...props }, forwardedRef) => {
112
112
  const { tx } = useThemeContext();
113
113
  return (
114
- <SelectPrimitive.SelectViewport
115
- {...props}
116
- className={tx('select.viewport', 'select__viewport', {}, classNames)}
117
- ref={forwardedRef}
118
- >
114
+ <SelectPrimitive.SelectViewport {...props} className={tx('select.viewport', {}, classNames)} ref={forwardedRef}>
119
115
  {children}
120
116
  </SelectPrimitive.SelectViewport>
121
117
  );
@@ -126,7 +122,7 @@ type SelectItemProps = ThemedClassName<SelectPrimitive.SelectItemProps>;
126
122
 
127
123
  const SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(({ classNames, ...props }, forwardedRef) => {
128
124
  const { tx } = useThemeContext();
129
- return <SelectPrimitive.Item {...props} className={tx('select.item', 'option', {}, classNames)} ref={forwardedRef} />;
125
+ return <SelectPrimitive.Item {...props} className={tx('select.item', {}, classNames)} ref={forwardedRef} />;
130
126
  });
131
127
 
132
128
  type SelectItemTextProps = SelectPrimitive.SelectItemTextProps;
@@ -141,7 +137,7 @@ const SelectItemIndicator = forwardRef<HTMLDivElement, SelectItemIndicatorProps>
141
137
  return (
142
138
  <SelectPrimitive.ItemIndicator
143
139
  {...props}
144
- className={tx('select.itemIndicator', 'option__indicator', {}, classNames)}
140
+ className={tx('select.itemIndicator', {}, classNames)}
145
141
  ref={forwardedRef}
146
142
  >
147
143
  {children}
@@ -156,9 +152,9 @@ type SelectOptionProps = SelectItemProps;
156
152
  const SelectOption = forwardRef<HTMLDivElement, SelectItemProps>(({ children, classNames, ...props }, forwardedRef) => {
157
153
  const { tx } = useThemeContext();
158
154
  return (
159
- <SelectPrimitive.Item {...props} className={tx('select.item', 'option', {}, classNames)} ref={forwardedRef}>
155
+ <SelectPrimitive.Item {...props} className={tx('select.item', {}, classNames)} ref={forwardedRef}>
160
156
  <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
161
- <span className='grow is-1' />
157
+ <span className='grow w-1' />
162
158
  {/* <SelectPrimitive.ItemIndicator className={tx('select.itemIndicator', 'option__indicator', {})}> */}
163
159
  <Icon icon='ph--check--regular' />
164
160
  {/* </SelectPrimitive.ItemIndicator> */}
@@ -178,26 +174,14 @@ type SelectSeparatorProps = ThemedClassName<SelectPrimitive.SelectSeparatorProps
178
174
 
179
175
  const SelectSeparator = forwardRef<HTMLDivElement, SelectSeparatorProps>(({ classNames, ...props }, forwardedRef) => {
180
176
  const { tx } = useThemeContext();
181
- return (
182
- <SelectPrimitive.Separator
183
- {...props}
184
- className={tx('select.separator', 'select__separator', {}, classNames)}
185
- ref={forwardedRef}
186
- />
187
- );
177
+ return <SelectPrimitive.Separator {...props} className={tx('select.separator', {}, classNames)} ref={forwardedRef} />;
188
178
  });
189
179
 
190
180
  type SelectArrowProps = ThemedClassName<SelectPrimitive.SelectArrowProps>;
191
181
 
192
182
  const SelectArrow = forwardRef<SVGSVGElement, SelectArrowProps>(({ classNames, ...props }, forwardedRef) => {
193
183
  const { tx } = useThemeContext();
194
- return (
195
- <SelectPrimitive.Arrow
196
- {...props}
197
- className={tx('select.arrow', 'select__arrow', {}, classNames)}
198
- ref={forwardedRef}
199
- />
200
- );
184
+ return <SelectPrimitive.Arrow {...props} className={tx('select.arrow', {}, classNames)} ref={forwardedRef} />;
201
185
  });
202
186
 
203
187
  export const Select = {
@@ -1,25 +1,22 @@
1
1
  //
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
- import {
5
- Separator as SeparatorPrimitive,
6
- type SeparatorProps as SeparatorPrimitiveProps,
7
- } from '@radix-ui/react-separator';
4
+ import * as SeparatorPrimitive from '@radix-ui/react-separator';
8
5
  import React, { forwardRef } from 'react';
9
6
 
10
7
  import { useThemeContext } from '../../hooks';
11
8
  import { type ThemedClassName } from '../../util';
12
9
 
13
- type SeparatorProps = ThemedClassName<SeparatorPrimitiveProps> & { subdued?: boolean };
10
+ type SeparatorProps = ThemedClassName<SeparatorPrimitive.SeparatorProps> & { subdued?: boolean };
14
11
 
15
12
  const Separator = forwardRef<HTMLDivElement, SeparatorProps>(
16
13
  ({ classNames, orientation = 'horizontal', subdued, ...props }, forwardedRef) => {
17
14
  const { tx } = useThemeContext();
18
15
  return (
19
- <SeparatorPrimitive
20
- orientation={orientation}
16
+ <SeparatorPrimitive.Root
21
17
  {...props}
22
- className={tx('separator.root', 'separator', { orientation, subdued }, classNames)}
18
+ orientation={orientation}
19
+ className={tx('separator.root', { orientation, subdued }, classNames)}
23
20
  ref={forwardedRef}
24
21
  />
25
22
  );
@@ -0,0 +1,52 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { withTheme } from '../../testing';
8
+
9
+ import { Skeleton } from './Skeleton';
10
+
11
+ export default {
12
+ title: 'ui/react-ui-core/components/Skeleton',
13
+ component: Skeleton,
14
+ decorators: [withTheme()],
15
+ parameters: {
16
+ layout: 'centered',
17
+ },
18
+ };
19
+
20
+ export const Default = {
21
+ render: () => (
22
+ <div className='flex flex-col gap-4 p-4 border border-separator rounded-xs'>
23
+ <div className='flex w-fit items-center gap-4'>
24
+ <Skeleton classNames='size-10 shrink-0 rounded-full' />
25
+ <div className='grid gap-2'>
26
+ <Skeleton classNames='h-4 w-[150px]' />
27
+ <Skeleton classNames='h-4 w-[100px]' />
28
+ </div>
29
+ </div>
30
+ </div>
31
+ ),
32
+ };
33
+
34
+ export const Card = {
35
+ render: () => (
36
+ <div className='flex flex-col gap-3 w-96 p-4 border border-separator rounded-xs'>
37
+ <div className='flex items-center gap-3'>
38
+ <Skeleton variant='circle' classNames='h-12 w-12 rounded-full' />
39
+ <div className='flex flex-col gap-2 flex-1'>
40
+ <Skeleton classNames='h-4 w-24' />
41
+ <Skeleton classNames='h-3 w-32' />
42
+ </div>
43
+ </div>
44
+ <Skeleton classNames='h-32 w-full rounded-sm' />
45
+ <div className='flex flex-col gap-2'>
46
+ <Skeleton classNames='h-3 w-full' />
47
+ <Skeleton classNames='h-3 w-5/6' />
48
+ <Skeleton classNames='h-3 w-4/6' />
49
+ </div>
50
+ </div>
51
+ ),
52
+ };
@@ -0,0 +1,26 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { type ComponentPropsWithRef, forwardRef } from 'react';
6
+
7
+ import { useThemeContext } from '../../hooks';
8
+ import { type ThemedClassName } from '../../util';
9
+
10
+ type SkeletonProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
11
+ variant?: 'default' | 'circle' | 'text';
12
+ };
13
+
14
+ /**
15
+ * A skeleton loading component that displays a placeholder while content is loading.
16
+ */
17
+ const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(
18
+ ({ classNames, variant = 'default', ...props }, forwardedRef) => {
19
+ const { tx } = useThemeContext();
20
+ return <div {...props} className={tx('skeleton.root', { variant }, classNames)} ref={forwardedRef} />;
21
+ },
22
+ );
23
+
24
+ export { Skeleton };
25
+
26
+ export type { SkeletonProps };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './Skeleton';