@dxos/react-ui 0.7.4 → 0.7.5-main.937ce75

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 (66) hide show
  1. package/dist/lib/browser/index.mjs +309 -184
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +399 -282
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +309 -184
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/Buttons/IconButton.d.ts +4 -2
  11. package/dist/types/src/components/Buttons/IconButton.d.ts.map +1 -1
  12. package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +1 -1
  13. package/dist/types/src/components/Dialogs/Dialog.d.ts.map +1 -1
  14. package/dist/types/src/components/Input/Input.d.ts +5 -6
  15. package/dist/types/src/components/Input/Input.d.ts.map +1 -1
  16. package/dist/types/src/components/Input/Input.stories.d.ts +1 -3
  17. package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Lists/List.d.ts +2 -0
  19. package/dist/types/src/components/Lists/List.d.ts.map +1 -1
  20. package/dist/types/src/components/Lists/ListDropIndicator.d.ts +11 -0
  21. package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +1 -0
  22. package/dist/types/src/components/Lists/Tree.d.ts +2 -0
  23. package/dist/types/src/components/Lists/Tree.d.ts.map +1 -1
  24. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts +8 -0
  25. package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +1 -0
  26. package/dist/types/src/components/Main/Main.d.ts.map +1 -1
  27. package/dist/types/src/components/Menus/ContextMenu.d.ts.map +1 -1
  28. package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +1 -1
  29. package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
  30. package/dist/types/src/components/Select/Select.d.ts.map +1 -1
  31. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +1 -1
  32. package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
  33. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -0
  34. package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
  35. package/dist/types/src/components/Toolbar/Toolbar.d.ts +11 -5
  36. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  37. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +3 -2
  38. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  39. package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
  40. package/dist/types/tsconfig.tsbuildinfo +1 -0
  41. package/package.json +13 -12
  42. package/src/components/Buttons/IconButton.tsx +19 -5
  43. package/src/components/Clipboard/CopyButton.tsx +1 -1
  44. package/src/components/Dialogs/AlertDialog.tsx +6 -2
  45. package/src/components/Dialogs/Dialog.tsx +6 -2
  46. package/src/components/Input/Input.stories.tsx +4 -6
  47. package/src/components/Input/Input.tsx +29 -44
  48. package/src/components/Lists/List.stories.tsx +2 -2
  49. package/src/components/Lists/List.tsx +3 -0
  50. package/src/components/Lists/ListDropIndicator.tsx +62 -0
  51. package/src/components/Lists/Tree.tsx +3 -0
  52. package/src/components/Lists/TreeDropIndicator.tsx +70 -0
  53. package/src/components/Main/Main.tsx +1 -2
  54. package/src/components/Menus/ContextMenu.tsx +4 -4
  55. package/src/components/Menus/DropdownMenu.tsx +3 -2
  56. package/src/components/Popover/Popover.tsx +4 -2
  57. package/src/components/ScrollArea/ScrollArea.stories.tsx +2 -2
  58. package/src/components/Select/Select.tsx +3 -2
  59. package/src/components/ThemeProvider/ThemeProvider.tsx +1 -2
  60. package/src/components/Toast/Toast.tsx +1 -1
  61. package/src/components/Toolbar/Toolbar.tsx +35 -7
  62. package/src/components/Tooltip/Tooltip.tsx +3 -2
  63. package/src/testing/decorators/withVariants.tsx +4 -4
  64. package/dist/types/src/playground/Surfaces.stories.d.ts +0 -21
  65. package/dist/types/src/playground/Surfaces.stories.d.ts.map +0 -1
  66. package/src/playground/Surfaces.stories.tsx +0 -73
