@dxos/react-ui 0.8.4-main.67995b8 → 0.8.4-main.6fa680abb7

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 (448) hide show
  1. package/dist/lib/browser/chunk-2FKSMWNY.mjs +774 -0
  2. package/dist/lib/browser/chunk-2FKSMWNY.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +3918 -61
  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 +100 -60
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/chunk-ZNBLTSHI.mjs +776 -0
  9. package/dist/lib/node-esm/chunk-ZNBLTSHI.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +3918 -61
  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 +100 -60
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  16. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  17. package/dist/types/src/components/Avatars/Avatar.stories.d.ts +5 -31
  18. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts +5 -11
  20. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts +1 -1
  22. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  23. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts +8 -20
  24. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  25. package/dist/types/src/components/{Buttons → Button}/Button.d.ts +2 -2
  26. package/dist/types/src/components/Button/Button.d.ts.map +1 -0
  27. package/dist/types/src/components/Button/Button.stories.d.ts +17 -0
  28. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -0
  29. package/dist/types/src/components/{Buttons → Button}/IconButton.d.ts +4 -4
  30. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -0
  31. package/dist/types/src/components/Button/IconButton.stories.d.ts +13 -0
  32. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -0
  33. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -0
  34. package/dist/types/src/components/Button/Toggle.stories.d.ts +16 -0
  35. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -0
  36. package/dist/types/src/components/Button/ToggleGroup.d.ts +27 -0
  37. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -0
  38. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +27 -0
  39. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -0
  40. package/dist/types/src/components/Button/index.d.ts.map +1 -0
  41. package/dist/types/src/components/Card/Card.d.ts +107 -0
  42. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  43. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  44. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  45. package/dist/types/src/components/Card/index.d.ts +2 -0
  46. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  47. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  48. package/dist/types/src/components/Clipboard/CopyButton.d.ts +1 -1
  49. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  50. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts +1 -1
  51. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  52. package/dist/types/src/components/{Dialogs → Dialog}/AlertDialog.d.ts +13 -4
  53. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -0
  54. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts +11 -0
  55. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -0
  56. package/dist/types/src/components/Dialog/Dialog.d.ts +47 -0
  57. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -0
  58. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +24 -0
  59. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -0
  60. package/dist/types/src/components/Dialog/index.d.ts.map +1 -0
  61. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts +1 -1
  62. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  63. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  64. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  65. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  66. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  67. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +8 -0
  68. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  69. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  70. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  71. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  72. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  73. package/dist/types/src/components/Icon/Icon.d.ts +2 -2
  74. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  75. package/dist/types/src/components/Icon/Icon.stories.d.ts +17 -0
  76. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
  77. package/dist/types/src/components/Image/Image.d.ts +14 -0
  78. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  79. package/dist/types/src/components/Image/Image.stories.d.ts +33 -0
  80. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  81. package/dist/types/src/components/Image/index.d.ts +2 -0
  82. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  83. package/dist/types/src/components/Input/Input.d.ts +6 -8
  84. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  85. package/dist/types/src/components/Input/Input.stories.d.ts +17 -18
  86. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  87. package/dist/types/src/components/Link/Link.stories.d.ts +8 -8
  88. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  89. package/dist/types/src/components/{Lists → List}/List.d.ts +3 -3
  90. package/dist/types/src/components/List/List.d.ts.map +1 -0
  91. package/dist/types/src/components/List/List.stories.d.ts +14 -0
  92. package/dist/types/src/components/List/List.stories.d.ts.map +1 -0
  93. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -0
  94. package/dist/types/src/components/{Lists → List}/Tree.d.ts +1 -1
  95. package/dist/types/src/components/List/Tree.d.ts.map +1 -0
  96. package/dist/types/src/components/List/Tree.stories.d.ts +15 -0
  97. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -0
  98. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -0
  99. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts +1 -1
  100. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts.map +1 -1
  101. package/dist/types/src/components/List/Treegrid.stories.d.ts +12 -0
  102. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -0
  103. package/dist/types/src/components/List/index.d.ts.map +1 -0
  104. package/dist/types/src/components/Main/Main.d.ts +18 -28
  105. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  106. package/dist/types/src/components/Main/Main.stories.d.ts +6 -10
  107. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  108. package/dist/types/src/components/{Menus → Menu}/ContextMenu.d.ts +6 -6
  109. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -0
  110. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts +12 -0
  111. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -0
  112. package/dist/types/src/components/{Menus → Menu}/DropdownMenu.d.ts +8 -8
  113. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -0
  114. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +15 -0
  115. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -0
  116. package/dist/types/src/components/Menu/index.d.ts.map +1 -0
  117. package/dist/types/src/components/Message/Message.d.ts +1 -1
  118. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  119. package/dist/types/src/components/Message/Message.stories.d.ts +10 -20
  120. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/Popover/Popover.d.ts +4 -3
  122. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  123. package/dist/types/src/components/Popover/Popover.stories.d.ts +6 -34
  124. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  125. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +23 -26
  126. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  127. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +35 -25
  128. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  129. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +39 -0
  130. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -0
  131. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +24 -0
  132. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -0
  133. package/dist/types/src/components/ScrollContainer/index.d.ts +2 -0
  134. package/dist/types/src/components/ScrollContainer/index.d.ts.map +1 -0
  135. package/dist/types/src/components/Select/Select.d.ts +10 -10
  136. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  137. package/dist/types/src/components/Select/Select.stories.d.ts +4 -9
  138. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  139. package/dist/types/src/components/Separator/Separator.d.ts +1 -1
  140. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  141. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  142. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  143. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  144. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  145. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  146. package/dist/types/src/components/Splitter/Splitter.d.ts +32 -0
  147. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  148. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  149. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  150. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  151. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  152. package/dist/types/src/components/Status/Status.stories.d.ts +6 -10
  153. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  154. package/dist/types/src/components/Tag/Tag.d.ts +1 -1
  155. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  156. package/dist/types/src/components/Tag/Tag.stories.d.ts +8 -13
  157. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  158. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +3 -3
  159. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  160. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  161. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  162. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -8
  163. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  164. package/dist/types/src/components/ThemeProvider/index.d.ts +2 -1
  165. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  166. package/dist/types/src/components/Toast/Toast.d.ts +5 -5
  167. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  168. package/dist/types/src/components/Toast/Toast.stories.d.ts +6 -44
  169. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  170. package/dist/types/src/components/Toolbar/Toolbar.d.ts +46 -20
  171. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  172. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +6 -50
  173. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  174. package/dist/types/src/components/Tooltip/Tooltip.d.ts +2 -4
  175. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  176. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +8 -61
  177. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  178. package/dist/types/src/components/index.d.ts +13 -8
  179. package/dist/types/src/components/index.d.ts.map +1 -1
  180. package/dist/types/src/exemplars/generics.stories.d.ts +18 -0
  181. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  182. package/dist/types/src/exemplars/slot.stories.d.ts +14 -0
  183. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  184. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  185. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  186. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  187. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  188. package/dist/types/src/hooks/useDensityContext.d.ts +1 -1
  189. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  190. package/dist/types/src/hooks/useElevationContext.d.ts +1 -1
  191. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  192. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  193. package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
  194. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  195. package/dist/types/src/index.d.ts +2 -1
  196. package/dist/types/src/index.d.ts.map +1 -1
  197. package/dist/types/src/playground/Controls.stories.d.ts +5 -9
  198. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  199. package/dist/types/src/playground/Custom.stories.d.ts +12 -4
  200. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  201. package/dist/types/src/playground/Typography.stories.d.ts +5 -11
  202. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  203. package/dist/types/src/primitives/Column/Column.d.ts +26 -0
  204. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  205. package/dist/types/src/primitives/Column/Column.stories.d.ts +6 -0
  206. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  207. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  208. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  209. package/dist/types/src/primitives/Container/Container.d.ts +8 -0
  210. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  211. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  212. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  213. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  214. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  215. package/dist/types/src/primitives/Flex/Flex.d.ts +13 -0
  216. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  217. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  218. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  219. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  220. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  221. package/dist/types/src/primitives/Grid/Grid.d.ts +15 -0
  222. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  223. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  224. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  225. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  226. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  227. package/dist/types/src/primitives/Panel/Panel.d.ts +26 -0
  228. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  229. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  230. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  231. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  232. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  233. package/dist/types/src/primitives/index.d.ts +6 -0
  234. package/dist/types/src/primitives/index.d.ts.map +1 -0
  235. package/dist/types/src/testing/Loading.d.ts +9 -0
  236. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  237. package/dist/types/src/testing/decorators/index.d.ts +2 -1
  238. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  239. package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
  240. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
  241. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts +12 -0
  242. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
  243. package/dist/types/src/testing/decorators/withTheme.d.ts +5 -1
  244. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  245. package/dist/types/src/testing/index.d.ts +1 -0
  246. package/dist/types/src/testing/index.d.ts.map +1 -1
  247. package/dist/types/src/translations.d.ts +11 -0
  248. package/dist/types/src/translations.d.ts.map +1 -0
  249. package/dist/types/src/util/index.d.ts +2 -1
  250. package/dist/types/src/util/index.d.ts.map +1 -1
  251. package/dist/types/src/util/usePx.d.ts +8 -0
  252. package/dist/types/src/util/usePx.d.ts.map +1 -0
  253. package/dist/types/tsconfig.tsbuildinfo +1 -1
  254. package/package.json +41 -31
  255. package/src/components/Avatars/Avatar.stories.tsx +24 -16
  256. package/src/components/Avatars/Avatar.tsx +9 -16
  257. package/src/components/Avatars/AvatarGroup.stories.tsx +12 -8
  258. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +20 -15
  259. package/src/components/Breadcrumb/Breadcrumb.tsx +12 -38
  260. package/src/components/{Buttons → Button}/Button.stories.tsx +10 -11
  261. package/src/components/{Buttons → Button}/Button.tsx +7 -13
  262. package/src/components/{Buttons → Button}/IconButton.stories.tsx +15 -12
  263. package/src/components/{Buttons → Button}/IconButton.tsx +23 -16
  264. package/src/components/Button/Toggle.stories.tsx +37 -0
  265. package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +12 -9
  266. package/src/components/{Buttons → Button}/ToggleGroup.tsx +17 -4
  267. package/src/components/Card/Card.stories.tsx +151 -0
  268. package/src/components/Card/Card.tsx +347 -0
  269. package/src/components/Card/index.ts +5 -0
  270. package/src/components/Clipboard/ClipboardProvider.tsx +1 -1
  271. package/src/components/Clipboard/CopyButton.tsx +9 -8
  272. package/src/components/DensityProvider/DensityProvider.tsx +2 -2
  273. package/src/components/Dialog/AlertDialog.stories.tsx +69 -0
  274. package/src/components/{Dialogs → Dialog}/AlertDialog.tsx +128 -28
  275. package/src/components/Dialog/Dialog.stories.tsx +122 -0
  276. package/src/components/{Dialogs → Dialog}/Dialog.tsx +190 -60
  277. package/src/components/ElevationProvider/ElevationProvider.tsx +2 -2
  278. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +50 -0
  279. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  280. package/src/components/ErrorFallback/ErrorStack.tsx +80 -0
  281. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  282. package/src/components/ErrorFallback/index.ts +9 -0
  283. package/src/components/Icon/Icon.stories.tsx +113 -0
  284. package/src/components/Icon/Icon.tsx +3 -3
  285. package/src/components/Image/Image.stories.tsx +86 -0
  286. package/src/components/Image/Image.tsx +223 -0
  287. package/src/components/Image/index.ts +5 -0
  288. package/src/components/Input/Input.stories.tsx +28 -49
  289. package/src/components/Input/Input.tsx +46 -82
  290. package/src/components/Link/Link.stories.tsx +12 -8
  291. package/src/components/Link/Link.tsx +2 -2
  292. package/src/components/{Lists → List}/List.stories.tsx +44 -45
  293. package/src/components/{Lists → List}/List.tsx +27 -28
  294. package/src/components/{Lists → List}/ListDropIndicator.tsx +7 -7
  295. package/src/components/{Lists → List}/Tree.stories.tsx +15 -12
  296. package/src/components/{Lists → List}/Tree.tsx +4 -3
  297. package/src/components/{Lists → List}/TreeDropIndicator.tsx +7 -7
  298. package/src/components/{Lists → List}/Treegrid.stories.tsx +15 -9
  299. package/src/components/{Lists → List}/Treegrid.tsx +67 -31
  300. package/src/components/Main/Main.stories.tsx +53 -27
  301. package/src/components/Main/Main.tsx +176 -104
  302. package/src/components/{Menus → Menu}/ContextMenu.stories.tsx +13 -10
  303. package/src/components/{Menus → Menu}/ContextMenu.tsx +10 -33
  304. package/src/components/{Menus → Menu}/DropdownMenu.stories.tsx +14 -11
  305. package/src/components/{Menus → Menu}/DropdownMenu.tsx +111 -80
  306. package/src/components/Message/Message.stories.tsx +35 -16
  307. package/src/components/Message/Message.tsx +46 -33
  308. package/src/components/Popover/Popover.stories.tsx +16 -13
  309. package/src/components/Popover/Popover.tsx +86 -64
  310. package/src/components/ScrollArea/ScrollArea.stories.tsx +163 -34
  311. package/src/components/ScrollArea/ScrollArea.tsx +84 -82
  312. package/src/components/ScrollArea/index.ts +1 -1
  313. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +89 -0
  314. package/src/components/ScrollContainer/ScrollContainer.tsx +238 -0
  315. package/src/components/ScrollContainer/index.ts +5 -0
  316. package/src/components/Select/Select.stories.tsx +15 -12
  317. package/src/components/Select/Select.tsx +16 -31
  318. package/src/components/Separator/Separator.tsx +1 -1
  319. package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
  320. package/src/components/Skeleton/Skeleton.tsx +26 -0
  321. package/src/components/Skeleton/index.ts +5 -0
  322. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  323. package/src/components/Splitter/Splitter.tsx +126 -0
  324. package/src/components/Splitter/index.ts +5 -0
  325. package/src/components/Status/Status.stories.tsx +30 -23
  326. package/src/components/Status/Status.tsx +2 -2
  327. package/src/components/Tag/Tag.stories.tsx +17 -13
  328. package/src/components/Tag/Tag.tsx +3 -8
  329. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +32 -0
  330. package/src/components/ThemeProvider/ThemeProvider.tsx +7 -7
  331. package/src/components/ThemeProvider/TranslationsProvider.tsx +3 -18
  332. package/src/components/ThemeProvider/index.ts +3 -3
  333. package/src/components/Toast/Toast.stories.tsx +14 -11
  334. package/src/components/Toast/Toast.tsx +19 -23
  335. package/src/components/Toolbar/Toolbar.stories.tsx +16 -14
  336. package/src/components/Toolbar/Toolbar.tsx +201 -12
  337. package/src/components/Tooltip/Tooltip.stories.tsx +31 -25
  338. package/src/components/Tooltip/Tooltip.tsx +30 -26
  339. package/src/components/index.ts +14 -9
  340. package/src/exemplars/generics.stories.tsx +49 -0
  341. package/src/exemplars/slot.stories.tsx +107 -0
  342. package/src/exemplars/tabster.stories.tsx +127 -0
  343. package/src/exemplars/virtualizer.stories.tsx +137 -0
  344. package/src/hooks/useDensityContext.ts +1 -1
  345. package/src/hooks/useElevationContext.ts +1 -1
  346. package/src/hooks/useSafeArea.ts +3 -2
  347. package/src/hooks/useVisualViewport.ts +4 -4
  348. package/src/index.ts +2 -1
  349. package/src/playground/Controls.stories.tsx +12 -15
  350. package/src/playground/Custom.stories.tsx +15 -26
  351. package/src/playground/Typography.stories.tsx +11 -9
  352. package/src/primitives/Column/Column.stories.tsx +78 -0
  353. package/src/primitives/Column/Column.tsx +134 -0
  354. package/src/primitives/Column/index.ts +5 -0
  355. package/src/primitives/Container/Container.stories.tsx +30 -0
  356. package/src/primitives/Container/Container.tsx +22 -0
  357. package/src/primitives/Container/index.ts +5 -0
  358. package/src/primitives/Flex/Flex.stories.tsx +58 -0
  359. package/src/primitives/Flex/Flex.tsx +29 -0
  360. package/src/primitives/Flex/index.ts +5 -0
  361. package/src/primitives/Grid/Grid.stories.tsx +57 -0
  362. package/src/primitives/Grid/Grid.tsx +35 -0
  363. package/src/primitives/Grid/index.ts +5 -0
  364. package/src/primitives/Panel/Panel.stories.tsx +67 -0
  365. package/src/primitives/Panel/Panel.tsx +119 -0
  366. package/src/primitives/Panel/index.ts +5 -0
  367. package/src/primitives/index.ts +9 -0
  368. package/src/testing/Loading.tsx +26 -0
  369. package/src/testing/decorators/index.ts +2 -1
  370. package/src/testing/decorators/withLayout.tsx +77 -0
  371. package/src/testing/decorators/withLayoutVariants.tsx +48 -0
  372. package/src/testing/decorators/withTheme.tsx +34 -0
  373. package/src/testing/index.ts +2 -0
  374. package/src/translations.ts +19 -0
  375. package/src/util/index.ts +3 -1
  376. package/src/util/usePx.ts +61 -0
  377. package/dist/lib/browser/chunk-2COVUP44.mjs +0 -4373
  378. package/dist/lib/browser/chunk-2COVUP44.mjs.map +0 -7
  379. package/dist/lib/node-esm/chunk-GHXHND5V.mjs +0 -4375
  380. package/dist/lib/node-esm/chunk-GHXHND5V.mjs.map +0 -7
  381. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  382. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  383. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  384. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  385. package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
  386. package/dist/types/src/components/Buttons/Button.stories.d.ts +0 -12
  387. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
  388. package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
  389. package/dist/types/src/components/Buttons/IconButton.stories.d.ts +0 -22
  390. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
  391. package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
  392. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -19
  393. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
  394. package/dist/types/src/components/Buttons/ToggleGroup.d.ts +0 -28
  395. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
  396. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +0 -39
  397. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
  398. package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
  399. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
  400. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +0 -43
  401. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
  402. package/dist/types/src/components/Dialogs/Dialog.d.ts +0 -31
  403. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
  404. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -48
  405. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
  406. package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
  407. package/dist/types/src/components/Lists/List.d.ts.map +0 -1
  408. package/dist/types/src/components/Lists/List.stories.d.ts +0 -37
  409. package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
  410. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
  411. package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
  412. package/dist/types/src/components/Lists/Tree.stories.d.ts +0 -41
  413. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
  414. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
  415. package/dist/types/src/components/Lists/Treegrid.stories.d.ts +0 -10
  416. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
  417. package/dist/types/src/components/Lists/index.d.ts.map +0 -1
  418. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +0 -1
  419. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +0 -50
  420. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +0 -1
  421. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +0 -1
  422. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +0 -50
  423. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +0 -1
  424. package/dist/types/src/components/Menus/index.d.ts.map +0 -1
  425. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts +0 -12
  426. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
  427. package/dist/types/src/util/ThemedClassName.d.ts +0 -5
  428. package/dist/types/src/util/ThemedClassName.d.ts.map +0 -1
  429. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  430. package/src/components/AnchoredOverflow/index.ts +0 -5
  431. package/src/components/Buttons/Toggle.stories.tsx +0 -33
  432. package/src/components/Dialogs/AlertDialog.stories.tsx +0 -66
  433. package/src/components/Dialogs/Dialog.stories.tsx +0 -65
  434. package/src/testing/decorators/withSurfaceVariantsLayout.tsx +0 -51
  435. package/src/testing/decorators/withTheme.ts +0 -25
  436. package/src/util/ThemedClassName.ts +0 -7
  437. /package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +0 -0
  438. /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
  439. /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
  440. /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
  441. /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
  442. /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
  443. /package/dist/types/src/components/{Menus → Menu}/index.d.ts +0 -0
  444. /package/src/components/{Buttons → Button}/Toggle.tsx +0 -0
  445. /package/src/components/{Buttons → Button}/index.ts +0 -0
  446. /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
  447. /package/src/components/{Lists → List}/index.ts +0 -0
  448. /package/src/components/{Menus → Menu}/index.ts +0 -0
