@dxos/react-ui 0.8.4-main.74a063c4e0 → 0.8.4-main.765dc60934

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 (220) 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-KRSEIVRM.mjs → chunk-BDBC6H6V.mjs} +74 -2
  6. package/dist/lib/browser/{chunk-KRSEIVRM.mjs.map → chunk-BDBC6H6V.mjs.map} +4 -4
  7. package/dist/lib/browser/index.mjs +653 -422
  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 +20 -13
  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-ENYC4TYH.mjs → chunk-3JSJK2ZY.mjs} +74 -2
  15. package/dist/lib/node-esm/{chunk-ENYC4TYH.mjs.map → chunk-3JSJK2ZY.mjs.map} +4 -4
  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 +653 -422
  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 +20 -13
  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.map +1 -1
  26. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  27. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  29. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  30. package/dist/types/src/components/Button/Button.stories.d.ts +1 -1
  31. package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -1
  32. package/dist/types/src/components/Button/IconButton.d.ts +1 -0
  33. package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
  34. package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -1
  35. package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/Button/ToggleGroup.d.ts +2 -2
  37. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +2 -2
  38. package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -1
  39. package/dist/types/src/components/Card/Card.d.ts +23 -49
  40. package/dist/types/src/components/Card/Card.d.ts.map +1 -1
  41. package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -1
  42. package/dist/types/src/components/Carousel/Carousel.d.ts +90 -0
  43. package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -0
  44. package/dist/types/src/components/Carousel/index.d.ts +2 -0
  45. package/dist/types/src/components/Carousel/index.d.ts.map +1 -0
  46. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  47. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  48. package/dist/types/src/components/Clipboard/index.d.ts +1 -1
  49. package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
  50. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  51. package/dist/types/src/components/Dialog/AlertDialog.d.ts +21 -23
  52. package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
  53. package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
  54. package/dist/types/src/components/Dialog/Dialog.d.ts +22 -24
  55. package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
  56. package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  58. package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -1
  59. package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -1
  60. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +14 -3
  61. package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -1
  62. package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -1
  63. package/dist/types/src/components/Focus/Focus.d.ts +2 -10
  64. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
  65. package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -1
  66. package/dist/types/src/components/Icon/Icon.d.ts +1 -0
  67. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  68. package/dist/types/src/components/Icon/Icon.stories.d.ts +1 -1
  69. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
  70. package/dist/types/src/components/Image/Image.d.ts +2 -1
  71. package/dist/types/src/components/Image/Image.d.ts.map +1 -1
  72. package/dist/types/src/components/Image/Image.stories.d.ts +3 -2
  73. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -1
  74. package/dist/types/src/components/Input/Input.d.ts +12 -15
  75. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  76. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  78. package/dist/types/src/components/List/List.d.ts +2 -6
  79. package/dist/types/src/components/List/List.d.ts.map +1 -1
  80. package/dist/types/src/components/List/List.stories.d.ts +2 -6
  81. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  82. package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -1
  83. package/dist/types/src/components/List/Tree.d.ts +2 -2
  84. package/dist/types/src/components/List/Tree.d.ts.map +1 -1
  85. package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -1
  86. package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -1
  87. package/dist/types/src/components/List/Treegrid.d.ts +1 -5
  88. package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
  89. package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -1
  90. package/dist/types/src/components/Main/Main.d.ts +7 -3
  91. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  92. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/Main/useSwipeToDismiss.d.ts.map +1 -1
  94. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts +30 -0
  95. package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts.map +1 -0
  96. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts +15 -0
  97. package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts.map +1 -0
  98. package/dist/types/src/components/MediaPlayer/index.d.ts +2 -0
  99. package/dist/types/src/components/MediaPlayer/index.d.ts.map +1 -0
  100. package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
  101. package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -1
  102. package/dist/types/src/components/Menu/DropdownMenu.d.ts +11 -3
  103. package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
  104. package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -1
  105. package/dist/types/src/components/Message/Message.d.ts +1 -1
  106. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  107. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  108. package/dist/types/src/components/Popover/Popover.d.ts +10 -2
  109. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  110. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  111. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +2 -10
  112. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  113. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +2 -10
  114. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  115. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +11 -15
  116. package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
  117. package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
  118. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  119. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  120. package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/Splitter/Splitter.d.ts +3 -11
  122. package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -1
  123. package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -1
  124. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  125. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  126. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  127. package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -1
  128. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +54 -55
  129. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  130. package/dist/types/src/components/ThemeProvider/index.d.ts +1 -1
  131. package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
  132. package/dist/types/src/components/Toast/Toast.d.ts +4 -4
  133. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  134. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  135. package/dist/types/src/components/Toolbar/Toolbar.d.ts +5 -13
  136. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  137. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  138. package/dist/types/src/components/Tooltip/Tooltip.d.ts +2 -2
  139. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  140. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  141. package/dist/types/src/components/index.d.ts +2 -0
  142. package/dist/types/src/components/index.d.ts.map +1 -1
  143. package/dist/types/src/exemplars/generics.stories.d.ts +1 -5
  144. package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -1
  145. package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -1
  146. package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -1
  147. package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -1
  148. package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
  149. package/dist/types/src/hooks/useElevationContext.d.ts.map +1 -1
  150. package/dist/types/src/hooks/useIconHref.d.ts.map +1 -1
  151. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  152. package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -1
  153. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  154. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  155. package/dist/types/src/playground/Custom.stories.d.ts +1 -1
  156. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  157. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  158. package/dist/types/src/primitives/Column/Column.d.ts +11 -29
  159. package/dist/types/src/primitives/Column/Column.d.ts.map +1 -1
  160. package/dist/types/src/primitives/Column/Column.stories.d.ts +7 -7
  161. package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -1
  162. package/dist/types/src/primitives/Container/Container.d.ts +1 -5
  163. package/dist/types/src/primitives/Container/Container.d.ts.map +1 -1
  164. package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -1
  165. package/dist/types/src/primitives/Flex/Flex.d.ts +1 -5
  166. package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -1
  167. package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -1
  168. package/dist/types/src/primitives/Grid/Grid.d.ts +1 -5
  169. package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -1
  170. package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -1
  171. package/dist/types/src/primitives/Panel/Panel.d.ts +4 -20
  172. package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -1
  173. package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -1
  174. package/dist/types/src/testing/Loading.d.ts.map +1 -1
  175. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
  176. package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
  177. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  178. package/dist/types/src/translations.d.ts +8 -3
  179. package/dist/types/src/translations.d.ts.map +1 -1
  180. package/dist/types/src/util/usePx.d.ts.map +1 -1
  181. package/dist/types/tsconfig.tsbuildinfo +1 -1
  182. package/package.json +27 -25
  183. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -1
  184. package/src/components/Button/IconButton.stories.tsx +1 -1
  185. package/src/components/Button/IconButton.tsx +3 -2
  186. package/src/components/Card/Card.stories.tsx +3 -3
  187. package/src/components/Card/Card.tsx +42 -20
  188. package/src/components/Carousel/Carousel.tsx +339 -0
  189. package/src/components/Carousel/index.ts +5 -0
  190. package/src/components/Clipboard/CopyButton.tsx +2 -2
  191. package/src/components/Dialog/Dialog.stories.tsx +2 -2
  192. package/src/components/Dialog/Dialog.tsx +29 -29
  193. package/src/components/ErrorFallback/ErrorStack.tsx +36 -2
  194. package/src/components/Icon/Icon.tsx +10 -3
  195. package/src/components/Image/Image.tsx +31 -8
  196. package/src/components/Input/Input.tsx +3 -3
  197. package/src/components/List/List.stories.tsx +1 -1
  198. package/src/components/List/List.tsx +1 -1
  199. package/src/components/List/ListDropIndicator.tsx +0 -1
  200. package/src/components/List/Tree.stories.tsx +1 -1
  201. package/src/components/MediaPlayer/MediaPlayer.stories.tsx +42 -0
  202. package/src/components/MediaPlayer/MediaPlayer.tsx +97 -0
  203. package/src/components/MediaPlayer/index.ts +5 -0
  204. package/src/components/Message/Message.stories.tsx +1 -1
  205. package/src/components/Message/Message.tsx +24 -7
  206. package/src/components/ScrollArea/ScrollArea.stories.tsx +1 -5
  207. package/src/components/ScrollContainer/ScrollContainer.tsx +1 -3
  208. package/src/components/ThemeProvider/index.ts +1 -1
  209. package/src/components/Toolbar/Toolbar.tsx +4 -2
  210. package/src/components/Tooltip/Tooltip.stories.tsx +1 -1
  211. package/src/components/index.ts +2 -0
  212. package/src/exemplars/slot.stories.tsx +2 -4
  213. package/src/exemplars/virtualizer.stories.tsx +0 -1
  214. package/src/playground/Custom.stories.tsx +13 -6
  215. package/src/primitives/Column/AUDIT.md +105 -311
  216. package/src/primitives/Column/Column.stories.tsx +58 -59
  217. package/src/primitives/Column/Column.tsx +54 -58
  218. package/src/testing/Loading.tsx +24 -4
  219. package/src/testing/decorators/withLayout.tsx +7 -17
  220. package/src/translations.ts +5 -0
