@dxos/react-ui 0.8.4-main.c1de068 → 0.8.4-main.c4373fc

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 (203) hide show
  1. package/dist/lib/browser/{chunk-2COVUP44.mjs → chunk-B7HPXBP2.mjs} +255 -114
  2. package/dist/lib/browser/chunk-B7HPXBP2.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +8 -1
  4. package/dist/lib/browser/index.mjs.map +2 -2
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +21 -21
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/{chunk-GHXHND5V.mjs → chunk-6JCSY5Y7.mjs} +255 -114
  9. package/dist/lib/node-esm/chunk-6JCSY5Y7.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +8 -1
  11. package/dist/lib/node-esm/index.mjs.map +2 -2
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +21 -21
  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/Input/Input.d.ts +2 -4
  54. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  55. package/dist/types/src/components/Input/Input.stories.d.ts +10 -11
  56. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/Link/Link.stories.d.ts +8 -8
  58. package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
  59. package/dist/types/src/components/Lists/List.d.ts +2 -2
  60. package/dist/types/src/components/Lists/List.d.ts.map +1 -1
  61. package/dist/types/src/components/Lists/List.stories.d.ts +8 -31
  62. package/dist/types/src/components/Lists/List.stories.d.ts.map +1 -1
  63. package/dist/types/src/components/Lists/Tree.d.ts +1 -1
  64. package/dist/types/src/components/Lists/Tree.d.ts.map +1 -1
  65. package/dist/types/src/components/Lists/Tree.stories.d.ts +6 -32
  66. package/dist/types/src/components/Lists/Tree.stories.d.ts.map +1 -1
  67. package/dist/types/src/components/Lists/Treegrid.d.ts +1 -1
  68. package/dist/types/src/components/Lists/Treegrid.d.ts.map +1 -1
  69. package/dist/types/src/components/Lists/Treegrid.stories.d.ts +6 -4
  70. package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +1 -1
  71. package/dist/types/src/components/Main/Main.d.ts +2 -11
  72. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  73. package/dist/types/src/components/Main/Main.stories.d.ts +6 -7
  74. package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
  75. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +1 -1
  76. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +6 -44
  77. package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +1 -1
  78. package/dist/types/src/components/Menus/DropdownMenu.d.ts +6 -5
  79. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +1 -1
  80. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +6 -41
  81. package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts.map +1 -1
  82. package/dist/types/src/components/Message/Message.d.ts +1 -1
  83. package/dist/types/src/components/Message/Message.d.ts.map +1 -1
  84. package/dist/types/src/components/Message/Message.stories.d.ts +7 -16
  85. package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
  86. package/dist/types/src/components/Popover/Popover.d.ts +2 -2
  87. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  88. package/dist/types/src/components/Popover/Popover.stories.d.ts +6 -34
  89. package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
  90. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +1 -1
  91. package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  92. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +6 -32
  93. package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
  94. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  95. package/dist/types/src/components/Select/Select.stories.d.ts +4 -9
  96. package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
  97. package/dist/types/src/components/Status/Status.stories.d.ts +2 -8
  98. package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
  99. package/dist/types/src/components/Tag/Tag.stories.d.ts +12 -12
  100. package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
  101. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +1 -1
  102. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  103. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -1
  104. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  105. package/dist/types/src/components/Toast/Toast.d.ts +1 -1
  106. package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
  107. package/dist/types/src/components/Toast/Toast.stories.d.ts +6 -44
  108. package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
  109. package/dist/types/src/components/Toolbar/Toolbar.d.ts +3 -7
  110. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  111. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +6 -50
  112. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  113. package/dist/types/src/components/Tooltip/Tooltip.d.ts +2 -4
  114. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  115. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +8 -61
  116. package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
  117. package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
  118. package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
  119. package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
  120. package/dist/types/src/index.d.ts +1 -1
  121. package/dist/types/src/index.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/withTheme.d.ts +3 -0
  129. package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
  130. package/dist/types/src/util/domino.d.ts +18 -0
  131. package/dist/types/src/util/domino.d.ts.map +1 -0
  132. package/dist/types/src/util/index.d.ts +2 -0
  133. package/dist/types/src/util/index.d.ts.map +1 -1
  134. package/dist/types/src/util/usePx.d.ts +8 -0
  135. package/dist/types/src/util/usePx.d.ts.map +1 -0
  136. package/dist/types/tsconfig.tsbuildinfo +1 -1
  137. package/package.json +22 -22
  138. package/src/components/Avatars/Avatar.stories.tsx +19 -10
  139. package/src/components/Avatars/Avatar.tsx +3 -3
  140. package/src/components/Avatars/AvatarGroup.stories.tsx +10 -6
  141. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +16 -11
  142. package/src/components/Breadcrumb/Breadcrumb.tsx +1 -1
  143. package/src/components/Buttons/Button.stories.tsx +8 -9
  144. package/src/components/Buttons/IconButton.stories.tsx +11 -8
  145. package/src/components/Buttons/IconButton.tsx +4 -3
  146. package/src/components/Buttons/Toggle.stories.tsx +10 -7
  147. package/src/components/Buttons/ToggleGroup.stories.tsx +10 -7
  148. package/src/components/Buttons/ToggleGroup.tsx +17 -4
  149. package/src/components/Clipboard/ClipboardProvider.tsx +1 -1
  150. package/src/components/Clipboard/CopyButton.tsx +2 -1
  151. package/src/components/DensityProvider/DensityProvider.tsx +1 -1
  152. package/src/components/Dialogs/AlertDialog.stories.tsx +14 -11
  153. package/src/components/Dialogs/AlertDialog.tsx +13 -13
  154. package/src/components/Dialogs/Dialog.stories.tsx +16 -14
  155. package/src/components/Dialogs/Dialog.tsx +13 -13
  156. package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
  157. package/src/components/Input/Input.stories.tsx +12 -14
  158. package/src/components/Input/Input.tsx +16 -16
  159. package/src/components/Link/Link.stories.tsx +10 -6
  160. package/src/components/Lists/List.stories.tsx +16 -14
  161. package/src/components/Lists/List.tsx +16 -12
  162. package/src/components/Lists/Tree.stories.tsx +11 -8
  163. package/src/components/Lists/Tree.tsx +4 -3
  164. package/src/components/Lists/TreeDropIndicator.tsx +1 -1
  165. package/src/components/Lists/Treegrid.stories.tsx +12 -6
  166. package/src/components/Lists/Treegrid.tsx +58 -17
  167. package/src/components/Main/Main.stories.tsx +16 -8
  168. package/src/components/Main/Main.tsx +32 -17
  169. package/src/components/Menus/ContextMenu.stories.tsx +11 -8
  170. package/src/components/Menus/ContextMenu.tsx +1 -0
  171. package/src/components/Menus/DropdownMenu.stories.tsx +11 -8
  172. package/src/components/Menus/DropdownMenu.tsx +23 -13
  173. package/src/components/Message/Message.stories.tsx +11 -7
  174. package/src/components/Message/Message.tsx +1 -1
  175. package/src/components/Popover/Popover.stories.tsx +11 -8
  176. package/src/components/Popover/Popover.tsx +9 -9
  177. package/src/components/ScrollArea/ScrollArea.stories.tsx +11 -8
  178. package/src/components/ScrollArea/ScrollArea.tsx +4 -4
  179. package/src/components/Select/Select.stories.tsx +15 -12
  180. package/src/components/Select/Select.tsx +5 -4
  181. package/src/components/Status/Status.stories.tsx +9 -6
  182. package/src/components/Tag/Tag.stories.tsx +18 -9
  183. package/src/components/ThemeProvider/ThemeProvider.tsx +3 -2
  184. package/src/components/ThemeProvider/TranslationsProvider.tsx +3 -3
  185. package/src/components/Toast/Toast.stories.tsx +11 -8
  186. package/src/components/Toast/Toast.tsx +9 -9
  187. package/src/components/Toolbar/Toolbar.stories.tsx +12 -8
  188. package/src/components/Toolbar/Toolbar.tsx +3 -2
  189. package/src/components/Tooltip/Tooltip.stories.tsx +15 -11
  190. package/src/components/Tooltip/Tooltip.tsx +5 -4
  191. package/src/hooks/useSafeArea.ts +1 -0
  192. package/src/hooks/useVisualViewport.ts +3 -3
  193. package/src/index.ts +1 -1
  194. package/src/playground/Controls.stories.tsx +12 -8
  195. package/src/playground/Custom.stories.tsx +7 -16
  196. package/src/playground/Typography.stories.tsx +8 -6
  197. package/src/testing/decorators/withTheme.tsx +31 -0
  198. package/src/util/domino.ts +51 -0
  199. package/src/util/index.ts +2 -0
  200. package/src/util/usePx.ts +61 -0
  201. package/dist/lib/browser/chunk-2COVUP44.mjs.map +0 -7
  202. package/dist/lib/node-esm/chunk-GHXHND5V.mjs.map +0 -7
  203. package/src/testing/decorators/withTheme.ts +0 -25