@@ -0,0 +1,62 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/types';
6
+ import React, { type CSSProperties, type HTMLAttributes } from 'react';
7
+
8
+ type Orientation = 'horizontal' | 'vertical';
9
+
10
+ const edgeToOrientationMap: Record<Edge, Orientation> = {
11
+ top: 'horizontal',
12
+ bottom: 'horizontal',
13
+ left: 'vertical',
14
+ right: 'vertical',
15
+ };
16
+
17
+ const orientationStyles: Record<Orientation, HTMLAttributes<HTMLElement>['className']> = {
18
+ horizontal: 'h-[--line-thickness] left-[--terminal-radius] right-0 before:left-[--negative-terminal-size]',
19
+ vertical: 'w-[--line-thickness] top-[--terminal-radius] bottom-0 before:top-[--negative-terminal-size]',
20
+ };
21
+
22
+ const edgeStyles: Record<Edge, HTMLAttributes<HTMLElement>['className']> = {
23
+ top: 'top-[--line-offset] before:top-[--offset-terminal]',
24
+ right: 'right-[--line-offset] before:right-[--offset-terminal]',
25
+ bottom: 'bottom-[--line-offset] before:bottom-[--offset-terminal]',
26
+ left: 'left-[--line-offset] before:left-[--offset-terminal]',
27
+ };
28
+
29
+ const strokeSize = 2;
30
+ const terminalSize = 8;
31
+ const offsetToAlignTerminalWithLine = (strokeSize - terminalSize) / 2;
32
+
33
+ export type DropIndicatorProps = {
34
+ edge: Edge;
35
+ gap?: number;
36
+ };
37
+
38
+ /**
39
+ * This is a tailwind port of `@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box`
40
+ */
41
+ export const ListDropIndicator = ({ edge, gap = 0 }: DropIndicatorProps) => {
42
+ const lineOffset = `calc(-0.5 * (${gap}px + ${strokeSize}px))`;
43
+
44
+ const orientation = edgeToOrientationMap[edge];
45
+
46
+ return (
47
+ <div
48
+ role='none'
49
+ style={
50
+ {
51
+ '--line-thickness': `${strokeSize}px`,
52
+ '--line-offset': `${lineOffset}`,
53
+ '--terminal-size': `${terminalSize}px`,
54
+ '--terminal-radius': `${terminalSize / 2}px`,
55
+ '--negative-terminal-size': `-${terminalSize}px`,
56
+ '--offset-terminal': `${offsetToAlignTerminalWithLine}px`,
57
+ } as CSSProperties
58
+ }
59
+ className={`absolute z-10 pointer-events-none bg-accentSurface before:content-[''] before:w-[--terminal-size] before:h-[--terminal-size] box-border before:absolute before:border-[length:--line-thickness] before:border-solid before:border-accentSurface before:rounded-full ${orientationStyles[orientation]} ${edgeStyles[edge]}`}
60
+ />
61
+ );
62
+ };
@@ -16,6 +16,7 @@ import {
16
16
  LIST_ITEM_NAME,
17
17
  useListItemContext,
18
18
  } from './List';
19
+ import { TreeDropIndicator } from './TreeDropIndicator';
19
20
  import { type ThemedClassName } from '../../util';
20
21
 
21
22
  type TreeRootProps = ListProps;
@@ -60,12 +61,14 @@ export const TreeItem: {
60
61
  Body: ForwardRefExoticComponent<TreeItemBodyProps>;
61
62
  OpenTrigger: ForwardRefExoticComponent<TreeItemOpenTriggerProps>;
62
63
  MockOpenTrigger: FC<ThemedClassName<Omit<ComponentPropsWithoutRef<'div'>, 'children'>>>;
64
+ DropIndicator: typeof TreeDropIndicator;
63
65
  } = {
64
66
  Root: TreeItemRoot,
65
67
  Heading: TreeItemHeading,
66
68
  Body: TreeItemBody,
67
69
  OpenTrigger: TreeItemOpenTrigger,
68
70
  MockOpenTrigger: MockTreeItemOpenTrigger,
71
+ DropIndicator: TreeDropIndicator,
69
72
  };
70
73
 
71
74
  export type { TreeRootProps, TreeItemProps, TreeItemHeadingProps, TreeItemBodyProps, TreeItemOpenTriggerProps };
