@dxos/react-ui-stack 0.8.4-main.b97322e → 0.8.4-main.bc674ce

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 (107) hide show
  1. package/dist/lib/browser/index.mjs +923 -50
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/playwright/index.mjs +4 -0
  5. package/dist/lib/browser/playwright/index.mjs.map +2 -2
  6. package/dist/lib/node-esm/index.mjs +924 -50
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/lib/node-esm/playwright/index.mjs +4 -0
  10. package/dist/lib/node-esm/playwright/index.mjs.map +2 -2
  11. package/dist/types/src/{exemplars → components}/CardStack/CardStack.d.ts +20 -13
  12. package/dist/types/src/components/CardStack/CardStack.d.ts.map +1 -0
  13. package/dist/types/src/components/CardStack/CardStack.stories.d.ts +15 -0
  14. package/dist/types/src/components/CardStack/CardStack.stories.d.ts.map +1 -0
  15. package/dist/types/src/{exemplars → components}/CardStack/CardStackDragPreview.d.ts +1 -1
  16. package/dist/types/src/components/CardStack/CardStackDragPreview.d.ts.map +1 -0
  17. package/dist/types/src/components/CardStack/index.d.ts.map +1 -0
  18. package/dist/types/src/components/Stack/Stack.d.ts +15 -7
  19. package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
  20. package/dist/types/src/components/Stack/Stack.stories.d.ts +12 -3
  21. package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
  22. package/dist/types/src/components/StackContext.d.ts +2 -1
  23. package/dist/types/src/components/StackContext.d.ts.map +1 -1
  24. package/dist/types/src/components/StackItem/StackItem.d.ts +9 -12
  25. package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
  26. package/dist/types/src/components/StackItem/StackItem.stories.d.ts +13 -5
  27. package/dist/types/src/components/StackItem/StackItem.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/StackItem/StackItemContent.d.ts +4 -37
  29. package/dist/types/src/components/StackItem/StackItemContent.d.ts.map +1 -1
  30. package/dist/types/src/components/StackItem/StackItemHeading.d.ts +1 -1
  31. package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
  32. package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts.map +1 -1
  33. package/dist/types/src/components/StackItem/StackItemSigil.d.ts +2 -2
  34. package/dist/types/src/components/StackItem/StackItemSigil.d.ts.map +1 -1
  35. package/dist/types/src/components/deprecated/LayoutControls.d.ts +3 -0
  36. package/dist/types/src/components/deprecated/LayoutControls.d.ts.map +1 -1
  37. package/dist/types/src/components/index.d.ts +2 -1
  38. package/dist/types/src/components/index.d.ts.map +1 -1
  39. package/dist/types/src/components/{defs.d.ts → types.d.ts} +1 -1
  40. package/dist/types/src/components/types.d.ts.map +1 -0
  41. package/dist/types/src/hooks/useStackDropForElements.d.ts +9 -7
  42. package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -1
  43. package/dist/types/src/index.d.ts +0 -1
  44. package/dist/types/src/index.d.ts.map +1 -1
  45. package/dist/types/src/translations.d.ts +2 -2
  46. package/dist/types/src/translations.d.ts.map +1 -1
  47. package/dist/types/tsconfig.tsbuildinfo +1 -1
  48. package/package.json +41 -38
  49. package/src/{exemplars → components}/CardStack/CardStack.stories.tsx +19 -18
  50. package/src/{exemplars → components}/CardStack/CardStack.tsx +114 -54
  51. package/src/{exemplars → components}/CardStack/CardStackDragPreview.tsx +3 -3
  52. package/src/components/Stack/Stack.stories.tsx +8 -9
  53. package/src/components/Stack/Stack.tsx +225 -26
  54. package/src/components/StackContext.tsx +2 -1
  55. package/src/components/StackItem/StackItem.stories.tsx +19 -15
  56. package/src/components/StackItem/StackItem.tsx +49 -29
  57. package/src/components/StackItem/StackItemContent.tsx +18 -39
  58. package/src/components/StackItem/StackItemHeading.tsx +5 -9
  59. package/src/components/StackItem/StackItemResizeHandle.tsx +2 -1
  60. package/src/components/StackItem/StackItemSigil.tsx +5 -4
  61. package/src/components/deprecated/LayoutControls.tsx +3 -0
  62. package/src/components/index.ts +2 -1
  63. package/src/hooks/useStackDropForElements.ts +59 -45
  64. package/src/index.ts +0 -3
  65. package/src/playwright/playwright.config.ts +1 -1
  66. package/src/translations.ts +1 -1
  67. package/dist/lib/browser/chunk-P3TQV4BA.mjs +0 -1198
  68. package/dist/lib/browser/chunk-P3TQV4BA.mjs.map +0 -7
  69. package/dist/lib/browser/testing/index.mjs +0 -31
  70. package/dist/lib/browser/testing/index.mjs.map +0 -7
  71. package/dist/lib/node-esm/chunk-3WVEPAJ4.mjs +0 -1200
  72. package/dist/lib/node-esm/chunk-3WVEPAJ4.mjs.map +0 -7
  73. package/dist/lib/node-esm/testing/index.mjs +0 -32
  74. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  75. package/dist/types/src/components/defs.d.ts.map +0 -1
  76. package/dist/types/src/exemplars/Card/Card.d.ts +0 -58
  77. package/dist/types/src/exemplars/Card/Card.d.ts.map +0 -1
  78. package/dist/types/src/exemplars/Card/Card.stories.d.ts +0 -13
  79. package/dist/types/src/exemplars/Card/Card.stories.d.ts.map +0 -1
  80. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts +0 -6
  81. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts.map +0 -1
  82. package/dist/types/src/exemplars/Card/fragments.d.ts +0 -12
  83. package/dist/types/src/exemplars/Card/fragments.d.ts.map +0 -1
  84. package/dist/types/src/exemplars/Card/index.d.ts +0 -4
  85. package/dist/types/src/exemplars/Card/index.d.ts.map +0 -1
  86. package/dist/types/src/exemplars/CardStack/CardStack.d.ts.map +0 -1
  87. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts +0 -9
  88. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts.map +0 -1
  89. package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts.map +0 -1
  90. package/dist/types/src/exemplars/CardStack/index.d.ts.map +0 -1
  91. package/dist/types/src/exemplars/index.d.ts +0 -3
  92. package/dist/types/src/exemplars/index.d.ts.map +0 -1
  93. package/dist/types/src/testing/CardContainer.d.ts +0 -6
  94. package/dist/types/src/testing/CardContainer.d.ts.map +0 -1
  95. package/dist/types/src/testing/index.d.ts +0 -2
  96. package/dist/types/src/testing/index.d.ts.map +0 -1
  97. package/src/exemplars/Card/Card.stories.tsx +0 -78
  98. package/src/exemplars/Card/Card.tsx +0 -186
  99. package/src/exemplars/Card/CardDragPreview.tsx +0 -22
  100. package/src/exemplars/Card/fragments.ts +0 -23
  101. package/src/exemplars/Card/index.ts +0 -7
  102. package/src/exemplars/index.ts +0 -6
  103. package/src/testing/CardContainer.tsx +0 -34
  104. package/src/testing/index.ts +0 -5
  105. /package/dist/types/src/{exemplars → components}/CardStack/index.d.ts +0 -0
  106. /package/src/{exemplars → components}/CardStack/index.ts +0 -0
  107. /package/src/components/{defs.ts → types.ts} +0 -0