@@ -2,14 +2,14 @@
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
- import { Main, useSidebars } from './Main';
10
8
  import { withTheme } from '../../testing';
11
9
  import { Button } from '../Buttons';
12
10
 
11
+ import { Main, useSidebars } from './Main';
12
+
13
13
  type StoryMainArgs = {};
14
14
 
15
15
  const NavigationSidebarToggle = () => {
@@ -45,15 +45,23 @@ const DefaultStory = (_args: StoryMainArgs) => {
45
45
  );
46
46
  };
47
47
 
48
- export default {
48
+ const meta = {
49
49
  title: 'ui/react-ui-core/Main',
50
50
  component: Main.Root,
51
51
  render: DefaultStory,
52
52
  decorators: [withTheme],
53
- parameters: { chromatic: { disableSnapshot: false } },
54
- };
53
+ parameters: {
54
+ layout: 'fullscreen',
55
+ chromatic: {
56
+ disableSnapshot: false,
57
+ },
58
+ },
59
+ } satisfies Meta<typeof DefaultStory>;
60
+
61
+ export default meta;
62
+
63
+ type Story = StoryObj<typeof meta>;
55
64
 
56
- export const Default = {
65
+ export const Default: Story = {
57
66
  args: {},
58
- layout: 'fullscreen',
59
67
  };
@@ -2,33 +2,35 @@
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
 
24
25
  import { log } from '@dxos/log';
25
- import { useMediaQuery, useForwardedRef } from '@dxos/react-hooks';
26
+ import { useForwardedRef, useMediaQuery } from '@dxos/react-hooks';
26
27
 
27
- import { useSwipeToDismiss } from './useSwipeToDismiss';
28
28
  import { useThemeContext } from '../../hooks';
29
29
  import { type ThemedClassName } from '../../util';
30
30
  import { type Label, toLocalizedString, useTranslation } from '../ThemeProvider';
31
31
 
32
+ import { useSwipeToDismiss } from './useSwipeToDismiss';
33
+
32
34
  const MAIN_ROOT_NAME = 'MainRoot';
33
35
  const NAVIGATION_SIDEBAR_NAME = 'NavigationSidebar';
34
36
  const COMPLEMENTARY_SIDEBAR_NAME = 'ComplementarySidebar';
@@ -69,20 +71,28 @@ const useLandmarkMover = (propsOnKeyDown: ComponentPropsWithoutRef<'div'>['onKey
69
71
  },
70
72
  [propsOnKeyDown],
71
73
  );
72
- const focusableGroupAttrs = window ? {} : { tabBehavior: 'limited', ignoreDefaultKeydown: { Tab: true } };
73
74
 
74
- return { onKeyDown: handleKeyDown, [landmarkAttr]: landmark, tabIndex: 0, ...focusableGroupAttrs };
75
+ // TODO(thure): This was disconnected once before in #8818, if this should change again to support the browser
76
+ // extension, please ensure the change doesn’t break web, desktop and mobile.
77
+ const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited', ignoreDefaultKeydown: { Tab: true } });
78
+
79
+ return {
80
+ onKeyDown: handleKeyDown,
81
+ [landmarkAttr]: landmark,
82
+ tabIndex: 0,
83
+ ...focusableGroupAttrs,
84
+ };
75
85
  };
