@dxos/react-ui 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b

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 (353) hide show
  1. package/dist/lib/browser/{chunk-6DTBPJE4.mjs → chunk-BDBC6H6V.mjs} +182 -108
  2. package/dist/lib/browser/chunk-BDBC6H6V.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +2961 -2056
  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 +70 -41
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/browser/translations.mjs +18 -0
  9. package/dist/lib/browser/translations.mjs.map +7 -0
  10. package/dist/lib/node-esm/{chunk-JKHQSGNU.mjs → chunk-3JSJK2ZY.mjs} +182 -108
  11. package/dist/lib/node-esm/chunk-3JSJK2ZY.mjs.map +7 -0
  12. package/dist/lib/node-esm/index.mjs +2961 -2056
  13. package/dist/lib/node-esm/index.mjs.map +4 -4
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/testing/index.mjs +70 -41
  16. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/translations.mjs +20 -0
  18. package/dist/lib/node-esm/translations.mjs.map +7 -0
  19. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  20. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  21. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  22. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  24. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  25. package/dist/types/src/components/Button/Button.d.ts +2 -2
  26. package/dist/types/src/components/Button/Button.d.ts.map +1 -1
  27. package/dist/types/src/components/Button/Button.stories.d.ts +1 -1
  28. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Button/IconButton.d.ts +1 -0
  30. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
  31. package/dist/types/src/components/Button/IconButton.stories.d.ts +3 -0
  32. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -1
  33. package/dist/types/src/components/Button/Toggle.d.ts +2 -2
  34. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -1
  35. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/Button/ToggleGroup.d.ts +6 -6
  37. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
  38. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +2 -2
  39. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/Card/Card.d.ts +124 -0
  41. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  42. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  43. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  44. package/dist/types/src/components/Card/index.d.ts +2 -0
  45. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  46. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  47. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  48. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  49. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  50. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  51. package/dist/types/src/components/Dialog/AlertDialog.d.ts +43 -23
  52. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
  53. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
  54. package/dist/types/src/components/Dialog/Dialog.d.ts +48 -30
  55. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  56. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +6 -8
  57. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
  58. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  59. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  60. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  61. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  62. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  63. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +19 -0
  64. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  65. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  66. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  67. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  68. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  69. package/dist/types/src/components/Focus/Focus.d.ts +36 -0
  70. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  71. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  72. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  73. package/dist/types/src/components/Focus/index.d.ts +2 -0
  74. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  75. package/dist/types/src/components/Icon/Icon.d.ts +4 -0
  76. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  77. package/dist/types/src/components/Icon/Icon.stories.d.ts +11 -3
  78. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
  79. package/dist/types/src/components/Image/Image.d.ts +15 -0
  80. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  81. package/dist/types/src/components/Image/Image.stories.d.ts +34 -0
  82. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  83. package/dist/types/src/components/Image/index.d.ts +2 -0
  84. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  85. package/dist/types/src/components/Input/Input.d.ts +16 -22
  86. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  87. package/dist/types/src/components/Input/Input.stories.d.ts +6 -6
  88. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  89. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  90. package/dist/types/src/components/List/List.d.ts +5 -3
  91. package/dist/types/src/components/List/List.d.ts.map +1 -1
  92. package/dist/types/src/components/List/List.stories.d.ts +3 -1
  93. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  94. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -1
  95. package/dist/types/src/components/List/Tree.d.ts +2 -2
  96. package/dist/types/src/components/List/Tree.d.ts.map +1 -1
  97. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -1
  98. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -1
  99. package/dist/types/src/components/List/Treegrid.d.ts +5 -9
  100. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
  101. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -1
  102. package/dist/types/src/components/Main/Main.d.ts +8 -4
  103. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  104. package/dist/types/src/components/Main/Main.stories.d.ts +0 -3
  105. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  106. package/dist/types/src/components/Main/useSwipeToDismiss.d.ts.map +1 -1
  107. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
  108. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -1
  109. package/dist/types/src/components/Menu/DropdownMenu.d.ts +58 -49
  110. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
  111. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +14 -1
  112. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -1
  113. package/dist/types/src/components/Message/Message.d.ts +1 -1
  114. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  115. package/dist/types/src/components/Message/Message.stories.d.ts +4 -5
  116. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  117. package/dist/types/src/components/Popover/Popover.d.ts +39 -22
  118. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  119. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  120. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +12 -11
  121. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  122. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +21 -10
  123. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  124. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +42 -13
  125. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
  126. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +9 -5
  127. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
  128. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  129. package/dist/types/src/components/Select/Select.stories.d.ts +2 -2
  130. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  131. package/dist/types/src/components/Separator/Separator.d.ts +3 -3
  132. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  133. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -1
  134. package/dist/types/src/components/Splitter/Splitter.d.ts +23 -15
  135. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -1
  136. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -1
  137. package/dist/types/src/components/Status/Status.d.ts +3 -4
  138. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  139. package/dist/types/src/components/Status/Status.stories.d.ts +4 -2
  140. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  141. package/dist/types/src/components/Tag/Tag.stories.d.ts +0 -5
  142. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  143. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +1 -1
  144. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  145. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  146. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  147. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +54 -55
  148. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  149. package/dist/types/src/components/ThemeProvider/index.d.ts +1 -1
  150. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  151. package/dist/types/src/components/Toast/Toast.d.ts +16 -16
  152. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  153. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  154. package/dist/types/src/components/Toolbar/Toolbar.d.ts +32 -15
  155. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  156. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  157. package/dist/types/src/components/Tooltip/Tooltip.d.ts +10 -10
  158. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  159. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -2
  160. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  161. package/dist/types/src/components/index.d.ts +7 -4
  162. package/dist/types/src/components/index.d.ts.map +1 -1
  163. package/dist/types/src/exemplars/generics.stories.d.ts +8 -6
  164. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -1
  165. package/dist/types/src/exemplars/slot.stories.d.ts +1 -0
  166. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -1
  167. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -1
  168. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  169. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  170. package/dist/types/src/hooks/index.d.ts +1 -0
  171. package/dist/types/src/hooks/index.d.ts.map +1 -1
  172. package/dist/types/src/hooks/useDensityContext.d.ts +1 -1
  173. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  174. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  175. package/dist/types/src/hooks/useIconHref.d.ts.map +1 -1
  176. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  177. package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -1
  178. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  179. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  180. package/dist/types/src/playground/Custom.stories.d.ts +1 -1
  181. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  182. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  183. package/dist/types/src/primitives/Column/Column.d.ts +33 -0
  184. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  185. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  186. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  187. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  188. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  189. package/dist/types/src/primitives/Container/Container.d.ts +6 -22
  190. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -1
  191. package/dist/types/src/primitives/Container/Container.stories.d.ts +2 -7
  192. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -1
  193. package/dist/types/src/primitives/Container/index.d.ts +0 -1
  194. package/dist/types/src/primitives/Container/index.d.ts.map +1 -1
  195. package/dist/types/src/primitives/Flex/Flex.d.ts +8 -5
  196. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -1
  197. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  198. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  199. package/dist/types/src/primitives/Grid/Grid.d.ts +10 -0
  200. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  201. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  202. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  203. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  204. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  205. package/dist/types/src/primitives/Panel/Panel.d.ts +35 -0
  206. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  207. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  208. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  209. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  210. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  211. package/dist/types/src/primitives/index.d.ts +3 -0
  212. package/dist/types/src/primitives/index.d.ts.map +1 -1
  213. package/dist/types/src/testing/Loading.d.ts +9 -0
  214. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  215. package/dist/types/src/testing/decorators/withLayout.d.ts +1 -1
  216. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  217. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
  218. package/dist/types/src/testing/decorators/withTheme.d.ts +1 -1
  219. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  220. package/dist/types/src/testing/index.d.ts +1 -0
  221. package/dist/types/src/testing/index.d.ts.map +1 -1
  222. package/dist/types/src/translations.d.ts +11 -0
  223. package/dist/types/src/translations.d.ts.map +1 -0
  224. package/dist/types/src/util/usePx.d.ts.map +1 -1
  225. package/dist/types/tsconfig.tsbuildinfo +1 -1
  226. package/package.json +33 -26
  227. package/src/components/Avatars/Avatar.stories.tsx +5 -7
  228. package/src/components/Avatars/Avatar.tsx +5 -6
  229. package/src/components/Avatars/AvatarGroup.stories.tsx +0 -1
  230. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -2
  231. package/src/components/Breadcrumb/Breadcrumb.tsx +10 -10
  232. package/src/components/Button/Button.stories.tsx +1 -2
  233. package/src/components/Button/Button.tsx +11 -19
  234. package/src/components/Button/IconButton.stories.tsx +6 -4
  235. package/src/components/Button/IconButton.tsx +3 -4
  236. package/src/components/Button/Toggle.stories.tsx +0 -1
  237. package/src/components/Button/Toggle.tsx +4 -4
  238. package/src/components/Button/ToggleGroup.stories.tsx +0 -1
  239. package/src/components/Button/ToggleGroup.tsx +12 -16
  240. package/src/components/Card/Card.stories.tsx +151 -0
  241. package/src/components/Card/Card.tsx +512 -0
  242. package/src/components/Card/index.ts +5 -0
  243. package/src/components/Clipboard/CopyButton.tsx +6 -7
  244. package/src/components/Dialog/AlertDialog.stories.tsx +14 -15
  245. package/src/components/Dialog/AlertDialog.tsx +123 -77
  246. package/src/components/Dialog/Dialog.stories.tsx +90 -14
  247. package/src/components/Dialog/Dialog.tsx +105 -104
  248. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +45 -0
  249. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  250. package/src/components/ErrorFallback/ErrorStack.tsx +114 -0
  251. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  252. package/src/components/ErrorFallback/index.ts +9 -0
  253. package/src/components/Focus/AUDIT.md +43 -0
  254. package/src/components/Focus/Focus.stories.tsx +230 -0
  255. package/src/components/Focus/Focus.tsx +201 -0
  256. package/src/components/Focus/index.ts +5 -0
  257. package/src/components/Icon/Icon.stories.tsx +43 -13
  258. package/src/components/Icon/Icon.tsx +14 -3
  259. package/src/components/Image/Image.stories.tsx +86 -0
  260. package/src/components/Image/Image.tsx +246 -0
  261. package/src/components/Image/index.ts +5 -0
  262. package/src/components/Input/Input.stories.tsx +17 -38
  263. package/src/components/Input/Input.tsx +20 -50
  264. package/src/components/Link/Link.stories.tsx +0 -1
  265. package/src/components/Link/Link.tsx +2 -2
  266. package/src/components/List/List.stories.tsx +14 -22
  267. package/src/components/List/List.tsx +11 -9
  268. package/src/components/List/ListDropIndicator.tsx +7 -8
  269. package/src/components/List/Tree.stories.tsx +4 -5
  270. package/src/components/List/Tree.tsx +0 -1
  271. package/src/components/List/TreeDropIndicator.tsx +6 -6
  272. package/src/components/List/Treegrid.stories.tsx +27 -28
  273. package/src/components/List/Treegrid.tsx +20 -20
  274. package/src/components/Main/Main.stories.tsx +3 -7
  275. package/src/components/Main/Main.tsx +13 -14
  276. package/src/components/Menu/ContextMenu.stories.tsx +0 -1
  277. package/src/components/Menu/ContextMenu.tsx +3 -3
  278. package/src/components/Menu/DropdownMenu.stories.tsx +0 -1
  279. package/src/components/Menu/DropdownMenu.tsx +51 -45
  280. package/src/components/Message/Message.stories.tsx +25 -11
  281. package/src/components/Message/Message.tsx +30 -15
  282. package/src/components/Popover/Popover.stories.tsx +5 -6
  283. package/src/components/Popover/Popover.tsx +59 -56
  284. package/src/components/ScrollArea/ScrollArea.stories.tsx +98 -39
  285. package/src/components/ScrollArea/ScrollArea.tsx +45 -25
  286. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +46 -25
  287. package/src/components/ScrollContainer/ScrollContainer.tsx +199 -92
  288. package/src/components/Select/Select.stories.tsx +5 -6
  289. package/src/components/Select/Select.tsx +2 -2
  290. package/src/components/Separator/Separator.tsx +4 -7
  291. package/src/components/Skeleton/Skeleton.stories.tsx +12 -13
  292. package/src/components/Splitter/Splitter.stories.tsx +47 -37
  293. package/src/components/Splitter/Splitter.tsx +44 -40
  294. package/src/components/Status/Status.stories.tsx +19 -16
  295. package/src/components/Status/Status.tsx +8 -5
  296. package/src/components/Tag/Tag.stories.tsx +3 -9
  297. package/src/components/Tag/Tag.tsx +2 -2
  298. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +31 -0
  299. package/src/components/ThemeProvider/ThemeProvider.tsx +7 -6
  300. package/src/components/ThemeProvider/index.ts +1 -1
  301. package/src/components/Toast/Toast.stories.tsx +0 -1
  302. package/src/components/Toast/Toast.tsx +22 -37
  303. package/src/components/Toolbar/Toolbar.stories.tsx +0 -1
  304. package/src/components/Toolbar/Toolbar.tsx +173 -29
  305. package/src/components/Tooltip/Tooltip.stories.tsx +18 -17
  306. package/src/components/Tooltip/Tooltip.tsx +16 -16
  307. package/src/components/index.ts +8 -5
  308. package/src/exemplars/generics.stories.tsx +12 -15
  309. package/src/exemplars/slot.stories.tsx +68 -61
  310. package/src/exemplars/tabster.stories.tsx +5 -5
  311. package/src/exemplars/virtualizer.stories.tsx +136 -0
  312. package/src/hooks/index.ts +1 -0
  313. package/src/hooks/useDensityContext.ts +2 -2
  314. package/src/playground/Controls.stories.tsx +0 -6
  315. package/src/playground/Custom.stories.tsx +13 -16
  316. package/src/playground/Typography.stories.tsx +1 -1
  317. package/src/primitives/Column/AUDIT.md +148 -0
  318. package/src/primitives/Column/Column.stories.tsx +181 -0
  319. package/src/primitives/Column/Column.tsx +165 -0
  320. package/src/primitives/Column/index.ts +5 -0
  321. package/src/primitives/Container/Container.stories.tsx +13 -51
  322. package/src/primitives/Container/Container.tsx +14 -74
  323. package/src/primitives/Container/index.ts +0 -1
  324. package/src/primitives/Flex/Flex.stories.tsx +57 -0
  325. package/src/primitives/Flex/Flex.tsx +20 -19
  326. package/src/primitives/Grid/Grid.stories.tsx +56 -0
  327. package/src/primitives/Grid/Grid.tsx +30 -0
  328. package/src/primitives/Grid/index.ts +5 -0
  329. package/src/primitives/Panel/Panel.stories.tsx +68 -0
  330. package/src/primitives/Panel/Panel.tsx +120 -0
  331. package/src/primitives/Panel/index.ts +5 -0
  332. package/src/primitives/index.ts +3 -0
  333. package/src/testing/Loading.tsx +47 -0
  334. package/src/testing/decorators/withLayout.tsx +15 -11
  335. package/src/testing/decorators/withLayoutVariants.tsx +18 -21
  336. package/src/testing/decorators/withTheme.tsx +10 -7
  337. package/src/testing/index.ts +2 -0
  338. package/src/translations.ts +19 -0
  339. package/src/util/usePx.ts +1 -0
  340. package/dist/lib/browser/chunk-6DTBPJE4.mjs.map +0 -7
  341. package/dist/lib/node-esm/chunk-JKHQSGNU.mjs.map +0 -7
  342. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -22
  343. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  344. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  345. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  346. package/dist/types/src/primitives/Container/Layout.d.ts +0 -18
  347. package/dist/types/src/primitives/Container/Layout.d.ts.map +0 -1
  348. package/dist/types/src/primitives/Container/Layout.stories.d.ts +0 -10
  349. package/dist/types/src/primitives/Container/Layout.stories.d.ts.map +0 -1
  350. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -57
  351. package/src/components/AnchoredOverflow/index.ts +0 -5
  352. package/src/primitives/Container/Layout.stories.tsx +0 -57
  353. package/src/primitives/Container/Layout.tsx +0 -61
