@dxos/react-ui 0.8.4-main.84f28bd → 0.8.4-main.ae835ea

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 (211) hide show
  1. package/dist/lib/browser/{chunk-T6YPS45E.mjs → chunk-HUZZ56DW.mjs} +323 -190
  2. package/dist/lib/browser/chunk-HUZZ56DW.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +7 -1
  4. package/dist/lib/browser/index.mjs.map +1 -1
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +54 -27
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/{chunk-TYVQJ4KW.mjs → chunk-OJLL6E2Z.mjs} +323 -190
  9. package/dist/lib/node-esm/chunk-OJLL6E2Z.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +7 -1
  11. package/dist/lib/node-esm/index.mjs.map +1 -1
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +54 -27
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
  16. package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
  17. package/dist/types/src/components/Avatars/Avatar.stories.d.ts +5 -31
  18. package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts +5 -11
  20. package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts +1 -1
  22. package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
  23. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts +8 -20
  24. package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
  25. package/dist/types/src/components/Buttons/Button.d.ts +1 -1
  26. package/dist/types/src/components/Buttons/Button.d.ts.map +1 -1
  27. package/dist/types/src/components/Buttons/Button.stories.d.ts +9 -4
  28. package/dist/types/src/components/Buttons/Button.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Buttons/IconButton.d.ts +2 -2
  30. package/dist/types/src/components/Buttons/IconButton.d.ts.map +1 -1
  31. package/dist/types/src/components/Buttons/IconButton.stories.d.ts +6 -15
  32. package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +1 -1
  33. package/dist/types/src/components/Buttons/Toggle.stories.d.ts +5 -11
  34. package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +1 -1
  35. package/dist/types/src/components/Buttons/ToggleGroup.d.ts +7 -8
  36. package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +1 -1
  37. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +7 -19
  38. package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +1 -1
  39. package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
  40. package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
  41. package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
  42. package/dist/types/src/components/Dialogs/AlertDialog.d.ts +1 -1
  43. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +1 -1
  44. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +7 -39
  45. package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/Dialogs/Dialog.d.ts +1 -1
  47. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +1 -1
  48. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +6 -29
  49. package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +1 -1
  50. package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
  51. package/dist/types/src/components/Icon/Icon.d.ts +1 -1
  52. package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
  53. package/dist/types/src/components/Icon/Icon.stories.d.ts +17 -0
  54. package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
  55. package/dist/types/src/components/Input/Input.d.ts +2 -4
  56. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  57. package/dist/types/src/components/Input/Input.stories.d.ts +10 -11
  58. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  59. package/dist/types/src/components/Link/Link.stories.d.ts +8 -8
  60. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  61. package/dist/types/src/components/Lists/List.d.ts +2 -2
  62. package/dist/types/src/components/Lists/List.d.ts.map +1 -1
  63. package/dist/types/src/components/Lists/List.stories.d.ts +8 -31
  64. package/dist/types/src/components/Lists/List.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Lists/Tree.d.ts +1 -1
  66. package/dist/types/src/components/Lists/Tree.d.ts.map +1 -1
  67. package/dist/types/src/components/Lists/Tree.stories.d.ts +6 -32
  68. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +1 -1
  69. package/dist/types/src/components/Lists/Treegrid.d.ts +1 -1
  70. package/dist/types/src/components/Lists/Treegrid.d.ts.map +1 -1
  71. package/dist/types/src/components/Lists/Treegrid.stories.d.ts +6 -4
  72. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +1 -1
  73. package/dist/types/src/components/Main/Main.d.ts +2 -11
  74. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  75. package/dist/types/src/components/Main/Main.stories.d.ts +6 -7
  76. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +1 -1
  78. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +6 -44
  79. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +1 -1
  80. package/dist/types/src/components/Menus/DropdownMenu.d.ts +6 -5
  81. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +1 -1
  82. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +6 -41
  83. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +1 -1
  84. package/dist/types/src/components/Message/Message.d.ts +1 -1
  85. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  86. package/dist/types/src/components/Message/Message.stories.d.ts +7 -16
  87. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  88. package/dist/types/src/components/Popover/Popover.d.ts +2 -2
  89. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  90. package/dist/types/src/components/Popover/Popover.stories.d.ts +6 -34
  91. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  92. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +1 -1
  93. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  94. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +6 -32
  95. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  96. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  97. package/dist/types/src/components/Select/Select.stories.d.ts +4 -9
  98. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  99. package/dist/types/src/components/Status/Status.stories.d.ts +2 -8
  100. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  101. package/dist/types/src/components/Tag/Tag.stories.d.ts +12 -12
  102. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  103. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +1 -1
  104. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  105. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -1
  106. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  107. package/dist/types/src/components/Toast/Toast.d.ts +1 -1
  108. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  109. package/dist/types/src/components/Toast/Toast.stories.d.ts +6 -44
  110. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  111. package/dist/types/src/components/Toolbar/Toolbar.d.ts +12 -12
  112. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  113. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +6 -50
  114. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  115. package/dist/types/src/components/Tooltip/Tooltip.d.ts +2 -4
  116. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  117. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +8 -61
  118. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  119. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  120. package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
  121. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  122. package/dist/types/src/playground/Controls.stories.d.ts +5 -9
  123. package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
  124. package/dist/types/src/playground/Custom.stories.d.ts +12 -4
  125. package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
  126. package/dist/types/src/playground/Typography.stories.d.ts +5 -11
  127. package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
  128. package/dist/types/src/testing/decorators/index.d.ts +2 -1
  129. package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
  130. package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
  131. package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
  132. package/dist/types/src/testing/decorators/withTheme.d.ts +3 -0
  133. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  134. package/dist/types/src/util/domino.d.ts +18 -0
  135. package/dist/types/src/util/domino.d.ts.map +1 -0
  136. package/dist/types/src/util/index.d.ts +3 -1
  137. package/dist/types/src/util/index.d.ts.map +1 -1
  138. package/dist/types/src/util/usePx.d.ts +8 -0
  139. package/dist/types/src/util/usePx.d.ts.map +1 -0
  140. package/dist/types/tsconfig.tsbuildinfo +1 -1
  141. package/package.json +23 -22
  142. package/src/components/Avatars/Avatar.stories.tsx +19 -10
  143. package/src/components/Avatars/Avatar.tsx +3 -3
  144. package/src/components/Avatars/AvatarGroup.stories.tsx +10 -6
  145. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +16 -11
  146. package/src/components/Breadcrumb/Breadcrumb.tsx +3 -3
  147. package/src/components/Buttons/Button.stories.tsx +10 -11
  148. package/src/components/Buttons/IconButton.stories.tsx +11 -8
  149. package/src/components/Buttons/IconButton.tsx +4 -3
  150. package/src/components/Buttons/Toggle.stories.tsx +12 -9
  151. package/src/components/Buttons/ToggleGroup.stories.tsx +13 -10
  152. package/src/components/Buttons/ToggleGroup.tsx +17 -4
  153. package/src/components/Clipboard/ClipboardProvider.tsx +1 -1
  154. package/src/components/Clipboard/CopyButton.tsx +3 -2
  155. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  156. package/src/components/Dialogs/AlertDialog.stories.tsx +14 -11
  157. package/src/components/Dialogs/AlertDialog.tsx +13 -13
  158. package/src/components/Dialogs/Dialog.stories.tsx +16 -14
  159. package/src/components/Dialogs/Dialog.tsx +13 -13
  160. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  161. package/src/components/Icon/Icon.stories.tsx +113 -0
  162. package/src/components/Icon/Icon.tsx +1 -1
  163. package/src/components/Input/Input.stories.tsx +12 -14
  164. package/src/components/Input/Input.tsx +16 -16
  165. package/src/components/Link/Link.stories.tsx +10 -6
  166. package/src/components/Lists/List.stories.tsx +22 -20
  167. package/src/components/Lists/List.tsx +15 -16
  168. package/src/components/Lists/Tree.stories.tsx +11 -8
  169. package/src/components/Lists/Tree.tsx +4 -3
  170. package/src/components/Lists/TreeDropIndicator.tsx +1 -1
  171. package/src/components/Lists/Treegrid.stories.tsx +12 -6
  172. package/src/components/Lists/Treegrid.tsx +58 -17
  173. package/src/components/Main/Main.stories.tsx +16 -8
  174. package/src/components/Main/Main.tsx +32 -17
  175. package/src/components/Menus/ContextMenu.stories.tsx +11 -8
  176. package/src/components/Menus/ContextMenu.tsx +1 -0
  177. package/src/components/Menus/DropdownMenu.stories.tsx +11 -8
  178. package/src/components/Menus/DropdownMenu.tsx +23 -13
  179. package/src/components/Message/Message.stories.tsx +11 -7
  180. package/src/components/Message/Message.tsx +1 -1
  181. package/src/components/Popover/Popover.stories.tsx +11 -8
  182. package/src/components/Popover/Popover.tsx +12 -12
  183. package/src/components/ScrollArea/ScrollArea.stories.tsx +11 -8
  184. package/src/components/ScrollArea/ScrollArea.tsx +4 -4
  185. package/src/components/Select/Select.stories.tsx +15 -12
  186. package/src/components/Select/Select.tsx +5 -5
  187. package/src/components/Status/Status.stories.tsx +9 -6
  188. package/src/components/Tag/Tag.stories.tsx +18 -9
  189. package/src/components/ThemeProvider/ThemeProvider.tsx +3 -2
  190. package/src/components/ThemeProvider/TranslationsProvider.tsx +3 -3
  191. package/src/components/Toast/Toast.stories.tsx +11 -8
  192. package/src/components/Toast/Toast.tsx +9 -9
  193. package/src/components/Toolbar/Toolbar.stories.tsx +20 -16
  194. package/src/components/Toolbar/Toolbar.tsx +19 -7
  195. package/src/components/Tooltip/Tooltip.stories.tsx +15 -11
  196. package/src/components/Tooltip/Tooltip.tsx +5 -4
  197. package/src/hooks/useSafeArea.ts +3 -2
  198. package/src/hooks/useSafeCollisionPadding.ts +1 -1
  199. package/src/hooks/useVisualViewport.ts +4 -4
  200. package/src/playground/Controls.stories.tsx +20 -17
  201. package/src/playground/Custom.stories.tsx +7 -16
  202. package/src/playground/Typography.stories.tsx +8 -6
  203. package/src/testing/decorators/index.ts +2 -1
  204. package/src/testing/decorators/withLayout.tsx +56 -0
  205. package/src/testing/decorators/withTheme.tsx +31 -0
  206. package/src/util/domino.ts +53 -0
  207. package/src/util/index.ts +3 -1
  208. package/src/util/usePx.ts +61 -0
  209. package/dist/lib/browser/chunk-T6YPS45E.mjs.map +0 -7
  210. package/dist/lib/node-esm/chunk-TYVQJ4KW.mjs.map +0 -7
  211. package/src/testing/decorators/withTheme.ts +0 -22
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { useCallback, useState } from 'react';
6
6
 
