@dxos/react-ui 0.8.4-main.b97322e → 0.8.4-main.bc2380dfbc

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 (502) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/chunk-A5QCIG5R.mjs +24 -0
  4. package/dist/lib/browser/chunk-A5QCIG5R.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-BDBC6H6V.mjs +848 -0
  6. package/dist/lib/browser/chunk-BDBC6H6V.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +4411 -60
  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 +106 -60
  11. package/dist/lib/browser/testing/index.mjs.map +4 -4
  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-3JSJK2ZY.mjs +850 -0
  15. package/dist/lib/node-esm/chunk-3JSJK2ZY.mjs.map +7 -0
  16. package/dist/lib/node-esm/chunk-XCFLA74M.mjs +26 -0
  17. package/dist/lib/node-esm/chunk-XCFLA74M.mjs.map +7 -0
  18. package/dist/lib/node-esm/index.mjs +4411 -60
  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 +106 -60
  22. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  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 +2 -2
  26. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  27. package/dist/types/src/components/Avatars/Avatar.stories.d.ts +5 -31
  28. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts +5 -11
  30. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts +1 -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 +8 -20
  34. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  35. package/dist/types/src/components/{Buttons → Button}/Button.d.ts +4 -4
  36. package/dist/types/src/components/Button/Button.d.ts.map +1 -0
  37. package/dist/types/src/components/Button/Button.stories.d.ts +17 -0
  38. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -0
  39. package/dist/types/src/components/{Buttons → Button}/IconButton.d.ts +5 -4
  40. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -0
  41. package/dist/types/src/components/Button/IconButton.stories.d.ts +16 -0
  42. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -0
  43. package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +2 -2
  44. package/dist/types/src/components/Button/Toggle.d.ts.map +1 -0
  45. package/dist/types/src/components/Button/Toggle.stories.d.ts +16 -0
  46. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -0
  47. package/dist/types/src/components/Button/ToggleGroup.d.ts +27 -0
  48. package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -0
  49. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +27 -0
  50. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -0
  51. package/dist/types/src/components/Button/index.d.ts.map +1 -0
  52. package/dist/types/src/components/Card/Card.d.ts +124 -0
  53. package/dist/types/src/components/Card/Card.d.ts.map +1 -0
  54. package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
  55. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
  56. package/dist/types/src/components/Card/index.d.ts +2 -0
  57. package/dist/types/src/components/Card/index.d.ts.map +1 -0
  58. package/dist/types/src/components/Carousel/Carousel.d.ts +90 -0
  59. package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -0
  60. package/dist/types/src/components/Carousel/index.d.ts +2 -0
  61. package/dist/types/src/components/Carousel/index.d.ts.map +1 -0
  62. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  63. package/dist/types/src/components/Clipboard/CopyButton.d.ts +1 -1
  64. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  65. package/dist/types/src/components/Clipboard/index.d.ts +10 -1
  66. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  67. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts +1 -1
  68. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  69. package/dist/types/src/components/Dialog/AlertDialog.d.ts +51 -0
  70. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -0
  71. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts +11 -0
  72. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -0
  73. package/dist/types/src/components/Dialog/Dialog.d.ts +64 -0
  74. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -0
  75. package/dist/types/src/components/Dialog/Dialog.stories.d.ts +25 -0
  76. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -0
  77. package/dist/types/src/components/Dialog/index.d.ts.map +1 -0
  78. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts +1 -1
  79. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  80. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
  81. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  82. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
  83. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
  84. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +19 -0
  85. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
  86. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
  87. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
  88. package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
  89. package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
  90. package/dist/types/src/components/Focus/Focus.d.ts +36 -0
  91. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
  92. package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
  93. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
  94. package/dist/types/src/components/Focus/index.d.ts +2 -0
  95. package/dist/types/src/components/Focus/index.d.ts.map +1 -0
  96. package/dist/types/src/components/Icon/Icon.d.ts +6 -2
  97. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  98. package/dist/types/src/components/Icon/Icon.stories.d.ts +25 -0
  99. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
  100. package/dist/types/src/components/Image/Image.d.ts +15 -0
  101. package/dist/types/src/components/Image/Image.d.ts.map +1 -0
  102. package/dist/types/src/components/Image/Image.stories.d.ts +34 -0
  103. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
  104. package/dist/types/src/components/Image/index.d.ts +2 -0
  105. package/dist/types/src/components/Image/index.d.ts.map +1 -0
  106. package/dist/types/src/components/Input/Input.d.ts +19 -24
  107. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  108. package/dist/types/src/components/Input/Input.stories.d.ts +17 -18
  109. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  110. package/dist/types/src/components/Link/Link.stories.d.ts +8 -8
  111. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  112. package/dist/types/src/components/{Lists → List}/List.d.ts +8 -6
  113. package/dist/types/src/components/List/List.d.ts.map +1 -0
  114. package/dist/types/src/components/List/List.stories.d.ts +16 -0
  115. package/dist/types/src/components/List/List.stories.d.ts.map +1 -0
  116. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -0
  117. package/dist/types/src/components/{Lists → List}/Tree.d.ts +3 -3
  118. package/dist/types/src/components/List/Tree.d.ts.map +1 -0
  119. package/dist/types/src/components/List/Tree.stories.d.ts +15 -0
  120. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -0
  121. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -0
  122. package/dist/types/src/components/{Lists → List}/Treegrid.d.ts +6 -10
  123. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -0
  124. package/dist/types/src/components/List/Treegrid.stories.d.ts +12 -0
  125. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -0
  126. package/dist/types/src/components/List/index.d.ts.map +1 -0
  127. package/dist/types/src/components/Main/Main.d.ts +25 -31
  128. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  129. package/dist/types/src/components/Main/Main.stories.d.ts +6 -10
  130. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  131. package/dist/types/src/components/Main/useSwipeToDismiss.d.ts.map +1 -1
  132. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts +46 -0
  133. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts.map +1 -0
  134. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts +16 -0
  135. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts.map +1 -0
  136. package/dist/types/src/components/MediaPlayer/index.d.ts +2 -0
  137. package/dist/types/src/components/MediaPlayer/index.d.ts.map +1 -0
  138. package/dist/types/src/components/{Menus → Menu}/ContextMenu.d.ts +6 -6
  139. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -0
  140. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts +12 -0
  141. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -0
  142. package/dist/types/src/components/Menu/DropdownMenu.d.ts +121 -0
  143. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -0
  144. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +28 -0
  145. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -0
  146. package/dist/types/src/components/Menu/index.d.ts.map +1 -0
  147. package/dist/types/src/components/Message/Message.d.ts +2 -2
  148. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  149. package/dist/types/src/components/Message/Message.stories.d.ts +12 -22
  150. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  151. package/dist/types/src/components/Popover/Popover.d.ts +41 -24
  152. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  153. package/dist/types/src/components/Popover/Popover.stories.d.ts +6 -34
  154. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  155. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +27 -27
  156. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  157. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +50 -27
  158. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  159. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +68 -0
  160. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -0
  161. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +23 -0
  162. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -0
  163. package/dist/types/src/components/ScrollContainer/index.d.ts +2 -0
  164. package/dist/types/src/components/ScrollContainer/index.d.ts.map +1 -0
  165. package/dist/types/src/components/Select/Select.d.ts +10 -10
  166. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  167. package/dist/types/src/components/Select/Select.stories.d.ts +6 -11
  168. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  169. package/dist/types/src/components/Separator/Separator.d.ts +4 -4
  170. package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
  171. package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
  172. package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
  173. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
  174. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  175. package/dist/types/src/components/Skeleton/index.d.ts +2 -0
  176. package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
  177. package/dist/types/src/components/Splitter/Splitter.d.ts +34 -0
  178. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
  179. package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
  180. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
  181. package/dist/types/src/components/Splitter/index.d.ts +2 -0
  182. package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
  183. package/dist/types/src/components/Status/Status.d.ts +3 -4
  184. package/dist/types/src/components/Status/Status.d.ts.map +1 -1
  185. package/dist/types/src/components/Status/Status.stories.d.ts +6 -10
  186. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  187. package/dist/types/src/components/Tag/Tag.d.ts +1 -1
  188. package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
  189. package/dist/types/src/components/Tag/Tag.stories.d.ts +8 -13
  190. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  191. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +4 -4
  192. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  193. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
  194. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
  195. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +55 -63
  196. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  197. package/dist/types/src/components/ThemeProvider/index.d.ts +2 -1
  198. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  199. package/dist/types/src/components/Toast/Toast.d.ts +20 -20
  200. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  201. package/dist/types/src/components/Toast/Toast.stories.d.ts +6 -44
  202. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  203. package/dist/types/src/components/Toolbar/Toolbar.d.ts +41 -23
  204. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  205. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +6 -50
  206. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  207. package/dist/types/src/components/Tooltip/Tooltip.d.ts +11 -13
  208. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  209. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +10 -63
  210. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  211. package/dist/types/src/components/index.d.ts +16 -8
  212. package/dist/types/src/components/index.d.ts.map +1 -1
  213. package/dist/types/src/exemplars/generics.stories.d.ts +19 -0
  214. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
  215. package/dist/types/src/exemplars/slot.stories.d.ts +15 -0
  216. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
  217. package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
  218. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
  219. package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
  220. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
  221. package/dist/types/src/hooks/index.d.ts +1 -0
  222. package/dist/types/src/hooks/index.d.ts.map +1 -1
  223. package/dist/types/src/hooks/useDensityContext.d.ts +2 -2
  224. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  225. package/dist/types/src/hooks/useElevationContext.d.ts +1 -1
  226. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  227. package/dist/types/src/hooks/useIconHref.d.ts.map +1 -1
  228. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  229. package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -1
  230. package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
  231. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  232. package/dist/types/src/index.d.ts +2 -1
  233. package/dist/types/src/index.d.ts.map +1 -1
  234. package/dist/types/src/playground/Controls.stories.d.ts +5 -9
  235. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  236. package/dist/types/src/playground/Custom.stories.d.ts +12 -4
  237. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  238. package/dist/types/src/playground/Typography.stories.d.ts +5 -11
  239. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  240. package/dist/types/src/primitives/Column/Column.d.ts +33 -0
  241. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
  242. package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
  243. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
  244. package/dist/types/src/primitives/Column/index.d.ts +2 -0
  245. package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
  246. package/dist/types/src/primitives/Container/Container.d.ts +7 -0
  247. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
  248. package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
  249. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
  250. package/dist/types/src/primitives/Container/index.d.ts +2 -0
  251. package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
  252. package/dist/types/src/primitives/Flex/Flex.d.ts +11 -0
  253. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
  254. package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
  255. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
  256. package/dist/types/src/primitives/Flex/index.d.ts +2 -0
  257. package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
  258. package/dist/types/src/primitives/Grid/Grid.d.ts +10 -0
  259. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
  260. package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
  261. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
  262. package/dist/types/src/primitives/Grid/index.d.ts +2 -0
  263. package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
  264. package/dist/types/src/primitives/Panel/Panel.d.ts +35 -0
  265. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
  266. package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
  267. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
  268. package/dist/types/src/primitives/Panel/index.d.ts +2 -0
  269. package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
  270. package/dist/types/src/primitives/index.d.ts +6 -0
  271. package/dist/types/src/primitives/index.d.ts.map +1 -0
  272. package/dist/types/src/testing/Loading.d.ts +9 -0
  273. package/dist/types/src/testing/Loading.d.ts.map +1 -0
  274. package/dist/types/src/testing/decorators/index.d.ts +2 -1
  275. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  276. package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
  277. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
  278. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts +12 -0
  279. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
  280. package/dist/types/src/testing/decorators/withTheme.d.ts +5 -1
  281. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  282. package/dist/types/src/testing/index.d.ts +1 -0
  283. package/dist/types/src/testing/index.d.ts.map +1 -1
  284. package/dist/types/src/translations.d.ts +16 -0
  285. package/dist/types/src/translations.d.ts.map +1 -0
  286. package/dist/types/src/util/index.d.ts +2 -1
  287. package/dist/types/src/util/index.d.ts.map +1 -1
  288. package/dist/types/src/util/usePx.d.ts +8 -0
  289. package/dist/types/src/util/usePx.d.ts.map +1 -0
  290. package/dist/types/tsconfig.tsbuildinfo +1 -1
  291. package/package.json +55 -40
  292. package/src/components/Avatars/Avatar.stories.tsx +23 -16
  293. package/src/components/Avatars/Avatar.tsx +10 -18
  294. package/src/components/Avatars/AvatarGroup.stories.tsx +11 -8
  295. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +19 -15
  296. package/src/components/Breadcrumb/Breadcrumb.tsx +12 -38
  297. package/src/components/{Buttons → Button}/Button.stories.tsx +9 -11
  298. package/src/components/{Buttons → Button}/Button.tsx +12 -26
  299. package/src/components/{Buttons → Button}/IconButton.stories.tsx +18 -13
  300. package/src/components/{Buttons → Button}/IconButton.tsx +22 -16
  301. package/src/components/Button/Toggle.stories.tsx +36 -0
  302. package/src/components/{Buttons → Button}/Toggle.tsx +4 -4
  303. package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +11 -9
  304. package/src/components/Button/ToggleGroup.tsx +50 -0
  305. package/src/components/Card/Card.stories.tsx +151 -0
  306. package/src/components/Card/Card.tsx +514 -0
  307. package/src/components/Card/index.ts +5 -0
  308. package/src/components/Carousel/Carousel.tsx +337 -0
  309. package/src/components/Carousel/index.ts +5 -0
  310. package/src/components/Clipboard/ClipboardProvider.tsx +1 -1
  311. package/src/components/Clipboard/CopyButton.tsx +11 -11
  312. package/src/components/DensityProvider/DensityProvider.tsx +2 -2
  313. package/src/components/Dialog/AlertDialog.stories.tsx +68 -0
  314. package/src/components/Dialog/AlertDialog.tsx +213 -0
  315. package/src/components/Dialog/Dialog.stories.tsx +177 -0
  316. package/src/components/Dialog/Dialog.tsx +285 -0
  317. package/src/components/ElevationProvider/ElevationProvider.tsx +2 -2
  318. package/src/components/ErrorFallback/ErrorFallback.stories.tsx +45 -0
  319. package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
  320. package/src/components/ErrorFallback/ErrorStack.tsx +114 -0
  321. package/src/components/ErrorFallback/ThrowError.tsx +37 -0
  322. package/src/components/ErrorFallback/index.ts +9 -0
  323. package/src/components/Focus/AUDIT.md +43 -0
  324. package/src/components/Focus/Focus.stories.tsx +230 -0
  325. package/src/components/Focus/Focus.tsx +201 -0
  326. package/src/components/Focus/index.ts +5 -0
  327. package/src/components/Icon/Icon.stories.tsx +143 -0
  328. package/src/components/Icon/Icon.tsx +15 -4
  329. package/src/components/Image/Image.stories.tsx +86 -0
  330. package/src/components/Image/Image.tsx +246 -0
  331. package/src/components/Image/index.ts +5 -0
  332. package/src/components/Input/Input.stories.tsx +27 -49
  333. package/src/components/Input/Input.tsx +51 -87
  334. package/src/components/Link/Link.stories.tsx +11 -8
  335. package/src/components/Link/Link.tsx +2 -2
  336. package/src/components/{Lists → List}/List.stories.tsx +44 -46
  337. package/src/components/{Lists → List}/List.tsx +31 -31
  338. package/src/components/{Lists → List}/ListDropIndicator.tsx +7 -8
  339. package/src/components/{Lists → List}/Tree.stories.tsx +16 -14
  340. package/src/components/{Lists → List}/Tree.tsx +3 -3
  341. package/src/components/{Lists → List}/TreeDropIndicator.tsx +7 -7
  342. package/src/components/{Lists → List}/Treegrid.stories.tsx +39 -34
  343. package/src/components/List/Treegrid.tsx +188 -0
  344. package/src/components/Main/Main.stories.tsx +52 -27
  345. package/src/components/Main/Main.tsx +176 -105
  346. package/src/components/MediaPlayer/MediaPlayer.stories.tsx +50 -0
  347. package/src/components/MediaPlayer/MediaPlayer.tsx +153 -0
  348. package/src/components/MediaPlayer/index.ts +5 -0
  349. package/src/components/{Menus → Menu}/ContextMenu.stories.tsx +12 -10
  350. package/src/components/{Menus → Menu}/ContextMenu.tsx +10 -33
  351. package/src/components/{Menus → Menu}/DropdownMenu.stories.tsx +13 -11
  352. package/src/components/{Menus → Menu}/DropdownMenu.tsx +157 -120
  353. package/src/components/Message/Message.stories.tsx +36 -18
  354. package/src/components/Message/Message.tsx +59 -33
  355. package/src/components/Popover/Popover.stories.tsx +18 -16
  356. package/src/components/Popover/Popover.tsx +124 -102
  357. package/src/components/ScrollArea/ScrollArea.stories.tsx +221 -33
  358. package/src/components/ScrollArea/ScrollArea.tsx +97 -79
  359. package/src/components/ScrollArea/index.ts +1 -1
  360. package/src/components/ScrollContainer/ScrollContainer.stories.tsx +91 -0
  361. package/src/components/ScrollContainer/ScrollContainer.tsx +345 -0
  362. package/src/components/ScrollContainer/index.ts +5 -0
  363. package/src/components/Select/Select.stories.tsx +19 -17
  364. package/src/components/Select/Select.tsx +16 -31
  365. package/src/components/Separator/Separator.tsx +5 -8
  366. package/src/components/Skeleton/Skeleton.stories.tsx +51 -0
  367. package/src/components/Skeleton/Skeleton.tsx +26 -0
  368. package/src/components/Skeleton/index.ts +5 -0
  369. package/src/components/Splitter/Splitter.stories.tsx +83 -0
  370. package/src/components/Splitter/Splitter.tsx +127 -0
  371. package/src/components/Splitter/index.ts +5 -0
  372. package/src/components/Status/Status.stories.tsx +29 -23
  373. package/src/components/Status/Status.tsx +10 -7
  374. package/src/components/Tag/Tag.stories.tsx +16 -13
  375. package/src/components/Tag/Tag.tsx +3 -8
  376. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +31 -0
  377. package/src/components/ThemeProvider/ThemeProvider.tsx +12 -11
  378. package/src/components/ThemeProvider/TranslationsProvider.tsx +3 -18
  379. package/src/components/ThemeProvider/index.ts +3 -3
  380. package/src/components/Toast/Toast.stories.tsx +13 -11
  381. package/src/components/Toast/Toast.tsx +23 -42
  382. package/src/components/Toolbar/Toolbar.stories.tsx +15 -14
  383. package/src/components/Toolbar/Toolbar.tsx +190 -14
  384. package/src/components/Tooltip/Tooltip.stories.tsx +35 -30
  385. package/src/components/Tooltip/Tooltip.tsx +44 -41
  386. package/src/components/index.ts +17 -9
  387. package/src/exemplars/generics.stories.tsx +41 -0
  388. package/src/exemplars/slot.stories.tsx +115 -0
  389. package/src/exemplars/tabster.stories.tsx +127 -0
  390. package/src/exemplars/virtualizer.stories.tsx +136 -0
  391. package/src/hooks/index.ts +1 -0
  392. package/src/hooks/useDensityContext.ts +3 -3
  393. package/src/hooks/useElevationContext.ts +1 -1
  394. package/src/hooks/useSafeArea.ts +3 -2
  395. package/src/hooks/useVisualViewport.ts +4 -4
  396. package/src/index.ts +2 -1
  397. package/src/playground/Controls.stories.tsx +12 -15
  398. package/src/playground/Custom.stories.tsx +20 -34
  399. package/src/playground/Typography.stories.tsx +11 -9
  400. package/src/primitives/Column/AUDIT.md +148 -0
  401. package/src/primitives/Column/Column.stories.tsx +181 -0
  402. package/src/primitives/Column/Column.tsx +165 -0
  403. package/src/primitives/Column/index.ts +5 -0
  404. package/src/primitives/Container/Container.stories.tsx +29 -0
  405. package/src/primitives/Container/Container.tsx +19 -0
  406. package/src/primitives/Container/index.ts +5 -0
  407. package/src/primitives/Flex/Flex.stories.tsx +57 -0
  408. package/src/primitives/Flex/Flex.tsx +27 -0
  409. package/src/primitives/Flex/index.ts +5 -0
  410. package/src/primitives/Grid/Grid.stories.tsx +56 -0
  411. package/src/primitives/Grid/Grid.tsx +30 -0
  412. package/src/primitives/Grid/index.ts +5 -0
  413. package/src/primitives/Panel/Panel.stories.tsx +68 -0
  414. package/src/primitives/Panel/Panel.tsx +120 -0
  415. package/src/primitives/Panel/index.ts +5 -0
  416. package/src/primitives/index.ts +9 -0
  417. package/src/testing/Loading.tsx +47 -0
  418. package/src/testing/decorators/index.ts +2 -1
  419. package/src/testing/decorators/withLayout.tsx +67 -0
  420. package/src/testing/decorators/withLayoutVariants.tsx +48 -0
  421. package/src/testing/decorators/withTheme.tsx +37 -0
  422. package/src/testing/index.ts +2 -0
  423. package/src/translations.ts +24 -0
  424. package/src/util/index.ts +3 -1
  425. package/src/util/usePx.ts +62 -0
  426. package/dist/lib/browser/chunk-2COVUP44.mjs +0 -4373
  427. package/dist/lib/browser/chunk-2COVUP44.mjs.map +0 -7
  428. package/dist/lib/node-esm/chunk-GHXHND5V.mjs +0 -4375
  429. package/dist/lib/node-esm/chunk-GHXHND5V.mjs.map +0 -7
  430. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
  431. package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
  432. package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
  433. package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
  434. package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
  435. package/dist/types/src/components/Buttons/Button.stories.d.ts +0 -12
  436. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
  437. package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
  438. package/dist/types/src/components/Buttons/IconButton.stories.d.ts +0 -22
  439. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
  440. package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
  441. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -19
  442. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
  443. package/dist/types/src/components/Buttons/ToggleGroup.d.ts +0 -28
  444. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
  445. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +0 -39
  446. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
  447. package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
  448. package/dist/types/src/components/Dialogs/AlertDialog.d.ts +0 -31
  449. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
  450. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +0 -43
  451. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
  452. package/dist/types/src/components/Dialogs/Dialog.d.ts +0 -31
  453. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
  454. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -48
  455. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
  456. package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
  457. package/dist/types/src/components/Lists/List.d.ts.map +0 -1
  458. package/dist/types/src/components/Lists/List.stories.d.ts +0 -37
  459. package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
  460. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
  461. package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
  462. package/dist/types/src/components/Lists/Tree.stories.d.ts +0 -41
  463. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
  464. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
  465. package/dist/types/src/components/Lists/Treegrid.d.ts.map +0 -1
  466. package/dist/types/src/components/Lists/Treegrid.stories.d.ts +0 -10
  467. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
  468. package/dist/types/src/components/Lists/index.d.ts.map +0 -1
  469. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +0 -1
  470. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +0 -50
  471. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +0 -1
  472. package/dist/types/src/components/Menus/DropdownMenu.d.ts +0 -112
  473. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +0 -1
  474. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +0 -50
  475. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +0 -1
  476. package/dist/types/src/components/Menus/index.d.ts.map +0 -1
  477. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts +0 -12
  478. package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
  479. package/dist/types/src/util/ThemedClassName.d.ts +0 -5
  480. package/dist/types/src/util/ThemedClassName.d.ts.map +0 -1
  481. package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
  482. package/src/components/AnchoredOverflow/index.ts +0 -5
  483. package/src/components/Buttons/Toggle.stories.tsx +0 -33
  484. package/src/components/Buttons/ToggleGroup.tsx +0 -41
  485. package/src/components/Dialogs/AlertDialog.stories.tsx +0 -66
  486. package/src/components/Dialogs/AlertDialog.tsx +0 -172
  487. package/src/components/Dialogs/Dialog.stories.tsx +0 -65
  488. package/src/components/Dialogs/Dialog.tsx +0 -159
  489. package/src/components/Lists/Treegrid.tsx +0 -152
  490. package/src/testing/decorators/withSurfaceVariantsLayout.tsx +0 -51
  491. package/src/testing/decorators/withTheme.ts +0 -25
  492. package/src/util/ThemedClassName.ts +0 -7
  493. /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
  494. /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
  495. /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
  496. /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
  497. /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
  498. /package/dist/types/src/components/{Menus → Menu}/index.d.ts +0 -0
  499. /package/src/components/{Buttons → Button}/index.ts +0 -0
  500. /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
  501. /package/src/components/{Lists → List}/index.ts +0 -0
  502. /package/src/components/{Menus → Menu}/index.ts +0 -0