@@ -0,0 +1,151 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useRef } from 'react';
7
+
8
+ import { random } from '@dxos/random';
9
+ import { Icon } from '@dxos/react-ui';
10
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
+
12
+ import { Card } from './Card';
13
+
14
+ random.seed(0);
15
+
16
+ type DefaultStoryProps = {
17
+ title: string;
18
+ description?: string;
19
+ image?: string;
20
+ fullWidth?: boolean;
21
+ };
22
+
23
+ const DefaultStory = ({ title, description, image, fullWidth }: DefaultStoryProps) => {
24
+ const handleRef = useRef<HTMLButtonElement>(null);
25
+ console.log(title);
26
+ return (
27
+ <Card.Root fullWidth={fullWidth}>
28
+ <Card.Toolbar>
29
+ <Card.DragHandle ref={handleRef} />
30
+ <Card.Title>{title}</Card.Title>
31
+ <Card.CloseIconButton onClick={() => console.log('close')} />
32
+ </Card.Toolbar>
33
+ <Card.Content>
34
+ <Card.Poster alt='Card.Poster' image={image} />
35
+ <Card.Row icon='ph--dot-outline--regular'>
36
+ <Card.Heading>Card.Heading</Card.Heading>
37
+ </Card.Row>
38
+ <Card.Row icon='ph--dot-outline--regular'>
39
+ <Card.Text>Card.Text (default)</Card.Text>
40
+ </Card.Row>
41
+ <Card.Row icon='ph--dot-outline--regular'>
42
+ <Card.Text variant='description'>
43
+ Card.Text (description)
44
+ <br />
45
+ {description}
46
+ </Card.Text>
47
+ </Card.Row>
48
+ <Card.Row icon='ph--dot-outline--regular'>
49
+ <Card.Heading variant='subtitle'>Card.Heading (subtitle)</Card.Heading>
50
+ </Card.Row>
51
+ <Card.Action label='Card.Action' onClick={() => console.log('action')} />
52
+ <Card.Link label='Card.Link' href='https://dxos.org' />
53
+ </Card.Content>
54
+ </Card.Root>
55
+ );
56
+ };
57
+
58
+ const meta = {
59
+ title: 'ui/react-ui-core/components/Card',
60
+ render: DefaultStory,
61
+ decorators: [withTheme(), withLayout({ layout: 'centered', classNames: 'grid w-[30rem] place-items-center' })],
62
+ } satisfies Meta<typeof DefaultStory>;
63
+
64
+ export default meta;
65
+
66
+ type Story = StoryObj<typeof meta>;
67
+
68
+ const image = random.image.url();
69
+
70
+ export const Default: Story = {
71
+ args: {
72
+ title: random.commerce.productName(),
73
+ description: random.lorem.paragraph(3),
74
+ image,
75
+ },
76
+ };
77
+
78
+ export const FullWidth: Story = {
79
+ args: {
80
+ title: random.commerce.productName(),
81
+ description: random.lorem.paragraph(3),
82
+ image,
83
+ fullWidth: true,
84
+ },
85
+ };
86
+
87
+ export const Simple: Story = {
88
+ args: {
89
+ title: random.commerce.productName(),
90
+ },
91
+ render: ({ title }) => {
92
+ const handleRef = useRef<HTMLButtonElement>(null);
93
+ return (
94
+ <Card.Root>
95
+ <Card.Toolbar>
96
+ <Card.DragHandle ref={handleRef} />
97
+ <Card.Title>{title}</Card.Title>
98
+ <Card.CloseIconButton onClick={() => console.log('close')} />
99
+ </Card.Toolbar>
100
+ </Card.Root>
101
+ );
102
+ },
103
+ };
104
+
105
+ export const Description: Story = {
106
+ args: {
107
+ title: random.commerce.productName(),
108
+ description: random.lorem.paragraph(3),
109
+ },
110
+ render: ({ title, description }) => {
111
+ const handleRef = useRef<HTMLButtonElement>(null);
112
+ return (
113
+ <Card.Root>
114
+ <Card.Toolbar>
115
+ <Card.DragHandle ref={handleRef} />
116
+ <Card.Title>{title}</Card.Title>
117
+ <Card.CloseIconButton onClick={() => console.log('close')} />
118
+ </Card.Toolbar>
119
+ <Card.Content>
120
+ <Card.Row>
121
+ <Card.Text variant='description'>{description}</Card.Text>
122
+ </Card.Row>
123
+ </Card.Content>
124
+ </Card.Root>
125
+ );
126
+ },
127
+ };
128
+
129
+ export const Mock = () => (
130
+ <div className='grid grid-cols-[2rem_1fr_2rem] w-full dx-card-min-width dx-card-max-width border border-separator rounded-xs'>
131
+ <div className='grid grid-cols-subgrid col-span-full'>
132
+ <div className='grid h-[var(--dx-rail-item)] w-[var(--dx-rail-item)] place-items-center'>
133
+ <Icon icon='ph--dots-six-vertical--regular' />
134
+ </div>
135
+ <div className='p-1 whitespace-normal break-words text-description items-center'>
136
+ This line is very very long and it should wrap.
137
+ </div>
138
+ <div className='grid h-[var(--dx-rail-item)] w-[var(--dx-rail-item)] place-items-center'>
139
+ <Icon icon='ph--x--regular' />
140
+ </div>
141
+ </div>
142
+ <div className='grid grid-cols-subgrid col-span-3'>
143
+ <div className='grid h-[var(--dx-rail-item)] w-[var(--dx-rail-item)] place-items-center'>
144
+ <Icon icon='ph--dots-six-vertical--regular' />
145
+ </div>
146
+ <div className='p-1 text-description items-center col-span-2'>
147
+ This line is very very long and it should wrap.
148
+ </div>
149
+ </div>
150
+ </div>
151
+ );
@@ -0,0 +1,512 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Primitive } from '@radix-ui/react-primitive';
6
+ import { Slot } from '@radix-ui/react-slot';
7
+ import DOMPurify from 'dompurify';
8
+ import React, {
9
+ CSSProperties,
10
+ MouseEventHandler,
11
+ type PropsWithChildren,
12
+ createContext,
13
+ forwardRef,
14
+ useContext,
15
+ useMemo,
16
+ } from 'react';
17
+
18
+ import { composable, composableProps, iconSize, mx, slottable } from '@dxos/ui-theme';
19
+ import { type Density } from '@dxos/ui-types';
20
+
21
+ import { useThemeContext } from '../../hooks';
22
+ import { Column } from '../../primitives';
23
+ import { type ThemedClassName } from '../../util';
24
+ import { Button } from '../Button';
25
+ import { Icon, type IconProps } from '../Icon';
26
+ import { Image } from '../Image';
27
+ import {
28
+ Toolbar,
29
+ ToolbarCloseIconButtonProps,
30
+ ToolbarDragHandleProps,
31
+ type ToolbarMenuItem,
32
+ type ToolbarMenuProps,
33
+ type ToolbarRootProps,
34
+ } from '../Toolbar';
35
+
36
+ //
37
+ // Context
38
+ //
39
+
40
+ const CARD_NAME = 'Card';
41
+
42
+ type CardContextValue = {
43
+ menuItems?: CardMenuItem<any>[];
44
+ };
45
+
46
+ /** @deprecated Use context for menus. */
47
+ const CardContext = createContext<CardContextValue>({});
48
+
49
+ //
50
+ // Root
51
+ //
52
+
53
+ const CARD_ROOT_NAME = 'Card.Root';
54
+
55
+ type CardRootProps = {
56
+ id?: string;
57
+ border?: boolean;
58
+ fullWidth?: boolean;
59
+ density?: Density;
60
+ style?: CSSProperties;
61
+ tabIndex?: number;
62
+ onClick?: MouseEventHandler<HTMLDivElement>;
63
+ 'data-selected'?: boolean;
64
+ 'data-testid'?: string;
65
+ };
66
+
67
+ // `Card.Root` does not support `asChild`. The Column grid is the root element
68
+ // (one `<div>` carrying both the `dx-card` and `dx-column-root` classes
69
+ // instead of the previous outer-card + inner-column pair), so caller-provided
70
+ // HTML attributes — `onClick`, `tabIndex`, `style`, `data-*`, `grid-template-rows`
71
+ // overrides via `classNames` — land directly on the grid container. Slot-parents
72
+ // (`Focus.Item asChild`, `Mosaic.Tile asChild`, etc.) continue to work because
73
+ // `composable()` preserves the COMPOSABLE marker that slottable parents check
74
+ // before warning, and Radix `Slot` merges the parent's props onto the inner
75
+ // `<div>` exactly the way `slottable`'s `Slot`/`Primitive.div` branch did.
76
+ const CardRoot = composable<HTMLDivElement, CardRootProps>(
77
+ ({ children, id, role, border = true, fullWidth, density, ...props }, forwardedRef) => {
78
+ const { className, ...rest } = composableProps(props);
79
+ const { tx } = useThemeContext();
80
+
81
+ return (
82
+ <Column.Root
83
+ asChild
84
+ gutter={density === 'coarse' ? 'lg' : 'md'}
85
+ classNames={tx('card.root', { border, fullWidth }, className)}
86
+ role={role ?? 'group'}
87
+ >
88
+ <div {...rest} {...(id && { 'data-object-id': id })} ref={forwardedRef}>
89
+ {children}
90
+ </div>
91
+ </Column.Root>
92
+ );
93
+ },
94
+ );
95
+
96
+ CardRoot.displayName = CARD_ROOT_NAME;
97
+
98
+ //
99
+ // Toolbar
100
+ //
101
+
102
+ const CARD_TOOLBAR_NAME = 'Card.Toolbar';
103
+
104
+ type CardToolbarProps = ToolbarRootProps;
105
+
106
+ const CardToolbar = composable<HTMLDivElement, CardToolbarProps>(({ children, classNames, ...props }, forwardedRef) => {
107
+ const { tx } = useThemeContext();
108
+
109
+ return (
110
+ <Toolbar.Root {...props} style={iconSize(5)} classNames={[tx('card.toolbar', {}), classNames]} ref={forwardedRef}>
111
+ {children}
112
+ </Toolbar.Root>
113
+ );
114
+ });
115
+
116
+ CardToolbar.displayName = CARD_TOOLBAR_NAME;
117
+
118
+ //
119
+ // DragHandle
120
+ //
121
+
122
+ const CARD_DRAG_HANDLE_NAME = 'Card.DragHandle';
123
+
124
+ type CardDragHandleProps = ToolbarDragHandleProps;
125
+
126
+ const CardDragHandle = forwardRef<HTMLButtonElement, CardDragHandleProps>((props, forwardedRef) => {
127
+ return (
128
+ <CardIconBlock padding>
129
+ <Toolbar.DragHandle {...props} ref={forwardedRef} />
130
+ </CardIconBlock>
131
+ );
132
+ });
133
+
134
+ CardDragHandle.displayName = CARD_DRAG_HANDLE_NAME;
135
+
136
+ //
137
+ // CloseIconButton
138
+ //
139
+
140
+ const CARD_CLOSE_ICON_BUTTON_NAME = 'Card.CloseIconButton';
141
+
142
+ type CloseIconButtonProps = ToolbarCloseIconButtonProps;
143
+
144
+ const CloseIconButton = forwardRef<HTMLButtonElement, CloseIconButtonProps>((props, forwardedRef) => {
145
+ return (
146
+ <CardIconBlock padding>
147
+ <Toolbar.CloseIconButton {...props} ref={forwardedRef} />
148
+ </CardIconBlock>
149
+ );
150
+ });
151
+
152
+ CloseIconButton.displayName = CARD_CLOSE_ICON_BUTTON_NAME;
153
+
154
+ //
155
+ // Menu
156
+ //
157
+
158
+ const CARD_MENU_NAME = 'Card.Menu';
159
+
160
+ type CardMenuItem<T extends any | void = void> = ToolbarMenuItem<T>;
161
+
162
+ type CardMenuProps<T extends any | void = void> = ToolbarMenuProps<T>;
163
+
164
+ const CardMenu = <T extends any | void = void>({ context, items, ...props }: CardMenuProps<T>) => {
165
+ const { menuItems } = useContext(CardContext) ?? {};
166
+ const combinedItems = [...(items ?? []), ...((menuItems as CardMenuItem<T>[]) ?? [])];
167
+
168
+ return (
169
+ <CardIconBlock padding>
170
+ <Toolbar.Menu {...props} context={context} items={combinedItems} />
171
+ </CardIconBlock>
172
+ );
173
+ };
174
+
175
+ (CardMenu as any).displayName = CARD_MENU_NAME;
176
+
177
+ //
178
+ // Icon
179
+ //
180
+
181
+ const CARD_ICON_NAME = 'Card.Icon';
182
+
183
+ const CardIcon = (props: IconProps) => {
184
+ return (
185
+ <CardIconBlock>
186
+ <Icon {...props} />
187
+ </CardIconBlock>
188
+ );
189
+ };
190
+
191
+ (CardIcon as any).displayName = CARD_ICON_NAME;
192
+
193
+ //
194
+ // IconBlock
195
+ //
196
+
197
+ const CARD_ICON_BLOCK_NAME = 'Card.IconBlock';
198
+
199
+ const CardIconBlock = forwardRef<HTMLDivElement, ThemedClassName<PropsWithChildren<{ padding?: boolean }>>>(
200
+ ({ classNames, children, padding, ...props }, forwardedRef) => {
201
+ const { tx } = useThemeContext();
202
+
203
+ return (
204
+ <div {...props} className={tx('card.icon-block', { padding }, classNames)} ref={forwardedRef}>
205
+ {children}
206
+ </div>
207
+ );
208
+ },
209
+ );
210
+
211
+ CardIconBlock.displayName = CARD_ICON_BLOCK_NAME;
212
+
213
+ //
214
+ // Title
215
+ //
216
+
217
+ const CARD_TITLE_NAME = 'Card.Title';
218
+
219
+ const CardTitle = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
220
+ const { tx } = useThemeContext();
221
+ const { className, ...rest } = composableProps(props, { role: 'heading' });
222
+ const Comp = asChild ? Slot : Primitive.div;
223
+
224
+ return (
225
+ <Comp {...rest} className={tx('card.title', {}, className)} ref={forwardedRef}>
226
+ {children}
227
+ </Comp>
228
+ );
229
+ });
230
+
231
+ CardTitle.displayName = CARD_TITLE_NAME;
232
+
233
+ //
234
+ // Content
235
+ //
236
+
237
+ const CARD_CONTENT_NAME = 'Card.Content';
238
+
239
+ const CardContent = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
240
+ const { className, ...rest } = composableProps(props);
241
+ const Comp = asChild ? Slot : Primitive.div;
242
+ const { tx } = useThemeContext();
243
+
244
+ return (
245
+ <Comp {...rest} className={tx('card.content', {}, className)} ref={forwardedRef}>
246
+ {children}
247
+ </Comp>
248
+ );
249
+ });
250
+
251
+ CardContent.displayName = CARD_CONTENT_NAME;
252
+
253
+ //
254
+ // Row
255
+ //
256
+
257
+ const CARD_ROW_NAME = 'Card.Row';
258
+
259
+ type CardRowProps = { icon?: string; fullWidth?: boolean };
260
+
261
+ // TODO(burdon): fullWidth should mean no columns.
262
+ const CardRow = slottable<HTMLDivElement, CardRowProps>(({ children, asChild, icon, ...props }, forwardedRef) => {
263
+ const { className, ...rest } = composableProps(props);
264
+ const Comp = asChild ? Slot : Primitive.div;
265
+ const { tx } = useThemeContext();
266
+
267
+ return (
268
+ <Comp {...rest} className={tx('card.row', {}, className)} ref={forwardedRef}>
269
+ {(icon && <CardIcon classNames='text-subdued' icon={icon} size={4} />) || <div />}
270
+ {children}
271
+ </Comp>
272
+ );
273
+ });
274
+
275
+ CardRow.displayName = CARD_ROW_NAME;
276
+
277
+ //
278
+ // Section
279
+ //
280
+
281
+ const CARD_SECTION_NAME = 'Card.Section';
282
+
283
+ /**
284
+ * @deprecated Merge with Card.Row fullWidth
285
+ */
286
+ const CardSection = slottable<HTMLDivElement>(({ children, asChild, role, ...props }, forwardedRef) => {
287
+ const { className, ...rest } = composableProps(props);
288
+ const Comp = asChild ? Slot : Primitive.div;
289
+
290
+ return (
291
+ <Comp {...rest} role={role ?? 'none'} className={mx('col-span-full', className)} ref={forwardedRef}>
292
+ {children}
293
+ </Comp>
294
+ );
295
+ });
296
+
297
+ CardSection.displayName = CARD_SECTION_NAME;
298
+
299
+ //
300
+ // Heading
301
+ //
302
+
303
+ const CARD_HEADING_NAME = 'Card.Heading';
304
+
305
+ type CardHeadingProps = { variant?: 'default' | 'subtitle' };
306
+
307
+ /**
308
+ * @deprecated Use typography.
309
+ */
310
+ const CardHeading = slottable<HTMLDivElement, CardHeadingProps>(
311
+ ({ children, asChild, role, variant = 'default', ...props }, forwardedRef) => {
312
+ const { className, ...rest } = composableProps(props);
313
+ const Comp = asChild ? Slot : Primitive.div;
314
+ const { tx } = useThemeContext();
315
+
316
+ return (
317
+ <Comp
318
+ {...rest}
319
+ role={role ?? 'heading'}
320
+ className={tx('card.heading', { variant }, className)}
321
+ ref={forwardedRef}
322
+ >
323
+ {children}
324
+ </Comp>
325
+ );
326
+ },
327
+ );
328
+
329
+ CardHeading.displayName = CARD_HEADING_NAME;
330
+
331
+ //
332
+ // Text
333
+ //
334
+
335
+ const CARD_TEXT_NAME = 'Card.Text';
336
+
337
+ type CardTextProps = { truncate?: boolean; variant?: 'default' | 'description' };
338
+
339
+ const CardText = slottable<HTMLDivElement, CardTextProps>(
340
+ ({ children, asChild, role, truncate, variant = 'default', ...props }, forwardedRef) => {
341
+ const { className, ...rest } = composableProps(props);
342
+ const Comp = asChild ? Slot : Primitive.div;
343
+ const { tx } = useThemeContext();
344
+
345
+ return (
346
+ <Comp {...rest} role={role ?? 'none'} className={tx('card.text', { variant }, className)} ref={forwardedRef}>
347
+ <span className={tx('card.text-span', { variant, truncate })}>{children}</span>
348
+ </Comp>
349
+ );
350
+ },
351
+ );
352
+
353
+ CardText.displayName = CARD_TEXT_NAME;
354
+
355
+ //
356
+ // Html
357
+ //
358
+
359
+ const CARD_HTML_NAME = 'Card.Html';
360
+
361
+ type CardHtmlProps = { html: string; variant?: 'default' | 'description' };
362
+
363
+ /**
364
+ * Renders sanitized HTML content inside a card text slot.
365
+ * Uses DOMPurify to prevent XSS from untrusted markup (e.g. RSS feed content).
366
+ */
367
+ const CardHtml = ({ html, variant = 'default', ...props }: CardHtmlProps & ThemedClassName<object>) => {
368
+ const { tx } = useThemeContext();
369
+ const sanitized = useMemo(() => DOMPurify.sanitize(html), [html]);
370
+
371
+ return (
372
+ <div
373
+ {...props}
374
+ className={tx('card.text', { variant })}
375
+ // eslint-disable-next-line react/no-danger
376
+ dangerouslySetInnerHTML={{ __html: sanitized }}
377
+ />
378
+ );
379
+ };
380
+
381
+ (CardHtml as any).displayName = CARD_HTML_NAME;
382
+
383
+ //
384
+ // Poster
385
+ //
386
+
387
+ const CARD_POSTER_NAME = 'Card.Poster';
388
+
389
+ type CardPosterProps = ThemedClassName<
390
+ {
391
+ alt: string;
392
+ aspect?: 'video' | 'auto';
393
+ /**
394
+ * How the image fills the poster box. `'contain'` (default) preserves
395
+ * aspect ratio and may letterbox; `'cover'` fills the box edge-to-edge,
396
+ * cropping as needed. Forwarded to the underlying `Image`'s
397
+ * `object-fit`.
398
+ */
399
+ fit?: 'contain' | 'cover';
400
+ } & Partial<{ image: string; icon: string }>
401
+ >;
402
+
403
+ const CardPoster = (props: CardPosterProps) => {
404
+ const { tx } = useThemeContext();
405
+ const aspect = props.aspect === 'auto' ? 'aspect-auto' : 'aspect-video';
406
+
407
+ if (props.image) {
408
+ return (
409
+ <div className='col-span-full'>
410
+ <Image
411
+ classNames={[tx('card.poster', {}), aspect, props.classNames]}
412
+ src={props.image}
413
+ alt={props.alt}
414
+ fit={props.fit}
415
+ />
416
+ </div>
417
+ );
418
+ }
419
+
420
+ if (props.icon) {
421
+ return (
422
+ <div role='image' className={tx('card.poster-icon', {}, [aspect, props.classNames])} aria-label={props.alt}>
423
+ <Icon icon={props.icon} size={10} />
424
+ </div>
425
+ );
426
+ }
427
+ };
428
+
429
+ (CardPoster as any).displayName = CARD_POSTER_NAME;
430
+
431
+ //
432
+ // Action
433
+ //
434
+
435
+ const CARD_ACTION_NAME = 'Card.Action';
436
+
437
+ type CardActionProps = { icon?: string; label: string; actionIcon?: string; onClick?: () => void };
438
+
439
+ const CardAction = ({ icon, actionIcon = 'ph--arrow-right--regular', label, onClick }: CardActionProps) => {
440
+ const { tx } = useThemeContext();
441
+ return (
442
+ <Button variant='ghost' classNames={tx('card.action', {})} onClick={onClick}>
443
+ {icon ? <CardIcon classNames='text-subdued' icon={icon} size={4} /> : <div />}
444
+ <span className={tx('card.action-label', {}, !actionIcon ? 'col-span-2' : undefined)}>{label}</span>
445
+ {actionIcon && <CardIcon icon={actionIcon} size={4} />}
446
+ </Button>
447
+ );
448
+ };
449
+
450
+ (CardAction as any).displayName = CARD_ACTION_NAME;
451
+
452
+ //
453
+ // Link
454
+ //
455
+
456
+ const CARD_LINK_NAME = 'Card.Link';
457
+
458
+ type CardLinkProps = { label: string; href: string };
459
+
460
+ const CardLink = ({ label, href }: CardLinkProps) => {
461
+ const { tx } = useThemeContext();
462
+ return (
463
+ <a className={tx('card.link', {})} data-variant='ghost' href={href} target='_blank' rel='noreferrer'>
464
+ <CardIcon classNames='text-subdued' icon='ph--link--regular' />
465
+ <span className={tx('card.link-label', {})}>{label}</span>
466
+ <CardIcon classNames='invisible group-hover:visible' icon='ph--arrow-square-out--regular' />
467
+ </a>
468
+ );
469
+ };
470
+
471
+ (CardLink as any).displayName = CARD_LINK_NAME;
472
+
473
+ //
474
+ // Card
475
+ //
476
+
477
+ export const Card = {
478
+ Root: CardRoot,
479
+
480
+ // Toolbar
481
+ Toolbar: CardToolbar,
482
+ ToolbarIconButton: Toolbar.IconButton,
483
+ ToolbarSeparator: Toolbar.Separator,
484
+
485
+ // Toolbar blocks
486
+ IconBlock: CardIconBlock,
487
+ DragHandle: CardDragHandle,
488
+ CloseIconButton: CloseIconButton,
489
+ Menu: CardMenu,
490
+ Icon: CardIcon,
491
+ Title: CardTitle,
492
+
493
+ // Content
494
+ Content: CardContent,
495
+ Row: CardRow,
496
+ Section: CardSection,
497
+ Heading: CardHeading,
498
+ Text: CardText,
499
+ Html: CardHtml,
500
+ Poster: CardPoster,
501
+ Action: CardAction,
502
+ Link: CardLink,
503
+ };
504
+
505
+ export type {
506
+ CardContextValue,
507
+ CardRootProps,
508
+ CardToolbarProps,
509
+ CardDragHandleProps,
510
+ CloseIconButtonProps,
511
+ CardMenuProps,
512
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export * from './Card';
@@ -10,7 +10,6 @@ import { Button, type ButtonProps, IconButton } from '../Button';
10
10
  import { Icon, type IconProps } from '../Icon';
11
11
  import { useTranslation } from '../ThemeProvider';
12
12
  import { type TooltipScopedProps, useTooltipContext } from '../Tooltip';
13
-
14
13
  import { useClipboard } from './ClipboardProvider';
15
14
 
16
15
  export type CopyButtonProps = ButtonProps &
@@ -18,7 +17,7 @@ export type CopyButtonProps = ButtonProps &
18
17
  value: string;
19
18
  };
