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

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 (293) hide show
  1. package/dist/lib/browser/{chunk-CEKVHJ27.mjs → chunk-EJSGYGYH.mjs} +117 -117
  2. package/dist/lib/browser/chunk-EJSGYGYH.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +2747 -1997
  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 +56 -32
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/{chunk-2NHEX4AD.mjs → chunk-B7MXDDMJ.mjs} +117 -117
  9. package/dist/lib/node-esm/chunk-B7MXDDMJ.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +2747 -1997
  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 +56 -32
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  16. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  18. package/dist/types/src/components/Button/Button.d.ts +2 -2
  19. package/dist/types/src/components/Button/Button.d.ts.map +1 -1
  20. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
  21. package/dist/types/src/components/Button/Toggle.d.ts +2 -2
  22. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -1
  23. package/dist/types/src/components/Button/ToggleGroup.d.ts +6 -6
  24. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
  25. package/dist/types/src/components/Card/Card.d.ts +107 -0
  26. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  27. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  28. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  29. package/dist/types/src/components/Card/index.d.ts +2 -0
  30. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  31. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  32. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  33. package/dist/types/src/components/Dialog/AlertDialog.d.ts +26 -17
  34. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
  35. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/Dialog/Dialog.d.ts +25 -18
  37. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  38. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +3 -6
  39. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  41. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  42. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  43. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  44. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +8 -0
  45. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  46. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  47. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  48. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  49. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  50. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  51. package/dist/types/src/components/Image/Image.d.ts +14 -0
  52. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  53. package/dist/types/src/components/Image/Image.stories.d.ts +33 -0
  54. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  55. package/dist/types/src/components/Image/index.d.ts +2 -0
  56. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  57. package/dist/types/src/components/Input/Input.d.ts +4 -7
  58. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  59. package/dist/types/src/components/Input/Input.stories.d.ts +7 -7
  60. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  61. package/dist/types/src/components/List/List.d.ts.map +1 -1
  62. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  63. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
  64. package/dist/types/src/components/Main/Main.d.ts +6 -32
  65. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  66. package/dist/types/src/components/Main/Main.stories.d.ts +1 -5
  67. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  68. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
  69. package/dist/types/src/components/Menu/DropdownMenu.d.ts +51 -49
  70. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
  71. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +6 -1
  72. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -1
  73. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  74. package/dist/types/src/components/Message/Message.stories.d.ts +2 -3
  75. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  76. package/dist/types/src/components/Popover/Popover.d.ts +28 -22
  77. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  78. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +21 -26
  79. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  80. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +41 -9
  81. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  82. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
  83. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +6 -1
  84. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
  85. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  86. package/dist/types/src/components/Separator/Separator.d.ts +3 -3
  87. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  88. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  89. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  90. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  91. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  92. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  93. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  94. package/dist/types/src/components/Splitter/Splitter.d.ts +32 -0
  95. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  96. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  97. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  98. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  99. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  100. package/dist/types/src/components/Status/Status.stories.d.ts +4 -2
  101. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  102. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  103. package/dist/types/src/components/Tag/Tag.stories.d.ts +0 -5
  104. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  105. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +1 -0
  106. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  107. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  108. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  109. package/dist/types/src/components/Toast/Toast.d.ts +15 -15
  110. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  111. package/dist/types/src/components/Toolbar/Toolbar.d.ts +33 -11
  112. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  113. package/dist/types/src/components/Tooltip/Tooltip.d.ts +9 -9
  114. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  115. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  116. package/dist/types/src/components/index.d.ts +8 -4
  117. package/dist/types/src/components/index.d.ts.map +1 -1
  118. package/dist/types/src/exemplars/generics.stories.d.ts +18 -0
  119. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  120. package/dist/types/src/exemplars/slot.stories.d.ts +14 -0
  121. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  122. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  123. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  124. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  125. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  126. package/dist/types/src/hooks/index.d.ts +1 -0
  127. package/dist/types/src/hooks/index.d.ts.map +1 -1
  128. package/dist/types/src/index.d.ts +1 -0
  129. package/dist/types/src/index.d.ts.map +1 -1
  130. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  131. package/dist/types/src/primitives/Column/Column.d.ts +26 -0
  132. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  133. package/dist/types/src/primitives/Column/Column.stories.d.ts +6 -0
  134. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  135. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  136. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  137. package/dist/types/src/primitives/Container/Container.d.ts +8 -0
  138. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  139. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  140. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  141. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  142. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  143. package/dist/types/src/primitives/Flex/Flex.d.ts +13 -0
  144. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  145. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  146. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  147. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  148. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  149. package/dist/types/src/primitives/Grid/Grid.d.ts +15 -0
  150. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  151. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  152. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  153. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  154. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  155. package/dist/types/src/primitives/Panel/Panel.d.ts +26 -0
  156. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  157. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  158. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  159. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  160. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  161. package/dist/types/src/primitives/index.d.ts +6 -0
  162. package/dist/types/src/primitives/index.d.ts.map +1 -0
  163. package/dist/types/src/testing/Loading.d.ts +9 -0
  164. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  165. package/dist/types/src/testing/decorators/withLayout.d.ts +1 -1
  166. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  167. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
  168. package/dist/types/src/testing/decorators/withTheme.d.ts +3 -2
  169. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  170. package/dist/types/src/testing/index.d.ts +1 -0
  171. package/dist/types/src/testing/index.d.ts.map +1 -1
  172. package/dist/types/src/translations.d.ts +11 -0
  173. package/dist/types/src/translations.d.ts.map +1 -0
  174. package/dist/types/tsconfig.tsbuildinfo +1 -1
  175. package/package.json +25 -21
  176. package/src/components/Avatars/Avatar.stories.tsx +5 -6
  177. package/src/components/Avatars/Avatar.tsx +5 -12
  178. package/src/components/Avatars/AvatarGroup.stories.tsx +2 -2
  179. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +3 -3
  180. package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
  181. package/src/components/Button/Button.stories.tsx +3 -3
  182. package/src/components/Button/Button.tsx +8 -14
  183. package/src/components/Button/IconButton.stories.tsx +4 -4
  184. package/src/components/Button/IconButton.tsx +2 -3
  185. package/src/components/Button/Toggle.stories.tsx +2 -2
  186. package/src/components/Button/Toggle.tsx +4 -4
  187. package/src/components/Button/ToggleGroup.stories.tsx +2 -2
  188. package/src/components/Button/ToggleGroup.tsx +12 -16
  189. package/src/components/Card/Card.stories.tsx +151 -0
  190. package/src/components/Card/Card.tsx +390 -0
  191. package/src/components/Card/index.ts +5 -0
  192. package/src/components/Clipboard/CopyButton.tsx +3 -3
  193. package/src/components/Dialog/AlertDialog.stories.tsx +15 -15
  194. package/src/components/Dialog/AlertDialog.tsx +137 -54
  195. package/src/components/Dialog/Dialog.stories.tsx +40 -15
  196. package/src/components/Dialog/Dialog.tsx +94 -78
  197. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +50 -0
  198. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  199. package/src/components/ErrorFallback/ErrorStack.tsx +80 -0
  200. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  201. package/src/components/ErrorFallback/index.ts +9 -0
  202. package/src/components/Icon/Icon.stories.tsx +2 -2
  203. package/src/components/Icon/Icon.tsx +3 -2
  204. package/src/components/Image/Image.stories.tsx +86 -0
  205. package/src/components/Image/Image.tsx +223 -0
  206. package/src/components/Image/index.ts +5 -0
  207. package/src/components/Input/Input.stories.tsx +20 -39
  208. package/src/components/Input/Input.tsx +24 -69
  209. package/src/components/Link/Link.stories.tsx +2 -2
  210. package/src/components/Link/Link.tsx +2 -2
  211. package/src/components/List/List.stories.tsx +15 -22
  212. package/src/components/List/List.tsx +11 -16
  213. package/src/components/List/ListDropIndicator.tsx +7 -7
  214. package/src/components/List/Tree.stories.tsx +4 -4
  215. package/src/components/List/TreeDropIndicator.tsx +6 -6
  216. package/src/components/List/Treegrid.stories.tsx +3 -3
  217. package/src/components/List/Treegrid.tsx +10 -15
  218. package/src/components/Main/Main.stories.tsx +6 -95
  219. package/src/components/Main/Main.tsx +61 -211
  220. package/src/components/Menu/ContextMenu.stories.tsx +2 -2
  221. package/src/components/Menu/ContextMenu.tsx +9 -33
  222. package/src/components/Menu/DropdownMenu.stories.tsx +2 -2
  223. package/src/components/Menu/DropdownMenu.tsx +56 -50
  224. package/src/components/Message/Message.stories.tsx +25 -10
  225. package/src/components/Message/Message.tsx +17 -29
  226. package/src/components/Popover/Popover.stories.tsx +4 -4
  227. package/src/components/Popover/Popover.tsx +61 -58
  228. package/src/components/ScrollArea/ScrollArea.stories.tsx +152 -76
  229. package/src/components/ScrollArea/ScrollArea.tsx +72 -116
  230. package/src/components/ScrollArea/index.ts +1 -1
  231. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +41 -22
  232. package/src/components/ScrollContainer/ScrollContainer.tsx +18 -13
  233. package/src/components/Select/Select.stories.tsx +2 -2
  234. package/src/components/Select/Select.tsx +11 -27
  235. package/src/components/Separator/Separator.tsx +5 -8
  236. package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
  237. package/src/components/Skeleton/Skeleton.tsx +26 -0
  238. package/src/components/Skeleton/index.ts +5 -0
  239. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  240. package/src/components/Splitter/Splitter.tsx +126 -0
  241. package/src/components/Splitter/index.ts +5 -0
  242. package/src/components/Status/Status.stories.tsx +21 -17
  243. package/src/components/Status/Status.tsx +2 -2
  244. package/src/components/Tag/Tag.stories.tsx +4 -9
  245. package/src/components/Tag/Tag.tsx +2 -7
  246. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +32 -0
  247. package/src/components/ThemeProvider/ThemeProvider.tsx +4 -3
  248. package/src/components/Toast/Toast.stories.tsx +2 -2
  249. package/src/components/Toast/Toast.tsx +22 -41
  250. package/src/components/Toolbar/Toolbar.stories.tsx +2 -2
  251. package/src/components/Toolbar/Toolbar.tsx +166 -21
  252. package/src/components/Tooltip/Tooltip.stories.tsx +15 -13
  253. package/src/components/Tooltip/Tooltip.tsx +18 -18
  254. package/src/components/index.ts +9 -5
  255. package/src/exemplars/generics.stories.tsx +49 -0
  256. package/src/exemplars/slot.stories.tsx +107 -0
  257. package/src/exemplars/tabster.stories.tsx +127 -0
  258. package/src/exemplars/virtualizer.stories.tsx +137 -0
  259. package/src/hooks/index.ts +1 -0
  260. package/src/index.ts +1 -0
  261. package/src/playground/Controls.stories.tsx +3 -10
  262. package/src/playground/Custom.stories.tsx +11 -11
  263. package/src/playground/Typography.stories.tsx +3 -3
  264. package/src/primitives/Column/Column.stories.tsx +78 -0
  265. package/src/primitives/Column/Column.tsx +133 -0
  266. package/src/primitives/Column/index.ts +5 -0
  267. package/src/primitives/Container/Container.stories.tsx +30 -0
  268. package/src/primitives/Container/Container.tsx +22 -0
  269. package/src/primitives/Container/index.ts +5 -0
  270. package/src/primitives/Flex/Flex.stories.tsx +58 -0
  271. package/src/primitives/Flex/Flex.tsx +29 -0
  272. package/src/primitives/Flex/index.ts +5 -0
  273. package/src/primitives/Grid/Grid.stories.tsx +57 -0
  274. package/src/primitives/Grid/Grid.tsx +35 -0
  275. package/src/primitives/Grid/index.ts +5 -0
  276. package/src/primitives/Panel/Panel.stories.tsx +67 -0
  277. package/src/primitives/Panel/Panel.tsx +119 -0
  278. package/src/primitives/Panel/index.ts +5 -0
  279. package/src/primitives/index.ts +9 -0
  280. package/src/testing/Loading.tsx +26 -0
  281. package/src/testing/decorators/withLayout.tsx +21 -7
  282. package/src/testing/decorators/withLayoutVariants.tsx +18 -21
  283. package/src/testing/decorators/withTheme.tsx +19 -17
  284. package/src/testing/index.ts +2 -0
  285. package/src/translations.ts +19 -0
  286. package/dist/lib/browser/chunk-CEKVHJ27.mjs.map +0 -7
  287. package/dist/lib/node-esm/chunk-2NHEX4AD.mjs.map +0 -7
  288. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  289. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  290. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  291. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  292. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  293. package/src/components/AnchoredOverflow/index.ts +0 -5