@@ -0,0 +1,113 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { IconBase, type IconProps, type IconWeight } from '@phosphor-icons/react';
6
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
+ import React, { type FC, type ReactElement, type SVGProps, forwardRef } from 'react';
8
+
9
+ import { getSize, mx } from '@dxos/ui-theme';
10
+
11
+ import { withTheme } from '../../testing';
12
+
13
+ import { Icon } from './Icon';
14
+
15
+ /**
16
+ * Create icon from serializable data.
17
+ * https://github.com/phosphor-icons/react#custom-icons
18
+ * https://github.com/phosphor-icons/core/tree/main/assets
19
+ */
20
+ const createIcon = ({
21
+ name,
22
+ weights,
23
+ }: {
24
+ name: string;
25
+ weights: Record<string, SVGProps<SVGPathElement>[]>;
26
+ }): FC<IconProps> => {
27
+ const CustomIcon = forwardRef<SVGSVGElement, IconProps>((props, ref) => (
28
+ <IconBase
29
+ ref={ref}
30
+ {...props}
31
+ weights={
32
+ new Map<IconWeight, ReactElement>(
33
+ Object.entries(weights).map(
34
+ ([key, paths]) =>
35
+ [
36
+ key,
37
+ <>
38
+ {paths.map((props, i) => (
39
+ <path key={`${key}-${i}`} {...props} />
40
+ ))}
41
+ </>,
42
+ ] as [IconWeight, ReactElement],
43
+ ),
44
+ )
45
+ }
46
+ />
47
+ ));
48
+
49
+ CustomIcon.displayName = name;
50
+ return CustomIcon;
51
+ };
52
+
53
+ const DefaultStory = ({ CustomIcon }: { CustomIcon: FC<IconProps> }) => {
54
+ return (
55
+ <div className='grid grid-cols-2 gap-8'>
56
+ <CustomIcon weight={'regular'} className={mx(getSize(16))} />
57
+ <Icon icon='ph--github-logo--regular' classNames={mx(getSize(16))} />
58
+ </div>
59
+ );
60
+ };
61
+
62
+ const meta = {
63
+ title: 'ui/react-ui-core/components/Icon',
64
+ render: DefaultStory,
65
+ decorators: [withTheme()],
66
+ parameters: {
67
+ layout: 'centered',
68
+ },
69
+ } satisfies Meta<typeof DefaultStory>;
70
+
71
+ export default meta;
72
+
73
+ type Story = StoryObj<typeof meta>;
74
+
75
+ export const Default: Story = {
76
+ args: {
77
+ CustomIcon: createIcon({
78
+ name: 'GithubLogo',
79
+ weights: {
80
+ // https://github.com/phosphor-icons/core/tree/main/assets
81
+ // <path d="M119.83,56A52,52,0,0,0,76,32a51.92,51.92,0,0,0-3.49,44.7A49.28,49.28,0,0,0,64,104v8a48,48,0,0,0,48,48h48a48,48,0,0,0,48-48v-8a49.28,49.28,0,0,0-8.51-27.3A51.92,51.92,0,0,0,196,32a52,52,0,0,0-43.83,24Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
82
+ // <path d="M104,232V192a32,32,0,0,1,32-32h0a32,32,0,0,1,32,32v40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
83
+ // <path d="M104,208H72a32,32,0,0,1-32-32A32,32,0,0,0,8,144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
84
+ regular: [
85
+ {
86
+ d: 'M119.83,56A52,52,0,0,0,76,32a51.92,51.92,0,0,0-3.49,44.7A49.28,49.28,0,0,0,64,104v8a48,48,0,0,0,48,48h48a48,48,0,0,0,48-48v-8a49.28,49.28,0,0,0-8.51-27.3A51.92,51.92,0,0,0,196,32a52,52,0,0,0-43.83,24Z',
87
+ fill: 'none',
88
+ stroke: 'currentColor',
89
+ strokeLinecap: 'round',
90
+ strokeLinejoin: 'round',
91
+ strokeWidth: '16',
92
+ },
93
+ {
94
+ d: 'M104,232V192a32,32,0,0,1,32-32h0a32,32,0,0,1,32,32v40',
95
+ fill: 'none',
96
+ stroke: 'currentColor',
97
+ strokeLinecap: 'round',
98
+ strokeLinejoin: 'round',
99
+ strokeWidth: '16',
100
+ },
101
+ {
102
+ d: 'M104,208H72a32,32,0,0,1-32-32A32,32,0,0,0,8,144',
103
+ fill: 'none',
104
+ stroke: 'currentColor',
105
+ strokeLinecap: 'round',
106
+ strokeLinejoin: 'round',
107
+ strokeWidth: '16',
108
+ },
109
+ ],
110
+ },
111
+ }),
112
+ },
113
+ };
@@ -5,7 +5,7 @@
5
5
  import { type Primitive } from '@radix-ui/react-primitive';
