@dxos/react-ui-stack 0.8.4-main.c4373fc → 0.8.4-main.cb12b3f963

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 (120) hide show
  1. package/dist/lib/browser/index.mjs +706 -71
  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 +10 -23
  5. package/dist/lib/browser/playwright/index.mjs.map +2 -2
  6. package/dist/lib/browser/translations.mjs +23 -0
  7. package/dist/lib/browser/translations.mjs.map +7 -0
  8. package/dist/lib/node-esm/index.mjs +707 -71
  9. package/dist/lib/node-esm/index.mjs.map +4 -4
  10. package/dist/lib/node-esm/meta.json +1 -1
  11. package/dist/lib/node-esm/playwright/index.mjs +10 -23
  12. package/dist/lib/node-esm/playwright/index.mjs.map +2 -2
  13. package/dist/lib/node-esm/translations.mjs +25 -0
  14. package/dist/lib/node-esm/translations.mjs.map +7 -0
  15. package/dist/types/src/components/Stack/Stack.d.ts +5 -10
  16. package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
  17. package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/StackContext.d.ts +1 -1
  19. package/dist/types/src/components/StackContext.d.ts.map +1 -1
  20. package/dist/types/src/components/StackItem/MenuSignifier.d.ts.map +1 -1
  21. package/dist/types/src/components/StackItem/StackItem.d.ts +10 -14
  22. package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
  23. package/dist/types/src/components/StackItem/StackItem.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/StackItem/StackItemContent.d.ts +2 -43
  25. package/dist/types/src/components/StackItem/StackItemContent.d.ts.map +1 -1
  26. package/dist/types/src/components/StackItem/StackItemDragHandle.d.ts.map +1 -1
  27. package/dist/types/src/components/StackItem/StackItemHeading.d.ts +1 -1
  28. package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
  29. package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts +1 -1
  30. package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts.map +1 -1
  31. package/dist/types/src/components/StackItem/StackItemSigil.d.ts +2 -2
  32. package/dist/types/src/components/StackItem/StackItemSigil.d.ts.map +1 -1
  33. package/dist/types/src/components/index.d.ts +1 -2
  34. package/dist/types/src/components/index.d.ts.map +1 -1
  35. package/dist/types/src/components/{defs.d.ts → types.d.ts} +1 -1
  36. package/dist/types/src/components/types.d.ts.map +1 -0
  37. package/dist/types/src/hooks/useStackDropForElements.d.ts +8 -6
  38. package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -1
  39. package/dist/types/src/index.d.ts +0 -2
  40. package/dist/types/src/index.d.ts.map +1 -1
  41. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
  42. package/dist/types/src/playwright/stack-manager.d.ts.map +1 -1
  43. package/dist/types/src/translations.d.ts +10 -10
  44. package/dist/types/src/translations.d.ts.map +1 -1
  45. package/dist/types/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +49 -47
  47. package/src/components/Stack/Stack.stories.tsx +10 -12
  48. package/src/components/Stack/Stack.tsx +207 -218
  49. package/src/components/StackContext.tsx +1 -1
  50. package/src/components/StackItem/MenuSignifier.tsx +2 -9
  51. package/src/components/StackItem/StackItem.stories.tsx +7 -5
  52. package/src/components/StackItem/StackItem.tsx +37 -27
  53. package/src/components/StackItem/StackItemContent.tsx +23 -54
  54. package/src/components/StackItem/StackItemDragHandle.tsx +4 -3
  55. package/src/components/StackItem/StackItemHeading.tsx +14 -13
  56. package/src/components/StackItem/StackItemResizeHandle.tsx +1 -2
  57. package/src/components/StackItem/StackItemSigil.tsx +10 -7
  58. package/src/components/index.ts +2 -2
  59. package/src/hooks/useStackDropForElements.ts +60 -46
  60. package/src/index.ts +0 -4
  61. package/src/playwright/playwright.config.ts +1 -1
  62. package/src/translations.ts +9 -9
  63. package/dist/lib/browser/chunk-SM27YTH3.mjs +0 -1418
  64. package/dist/lib/browser/chunk-SM27YTH3.mjs.map +0 -7
  65. package/dist/lib/browser/testing/index.mjs +0 -31
  66. package/dist/lib/browser/testing/index.mjs.map +0 -7
  67. package/dist/lib/node-esm/chunk-MMAOXKOM.mjs +0 -1420
  68. package/dist/lib/node-esm/chunk-MMAOXKOM.mjs.map +0 -7
  69. package/dist/lib/node-esm/testing/index.mjs +0 -32
  70. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  71. package/dist/types/src/components/Image/Image.d.ts +0 -11
  72. package/dist/types/src/components/Image/Image.d.ts.map +0 -1
  73. package/dist/types/src/components/Image/Image.stories.d.ts +0 -30
  74. package/dist/types/src/components/Image/Image.stories.d.ts.map +0 -1
  75. package/dist/types/src/components/Image/index.d.ts +0 -2
  76. package/dist/types/src/components/Image/index.d.ts.map +0 -1
  77. package/dist/types/src/components/defs.d.ts.map +0 -1
  78. package/dist/types/src/components/deprecated/LayoutControls.d.ts +0 -19
  79. package/dist/types/src/components/deprecated/LayoutControls.d.ts.map +0 -1
  80. package/dist/types/src/exemplars/Card/Card.d.ts +0 -65
  81. package/dist/types/src/exemplars/Card/Card.d.ts.map +0 -1
  82. package/dist/types/src/exemplars/Card/Card.stories.d.ts +0 -21
  83. package/dist/types/src/exemplars/Card/Card.stories.d.ts.map +0 -1
  84. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts +0 -6
  85. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts.map +0 -1
  86. package/dist/types/src/exemplars/Card/fragments.d.ts +0 -13
  87. package/dist/types/src/exemplars/Card/fragments.d.ts.map +0 -1
  88. package/dist/types/src/exemplars/Card/index.d.ts +0 -4
  89. package/dist/types/src/exemplars/Card/index.d.ts.map +0 -1
  90. package/dist/types/src/exemplars/CardStack/CardStack.d.ts +0 -42
  91. package/dist/types/src/exemplars/CardStack/CardStack.d.ts.map +0 -1
  92. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts +0 -15
  93. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts.map +0 -1
  94. package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts +0 -9
  95. package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts.map +0 -1
  96. package/dist/types/src/exemplars/CardStack/index.d.ts +0 -3
  97. package/dist/types/src/exemplars/CardStack/index.d.ts.map +0 -1
  98. package/dist/types/src/exemplars/index.d.ts +0 -3
  99. package/dist/types/src/exemplars/index.d.ts.map +0 -1
  100. package/dist/types/src/testing/CardContainer.d.ts +0 -6
  101. package/dist/types/src/testing/CardContainer.d.ts.map +0 -1
  102. package/dist/types/src/testing/index.d.ts +0 -2
  103. package/dist/types/src/testing/index.d.ts.map +0 -1
  104. package/src/components/Image/Image.stories.tsx +0 -56
  105. package/src/components/Image/Image.tsx +0 -137
  106. package/src/components/Image/index.ts +0 -5
  107. package/src/components/deprecated/LayoutControls.tsx +0 -109
  108. package/src/exemplars/Card/Card.stories.tsx +0 -64
  109. package/src/exemplars/Card/Card.tsx +0 -204
  110. package/src/exemplars/Card/CardDragPreview.tsx +0 -22
  111. package/src/exemplars/Card/fragments.ts +0 -24
  112. package/src/exemplars/Card/index.ts +0 -7
  113. package/src/exemplars/CardStack/CardStack.stories.tsx +0 -173
  114. package/src/exemplars/CardStack/CardStack.tsx +0 -139
  115. package/src/exemplars/CardStack/CardStackDragPreview.tsx +0 -61
  116. package/src/exemplars/CardStack/index.ts +0 -6
  117. package/src/exemplars/index.ts +0 -6
  118. package/src/testing/CardContainer.tsx +0 -37
  119. package/src/testing/index.ts +0 -5
  120. /package/src/components/{defs.ts → types.ts} +0 -0