@@ -0,0 +1,26 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { type ComponentPropsWithRef, forwardRef } from 'react';
6
+
7
+ import { useThemeContext } from '../../hooks';
8
+ import { type ThemedClassName } from '../../util';
9
+
10
+ type SkeletonProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
11
+ variant?: 'default' | 'circle' | 'text';
12
+ };
13
+
14
+ /**
15
+ * A skeleton loading component that displays a placeholder while content is loading.
16
+ */
17
+ const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(
18
+ ({ classNames, variant = 'default', ...props }, forwardedRef) => {
19
+ const { tx } = useThemeContext();
20
+ return <div {...props} className={tx('skeleton.root', { variant }, classNames)} ref={forwardedRef} />;
21
+ },
22
+ );
23
+
24
+ export { Skeleton };
25
+
26
+ export type { SkeletonProps };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './Skeleton';
@@ -0,0 +1,83 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { type ComponentPropsWithoutRef, forwardRef, useState } from 'react';
7
+
8
+ import { Panel } from '../../primitives';
9
+ import { withLayout, withTheme } from '../../testing';
10
+ import { ScrollArea } from '../ScrollArea';
11
+ import { Toolbar } from '../Toolbar';
12
+
13
+ import { Splitter, type SplitterRootProps } from './Splitter';
14
+
15
+ const PanelContent = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<'div'> & { label: string }>(
16
+ ({ label, ...props }, ref) => (
17
+ <div ref={ref} {...props}>
18
+ <Panel.Root>
19
+ <Panel.Toolbar asChild>
20
+ <Toolbar.Root>{label}</Toolbar.Root>
21
+ </Panel.Toolbar>
22
+ <Panel.Content asChild>
23
+ <ScrollArea.Root orientation='vertical'>
24
+ <ScrollArea.Viewport>
25
+ {Array.from({ length: 100 }).map((_, i) => (
26
+ <div key={i} className='p-1'>
27
+ {label}-{i}
28
+ </div>
29
+ ))}
30
+ </ScrollArea.Viewport>
31
+ </ScrollArea.Root>
32
+ </Panel.Content>
33
+ </Panel.Root>
34
+ </div>
35
+ ),
36
+ );
37
+
38
+ const DefaultStory = (props: SplitterRootProps) => {
39
+ const [mode, setMode] = useState(props.mode ?? 'both');
40
+
41
+ return (
42
+ <Panel.Root>
43
+ <Panel.Toolbar asChild>
44
+ <Toolbar.Root>
45
+ <Toolbar.Button onClick={() => setMode('upper')}>A</Toolbar.Button>
46
+ <Toolbar.Button onClick={() => setMode('both')}>A + B</Toolbar.Button>
47
+ <Toolbar.Button onClick={() => setMode('lower')}>B</Toolbar.Button>
48
+ </Toolbar.Root>
49
+ </Panel.Toolbar>
50
+ <Panel.Content asChild>
51
+ <Splitter.Root mode={mode} ratio={props.ratio}>
52
+ <Splitter.Panel asChild position='upper'>
53
+ <PanelContent label='A' />
54
+ </Splitter.Panel>
55
+ <Splitter.Panel asChild position='lower'>
56
+ <PanelContent label='B' />
57
+ </Splitter.Panel>
58
+ </Splitter.Root>
59
+ </Panel.Content>
60
+ </Panel.Root>
61
+ );
62
+ };
63
+
64
+ const meta: Meta<SplitterRootProps> = {
65
+ title: 'ui/react-ui-core/components/Splitter',
66
+ component: Splitter.Root,
67
+ render: DefaultStory,
68
+ decorators: [withTheme(), withLayout({ layout: 'column' })],
69
+ parameters: {
70
+ layout: 'fullscreen',
71
+ },
72
+ };
73
+
74
+ export default meta;
75
+
76
+ type Story = StoryObj<SplitterRootProps>;
77
+
78
+ export const Default: Story = {
79
+ args: {
80
+ mode: 'both',
81
+ ratio: 0.5,
82
+ },
83
+ };
@@ -0,0 +1,126 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { createContextScope } from '@radix-ui/react-context';
6
+ import { Primitive } from '@radix-ui/react-primitive';
7
+ import { Slot } from '@radix-ui/react-slot';
8
+ import React, { forwardRef } from 'react';
9
+
10
+ import { composableProps } from '@dxos/ui-theme';
11
+ import { type SlottableProps } from '@dxos/ui-types';
12
+
13
+ import { useThemeContext } from '../../hooks';
14
+
15
+ type ScopedProps<P> = P & { __scopeSplitter?: any };
16
+
17
+ // TODO(burdon): Enable resize.
18
+ // TODO(burdon): Generalize horizontal/vertical and change to start/end.
19
+ type Mode = 'upper' | 'lower' | 'both';
20
+
21
+ type SplitterContextValue = {
22
+ mode: Mode;
23
+ ratio: number;
24
+ transition: number;
25
+ };
26
+
27
+ const SPLITTER_NAME = 'Splitter';
28
+
29
+ const [createSplitterContext, createSplitterScope] = createContextScope(SPLITTER_NAME);
30
+
31
+ const [SplitterProvider, useSplitterContext] = createSplitterContext<SplitterContextValue>(SPLITTER_NAME);
32
+
33
+ //
34
+ // Root
35
+ //
36
+
37
+ const ROOT_NAME = 'Splitter.Root';
38
+
39
+ type RootProps = SlottableProps<HTMLDivElement, Partial<SplitterContextValue>>;
40
+
41
+ const Root = forwardRef<HTMLDivElement, ScopedProps<RootProps>>(
42
+ ({ __scopeSplitter, asChild, mode = 'upper', ratio = 0.5, transition = 250, children, ...props }, forwardedRef) => {
43
+ const { className, ...rest } = composableProps(props);
44
+ const Comp = asChild ? Slot : Primitive.div;
45
+ const { tx } = useThemeContext();
46
+ return (
47
+ <SplitterProvider scope={__scopeSplitter} mode={mode} ratio={ratio} transition={transition}>
48
+ <Comp role='none' {...rest} ref={forwardedRef} className={tx('splitter.root', {}, className)}>
49
+ {children}
50
+ </Comp>
51
+ </SplitterProvider>
52
+ );
53
+ },
54
+ );
55
+
56
+ Root.displayName = ROOT_NAME;
57
+
58
+ //
59
+ // Panel
60
+ //
61
+
62
+ const PANEL_NAME = 'Splitter.Panel';
63
+
64
+ type PanelProps = SlottableProps<
65
+ HTMLDivElement,
66
+ {
67
+ position: 'upper' | 'lower';
68
+ }
69
+ >;
70
+
71
+ const Panel = forwardRef<HTMLDivElement, ScopedProps<PanelProps>>(
72
+ ({ __scopeSplitter, asChild, children, position, style, ...props }, forwardedRef) => {
73
+ const { className, ...rest } = composableProps(props);
74
+ const Comp = asChild ? Slot : Primitive.div;
75
+ const { mode, ratio, transition } = useSplitterContext(PANEL_NAME, __scopeSplitter);
76
+ const { tx } = useThemeContext();
77
+
78
+ // Calculate position and height based on mode and ratio.
79
+ const isUpper = position === 'upper';
80
+ const top = isUpper ? '0%' : mode === 'upper' ? '100%' : mode === 'lower' ? '0%' : `${ratio * 100}%`;
81
+
82
+ const height = isUpper
83
+ ? mode === 'upper'
84
+ ? '100%'
85
+ : mode === 'lower'
86
+ ? '0%'
87
+ : `${ratio * 100}%`
88
+ : mode === 'lower'
89
+ ? '100%'
90
+ : mode === 'upper'
91
+ ? '0%'
92
+ : `${(1 - ratio) * 100}%`;
93
+
94
+ return (
95
+ <Comp
96
+ role='none'
97
+ {...rest}
98
+ ref={forwardedRef}
99
+ className={tx('splitter.panel', {}, className)}
100
+ style={{
101
+ top,
102
+ height,
103
+ transition: `top ${transition}ms, height ${transition}ms ease-out`,
104
+ ...style,
105
+ }}
106
+ >
107
+ {children}
108
+ </Comp>
109
+ );
110
+ },
111
+ );
112
+
113
+ Panel.displayName = PANEL_NAME;
114
+
115
+ //
116
+ // Splitter
117
+ //
118
+
119
+ const Splitter = {
120
+ Root,
121
+ Panel,
122
+ };
123
+
124
+ export { Splitter, createSplitterScope };
125
+
126
+ export type { Mode as SplitterMode, RootProps as SplitterRootProps, PanelProps as SplitterPanelProps };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './Splitter';
@@ -10,30 +10,34 @@ import { withTheme } from '../../testing';
10
10
  import { Status } from './Status';