@@ -7,7 +7,6 @@ import React from 'react';
7
7
 
8
8
  import { Input, ScrollArea } from '../../components';
9
9
  import { withLayout, withTheme } from '../../testing';
10
- import { Flex } from '../Flex';
11
10
  import { Column } from './Column';
12
11
 
13
12
  const List = () => {
@@ -27,9 +26,9 @@ const List = () => {
27
26
  const DefaultStory = () => {
28
27
  return (
29
28
  <Column.Root classNames='overflow-hidden' gutter='md'>
30
- <Column.Row center>
29
+ <Column.Center>
31
30
  <h1 className='p-1 bg-blue-500 text-black'>Header</h1>
32
- </Column.Row>
31
+ </Column.Center>
33
32
 
34
33
  <Column.Row>
35
34
  <div className='p-1 bg-blue-500'>A</div>
@@ -37,34 +36,36 @@ const DefaultStory = () => {
37
36
  <div className='p-1 bg-blue-500'>C</div>
38
37
  </Column.Row>
39
38
 
40
- <Column.Row asChild center>
41
- <div className='py-2'>
39
+ <Column.Center asChild>
40
+ <div>
42
41
  <Input.Root>
43
42
  <Input.TextInput placeholder='Search' />
44
43
  </Input.Root>
45
44
  </div>
46
- </Column.Row>
45
+ </Column.Center>
47
46
 
48
- <Column.Viewport asChild>
49
- <div className='flex flex-col gap-2'>
50
- {Array.from({ length: 100 }).map((_, i) => (
51
- <Input.Root key={i}>
52
- <Input.TextInput value={`Item ${i}`} readOnly />
53
- </Input.Root>
54
- ))}
55
- </div>
56
- </Column.Viewport>
47
+ <ScrollArea.Root orientation='vertical' padding>
48
+ <ScrollArea.Viewport>
49
+ <div className='flex flex-col gap-2'>
50
+ {Array.from({ length: 100 }).map((_, i) => (
51
+ <Input.Root key={i}>
52
+ <Input.TextInput value={`Item ${i}`} readOnly />
53
+ </Input.Root>
54
+ ))}
55
+ </div>
56
+ </ScrollArea.Viewport>
57
+ </ScrollArea.Root>
57
58
 
58
- <Column.Row asChild center>
59
- <Flex column>
59
+ <Column.Center asChild>
60
+ <div className='flex flex-col'>
60
61
  <h1 className='p-1 bg-red-500 text-black'>Section with overflow</h1>
61
62
  <pre className='p-1 text-xs text-subdued overflow-auto'>{new Error().stack}</pre>
62
- </Flex>
63
- </Column.Row>
63
+ </div>
64
+ </Column.Center>
64
65
 
65
- <Column.Row center>
66
+ <Column.Center>
66
67
  <div className='p-1 bg-green-500 text-black'>Footer</div>
67
- </Column.Row>
68
+ </Column.Center>
68
69
  </Column.Root>
69
70
  );
70
71
  };
@@ -98,68 +99,66 @@ export const WithScrollArea = {
98
99
  decorators: [withLayout({ layout: 'column' })],
99
100
  render: () => (
100
101
  <Column.Root classNames='overflow-hidden' gutter='md'>
101
- <Column.Row center>
102
- <h2 className='py-3'>Header</h2>
103
- </Column.Row>
104
- <ScrollArea.Root padding centered orientation='vertical' classNames='col-span-full'>
102
+ <Column.Center>
103
+ <h2>Header</h2>
104
+ </Column.Center>
105
+ <ScrollArea.Root padding centered orientation='vertical'>
105
106
  <ScrollArea.Viewport>
106
107
  <InputList items={30} />
107
108
  </ScrollArea.Viewport>
108
109
  </ScrollArea.Root>
109
- <Column.Row center>
110
- <h2 className='py-3'>Footer</h2>
111
- </Column.Row>
110
+ <Column.Center>
111
+ <h2>Footer</h2>
112
+ </Column.Center>
112
113
  </Column.Root>
113
114
  ),
114
115
  };
115
116
 
116
117
  /**
117
- * Column.Content provides gutter padding for non-scrolling content.
118
- * Compare with Column.Row which uses subgrid for gutter alignment.
118
+ * Column.Center places a single element in the center column of the parent grid.
119
+ * Preferred for centered content safe to nest
120
+ * compound components (Form.Root, Editor.Root, etc.) that render `display: contents`.
119
121
  */
120
- export const WithContent: Story = {
121
- decorators: [withLayout({ layout: 'column', classNames: 'w-[25rem]' })],
122
+ export const WithCenter: Story = {
123
+ decorators: [withLayout({ classNames: 'w-[25rem]' })],
122
124
  render: () => (
123
- <Column.Root classNames='overflow-hidden' gutter='md'>
124
- <Column.Row center>
125
- <h2 className='py-3'>Header (Column.Row)</h2>
126
- </Column.Row>
127
- <Column.Content>
128
- <p className='py-2'>This text is inside Column.Content. It gets gutter padding automatically.</p>
125
+ <Column.Root gutter='md'>
126
+ <Column.Center>
127
+ <h2>Header (Column.Center)</h2>
128
+ </Column.Center>
129
+ <Column.Center classNames='flex flex-col'>
130
+ <p>This text is inside Column.Center. It sits in the central column between the gutters.</p>
129
131
  <Input.Root>
130
132
  <Input.Label>Name</Input.Label>
131
133
  <Input.TextInput placeholder='Enter name' />
132
134
  </Input.Root>
133
- </Column.Content>
134
- <Column.Row center>
135
- <h2 className='py-3'>Footer (Column.Row)</h2>
136
- </Column.Row>
135
+ </Column.Center>
136
+ <Column.Center>
137
+ <h2>Footer (Column.Center)</h2>
138
+ </Column.Center>
137
139
  </Column.Root>
138
140
  ),
139
141
  };
140
142
 
141
143
  /**
142
- * Column.Content with a nested ScrollArea.
143
- * The ScrollArea breaks out of Content's gutter padding via `--gutter-offset`
144
- * and applies its own asymmetric padding (accounting for scrollbar width).
144
+ * ScrollArea auto-bleeds inside Column.Root (via [.dx-column_&]:col-span-full).
145
+ * No Column.Bleed wrapper needed.
145
146
  */
146
- export const ContentWithScrollArea: Story = {
147
+ export const WithScrollAreaAutoBleed: Story = {
147
148
  decorators: [withLayout({ layout: 'column', classNames: 'w-[25rem]' })],
148
149
  render: () => (
149
150
  <Column.Root classNames='overflow-hidden' gutter='md'>
150
- <Column.Row center>
151
- <h2 className='py-3'>Header (Column.Row)</h2>
152
- </Column.Row>
153
- <Column.Content>
154
- <ScrollArea.Root orientation='vertical' padding thin>
155
- <ScrollArea.Viewport>
156
- <InputList items={30} />
157
- </ScrollArea.Viewport>
158
- </ScrollArea.Root>
159
- </Column.Content>
160
- <Column.Row center>
161
- <h2 className='py-3'>Footer (Column.Row)</h2>
162
- </Column.Row>
151
+ <Column.Center>
152
+ <h2>Header (Column.Center)</h2>
153
+ </Column.Center>
154
+ <ScrollArea.Root orientation='vertical' padding thin>
155
+ <ScrollArea.Viewport>
156
+ <InputList items={30} />
157
+ </ScrollArea.Viewport>
158
+ </ScrollArea.Root>
159
+ <Column.Center>
160
+ <h2>Footer (Column.Center)</h2>
161
+ </Column.Center>
163
162
  </Column.Root>
164
163
  ),
165
164
  };
@@ -6,10 +6,9 @@ import { Primitive } from '@radix-ui/react-primitive';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
7
  import React, { type CSSProperties } from 'react';
8
8
 
9
- import { type ColumnStyleProps, composableProps, slottable } from '@dxos/ui-theme';
9
+ import { composableProps, slottable } from '@dxos/ui-theme';
10
10
  import { type SlottableProps } from '@dxos/ui-types';
11
11
 
12
- import { ScrollArea, type ScrollAreaRootProps } from '../../components';
13
12
  import { useThemeContext } from '../../hooks';
14
13
 
15
14
  //
@@ -31,13 +30,18 @@ type ColumnRootProps = { gutter?: GutterSize };
31
30
 
32
31
  /**
33
32
  * Creates a 3-column CSS grid with left/right gutter columns and a center content column.
34
- * Sets the `--gutter` CSS variable for nested components.
33
+ * Sets `--gutter` and `--dx-col` CSS variables for nested components.
35
34
  *
36
- * Direct children participate in the grid in one of three ways:
35
+ * `--dx-col` defaults to `2 / span 1` (center column),
36
+ * enabling `withColumn` utilities to cascade the correct grid placement to slotted children.
37
+ *
38
+ * Direct children participate in the grid in one of several ways:
39
+ * - **Column.Center** — places element in the center column (col 2). Preferred for plain content.
40
+ * - **Column.Bleed** — spans all 3 columns gutter-to-gutter. Preferred for `ScrollArea` and
41
+ * other content that should ignore the gutters.
37
42
  * - **Column.Row** — 3-col subgrid row (icons in gutters, content in center).
38
- * - **Column.Content** — spans full width; re-applies gutters as `px-[var(--gutter)]` padding.
39
- * Sets `--gutter-offset` so nested ScrollAreas can break out of the padding.
40
- * - **Column.Viewport** — spans full width; delegates gutters to ScrollArea.
43
+ *
44
+ * Use `withColumn.center()` / `withColumn.bleed()` helpers to apply placement on slotted elements.
41
45
  *
42
46
  * Gutter sizes: `'sm'` for compact layouts (Dialog); `'md'` (default); `'lg'` for wider spacing.
43
47
  */
@@ -54,6 +58,7 @@ const ColumnRoot = slottable<HTMLDivElement, ColumnRootProps>(
54
58
  style={
55
59
  {
56
60
  '--gutter': gutterSize,
61
+ '--dx-col': '2 / span 1',
57
62
  gridTemplateColumns: [gutterSize, 'minmax(0,1fr)', gutterSize].join(' '),
58
63
  } as CSSProperties
59
64
  }
@@ -74,86 +79,77 @@ ColumnRoot.displayName = COLUMN_ROOT_NAME;
74
79
 
75
80
  const COLUMN_ROW_NAME = 'Column.Row';
76
81
 
77
- type ColumnRowProps = ColumnStyleProps;
82
+ type ColumnRowProps = {};
78
83
 
79
84
  /**
80
85
  * Spans all 3 columns of the parent Column.Root and uses CSS subgrid to inherit their sizing.
81
86
  * Children map to: [col-1: icon/slot] [col-2: content] [col-3: icon/action].
82
87
  * Must be a direct child of Column.Root.
83
88
  */
84
- const ColumnRow = slottable<HTMLDivElement, ColumnRowProps>(
85
- ({ children, asChild, role, fullWidth, center, ...props }, forwardedRef) => {
86
- const { className, ...rest } = composableProps(props);
87
- const Comp = asChild ? Slot : Primitive.div;
88
- const { tx } = useThemeContext();
89
- return (
90
- <Comp
91
- {...rest}
92
- role={role ?? 'none'}
93
- className={tx('column.row', { fullWidth, center }, className)}
94
- ref={forwardedRef}
95
- >
96
- {children}
97
- </Comp>
98
- );
99
- },
100
- );
89
+ const ColumnRow = slottable<HTMLDivElement, ColumnRowProps>(({ children, asChild, role, ...props }, forwardedRef) => {
90
+ const { className, ...rest } = composableProps(props);
91
+ const Comp = asChild ? Slot : Primitive.div;
92
+ const { tx } = useThemeContext();
93
+ return (
94
+ <Comp {...rest} role={role ?? 'none'} className={tx('column.row', {}, className)} ref={forwardedRef}>
95
+ {children}
96
+ </Comp>
97
+ );
98
+ });
101
99
 
102
100
  ColumnRow.displayName = COLUMN_ROW_NAME;
103
101
 
104
102
  //
105
- // Content
103
+ // Bleed
106
104
  //
107
105
 
108
- const COLUMN_CONTENT_NAME = 'Column.Content';
106
+ const COLUMN_BLEED_NAME = 'Column.Bleed';
109
107
 
110
- type ColumnContentProps = SlottableProps;
108
+ type ColumnBleedProps = SlottableProps;
111
109
 
112
110
  /**
113
- * Full-width content area that inherits Column.Root's 3-column grid via CSS subgrid.
114
- * Non-scrolling children default to the center column (between gutters).
115
- * ScrollArea children span all 3 columns via `[.dx-column_&]:col-span-full`.
111
+ * Spans all 3 columns of the parent Column.Root (gutter-to-gutter).
112
+ * Establishes a CSS subgrid so that grandchildren can participate in the parent column tracks.
113
+ * Use for `ScrollArea`, full-width dividers, tables, or any content that should ignore the gutters.
116
114
  */
117
- const ColumnContent = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
115
+ const ColumnBleed = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
118
116
  const { tx } = useThemeContext();
119
117
  const { className, ...rest } = composableProps(props);
120
118
  const Comp = asChild ? Slot : Primitive.div;
121
119
  return (
122
- <Comp {...rest} className={tx('column.content', {}, className)} ref={forwardedRef}>
120
+ <Comp {...rest} className={tx('column.bleed', {}, className)} ref={forwardedRef}>
123
121
  {children}
124
122
  </Comp>
125
123
  );
126
124
  });
127
125
 
128
- ColumnContent.displayName = COLUMN_CONTENT_NAME;
126
+ ColumnBleed.displayName = COLUMN_BLEED_NAME;
129
127
 
130
128
  //
131
- // Viewport
129
+ // Center
132
130
  //
133
131
 
134
- const COLUMN_VIEWPORT_NAME = 'Column.Viewport';
132
+ const COLUMN_CENTER_NAME = 'Column.Center';
135
133
 
136
- type ColumnViewportProps = Pick<ScrollAreaRootProps, 'thin'>;
134
+ type ColumnCenterProps = SlottableProps;
137
135
 
138
- const ColumnViewport = slottable<HTMLDivElement, ColumnViewportProps>(
139
- ({ children, asChild, role, ...props }, forwardedRef) => {
140
- const { tx } = useThemeContext();
141
- const { className, ...rest } = composableProps(props);
142
- return (
143
- <ScrollArea.Root
144
- {...rest}
145
- className={tx('column.viewport', {}, className)}
146
- orientation='vertical'
147
- padding
148
- ref={forwardedRef}
149
- >
150
- <ScrollArea.Viewport>{children}</ScrollArea.Viewport>
151
- </ScrollArea.Root>
152
- );
153
- },
154
- );
136
+ /**
137
+ * Places its element in column 2 (the center track between gutters) of the parent Column.Root.
138
+ * Does NOT use subgrid — placement is explicit on this element only, so it is safe to nest
139
+ * arbitrary compound components (including ones that render `display: contents` wrappers).
140
+ */
141
+ const ColumnCenter = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
142
+ const { tx } = useThemeContext();
143
+ const { className, ...rest } = composableProps(props);
144
+ const Comp = asChild ? Slot : Primitive.div;
145
+ return (
146
+ <Comp {...rest} className={tx('column.center', {}, className)} ref={forwardedRef}>
147
+ {children}
148
+ </Comp>
149
+ );
150
+ });
155
151
 
156
- ColumnViewport.displayName = COLUMN_VIEWPORT_NAME;
152
+ ColumnCenter.displayName = COLUMN_CENTER_NAME;
157
153
 
158
154
  //
159
155
  // Column
@@ -161,9 +157,9 @@ ColumnViewport.displayName = COLUMN_VIEWPORT_NAME;
161
157
 
162
158
  export const Column = {
163
159
  Root: ColumnRoot,
164
- Content: ColumnContent,
165
- Viewport: ColumnViewport,
166
160
  Row: ColumnRow,
161
+ Bleed: ColumnBleed,
162
+ Center: ColumnCenter,
167
163
  };
168
164
 
169
- export type { ColumnRootProps, ColumnContentProps, ColumnViewportProps, ColumnRowProps };
165
+ export type { ColumnRootProps, ColumnRowProps, ColumnBleedProps, ColumnCenterProps };
@@ -2,11 +2,13 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React, { useEffect, useState } from 'react';
5
+ import React, { captureOwnerStack, useEffect, useState } from 'react';
6
6
 
7
7
  import { mx } from '@dxos/ui-theme';
8
8
  import { safeStringify } from '@dxos/util';
9
9
 
10
+ import { ErrorStack, parseCaptureOwnerStack } from '../components';
11
+
10
12
  export type LoadingProps = { data?: any };
11
13
 
12
14
  /**
@@ -14,14 +16,32 @@ export type LoadingProps = { data?: any };
14
16
  */
15
17
  export const Loading = ({ data }: LoadingProps) => {
16
18
  const [visible, setVisible] = useState(false);
19
+ const ownerFrames = parseCaptureOwnerStack(captureOwnerStack());
20
+
17
21
  useEffect(() => {
18
22
  const t = setTimeout(() => setVisible(true), 500);
19
23
  return () => clearTimeout(t);
20
24
  }, []);
25
+
21
26
  return (
22
- <div className={mx('flex flex-col opacity-0 transition delay-1000 duration-1000', visible && 'opacity-100')}>
23
- <h2 className='uppercase'>Loading</h2>
24
- <pre>{safeStringify(data, undefined, 2)}</pre>
27
+ <div className='w-full p-2'>
28
+ <div
29
+ className={mx(
30
+ 'flex flex-col w-full p-2 border-2 border-teal-500 rounded-md',
31
+ 'opacity-0 transition delay-1000 duration-1000',
32
+ visible && 'opacity-100',
33
+ )}
34
+ >
35
+ <h2 className='uppercase capitalize text-xs'>Loading State</h2>
36
+ <pre className='text-sm text-description'>{safeStringify(data, undefined, 2)}</pre>
37
+
38
+ <h3 className='uppercase capitalize text-xs mt-2'>Owner stack</h3>
39
+ {ownerFrames && ownerFrames.length > 0 ? (
40
+ <ErrorStack frames={ownerFrames} />
41
+ ) : (
42
+ <p className='text-xs text-subdued'>No owner stack (production build or unsupported context).</p>
43
+ )}
44
+ </div>
25
45
  </div>
26
46
  );
27
47
  };
@@ -39,7 +39,7 @@ export const withLayout =
39
39
  const { layout = 'default', classNames, scroll } = props;
40
40
  const Container = layouts[layout] ?? layouts.fullscreen;
41
41
  return (
42
- <Container classNames={mx(classNames, scroll ? 'overflow-y-auto' : 'overflow-hidden')}>
42
+ <Container classNames={mx(scroll ? 'overflow-y-auto' : 'overflow-hidden', classNames)}>
43
43
  <MemoizedStory />
44
44
  </Container>
45
45
  );
@@ -47,31 +47,21 @@ export const withLayout =
47
47
  };
48
48
 
49
49
  const layouts: Record<ContainerType, FC<ContainerProps>> = {
50
- default: ({ classNames, children }: ContainerProps) => (
51
- <div role='none' className={mx('p-4', classNames)}>
52
- {children}
53
- </div>
54
- ),
50
+ default: ({ classNames, children }: ContainerProps) => <div className={mx('p-4', classNames)}>{children}</div>,
55
51
 
56
52
  fullscreen: ({ classNames, children }: ContainerProps) => (
57
- <div role='none' className={mx('fixed inset-0 flex overflow-hidden bg-black', classNames)}>
58
- {children}
59
- </div>
53
+ <div className={mx('fixed inset-0 flex overflow-hidden bg-black', classNames)}>{children}</div>
60
54
  ),
61
55
 
62
56
  centered: ({ classNames, children }: ContainerProps) => (
63
- <div role='none' className={mx('fixed inset-0 grid overflow-hidden place-items-center bg-black')}>
64
- <div role='none' className={mx('flex flex-col bg-base-surface', classNames)}>
65
- {children}
66
- </div>
57
+ <div className={mx('fixed inset-0 grid overflow-hidden place-items-center bg-black')}>
58
+ <div className={mx('flex flex-col bg-base-surface', classNames)}>{children}</div>
67
59
  </div>
68
60
  ),
69
61
 
70
62
  column: ({ classNames, children }: ContainerProps) => (
71
- <div role='none' className='fixed inset-0 flex overflow-hidden justify-center bg-black'>
72
- <div role='none' className={mx('flex flex-col w-[40rem] bg-base-surface', classNames)}>
73
- {children}
74
- </div>
63
+ <div className='fixed inset-0 flex overflow-hidden justify-center bg-black'>
64
+ <div className={mx('flex flex-col w-[40rem] bg-base-surface', classNames)}>{children}</div>
75
65
  </div>
76
66
  ),
77
67
  };
@@ -13,6 +13,11 @@ export const translations = [
13
13
  'toolbar-menu.label': 'Action menu',
14
14
  'toolbar-drag-handle.label': 'Drag to rearrange',
15
15
  'toolbar-close.label': 'Close',
16
+ 'carousel-viewport.label': 'Carousel',
17
+ 'carousel-prev.label': 'Previous slide',
18
+ 'carousel-next.label': 'Next slide',
19
+ 'carousel-indicators.label': 'Carousel slides',
20
+ 'carousel-go-to.label': 'Go to slide {{index}}',
16
21
  },
17
22
  },
18
23
  },