@@ -2,49 +2,50 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { useFocusableGroup } from '@fluentui/react-tabster';
5
6
  import { createContext } from '@radix-ui/react-context';
6
- import { Root as DialogRoot, DialogContent, DialogTitle } from '@radix-ui/react-dialog';
7
+ import { DialogContent, Root as DialogRoot, DialogTitle } from '@radix-ui/react-dialog';
7
8
  import { Primitive } from '@radix-ui/react-primitive';
8
9
  import { Slot } from '@radix-ui/react-slot';
9
10
  import { useControllableState } from '@radix-ui/react-use-controllable-state';
10
11
  import React, {
11
12
  type ComponentPropsWithRef,
13
+ type ComponentPropsWithoutRef,
12
14
  type Dispatch,
13
- forwardRef,
15
+ type KeyboardEvent,
14
16
  type PropsWithChildren,
15
17
  type SetStateAction,
18
+ forwardRef,
16
19
  useCallback,
17
20
  useEffect,
18
21
  useRef,
19
22
  useState,
20
- type KeyboardEvent,
21
- type ComponentPropsWithoutRef,
22
23
  } from 'react';
23
24
 
25
+ import { addEventListener } from '@dxos/async';
24
26
  import { log } from '@dxos/log';
25
- import { useMediaQuery, useForwardedRef } from '@dxos/react-hooks';
27
+ import { useForwardedRef, useMediaQuery } from '@dxos/react-hooks';
28
+ import { type MainStyleProps, osTranslations } from '@dxos/ui-theme';
26
29
 