11
11
 
12
12
  const meta = {
13
- title: 'ui/react-ui-core/Status',
13
+ title: 'ui/react-ui-core/components/Status',
14
14
  component: Status,
15
- decorators: [withTheme],
15
+ decorators: [withTheme()],
16
16
  } satisfies Meta<typeof Status>;
17
17
 
18
18
  export default meta;
19
19
 
20
20
  type Story = StoryObj<typeof meta>;
21
21
 
22
- export const Normal = (props: any) => {
23
- return (
24
- <div className='m-5 space-b-5'>
25
- <Status classNames='block' progress={0} {...props} />
26
- <Status classNames='block' progress={0.3} {...props} />
27
- <Status classNames='block' progress={0.7} {...props} />
28
- <Status classNames='block' progress={1} {...props} />
29
- </div>
30
- );
22
+ export const Normal: Story = {
23
+ render: (props) => {
24
+ return (
25
+ <div className='m-5 space-b-5'>
26
+ <Status classNames='block' progress={0} {...props} />
27
+ <Status classNames='block' progress={0.3} {...props} />
28
+ <Status classNames='block' progress={0.7} {...props} />
29
+ <Status classNames='block' progress={1} {...props} />
30
+ </div>
31
+ );
32
+ },
31
33
  };
32
34
 
33
- export const Indeterminate = (props: any) => {
34
- return (
35
- <div className='m-5'>
36
- <Status classNames='block' indeterminate {...props} />
37
- </div>
38
- );
35
+ export const Indeterminate: Story = {
36
+ render: (props) => {
37
+ return (
38
+ <div className='m-5'>
39
+ <Status classNames='block' indeterminate {...props} />
40
+ </div>
41
+ );
42
+ },
39
43
  };
@@ -20,12 +20,12 @@ const Status = forwardRef<HTMLSpanElement, StatusProps>(
20
20
  <span
21
21
  role='status'
22
22
  {...props}
23
- className={tx('status.root', 'status', { indeterminate, variant }, classNames)}
23
+ className={tx('status.root', { indeterminate, variant }, classNames)}
24
24
  ref={forwardedRef}
25
25
  >
26
26
  <span
27
27
  role='none'
28
- className={tx('status.bar', 'status__bar', { indeterminate, variant }, classNames)}
28
+ className={tx('status.bar', { indeterminate, variant }, classNames)}
29
29
  {...(!indeterminate && { style: { width: `${Math.round(progress * 100)}%` } })}
30
30
  />
31
31
  {children}
@@ -8,17 +8,17 @@ import React from 'react';
8
8
  import { hues } from '@dxos/ui-theme';
9
9
  import { type ChromaticPalette, type MessageValence } from '@dxos/ui-types';
10
10
 
11
- import { withTheme } from '../../testing';
11
+ import { withLayout, withTheme } from '../../testing';
12
12
 
13
13
  import { Tag } from './Tag';
14
14
 
15
15
  const palettes = ['neutral', 'success', 'info', 'warning', 'error', ...hues] as (ChromaticPalette | MessageValence)[];
16
16
 
17
17
  const meta = {
18
- title: 'ui/react-ui-core/Tag',
18
+ title: 'ui/react-ui-core/components/Tag',
19
19
  component: Tag,
20
20
  render: () => (
21
- <div role='grid' className='grid grid-cols-5 gap-2 max-is-screen-md'>
21
+ <div>
22
22
  {palettes.map((palette) => (
23
23
  <Tag key={palette} palette={palette}>
24
24
  {palette}
@@ -26,12 +26,7 @@ const meta = {
26
26
  ))}
27
27
  </div>
28
28
  ),
29
- decorators: [withTheme],
30
- parameters: {
31
- chromatic: {
32
- disableSnapshot: false,
33
- },
34
- },
29
+ decorators: [withTheme(), withLayout({ layout: 'default' })],
35
30
  } satisfies Meta<typeof Tag>;
36
31
 
37
32
  export default meta;
@@ -19,14 +19,9 @@ export type TagProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.sp
19
19
  export const Tag = forwardRef<HTMLSpanElement, TagProps>(
20
20
  ({ asChild, palette = 'neutral', classNames, ...props }, forwardedRef) => {
21
21
  const { tx } = useThemeContext();
22
- const Root = asChild ? Slot : Primitive.span;
22
+ const Comp = asChild ? Slot : Primitive.span;
23
23
  return (
24
- <Root
25
- {...props}
26
- className={tx('tag.root', 'dx-tag', { palette }, classNames)}
27
- data-hue={palette}
28
- ref={forwardedRef}
29
- />
24
+ <Comp {...props} className={tx('tag.root', { palette }, classNames)} data-hue={palette} ref={forwardedRef} />
30
25
  );
31
26
  },
32
27
  );
@@ -0,0 +1,32 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { useThemeContext } from '../../hooks';
9
+ import { withLayout, withTheme } from '../../testing';
10
+
11
+ import { ThemeProvider } from './ThemeProvider';
12
+
13
+ const meta = {
14
+ title: 'ui/react-ui-core/components/ThemeProvider',
15
+ component: ThemeProvider,
16
+ render: () => {
17
+ const { themeMode, platform } = useThemeContext();
18
+ return (
19
+ <div className='p-4 flex flex-col gap-4'>
20
+ <h1>ThemeProvider</h1>
21
+ <pre className='text-sm text-description'>{JSON.stringify({ themeMode, platform }, null, 2)}</pre>
22
+ </div>
23
+ );
24
+ },
25
+ decorators: [withTheme(), withLayout()],
26
+ } satisfies Meta<typeof ThemeProvider>;
27
+
28
+ export default meta;
29
+
30
+ type Story = StoryObj<typeof meta>;
31
+
32
+ export const Default: Story = {};
@@ -20,6 +20,7 @@ export type ThemeContextValue = {
20
20
  hasIosKeyboard: boolean;
21
21
  safeAreaPadding?: SafeAreaPadding;
22
22
  noCache?: boolean;
23
+ platform?: 'mobile' | 'desktop';
23
24
  };
24
25
 
25
26
  /**
@@ -39,7 +40,7 @@ export const ThemeProvider = ({
39
40
  fallback = null,
40
41
  resourceExtensions,
41
42
  appNs,
42
- tx = (_path, defaultClassName, _styleProps, ..._options) => defaultClassName,
43
+ tx = (_path, _styleProps, ..._options) => undefined,
43
44
  themeMode = 'dark',
44
45
  rootDensity = 'fine',
45
46
  ...rest
@@ -77,8 +78,8 @@ export const ThemeProvider = ({
77
78
 
78
79
  const handleInputModalityChange = (isUsingKeyboard: boolean) => {
79
80
  if (isUsingKeyboard) {
80
- document.body.setAttribute('data-is-keyboard', 'true');
81
+ document.body.setAttribute('data-w-keyboard', 'true');
81
82
  } else {
82
- document.body.removeAttribute('data-is-keyboard');
83
+ document.body.removeAttribute('data-w-keyboard');
83
84
  }
84
85
  };
@@ -45,10 +45,10 @@ const DefaultStory = ({ title, description, actionTriggers, openTrigger, closeTr
45
45
  };
46
46
 
47
47
  const meta = {
48
- title: 'ui/react-ui-core/Toast',
48
+ title: 'ui/react-ui-core/components/Toast',
49
49
  component: Toast as any,
50
50
  render: DefaultStory,
51
- decorators: [withTheme],
51
+ decorators: [withTheme()],
52
52
  } satisfies Meta<typeof DefaultStory>;
53
53
 
54
54
  export default meta;
@@ -4,49 +4,32 @@
4
4
 
5
5
  import { Primitive } from '@radix-ui/react-primitive';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
- import {
8
- ToastAction as ToastActionPrimitive,
9
- type ToastActionProps as ToastActionPrimitiveProps,
10
- ToastClose as ToastClosePrimitive,
11
- type ToastCloseProps as ToastClosePrimitiveProps,
12
- ToastDescription as ToastDescriptionPrimitive,
13
- type ToastDescriptionProps as ToastDescriptionPrimitiveProps,
14
- ToastProvider as ToastProviderPrimitive,
15
- type ToastProviderProps as ToastProviderPrimitiveProps,
16
- Root as ToastRootPrimitive,
17
- type ToastProps as ToastRootPrimitiveProps,
18
- ToastTitle as ToastTitlePrimitive,
19
- type ToastTitleProps as ToastTitlePrimitiveProps,
20
- ToastViewport as ToastViewportPrimitive,
21
- type ToastViewportProps as ToastViewportPrimitiveProps,
22
- } from '@radix-ui/react-toast';
7
+ import * as ToastPrimitive from '@radix-ui/react-toast';
23
8
  import React, { type ComponentPropsWithRef, type FunctionComponent, forwardRef } from 'react';
24
9
 
25
10
  import { useThemeContext } from '../../hooks';
26
11
  import { type ThemedClassName } from '../../util';
27
12
  import { ElevationProvider } from '../ElevationProvider';
28
13
 
29
- type ToastProviderProps = ToastProviderPrimitiveProps;
14
+ type ToastProviderProps = ToastPrimitive.ToastProviderProps;
30
15
 
31
- const ToastProvider: FunctionComponent<ToastProviderProps> = ToastProviderPrimitive;
16
+ const ToastProvider: FunctionComponent<ToastProviderProps> = ToastPrimitive.Provider;
32
17
 
33
- type ToastViewportProps = ThemedClassName<ToastViewportPrimitiveProps>;
18
+ type ToastViewportProps = ThemedClassName<ToastPrimitive.ToastViewportProps>;
34
19
 
35
20
  const ToastViewport = forwardRef<HTMLOListElement, ToastViewportProps>(({ classNames, ...props }, forwardedRef) => {
36
21
  const { tx } = useThemeContext();
37
- return (
38
- <ToastViewportPrimitive className={tx('toast.viewport', 'toast-viewport', {}, classNames)} ref={forwardedRef} />
39
- );
22
+ return <ToastPrimitive.Viewport {...props} className={tx('toast.viewport', {}, classNames)} ref={forwardedRef} />;
40
23
  });
41
24
 
42
- type ToastRootProps = ThemedClassName<ToastRootPrimitiveProps>;
25
+ type ToastRootProps = ThemedClassName<ToastPrimitive.ToastProps>;
43
26
 
44
27
  const ToastRoot = forwardRef<HTMLLIElement, ToastRootProps>(({ classNames, children, ...props }, forwardedRef) => {
45
28
  const { tx } = useThemeContext();
46
29
  return (
47
- <ToastRootPrimitive {...props} className={tx('toast.root', 'toast', {}, classNames)} ref={forwardedRef}>
30
+ <ToastPrimitive.Root {...props} className={tx('toast.root', {}, classNames)} ref={forwardedRef}>
48
31
  <ElevationProvider elevation='toast'>{children}</ElevationProvider>
49
- </ToastRootPrimitive>
32
+ </ToastPrimitive.Root>
50
33
  );
51
34
  });
52
35
 
@@ -54,29 +37,27 @@ type ToastBodyProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.div
54
37
 
55
38
  const ToastBody = forwardRef<HTMLDivElement, ToastBodyProps>(({ asChild, classNames, ...props }, forwardedRef) => {
56
39
  const { tx } = useThemeContext();
57
- const Root = asChild ? Slot : Primitive.div;
58
- return <Root {...props} className={tx('toast.body', 'toast__body', {}, classNames)} ref={forwardedRef} />;
40
+ const Comp = asChild ? Slot : Primitive.div;
41
+ return <Comp {...props} className={tx('toast.body', {}, classNames)} ref={forwardedRef} />;
59
42
  });
60
43
 
61
- type ToastTitleProps = ThemedClassName<ToastTitlePrimitiveProps>;
44
+ type ToastTitleProps = ThemedClassName<ToastPrimitive.ToastTitleProps>;
62
45
 
63
46
  const ToastTitle = forwardRef<HTMLHeadingElement, ToastTitleProps>(
64
47
  ({ asChild, classNames, ...props }, forwardedRef) => {
65
48
  const { tx } = useThemeContext();
66
- const Root = asChild ? Slot : ToastTitlePrimitive;
67
- return <Root {...props} className={tx('toast.title', 'toast__title', {}, classNames)} ref={forwardedRef} />;
49
+ const Comp = asChild ? Slot : ToastPrimitive.Title;
50
+ return <Comp {...props} className={tx('toast.title', {}, classNames)} ref={forwardedRef} />;
68
51
  },
69
52
  );
70
53
 
71
- type ToastDescriptionProps = ThemedClassName<ToastDescriptionPrimitiveProps>;
54
+ type ToastDescriptionProps = ThemedClassName<ToastPrimitive.ToastDescriptionProps>;
72
55
 
73
56
  const ToastDescription = forwardRef<HTMLParagraphElement, ToastDescriptionProps>(
74
57
  ({ asChild, classNames, ...props }, forwardedRef) => {
75
58
  const { tx } = useThemeContext();
76
- const Root = asChild ? Slot : ToastDescriptionPrimitive;
77
- return (
78
- <Root {...props} className={tx('toast.description', 'toast__description', {}, classNames)} ref={forwardedRef} />
79
- );
59
+ const Comp = asChild ? Slot : ToastPrimitive.Description;
60
+ return <Comp {...props} className={tx('toast.description', {}, classNames)} ref={forwardedRef} />;
80
61
  },
81
62
  );
82
63
 
@@ -85,18 +66,18 @@ type ToastActionsProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.
85
66
  const ToastActions = forwardRef<HTMLDivElement, ToastActionsProps>(
86
67
  ({ asChild, classNames, ...props }, forwardedRef) => {
87
68
  const { tx } = useThemeContext();
88
- const Root = asChild ? Slot : Primitive.div;
89
- return <Root {...props} className={tx('toast.actions', 'toast__actions', {}, classNames)} ref={forwardedRef} />;
69
+ const Comp = asChild ? Slot : Primitive.div;
70
+ return <Comp {...props} className={tx('toast.actions', {}, classNames)} ref={forwardedRef} />;
90
71
  },
91
72
  );
92
73
 
93
- type ToastActionProps = ToastActionPrimitiveProps;
74
+ type ToastActionProps = ToastPrimitive.ToastActionProps;
94
75
 
95
- const ToastAction: FunctionComponent<ToastActionProps> = ToastActionPrimitive;
76
+ const ToastAction: FunctionComponent<ToastActionProps> = ToastPrimitive.Action;
96
77
 
97
- type ToastCloseProps = ToastClosePrimitiveProps;
78
+ type ToastCloseProps = ToastPrimitive.ToastCloseProps;
98
79
 
99
- const ToastClose: FunctionComponent<ToastCloseProps> = ToastClosePrimitive;
80
+ const ToastClose: FunctionComponent<ToastCloseProps> = ToastPrimitive.Close;
100
81
 
101
82
  export const Toast = {
102
83
  Provider: ToastProvider,
@@ -69,10 +69,10 @@ const DefaultStory = (props: StorybookToolbarProps) => {
69
69
  };
70
70
 
71
71
  const meta = {
72
- title: 'ui/react-ui-core/Toolbar',
72
+ title: 'ui/react-ui-core/components/Toolbar',
73
73
  component: Toolbar as any,
74
74
  render: DefaultStory,
75
- decorators: [withTheme],
75
+ decorators: [withTheme()],
76
76
  } satisfies Meta<typeof DefaultStory>;
77
77
 
78
78
  export default meta;