76
86
 
77
87
  const [MainProvider, useMainContext] = createContext<MainContextValue>(MAIN_NAME, {
78
88
  resizing: false,
79
89
  navigationSidebarState: 'closed',
80
- setNavigationSidebarState: (nextState) => {
90
+ setNavigationSidebarState: (_nextState) => {
81
91
  // TODO(burdon): Standardize with other context missing errors using raise.
82
92
  log.warn('Attempt to set sidebar state without initializing `MainRoot`');
83
93
  },
84
94
  complementarySidebarState: 'closed',
85
- setComplementarySidebarState: (nextState) => {
95
+ setComplementarySidebarState: (_nextState) => {
86
96
  // TODO(burdon): Standardize with other context missing errors using raise.
87
97
  log.warn('Attempt to set sidebar state without initializing `MainRoot`');
88
98
  },
@@ -135,7 +145,7 @@ const MainRoot = ({
135
145
  children,
136
146
  ...props
137
147
  }: MainRootProps) => {
138
- const [isLg] = useMediaQuery('lg', { ssr: false });
148
+ const [isLg] = useMediaQuery('lg');
139
149
  const [navigationSidebarState = isLg ? 'expanded' : 'collapsed', setNavigationSidebarState] =
140
150
  useControllableState<SidebarState>({
141
151
  prop: propsNavigationSidebarState,
@@ -204,7 +214,7 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
204
214
  { classNames, children, swipeToDismiss, onOpenAutoFocus, state, resizing, onStateChange, side, label, ...props },
205
215
  forwardedRef,
206
216
  ) => {
207
- const [isLg] = useMediaQuery('lg', { ssr: false });
217
+ const [isLg] = useMediaQuery('lg');
208
218
  const { tx } = useThemeContext();
209
219
  const { t } = useTranslation();
210
220
  const ref = useForwardedRef(forwardedRef);
@@ -212,10 +222,15 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
212
222
  useSwipeToDismiss(swipeToDismiss ? ref : noopRef, {
213
223
  onDismiss: () => onStateChange?.('closed'),
214
224
  });
225
+ // NOTE(thure): This is a workaround for something further down the tree grabbing focus on Escape. Adding this
226
+ // intervention to `Tabs.Root` or `Tabs.Tabpenel` instances is somehow ineffectual.
215
227
  const handleKeyDown = useCallback(
216
228
  (event: KeyboardEvent<HTMLDivElement>) => {
217
- if (event.key === 'Escape') {
218
- ((event.target as HTMLDivElement).closest('[data-tabster]') as HTMLDivElement)?.focus();
229
+ const focusGroupParent = (event.target as HTMLElement).closest('[data-tabster]');
230
+ if (event.key === 'Escape' && focusGroupParent) {
231
+ event.preventDefault();
232
+ event.stopPropagation();
233
+ (focusGroupParent as HTMLElement).focus();
219
234
  }
220
235
  props.onKeyDown?.(event);
221
236
  },
@@ -233,8 +248,8 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
233
248
  data-state={state}
234
249
  data-resizing={resizing ? 'true' : 'false'}
235
250
  className={tx('main.sidebar', 'main__sidebar', {}, classNames)}
236
- onKeyDown={handleKeyDown}
237
- {...(state === 'closed' && { inert: 'true' })}
251
+ onKeyDownCapture={handleKeyDown}
252
+ {...(state === 'closed' && { inert: true })}
238
253
  ref={ref}
239
254
  >
240
255
  {children}
@@ -323,7 +338,7 @@ MainContent.displayName = MAIN_NAME;
323
338
  type MainOverlayProps = ThemedClassName<Omit<ComponentPropsWithRef<typeof Primitive.div>, 'children'>>;
324
339
 
325
340
  const MainOverlay = forwardRef<HTMLDivElement, MainOverlayProps>(({ classNames, ...props }, forwardedRef) => {
326
- const [isLg] = useMediaQuery('lg', { ssr: false });
341
+ const [isLg] = useMediaQuery('lg');
327
342
  const { navigationSidebarState, setNavigationSidebarState, complementarySidebarState, setComplementarySidebarState } =
328
343
  useMainContext(MAIN_NAME);
329
344
  const { tx } = useThemeContext();
@@ -2,13 +2,13 @@
2
2
  // Copyright 2022 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
- import { ContextMenu } from './ContextMenu';
10
8
  import { withTheme } from '../../testing';
11
9
 
10
+ import { ContextMenu } from './ContextMenu';
11
+
12
12
  const DefaultStory = () => {
13
13
  // NOTE(thure): Since long-tap will select text in some OSs, apply `select-none` to `ContextMenu.Trigger` where possible.
14
14
  return (
@@ -91,15 +91,18 @@ const DefaultStory = () => {
91
91
  );
92
92
  };
93
93
 
94
- export default {
94
+ const meta = {
95
95
  title: 'ui/react-ui-core/ContextMenu',
96
- component: ContextMenu,
96
+ component: ContextMenu.Root as any,
97
97
  render: DefaultStory,
98
98
  decorators: [withTheme],
99
- parameters: { chromatic: { disableSnapshot: false } },
100
- };
99
+ } satisfies Meta<typeof DefaultStory>;
100
+
101
+ export default meta;
102
+
103
+ type Story = StoryObj<typeof meta>;
101
104
 
102
- export const Default = {
105
+ export const Default: Story = {
103
106
  args: {},
104
107
  parameters: {
105
108
  chromatic: { delay: 1600 },
@@ -34,6 +34,7 @@ const ContextMenuContent = forwardRef<HTMLDivElement, ContextMenuContentProps>(
34
34
  return (
35
35
  <ContextMenuPrimitive.Content
36
36
  {...props}
37
+ data-arrow-keys='up down'
37
38
  collisionPadding={safeCollisionPadding}
38
39
  className={tx('menu.content', 'menu', { elevation }, classNames)}
39
40
  ref={forwardedRef}
@@ -2,14 +2,14 @@
2
2
  // Copyright 2022 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, { useRef, useState } from 'react';
8
7
 
9
- import { DropdownMenu } from './DropdownMenu';
10
8
  import { withTheme } from '../../testing';
11
9
  import { Button } from '../Buttons';
12
10
 
11
+ import { DropdownMenu } from './DropdownMenu';
12
+
13
13
  const DefaultStory = () => {
14
14
  return (
15
15
  <DropdownMenu.Root defaultOpen>
@@ -91,15 +91,18 @@ const DefaultStory = () => {
91
91
  );
92
92
  };
93
93
 
94
- export default {
94
+ const meta = {
95
95
  title: 'ui/react-ui-core/DropdownMenu',
96
- component: DropdownMenu,
96
+ component: DropdownMenu.Root,
97
97
  render: DefaultStory,
98
98
  decorators: [withTheme],
99
- parameters: { chromatic: { disableSnapshot: false } },
100
- };
99
+ } satisfies Meta<typeof DefaultStory>;
100
+
101
+ export default meta;
102
+
103
+ type Story = StoryObj<typeof meta>;
101
104
 
102
- export const Default = {
105
+ export const Default: Story = {
103
106
  args: {},
104
107
  parameters: {
105
108
  chromatic: { delay: 1600 },
@@ -15,17 +15,17 @@ import { Primitive } from '@radix-ui/react-primitive';
15
15
  import { Slot } from '@radix-ui/react-slot';
16
16
  import { useControllableState } from '@radix-ui/react-use-controllable-state';
17
17
  import React, {
18
- type ReactNode,
19
- type FC,
20
- useRef,
21
- type ElementRef,
22
- useCallback,
23
- type ComponentPropsWithoutRef,
24
- forwardRef,
25
18
  type ComponentPropsWithRef,
26
- useEffect,
19
+ type ComponentPropsWithoutRef,
20
+ type ElementRef,
21
+ type FC,
27
22
  type MutableRefObject,
23
+ type ReactNode,
28
24
  type RefObject,
25
+ forwardRef,
26
+ useCallback,
27
+ useEffect,
28
+ useRef,
29
29
  } from 'react';
30
30
 
31
31
  import { useElevationContext, useThemeContext } from '../../hooks';
@@ -124,6 +124,7 @@ const DropdownMenuTrigger = forwardRef<DropdownMenuTriggerElement, DropdownMenuT
124
124
  disabled={disabled}
125
125
  {...triggerProps}
126
126
  ref={composeRefs(forwardedRef, context.triggerRef)}
127
+ data-arrow-keys='down'
127
128
  onPointerDown={composeEventHandlers(props.onPointerDown, (event) => {
128
129
  // only call handler if it's the left button (mousedown gets triggered by all mouse buttons)
129
130
  // but not when the control key is pressed (avoiding MacOS right click)
@@ -167,7 +168,7 @@ DropdownMenuTrigger.displayName = TRIGGER_NAME;
167
168
  const VIRTUAL_TRIGGER_NAME = 'DropdownMenuVirtualTrigger';
168
169
 
169
170
  interface DropdownMenuVirtualTriggerProps {
170
- virtualRef: RefObject<DropdownMenuTriggerElement>;
171
+ virtualRef: RefObject<DropdownMenuTriggerElement | null>;
171
172
  }
172
173
 
173
174
  const DropdownMenuVirtualTrigger = (props: ScopedProps<DropdownMenuVirtualTriggerProps>) => {
@@ -179,7 +180,7 @@ const DropdownMenuVirtualTrigger = (props: ScopedProps<DropdownMenuVirtualTrigge
179
180
  context.triggerRef.current = virtualRef.current;
180
181
  }
181
182
  });
182
- return <MenuPrimitive.Anchor {...menuScope} virtualRef={virtualRef} />;
183
+ return <MenuPrimitive.Anchor {...menuScope} virtualRef={virtualRef as RefObject<DropdownMenuTriggerElement>} />;
183
184
  };
184
185
 
185
186
  DropdownMenuVirtualTrigger.displayName = VIRTUAL_TRIGGER_NAME;
@@ -264,6 +265,7 @@ const DropdownMenuContent = forwardRef<DropdownMenuContentElement, DropdownMenuC
264
265
  hasInteractedOutsideRef.current = true;
265
266
  }
266
267
  })}
268
+ data-arrow-keys='up down'
267
269
  className={tx('menu.content', 'menu', { elevation }, classNames)}
268
270
  style={{
269
271
  ...props.style,
@@ -415,13 +417,21 @@ const RADIO_ITEM_NAME = 'DropdownMenuRadioItem';
415
417
 
416
418
  type DropdownMenuRadioItemElement = ElementRef<typeof MenuPrimitive.RadioItem>;
417
419
  type MenuRadioItemProps = ComponentPropsWithoutRef<typeof MenuPrimitive.RadioItem>;
418
- interface DropdownMenuRadioItemProps extends MenuRadioItemProps {}
420
+ type DropdownMenuRadioItemProps = ThemedClassName<MenuRadioItemProps>;
419
421
 
420
422
  const DropdownMenuRadioItem = forwardRef<DropdownMenuRadioItemElement, DropdownMenuRadioItemProps>(
421
423
  (props: ScopedProps<DropdownMenuRadioItemProps>, forwardedRef) => {
422
- const { __scopeDropdownMenu, ...radioItemProps } = props;
424
+ const { __scopeDropdownMenu, classNames, ...itemProps } = props;
423
425
  const menuScope = useMenuScope(__scopeDropdownMenu);
424
- return <MenuPrimitive.RadioItem {...menuScope} {...radioItemProps} ref={forwardedRef} />;
426
+ const { tx } = useThemeContext();
427
+ return (
428
+ <MenuPrimitive.Item
429
+ {...menuScope}
430
+ {...itemProps}
431
+ className={tx('menu.item', 'menu__item', {}, classNames)}
432
+ ref={forwardedRef}
433
+ />
434
+ );
425
435
  },
426
436
  );
427
437
 
@@ -2,15 +2,15 @@
2
2
  // Copyright 2022 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 { type MessageValence } from '@dxos/react-ui-types';
10
9
 
11
- import { Callout } from './Message';
12
10
  import { withTheme } from '../../testing';
13
11
 
12
+ import { Callout } from './Message';
13
+
14
14
  type StoryProps = {
15
15
  valence: MessageValence;
16
16
  title: string;
@@ -24,9 +24,9 @@ const DefaultStory = ({ valence, title, body }: StoryProps) => (
24
24
  </Callout.Root>
25
25
  );
26
26
 
27
- export default {
27
+ const meta = {
28
28
  title: 'ui/react-ui-core/Callout',
29
- component: Callout,
29
+ component: Callout.Root as any,
30
30
  render: DefaultStory,
31
31
  decorators: [withTheme],
32
32
  parameters: { chromatic: { disableSnapshot: false } },
@@ -36,9 +36,13 @@ export default {
36
36
  options: ['success', 'info', 'warning', 'error', 'neutral'],
37
37
  },
38
38
  },
39
- };
39
+ } satisfies Meta<typeof DefaultStory>;
40
+
41
+ export default meta;
42
+
43
+ type Story = StoryObj<typeof meta>;
40
44
 
41
- export const Default = {
45
+ export const Default: Story = {
42
46
  args: {
43
47
  valence: 'neutral',
44
48
  title: 'Alert title',
@@ -8,7 +8,7 @@ import { Slot } from '@radix-ui/react-slot';
8
8
  import React, { type ComponentPropsWithRef, forwardRef } from 'react';
9
9
 
10
10
  import { useId } from '@dxos/react-hooks';
11
- import { type MessageValence, type Elevation } from '@dxos/react-ui-types';
11
+ import { type Elevation, type MessageValence } from '@dxos/react-ui-types';
12
12
 
13
13
  import { useElevationContext, useThemeContext } from '../../hooks';
14
14
  import { type ThemedClassName } from '../../util';
@@ -2,16 +2,16 @@
2
2
  // Copyright 2022 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, { type PropsWithChildren, type ReactNode, useRef, useState } from 'react';
8
7
 
9
8
  import { faker } from '@dxos/random';
10
9
 
11
- import { Popover } from './Popover';
12
10
  import { withTheme } from '../../testing';
13
11
  import { Button } from '../Buttons';
14
12
 
13
+ import { Popover } from './Popover';
14
+
15
15
  faker.seed(1234);
16
16
 
17
17
  const DefaultStory = ({ openTrigger, children }: PropsWithChildren<{ openTrigger: ReactNode }>) => {
@@ -28,15 +28,18 @@ const DefaultStory = ({ openTrigger, children }: PropsWithChildren<{ openTrigger
28
28
  );
29
29
  };
30
30
 
31
- export default {
31
+ const meta = {
32
32
  title: 'ui/react-ui-core/Popover',
33
- component: Popover,
33
+ component: Popover.Root,
34
34
  render: DefaultStory,
35
35
  decorators: [withTheme],
36
- parameters: { chromatic: { disableSnapshot: false } },
37
- };
36
+ } satisfies Meta<typeof DefaultStory>;
37
+
38
+ export default meta;
39
+
40
+ type Story = StoryObj<typeof meta>;
38
41
 
39
- export const Default = {
42
+ export const Default: Story = {
40
43
  args: {
41
44
  openTrigger: <Button>Open popover</Button>,
42
45
  children: faker.lorem.paragraphs(3),
@@ -22,17 +22,17 @@ import { useControllableState } from '@radix-ui/react-use-controllable-state';
22
22
  import { hideOthers } from 'aria-hidden';
23
23
  import React, {
24
24
  type ComponentPropsWithRef,
25
- forwardRef,
25
+ type ComponentPropsWithoutRef,
26
26
  type ElementRef,
27
- type RefObject,
27
+ type FC,
28
+ type MutableRefObject,
28
29
  type ReactNode,
29
- useRef,
30
+ type RefObject,
31
+ forwardRef,
30
32
  useCallback,
31
- type ComponentPropsWithoutRef,
32
- type FC,
33
- useState,
34
33
  useEffect,
35
- type MutableRefObject,
34
+ useRef,
35
+ useState,
36
36
  } from 'react';
37
37
  import { RemoveScroll } from 'react-remove-scroll';
38
38
 
@@ -182,7 +182,7 @@ PopoverTrigger.displayName = TRIGGER_NAME;
182
182
  const VIRTUAL_TRIGGER_NAME = 'PopoverVirtualTrigger';
183
183
 
184
184
  interface PopoverVirtualTriggerProps {
185
- virtualRef: RefObject<PopoverTriggerElement>;
185
+ virtualRef: RefObject<PopoverTriggerElement | null>;
186
186
  }
187
187
 
188
188
  const PopoverVirtualTrigger = (props: ScopedProps<PopoverVirtualTriggerProps>) => {
@@ -194,7 +194,7 @@ const PopoverVirtualTrigger = (props: ScopedProps<PopoverVirtualTriggerProps>) =
194
194
  context.triggerRef.current = virtualRef.current;
195
195
  }
196
196
  });
197
- return <PopperPrimitive.Anchor {...popperScope} virtualRef={virtualRef} />;
197
+ return <PopperPrimitive.Anchor {...popperScope} virtualRef={virtualRef as RefObject<PopoverTriggerElement>} />;
198
198
  };
199
199
 
200
200
  PopoverVirtualTrigger.displayName = VIRTUAL_TRIGGER_NAME;
@@ -2,16 +2,16 @@
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, { type PropsWithChildren } from 'react';
8
7
 
9
8
  import { faker } from '@dxos/random';
10
9
  import { activeSurface, surfaceShadow } from '@dxos/react-ui-theme';
11
10
 
12
- import { ScrollArea } from './ScrollArea';
13
11
  import { withTheme } from '../../testing';
14
12
 
13
+ import { ScrollArea } from './ScrollArea';
14
+
15
15
  faker.seed(1234);
16
16
 
17
17
  const DefaultStory = ({ children }: PropsWithChildren<{}>) => {
@@ -33,15 +33,18 @@ const DefaultStory = ({ children }: PropsWithChildren<{}>) => {
33
33
  );
34
34
  };
35
35
 
36
- export default {
36
+ const meta = {
37
37
  title: 'ui/react-ui-core/Scroll area',
38
- component: ScrollArea,
38
+ component: ScrollArea as any,
39
39
  render: DefaultStory,
40
40
  decorators: [withTheme],
41
- parameters: { chromatic: { disableSnapshot: false } },
42
- };
41
+ } satisfies Meta<typeof DefaultStory>;
42
+
43
+ export default meta;
44
+
45
+ type Story = StoryObj<typeof meta>;
43
46
 
44
- export const Default = {
47
+ export const Default: Story = {
45
48
  args: {
46
49
  children: faker.lorem.paragraphs(5),
47
50
  },
@@ -3,16 +3,16 @@
3
3
  //
4
4
 
5
5
  import {
6
+ Corner as ScrollAreaPrimitiveCorner,
7
+ type ScrollAreaCornerProps as ScrollAreaPrimitiveCornerProps,
6
8
  Root as ScrollAreaPrimitiveRoot,
7
9
  type ScrollAreaProps as ScrollAreaPrimitiveRootProps,
8
- Viewport as ScrollAreaPrimitiveViewport,
9
- type ScrollAreaViewportProps as ScrollAreaPrimitiveViewportProps,
10
10
  Scrollbar as ScrollAreaPrimitiveScrollbar,
11
11
  type ScrollAreaScrollbarProps as ScrollAreaPrimitiveScrollbarProps,
12
12
  Thumb as ScrollAreaPrimitiveThumb,
13
13
  type ScrollAreaThumbProps as ScrollAreaPrimitiveThumbProps,
14
- Corner as ScrollAreaPrimitiveCorner,
15
- type ScrollAreaCornerProps as ScrollAreaPrimitiveCornerProps,
14
+ Viewport as ScrollAreaPrimitiveViewport,
15
+ type ScrollAreaViewportProps as ScrollAreaPrimitiveViewportProps,
16
16
  } from '@radix-ui/react-scroll-area';
17
17
  import React, { forwardRef } from 'react';
18
18
 
@@ -2,15 +2,15 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { type StoryObj } from '@storybook/react-vite';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React, { useState } from 'react';
9
7
 
10
8
  import { faker } from '@dxos/random';
11
9
 
10
+ import { withTheme } from '../../testing';
11
+ import { withSurfaceVariantsLayout } from '../../testing';
12
+
12
13
  import { Select } from './Select';
13
- import { withSurfaceVariantsLayout, withTheme } from '../../testing';
14
14
 
15
15
  faker.seed(1234);
16
16
 
@@ -41,15 +41,18 @@ const DefaultStory = ({ items = [] }: StoryProps) => {
41
41
  );
42
42
  };
43
43
 
44
- export const Default: StoryObj<StoryProps> = {
44
+ const meta = {
45
+ title: 'ui/react-ui-core/Select',
46
+ render: DefaultStory,
47
+ decorators: [withTheme, withSurfaceVariantsLayout()],
48
+ } satisfies Meta<typeof DefaultStory>;
49
+
50
+ export default meta;
51
+
52
+ type Story = StoryObj<typeof meta>;
53
+
54
+ export const Default: Story = {
45
55
  args: {
46
56
  items: Array.from({ length: 16 }).map((_, i) => ({ id: `item-${i}`, text: faker.lorem.word() })),
47
57
  },
48
58
  };
49
-
50
- export default {
51
- title: 'ui/react-ui-core/Select',
52
- render: DefaultStory,
53
- decorators: [withSurfaceVariantsLayout(), withTheme],
54
- parameters: { chromatic: { disableSnapshot: false } },
55
- };
@@ -35,14 +35,13 @@ type SelectTriggerButtonProps = Omit<ButtonProps, 'children'> & Pick<SelectValue
35
35
 
36
36
  const SelectTriggerButton = forwardRef<HTMLButtonElement, SelectTriggerButtonProps>(
37
37
  ({ children, placeholder, ...props }, forwardedRef) => {
38
- const { tx } = useThemeContext();
39
38
  return (
40
39
  <SelectPrimitive.Trigger asChild ref={forwardedRef}>
41
40
  <Button {...props}>
42
41
  <SelectPrimitive.Value placeholder={placeholder}>{children}</SelectPrimitive.Value>
43
42
  <span className='w-1 flex-1' />
44
43
  <SelectPrimitive.Icon asChild>
45
- <Icon icon='ph--caret-down--bold' classNames={tx('select.triggerIcon', 'select__trigger__icon', {})} />
44
+ <Icon size={3} icon='ph--caret-down--bold' />
46
45
  </SelectPrimitive.Icon>
47
46
  </Button>
48
47
  </SelectPrimitive.Trigger>
@@ -60,6 +59,7 @@ const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
60
59
  return (
61
60
  <SelectPrimitive.Content
62
61
  {...props}
62
+ data-arrow-keys='up down'
63
63
  collisionPadding={safeCollisionPadding}
64
64
  className={tx('select.content', 'select__content', { elevation }, classNames)}
65
65
  position='popper'
@@ -82,7 +82,7 @@ const SelectScrollUpButton = forwardRef<HTMLDivElement, SelectScrollUpButtonProp
82
82
  className={tx('select.scrollButton', 'select__scroll-button--up', {}, classNames)}
83
83
  ref={forwardedRef}
84
84
  >
85
- {children ?? <Icon icon='ph--caret-up--bold' />}
85
+ {children ?? <Icon size={3} icon='ph--caret-up--bold' />}
86
86
  </SelectPrimitive.SelectScrollUpButton>
87
87
  );
88
88
  },
@@ -99,7 +99,7 @@ const SelectScrollDownButton = forwardRef<HTMLDivElement, SelectScrollDownButton
99
99
  className={tx('select.scrollButton', 'select__scroll-button--down', {}, classNames)}
100
100
  ref={forwardedRef}
101
101
  >
102
- {children ?? <Icon icon='ph--caret-down--bold' />}
102
+ {children ?? <Icon size={3} icon='ph--caret-down--bold' />}
103
103
  </SelectPrimitive.SelectScrollDownButton>
104
104
  );
105
105
  },
@@ -152,6 +152,7 @@ const SelectItemIndicator = forwardRef<HTMLDivElement, SelectItemIndicatorProps>
152
152
 
153
153
  type SelectOptionProps = SelectItemProps;
154
154
 
155
+ // TODO(burdon): Option to show icon on left/right.
155
156
  const SelectOption = forwardRef<HTMLDivElement, SelectItemProps>(({ children, classNames, ...props }, forwardedRef) => {
156
157
  const { tx } = useThemeContext();
157
158
  return (