27
- import { useSwipeToDismiss } from './useSwipeToDismiss';
28
30
  import { useThemeContext } from '../../hooks';
29
31
  import { type ThemedClassName } from '../../util';
30
32
  import { type Label, toLocalizedString, useTranslation } from '../ThemeProvider';
33
+ import { useSwipeToDismiss } from './useSwipeToDismiss';
31
34
 
35
+ const MAIN_NAME = 'Main';
32
36
  const MAIN_ROOT_NAME = 'MainRoot';
37
+ const MAIN_OVERLAY_NAME = 'MainOverlay';
33
38
  const NAVIGATION_SIDEBAR_NAME = 'NavigationSidebar';
34
39
  const COMPLEMENTARY_SIDEBAR_NAME = 'ComplementarySidebar';
35
- const MAIN_NAME = 'Main';
36
- const GENERIC_CONSUMER_NAME = 'GenericConsumer';
37
-
38
- type SidebarState = 'expanded' | 'collapsed' | 'closed';
39
40
 
40
- type MainContextValue = {
41
- resizing: boolean;
42
- navigationSidebarState: SidebarState;
43
- setNavigationSidebarState: Dispatch<SetStateAction<SidebarState | undefined>>;
44
- complementarySidebarState: SidebarState;
45
- setComplementarySidebarState: Dispatch<SetStateAction<SidebarState | undefined>>;
41
+ const handleOpenAutoFocus = (event: Event) => {
42
+ !document.body.hasAttribute('data-w-keyboard') && event.preventDefault();
46
43
  };
47
44
 
45
+ //
46
+ // Landmark
47
+ //
48
+
48
49
  const landmarkAttr = 'data-main-landmark';
49
50
 
50
51
  /**
@@ -69,28 +70,60 @@ const useLandmarkMover = (propsOnKeyDown: ComponentPropsWithoutRef<'div'>['onKey
69
70
  },
70
71
  [propsOnKeyDown],
71
72
  );
72
- const focusableGroupAttrs = window ? {} : { tabBehavior: 'limited', ignoreDefaultKeydown: { Tab: true } };
73
73
 
74
- return { onKeyDown: handleKeyDown, [landmarkAttr]: landmark, tabIndex: 0, ...focusableGroupAttrs };
74
+ // TODO(thure): This was disconnected once before in #8818;
75
+ // if this should change again to support the browser extension, please ensure the change doesn’t break web, desktop and mobile.
76
+ const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited', ignoreDefaultKeydown: { Tab: true } });
77
+
78
+ return {
79
+ [landmarkAttr]: landmark,
80
+ tabIndex: 0,
81
+ onKeyDown: handleKeyDown,
82
+ ...focusableGroupAttrs,
83
+ };
84
+ };
85
+
86
+ //
87
+ // Context
88
+ //
89
+
90
+ // TODO(burdon): Define collapsed state.
91
+ type SidebarState = 'expanded' | 'collapsed' | 'closed';
92
+
93
+ type MainContextValue = {
94
+ resizing: boolean;
95
+
96
+ // Navigation
97
+ navigationSidebarState: SidebarState;
98
+ setNavigationSidebarState: Dispatch<SetStateAction<SidebarState | undefined>>;
99
+
100
+ // Complementary
101
+ complementarySidebarState: SidebarState;
102
+ setComplementarySidebarState: Dispatch<SetStateAction<SidebarState | undefined>>;
75
103
  };
76
104
 
77
105
  const [MainProvider, useMainContext] = createContext<MainContextValue>(MAIN_NAME, {
78
106
  resizing: false,
107
+
79
108
  navigationSidebarState: 'closed',
80
- setNavigationSidebarState: (nextState) => {
81
- // TODO(burdon): Standardize with other context missing errors using raise.
82
- log.warn('Attempt to set sidebar state without initializing `MainRoot`');
109
+ setNavigationSidebarState: (_nextState) => {
110
+ log.warn('Not initialized');
83
111
  },
112
+
84
113
  complementarySidebarState: 'closed',
85
- setComplementarySidebarState: (nextState) => {
86
- // TODO(burdon): Standardize with other context missing errors using raise.
87
- log.warn('Attempt to set sidebar state without initializing `MainRoot`');
114
+ setComplementarySidebarState: (_nextState) => {
115
+ log.warn('Not initialized');
88
116
  },
89
117
  });
90
118
 
91
- const useSidebars = (consumerName = GENERIC_CONSUMER_NAME) => {
92
- const { setNavigationSidebarState, navigationSidebarState, setComplementarySidebarState, complementarySidebarState } =
93
- useMainContext(consumerName);
119
+ const useSidebars = (consumerName: string) => {
120
+ const {
121
+ navigationSidebarState,
122
+ setNavigationSidebarState,
123
+
124
+ complementarySidebarState,
125
+ setComplementarySidebarState,
126
+ } = useMainContext(consumerName);
94
127
 
95
128
  return {
96
129
  navigationSidebarState,
@@ -102,6 +135,7 @@ const useSidebars = (consumerName = GENERIC_CONSUMER_NAME) => {
102
135
  openNavigationSidebar: useCallback(() => setNavigationSidebarState('expanded'), []),
103
136
  collapseNavigationSidebar: useCallback(() => setNavigationSidebarState('collapsed'), []),
104
137
  closeNavigationSidebar: useCallback(() => setNavigationSidebarState('closed'), []),
138
+
105
139
  complementarySidebarState,
106
140
  setComplementarySidebarState,
107
141
  toggleComplementarySidebar: useCallback(
@@ -114,28 +148,33 @@ const useSidebars = (consumerName = GENERIC_CONSUMER_NAME) => {
114
148
  };
115
149
  };
116
150
 
151
+ //
152
+ // Root
153
+ //
154
+
117
155
  type MainRootProps = PropsWithChildren<{
118
156
  navigationSidebarState?: SidebarState;
119
157
  defaultNavigationSidebarState?: SidebarState;
120
158
  onNavigationSidebarStateChange?: (nextState: SidebarState) => void;
159
+
121
160
  complementarySidebarState?: SidebarState;
122
161
  defaultComplementarySidebarState?: SidebarState;
123
162
  onComplementarySidebarStateChange?: (nextState: SidebarState) => void;
124
163
  }>;
125
164
 
126
- const resizeDebounce = 3000;
127
-
128
165
  const MainRoot = ({
129
166
  navigationSidebarState: propsNavigationSidebarState,
130
- defaultNavigationSidebarState,
167
+ defaultNavigationSidebarState = 'closed',
131
168
  onNavigationSidebarStateChange,
169
+
132
170
  complementarySidebarState: propsComplementarySidebarState,
133
- defaultComplementarySidebarState,
171
+ defaultComplementarySidebarState = 'closed',
134
172
  onComplementarySidebarStateChange,
173
+
135
174
  children,
136
175
  ...props
137
176
  }: MainRootProps) => {
138
- const [isLg] = useMediaQuery('lg', { ssr: false });
177
+ const [isLg] = useMediaQuery('lg');
139
178
  const [navigationSidebarState = isLg ? 'expanded' : 'collapsed', setNavigationSidebarState] =
140
179
  useControllableState<SidebarState>({
141
180
  prop: propsNavigationSidebarState,
@@ -151,22 +190,21 @@ const MainRoot = ({
151
190
 
152
191
  const [resizing, setResizing] = useState(false);
153
192
  const resizeInterval = useRef<ReturnType<typeof setTimeout> | null>(null);
193
+ useEffect(
194
+ () =>
195
+ addEventListener(window, 'resize', () => {
196
+ setResizing(true);
197
+ if (resizeInterval.current) {
198
+ clearTimeout(resizeInterval.current);
199
+ }
154
200
 
155
- const handleResize = useCallback(() => {
156
- setResizing(true);
157
- if (resizeInterval.current) {
158
- clearTimeout(resizeInterval.current);
159
- }
160
- resizeInterval.current = setTimeout(() => {
161
- setResizing(false);
162
- resizeInterval.current = null;
163
- }, resizeDebounce);
164
- }, []);
165
-
166
- useEffect(() => {
167
- window.addEventListener('resize', handleResize);
168
- return () => window.removeEventListener('resize', handleResize);
169
- }, [handleResize]);
201
+ resizeInterval.current = setTimeout(() => {
202
+ setResizing(false);
203
+ resizeInterval.current = null;
204
+ }, 3_000);
205
+ }),
206
+ [],
207
+ );
170
208
 
171
209
  return (
172
210
  <MainProvider
@@ -186,16 +224,52 @@ const MainRoot = ({
186
224
 
187
225
  MainRoot.displayName = MAIN_ROOT_NAME;
188
226
 
189
- const handleOpenAutoFocus = (event: Event) => {
190
- !document.body.hasAttribute('data-is-keyboard') && event.preventDefault();
191
- };
227
+ //
228
+ // Overlay
229
+ //
230
+
231
+ type MainOverlayProps = ThemedClassName<Omit<ComponentPropsWithRef<typeof Primitive.div>, 'children' | 'onClick'>>;
232
+
233
+ const MainOverlay = forwardRef<HTMLDivElement, MainOverlayProps>(({ classNames, ...props }, forwardedRef) => {
234
+ const [isLg] = useMediaQuery('lg');
235
+ const { navigationSidebarState, setNavigationSidebarState, complementarySidebarState, setComplementarySidebarState } =
236
+ useMainContext(MAIN_OVERLAY_NAME);
237
+ const { tx } = useThemeContext();
238
+ return (
239
+ <div
240
+ {...props}
241
+ onClick={() => {
242
+ setNavigationSidebarState('collapsed');
243
+ setComplementarySidebarState('collapsed');
244
+ }}
245
+ className={tx(
246
+ 'main.overlay',
247
+ {
248
+ isLg,
249
+ inlineStartSidebarOpen: navigationSidebarState,
250
+ inlineEndSidebarOpen: complementarySidebarState,
251
+ },
252
+ classNames,
253
+ )}
254
+ data-state={navigationSidebarState === 'expanded' || complementarySidebarState === 'expanded' ? 'open' : 'closed'}
255
+ aria-hidden='true'
256
+ ref={forwardedRef}
257
+ />
258
+ );
259
+ });
260
+
261
+ MainOverlay.displayName = MAIN_OVERLAY_NAME;
262
+
263
+ //
264
+ // Sidebar
265
+ //
192
266
 
193
267
  type MainSidebarProps = ThemedClassName<ComponentPropsWithRef<typeof DialogContent>> & {
194
268
  swipeToDismiss?: boolean;
195
269
  state?: SidebarState;
196
270
  resizing?: boolean;
197
271
  onStateChange?: (nextState: SidebarState) => void;
198
- side: 'inline-start' | 'inline-end';
272
+ side: 'w-start' | 'w-end';
199
273
  label: Label;
200
274
  };
201
275
 
@@ -204,23 +278,31 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
204
278
  { classNames, children, swipeToDismiss, onOpenAutoFocus, state, resizing, onStateChange, side, label, ...props },
205
279
  forwardedRef,
206
280
  ) => {
207
- const [isLg] = useMediaQuery('lg', { ssr: false });
281
+ const [isLg] = useMediaQuery('lg');
208
282
  const { tx } = useThemeContext();
209
- const { t } = useTranslation();
283
+ const { t } = useTranslation(osTranslations);
210
284
  const ref = useForwardedRef(forwardedRef);
211
285
  const noopRef = useRef(null);
286
+
212
287
  useSwipeToDismiss(swipeToDismiss ? ref : noopRef, {
213
288
  onDismiss: () => onStateChange?.('closed'),
214
289
  });
290
+
291
+ // NOTE(thure): This is a workaround for something further down the tree grabbing focus on Escape. Adding this
292
+ // intervention to `Tabs.Root` or `Tabs.Tabpenel` instances is somehow ineffectual.
215
293
  const handleKeyDown = useCallback(
216
294
  (event: KeyboardEvent<HTMLDivElement>) => {
217
- if (event.key === 'Escape') {
218
- ((event.target as HTMLDivElement).closest('[data-tabster]') as HTMLDivElement)?.focus();
295
+ const focusGroupParent = (event.target as HTMLElement).closest('[data-tabster]');
296
+ if (event.key === 'Escape' && focusGroupParent) {
297
+ event.preventDefault();
298
+ event.stopPropagation();
299
+ (focusGroupParent as HTMLElement).focus();
219
300
  }
220
301
  props.onKeyDown?.(event);
221
302
  },
222
303
  [props.onKeyDown],
223
304
  );
305
+
224
306
  const Root = isLg ? Primitive.div : DialogContent;
225
307
 
226
308
  return (
@@ -228,13 +310,13 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
228
310
  {!isLg && <DialogTitle className='sr-only'>{toLocalizedString(label, t)}</DialogTitle>}
229
311
  <Root
230
312
  {...(!isLg && { forceMount: true, tabIndex: -1, onOpenAutoFocus: onOpenAutoFocus ?? handleOpenAutoFocus })}
313
+ {...(state === 'closed' && { inert: true })}
231
314
  {...props}
232
- data-side={side === 'inline-end' ? 'ie' : 'is'}
315
+ data-side={side === 'w-end' ? 'ie' : 'is'}
233
316
  data-state={state}
234
317
  data-resizing={resizing ? 'true' : 'false'}
235
- className={tx('main.sidebar', 'main__sidebar', {}, classNames)}
236
- onKeyDown={handleKeyDown}
237
- {...(state === 'closed' && { inert: 'true' })}
318
+ className={tx('main.sidebar', {}, classNames)}
319
+ onKeyDownCapture={handleKeyDown}
238
320
  ref={ref}
239
321
  >
240
322
  {children}
@@ -244,6 +326,10 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
244
326
  },
245
327
  );
246
328
 
329
+ //
330
+ // Navigation Sidebar
331
+ //
332
+
247
333
  type MainNavigationSidebarProps = Omit<MainSidebarProps, 'expanded' | 'side'>;
248
334
 
249
335
  const MainNavigationSidebar = forwardRef<HTMLDivElement, MainNavigationSidebarProps>((props, forwardedRef) => {
@@ -257,7 +343,7 @@ const MainNavigationSidebar = forwardRef<HTMLDivElement, MainNavigationSidebarPr
257
343
  state={navigationSidebarState}
258
344
  onStateChange={setNavigationSidebarState}
259
345
  resizing={resizing}
260
- side='inline-start'
346
+ side='w-start'
261
347
  ref={forwardedRef}
262
348
  />
263
349
  );
@@ -265,6 +351,10 @@ const MainNavigationSidebar = forwardRef<HTMLDivElement, MainNavigationSidebarPr
265
351
 
266
352
  MainNavigationSidebar.displayName = NAVIGATION_SIDEBAR_NAME;
267
353
 
354
+ //
355
+ // Complementary Sidebar
356
+ //
357
+
268
358
  type MainComplementarySidebarProps = Omit<MainSidebarProps, 'expanded' | 'side'>;
269
359
 
270
360
  const MainComplementarySidebar = forwardRef<HTMLDivElement, MainComplementarySidebarProps>((props, forwardedRef) => {
@@ -279,82 +369,63 @@ const MainComplementarySidebar = forwardRef<HTMLDivElement, MainComplementarySid
279
369
  state={complementarySidebarState}
280
370
  onStateChange={setComplementarySidebarState}
281
371
  resizing={resizing}
282
- side='inline-end'
372
+ side='w-end'
283
373
  ref={forwardedRef}
284
374
  />
285
375
  );
286
376
  });
287
377
 
288
- MainNavigationSidebar.displayName = NAVIGATION_SIDEBAR_NAME;
378
+ MainComplementarySidebar.displayName = COMPLEMENTARY_SIDEBAR_NAME;
289
379
 
290
- type MainProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.div>> & {
291
- asChild?: boolean;
292
- bounce?: boolean;
293
- handlesFocus?: boolean;
294
- };
380
+ //
381
+ // Content
382
+ //
383
+
384
+ type MainContentProps = ThemedClassName<
385
+ ComponentPropsWithRef<typeof Primitive.div> &
386
+ MainStyleProps & {
387
+ asChild?: boolean;
388
+ }
389
+ >;
295
390
 
296
- const MainContent = forwardRef<HTMLDivElement, MainProps>(
297
- ({ asChild, classNames, bounce, handlesFocus, children, role, ...props }: MainProps, forwardedRef) => {
391
+ const MainContent = forwardRef<HTMLDivElement, MainContentProps>(
392
+ ({ asChild, classNames, bounce, handlesFocus, children, role, ...props }: MainContentProps, forwardedRef) => {
298
393
  const { navigationSidebarState, complementarySidebarState } = useMainContext(MAIN_NAME);
299
394
  const { tx } = useThemeContext();
300
- const Root = asChild ? Slot : role ? 'div' : 'main';
301
-
395
+ const Comp = asChild ? Slot : role ? Primitive.div : 'main';
302
396
  const mover = useLandmarkMover(props.onKeyDown, '1');
303
397
 
304
398
  return (
305
- <Root
306
- role={role}
399
+ <Comp
307
400
  {...(handlesFocus && { ...mover })}
308
401
  {...props}
309
- data-sidebar-inline-start-state={navigationSidebarState}
310
- data-sidebar-inline-end-state={complementarySidebarState}
402
+ role={role}
403
+ data-sidebar-left-state={navigationSidebarState}
404
+ data-sidebar-right-state={complementarySidebarState}
311
405
  data-handles-focus={handlesFocus}
312
- className={tx('main.content', 'main', { bounce, handlesFocus }, classNames)}
406
+ className={tx('main.content', { bounce, handlesFocus }, classNames)}
313
407
  ref={forwardedRef}
314
408
  >
315
409
  {children}
316
- </Root>
410
+ </Comp>
317
411
  );
318
412
  },
319
413
  );
320
414
 
321
415
  MainContent.displayName = MAIN_NAME;
322
416
 
323
- type MainOverlayProps = ThemedClassName<Omit<ComponentPropsWithRef<typeof Primitive.div>, 'children'>>;
324
-
325
- const MainOverlay = forwardRef<HTMLDivElement, MainOverlayProps>(({ classNames, ...props }, forwardedRef) => {
326
- const [isLg] = useMediaQuery('lg', { ssr: false });
327
- const { navigationSidebarState, setNavigationSidebarState, complementarySidebarState, setComplementarySidebarState } =
328
- useMainContext(MAIN_NAME);
329
- const { tx } = useThemeContext();
330
- return (
331
- <div
332
- onClick={() => {
333
- setNavigationSidebarState('collapsed');
334
- setComplementarySidebarState('collapsed');
335
- }}
336
- {...props}
337
- className={tx(
338
- 'main.overlay',
339
- 'main__overlay',
340
- { isLg, inlineStartSidebarOpen: navigationSidebarState, inlineEndSidebarOpen: complementarySidebarState },
341
- classNames,
342
- )}
343
- data-state={navigationSidebarState === 'expanded' || complementarySidebarState === 'expanded' ? 'open' : 'closed'}
344
- aria-hidden='true'
345
- ref={forwardedRef}
346
- />
347
- );
348
- });
417
+ //
418
+ // Main
419
+ //
349
420
 
350
421
  export const Main = {
351
422
  Root: MainRoot,
352
- Content: MainContent,
353
423
  Overlay: MainOverlay,
424
+ Content: MainContent,
354
425
  NavigationSidebar: MainNavigationSidebar,
355
426
  ComplementarySidebar: MainComplementarySidebar,
356
427
  };
357
428
 
358
429
  export { useMainContext, useSidebars, useLandmarkMover };
359
430
 
360
- export type { MainRootProps, MainProps, MainOverlayProps, MainNavigationSidebarProps, SidebarState };
431
+ export type { MainRootProps, MainOverlayProps, MainContentProps, MainNavigationSidebarProps, SidebarState };
@@ -0,0 +1,50 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+
7
+ import { withTheme } from '@dxos/react-ui/testing';
8
+
9
+ import { MediaPlayer } from './MediaPlayer';
10
+
11
+ const meta = {
12
+ title: 'ui/react-ui-core/components/MediaPlayer',
13
+ component: MediaPlayer,
14
+ decorators: [withTheme()],
15
+ parameters: { layout: 'centered' },
16
+ } satisfies Meta<typeof MediaPlayer>;
17
+
18
+ export default meta;
19
+
20
+ type Story = StoryObj<typeof meta>;
21
+
22
+ export const Video: Story = {
23
+ args: {
24
+ // TODO(burdon): CORS issue.
25
+ src: 'https://customer-5rxcjpyab08avpmn.cloudflarestream.com/f58459bcdf3a6f3e93644a4e0f39b22a/downloads/default.mp4',
26
+ classNames: 'max-w-[640px]',
27
+ },
28
+ };
29
+
30
+ export const Audio: Story = {
31
+ args: {
32
+ src: 'https://commondatastorage.googleapis.com/codeskulptor-demos/DDR_assets/Kangaroo_MusiQue_-_The_Neverwritten_Role_Playing_Game.mp3',
33
+ classNames: 'min-w-[480px]',
34
+ },
35
+ };
36
+
37
+ export const ExplicitKind: Story = {
38
+ args: {
39
+ src: 'https://commondatastorage.googleapis.com/codeskulptor-demos/DDR_assets/Kangaroo_MusiQue_-_The_Neverwritten_Role_Playing_Game.mp3',
40
+ kind: 'audio',
41
+ classNames: 'min-w-[480px]',
42
+ },
43
+ };
44
+
45
+ export const Streaming: Story = {
46
+ args: {
47
+ src: 'https://customer-5rxcjpyab08avpmn.cloudflarestream.com/f58459bcdf3a6f3e93644a4e0f39b22a/iframe?poster=https%3A%2F%2Fcustomer-5rxcjpyab08avpmn.cloudflarestream.com%2Ff58459bcdf3a6f3e93644a4e0f39b22a%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600',
48
+ classNames: 'min-w-[480px]',
49
+ },
50
+ };
@@ -0,0 +1,153 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { mx } from '@dxos/ui-theme';
8
+
9
+ import { type ThemedClassName } from '../../util';
10
+
11
+ export type MediaKind = 'video' | 'audio';
12
+
13
+ const VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogv', '.mov', '.m4v'];
14
+ const AUDIO_EXTENSIONS = ['.mp3', '.wav', '.ogg', '.m4a', '.aac', '.flac'];
15
+
16
+ /** iframe sandbox flags compatible with typical oEmbed-style players. */
17
+ const DEFAULT_IFRAME_SANDBOX = 'allow-scripts allow-same-origin allow-presentation';
18
+
19
+ /**
20
+ * Best-effort detection of `video` vs `audio` from a media URL.
21
+ * Inspects the pathname's extension (ignoring query/hash). Returns `undefined`
22
+ * when the URL doesn't look like a recognised media file — callers should
23
+ * default to 'video' or render a fallback (e.g. iframe / img).
24
+ */
25
+ export const detectMediaKind = (src: string): MediaKind | undefined => {
26
+ // Strip query and hash, then take the last path segment's extension.
27
+ const pathname = src.split(/[?#]/, 1)[0]!;
28
+ const lower = pathname.toLowerCase();
29
+ if (VIDEO_EXTENSIONS.some((extension) => lower.endsWith(extension))) {
30
+ return 'video';
31
+ }
32
+ if (AUDIO_EXTENSIONS.some((extension) => lower.endsWith(extension))) {
33
+ return 'audio';
34
+ }
35
+
36
+ return undefined;
37
+ };
38
+
39
+ /**
40
+ * Heuristic match for URLs that should render as native `<video>` / `<audio>`
41
+ * (i.e. URLs ending in a recognised media extension).
42
+ *
43
+ * NB: legacy embed URLs (Cloudflare Stream etc. — paths containing `iframe`)
44
+ * serve an HTML player page, **not** a media stream, so they cannot be loaded
45
+ * via `<video>`. Those are detected by {@link isLegacyIframeUrl} and rendered
46
+ * via `<iframe>` instead.
47
+ */
48
+ export const isEmbedUrl = (src: string): boolean => detectMediaKind(src) !== undefined;
49
+
50
+ /** Match URLs whose pathname has an `/iframe` segment (e.g. Cloudflare Stream embeds). */
51
+ const LEGACY_IFRAME_PATH_PATTERN = /\/iframe(?:[/?#]|$)/i;
52
+
53
+ const isLegacyIframeUrl = (src: string): boolean => {
54
+ const pathAndQuery = src.split('#', 1)[0]!;
55
+ return LEGACY_IFRAME_PATH_PATTERN.test(pathAndQuery);
56
+ };
57
+
58
+ export type MediaPlayerProps = ThemedClassName<{
59
+ src: string;
60
+ /** Override auto-detection. When omitted, `detectMediaKind(src)` is used and falls back to 'video'. */
61
+ kind?: MediaKind;
62
+ controls?: boolean;
63
+ autoPlay?: boolean;
64
+ loop?: boolean;
65
+ muted?: boolean;
66
+ /** Accessible label for the `<video>` / `<audio>` element. */
67
+ alt?: string;
68
+ /** Defaults to 'anonymous' for cross-origin sources (e.g. signed S3 URLs). */
69
+ crossOrigin?: 'anonymous' | 'use-credentials' | '';
70
+ /** Additional classes applied only when rendering `<img>`. */
71
+ imgClassNames?: string;
72
+ /** Additional classes applied only when rendering native media or `<iframe>`. */
73
+ mediaClassNames?: string;
74
+ }>;
75
+
76
+ /**
77
+ * Renders a media URL using the appropriate element:
78
+ * - Direct media URLs (mp4, mp3, …) → native `<video>` / `<audio>`.
79
+ * - Legacy `iframe`-style embed URLs (Cloudflare Stream, oEmbed players) → `<iframe>`.
80
+ * - Everything else → `<img>` that hides itself on load failure (broken images
81
+ * are common in feeds and the placeholder is uglier than nothing).
82
+ */
83
+ export const MediaPlayer = ({
84
+ classNames,
85
+ src,
86
+ kind,
87
+ controls = true,
88
+ autoPlay = false,
89
+ loop = false,
90
+ muted = false,
91
+ alt,
92
+ crossOrigin = 'anonymous',
93
+ imgClassNames,
94
+ mediaClassNames,
95
+ }: MediaPlayerProps) => {
96
+ if (isEmbedUrl(src)) {
97
+ const resolved = kind ?? detectMediaKind(src) ?? 'video';
98
+ if (resolved === 'audio') {
99
+ return (
100
+ <audio
101
+ className={mx('w-full', classNames, mediaClassNames)}
102
+ src={src}
103
+ controls={controls}
104
+ autoPlay={autoPlay}
105
+ loop={loop}
106
+ muted={muted}
107
+ crossOrigin={crossOrigin}
108
+ aria-label={alt}
109
+ />
110
+ );
111
+ }
112
+
113
+ return (
114
+ <video
115
+ className={mx('aspect-video max-w-full max-h-full', classNames, mediaClassNames)}
116
+ src={src}
117
+ controls={controls}
118
+ autoPlay={autoPlay}
119
+ loop={loop}
120
+ muted={muted}
121
+ crossOrigin={crossOrigin}
122
+ aria-label={alt}
123
+ />
124
+ );
125
+ }
126
+
127
+ if (isLegacyIframeUrl(src)) {
128
+ return (
129
+ <iframe
130
+ src={src}
131
+ title={alt ?? 'Embedded media'}
132
+ loading='lazy'
133
+ className={mx('border-none', classNames, mediaClassNames)}
134
+ sandbox={DEFAULT_IFRAME_SANDBOX}
135
+ referrerPolicy='no-referrer'
136
+ allow='accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;'
137
+ allowFullScreen
138
+ />
139
+ );
140
+ }
141
+
142
+ return (
143
+ <img
144
+ src={src}
145
+ alt={alt ?? ''}
146
+ loading='lazy'
147
+ className={mx(classNames, imgClassNames)}
148
+ onError={(event) => {
149
+ event.currentTarget.style.display = 'none';
150
+ }}
151
+ />
152
+ );
153
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './MediaPlayer';