@@ -0,0 +1,70 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
6
+ import React, { type HTMLAttributes, type CSSProperties } from 'react';
7
+
8
+ // Tree item hitbox
9
+ // https://github.com/atlassian/pragmatic-drag-and-drop/blob/main/packages/hitbox/constellation/index/about.mdx#tree-item
10
+
11
+ type InstructionType = Exclude<Instruction, { type: 'instruction-blocked' }>['type'];
12
+ type Orientation = 'sibling' | 'child';
13
+
14
+ const edgeToOrientationMap: Record<InstructionType, Orientation> = {
15
+ 'reorder-above': 'sibling',
16
+ 'reorder-below': 'sibling',
17
+ 'make-child': 'child',
18
+ reparent: 'child',
19
+ };
20
+
21
+ const orientationStyles: Record<Orientation, HTMLAttributes<HTMLElement>['className']> = {
22
+ // TODO(wittjosiah): Stop using left/right here.
23
+ sibling:
24
+ 'bs-[--line-thickness] left-[--horizontal-indent] right-0 bg-accentSurface before:left-[--negative-terminal-size]',
25
+ child: 'is-full block-start-0 block-end-0 border-[length:--line-thickness] before:invisible',
26
+ };
27
+
28
+ const instructionStyles: Record<InstructionType, HTMLAttributes<HTMLElement>['className']> = {
29
+ 'reorder-above': 'block-start-[--line-offset] before:block-start-[--offset-terminal]',
30
+ 'reorder-below': 'block-end-[--line-offset] before:block-end-[--offset-terminal]',
31
+ 'make-child': 'border-accentSurface',
32
+ // TODO(wittjosiah): This is not occurring in the current implementation.
33
+ reparent: '',
34
+ };
35
+
36
+ const strokeSize = 2;
37
+ const terminalSize = 8;
38
+ const offsetToAlignTerminalWithLine = (strokeSize - terminalSize) / 2;
39
+
40
+ export type DropIndicatorProps = {
41
+ instruction: Instruction;
42
+ gap?: number;
43
+ };
44
+
45
+ export const TreeDropIndicator = ({ instruction, gap = 0 }: DropIndicatorProps) => {
46
+ const lineOffset = `calc(-0.5 * (${gap}px + ${strokeSize}px))`;
47
+ const isBlocked = instruction.type === 'instruction-blocked';
48
+ const desiredInstruction = isBlocked ? instruction.desired : instruction;
49
+ const orientation = edgeToOrientationMap[desiredInstruction.type];
50
+ if (isBlocked) {
51
+ return null;
52
+ }
53
+
54
+ return (
55
+ <div
56
+ style={
57
+ {
58
+ '--line-thickness': `${strokeSize}px`,
59
+ '--line-offset': `${lineOffset}`,
60
+ '--terminal-size': `${terminalSize}px`,
61
+ '--terminal-radius': `${terminalSize / 2}px`,
62
+ '--negative-terminal-size': `-${terminalSize}px`,
63
+ '--offset-terminal': `${offsetToAlignTerminalWithLine}px`,
64
+ '--horizontal-indent': `${desiredInstruction.currentLevel * desiredInstruction.indentPerLevel + 4}px`,
65
+ } as CSSProperties
66
+ }
67
+ className={`absolute z-10 pointer-events-none before:is-[--terminal-size] before:bs-[--terminal-size] box-border before:absolute before:border-[length:--line-thickness] before:border-solid before:border-accentSurface before:rounded-full ${orientationStyles[orientation]} ${instructionStyles[desiredInstruction.type]}`}
68
+ ></div>
69
+ );
70
+ };
@@ -29,7 +29,6 @@ import { useMediaQuery, useForwardedRef } from '@dxos/react-hooks';
29
29
  import { useSwipeToDismiss } from './useSwipeToDismiss';
30
30
  import { useThemeContext } from '../../hooks';
31
31
  import { type ThemedClassName } from '../../util';