7
- import { useResize } from '@dxos/react-hooks';
7
+ import { useViewportResize } from '@dxos/react-hooks';
8
8
 
9
9
  export type SafeAreaPadding = Record<'top' | 'right' | 'bottom' | 'left', number>;
10
10
 
@@ -20,6 +20,7 @@ export const useSafeArea = (): SafeAreaPadding => {
20
20
  left: parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--safe-area-left')),
21
21
  });
22
22
  }, []);
23
- useResize(handleResize);
23
+
24
+ useViewportResize(handleResize);
24
25
  return padding;
25
26
  };
@@ -21,7 +21,7 @@ const safePadding = (
21
21
  ) => {
22
22
  return (
23
23
  (propIsNumber(safePadding[side]) ? safePadding[side] : 0) +
24
- (propIsNumber(propsPadding) ? propsPadding : propsIsRecord(propsPadding) ? propsPadding[side] ?? 0 : 0)
24
+ (propIsNumber(propsPadding) ? propsPadding : propsIsRecord(propsPadding) ? (propsPadding[side] ?? 0) : 0)
25
25
  );
26
26
  };
27
27
 
@@ -2,11 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { useCallback, type useEffect, useState } from 'react';
5
+ import { useCallback, useState } from 'react';
6
6
 
7
- import { useResize } from '@dxos/react-hooks';
7
+ import { useViewportResize } from '@dxos/react-hooks';
8
8
 
