@dxos/react-ui 0.8.4-main.d05673bc65 → 0.8.4-main.d9fc60f731

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 (534) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/chunk-5SPBSIWS.mjs +33 -0
  4. package/dist/lib/browser/chunk-5SPBSIWS.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-KVJDKHLF.mjs +1613 -0
  6. package/dist/lib/browser/chunk-KVJDKHLF.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +2982 -1631
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/testing/index.mjs +37 -28
  11. package/dist/lib/browser/testing/index.mjs.map +3 -3
  12. package/dist/lib/browser/translations.mjs +9 -0
  13. package/dist/lib/browser/translations.mjs.map +7 -0
  14. package/dist/lib/node-esm/chunk-5JYHWJDZ.mjs +1615 -0
  15. package/dist/lib/node-esm/chunk-5JYHWJDZ.mjs.map +7 -0
  16. package/dist/lib/node-esm/chunk-FPVTVXND.mjs +35 -0
  17. package/dist/lib/node-esm/chunk-FPVTVXND.mjs.map +7 -0
  18. package/dist/lib/node-esm/index.mjs +2982 -1631
  19. package/dist/lib/node-esm/index.mjs.map +4 -4
  20. package/dist/lib/node-esm/meta.json +1 -1
  21. package/dist/lib/node-esm/testing/index.mjs +37 -28
  22. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  23. package/dist/lib/node-esm/translations.mjs +10 -0
  24. package/dist/lib/node-esm/translations.mjs.map +7 -0
  25. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  26. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  27. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Avatars/Avatar.theme.d.ts +11 -0
  29. package/dist/types/src/components/Avatars/Avatar.theme.d.ts.map +1 -0
  30. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts +5 -1
  32. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  33. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/Breadcrumb/Breadcrumb.theme.d.ts +4 -0
  35. package/dist/types/src/components/Breadcrumb/Breadcrumb.theme.d.ts.map +1 -0
  36. package/dist/types/src/components/Button/Button.d.ts +3 -3
  37. package/dist/types/src/components/Button/Button.d.ts.map +1 -1
  38. package/dist/types/src/components/Button/Button.stories.d.ts +1 -1
  39. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/Button/Button.theme.d.ts +11 -0
  41. package/dist/types/src/components/Button/Button.theme.d.ts.map +1 -0
  42. package/dist/types/src/components/Button/IconButton.d.ts +1 -0
  43. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
  44. package/dist/types/src/components/Button/IconButton.stories.d.ts +4 -0
  45. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/Button/IconButton.theme.d.ts +8 -0
  47. package/dist/types/src/components/Button/IconButton.theme.d.ts.map +1 -0
  48. package/dist/types/src/components/Button/Toggle.d.ts +2 -2
  49. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -1
  50. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -1
  51. package/dist/types/src/components/Button/ToggleGroup.d.ts +6 -6
  52. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
  53. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +2 -2
  54. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -1
  55. package/dist/types/src/components/Calendar/Calendar.d.ts +33 -0
  56. package/dist/types/src/components/Calendar/Calendar.d.ts.map +1 -0
  57. package/dist/types/src/components/Calendar/Calendar.stories.d.ts +9 -0
  58. package/dist/types/src/components/Calendar/Calendar.stories.d.ts.map +1 -0
  59. package/dist/types/src/components/Calendar/Calendar.theme.d.ts +4 -0
  60. package/dist/types/src/components/Calendar/Calendar.theme.d.ts.map +1 -0
  61. package/dist/types/src/components/Calendar/index.d.ts +2 -0
  62. package/dist/types/src/components/Calendar/index.d.ts.map +1 -0
  63. package/dist/types/src/components/Card/Card.d.ts +92 -68
  64. package/dist/types/src/components/Card/Card.d.ts.map +1 -1
  65. package/dist/types/src/components/Card/Card.stories.d.ts +3 -2
  66. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -1
  67. package/dist/types/src/components/Card/Card.theme.d.ts +12 -0
  68. package/dist/types/src/components/Card/Card.theme.d.ts.map +1 -0
  69. package/dist/types/src/components/Carousel/Carousel.d.ts +102 -0
  70. package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -0
  71. package/dist/types/src/components/Carousel/index.d.ts +2 -0
  72. package/dist/types/src/components/Carousel/index.d.ts.map +1 -0
  73. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  74. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  75. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  76. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  77. package/dist/types/src/components/Column/Column.d.ts +33 -0
  78. package/dist/types/src/components/Column/Column.d.ts.map +1 -0
  79. package/dist/types/src/components/Column/Column.stories.d.ts +25 -0
  80. package/dist/types/src/components/Column/Column.stories.d.ts.map +1 -0
  81. package/dist/types/src/components/Column/Column.theme.d.ts +9 -0
  82. package/dist/types/src/components/Column/Column.theme.d.ts.map +1 -0
  83. package/dist/types/src/components/Column/index.d.ts +3 -0
  84. package/dist/types/src/components/Column/index.d.ts.map +1 -0
  85. package/dist/types/src/components/Column/withColumn.d.ts +21 -0
  86. package/dist/types/src/components/Column/withColumn.d.ts.map +1 -0
  87. package/dist/types/src/components/DatePicker/DatePicker.d.ts +72 -0
  88. package/dist/types/src/components/DatePicker/DatePicker.d.ts.map +1 -0
  89. package/dist/types/src/components/DatePicker/DatePicker.stories.d.ts +10 -0
  90. package/dist/types/src/components/DatePicker/DatePicker.stories.d.ts.map +1 -0
  91. package/dist/types/src/components/DatePicker/DatePicker.theme.d.ts +6 -0
  92. package/dist/types/src/components/DatePicker/DatePicker.theme.d.ts.map +1 -0
  93. package/dist/types/src/components/DatePicker/index.d.ts +2 -0
  94. package/dist/types/src/components/DatePicker/index.d.ts.map +1 -0
  95. package/dist/types/src/components/Dialog/AlertDialog.d.ts +43 -32
  96. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
  97. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
  98. package/dist/types/src/components/Dialog/Dialog.d.ts +51 -32
  99. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  100. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +3 -2
  101. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
  102. package/dist/types/src/components/Dialog/Dialog.theme.d.ts +10 -0
  103. package/dist/types/src/components/Dialog/Dialog.theme.d.ts.map +1 -0
  104. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -1
  105. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -1
  106. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +14 -3
  107. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -1
  108. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -1
  109. package/dist/types/src/components/Focus/Focus.d.ts +36 -0
  110. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  111. package/dist/types/src/{primitives/Column/Column.stories.d.ts → components/Focus/Focus.stories.d.ts} +4 -1
  112. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  113. package/dist/types/src/components/Focus/Focus.theme.d.ts +6 -0
  114. package/dist/types/src/components/Focus/Focus.theme.d.ts.map +1 -0
  115. package/dist/types/src/components/Focus/index.d.ts +2 -0
  116. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  117. package/dist/types/src/components/Icon/Icon.d.ts +4 -0
  118. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  119. package/dist/types/src/components/Icon/Icon.stories.d.ts +11 -3
  120. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/Icon/Icon.theme.d.ts +11 -0
  122. package/dist/types/src/components/Icon/Icon.theme.d.ts.map +1 -0
  123. package/dist/types/src/components/Icon/IconBlock.d.ts +15 -0
  124. package/dist/types/src/components/Icon/IconBlock.d.ts.map +1 -0
  125. package/dist/types/src/components/Icon/index.d.ts +1 -0
  126. package/dist/types/src/components/Icon/index.d.ts.map +1 -1
  127. package/dist/types/src/components/Image/Image.d.ts +2 -1
  128. package/dist/types/src/components/Image/Image.d.ts.map +1 -1
  129. package/dist/types/src/components/Image/Image.stories.d.ts +3 -2
  130. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -1
  131. package/dist/types/src/components/Input/Input.d.ts +90 -15
  132. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  133. package/dist/types/src/components/Input/Input.stories.d.ts +17 -6
  134. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  135. package/dist/types/src/components/Input/Input.theme.d.ts +115 -0
  136. package/dist/types/src/components/Input/Input.theme.d.ts.map +1 -0
  137. package/dist/types/src/components/Input/SegmentedInput.d.ts +79 -0
  138. package/dist/types/src/components/Input/SegmentedInput.d.ts.map +1 -0
  139. package/dist/types/src/components/Input/constants.d.ts +2 -0
  140. package/dist/types/src/components/Input/constants.d.ts.map +1 -0
  141. package/dist/types/src/components/Input/index.d.ts +2 -0
  142. package/dist/types/src/components/Input/index.d.ts.map +1 -1
  143. package/dist/types/src/components/Link/Link.d.ts.map +1 -1
  144. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  145. package/dist/types/src/components/Link/Link.theme.d.ts +6 -0
  146. package/dist/types/src/components/Link/Link.theme.d.ts.map +1 -0
  147. package/dist/types/src/components/List/List.d.ts +5 -3
  148. package/dist/types/src/components/List/List.d.ts.map +1 -1
  149. package/dist/types/src/components/List/List.stories.d.ts +3 -1
  150. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  151. package/dist/types/src/components/List/List.theme.d.ts +7 -0
  152. package/dist/types/src/components/List/List.theme.d.ts.map +1 -0
  153. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -1
  154. package/dist/types/src/components/List/Tree.d.ts +2 -2
  155. package/dist/types/src/components/List/Tree.d.ts.map +1 -1
  156. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -1
  157. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -1
  158. package/dist/types/src/components/List/Treegrid.d.ts +6 -10
  159. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
  160. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -1
  161. package/dist/types/src/components/List/Treegrid.theme.d.ts +7 -0
  162. package/dist/types/src/components/List/Treegrid.theme.d.ts.map +1 -0
  163. package/dist/types/src/components/Main/Main.d.ts +9 -5
  164. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  165. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  166. package/dist/types/src/components/Main/Main.theme.d.ts +20 -0
  167. package/dist/types/src/components/Main/Main.theme.d.ts.map +1 -0
  168. package/dist/types/src/components/Main/constants.d.ts +3 -0
  169. package/dist/types/src/components/Main/constants.d.ts.map +1 -0
  170. package/dist/types/src/components/Main/index.d.ts +1 -0
  171. package/dist/types/src/components/Main/index.d.ts.map +1 -1
  172. package/dist/types/src/components/Main/useSwipeToDismiss.d.ts.map +1 -1
  173. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts +43 -0
  174. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts.map +1 -0
  175. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts +16 -0
  176. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts.map +1 -0
  177. package/dist/types/src/components/MediaPlayer/index.d.ts +2 -0
  178. package/dist/types/src/components/MediaPlayer/index.d.ts.map +1 -0
  179. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
  180. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -1
  181. package/dist/types/src/components/Menu/DropdownMenu.d.ts +58 -49
  182. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
  183. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +14 -1
  184. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -1
  185. package/dist/types/src/components/Menu/Menu.theme.d.ts +7 -0
  186. package/dist/types/src/components/Menu/Menu.theme.d.ts.map +1 -0
  187. package/dist/types/src/components/Message/Message.d.ts +3 -3
  188. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  189. package/dist/types/src/components/Message/Message.stories.d.ts +6 -2
  190. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  191. package/dist/types/src/components/Message/Message.theme.d.ts +7 -0
  192. package/dist/types/src/components/Message/Message.theme.d.ts.map +1 -0
  193. package/dist/types/src/components/Panel/Panel.d.ts +35 -0
  194. package/dist/types/src/components/Panel/Panel.d.ts.map +1 -0
  195. package/dist/types/src/components/Panel/Panel.stories.d.ts.map +1 -0
  196. package/dist/types/src/components/Panel/Panel.theme.d.ts +13 -0
  197. package/dist/types/src/components/Panel/Panel.theme.d.ts.map +1 -0
  198. package/dist/types/src/components/Panel/index.d.ts.map +1 -0
  199. package/dist/types/src/components/Popover/Popover.d.ts +38 -22
  200. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  201. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  202. package/dist/types/src/components/Popover/Popover.theme.d.ts +8 -0
  203. package/dist/types/src/components/Popover/Popover.theme.d.ts.map +1 -0
  204. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +12 -9
  205. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  206. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +18 -5
  207. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  208. package/dist/types/src/components/ScrollArea/ScrollArea.theme.d.ts +17 -0
  209. package/dist/types/src/components/ScrollArea/ScrollArea.theme.d.ts.map +1 -0
  210. package/dist/types/src/components/ScrollArea/index.d.ts +1 -0
  211. package/dist/types/src/components/ScrollArea/index.d.ts.map +1 -1
  212. package/dist/types/src/components/ScrollArea/scrollbar.d.ts +18 -0
  213. package/dist/types/src/components/ScrollArea/scrollbar.d.ts.map +1 -0
  214. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +41 -18
  215. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
  216. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +5 -6
  217. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
  218. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  219. package/dist/types/src/components/Select/Select.stories.d.ts +2 -2
  220. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  221. package/dist/types/src/components/Select/Select.theme.d.ts +6 -0
  222. package/dist/types/src/components/Select/Select.theme.d.ts.map +1 -0
  223. package/dist/types/src/components/Separator/Separator.d.ts +3 -3
  224. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  225. package/dist/types/src/components/Separator/Separator.theme.d.ts +7 -0
  226. package/dist/types/src/components/Separator/Separator.theme.d.ts.map +1 -0
  227. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -1
  228. package/dist/types/src/components/Skeleton/Skeleton.theme.d.ts +6 -0
  229. package/dist/types/src/components/Skeleton/Skeleton.theme.d.ts.map +1 -0
  230. package/dist/types/src/components/Splitter/Splitter.d.ts +18 -18
  231. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -1
  232. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -1
  233. package/dist/types/src/components/Splitter/Splitter.theme.d.ts +4 -0
  234. package/dist/types/src/components/Splitter/Splitter.theme.d.ts.map +1 -0
  235. package/dist/types/src/components/Status/Status.d.ts +3 -4
  236. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  237. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  238. package/dist/types/src/components/Status/Status.theme.d.ts +7 -0
  239. package/dist/types/src/components/Status/Status.theme.d.ts.map +1 -0
  240. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  241. package/dist/types/src/components/Tag/Tag.theme.d.ts +6 -0
  242. package/dist/types/src/components/Tag/Tag.theme.d.ts.map +1 -0
  243. package/dist/types/src/components/Toast/Toast.d.ts +23 -20
  244. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  245. package/dist/types/src/components/Toast/Toast.stories.d.ts +5 -2
  246. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  247. package/dist/types/src/components/Toast/Toast.theme.d.ts +4 -0
  248. package/dist/types/src/components/Toast/Toast.theme.d.ts.map +1 -0
  249. package/dist/types/src/components/Toolbar/Toolbar.d.ts +30 -26
  250. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  251. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  252. package/dist/types/src/components/Toolbar/Toolbar.theme.d.ts +8 -0
  253. package/dist/types/src/components/Toolbar/Toolbar.theme.d.ts.map +1 -0
  254. package/dist/types/src/components/Tooltip/Tooltip.d.ts +16 -16
  255. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  256. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -2
  257. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  258. package/dist/types/src/components/Tooltip/Tooltip.theme.d.ts +6 -0
  259. package/dist/types/src/components/Tooltip/Tooltip.theme.d.ts.map +1 -0
  260. package/dist/types/src/components/Tooltip/index.d.ts +1 -0
  261. package/dist/types/src/components/Tooltip/index.d.ts.map +1 -1
  262. package/dist/types/src/components/Tooltip/tooltipContent.d.ts +4 -0
  263. package/dist/types/src/components/Tooltip/tooltipContent.d.ts.map +1 -0
  264. package/dist/types/src/components/index.d.ts +8 -4
  265. package/dist/types/src/components/index.d.ts.map +1 -1
  266. package/dist/types/src/exemplars/generics.stories.d.ts +6 -5
  267. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -1
  268. package/dist/types/src/exemplars/slot.stories.d.ts +1 -0
  269. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -1
  270. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -1
  271. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -1
  272. package/dist/types/src/hooks/index.d.ts +1 -0
  273. package/dist/types/src/hooks/index.d.ts.map +1 -1
  274. package/dist/types/src/hooks/useDensityContext.d.ts +1 -1
  275. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  276. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  277. package/dist/types/src/hooks/useIconHref.d.ts.map +1 -1
  278. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  279. package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -1
  280. package/dist/types/src/hooks/useTranslationsContext.d.ts +1 -1
  281. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  282. package/dist/types/src/index.d.ts +1 -0
  283. package/dist/types/src/index.d.ts.map +1 -1
  284. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  285. package/dist/types/src/playground/Custom.stories.d.ts +1 -1
  286. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  287. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  288. package/dist/types/src/primitives/Container/Container.d.ts +4 -5
  289. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -1
  290. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -1
  291. package/dist/types/src/{components → primitives}/DensityProvider/DensityProvider.d.ts.map +1 -1
  292. package/dist/types/src/primitives/DensityProvider/index.d.ts.map +1 -0
  293. package/dist/types/src/{components → primitives}/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  294. package/dist/types/src/primitives/ElevationProvider/index.d.ts.map +1 -0
  295. package/dist/types/src/primitives/Flex/Flex.d.ts +5 -7
  296. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -1
  297. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -1
  298. package/dist/types/src/primitives/Grid/Grid.d.ts +3 -8
  299. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -1
  300. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -1
  301. package/dist/types/src/{components → primitives}/ThemeProvider/ThemeProvider.d.ts +1 -1
  302. package/dist/types/src/{components → primitives}/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  303. package/dist/types/src/{components → primitives}/ThemeProvider/ThemeProvider.stories.d.ts +1 -1
  304. package/dist/types/src/primitives/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  305. package/dist/types/src/primitives/ThemeProvider/TranslationsProvider.d.ts +128 -0
  306. package/dist/types/src/primitives/ThemeProvider/TranslationsProvider.d.ts.map +1 -0
  307. package/dist/types/src/primitives/ThemeProvider/index.d.ts +4 -0
  308. package/dist/types/src/primitives/ThemeProvider/index.d.ts.map +1 -0
  309. package/dist/types/src/primitives/index.d.ts +3 -2
  310. package/dist/types/src/primitives/index.d.ts.map +1 -1
  311. package/dist/types/src/testing/Loading.d.ts.map +1 -1
  312. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  313. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
  314. package/dist/types/src/testing/decorators/withTheme.d.ts +6 -2
  315. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  316. package/dist/types/src/theme/bindTheme.d.ts +3 -0
  317. package/dist/types/src/theme/bindTheme.d.ts.map +1 -0
  318. package/dist/types/src/theme/defaultTheme.d.ts +4 -0
  319. package/dist/types/src/theme/defaultTheme.d.ts.map +1 -0
  320. package/dist/types/src/theme/index.d.ts +31 -0
  321. package/dist/types/src/theme/index.d.ts.map +1 -0
  322. package/dist/types/src/translations.d.ts +17 -3
  323. package/dist/types/src/translations.d.ts.map +1 -1
  324. package/dist/types/src/util/index.d.ts +2 -1
  325. package/dist/types/src/util/index.d.ts.map +1 -1
  326. package/dist/types/src/util/mobile.d.ts +5 -0
  327. package/dist/types/src/util/mobile.d.ts.map +1 -0
  328. package/dist/types/src/util/slots.d.ts +57 -0
  329. package/dist/types/src/util/slots.d.ts.map +1 -0
  330. package/dist/types/src/util/usePx.d.ts.map +1 -1
  331. package/dist/types/tsconfig.tsbuildinfo +1 -1
  332. package/package.json +31 -26
  333. package/src/components/Avatars/Avatar.stories.tsx +2 -3
  334. package/src/components/Avatars/Avatar.theme.ts +93 -0
  335. package/src/components/Avatars/Avatar.tsx +1 -2
  336. package/src/components/Avatars/AvatarGroup.stories.tsx +0 -1
  337. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -2
  338. package/src/components/Breadcrumb/Breadcrumb.theme.ts +26 -0
  339. package/src/components/Breadcrumb/Breadcrumb.tsx +14 -2
  340. package/src/components/Button/Button.stories.tsx +0 -1
  341. package/src/components/Button/Button.theme.ts +31 -0
  342. package/src/components/Button/Button.tsx +6 -14
  343. package/src/components/Button/IconButton.stories.tsx +56 -6
  344. package/src/components/Button/IconButton.theme.ts +21 -0
  345. package/src/components/Button/IconButton.tsx +3 -4
  346. package/src/components/Button/Toggle.stories.tsx +0 -1
  347. package/src/components/Button/Toggle.tsx +4 -4
  348. package/src/components/Button/ToggleGroup.stories.tsx +0 -1
  349. package/src/components/Button/ToggleGroup.tsx +12 -16
  350. package/src/components/Calendar/Calendar.stories.tsx +43 -0
  351. package/src/components/Calendar/Calendar.theme.ts +74 -0
  352. package/src/components/Calendar/Calendar.tsx +196 -0
  353. package/src/components/Calendar/index.ts +5 -0
  354. package/src/components/Card/Card.stories.tsx +55 -34
  355. package/src/components/Card/Card.theme.ts +93 -0
  356. package/src/components/Card/Card.tsx +297 -156
  357. package/src/components/Carousel/Carousel.tsx +371 -0
  358. package/src/components/Carousel/index.ts +5 -0
  359. package/src/components/Clipboard/CopyButton.tsx +6 -7
  360. package/src/components/Column/AUDIT.md +148 -0
  361. package/src/components/Column/Column.stories.tsx +181 -0
  362. package/src/components/Column/Column.theme.ts +48 -0
  363. package/src/components/Column/Column.tsx +166 -0
  364. package/src/{primitives → components}/Column/index.ts +1 -0
  365. package/src/components/Column/withColumn.ts +27 -0
  366. package/src/components/DatePicker/DatePicker.stories.tsx +102 -0
  367. package/src/components/DatePicker/DatePicker.theme.ts +35 -0
  368. package/src/components/DatePicker/DatePicker.tsx +279 -0
  369. package/src/components/DatePicker/index.ts +5 -0
  370. package/src/components/Dialog/AlertDialog.stories.tsx +5 -6
  371. package/src/components/Dialog/AlertDialog.tsx +72 -132
  372. package/src/components/Dialog/Dialog.stories.tsx +65 -10
  373. package/src/components/Dialog/Dialog.theme.ts +61 -0
  374. package/src/components/Dialog/Dialog.tsx +124 -99
  375. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +3 -8
  376. package/src/components/ErrorFallback/ErrorFallback.tsx +14 -8
  377. package/src/components/ErrorFallback/ErrorStack.tsx +48 -8
  378. package/src/components/Focus/AUDIT.md +43 -0
  379. package/src/components/Focus/Focus.stories.tsx +230 -0
  380. package/src/components/Focus/Focus.theme.ts +32 -0
  381. package/src/components/Focus/Focus.tsx +201 -0
  382. package/src/components/Focus/index.ts +5 -0
  383. package/src/components/Icon/Icon.stories.tsx +43 -13
  384. package/src/components/Icon/Icon.theme.ts +45 -0
  385. package/src/components/Icon/Icon.tsx +14 -3
  386. package/src/components/Icon/IconBlock.tsx +38 -0
  387. package/src/components/Icon/index.ts +1 -0
  388. package/src/components/Image/Image.stories.tsx +4 -4
  389. package/src/components/Image/Image.tsx +31 -8
  390. package/src/components/Input/Input.stories.tsx +135 -33
  391. package/src/components/Input/Input.theme.ts +191 -0
  392. package/src/components/Input/Input.tsx +214 -9
  393. package/src/components/Input/SegmentedInput.tsx +454 -0
  394. package/src/components/Input/constants.ts +5 -0
  395. package/src/components/Input/index.ts +2 -0
  396. package/src/components/Link/Link.stories.tsx +0 -1
  397. package/src/components/Link/Link.theme.ts +16 -0
  398. package/src/components/Link/Link.tsx +10 -2
  399. package/src/components/List/List.stories.tsx +1 -2
  400. package/src/components/List/List.theme.ts +47 -0
  401. package/src/components/List/List.tsx +8 -7
  402. package/src/components/List/ListDropIndicator.tsx +1 -2
  403. package/src/components/List/Tree.stories.tsx +2 -3
  404. package/src/components/List/Tree.tsx +0 -1
  405. package/src/components/List/TreeDropIndicator.tsx +3 -3
  406. package/src/components/List/Treegrid.stories.tsx +26 -27
  407. package/src/components/List/Treegrid.theme.ts +35 -0
  408. package/src/components/List/Treegrid.tsx +15 -16
  409. package/src/components/Main/Main.stories.tsx +0 -1
  410. package/src/components/Main/Main.theme.ts +29 -0
  411. package/src/components/Main/Main.tsx +10 -9
  412. package/src/components/Main/constants.ts +6 -0
  413. package/src/components/Main/index.ts +1 -0
  414. package/src/components/MediaPlayer/MediaPlayer.stories.tsx +50 -0
  415. package/src/components/MediaPlayer/MediaPlayer.tsx +178 -0
  416. package/src/components/MediaPlayer/index.ts +5 -0
  417. package/src/components/Menu/ContextMenu.stories.tsx +0 -4
  418. package/src/components/Menu/DropdownMenu.stories.tsx +0 -4
  419. package/src/components/Menu/DropdownMenu.tsx +63 -57
  420. package/src/components/Menu/Menu.theme.ts +48 -0
  421. package/src/components/Message/Message.stories.tsx +48 -11
  422. package/src/components/Message/Message.theme.ts +44 -0
  423. package/src/components/Message/Message.tsx +75 -19
  424. package/src/{primitives → components}/Panel/Panel.stories.tsx +9 -9
  425. package/src/components/Panel/Panel.theme.ts +42 -0
  426. package/src/components/Panel/Panel.tsx +121 -0
  427. package/src/components/Popover/Popover.stories.tsx +4 -5
  428. package/src/components/Popover/Popover.theme.ts +40 -0
  429. package/src/components/Popover/Popover.tsx +49 -49
  430. package/src/components/ScrollArea/ScrollArea.stories.tsx +89 -30
  431. package/src/components/ScrollArea/ScrollArea.theme.ts +107 -0
  432. package/src/components/ScrollArea/ScrollArea.tsx +40 -23
  433. package/src/components/ScrollArea/index.ts +1 -0
  434. package/src/components/ScrollArea/scrollbar.ts +21 -0
  435. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +21 -19
  436. package/src/components/ScrollContainer/ScrollContainer.tsx +215 -106
  437. package/src/components/Select/Select.stories.tsx +5 -6
  438. package/src/components/Select/Select.theme.ts +55 -0
  439. package/src/components/Select/Select.tsx +26 -10
  440. package/src/components/Separator/Separator.theme.ts +23 -0
  441. package/src/components/Separator/Separator.tsx +4 -7
  442. package/src/components/Skeleton/Skeleton.stories.tsx +0 -1
  443. package/src/components/Skeleton/Skeleton.theme.ts +22 -0
  444. package/src/components/Splitter/Splitter.stories.tsx +30 -30
  445. package/src/components/Splitter/Splitter.theme.ts +18 -0
  446. package/src/components/Splitter/Splitter.tsx +36 -40
  447. package/src/components/Status/Status.stories.tsx +0 -1
  448. package/src/components/Status/Status.theme.ts +31 -0
  449. package/src/components/Status/Status.tsx +7 -5
  450. package/src/components/Tag/Tag.stories.tsx +0 -1
  451. package/src/components/Tag/Tag.theme.ts +22 -0
  452. package/src/components/Toast/Toast.stories.tsx +41 -21
  453. package/src/components/Toast/Toast.theme.ts +56 -0
  454. package/src/components/Toast/Toast.tsx +105 -52
  455. package/src/components/Toolbar/Toolbar.stories.tsx +0 -1
  456. package/src/components/Toolbar/Toolbar.theme.ts +36 -0
  457. package/src/components/Toolbar/Toolbar.tsx +83 -46
  458. package/src/components/Tooltip/Tooltip.stories.tsx +7 -17
  459. package/src/components/Tooltip/Tooltip.theme.ts +19 -0
  460. package/src/components/Tooltip/Tooltip.tsx +33 -33
  461. package/src/components/Tooltip/index.ts +1 -0
  462. package/src/components/Tooltip/tooltipContent.ts +16 -0
  463. package/src/components/index.ts +8 -5
  464. package/src/exemplars/generics.stories.tsx +7 -16
  465. package/src/exemplars/slot.stories.tsx +66 -57
  466. package/src/exemplars/tabster.stories.tsx +1 -1
  467. package/src/exemplars/virtualizer.stories.tsx +4 -5
  468. package/src/hooks/index.ts +1 -0
  469. package/src/hooks/useDensityContext.ts +3 -3
  470. package/src/hooks/useElevationContext.ts +1 -1
  471. package/src/hooks/useThemeContext.ts +1 -1
  472. package/src/hooks/useTranslationsContext.ts +1 -1
  473. package/src/index.ts +1 -0
  474. package/src/playground/Custom.stories.tsx +13 -36
  475. package/src/primitives/Container/Container.stories.tsx +0 -1
  476. package/src/primitives/Container/Container.tsx +7 -8
  477. package/src/{components → primitives}/DensityProvider/DensityProvider.tsx +1 -1
  478. package/src/primitives/Flex/Flex.stories.tsx +0 -1
  479. package/src/primitives/Flex/Flex.tsx +12 -12
  480. package/src/primitives/Grid/Grid.stories.tsx +0 -1
  481. package/src/primitives/Grid/Grid.tsx +6 -9
  482. package/src/{components → primitives}/ThemeProvider/ThemeProvider.stories.tsx +1 -2
  483. package/src/{components → primitives}/ThemeProvider/ThemeProvider.tsx +6 -5
  484. package/src/{components → primitives}/ThemeProvider/index.ts +2 -2
  485. package/src/primitives/index.ts +4 -2
  486. package/src/testing/Loading.tsx +25 -4
  487. package/src/testing/decorators/withLayout.tsx +7 -17
  488. package/src/testing/decorators/withLayoutVariants.tsx +1 -1
  489. package/src/testing/decorators/withTheme.tsx +23 -12
  490. package/src/theme/bindTheme.ts +13 -0
  491. package/src/theme/defaultTheme.ts +83 -0
  492. package/src/theme/index.ts +37 -0
  493. package/src/translations.ts +17 -3
  494. package/src/util/index.ts +2 -1
  495. package/src/util/mobile.ts +11 -0
  496. package/src/util/slots.ts +129 -0
  497. package/src/util/usePx.ts +5 -1
  498. package/dist/lib/browser/chunk-2FKSMWNY.mjs +0 -774
  499. package/dist/lib/browser/chunk-2FKSMWNY.mjs.map +0 -7
  500. package/dist/lib/node-esm/chunk-ZNBLTSHI.mjs +0 -776
  501. package/dist/lib/node-esm/chunk-ZNBLTSHI.mjs.map +0 -7
  502. package/dist/types/src/components/DensityProvider/index.d.ts.map +0 -1
  503. package/dist/types/src/components/ElevationProvider/index.d.ts.map +0 -1
  504. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +0 -1
  505. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +0 -129
  506. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +0 -1
  507. package/dist/types/src/components/ThemeProvider/index.d.ts +0 -4
  508. package/dist/types/src/components/ThemeProvider/index.d.ts.map +0 -1
  509. package/dist/types/src/primitives/Column/Column.d.ts +0 -26
  510. package/dist/types/src/primitives/Column/Column.d.ts.map +0 -1
  511. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +0 -1
  512. package/dist/types/src/primitives/Column/index.d.ts +0 -2
  513. package/dist/types/src/primitives/Column/index.d.ts.map +0 -1
  514. package/dist/types/src/primitives/Panel/Panel.d.ts +0 -26
  515. package/dist/types/src/primitives/Panel/Panel.d.ts.map +0 -1
  516. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +0 -1
  517. package/dist/types/src/primitives/Panel/index.d.ts.map +0 -1
  518. package/dist/types/src/util/hasIosKeyboard.d.ts +0 -2
  519. package/dist/types/src/util/hasIosKeyboard.d.ts.map +0 -1
  520. package/src/primitives/Column/Column.stories.tsx +0 -78
  521. package/src/primitives/Column/Column.tsx +0 -134
  522. package/src/primitives/Panel/Panel.tsx +0 -119
  523. package/src/util/hasIosKeyboard.ts +0 -8
  524. /package/dist/types/src/{primitives → components}/Panel/Panel.stories.d.ts +0 -0
  525. /package/dist/types/src/{primitives → components}/Panel/index.d.ts +0 -0
  526. /package/dist/types/src/{components → primitives}/DensityProvider/DensityProvider.d.ts +0 -0
  527. /package/dist/types/src/{components → primitives}/DensityProvider/index.d.ts +0 -0
  528. /package/dist/types/src/{components → primitives}/ElevationProvider/ElevationProvider.d.ts +0 -0
  529. /package/dist/types/src/{components → primitives}/ElevationProvider/index.d.ts +0 -0
  530. /package/src/{primitives → components}/Panel/index.ts +0 -0
  531. /package/src/{components → primitives}/DensityProvider/index.ts +0 -0
  532. /package/src/{components → primitives}/ElevationProvider/ElevationProvider.tsx +0 -0
  533. /package/src/{components → primitives}/ElevationProvider/index.ts +0 -0
  534. /package/src/{components → primitives}/ThemeProvider/TranslationsProvider.tsx +0 -0
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { createContext } from '@radix-ui/react-context';
6
6
  import React, {
7
- type HTMLAttributes,
8
7
  type PropsWithChildren,
8
+ type RefObject,
9
9
  forwardRef,
10
10
  useCallback,
11
11
  useEffect,
@@ -17,12 +17,14 @@ import React, {
17
17
 
18
18
  import { addEventListener, combine } from '@dxos/async';
19
19
  import { invariant } from '@dxos/invariant';
20
- import { useForwardedRef } from '@dxos/react-hooks';
20
+ import { useMergeRefs } from '@dxos/react-hooks';
21
21
  import { mx } from '@dxos/ui-theme';
22
+ import { type SlottableProps } from '@dxos/ui-types';
22
23
 
24
+ import { composable, composableProps, slottable } from '../../util';
23
25
  import { type ThemedClassName } from '../../util';
24
26
  import { IconButton } from '../Button';
25
- import { ScrollArea } from '../ScrollArea';
27
+ import { ScrollArea, type ScrollAreaRootProps } from '../ScrollArea';
26
28
 
27
29
  const isBottom = (el: HTMLElement | null) => {
28
30
  return !!(el && el.scrollHeight - el.scrollTop === el.clientHeight);
@@ -35,9 +37,15 @@ export interface ScrollController {
35
37
  }
36
38
 
37
39
  type ScrollContainerContextValue = {
38
- scrollToBottom: (behavior?: ScrollBehavior) => void;
39
40
  controller?: ScrollController;
40
41
  pinned?: boolean;
42
+ overflow?: boolean;
43
+ /** Called by Viewport to register/unregister the scroll element. */
44
+ setViewport: (el: HTMLDivElement | null) => void;
45
+ /** Called by Viewport on wheel events to update pinned state. */
46
+ setPinned: (value: boolean) => void;
47
+ /** Called by Viewport on scroll events to update overflow state. */
48
+ setOverflow: (value: boolean) => void;
41
49
  };
42
50
 
43
51
  const [ScrollContainerProvider, useScrollContainerContext] =
@@ -47,108 +55,119 @@ const [ScrollContainerProvider, useScrollContainerContext] =
47
55
  // Root
48
56
  //
49
57
 
50
- type RootProps = ThemedClassName<
51
- PropsWithChildren<{
52
- pin?: boolean;
53
- fade?: boolean;
54
- behavior?: ScrollBehavior;
55
- }>
56
- >;
58
+ type ScrollContainerRootProps = PropsWithChildren<{
59
+ pin?: boolean;
60
+ behavior?: ScrollBehavior;
61
+ }>;
57
62
 
58
63
  /**
59
- * Scroll container that automatically scrolls to the bottom when new content is added.
64
+ * Headless scroll container that provides context for scroll state.
65
+ * Render ScrollContainer.Content and ScrollContainer.Viewport as children.
60
66
  */
61
- const Root = forwardRef<ScrollController, RootProps>(
62
- ({ children, classNames, pin, fade, behavior: behaviorProp = 'smooth' }, forwardedRef) => {
63
- const scrollerRef = useRef<HTMLDivElement>(null);
67
+ const ScrollContainerRoot = forwardRef<ScrollController, ScrollContainerRootProps>(
68
+ ({ children, pin, behavior: behaviorProp = 'smooth' }, forwardedRef) => {
69
+ const scrollerRef = useRef<HTMLDivElement | null>(null);
64
70
  const autoScrollRef = useRef(false);
65
- const [overflow, setOverflow] = useState(false);
66
71
  const [pinned, setPinned] = useState(pin);
72
+ const [overflow, setOverflow] = useState(false);
67
73
 
68
74
  const timeoutRef = useRef<NodeJS.Timeout>(undefined);
69
- const scrollToBottom = useCallback((behavior: ScrollBehavior = behaviorProp) => {
70
- if (scrollerRef.current) {
71
- // Temporarily hide scrollbar to prevent flickering.
72
- autoScrollRef.current = true;
73
- scrollerRef.current.classList.add('scrollbar-none');
74
- scrollerRef.current.scrollTo({
75
- top: scrollerRef.current.scrollHeight,
76
- behavior,
77
- });
78
-
79
- clearTimeout(timeoutRef.current);
80
- if (behavior !== 'instant') {
81
- timeoutRef.current = setTimeout(() => {
82
- scrollerRef.current?.classList.remove('scrollbar-none');
83
- autoScrollRef.current = false;
84
- }, 500);
75
+ const scrollToBottom = useCallback(
76
+ (behavior: ScrollBehavior = behaviorProp) => {
77
+ if (scrollerRef.current) {
78
+ if (behavior !== 'instant') {
79
+ // Temporarily hide scrollbar to prevent flickering during smooth scroll.
80
+ // For instant scrolling we skip this — there's no animation to hide,
81
+ // and adding the class changes element size which re-fires the ResizeObserver.
82
+ autoScrollRef.current = true;
83
+ scrollerRef.current.classList.add('scrollbar-none');
84
+ clearTimeout(timeoutRef.current);
85
+ timeoutRef.current = setTimeout(() => {
86
+ scrollerRef.current?.classList.remove('scrollbar-none');
87
+ autoScrollRef.current = false;
88
+ }, 500);
89
+ }
90
+
91
+ scrollerRef.current.scrollTo({
92
+ top: scrollerRef.current.scrollHeight,
93
+ behavior,
94
+ });
95
+
96
+ setPinned(true);
85
97
  }
98
+ },
99
+ [behaviorProp],
100
+ );
86
101
 
87
- setPinned(true);
88
- }
89
- }, []);
90
-
91
- const controller = useMemo(
102
+ const controller = useMemo<ScrollController>(
92
103
  () => ({
93
- viewport: scrollerRef.current,
104
+ get viewport() {
105
+ return scrollerRef.current;
106
+ },
94
107
  scrollToTop: () => {
95
108
  invariant(scrollerRef.current);
96
109
  scrollerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
97
110
  setPinned(false);
98
111
  },
99
- scrollToBottom: () => {
100
- scrollToBottom('smooth');
112
+ scrollToBottom: (behavior = 'smooth' as ScrollBehavior) => {
113
+ scrollToBottom(behavior);
101
114
  },
102
115
  }),
103
- [scrollToBottom, scrollerRef.current],
116
+ [scrollToBottom],
104
117
  );
105
118
 
106
119
  // Scroll controller imperative ref.
107
120
  useImperativeHandle(forwardedRef, () => controller, [controller]);
108
121
 
109
- // Listen for scroll events.
110
- useEffect(() => {
111
- if (!scrollerRef.current) {
112
- return;
113
- }
114
-
115
- return combine(
116
- // Check if user scrolls.
117
- addEventListener(scrollerRef.current, 'wheel', () => {
118
- setPinned(isBottom(scrollerRef.current));
119
- }),
120
- // Check if scrolls.
121
- addEventListener(scrollerRef.current, 'scroll', () => {
122
- setOverflow((scrollerRef.current?.scrollTop ?? 0) > 0);
123
- }),
124
- );
122
+ // Called by Viewport when the scroll element mounts/unmounts.
123
+ const setViewport = useCallback((el: HTMLDivElement | null) => {
124
+ scrollerRef.current = el;
125
125
  }, []);
126
126
 
127
127
  return (
128
- <ScrollContainerProvider pinned={pinned} controller={controller} scrollToBottom={scrollToBottom}>
129
- <div className='relative grid dx-container overflow-hidden'>
130
- {fade && (
131
- <div
132
- role='none'
133
- data-visible={overflow}
134
- className={mx(
135
- // NOTE: Gradients may not be visible with dark reader extensions.
136
- 'z-10 absolute top-0 inset-x-0 h-24 w-full',
137
- 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
138
- 'bg-gradient-to-b from-(--surface-bg) to-transparent pointer-events-none',
139
- )}
140
- />
141
- )}
142
- <ScrollArea.Root classNames={mx('min-h-0', classNames)} thin>
143
- <ScrollArea.Viewport ref={scrollerRef}>{children}</ScrollArea.Viewport>
144
- </ScrollArea.Root>
145
- </div>
128
+ <ScrollContainerProvider
129
+ pinned={pinned}
130
+ overflow={overflow}
131
+ controller={controller}
132
+ setViewport={setViewport}
133
+ setPinned={setPinned}
134
+ setOverflow={setOverflow}
135
+ >
136
+ {children}
146
137
  </ScrollContainerProvider>
147
138
  );
148
139
  },
149
140
  );
150
141
 
151
- Root.displayName = 'ScrollContainer.Root';
142
+ ScrollContainerRoot.displayName = 'ScrollContainer.Root';
143
+
144
+ //
145
+ // Content
146
+ //
147
+
148
+ type ScrollContainerContentProps = Pick<ScrollAreaRootProps, 'thin' | 'padding' | 'centered'>;
149
+
150
+ /**
151
+ * Composable wrapper around ScrollArea.Root.
152
+ * Provides the DOM structure for the scroll container.
153
+ */
154
+ const ScrollContainerContent = composable<HTMLDivElement, ScrollContainerContentProps>(
155
+ ({ children, thin, padding, centered, ...props }, forwardedRef) => {
156
+ return (
157
+ <ScrollArea.Root
158
+ {...composableProps(props, { classNames: 'relative isolate' })}
159
+ thin={thin}
160
+ padding={padding}
161
+ centered={centered}
162
+ ref={forwardedRef}
163
+ >
164
+ {children}
165
+ </ScrollArea.Root>
166
+ );
167
+ },
168
+ );
169
+
170
+ ScrollContainerContent.displayName = 'ScrollContainer.Content';
152
171
 
153
172
  //
154
173
  // Viewport
@@ -156,34 +175,121 @@ Root.displayName = 'ScrollContainer.Root';
156
175
 
157
176
  const VIEWPORT_NAME = 'ScrollContainer.Viewport';
158
177
 
159
- type ViewportProps = ThemedClassName<PropsWithChildren<Omit<HTMLAttributes<HTMLDivElement>, 'className'>>>;
178
+ type ScrollContainerViewportProps = SlottableProps;
160
179
 
161
- const Viewport = forwardRef<HTMLDivElement, ViewportProps>(({ classNames, children, ...props }, forwardedRef) => {
162
- const contentRef = useForwardedRef(forwardedRef);
163
- const { pinned, scrollToBottom } = useScrollContainerContext(VIEWPORT_NAME);
180
+ const ScrollContainerViewport = slottable<HTMLDivElement, ScrollContainerViewportProps>(
181
+ ({ children, asChild, ...props }, forwardedRef) => {
182
+ const scrollerRef = useRef<HTMLDivElement>(null);
183
+ const mergedRef = useMergeRefs([forwardedRef, scrollerRef]);
184
+ const { setViewport, setPinned, setOverflow } = useScrollContainerContext(VIEWPORT_NAME);
164
185
 
186
+ // Register the scroll element with Root and set up wheel/scroll listeners.
187
+ useEffect(() => {
188
+ const el = scrollerRef.current;
189
+ if (!el) {
190
+ return;
191
+ }
192
+
193
+ setViewport(el);
194
+
195
+ return combine(
196
+ addEventListener(el, 'wheel', () => setPinned(isBottom(el))),
197
+ addEventListener(el, 'scroll', () => setOverflow((el.scrollTop ?? 0) > 0)),
198
+ () => setViewport(null),
199
+ );
200
+ }, [setViewport, setPinned, setOverflow]);
201
+
202
+ return (
203
+ <>
204
+ <ScrollArea.Viewport asChild={asChild} {...composableProps(props)} ref={mergedRef}>
205
+ {children}
206
+ </ScrollArea.Viewport>
207
+ <ScrollContainerPinEffect scrollerRef={scrollerRef} />
208
+ </>
209
+ );
210
+ },
211
+ );
212
+
213
+ ScrollContainerViewport.displayName = VIEWPORT_NAME;
214
+
215
+ /**
216
+ * Isolated component that consumes pinned/controller from context.
217
+ * Kept separate so that Viewport does not re-render when pinned changes.
218
+ */
219
+ const PIN_EFFECT_NAME = 'ScrollContainer.PinEffect';
220
+
221
+ const ScrollContainerPinEffect = ({ scrollerRef }: { scrollerRef: RefObject<HTMLDivElement | null> }) => {
222
+ const { pinned, controller } = useScrollContainerContext(PIN_EFFECT_NAME);
223
+
224
+ // Pin scroll to bottom when content changes.
165
225
  useEffect(() => {
166
- if (!pinned || !contentRef.current) {
226
+ const viewport = scrollerRef.current;
227
+ if (!pinned || !viewport) {
167
228
  return;
168
229
  }
169
230
 
170
- // Scroll instantly otherwise it might move while we're scrolling.
171
- scrollToBottom();
231
+ // Scroll instantly so we don't visually jump while content is being added.
232
+ controller?.scrollToBottom('instant');
233
+
234
+ // Setup resize observer on content children to detect size changes (e.g. streaming).
235
+ // We observe children rather than the viewport itself, because the viewport's size
236
+ // stays fixed — only its content grows.
237
+ // Use instant scroll in the callback — smooth scrolling adds/removes the
238
+ // scrollbar-none class, which changes the element size and re-fires the
239
+ // observer, creating an infinite loop.
240
+ const resizeObserver = new ResizeObserver(() => controller?.scrollToBottom('smooth'));
241
+ Array.from(viewport.children).forEach((child) => {
242
+ resizeObserver.observe(child);
243
+ });
244
+
245
+ // Watch for added/removed children.
246
+ const mutationObserver = new MutationObserver((mutations) => {
247
+ mutations.forEach((mutation) => {
248
+ mutation.addedNodes.forEach((node) => {
249
+ if (node instanceof Element) {
250
+ resizeObserver.observe(node);
251
+ }
252
+ });
253
+ });
254
+
255
+ controller?.scrollToBottom('smooth');
256
+ });
257
+ mutationObserver.observe(viewport, { childList: true });
258
+
259
+ return () => {
260
+ resizeObserver.disconnect();
261
+ mutationObserver.disconnect();
262
+ };
263
+ }, [pinned, controller, scrollerRef]);
264
+
265
+ return null;
266
+ };
267
+
268
+ //
269
+ // Fade
270
+ //
271
+
272
+ const FADE_NAME = 'ScrollContainer.Fade';
172
273
 
173
- // Setup resize observer to detect content changes.
174
- const resizeObserver = new ResizeObserver(() => scrollToBottom());
175
- resizeObserver.observe(contentRef.current);
176
- return () => resizeObserver.disconnect();
177
- }, [pinned, scrollToBottom]);
274
+ type ScrollContainerFadeProps = {};
275
+
276
+ function ScrollContainerFade() {
277
+ const { overflow } = useScrollContainerContext(FADE_NAME);
178
278
 
179
279
  return (
180
- <div className={mx('w-full', classNames)} {...props} ref={contentRef}>
181
- {children}
182
- </div>
280
+ <div
281
+ data-visible={overflow}
282
+ className={mx(
283
+ // NOTE: Gradients may not be visible with dark reader extensions.
284
+ 'z-10 absolute top-0 inset-x-0 h-24 w-full',
285
+ 'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
286
+ 'bg-gradient-to-b from-(--color-base-surface) to-transparent pointer-events-none',
287
+ )}
288
+ />
183
289
  );
184
- });
290
+ }
185
291
 
186
- Viewport.displayName = VIEWPORT_NAME;
292
+ ScrollContainerFade.displayName = FADE_NAME;
187
293
 
188
294
  //
189
295
  // ScrollDownButton
@@ -191,14 +297,13 @@ Viewport.displayName = VIEWPORT_NAME;
191
297
 
192
298
  const SCROLL_DOWN_BUTTON_NAME = 'ScrollContainer.ScrollDownButton';
193
299
 
194
- type ScrollDownButtonProps = ThemedClassName;
300
+ type ScrollContainerScrollDownButtonProps = ThemedClassName;
195
301
 
196
- const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
197
- const { pinned, scrollToBottom } = useScrollContainerContext(SCROLL_DOWN_BUTTON_NAME);
302
+ function ScrollContainerScrollDownButton({ classNames }: ScrollContainerScrollDownButtonProps) {
303
+ const { pinned, controller } = useScrollContainerContext(SCROLL_DOWN_BUTTON_NAME);
198
304
 
199
305
  return (
200
306
  <div
201
- role='none'
202
307
  className={mx(
203
308
  'absolute bottom-2 right-4 opacity-100 transition-opacity duration-300',
204
309
  pinned && 'opacity-0',
@@ -211,13 +316,13 @@ const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
211
316
  iconOnly
212
317
  size={4}
213
318
  label='Scroll down'
214
- onClick={() => scrollToBottom()}
319
+ onClick={() => controller?.scrollToBottom()}
215
320
  />
216
321
  </div>
217
322
  );
218
- };
323
+ }
219
324
 
220
- ScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
325
+ ScrollContainerScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
221
326
 
222
327
  //
223
328
  // ScrollContainer
@@ -226,13 +331,17 @@ ScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
226
331
  export { useScrollContainerContext };
227
332
 
228
333
  export const ScrollContainer = {
229
- Root,
230
- Viewport,
231
- ScrollDownButton,
334
+ Root: ScrollContainerRoot,
335
+ Content: ScrollContainerContent,
336
+ Viewport: ScrollContainerViewport,
337
+ Fade: ScrollContainerFade,
338
+ ScrollDownButton: ScrollContainerScrollDownButton,
232
339
  };
233
340
 
234
341
  export type {
235
- RootProps as ScrollContainerRootProps,
236
- ViewportProps as ScrollContainerViewportProps,
237
- ScrollDownButtonProps as ScrollContainerScrollDownButtonProps,
342
+ ScrollContainerRootProps,
343
+ ScrollContainerContentProps,
344
+ ScrollContainerViewportProps,
345
+ ScrollContainerFadeProps,
346
+ ScrollContainerScrollDownButtonProps,
238
347
  };
@@ -5,20 +5,19 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { useState } from 'react';
7
7
 
8
- import { faker } from '@dxos/random';
8
+ import { random } from '@dxos/random';
9
9
 
10
10
  import { withTheme } from '../../testing';
11
11
  import { withLayoutVariants } from '../../testing';
12
-
13
12
  import { Select } from './Select';
14
13
 
15
- faker.seed(1234);
14
+ random.seed(1234);
16
15
 
17
16
  type ItemProps = { id: string; text: string };
18
17
 
19
- type StoryProps = { items: ItemProps[] };
18
+ type DefaultStoryProps = { items: ItemProps[] };
20
19
 
21
- const DefaultStory = ({ items = [] }: StoryProps) => {
20
+ const DefaultStory = ({ items = [] }: DefaultStoryProps) => {
22
21
  const [value, setValue] = useState<string>();
23
22
  return (
24
23
  <Select.Root value={value} onValueChange={setValue}>
@@ -53,6 +52,6 @@ type Story = StoryObj<typeof meta>;
53
52
 
54
53
  export const Default: Story = {
55
54
  args: {
56
- items: Array.from({ length: 16 }).map((_, i) => ({ id: `item-${i}`, text: faker.lorem.word() })),
55
+ items: Array.from({ length: 16 }).map((_, i) => ({ id: `item-${i}`, text: random.lorem.word() })),
57
56
  },
58
57
  };
@@ -0,0 +1,55 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { mx, surfaceShadow, surfaceZIndex } from '@dxos/ui-theme';
6
+ import { type ComponentFunction, type Elevation, type Theme } from '@dxos/ui-types';
7
+
8
+ export type SelectStyleProps = Partial<{
9
+ elevation: Elevation;
10
+ }>;
11
+
12
+ const content: ComponentFunction<SelectStyleProps> = ({ elevation }, ...etc) => {
13
+ return mx(
14
+ 'dx-modal-surface rounded-sm border border-separator',
15
+ 'min-w-(--radix-select-trigger-width) max-h-(--radix-select-content-available-height)',
16
+ surfaceShadow({ elevation: 'positioned' }),
17
+ surfaceZIndex({ elevation, level: 'menu' }),
18
+ ...etc,
19
+ );
20
+ };
21
+
22
+ const triggerButton: ComponentFunction<SelectStyleProps> = (_props, ...etc) =>
23
+ mx('grid grid-cols-[1fr_auto] [&>span]:text-left', ...etc);
24
+
25
+ const viewport: ComponentFunction<SelectStyleProps> = (_props, ...etc) => mx(...etc);
26
+
27
+ const item: ComponentFunction<SelectStyleProps> = (_props, ...etc) =>
28
+ mx(
29
+ 'flex items-center min-h-[2rem] px-2.5 py-1 gap-2',
30
+ 'text-base-fg leading-none select-none outline-hidden',
31
+ '[&>svg]:invisible [&[data-state=checked]>svg]:visible',
32
+ 'dx-highlighted',
33
+ ...etc,
34
+ );
35
+
36
+ const itemIndicator: ComponentFunction<SelectStyleProps> = (_props, ...etc) => mx('items-center', ...etc);
37
+
38
+ const arrow: ComponentFunction<SelectStyleProps> = (_props, ...etc) => mx('fill-separator', ...etc);
39
+
40
+ const separator: ComponentFunction<SelectStyleProps> = (_props, ...etc) =>
41
+ mx('self-stretch border-b my-1 border-separator', ...etc);
42
+
43
+ const scrollButton: ComponentFunction<SelectStyleProps> = (_props, ...etc) =>
44
+ mx('dx-modal-surface flex items-center justify-center cursor-default h-6 w-full', ...etc);
45
+
46
+ export const selectTheme: Theme<SelectStyleProps> = {
47
+ content,
48
+ triggerButton,
49
+ viewport,
50
+ item,
51
+ itemIndicator,
52
+ arrow,
53
+ separator,
54
+ scrollButton,
55
+ };
@@ -5,8 +5,7 @@
5
5
  import * as SelectPrimitive from '@radix-ui/react-select';
6
6
  import React, { forwardRef } from 'react';
7
7
 
8
- import { useElevationContext, useThemeContext } from '../../hooks';
9
- import { useSafeCollisionPadding } from '../../hooks/useSafeCollisionPadding';
8
+ import { useSafeCollisionPadding, useElevationContext, useThemeContext } from '../../hooks';
10
9
  import { type ThemedClassName } from '../../util';
11
10
  import { Button, type ButtonProps } from '../Button';
12
11
  import { Icon } from '../Icon';
@@ -34,12 +33,12 @@ const SelectPortal = SelectPrimitive.Portal;
34
33
  type SelectTriggerButtonProps = Omit<ButtonProps, 'children'> & Pick<SelectValueProps, 'placeholder' | 'children'>;
35
34
 
36
35
  const SelectTriggerButton = forwardRef<HTMLButtonElement, SelectTriggerButtonProps>(
37
- ({ children, placeholder, ...props }, forwardedRef) => {
36
+ ({ children, placeholder, classNames, ...props }, forwardedRef) => {
37
+ const { tx } = useThemeContext();
38
38
  return (
39
39
  <SelectPrimitive.Trigger asChild ref={forwardedRef}>
40
- <Button {...props}>
40
+ <Button {...props} classNames={tx('select.triggerButton', {}, classNames)}>
41
41
  <SelectPrimitive.Value placeholder={placeholder}>{children}</SelectPrimitive.Value>
42
- <span className='w-1 flex-1' />
43
42
  <SelectPrimitive.Icon asChild>
44
43
  <Icon size={3} icon='ph--caret-down--bold' />
45
44
  </SelectPrimitive.Icon>
@@ -49,6 +48,8 @@ const SelectTriggerButton = forwardRef<HTMLButtonElement, SelectTriggerButtonPro
49
48
  },
50
49
  );
51
50
 
51
+ SelectTriggerButton.displayName = 'Select.TriggerButton';
52
+
52
53
  type SelectContentProps = ThemedClassName<SelectPrimitive.SelectContentProps>;
53
54
 
54
55
  const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
@@ -71,6 +72,8 @@ const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
71
72
  },
72
73
  );
73
74
 
75
+ SelectContent.displayName = 'Select.Content';
76
+
74
77
  type SelectScrollUpButtonProps = ThemedClassName<SelectPrimitive.SelectScrollUpButtonProps>;
75
78
 
76
79
  const SelectScrollUpButton = forwardRef<HTMLDivElement, SelectScrollUpButtonProps>(
@@ -88,6 +91,8 @@ const SelectScrollUpButton = forwardRef<HTMLDivElement, SelectScrollUpButtonProp
88
91
  },
89
92
  );
90
93
 
94
+ SelectScrollUpButton.displayName = 'Select.ScrollUpButton';
95
+
91
96
  type SelectScrollDownButtonProps = ThemedClassName<SelectPrimitive.SelectScrollDownButtonProps>;
92
97
 
93
98
  const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButtonProps>(
@@ -105,6 +110,8 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
105
110
  },
106
111
  );
107
112
 
113
+ SelectScrollDownButton.displayName = 'Select.ScrollDownButton';
114
+
108
115
  type SelectViewportProps = ThemedClassName<SelectPrimitive.SelectViewportProps>;
109
116
 
110
117
  const SelectViewport = forwardRef<HTMLDivElement, SelectViewportProps>(
@@ -118,6 +125,8 @@ const SelectViewport = forwardRef<HTMLDivElement, SelectViewportProps>(
118
125
  },
119
126
  );
120
127
 
128
+ SelectViewport.displayName = 'Select.Viewport';
129
+
121
130
  type SelectItemProps = ThemedClassName<SelectPrimitive.SelectItemProps>;
122
131
 
123
132
  const SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(({ classNames, ...props }, forwardedRef) => {
@@ -125,6 +134,8 @@ const SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(({ classNames, ..
125
134
  return <SelectPrimitive.Item {...props} className={tx('select.item', {}, classNames)} ref={forwardedRef} />;
126
135
  });
127
136
 
137
+ SelectItem.displayName = 'Select.Item';
138
+
128
139
  type SelectItemTextProps = SelectPrimitive.SelectItemTextProps;
129
140
 
130
141
  const SelectItemText = SelectPrimitive.ItemText;
@@ -146,22 +157,23 @@ const SelectItemIndicator = forwardRef<HTMLDivElement, SelectItemIndicatorProps>
146
157
  },
147
158
  );
148
159
 
160
+ SelectItemIndicator.displayName = 'Select.ItemIndicator';
161
+
149
162
  type SelectOptionProps = SelectItemProps;
150
163
 
151
- // TODO(burdon): Option to show icon on left/right.
152
164
  const SelectOption = forwardRef<HTMLDivElement, SelectItemProps>(({ children, classNames, ...props }, forwardedRef) => {
153
165
  const { tx } = useThemeContext();
154
166
  return (
155
167
  <SelectPrimitive.Item {...props} className={tx('select.item', {}, classNames)} ref={forwardedRef}>
156
168
  <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
157
- <span className='grow w-1' />
158
- {/* <SelectPrimitive.ItemIndicator className={tx('select.itemIndicator', 'option__indicator', {})}> */}
159
- <Icon icon='ph--check--regular' />
160
- {/* </SelectPrimitive.ItemIndicator> */}
169
+ <span className='grow' />
170
+ <Icon size={3} icon='ph--check--regular' />
161
171
  </SelectPrimitive.Item>
162
172
  );
163
173
  });
164
174
 
175
+ SelectOption.displayName = 'Select.Option';
176
+
165
177
  type SelectGroupProps = SelectPrimitive.SelectGroupProps;
166
178
 
167
179
  const SelectGroup = SelectPrimitive.Group;
@@ -177,6 +189,8 @@ const SelectSeparator = forwardRef<HTMLDivElement, SelectSeparatorProps>(({ clas
177
189
  return <SelectPrimitive.Separator {...props} className={tx('select.separator', {}, classNames)} ref={forwardedRef} />;
178
190
  });
179
191
 
192
+ SelectSeparator.displayName = 'Select.Separator';
193
+
180
194
  type SelectArrowProps = ThemedClassName<SelectPrimitive.SelectArrowProps>;
181
195
 
182
196
  const SelectArrow = forwardRef<SVGSVGElement, SelectArrowProps>(({ classNames, ...props }, forwardedRef) => {
@@ -184,6 +198,8 @@ const SelectArrow = forwardRef<SVGSVGElement, SelectArrowProps>(({ classNames, .
184
198
  return <SelectPrimitive.Arrow {...props} className={tx('select.arrow', {}, classNames)} ref={forwardedRef} />;
185
199
  });
186
200
 
201
+ SelectArrow.displayName = 'Select.Arrow';
202
+
187
203
  export const Select = {
188
204
  Root: SelectRoot,
189
205
  Trigger: SelectTrigger,
@@ -0,0 +1,23 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { mx } from '@dxos/ui-theme';
6
+ import { type ComponentFunction, type Theme } from '@dxos/ui-types';
7
+
8
+ export type SeparatorStyleProps = {
9
+ orientation?: 'horizontal' | 'vertical';
10
+ subdued?: boolean;
11
+ };
12
+
13
+ const root: ComponentFunction<SeparatorStyleProps> = ({ orientation, subdued }, ...etc) =>
14
+ mx(
15
+ 'self-stretch',
16
+ orientation === 'vertical' ? 'border-e mx-1' : 'border-b my-1',
17
+ subdued ? 'border-subdued-separator' : 'border-separator',
18
+ ...etc,
19
+ );
20
+
21
+ export const separatorTheme: Theme<SeparatorStyleProps> = {
22
+ root,
23
+ };