32
- import { ElevationProvider } from '../ElevationProvider';
33
32
 
34
33
  const MAIN_ROOT_NAME = 'MainRoot';
35
34
  const NAVIGATION_SIDEBAR_NAME = 'NavigationSidebar';
@@ -227,7 +226,7 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
227
226
  {...(!open && { inert: 'true' })}
228
227
  ref={ref}
229
228
  >
230
- <ElevationProvider elevation='group'>{children}</ElevationProvider>
229
+ {children}
231
230
  </Root>
232
231
  </DialogRoot>
233
232
  );
@@ -6,9 +6,8 @@ import { Primitive } from '@radix-ui/react-primitive';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
7
  import React, { type ComponentPropsWithRef, forwardRef } from 'react';
8
8
 
9
- import { useThemeContext } from '../../hooks';
9
+ import { useElevationContext, useThemeContext } from '../../hooks';
10
10
  import { type ThemedClassName } from '../../util';
11
- import { ElevationProvider } from '../ElevationProvider';
12
11
 
13
12
  type ContextMenuRootProps = ContextMenuPrimitive.ContextMenuProps;
14
13
 
@@ -29,14 +28,15 @@ type ContextMenuContentProps = ThemedClassName<ContextMenuPrimitive.ContextMenuC
29
28
  const ContextMenuContent = forwardRef<HTMLDivElement, ContextMenuContentProps>(
30
29
  ({ classNames, children, ...props }, forwardedRef) => {
31
30
  const { tx } = useThemeContext();
31
+ const elevation = useElevationContext();
32
32
  return (
33
33
  <ContextMenuPrimitive.Content
34
34
  collisionPadding={8}
35
35
  {...props}
36
- className={tx('menu.content', 'menu', {}, classNames)}
36
+ className={tx('menu.content', 'menu', { elevation }, classNames)}
37
37
  ref={forwardedRef}
38
38
  >
39
- <ElevationProvider elevation='chrome'>{children}</ElevationProvider>
39
+ {children}
40
40
  </ContextMenuPrimitive.Content>
41
41
  );
42
42
  },
@@ -28,7 +28,7 @@ import React, {
28
28
  type RefObject,
29
29
  } from 'react';
30
30
 
31
- import { useThemeContext } from '../../hooks';
31
+ import { useElevationContext, useThemeContext } from '../../hooks';
32
32
  import { type ThemedClassName } from '../../util';
33
33
 
34
34
  type Direction = 'ltr' | 'rtl';
@@ -235,6 +235,7 @@ const DropdownMenuContent = forwardRef<DropdownMenuContentElement, DropdownMenuC
235
235
  const { __scopeDropdownMenu, classNames, ...contentProps } = props;
236
236
  const { tx } = useThemeContext();
237
237
  const context = useDropdownMenuContext(CONTENT_NAME, __scopeDropdownMenu);
238
+ const elevation = useElevationContext();
238
239
  const menuScope = useMenuScope(__scopeDropdownMenu);
239
240
  const hasInteractedOutsideRef = useRef(false);
240
241
 
@@ -261,7 +262,7 @@ const DropdownMenuContent = forwardRef<DropdownMenuContentElement, DropdownMenuC
261
262
  hasInteractedOutsideRef.current = true;
262
263
  }
263
264
  })}