9
- export const useVisualViewport = (deps?: Parameters<typeof useEffect>[1]) => {
9
+ export const useVisualViewport = (deps?: Parameters<typeof useViewportResize>[1]) => {
10
10
  const [width, setWidth] = useState<number | null>(null);
11
11
  const [height, setHeight] = useState<number | null>(null);
12
12
 
@@ -17,7 +17,7 @@ export const useVisualViewport = (deps?: Parameters<typeof useEffect>[1]) => {
17
17
  }
18
18
  }, []);
19
19
 
20
- useResize(handleResize);
20
+ useViewportResize(handleResize, deps);
21
21
 
22
22
  return { width, height };
23
23
  };
@@ -2,13 +2,12 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { FileTs, FileJs, ArrowClockwise, Bug, TextUnderline, TextB, TextItalic } from '@phosphor-icons/react';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React, { useState } from 'react';
9
7
 
10
- import { Input, Select, Toggle, Toolbar } from '../components';
11
- import { withTheme, withSurfaceVariantsLayout } from '../testing';
8
+ import { Icon, Input, Select, Toggle, Toolbar } from '../components';
9
+ import { withTheme } from '../testing';
10
+ import { withSurfaceVariantsLayout } from '../testing';
12
11
 
13
12
  const DefaultStory = () => {
14
13
  const [checked, setChecked] = useState<boolean>(false);
@@ -29,6 +28,7 @@ const DefaultStory = () => {
29
28
  <Select.Option value={'b'}>B</Select.Option>
30
29
  <Select.Option value={'c'}>C</Select.Option>
31
30
  </Select.Viewport>
31
+ <Select.Arrow />
32
32
  </Select.Content>
33
33
  </Select.Portal>
34
34
  </Select.Root>
@@ -37,27 +37,27 @@ const DefaultStory = () => {
37
37
  {/* TODO(burdon): Icon sizes should adapt to density. */}
38
38
  <Toolbar.ToggleGroup type='multiple'>
39
39
  <Toolbar.ToggleGroupItem value='a'>
40
- <TextB />
40
+ <Icon icon='ph--text-b--regular' />
41
41
  </Toolbar.ToggleGroupItem>
42
42
  <Toolbar.ToggleGroupItem value='b'>
43
- <TextItalic />
43
+ <Icon icon='ph--text-italic--regular' />
44
44
  </Toolbar.ToggleGroupItem>
45
45
  <Toolbar.ToggleGroupItem value='c'>
46
- <TextUnderline />
46
+ <Icon icon='ph--text-underline--regular' />
47
47
  </Toolbar.ToggleGroupItem>
48
48
  </Toolbar.ToggleGroup>
49
49
  {/* TODO(burdon): Highlight isn't shown. */}
50
50
  <Toolbar.ToggleGroup type='single' defaultValue='a'>
51
51
  <Toolbar.ToggleGroupItem value='a'>
52
- <FileTs />
52
+ <Icon icon='ph--file-ts--regular' />
53
53
  </Toolbar.ToggleGroupItem>
54
54
  <Toolbar.ToggleGroupItem value='b'>
55
- <FileJs />
55
+ <Icon icon='ph--file-js--regular' />
56
56
  </Toolbar.ToggleGroupItem>
57
57
  </Toolbar.ToggleGroup>
58
58
  <Toolbar.Button asChild>
59
59
  <Toggle>
60
- <Bug />
60
+ <Icon icon='ph--bug--regular' />
61
61
  </Toggle>
62
62
  </Toolbar.Button>
63
63
  {/* TODO(burdon): Should not be 'is-full' by default. */}
@@ -71,7 +71,7 @@ const DefaultStory = () => {
71
71
  </Input.Root>
72
72
  <Toolbar.Button>Test</Toolbar.Button>
73
73
  <Toolbar.Button>
74
- <ArrowClockwise />
74
+ <Icon icon='ph--arrow-clockwise--regular' />
75
75
  </Toolbar.Button>
76
76
  </Toolbar.Root>
77
77
  <Input.Root>
@@ -81,11 +81,14 @@ const DefaultStory = () => {
81
81
  );
82
82
  };
83
83
 
84
- export default {
84
+ const meta = {
85
85
  title: 'ui/react-ui-core/Playground/Controls',
86
86
  render: DefaultStory,
87
- decorators: [withSurfaceVariantsLayout(), withTheme],
88
- parameters: { chromatic: { disableSnapshot: false } },
89
- };
87
+ decorators: [withTheme, withSurfaceVariantsLayout()],
88
+ } satisfies Meta<typeof Icon>;
89
+
90
+ export default meta;
91
+
92
+ type Story = StoryObj<typeof meta>;
90
93
 
91
- export const Default = {};
94
+ export const Default: Story = {};
@@ -2,23 +2,12 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { type StoryObj, type Meta } from '@storybook/react-vite';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
- import { Button, IconButton, type ButtonProps, Tooltip } from '../components';
8
+ import { Button, type ButtonProps, IconButton, Tooltip } from '../components';
11
9
  import { withTheme } from '../testing';
12
10
 
13
- // TODO(burdon): Change density to 3 or 4 sizes: (large, medium, small; or 22, 28, 32, 40)
14
- // TODO(burdon): IconButton should be square if no text.
15
- // TODO(burdon): IconButton icon should be auto-sized based on density.
16
-
17
- // TODO(burdon): Remove custom padding from all Buttons.
18
-
19
- // TODO(burdon): Forms w/ labels.
20
- // TODO(burdon): Card preview with sections.
21
-
22
11
  const DefaultStory = ({ children, ...args }: Omit<ButtonProps, 'ref'>) => {
23
12
  return (
24
13
  <Tooltip.Provider>
@@ -120,13 +109,15 @@ const DefaultStory = ({ children, ...args }: Omit<ButtonProps, 'ref'>) => {
120
109
  );
121
110
  };
122
111
 
123
- const meta: Meta<typeof Button> = {
112
+ const meta = {
124
113
  title: 'ui/react-ui-core/Playground/Custom',
125
114
  component: Button,
126
115
  render: DefaultStory,
127
116
  decorators: [withTheme],
128
- parameters: { layout: 'centered' },
129
- };
117
+ parameters: {
118
+ layout: 'centered',
119
+ },
120
+ } satisfies Meta<typeof Button>;
130
121
 
131
122
  export default meta;
132
123
 
@@ -2,8 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
6
  import React from 'react';
8
7
 
9
8
  import { withTheme } from '../testing';
@@ -43,13 +42,16 @@ const DefaultStory = () => {
43
42
  );
44
43
  };
45
44
 
46
- export default {
45
+ const meta = {
47
46
  title: 'ui/react-ui-core/Playground/Typography',
48
47
  render: DefaultStory,
49
48
  decorators: [withTheme],
50
- parameters: { chromatic: { disableSnapshot: false } },
51
- };
49
+ } satisfies Meta<typeof DefaultStory>;
50
+
51
+ export default meta;
52
+
53
+ type Story = StoryObj<typeof meta>;
52
54
 
53
- export const Default = {
55
+ export const Default: Story = {
54
56
  args: {},
55
57
  };
@@ -2,5 +2,6 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './withTheme';
5
+ export * from './withLayout';
6
6
  export * from './withSurfaceVariantsLayout';
7
+ export * from './withTheme';
@@ -0,0 +1,56 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Decorator } from '@storybook/react';
6
+ import React, { type FC, type PropsWithChildren } from 'react';
7
+
8
+ import { type ClassNameValue, type ThemedClassName } from '@dxos/react-ui';
9
+ import { mx } from '@dxos/react-ui-theme';
10
+
11
+ export type ContainerProps = ThemedClassName<PropsWithChildren>;
12
+
13
+ export type ContainerType = 'default' | 'column';
14
+
15
+ export type WithLayoutProps =
16
+ | FC<ContainerProps>
17
+ | { classNames?: ClassNameValue; container?: ContainerType; scroll?: boolean };
18
+
19
+ /**
20
+ * Adds layout container.
21
+ */
22
+ export const withLayout =
23
+ (props: WithLayoutProps): Decorator =>
24
+ (Story) => {
25
+ if (typeof props === 'function') {
26
+ const Container = props;
27
+ return (
28
+ <Container>
29
+ <Story />
30
+ </Container>
31
+ );
32
+ }
33
+
34
+ const Container = layouts[(props as any).container as ContainerType] ?? layouts.default;
35
+ return (
36
+ <Container classNames={mx(props.classNames, props.scroll ? 'overflow-y-auto' : 'overflow-hidden')}>
37
+ <Story />
38
+ </Container>
39
+ );
40
+ };
41
+
42
+ const layouts: Record<ContainerType, FC<ContainerProps>> = {
43
+ default: ({ children, classNames }: ContainerProps) => (
44
+ <div role='none' className={mx(classNames)}>
45
+ {children}
46
+ </div>
47
+ ),
48
+
49
+ column: ({ children, classNames }: ContainerProps) => (
50
+ <div role='none' className='fixed inset-0 flex justify-center overflow-hidden bg-deckSurface'>
51
+ <div role='none' className={mx('flex flex-col is-[40rem] bg-baseSurface', classNames)}>
52
+ {children}
53
+ </div>
54
+ </div>
55
+ ),
56
+ };
@@ -0,0 +1,31 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Decorator } from '@storybook/react';
6
+ import React, { memo } from 'react';
7
+
8
+ import { defaultTx } from '@dxos/react-ui-theme';
9
+
10
+ import { type ThemeMode, ThemeProvider, Tooltip } from '../../components';
11
+
12
+ /**
13
+ * Adds theme decorator (add to preview.ts)
14
+ */
15
+ export const withTheme: Decorator = (Story, context) => {
16
+ const {
17
+ globals: { theme },
18
+ parameters: { translations },
19
+ } = context;
20
+
21
+ // Prevent re-rendering of the story.
22
+ const MemoizedStory = memo(Story);
23
+
24
+ return (
25
+ <ThemeProvider tx={defaultTx} themeMode={theme as ThemeMode} resourceExtensions={translations} noCache>
26
+ <Tooltip.Provider>
27
+ <MemoizedStory />
28
+ </Tooltip.Provider>
29
+ </ThemeProvider>
30
+ );
31
+ };
@@ -0,0 +1,53 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { mx } from '@dxos/react-ui-theme';
6
+ import { type ClassNameValue } from '@dxos/react-ui-types';
7
+
8
+ /**
9
+ * Super lightweight chainable DOM builder.
10
+ */
11
+ export class Domino<T extends HTMLElement> {
12
+ static of<K extends keyof HTMLElementTagNameMap>(tag: K): Domino<HTMLElementTagNameMap[K]> {
13
+ return new Domino<HTMLElementTagNameMap[K]>(tag);
14
+ }
15
+
16
+ private readonly _el: T;
17
+ constructor(tag: keyof HTMLElementTagNameMap) {
18
+ this._el = document.createElement(tag) as T;
19
+ }
20
+ classNames(...classNames: ClassNameValue[]): this {
21
+ this._el.className = mx(classNames);
22
+ return this;
23
+ }
24
+ text(value: string): this {
25
+ this._el.textContent = value;
26
+ return this;
27
+ }
28
+ data(key: string, value: string): this {
29
+ this._el.dataset[key] = value;
30
+ return this;
31
+ }
32
+ attributes(attr: Record<string, string | undefined>): this {
33
+ Object.entries(attr)
34
+ .filter(([_, value]) => value !== undefined)
35
+ .map(([key, value]) => this._el.setAttribute(key, value!));
36
+ return this;
37
+ }
38
+ style(styles: Partial<CSSStyleDeclaration>): this {
39
+ Object.assign(this._el.style, styles);
40
+ return this;
41
+ }
42
+ children<C extends HTMLElement>(...children: Domino<C>[]): this {
43
+ children.forEach((child) => this._el.appendChild(child.build()));
44
+ return this;
45
+ }
46
+ on(event: string, handler: (e: Event) => void): this {
47
+ this._el.addEventListener(event, handler);
48
+ return this;
49
+ }
50
+ build(): T {
51
+ return this._el;
52
+ }
53
+ }
package/src/util/index.ts CHANGED
@@ -2,5 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ export * from './domino';
5
6
  export * from './hasIosKeyboard';
6
- export * from './ThemedClassName';
7
+ export type * from './ThemedClassName';
8
+ export * from './usePx';
@@ -0,0 +1,61 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useCallback, useEffect, useMemo, useState } from 'react';
6
+
7
+ const getDocumentElementFontSize = () => parseFloat(getComputedStyle(document.documentElement).fontSize);
8
+
9
+ /**
10
+ * React hook that converts rem values to pixels and updates when the root font size changes.
11
+ *
12
+ * @param rem The rem value to convert to pixels
13
+ * @returns The current pixel value equivalent of the rem input
14
+ */
15
+ export const usePx = (rem: number): number => {
16
+ const [fontSize, setFontSize] = useState(() => {
17
+ if (typeof document !== 'undefined') {
18
+ return getDocumentElementFontSize();
19
+ }
20
+ return 16; // Default fallback for SSR
21
+ });
22
+
23
+ const updateFontSize = useCallback(() => {
24
+ setFontSize(getDocumentElementFontSize());
25
+ }, []);
26
+
27
+ useEffect(() => {
28
+ if (typeof document === 'undefined') {
29
+ return;
30
+ }
31
+
32
+ // Create a ResizeObserver to watch for font size changes on the document element
33
+ const resizeObserver = new ResizeObserver(updateFontSize);
34
+ resizeObserver.observe(document.documentElement);
35
+
36
+ // Also listen for viewport changes that might affect font size
37
+ const mediaQueryList = window.matchMedia('all');
38
+ const handleMediaChange = () => {
39
+ updateFontSize();
40
+ };
41
+
42
+ if (mediaQueryList.addEventListener) {
43
+ mediaQueryList.addEventListener('change', handleMediaChange);
44
+ } else {
45
+ // Fallback for older browsers
46
+ mediaQueryList.addListener(handleMediaChange);
47
+ }
48
+
49
+ return () => {
50
+ resizeObserver.disconnect();
51
+ if (mediaQueryList.removeEventListener) {
52
+ mediaQueryList.removeEventListener('change', handleMediaChange);
53
+ } else {
54
+ // Fallback for older browsers
55
+ mediaQueryList.removeListener(handleMediaChange);
56
+ }
57
+ };
58
+ }, []);
59
+
60
+ return useMemo(() => rem * fontSize, [fontSize]);
61
+ };