20
19
 
21
- const inactiveLabelStyles = 'invisible bs-px -mbe-px overflow-hidden';
20
+ const inactiveLabelStyles = 'invisible h-px -mb-px overflow-hidden';
22
21
 
23
22
  export const CopyButton = ({ classNames, value, size = 5, ...props }: CopyButtonProps) => {
24
23
  const { t } = useTranslation(osTranslations);
@@ -31,12 +30,12 @@ export const CopyButton = ({ classNames, value, size = 5, ...props }: CopyButton
31
30
  onClick={() => setTextValue(value)}
32
31
  data-testid='copy-invitation'
33
32
  >
34
- <div role='none' className={mx('flex gap-1 items-center', isCopied && inactiveLabelStyles)}>
35
- <span className='pli-1'>{t('copy label')}</span>
33
+ <div className={mx('flex gap-1 items-center', isCopied && inactiveLabelStyles)}>
34
+ <span className='px-1'>{t('copy.label')}</span>
36
35
  <Icon icon='ph--copy--regular' size={size} />
37
36
  </div>
38
- <div role='none' className={mx('flex gap-1 items-center', !isCopied && inactiveLabelStyles)}>
39
- <span className='pli-1'>{t('copy success label')}</span>
37
+ <div className={mx('flex gap-1 items-center', !isCopied && inactiveLabelStyles)}>
38
+ <span className='px-1'>{t('copy-success.label')}</span>
40
39
  <Icon icon='ph--check--regular' size={size} />
41
40
  </div>
42
41
  </Button>
@@ -58,7 +57,7 @@ export const CopyButtonIconOnly = ({
58
57
  const { t } = useTranslation(osTranslations);
59
58
  const { textValue, setTextValue } = useClipboard();
60
59
  const isCopied = textValue === value;
61
- const label = isCopied ? t('copy success label') : (props.label ?? t('copy label'));
60
+ const label = isCopied ? t('copy-success.label') : (props.label ?? t('copy.label'));
62
61
  const { onOpen } = useTooltipContext('CopyButton', __scopeTooltip);
63
62
  return (
64
63
  <IconButton