264
- className={tx('menu.content', 'menu', {}, classNames)}
265
+ className={tx('menu.content', 'menu', { elevation }, classNames)}
265
266
  style={{
266
267
  ...props.style,
267
268
  // re-namespace exposed content custom properties
@@ -36,7 +36,7 @@ import React, {
36
36
  } from 'react';
37
37
  import { RemoveScroll } from 'react-remove-scroll';
38
38
 
39
- import { useThemeContext } from '../../hooks';
39
+ import { useElevationContext, useThemeContext } from '../../hooks';
40
40
  import { type ThemedClassName } from '../../util';
41
41
 
42
42
  /* -------------------------------------------------------------------------------------------------
@@ -258,6 +258,7 @@ const PopoverContent = forwardRef<PopoverContentTypeElement, PopoverContentProps
258
258
  const portalContext = usePortalContext(CONTENT_NAME, props.__scopePopover);
259
259
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
260
260
  const context = usePopoverContext(CONTENT_NAME, props.__scopePopover);
261
+
261
262
  return (
262
263
  <Presence present={forceMount || context.open}>
263
264
  {context.modal ? (
@@ -433,6 +434,7 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
433
434
  const context = usePopoverContext(CONTENT_NAME, __scopePopover);
434
435
  const popperScope = usePopperScope(__scopePopover);
435
436
  const { tx } = useThemeContext();
437
+ const elevation = useElevationContext();
436
438
 
437
439
  // Make sure the whole tree has focus guards as our `Popover` may be
438
440
  // the last element in the DOM (because of the `Portal`)
@@ -461,7 +463,7 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
461
463
  id={context.contentId}
462
464
  {...popperScope}
463
465
  {...contentProps}
464
- className={tx('popover.content', 'popover', {}, classNames)}
466
+ className={tx('popover.content', 'popover', { elevation }, classNames)}
465
467
  ref={forwardedRef}
466
468
  style={{
467
469
  ...contentProps.style,
@@ -7,7 +7,7 @@ import '@dxos-theme';
7
7
  import React, { type PropsWithChildren } from 'react';
8
8
 
9
9
  import { faker } from '@dxos/random';
10
- import { groupSurface, surfaceElevation } from '@dxos/react-ui-theme';
10
+ import { groupSurface, surfaceShadow } from '@dxos/react-ui-theme';
11
11
 
12
12
  import { ScrollArea } from './ScrollArea';
13
13
  import { withTheme } from '../../testing';
@@ -17,7 +17,7 @@ faker.seed(1234);
17
17
  const StorybookScrollArea = ({ children }: PropsWithChildren<{}>) => {
18
18
  return (
19
19
  <ScrollArea.Root
20
- classNames={['is-[300px] bs-[400px] rounded', groupSurface, surfaceElevation({ elevation: 'group' })]}
20
+ classNames={['is-[300px] bs-[400px] rounded', groupSurface, surfaceShadow({ elevation: 'positioned' })]}
21
21
  >
22
22
  <ScrollArea.Viewport classNames='rounded p-4'>
23
23
  <p>{children}</p>
@@ -6,7 +6,7 @@ import { CaretDown, CaretUp } from '@phosphor-icons/react';
6
6
  import * as SelectPrimitive from '@radix-ui/react-select';
7
7
  import React, { forwardRef } from 'react';
8
8
 
9
- import { useThemeContext } from '../../hooks';
9
+ import { useElevationContext, useThemeContext } from '../../hooks';
10
10
  import { type ThemedClassName } from '../../util';
11
11
  import { Button, type ButtonProps } from '../Buttons';
12
12
  import { Icon } from '../Icon';
@@ -55,10 +55,11 @@ type SelectContentProps = ThemedClassName<SelectPrimitive.SelectContentProps>;
55
55
  const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
56
56
  ({ classNames, children, ...props }, forwardedRef) => {
57
57
  const { tx } = useThemeContext();
58
+ const elevation = useElevationContext();
58
59
  return (
59
60
  <SelectPrimitive.Content
60
61
  {...props}
61
- className={tx('select.content', 'select__content', {}, classNames)}
62
+ className={tx('select.content', 'select__content', { elevation }, classNames)}
62
63
  position='popper'
63
64
  ref={forwardedRef}
64
65
  >
@@ -41,7 +41,6 @@ export const ThemeProvider = ({
41
41
  tx = (_path, defaultClassName, _styleProps, ..._options) => defaultClassName,
42
42
  themeMode = 'dark',
43
43
  rootDensity = 'fine',
44
- rootElevation = 'base',
45
44
  ...rest
46
45
  }: ThemeProviderProps) => {
47
46
  useEffect(() => {
@@ -61,7 +60,7 @@ export const ThemeProvider = ({
61
60
  appNs,
62
61
  }}
63
62
  >
64
- <ElevationProvider elevation={rootElevation}>
63
+ <ElevationProvider elevation='base'>
65
64
  <DensityProvider density={rootDensity}>{children}</DensityProvider>
66
65
  </ElevationProvider>
67
66
  </TranslationsProvider>
@@ -45,7 +45,7 @@ const ToastRoot = forwardRef<HTMLLIElement, ToastRootProps>(({ classNames, child
45
45
  const { tx } = useThemeContext();
46
46
  return (
47
47
  <ToastRootPrimitive {...props} className={tx('toast.root', 'toast', {}, classNames)} ref={forwardedRef}>
48
- <ElevationProvider elevation='chrome'>{children}</ElevationProvider>
48
+ <ElevationProvider elevation='toast'>{children}</ElevationProvider>
49
49
  </ToastRootPrimitive>
50
50
  );
51
51
  });
@@ -2,6 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import type { ToggleGroupItemProps as ToggleGroupItemPrimitiveProps } from '@radix-ui/react-toggle-group';
5
6
  import * as ToolbarPrimitive from '@radix-ui/react-toolbar';
6
7
  import React, { forwardRef } from 'react';
7
8
 
@@ -15,6 +16,8 @@ import {
15
16
  Toggle,
16
17
  type ToggleGroupItemProps,
17
18
  type ToggleProps,
19
+ IconButton,
20
+ type IconButtonProps,
18
21
  } from '../Buttons';
19
22
  import { Link, type LinkProps } from '../Link';
20
23
  import { Separator, type SeparatorProps } from '../Separator';
@@ -40,6 +43,16 @@ const ToolbarButton = forwardRef<HTMLButtonElement, ToolbarButtonProps>((props,
40
43
  );
41
44
  });
42
45
 
46
+ type ToolbarIconButtonProps = IconButtonProps;
47
+
48
+ const ToolbarIconButton = forwardRef<HTMLButtonElement, ToolbarIconButtonProps>((props, forwardedRef) => {
49
+ return (
50
+ <ToolbarPrimitive.Button asChild>
51
+ <IconButton {...props} ref={forwardedRef} />
52
+ </ToolbarPrimitive.Button>
53
+ );
54
+ });
55
+
43
56
  type ToolbarToggleProps = ToggleProps;
44
57
 
45
58
  const ToolbarToggle = forwardRef<HTMLButtonElement, ToolbarToggleProps>((props, forwardedRef) => {
@@ -88,35 +101,50 @@ const ToolbarToggleGroupItem = forwardRef<HTMLButtonElement, ToolbarToggleGroupI
88
101
  },
89
102
  );
90
103
 
91
- type ToolbarSeparatorProps = SeparatorProps;
104
+ type ToolbarToggleGroupIconItemProps = Omit<ToggleGroupItemPrimitiveProps, 'className'> & IconButtonProps;
92
105
 
93
- const ToolbarSeparator = (props: SeparatorProps) => {
94
- return (
106
+ const ToolbarToggleGroupIconItem = forwardRef<HTMLButtonElement, ToolbarToggleGroupIconItemProps>(
107
+ ({ variant, density, elevation, classNames, icon, label, iconOnly, ...props }, forwardedRef) => {
108
+ return (
109
+ <ToolbarPrimitive.ToolbarToggleItem {...props} asChild>
110
+ <IconButton {...{ variant, density, elevation, classNames, icon, label, iconOnly }} ref={forwardedRef} />
111
+ </ToolbarPrimitive.ToolbarToggleItem>
112
+ );
113
+ },
114
+ );
115
+
116
+ type ToolbarSeparatorProps = SeparatorProps & { variant?: 'gap' | 'line' };
117
+
118
+ const ToolbarSeparator = ({ variant = 'line', ...props }: ToolbarSeparatorProps) => {
119
+ return variant === 'line' ? (
95
120
  <ToolbarPrimitive.Separator asChild>
96
- <Separator orientation='vertical' {...props} />
121
+ <Separator {...props} />
97
122
  </ToolbarPrimitive.Separator>
123
+ ) : (
124
+ <ToolbarPrimitive.Separator className='grow' />
98
125
  );
99
126
  };
100
127
 
101
- const ToolbarExpander = () => <div className={'grow'} />;
102
-
103
128
  export const Toolbar = {
104
129
  Root: ToolbarRoot,
105
130
  Button: ToolbarButton,
131
+ IconButton: ToolbarIconButton,
106
132
  Link: ToolbarLink,
107
133
  Toggle: ToolbarToggle,
108
134
  ToggleGroup: ToolbarToggleGroup,
109
135
  ToggleGroupItem: ToolbarToggleGroupItem,
136
+ ToggleGroupIconItem: ToolbarToggleGroupIconItem,
110
137
  Separator: ToolbarSeparator,
111
- Expander: ToolbarExpander,
112
138
  };
113
139
 
114
140
  export type {
115
141
  ToolbarRootProps,
116
142
  ToolbarButtonProps,
143
+ ToolbarIconButtonProps,
117
144
  ToolbarLinkProps,
118
145
  ToolbarToggleProps,
119
146
  ToolbarToggleGroupProps,
120
147
  ToolbarToggleGroupItemProps,
148
+ ToolbarToggleGroupIconItemProps,
121
149
  ToolbarSeparatorProps,
122
150
  };
@@ -18,7 +18,7 @@ import {
18
18
  } from '@radix-ui/react-tooltip';
19
19
  import React, { forwardRef, type FunctionComponent } from 'react';
20
20
 
21
- import { useThemeContext } from '../../hooks';
21
+ import { useElevationContext, useThemeContext } from '../../hooks';
22
22
  import { type ThemedClassName } from '../../util';
23
23
 
24
24
  type TooltipProviderProps = TooltipProviderPrimitiveProps;
@@ -54,12 +54,13 @@ type TooltipContentProps = ThemedClassName<TooltipContentPrimitiveProps>;
54
54
 
55
55
  const TooltipContent = forwardRef<HTMLDivElement, TooltipContentProps>(({ classNames, ...props }, forwardedRef) => {
56
56
  const { tx } = useThemeContext();
57
+ const elevation = useElevationContext();
57
58
  return (
58
59
  <TooltipContentPrimitive
59
60
  sideOffset={4}
60
61
  collisionPadding={8}
61
62
  {...props}
62
- className={tx('tooltip.content', 'tooltip', {}, classNames)}
63
+ className={tx('tooltip.content', 'tooltip', { elevation }, classNames)}
63
64
  ref={forwardedRef}
64
65
  />
65
66
  );
@@ -7,7 +7,7 @@ import '@dxos-theme';
7
7
  import { type Decorator } from '@storybook/react';
8
8
  import React from 'react';
9
9
 
10
- import { modalSurface, groupSurface, mx, surfaceElevation } from '@dxos/react-ui-theme';
10
+ import { modalSurface, groupSurface, mx, surfaceShadow } from '@dxos/react-ui-theme';
11
11
  import { type Density, type Elevation } from '@dxos/react-ui-types';
12
12
 
13
13
  import { DensityProvider, ElevationProvider } from '../../components';
@@ -20,8 +20,8 @@ type Config = {
20
20
  export const withVariants = ({
21
21
  elevations = [
22
22
  { elevation: 'base' },
23
- { elevation: 'group', surface: groupSurface },
24
- { elevation: 'chrome', surface: modalSurface },
23
+ { elevation: 'positioned', surface: groupSurface },
24
+ { elevation: 'dialog', surface: modalSurface },
25
25
  ],
26
26
  densities = ['coarse', 'fine'],
27
27
  }: Config = {}): Decorator => {
@@ -32,7 +32,7 @@ export const withVariants = ({
32
32
  <div className='flex flex-col gap-8'>
33
33
  {densities.map((density) => (
34
34
  <DensityProvider key={density} density={density}>
35
- <div className={mx('p-4 rounded-lg', surface, surfaceElevation({ elevation }))}>
35
+ <div className={mx('p-4 rounded-lg', surface, surfaceShadow({ elevation }))}>
36
36
  <Story />
37
37
  </div>
38
38
  </DensityProvider>
@@ -1,21 +0,0 @@
1
- import '@dxos-theme';
2
- import React, { type PropsWithChildren } from 'react';
3
- type SurfaceLevel = 'base' | 'group' | 'chrome' | 'fixed' | 'input' | 'accent';
4
- declare const _default: {
5
- title: string;
6
- component: ({ children, level }: PropsWithChildren & {
7
- level: SurfaceLevel;
8
- }) => React.JSX.Element;
9
- render: () => React.JSX.Element;
10
- decorators: import("@storybook/react/*").Decorator[];
11
- parameters: {
12
- chromatic: {
13
- disableSnapshot: boolean;
14
- };
15
- };
16
- };
17
- export default _default;
18
- export declare const Default: {
19
- args: {};
20
- };
21
- //# sourceMappingURL=Surfaces.stories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Surfaces.stories.d.ts","sourceRoot":"","sources":["../../../../src/playground/Surfaces.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAgBtD,KAAK,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;;;qCAEzC,iBAAiB,GAAG;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE;;;;;;;;;AAsCjF,wBAME;AAEF,eAAO,MAAM,OAAO;;CAEnB,CAAC"}
@@ -1,73 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import React, { type PropsWithChildren } from 'react';
8
-
9
- import {
10
- baseSurface,
11
- modalSurface,
12
- groupSurface,
13
- mx,
14
- surfaceElevation,
15
- fixedSurface,
16
- fixedBorder,
17
- attentionSurface,
18
- accentSurface,
19
- } from '@dxos/react-ui-theme';
20
-
21
- import { withTheme } from '../testing';
22
-
23
- type SurfaceLevel = 'base' | 'group' | 'chrome' | 'fixed' | 'input' | 'accent';
24
-
25
- const Surface = ({ children, level }: PropsWithChildren & { level: SurfaceLevel }) => {
26
- const surface =
27
- level === 'chrome'
28
- ? [modalSurface, surfaceElevation({ elevation: 'chrome' })]
29
- : level === 'group'
30
- ? [groupSurface, surfaceElevation({ elevation: 'group' })]
31
- : level === 'input'
32
- ? [attentionSurface, surfaceElevation({ elevation: 'group' })]
33
- : level === 'fixed'
34
- ? [fixedSurface, fixedBorder, 'border', surfaceElevation({ elevation: 'chrome' })]
35
- : level === 'accent'
36
- ? [accentSurface, surfaceElevation({ elevation: 'chrome' })]
37
- : [baseSurface];
38
-
39
- return (
40
- <div
41
- role='region'
42
- className={mx('flex justify-center items-center m-8 p-2 w-[320px] h-[160px] rounded-lg', ...surface)}
43
- >
44
- <div>{level}</div>
45
- {children}
46
- </div>
47
- );
48
- };
49
-
50
- const SurfaceStory = () => {
51
- return (
52
- <div className='bg-cubes p-10 m-0'>
53
- <Surface level='fixed' />
54
- <Surface level='base' />
55
- <Surface level='group' />
56
- <Surface level='chrome' />
57
- <Surface level='input' />
58
- <Surface level='accent' />
59
- </div>
60
- );
61
- };
62
-
63
- export default {
64
- title: 'ui/react-ui-core/Playground/Surfaces',
65
- component: Surface,
66
- render: SurfaceStory,
67
- decorators: [withTheme],
68
- parameters: { chromatic: { disableSnapshot: false } },
69
- };
70
-
71
- export const Default = {
72
- args: {},
73
- };