@@ -2,15 +2,15 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
6
- import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
7
- import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
8
- import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
9
5
  import {
10
6
  type Edge,
11
7
  attachClosestEdge,
12
8
  extractClosestEdge,
13
9
  } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
10
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
11
+ import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
12
+ import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
13
+ import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
14
14
  import { useFocusableGroup } from '@fluentui/react-tabster';
15
15
  import { composeRefs } from '@radix-ui/react-compose-refs';
16
16
  import React, {
@@ -26,11 +26,10 @@ import { createPortal } from 'react-dom';
26
26
 
27
27
  import { ListItem, type ThemedClassName } from '@dxos/react-ui';
28
28
  import { resizeAttributes, sizeStyle } from '@dxos/react-ui-dnd';
29
- import { mx } from '@dxos/react-ui-theme';
29
+ import { mx } from '@dxos/ui-theme';
30
30
 
31
- import { type StackItemData, type StackItemSize } from '../defs';
32
31
  import { type ItemDragState, StackItemContext, idle, useStack, useStackItem } from '../StackContext';
33
-
32
+ import { type StackItemData, type StackItemSize } from '../types';
34
33
  import { StackItemContent, type StackItemContentProps } from './StackItemContent';
35
34
  import { StackItemDragHandle, type StackItemDragHandleProps } from './StackItemDragHandle';
36
35
  import {
@@ -49,19 +48,22 @@ import {
49
48
  type StackItemSigilProps,
50
49
  } from './StackItemSigil';
51
50
 
52
- // NOTE: 48rem fills the screen on a MacbookPro with the sidebars closed.
53
- export const DEFAULT_HORIZONTAL_SIZE = 48 satisfies StackItemSize;
54
51
  export const DEFAULT_VERTICAL_SIZE = 'min-content' satisfies StackItemSize;
52
+ export const DEFAULT_HORIZONTAL_SIZE = 50 satisfies StackItemSize;
55
53
  export const DEFAULT_EXTRINSIC_SIZE = DEFAULT_HORIZONTAL_SIZE satisfies StackItemSize;
56
54
 
55
+ //
56
+ // StackItemRoot
57
+ //
58
+
57
59
  type StackItemRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
60
+ role?: 'article' | 'section';
58
61
  item: Omit<StackItemData, 'type'>;
59
62
  order?: number;
60
63
  prevSiblingId?: string;
61
64
  nextSiblingId?: string;
62
65
  size?: StackItemSize;
63
66
  onSizeChange?: (nextSize: StackItemSize) => void;
64
- role?: 'article' | 'section';
65
67
  disableRearrange?: boolean;
66
68
  focusIndicatorVariant?: 'over-all' | 'group' | 'over-all-always' | 'group-always';
67
69
  };
@@ -69,16 +71,16 @@ type StackItemRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
69
71
  const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
70
72
  (
71
73
  {
72
- item,
73
- children,
74
74
  classNames,
75
- size: propsSize,
76
- onSizeChange,
75
+ children,
76
+ style,
77
77
  role,
78
+ item,
78
79
  order,
79
80
  prevSiblingId,
80
81
  nextSiblingId,
81
- style,
82
+ size: sizeProp,
83
+ onSizeChange,
82
84
  disableRearrange,
83
85
  focusIndicatorVariant = 'over-all',
84
86
  ...props
@@ -86,18 +88,17 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
86
88
  forwardedRef,
87
89
  ) => {
88
90
  const [itemElement, itemRef] = useState<HTMLDivElement | null>(null);
91
+ const composedItemRef = composeRefs<HTMLDivElement>(itemRef, forwardedRef);
89
92
  const [selfDragHandleElement, selfDragHandleRef] = useState<HTMLDivElement | null>(null);
90
93
  const [closestEdge, setEdge] = useState<Edge | null>(null);
91
94
  const [sourceId, setSourceId] = useState<string | null>(null);
92
95
  const [dragState, setDragState] = useState<ItemDragState>(idle);
93
96
  const { orientation, rail, onRearrange, size: stackSize, stackId } = useStack();
94
97
  const [size = orientation === 'horizontal' ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] =
95
- useState(propsSize);
98
+ useState(sizeProp);
96
99
 
97
100
  const Root = role ?? 'div';
98
101
 
99
- const composedItemRef = composeRefs<HTMLDivElement>(itemRef, forwardedRef);
100
-
101
102
  const setSize = useCallback(
102
103
  (nextSize: StackItemSize, commit?: boolean) => {
103
104
  setInternalSize(nextSize);
@@ -110,6 +111,7 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
110
111
 
111
112
  const type = orientation === 'horizontal' ? 'column' : 'card';
112
113
 
114
+ // TODO(burdon): Factor out?
113
115
  useLayoutEffect(() => {
114
116
  if (!itemElement || !onRearrange || disableRearrange) {
115
117
  return;
@@ -183,18 +185,18 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
183
185
 
184
186
  const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited' });
185
187
 
186
- // Determine if the drop would result in any changes
188
+ // Determine if the drop would result in any changes.
187
189
  const shouldShowDropIndicator = () => {
188
190
  if (!closestEdge || !sourceId) {
189
191
  return false;
190
192
  }
191
193
 
192
- // Don't show indicator when dragged item is over itself
194
+ // Don't show indicator when dragged item is over itself.
193
195
  if (sourceId === item.id) {
194
196
  return false;
195
197
  }
196
198
 
197
- // Don't show indicator when dragged item is over the trailing edge of its previous sibling
199
+ // Don't show indicator when dragged item is over the trailing edge of its previous sibling.
198
200
  const isTrailingEdgeOfPrevSibling =
199
201
  prevSiblingId !== undefined &&
200
202
  sourceId === prevSiblingId &&
@@ -243,7 +245,7 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
243
245
  : 'dx-focus-ring-group-y',
244
246
  orientation === 'horizontal' ? 'grid-rows-subgrid' : 'grid-cols-subgrid',
245
247
  rail && (orientation === 'horizontal' ? 'row-span-2' : 'col-span-2'),
246
- role === 'section' && orientation !== 'horizontal' && 'border-be border-subduedSeparator',
248
+ role === 'section' && orientation !== 'horizontal' && 'border-b border-subdued-separator',
247
249
  classNames,
248
250
  )}
249
251
  data-dx-stack-item={stackId}
@@ -268,37 +270,45 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
268
270
  },
269
271
  );
270
272
 
273
+ //
274
+ // StackItemDragPreview
275
+ //
276
+
271
277
  type StackItemDragPreviewProps = {
272
278
  children: ({ item }: { item: any }) => ReactNode;
273
279
  };
274
280
 
275
- export const StackItemDragPreview = ({ children }: StackItemDragPreviewProps) => {
281
+ const StackItemDragPreview = ({ children }: StackItemDragPreviewProps) => {
276
282
  const { state } = useStackItem();
277
283
  return state?.type === 'preview' ? createPortal(children({ item: state.item }), state.container) : null;
278
284
  };
279
285
 
286
+ //
287
+ // StackItem
288
+ //
289
+
280
290
  export const StackItem = {
281
291
  Root: StackItemRoot,
282
292
  Content: StackItemContent,
293
+ DragHandle: StackItemDragHandle,
294
+ DragPreview: StackItemDragPreview,
283
295
  Heading: StackItemHeading,
284
296
  HeadingLabel: StackItemHeadingLabel,
285
297
  HeadingStickyContent: StackItemHeadingStickyContent,
286
298
  ResizeHandle: StackItemResizeHandle,
287
- DragHandle: StackItemDragHandle,
288
299
  Sigil: StackItemSigil,
289
300
  SigilButton: StackItemSigilButton,
290
- DragPreview: StackItemDragPreview,
291
301
  };
292
302
 
293
303
  export type {
294
304
  StackItemRootProps,
295
305
  StackItemContentProps,
306
+ StackItemDragHandleProps,
307
+ StackItemDragPreviewProps,
296
308
  StackItemHeadingProps,
297
309
  StackItemHeadingLabelProps,
298
310
  StackItemResizeHandleProps,
299
- StackItemDragHandleProps,
300
311
  StackItemSigilProps,
301
312
  StackItemSigilButtonProps,
302
313
  StackItemSigilAction,
303
- StackItemDragPreviewProps,
304
314
  };
@@ -5,82 +5,49 @@
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
- // TODO(burdon): Add prop for container-max-width?
13
12
  export type StackItemContentProps = ThemedClassName<Omit<ComponentPropsWithoutRef<'div'>, 'role' | 'scrollable'>> & {
14
- /**
15
- * This flag is required in order to clarify a developer experience that seemed like it needed extra boilerplate
16
- * (`row-span-2`) or was buggy. See the description of the StackItem.Content component itself for more information.
17
- */
18
13
  toolbar?: boolean;
19
-
20
- /**
21
- * Whether to provide for the layout of a statusbar after the content.
22
- */
23
14
  statusbar?: boolean;
24
-
25
- /**
26
- * Whether to support y-axis scrolling.
27
- */
28
- scrollable?: boolean;
29
-
30
- /**
31
- * Whether the consumer intends to do something custom and typical affordances should not apply.
32
- */
33
- // TODO(burdon): This is cryptic; can we remove (only used by plugin-inbox?) Normalize toolbar?
34
- layoutManaged?: boolean;
35
-
36
- /**
37
- * Whether to set a certain aspect ratio on the content, including the toolbar and statusbar.
38
- * This is provided for convenience and consistency; it can instead be specified by the `classNames` or `style` props as needed.
39
- */
40
- size?: 'intrinsic' | 'video' | 'square';
41
15
  };
42
16
 
43
17
  /**
44
- * This component should be used by plugins for rendering content within a stack item, a.k.a. a “plank” or “section”.
45
- * 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”).
46
19
  */
47
20
  export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps>(
48
- (
49
- { children, toolbar, statusbar, layoutManaged, classNames, size = 'intrinsic', scrollable, ...props },
50
- forwardedRef,
51
- ) => {
21
+ ({ classNames, children, toolbar, statusbar, ...props }, forwardedRef) => {
52
22
  const { size: stackItemSize } = useStack();
53
23
  const { role } = useStackItem();
54
24
  const style = useMemo(
55
- () =>
56
- layoutManaged
57
- ? {}
58
- : {
59
- gridTemplateRows: [
60
- ...(toolbar ? [role === 'section' ? 'calc(var(--toolbar-size) - 1px)' : 'var(--toolbar-size)'] : []),
61
- '1fr',
62
- ...(statusbar ? ['var(--statusbar-size)'] : []),
63
- ].join(' '),
64
- },
65
- [toolbar, statusbar, layoutManaged],
25
+ () => ({
26
+ gridTemplateRows: [
27
+ toolbar && role === 'section' ? 'calc(var(--dx-toolbar-size) - 1px)' : 'var(--dx-toolbar-size)',
28
+ '1fr',
29
+ statusbar && 'var(--dx-statusbar-size)',
30
+ ]
31
+ .filter(Boolean)
32
+ .join(' '),
33
+ }),
34
+ [toolbar, statusbar],
66
35
  );
67
36
 
68
37
  return (
69
38
  <div
70
- role='none'
71
39
  {...props}
40
+ role='none'
41
+ style={style}
72
42
  className={mx(
73
- 'group grid grid-cols-[100%] density-coarse',
74
- stackItemSize === 'contain' && 'min-bs-0 overflow-hidden',
75
- size === 'video' ? 'aspect-video' : size === 'square' && 'aspect-square',
76
- toolbar && '[&>.dx-toolbar]:relative [&>.dx-toolbar]:border-be [&>.dx-toolbar]:border-subduedSeparator',
77
- scrollable ? 'min-bs-0 overflow-y-auto scrollbar-thin contain-layout' : 'overflow-hidden',
78
- role === 'section' &&
79
- toolbar &&
80
- '[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:block-start-0 [&_.dx-toolbar]:-mbe-px [&_.dx-toolbar]:min-is-0',
43
+ 'group grid grid-cols-[100%] dx-density-coarse',
44
+ stackItemSize === 'contain' && 'min-h-0 overflow-hidden',
45
+ toolbar &&
46
+ role === 'section' &&
47
+ '[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:top-0 [&_.dx-toolbar]:-mb-px [&_.dx-toolbar]:min-w-0',
48
+ toolbar && '[&>.dx-toolbar]:relative [&>.dx-toolbar]:border-b [&>.dx-toolbar]:border-subdued-separator',
81
49
  classNames,
82
50
  )}
83
- style={style}
84
51
  data-popover-collision-boundary={true}
85
52
  ref={forwardedRef}
86
53
  >
@@ -89,3 +56,5 @@ export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps
89
56
  );
90
57
  },
91
58
  );
59
+
60
+ StackItemContent.displayName = 'StackItemContent';
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { Primitive } from '@radix-ui/react-primitive';
5
6
  import { Slot } from '@radix-ui/react-slot';
6
7
  import React, { type ComponentPropsWithoutRef } from 'react';
7
8
 
@@ -12,11 +13,11 @@ export type StackItemDragHandleProps = ComponentPropsWithoutRef<'button'> & { as
12
13
  export const StackItemDragHandle = ({ asChild, children }: StackItemDragHandleProps) => {
13
14
  const { selfDragHandleRef } = useStackItem();
14
15
 
15
- const Root = asChild ? Slot : 'div';
16
+ const Comp = asChild ? Slot : Primitive.div;
16
17
 
17
18
  return (
18
- <Root ref={selfDragHandleRef} role='button'>
19
+ <Comp ref={selfDragHandleRef} role='button'>
19
20
  {children}
20
- </Root>
21
+ </Comp>
21
22
  );
22
23
  };
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { Primitive } from '@radix-ui/react-primitive';
5
6
  import { Slot } from '@radix-ui/react-slot';
6
7
  import React, {
7
8
  type ComponentPropsWithRef,
@@ -12,7 +13,7 @@ import React, {
12
13
 
13
14
  import { type ThemedClassName } from '@dxos/react-ui';
14
15
  import { type AttendableId, type Related, useAttention } from '@dxos/react-ui-attention';
15
- import { mx } from '@dxos/react-ui-theme';
16
+ import { mx } from '@dxos/ui-theme';
16
17
 
17
18
  import { useStack } from '../StackContext';
18
19
 
@@ -26,34 +27,34 @@ export const StackItemHeading = ({
26
27
  classNames,
27
28
  asChild,
28
29
  separateOnScroll,
30
+ role,
29
31
  ...props
30
32
  }: StackItemHeadingProps) => {
31
33
  const { orientation } = useStack();
32
-
33
- const Root = asChild ? Slot : 'div';
34
+ const Comp = asChild ? Slot : Primitive.div;
34
35
 
35
36
  return (
36
- <Root
37
- role='heading'
37
+ <Comp
38
38
  {...props}
39
+ role={role ?? 'heading'}
39
40
  className={mx(
40
- 'flex items-center !border-is-0 bg-headerSurface',
41
+ 'flex items-center border-x-0! bg-header-surface',
41
42
  separateOnScroll
42
- ? 'border-transparent [[data-scroll-separator="true"]_&]:border-subduedSeparator'
43
- : 'border-subduedSeparator',
44
- orientation === 'horizontal' ? 'bs-[--rail-size]' : 'is-[--rail-size] flex-col',
45
- orientation === 'horizontal' ? 'border-be' : 'border-ie',
43
+ ? 'border-transparent [[data-scroll-separator="true"]_&]:border-subdued-separator'
44
+ : 'border-subdued-separator',
45
+ orientation === 'horizontal' ? 'h-(--dx-rail-size)' : 'w-(--dx-rail-size) flex-col',
46
+ orientation === 'horizontal' ? 'border-b' : 'border-e',
46
47
  classNames,
47
48
  )}
48
49
  >
49
50
  {children}
50
- </Root>
51
+ </Comp>
51
52
  );
52
53
  };
53
54
 
54
55
  export const StackItemHeadingStickyContent = ({ children }: PropsWithChildren<{}>) => {
55
56
  return (
56
- <div role='none' className='sticky block-start-0 bg-[--sticky-bg] p-1 is-full'>
57
+ <div role='none' className='sticky top-0 bg-(--sticky-bg) p-1 w-full'>
57
58
  {children}
58
59
  </div>
59
60
  );
@@ -70,7 +71,7 @@ export const StackItemHeadingLabel = forwardRef<HTMLHeadingElement, StackItemHea
70
71
  {...props}
71
72
  data-attention={((related && isRelated) || hasAttention || isAncestor).toString()}
72
73
  className={mx(
73
- 'pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center',
74
+ 'px-1 min-w-0 w-0 grow truncate font-medium text-base-surface-text data-[attention=true]:text-accent-text self-center',
74
75
  classNames,
75
76
  )}
76
77
  ref={forwardedRef}
@@ -7,7 +7,6 @@ import React from 'react';
7
7
  import { ResizeHandle } from '@dxos/react-ui-dnd';
8
8
 
9
9
  import { useStack, useStackItem } from '../StackContext';
10
-
11
10
  import { DEFAULT_EXTRINSIC_SIZE } from './StackItem';
12
11
 
13
12
  const MIN_WIDTH = 20;
@@ -15,7 +14,7 @@ const MIN_HEIGHT = 3;
15
14
 
16
15
  export type StackItemResizeHandleProps = {};
17
16
 
18
- export const StackItemResizeHandle = () => {
17
+ export const StackItemResizeHandle = (_: StackItemResizeHandleProps) => {
19
18
  const { orientation } = useStack();
20
19
  const { setSize, size } = useStackItem();
21
20
 
@@ -4,14 +4,14 @@
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 { mx } from '@dxos/ui-theme';
12
12
  import { getHostPlatform } from '@dxos/util';
13
13
 
14
- import { translationKey } from '../../translations';
14
+ import { translationKey } from '#translations';
15
15
 
16
16
  import { MenuSignifierHorizontal } from './MenuSignifier';
17
17
 
@@ -23,7 +23,7 @@ export type KeyBinding = {
23
23
  unknown?: string;
24
24
  };
25
25
 
26
- export type StackItemSigilAction = Pick<ActionLike, 'id' | 'properties' | 'data'>;
26
+ export type StackItemSigilAction = Pick<Node.ActionLike, 'id' | 'properties' | 'data'>;
27
27
 
28
28
  export type StackItemSigilButtonProps = Omit<ButtonProps, 'variant'> &
29
29
  AttendableId &
@@ -40,7 +40,10 @@ export const StackItemSigilButton = forwardRef<HTMLButtonElement, StackItemSigil
40
40
  <Button
41
41
  {...props}
42
42
  variant={variant}
43
- classNames={['shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag', classNames]}
43
+ classNames={[
44
+ 'shrink-0 px-0 min-h-0 w-(--dx-rail-action) h-(--dx-rail-action) relative dx-app-no-drag',
45
+ classNames,
46
+ ]}
44
47
  ref={forwardedRef}
45
48
  >
46
49
  {isMenu && <MenuSignifierHorizontal />}
@@ -78,7 +81,7 @@ export const StackItemSigil = forwardRef<HTMLButtonElement, StackItemSigilProps>
78
81
  classNames={!hasActions && 'cursor-default'}
79
82
  >
80
83
  <span className='sr-only'>{triggerLabel}</span>
81
- <Icon icon={icon} size={5} />
84
+ <Icon icon={icon} />
82
85
  </StackItemSigilButton>
83
86
  );
84
87
 
@@ -133,7 +136,7 @@ export const StackItemSigil = forwardRef<HTMLButtonElement, StackItemSigilProps>
133
136
  </DropdownMenu.ItemIndicator>
134
137
  )}
135
138
  {shortcut && (
136
- <span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>
139
+ <span className={mx('shrink-0', 'text-description')}>{keySymbols(shortcut).join('')}</span>
137
140
  )}
138
141
  </Root>
139
142
  );
@@ -2,8 +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 './Image';
8
7
  export * from './Stack';
8
+
9
9
  export * from './StackItem';
@@ -2,76 +2,90 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
6
- import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
7
5
  import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
8
6
  import { attachClosestEdge, extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
7
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
8
+ import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
9
9
  import { useLayoutEffect, useState } from 'react';
10
10
 
11
11
  import { type Orientation, type StackItemData, type StackItemRearrangeHandler } from '../components';
12
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
+ };
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,4 @@
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
- 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: 'pnpm storybook dev --ci --quiet --port=9003 --config-dir=.storybook',
14
14
  port: 9003,
15
15
  reuseExistingServer: false,
16
16
  },