6
6
  import React, { type ComponentPropsWithRef, forwardRef, memo } from 'react';
7
7
 
8
- import { type Size } from '@dxos/react-ui-types';
8
+ import { type Size } from '@dxos/ui-types';
9
9
 
10
10
  import { useIconHref, useThemeContext } from '../../hooks';
11
11
  import { type ThemedClassName } from '../../util';
@@ -16,11 +16,11 @@ export type IconProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.s
16
16
  };
17
17
 
18
18
  export const Icon = memo(
19
- forwardRef<SVGSVGElement, IconProps>(({ icon, classNames, size, ...props }, forwardedRef) => {
19
+ forwardRef<SVGSVGElement, IconProps>(({ icon, classNames, size = 4, ...props }, forwardedRef) => {
20
20
  const { tx } = useThemeContext();
21
21
  const href = useIconHref(icon);
22
22
  return (
23
- <svg {...props} className={tx('icon.root', 'icon', { size }, classNames)} ref={forwardedRef}>
23
+ <svg {...props} className={tx('icon.root', { size }, classNames)} ref={forwardedRef}>
24
24
  <use href={href} />
25
25
  </svg>
26
26
  );
@@ -0,0 +1,86 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useMemo } from 'react';
7
+
8
+ import { faker } from '@dxos/random';
9
+ import { withTheme } from '@dxos/react-ui/testing';
10
+
11
+ import { Image } from './Image';
12
+
13
+ const seed = Math.random();
14
+
15
+ faker.seed(seed);
16
+
17
+ const meta = {
18
+ title: 'ui/react-ui-mosaic/Image',
19
+ component: Image,
20
+ render: (args) => (
21
+ <div className='absolute inset-0 flex justify-center items-center'>
22
+ <Image {...args} />
23
+ </div>
24
+ ),
25
+ decorators: [withTheme()],
26
+ parameters: {
27
+ layout: 'centered',
28
+ },
29
+ } satisfies Meta<typeof Image>;
30
+
31
+ export default meta;
32
+
33
+ type Story = StoryObj<typeof meta>;
34
+
35
+ export const Default: Story = {
36
+ args: {
37
+ src: faker.image.url(),
38
+ },
39
+ };
40
+
41
+ const classNames = 'h-[12rem] w-[18rem]';
42
+
43
+ /**
44
+ * Access to image at 'https://dxos.network/dxos-logotype-blue.png'
45
+ * from origin 'http://localhost:9009' has been blocked by CORS policy:
46
+ * No 'Access-Control-Allow-Origin' header is present on the requested resource.
47
+ */
48
+ export const Cors: Story = {
49
+ args: {
50
+ src: 'https://dxos.network/dxos-logotype-blue.png',
51
+ classNames,
52
+ },
53
+ };
54
+
55
+ export const Corners: Story = {
56
+ args: {
57
+ src: 'https://picsum.photos/seed/picsum/200/200',
58
+ classNames,
59
+ },
60
+ };
61
+
62
+ export const SVG: Story = {
63
+ args: {
64
+ src: 'https://dxos.network/bg-kube.svg',
65
+ classNames,
66
+ },
67
+ };
68
+
69
+ export const Many: Story = {
70
+ args: {
71
+ src: 'https://dxos.network/bg-kube.svg',
72
+ },
73
+ render: () => {
74
+ const images = useMemo(
75
+ () => Array.from({ length: 9 }, (_, i) => `https://picsum.photos/seed/${seed + i}/500/500`),
76
+ [],
77
+ );
78
+ return (
79
+ <div className='w-[60rem] grid grid-cols-3 grid-rows-3 gap-8'>
80
+ {images.map((src, i) => (
81
+ <Image key={i} src={src} classNames={classNames} />
82
+ ))}
83
+ </div>
84
+ );
85
+ },
86
+ };
@@ -0,0 +1,223 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, { type SyntheticEvent, useCallback, useRef, useState } from 'react';
6
+
7
+ import { type ThemedClassName } from '@dxos/react-ui';
8
+ import { mx } from '@dxos/ui-theme';
9
+
10
+ const cache = new Map<string, string>();
11
+
12
+ export type ImageProps = ThemedClassName<
13
+ {
14
+ src: string;
15
+ alt?: string;
16
+ crossOrigin?: 'anonymous' | 'use-credentials' | '';
17
+ } & ColorOptions
18
+ >;
19
+
20
+ // TODO(burdon): Option for neutral background color.
21
+ export const Image = ({
22
+ classNames,
23
+ src,
24
+ alt = '',
25
+ crossOrigin = 'anonymous',
26
+ sampleSize = 64,
27
+ contrast = 0.9,
28
+ }: ImageProps) => {
29
+ const [crossOriginState, setCrossOriginState] = useState<ImageProps['crossOrigin']>(crossOrigin);
30
+ const [dominantColor, setDominantColor] = useState<string | undefined>(undefined);
31
+ const [imageLoaded, setImageLoaded] = useState<boolean>(false);
32
+ const canvasRef = useRef<HTMLCanvasElement>(null);
33
+
34
+ // CORS not supported by server.
35
+ const handleImageError = (): void => {
36
+ setCrossOriginState(undefined);
37
+ };
38
+
39
+ const handleImageLoad = useCallback(
40
+ ({ target }: SyntheticEvent<HTMLImageElement>): void => {
41
+ const rgb = cache.get(src);
42
+ if (rgb) {
43
+ setDominantColor(rgb);
44
+ setImageLoaded(true);
45
+ return;
46
+ }
47
+
48
+ const img = target as HTMLImageElement;
49
+ if (!canvasRef.current) {
50
+ return;
51
+ }
52
+
53
+ try {
54
+ const color = extractDominantColor(canvasRef.current, img, { sampleSize, contrast });
55
+ if (color) {
56
+ const rgb = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
57
+ cache.set(src, rgb);
58
+ setDominantColor(rgb);
59
+ }
60
+ } catch {
61
+ setCrossOriginState(undefined);
62
+ }
63
+
64
+ setImageLoaded(true);
65
+ },
66
+ [sampleSize, contrast, src],
67
+ );
68
+
69
+ return (
70
+ <div
71
+ className={mx(`relative flex w-full justify-center overflow-hidden transition-all duration-700`, classNames)}
72
+ style={{
73
+ backgroundColor: dominantColor,
74
+ }}
75
+ >
76
+ {/* Hidden canvas for color extraction. */}
77
+ <canvas ref={canvasRef} style={{ display: 'none' }} aria-hidden='true' />
78
+
79
+ {/* Background gradient overlay for smooth transition. */}
80
+ <div
81
+ className='absolute inset-0 pointer-events-none'
82
+ style={{
83
+ background: dominantColor
84
+ ? `radial-gradient(circle at center, transparent 30%, ${dominantColor} 100%)`
85
+ : undefined,
86
+ transition: 'opacity 0.7s ease-in-out',
87
+ opacity: 0.5,
88
+ }}
89
+ />
90
+
91
+ <img
92
+ src={src}
93
+ alt={alt}
94
+ crossOrigin={crossOriginState}
95
+ onError={handleImageError}
96
+ onLoad={handleImageLoad}
97
+ className='z-10 object-contain transition-opacity duration-500'
98
+ style={{
99
+ opacity: imageLoaded ? 1 : 0,
100
+ }}
101
+ />
102
+ </div>
103
+ );
104
+ };
105
+
106
+ type ColorOptions = {
107
+ sampleSize?: number;
108
+ contrast?: number;
109
+ };
110
+
111
+ /**
112
+ * Get dominant color from image (esp. from corners).
113
+ */
114
+ const extractDominantColor = (
115
+ canvas: HTMLCanvasElement,
116
+ img: HTMLImageElement,
117
+ { sampleSize = 64, contrast = 0.95 }: ColorOptions,
118
+ ): [number, number, number] | null => {
119
+ const ctx = canvas.getContext('2d');
120
+ if (!ctx) {
121
+ return null;
122
+ }
123
+
124
+ // Draw the image scaled down.
125
+ canvas.width = sampleSize;
126
+ canvas.height = sampleSize;
127
+ ctx.drawImage(img, 0, 0, sampleSize, sampleSize);
128
+
129
+ // Get image data.
130
+ const imageData = ctx.getImageData(0, 0, sampleSize, sampleSize);
131
+ const pixels = imageData.data;
132
+
133
+ // Check for transparent background.
134
+ if (isTransparent(pixels, sampleSize)) {
135
+ return null;
136
+ }
137
+
138
+ let r = 0;
139
+ let g = 0;
140
+ let b = 0;
141
+ let totalWeight = 0;
142
+
143
+ // Define corner sampling areas (e.g., 25% of each dimension from each corner).
144
+ const cornerSize = Math.floor(sampleSize * 0.125);
145
+
146
+ // Sample only pixels in corner areas.
147
+ for (let y = 0; y < sampleSize; y++) {
148
+ for (let x = 0; x < sampleSize; x++) {
149
+ // Check if pixel is in any corner area.
150
+ const isInTopLeft = x < cornerSize && y < cornerSize;
151
+ const isInTopRight = x >= sampleSize - cornerSize && y < cornerSize;
152
+ const isInBottomLeft = x < cornerSize && y >= sampleSize - cornerSize;
153
+ const isInBottomRight = x >= sampleSize - cornerSize && y >= sampleSize - cornerSize;
154
+ if (!isInTopLeft && !isInTopRight && !isInBottomLeft && !isInBottomRight) {
155
+ continue; // Skip pixels not in corner areas.
156
+ }
157
+
158
+ const i = (y * sampleSize + x) * 4;
159
+ const red = pixels[i];
160
+ const green = pixels[i + 1];
161
+ const blue = pixels[i + 2];
162
+ const alpha = pixels[i + 3];
163
+
164
+ // Skip transparent pixels.
165
+ if (alpha === 0) continue;
166
+
167
+ // Calculate saturation to weight vibrant colors more.
168
+ const max = Math.max(red, green, blue);
169
+ const min = Math.min(red, green, blue);
170
+ const saturation = max === 0 ? 0 : (max - min) / max;
171
+ const weight = 1 + saturation * 2;
172
+
173
+ r += red * weight;
174
+ g += green * weight;
175
+ b += blue * weight;
176
+ totalWeight += weight;
177
+ }
178
+ }
179
+
180
+ if (totalWeight > 0) {
181
+ // Slightly darken the color for better contrast.
182
+ r = Math.round(Math.round(r / totalWeight) * contrast);
183
+ g = Math.round(Math.round(g / totalWeight) * contrast);
184
+ b = Math.round(Math.round(b / totalWeight) * contrast);
185
+ return [r, g, b];
186
+ }
187
+
188
+ return null;
189
+ };
190
+
191
+ /**
192
+ * Detects if an image has a transparent background by examining edge pixels.
193
+ * @param pixels - Image pixel data from canvas
194
+ * @param sampleSize - Size of the sampled image
195
+ * @param threshold - Percentage threshold for considering background transparent (default: 0.5)
196
+ * @returns True if the image has a transparent background
197
+ */
198
+ const isTransparent = (pixels: Uint8ClampedArray, sampleSize: number, threshold: number = 0.5): boolean => {
199
+ let edgeTransparentPixels = 0;
200
+ const edgePixels = sampleSize * 4 - 4; // Perimeter minus corners counted twice.
201
+
202
+ for (let x = 0; x < sampleSize; x++) {
203
+ // Top edge.
204
+ const topIndex = x * 4;
205
+ if (pixels[topIndex + 3] === 0) edgeTransparentPixels++;
206
+
207
+ // Bottom edge.
208
+ const bottomIndex = ((sampleSize - 1) * sampleSize + x) * 4;
209
+ if (pixels[bottomIndex + 3] === 0) edgeTransparentPixels++;
210
+ }
211
+
212
+ for (let y = 1; y < sampleSize - 1; y++) {
213
+ // Left edge.
214
+ const leftIndex = y * sampleSize * 4;
215
+ if (pixels[leftIndex + 3] === 0) edgeTransparentPixels++;
216
+
217
+ // Right edge.
218
+ const rightIndex = (y * sampleSize + sampleSize - 1) * 4;
219
+ if (pixels[rightIndex + 3] === 0) edgeTransparentPixels++;
220
+ }
221
+
222
+ return edgeTransparentPixels / edgePixels > threshold;
223
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './Image';
@@ -2,23 +2,21 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { type StoryObj, type Meta } from '@storybook/react-vite';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
- import { baseSurface, modalSurface, activeSurface, mx, surfaceShadow } from '@dxos/react-ui-theme';
11
- import { type MessageValence } from '@dxos/react-ui-types';
8
+ import { type MessageValence } from '@dxos/ui-types';
9
+
10
+ import { withLayoutVariants, withTheme } from '../../testing';
12
11
 
13
12
  import {
14
13
  type CheckboxProps,
15
14
  Input,
16
15
  type PinInputProps,
17
16
  type SwitchProps,
18
- type TextInputProps,
19
17
  type TextAreaProps,
18
+ type TextInputProps,
20
19
  } from './Input';
21
- import { withTheme } from '../../testing';
22
20
 
23
21
  type VariantMap = {
24
22
  text: TextInputProps;
@@ -30,7 +28,7 @@ type VariantMap = {
30
28
 
31
29
  type Variant = { [K in keyof VariantMap]: { type: K } & VariantMap[K] }[keyof VariantMap];
32
30
 
33
- type BaseProps = Partial<{
31
+ type StoryProps = Partial<{
34
32
  kind: keyof VariantMap;
35
33
  label: string;
36
34
  labelVisuallyHidden: boolean;
@@ -40,7 +38,7 @@ type BaseProps = Partial<{
40
38
  validationMessage: string;
41
39
  }>;
42
40
 
43
- const Wrapper = ({
41
+ const DefaultStory = ({
44
42
  kind,
45
43
  label,
46
44
  description,
@@ -49,7 +47,7 @@ const Wrapper = ({
49
47
  validationValence,
50
48
  validationMessage,
51
49
  ...props
52
- }: BaseProps) => {
50
+ }: StoryProps) => {
53
51
  return (
54
52
  <Input.Root {...{ validationValence }}>
55
53
  <Input.Label srOnly={labelVisuallyHidden}>{label}</Input.Label>
@@ -61,49 +59,28 @@ const Wrapper = ({
61
59
  {kind === 'switch' && <Input.Switch {...props} />}
62
60
 
63
61
  <Input.DescriptionAndValidation srOnly={descriptionVisuallyHidden}>
64
- {validationMessage && (
65
- <>
66
- <Input.Validation>{validationMessage}</Input.Validation>{' '}
67
- </>
68
- )}
62
+ {validationMessage && <Input.Validation classNames='block'>{validationMessage}</Input.Validation>}
69
63
  <Input.Description>{description}</Input.Description>
70
64
  </Input.DescriptionAndValidation>
71
65
  </Input.Root>
72
66
  );
73
67
  };
74
68
 
75
- const DefaultStory = (props: BaseProps) => {
76
- return (
77
- <div className='space-b-4'>
78
- <div className={mx(baseSurface, 'p-4')}>
79
- <Wrapper {...props} />
80
- </div>
81
- <div className={mx(activeSurface, 'p-4 rounded-md', surfaceShadow({ elevation: 'positioned' }))}>
82
- <Wrapper {...props} />
83
- </div>
84
- <div className={mx(modalSurface, 'p-4 rounded-md', surfaceShadow({ elevation: 'dialog' }))}>
85
- <Wrapper {...props} />
86
- </div>
87
- </div>
88
- );
89
- };
90
-
91
- const meta: Meta<BaseProps> = {
92
- title: 'ui/react-ui-core/Input',
93
- component: Input.Root,
69
+ const meta = {
70
+ title: 'ui/react-ui-core/components/Input',
71
+ component: Input.Root as any,
94
72
  render: DefaultStory,
95
- decorators: [withTheme],
96
- parameters: { chromatic: { disableSnapshot: false } },
97
- };
73
+ decorators: [withTheme(), withLayoutVariants()],
74
+ } satisfies Meta<typeof DefaultStory>;
98
75
 
99
76
  export default meta;
100
77
 
101
- type Story = StoryObj<BaseProps & Variant>;
78
+ type Story = StoryObj<StoryProps & Variant>;
102
79
 
103
- export const Default: Story = {
80
+ export const DensityCoarse: Story = {
104
81
  args: {
105
82
  kind: 'text',
106
- label: 'Hello',
83
+ label: 'Input value',
107
84
  placeholder: 'This is an input',
108
85
  disabled: false,
109
86
  description: undefined,
@@ -111,13 +88,14 @@ export const Default: Story = {
111
88
  descriptionVisuallyHidden: false,
112
89
  validationMessage: '',
113
90
  validationValence: undefined,
91
+ density: 'coarse',
114
92
  },
115
93
  };
116
94
 
117
95
  export const DensityFine: Story = {
118
96
  args: {
119
97
  kind: 'text',
120
- label: 'This is an Input with a density value of ‘fine’',
98
+ label: 'Input value',
121
99
  placeholder: 'This is a density:fine input',
122
100
  disabled: false,
123
101
  description: undefined,
@@ -132,7 +110,7 @@ export const DensityFine: Story = {
132
110
  export const Subdued: Story = {
133
111
  args: {
134
112
  kind: 'text',
135
- label: 'Hello',
113
+ label: 'Input value',
136
114
  placeholder: 'This is a subdued input',
137
115
  disabled: false,
138
116
  description: undefined,
@@ -162,7 +140,7 @@ export const LabelVisuallyHidden: Story = {
162
140
  },
163
141
  };
164
142
 
165
- export const InputWithDescription: Story = {
143
+ export const WithDescription: Story = {
166
144
  args: {
167
145
  kind: 'text',
168
146
  label: 'Described input',
@@ -171,7 +149,7 @@ export const InputWithDescription: Story = {
171
149
  },
172
150
  };
173
151
 
174
- export const InputWithErrorAndDescription: Story = {
152
+ export const WithErrorAndDescription: Story = {
175
153
  args: {
176
154
  kind: 'text',
177
155
  label: 'Described invalid input',
@@ -182,7 +160,7 @@ export const InputWithErrorAndDescription: Story = {
182
160
  },
183
161
  };
184
162
 
185
- export const InputWithValidationAndDescription: Story = {
163
+ export const WithValidationAndDescription: Story = {
186
164
  args: {
187
165
  kind: 'text',
188
166
  label: 'Described input with validation message',
@@ -208,7 +186,8 @@ export const PinInput: Story = {
208
186
  label: 'This input is a PIN-style input',
209
187
  length: 6,
210
188
  description: 'Type in secret you received',
211
- placeholder: '••••••',
189
+ pattern: '\\d*',
190
+ density: 'coarse',
212
191
  },
213
192
  };
214
193
 
@@ -216,15 +195,15 @@ export const Checkbox: Story = {
216
195
  args: {
217
196
  kind: 'checkbox',
218
197
  label: 'This is a checkbox',
219
- description: 'It’s checked, indeterminate, or unchecked',
198
+ description: 'Checked, indeterminate, or unchecked',
220
199
  size: 5,
221
200
  },
222
201
  };
223
202
 
224
- export const Switch = {
203
+ export const Switch: Story = {
225
204
  args: {
226
205
  kind: 'switch',
227
206
  label: 'This is a switch',
228
- description: 'It’s either off... or on.',
207
+ description: 'On or off',
229
208
  },
230
209
  };