@dxos/react-ui-stack 0.8.4-main.dedc0f3 → 0.8.4-main.dfabb4ec29
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.
- package/dist/lib/browser/index.mjs +704 -67
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/playwright/index.mjs +10 -23
- package/dist/lib/browser/playwright/index.mjs.map +2 -2
- package/dist/lib/browser/translations.mjs +23 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +705 -67
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/playwright/index.mjs +10 -23
- package/dist/lib/node-esm/playwright/index.mjs.map +2 -2
- package/dist/lib/node-esm/translations.mjs +25 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/Stack/Stack.d.ts +5 -9
- package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
- package/dist/types/src/components/Stack/Stack.stories.d.ts +1 -2
- package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
- package/dist/types/src/components/StackContext.d.ts +1 -1
- package/dist/types/src/components/StackContext.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/MenuSignifier.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItem.d.ts +12 -15
- package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItem.stories.d.ts +0 -1
- package/dist/types/src/components/StackItem/StackItem.stories.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemContent.d.ts +4 -37
- package/dist/types/src/components/StackItem/StackItemContent.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemDragHandle.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemHeading.d.ts +1 -1
- package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts +1 -1
- package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemSigil.d.ts +2 -2
- package/dist/types/src/components/StackItem/StackItemSigil.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/{defs.d.ts → types.d.ts} +1 -1
- package/dist/types/src/components/types.d.ts.map +1 -0
- package/dist/types/src/hooks/useStackDropForElements.d.ts +8 -6
- package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
- package/dist/types/src/playwright/stack-manager.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +10 -10
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +49 -47
- package/src/components/Stack/Stack.stories.tsx +10 -14
- package/src/components/Stack/Stack.tsx +216 -172
- package/src/components/StackContext.tsx +1 -1
- package/src/components/StackItem/MenuSignifier.tsx +2 -9
- package/src/components/StackItem/StackItem.stories.tsx +8 -8
- package/src/components/StackItem/StackItem.tsx +48 -31
- package/src/components/StackItem/StackItemContent.tsx +23 -44
- package/src/components/StackItem/StackItemDragHandle.tsx +4 -3
- package/src/components/StackItem/StackItemHeading.tsx +14 -21
- package/src/components/StackItem/StackItemResizeHandle.tsx +1 -2
- package/src/components/StackItem/StackItemSigil.tsx +10 -7
- package/src/components/index.ts +2 -2
- package/src/hooks/useStackDropForElements.ts +60 -46
- package/src/index.ts +0 -4
- package/src/playwright/playwright.config.ts +1 -1
- package/src/translations.ts +9 -9
- package/dist/lib/browser/chunk-3V2YUQK5.mjs +0 -1375
- package/dist/lib/browser/chunk-3V2YUQK5.mjs.map +0 -7
- package/dist/lib/browser/testing/index.mjs +0 -31
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HE3BRF7A.mjs +0 -1377
- package/dist/lib/node-esm/chunk-HE3BRF7A.mjs.map +0 -7
- package/dist/lib/node-esm/testing/index.mjs +0 -32
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/components/Image/Image.d.ts +0 -11
- package/dist/types/src/components/Image/Image.d.ts.map +0 -1
- package/dist/types/src/components/Image/Image.stories.d.ts +0 -31
- package/dist/types/src/components/Image/Image.stories.d.ts.map +0 -1
- package/dist/types/src/components/Image/index.d.ts +0 -2
- package/dist/types/src/components/Image/index.d.ts.map +0 -1
- package/dist/types/src/components/defs.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/LayoutControls.d.ts +0 -19
- package/dist/types/src/components/deprecated/LayoutControls.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/Card.d.ts +0 -58
- package/dist/types/src/exemplars/Card/Card.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/Card.stories.d.ts +0 -44
- package/dist/types/src/exemplars/Card/Card.stories.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/CardDragPreview.d.ts +0 -6
- package/dist/types/src/exemplars/Card/CardDragPreview.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/fragments.d.ts +0 -13
- package/dist/types/src/exemplars/Card/fragments.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/index.d.ts +0 -4
- package/dist/types/src/exemplars/Card/index.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/CardStack.d.ts +0 -40
- package/dist/types/src/exemplars/CardStack/CardStack.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts +0 -13
- package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts +0 -9
- package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/index.d.ts +0 -3
- package/dist/types/src/exemplars/CardStack/index.d.ts.map +0 -1
- package/dist/types/src/exemplars/index.d.ts +0 -3
- package/dist/types/src/exemplars/index.d.ts.map +0 -1
- package/dist/types/src/testing/CardContainer.d.ts +0 -6
- package/dist/types/src/testing/CardContainer.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts +0 -2
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/src/components/Image/Image.stories.tsx +0 -58
- package/src/components/Image/Image.tsx +0 -137
- package/src/components/Image/index.ts +0 -5
- package/src/components/deprecated/LayoutControls.tsx +0 -109
- package/src/exemplars/Card/Card.stories.tsx +0 -88
- package/src/exemplars/Card/Card.tsx +0 -186
- package/src/exemplars/Card/CardDragPreview.tsx +0 -22
- package/src/exemplars/Card/fragments.ts +0 -24
- package/src/exemplars/Card/index.ts +0 -7
- package/src/exemplars/CardStack/CardStack.stories.tsx +0 -172
- package/src/exemplars/CardStack/CardStack.tsx +0 -136
- package/src/exemplars/CardStack/CardStackDragPreview.tsx +0 -61
- package/src/exemplars/CardStack/index.ts +0 -6
- package/src/exemplars/index.ts +0 -6
- package/src/testing/CardContainer.tsx +0 -37
- package/src/testing/index.ts +0 -5
- /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/
|
|
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,36 +48,39 @@ 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
|
-
focusIndicatorVariant?: 'over-all' | 'group';
|
|
68
|
+
focusIndicatorVariant?: 'over-all' | 'group' | 'over-all-always' | 'group-always';
|
|
67
69
|
};
|
|
68
70
|
|
|
69
71
|
const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
70
72
|
(
|
|
71
73
|
{
|
|
72
|
-
item,
|
|
73
|
-
children,
|
|
74
74
|
classNames,
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
children,
|
|
76
|
+
style,
|
|
77
77
|
role,
|
|
78
|
+
item,
|
|
78
79
|
order,
|
|
79
80
|
prevSiblingId,
|
|
80
81
|
nextSiblingId,
|
|
81
|
-
|
|
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(
|
|
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 &&
|
|
@@ -232,15 +234,22 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
232
234
|
'group/stack-item grid relative',
|
|
233
235
|
focusIndicatorVariant === 'over-all'
|
|
234
236
|
? 'dx-focus-ring-inset-over-all'
|
|
235
|
-
:
|
|
236
|
-
? 'dx-focus-ring-
|
|
237
|
-
: '
|
|
237
|
+
: focusIndicatorVariant === 'over-all-always'
|
|
238
|
+
? 'dx-focus-ring-inset-over-all-always'
|
|
239
|
+
: orientation === 'horizontal'
|
|
240
|
+
? focusIndicatorVariant === 'group-always'
|
|
241
|
+
? 'dx-focus-ring-group-x-always'
|
|
242
|
+
: 'dx-focus-ring-group-x'
|
|
243
|
+
: focusIndicatorVariant === 'group-always'
|
|
244
|
+
? 'dx-focus-ring-group-y-always'
|
|
245
|
+
: 'dx-focus-ring-group-y',
|
|
238
246
|
orientation === 'horizontal' ? 'grid-rows-subgrid' : 'grid-cols-subgrid',
|
|
239
247
|
rail && (orientation === 'horizontal' ? 'row-span-2' : 'col-span-2'),
|
|
240
|
-
role === 'section' && orientation !== 'horizontal' && 'border-
|
|
248
|
+
role === 'section' && orientation !== 'horizontal' && 'border-b border-subdued-separator',
|
|
241
249
|
classNames,
|
|
242
250
|
)}
|
|
243
251
|
data-dx-stack-item={stackId}
|
|
252
|
+
data-dx-item-id={item.id}
|
|
244
253
|
{...resizeAttributes}
|
|
245
254
|
style={{
|
|
246
255
|
...(stackSize !== 'split' && sizeStyle(size, orientation)),
|
|
@@ -261,37 +270,45 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
261
270
|
},
|
|
262
271
|
);
|
|
263
272
|
|
|
273
|
+
//
|
|
274
|
+
// StackItemDragPreview
|
|
275
|
+
//
|
|
276
|
+
|
|
264
277
|
type StackItemDragPreviewProps = {
|
|
265
278
|
children: ({ item }: { item: any }) => ReactNode;
|
|
266
279
|
};
|
|
267
280
|
|
|
268
|
-
|
|
281
|
+
const StackItemDragPreview = ({ children }: StackItemDragPreviewProps) => {
|
|
269
282
|
const { state } = useStackItem();
|
|
270
283
|
return state?.type === 'preview' ? createPortal(children({ item: state.item }), state.container) : null;
|
|
271
284
|
};
|
|
272
285
|
|
|
286
|
+
//
|
|
287
|
+
// StackItem
|
|
288
|
+
//
|
|
289
|
+
|
|
273
290
|
export const StackItem = {
|
|
274
291
|
Root: StackItemRoot,
|
|
275
292
|
Content: StackItemContent,
|
|
293
|
+
DragHandle: StackItemDragHandle,
|
|
294
|
+
DragPreview: StackItemDragPreview,
|
|
276
295
|
Heading: StackItemHeading,
|
|
277
296
|
HeadingLabel: StackItemHeadingLabel,
|
|
278
297
|
HeadingStickyContent: StackItemHeadingStickyContent,
|
|
279
298
|
ResizeHandle: StackItemResizeHandle,
|
|
280
|
-
DragHandle: StackItemDragHandle,
|
|
281
299
|
Sigil: StackItemSigil,
|
|
282
300
|
SigilButton: StackItemSigilButton,
|
|
283
|
-
DragPreview: StackItemDragPreview,
|
|
284
301
|
};
|
|
285
302
|
|
|
286
303
|
export type {
|
|
287
304
|
StackItemRootProps,
|
|
288
305
|
StackItemContentProps,
|
|
306
|
+
StackItemDragHandleProps,
|
|
307
|
+
StackItemDragPreviewProps,
|
|
289
308
|
StackItemHeadingProps,
|
|
290
309
|
StackItemHeadingLabelProps,
|
|
291
310
|
StackItemResizeHandleProps,
|
|
292
|
-
StackItemDragHandleProps,
|
|
293
311
|
StackItemSigilProps,
|
|
294
312
|
StackItemSigilButtonProps,
|
|
295
313
|
StackItemSigilAction,
|
|
296
|
-
StackItemDragPreviewProps,
|
|
297
314
|
};
|
|
@@ -5,71 +5,48 @@
|
|
|
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/
|
|
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
|
|
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,
|
|
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
|
-
|
|
47
|
-
?
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
[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],
|
|
56
35
|
);
|
|
57
36
|
|
|
58
37
|
return (
|
|
59
38
|
<div
|
|
60
|
-
role='none'
|
|
61
39
|
{...props}
|
|
40
|
+
style={style}
|
|
62
41
|
className={mx(
|
|
63
|
-
'group grid grid-cols-[100%] density-coarse',
|
|
64
|
-
stackItemSize === 'contain' && 'min-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
'[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:block-start-0 [&_.dx-toolbar]:-mbe-px [&_.dx-toolbar]:min-is-0',
|
|
42
|
+
'group grid grid-cols-[100%] dx-density-coarse',
|
|
43
|
+
stackItemSize === 'contain' && 'min-h-0 overflow-hidden',
|
|
44
|
+
toolbar &&
|
|
45
|
+
role === 'section' &&
|
|
46
|
+
'[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:top-0 [&_.dx-toolbar]:-mb-px [&_.dx-toolbar]:min-w-0',
|
|
47
|
+
toolbar && '[&>.dx-toolbar]:relative [&>.dx-toolbar]:border-b [&>.dx-toolbar]:border-subdued-separator',
|
|
70
48
|
classNames,
|
|
71
49
|
)}
|
|
72
|
-
style={style}
|
|
73
50
|
data-popover-collision-boundary={true}
|
|
74
51
|
ref={forwardedRef}
|
|
75
52
|
>
|
|
@@ -78,3 +55,5 @@ export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps
|
|
|
78
55
|
);
|
|
79
56
|
},
|
|
80
57
|
);
|
|
58
|
+
|
|
59
|
+
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
|
|
16
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
16
17
|
|
|
17
18
|
return (
|
|
18
|
-
<
|
|
19
|
+
<Comp ref={selfDragHandleRef} role='button'>
|
|
19
20
|
{children}
|
|
20
|
-
</
|
|
21
|
+
</Comp>
|
|
21
22
|
);
|
|
22
23
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Primitive } from '@radix-ui/react-primitive';
|
|
6
6
|
import { Slot } from '@radix-ui/react-slot';
|
|
7
7
|
import React, {
|
|
8
8
|
type ComponentPropsWithRef,
|
|
@@ -13,7 +13,7 @@ import React, {
|
|
|
13
13
|
|
|
14
14
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
15
15
|
import { type AttendableId, type Related, useAttention } from '@dxos/react-ui-attention';
|
|
16
|
-
import { mx } from '@dxos/
|
|
16
|
+
import { mx } from '@dxos/ui-theme';
|
|
17
17
|
|
|
18
18
|
import { useStack } from '../StackContext';
|
|
19
19
|
|
|
@@ -27,40 +27,33 @@ export const StackItemHeading = ({
|
|
|
27
27
|
classNames,
|
|
28
28
|
asChild,
|
|
29
29
|
separateOnScroll,
|
|
30
|
+
role,
|
|
30
31
|
...props
|
|
31
32
|
}: StackItemHeadingProps) => {
|
|
32
33
|
const { orientation } = useStack();
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
const Root = asChild ? Slot : 'div';
|
|
34
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
36
35
|
|
|
37
36
|
return (
|
|
38
|
-
<
|
|
39
|
-
role='heading'
|
|
37
|
+
<Comp
|
|
40
38
|
{...props}
|
|
41
|
-
|
|
42
|
-
{...focusableGroupAttrs}
|
|
39
|
+
role={role ?? 'heading'}
|
|
43
40
|
className={mx(
|
|
44
|
-
'flex items-center
|
|
41
|
+
'flex items-center border-x-0! bg-header-surface',
|
|
45
42
|
separateOnScroll
|
|
46
|
-
? 'border-transparent [[data-scroll-separator="true"]_&]:border-
|
|
47
|
-
: 'border-
|
|
48
|
-
orientation === 'horizontal' ? '
|
|
49
|
-
orientation === 'horizontal' ? 'border-
|
|
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',
|
|
50
47
|
classNames,
|
|
51
48
|
)}
|
|
52
49
|
>
|
|
53
50
|
{children}
|
|
54
|
-
</
|
|
51
|
+
</Comp>
|
|
55
52
|
);
|
|
56
53
|
};
|
|
57
54
|
|
|
58
55
|
export const StackItemHeadingStickyContent = ({ children }: PropsWithChildren<{}>) => {
|
|
59
|
-
return (
|
|
60
|
-
<div role='none' className='sticky block-start-0 bg-[--sticky-bg] p-1 is-full'>
|
|
61
|
-
{children}
|
|
62
|
-
</div>
|
|
63
|
-
);
|
|
56
|
+
return <div className='sticky top-0 bg-(--sticky-bg) p-1 w-full'>{children}</div>;
|
|
64
57
|
};
|
|
65
58
|
|
|
66
59
|
export type StackItemHeadingLabelProps = ThemedClassName<ComponentPropsWithRef<'h1'>> & AttendableId & Related;
|
|
@@ -74,7 +67,7 @@ export const StackItemHeadingLabel = forwardRef<HTMLHeadingElement, StackItemHea
|
|
|
74
67
|
{...props}
|
|
75
68
|
data-attention={((related && isRelated) || hasAttention || isAncestor).toString()}
|
|
76
69
|
className={mx(
|
|
77
|
-
'
|
|
70
|
+
'px-1 min-w-0 w-0 grow truncate font-medium text-base-surface-text data-[attention=true]:text-accent-text self-center',
|
|
78
71
|
classNames,
|
|
79
72
|
)}
|
|
80
73
|
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
|
|
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 {
|
|
11
|
+
import { mx } from '@dxos/ui-theme';
|
|
12
12
|
import { getHostPlatform } from '@dxos/util';
|
|
13
13
|
|
|
14
|
-
import { translationKey } from '
|
|
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={[
|
|
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}
|
|
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',
|
|
139
|
+
<span className={mx('shrink-0', 'text-description')}>{keySymbols(shortcut).join('')}</span>
|
|
137
140
|
)}
|
|
138
141
|
</Root>
|
|
139
142
|
);
|
package/src/components/index.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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,
|
|
88
|
+
}, [id, element, scrollElement, selfDroppable, orientation, onRearrange]);
|
|
75
89
|
|
|
76
90
|
return { dropping };
|
|
77
91
|
};
|
package/src/index.ts
CHANGED
|
@@ -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: '
|
|
13
|
+
command: 'pnpm storybook dev --ci --quiet --port=9003 --config-dir=.storybook',
|
|
14
14
|
port: 9003,
|
|
15
15
|
reuseExistingServer: false,
|
|
16
16
|
},
|