@@ -5,70 +5,47 @@
5
5
  import React, { type ComponentPropsWithoutRef, forwardRef, useMemo } from 'react';
6
6
 
7
7
  import { type ThemedClassName } from '@dxos/react-ui';
8
- import { mx } from '@dxos/react-ui-theme';
8
+ import { mx } from '@dxos/ui-theme';
9
9
 
10
10
  import { useStack, useStackItem } from '../StackContext';
11
11
 
12
- export type StackItemContentProps = ThemedClassName<Omit<ComponentPropsWithoutRef<'div'>, 'role'>> & {
13
- /**
14
- * This flag is required in order to clarify a developer experience that seemed like it needed extra boilerplate
15
- * (`row-span-2`) or was buggy. See the description of the StackItem.Content component itself for more information.
16
- */
12
+ export type StackItemContentProps = ThemedClassName<Omit<ComponentPropsWithoutRef<'div'>, 'role' | 'scrollable'>> & {
17
13
  toolbar?: boolean;
18
-
19
- /**
20
- * Whether to provide for the layout of a statusbar after the content.
21
- */
22
14
  statusbar?: boolean;
23
-
24
- /**
25
- * Whether the consumer intends to do something custom and typical affordances should not apply
26
- */
27
- layoutManaged?: boolean;
28
-
29
- /**
30
- * Whether to set a certain aspect ratio on the content, including the toolbar and statusbar. This is provided for
31
- * convenience and consistency; it can instead be specified by the `classNames` or `style` props as needed.
32
- */
33
- size?: 'intrinsic' | 'video' | 'square';
34
15
  };
35
16
 
36
17
  /**
37
- * This component should be used by plugins for rendering content within a stack item, a.k.a. a “plank” or “section”.
38
- * The `toolbar` flag must be provided since this component provides for the layout of content with the toolbar.
18
+ * This component should be used by plugins for rendering content within a stack item (i.e., a “plank” or “section”).
39
19
  */
40
20
  export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps>(
41
- ({ children, toolbar, statusbar, layoutManaged, classNames, size = 'intrinsic', ...props }, forwardedRef) => {
21
+ ({ classNames, children, toolbar, statusbar, ...props }, forwardedRef) => {
42
22
  const { size: stackItemSize } = useStack();
43
23
  const { role } = useStackItem();
44
24
  const style = useMemo(
45
- () =>
46
- layoutManaged
47
- ? {}
48
- : {
49
- gridTemplateRows: [
50
- ...(toolbar ? [role === 'section' ? 'calc(var(--toolbar-size) - 1px)' : 'var(--toolbar-size)'] : []),
51
- '1fr',
52
- ...(statusbar ? ['var(--statusbar-size)'] : []),
53
- ].join(' '),
54
- },
55
- [toolbar, statusbar, layoutManaged],
25
+ () => ({
26
+ gridTemplateRows: [
27
+ ...(toolbar ? [role === 'section' ? 'calc(var(--toolbar-size) - 1px)' : 'var(--toolbar-size)'] : []),
28
+ '1fr',
29
+ ...(statusbar ? ['var(--statusbar-size)'] : []),
30
+ ].join(' '),
31
+ }),
32
+ [toolbar, statusbar],
56
33
  );
34
+
57
35
  return (
58
36
  <div
59
- role='none'
60
37
  {...props}
38
+ role='none'
39
+ style={style}
61
40
  className={mx(
62
41
  'group grid grid-cols-[100%] density-coarse',
63
42
  stackItemSize === 'contain' && 'min-bs-0 overflow-hidden',
64
- size === 'video' ? 'aspect-video' : size === 'square' && 'aspect-square',
65
- toolbar && '[&>.dx-toolbar]:relative [&>.dx-toolbar]:border-be [&>.dx-toolbar]:border-subduedSeparator',
66
43
  role === 'section' &&
67
44
  toolbar &&
68
45
  '[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:block-start-0 [&_.dx-toolbar]:-mbe-px [&_.dx-toolbar]:min-is-0',
46
+ toolbar && '[&>.dx-toolbar]:relative [&>.dx-toolbar]:border-be [&>.dx-toolbar]:border-subduedSeparator',
69
47
  classNames,
70
48
  )}
71
- style={style}
72
49
  data-popover-collision-boundary={true}
73
50
  ref={forwardedRef}
74
51
  >
@@ -77,3 +54,5 @@ export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps
77
54
  );
78
55
  },
79
56
  );
57
+
58
+ StackItemContent.displayName = 'StackItemContent';
@@ -2,18 +2,17 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { useFocusableGroup } from '@fluentui/react-tabster';
6
5
  import { Slot } from '@radix-ui/react-slot';
7
6
  import React, {
8
- type ComponentPropsWithoutRef,
9
7
  type ComponentPropsWithRef,
10
- forwardRef,
8
+ type ComponentPropsWithoutRef,
11
9
  type PropsWithChildren,
10
+ forwardRef,
12
11
  } from 'react';
13
12
 
14
13
  import { type ThemedClassName } from '@dxos/react-ui';
15
- import { useAttention, type AttendableId, type Related } from '@dxos/react-ui-attention';
16
- import { mx } from '@dxos/react-ui-theme';
14
+ import { type AttendableId, type Related, useAttention } from '@dxos/react-ui-attention';
15
+ import { mx } from '@dxos/ui-theme';
17
16
 
18
17
  import { useStack } from '../StackContext';
19
18
 
@@ -30,7 +29,6 @@ export const StackItemHeading = ({
30
29
  ...props
31
30
  }: StackItemHeadingProps) => {
32
31
  const { orientation } = useStack();
33
- const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited' });
34
32
 
35
33
  const Root = asChild ? Slot : 'div';
36
34
 
@@ -38,10 +36,8 @@ export const StackItemHeading = ({
38
36
  <Root
39
37
  role='heading'
40
38
  {...props}
41
- tabIndex={0}
42
- {...focusableGroupAttrs}
43
39
  className={mx(
44
- 'flex items-center dx-focus-ring-inset-over-all relative !border-is-0 bg-headerSurface',
40
+ 'flex items-center !border-is-0 bg-headerSurface',
45
41
  separateOnScroll
46
42
  ? 'border-transparent [[data-scroll-separator="true"]_&]:border-subduedSeparator'
47
43
  : 'border-subduedSeparator',
@@ -6,9 +6,10 @@ import React from 'react';
6
6
 
7
7
  import { ResizeHandle } from '@dxos/react-ui-dnd';
8
8
 
9
- import { DEFAULT_EXTRINSIC_SIZE } from './StackItem';
10
9
  import { useStack, useStackItem } from '../StackContext';
11
10
 
11
+ import { DEFAULT_EXTRINSIC_SIZE } from './StackItem';
12
+
12
13
  const MIN_WIDTH = 20;
13
14
  const MIN_HEIGHT = 3;
14
15
 
@@ -4,16 +4,17 @@
4
4
 
5
5
  import React, { Fragment, type PropsWithChildren, forwardRef, useState } from 'react';
6
6
 
7
- import { type ActionLike } from '@dxos/app-graph';
7
+ import { type Node } from '@dxos/app-graph';
8
8
  import { keySymbols } from '@dxos/keyboard';
9
9
  import { Button, type ButtonProps, DropdownMenu, Icon, toLocalizedString, useTranslation } from '@dxos/react-ui';
10
10
  import { type AttendableId, type Related, useAttention } from '@dxos/react-ui-attention';
11
- import { descriptionText, mx } from '@dxos/react-ui-theme';
11
+ import { descriptionText, mx } from '@dxos/ui-theme';
12
12
  import { getHostPlatform } from '@dxos/util';
13
13
 
14
- import { MenuSignifierHorizontal } from './MenuSignifier';
15
14
  import { translationKey } from '../../translations';
16
15
 
16
+ import { MenuSignifierHorizontal } from './MenuSignifier';
17
+
17
18
  export type KeyBinding = {
18
19
  windows?: string;
19
20
  macos?: string;
@@ -22,7 +23,7 @@ export type KeyBinding = {
22
23
  unknown?: string;
23
24
  };
24
25
 
25
- export type StackItemSigilAction = Pick<ActionLike, 'id' | 'properties' | 'data'>;
26
+ export type StackItemSigilAction = Pick<Node.ActionLike, 'id' | 'properties' | 'data'>;
26
27
 
27
28
  export type StackItemSigilButtonProps = Omit<ButtonProps, 'variant'> &
28
29
  AttendableId &
@@ -30,6 +30,9 @@ const LayoutControl = ({ icon, label, ...props }: Omit<ButtonProps, 'children'>
30
30
  return <IconButton iconOnly icon={icon} label={label} tooltipSide='bottom' variant='ghost' {...props} />;
31
31
  };
32
32
 
33
+ /**
34
+ * @deprecated
35
+ */
33
36
  export const LayoutControls = forwardRef<HTMLDivElement, LayoutControlsProps>(
34
37
  (
35
38
  { onClick, variant = 'default', capabilities: can, isSolo, pin, close = false, children, ...props },
@@ -2,7 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export type * from './defs';
5
+ export type * from './types';
6
6
 
7
+ export * from './CardStack';
7
8
  export * from './Stack';
8
9
  export * from './StackItem';
@@ -8,70 +8,84 @@ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-sc
8
8
  import { attachClosestEdge, extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
9
9
  import { useLayoutEffect, useState } from 'react';
10
10
 
11
- import { type StackItemRearrangeHandler, type StackItemData, type Orientation } from '../components';
11
+ import { type Orientation, type StackItemData, type StackItemRearrangeHandler } from '../components';
12
+
13
+ const noop = () => {};
14
+
15
+ export type UseStackDropForElementsProps = {
16
+ id?: string;
17
+ element: HTMLDivElement | null;
18
+ scrollElement?: HTMLDivElement | null;
19
+ orientation: Orientation;
20
+ selfDroppable: boolean;
21
+ onRearrange?: StackItemRearrangeHandler;
22
+ };
23
+
24
+ export type UseStackDropForElements = {
25
+ dropping: boolean;
26
+ };
12
27
 
13
28
  /**
14
- * Hook to handle drag and drop functionality for Stack components.
29
+ * Hook to handle drag-and-drop functionality for Stack components.
15
30
  */
16
31
  export const useStackDropForElements = ({
17
32
  id,
18
33
  element,
19
34
  scrollElement = element,
20
- selfDroppable,
21
35
  orientation,
36
+ selfDroppable,
22
37
  onRearrange,
23
- }: {
24
- id?: string;
25
- element: HTMLDivElement | null;
26
- scrollElement?: HTMLDivElement | null;
27
- selfDroppable: boolean;
28
- orientation: Orientation;
29
- onRearrange?: StackItemRearrangeHandler;
30
- }) => {
38
+ }: UseStackDropForElementsProps): UseStackDropForElements => {
31
39
  const [dropping, setDropping] = useState(false);
32
40
 
33
41
  useLayoutEffect(() => {
34
- if (!element || !selfDroppable) {
42
+ if (!element) {
35
43
  return;
36
44
  }
37
45
 
38
46
  const acceptSourceType = orientation === 'horizontal' ? 'column' : 'card';
39
47
 
48
+ // TODO(burdon): Use monitor?
40
49
  return combine(
41
- dropTargetForElements({
42
- element,
43
- getData: ({ input, element }) => {
44
- return attachClosestEdge(
45
- { id, type: orientation === 'horizontal' ? 'card' : 'column' },
46
- { input, element, allowedEdges: [orientation === 'horizontal' ? 'left' : 'top'] },
47
- );
48
- },
49
- onDragEnter: ({ source }) => {
50
- if (source.data.type === acceptSourceType) {
51
- setDropping(true);
52
- }
53
- },
54
- onDrag: ({ source }) => {
55
- if (source.data.type === acceptSourceType) {
56
- setDropping(true);
57
- }
58
- },
59
- onDragLeave: () => {
60
- return setDropping(false);
61
- },
62
- onDrop: ({ self, source }) => {
63
- setDropping(false);
64
- if (source.data.type === acceptSourceType && selfDroppable && onRearrange) {
65
- onRearrange(source.data as StackItemData, self.data as StackItemData, extractClosestEdge(self.data));
66
- }
67
- },
68
- }),
69
- autoScrollForElements({
70
- element: scrollElement as Element,
71
- getAllowedAxis: () => orientation,
72
- }),
50
+ selfDroppable
51
+ ? dropTargetForElements({
52
+ element,
53
+ getData: ({ input, element }) => {
54
+ return attachClosestEdge(
55
+ { id, type: orientation === 'horizontal' ? 'card' : 'column' },
56
+ { input, element, allowedEdges: [orientation === 'horizontal' ? 'left' : 'top'] },
57
+ );
58
+ },
59
+ onDragEnter: ({ source }) => {
60
+ if (source.data.type === acceptSourceType) {
61
+ setDropping(true);
62
+ }
63
+ },
64
+ onDrag: ({ source }) => {
65
+ if (source.data.type === acceptSourceType) {
66
+ setDropping(true);
67
+ }
68
+ },
69
+ onDragLeave: () => {
70
+ return setDropping(false);
71
+ },
72
+ onDrop: ({ self, source }) => {
73
+ setDropping(false);
74
+ if (source.data.type === acceptSourceType && selfDroppable && onRearrange) {
75
+ onRearrange(source.data as StackItemData, self.data as StackItemData, extractClosestEdge(self.data));
76
+ }
77
+ },
78
+ })
79
+ : noop,
80
+
81
+ scrollElement
82
+ ? autoScrollForElements({
83
+ element: scrollElement,
84
+ getAllowedAxis: () => orientation,
85
+ })
86
+ : noop,
73
87
  );
74
- }, [element, scrollElement, selfDroppable, orientation, id, onRearrange]);
88
+ }, [id, element, scrollElement, selfDroppable, orientation, onRearrange]);
75
89
 
76
90
  return { dropping };
77
91
  };
package/src/index.ts CHANGED
@@ -2,8 +2,5 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- // TODO(thure): Consider exporting exemplars from separate endpoints.
6
-
7
5
  export * from './components';
8
- export * from './exemplars';
9
6
  export * from './translations';
@@ -10,7 +10,7 @@ export default defineConfig({
10
10
  ...e2ePreset(import.meta.dirname),
11
11
  // TODO(wittjosiah): Avoid hard-coding ports.
12
12
  webServer: {
13
- command: 'moon run storybook:serve-e2e -- --port=9003',
13
+ command: 'moon run storybook-react:serve-e2e -- --port=9003',
14
14
  port: 9003,
15
15
  reuseExistingServer: false,
16
16
  },
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { type Resource } from '@dxos/react-ui';
6
6
 
7
- export const translationKey = 'react-ui-stack';
7
+ export const translationKey = '@dxos/react-ui-stack';
8
8
 
9
9
  export const translations = [
10
10
  {