@dxos/react-ui-stack 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.
- package/dist/lib/browser/index.mjs +166 -94
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +178 -105
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +166 -94
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/LayoutControls.d.ts.map +1 -1
- package/dist/types/src/components/Stack.d.ts.map +1 -1
- package/dist/types/src/components/Stack.stories.d.ts.map +1 -1
- package/dist/types/src/components/StackContext.d.ts +9 -4
- package/dist/types/src/components/StackContext.d.ts.map +1 -1
- package/dist/types/src/components/StackItem.d.ts +5 -8
- package/dist/types/src/components/StackItem.d.ts.map +1 -1
- package/dist/types/src/components/StackItemContent.d.ts.map +1 -1
- package/dist/types/src/components/StackItemDragHandle.d.ts +6 -0
- package/dist/types/src/components/StackItemDragHandle.d.ts.map +1 -0
- package/dist/types/src/components/StackItemHeading.d.ts.map +1 -1
- package/dist/types/src/components/StackItemResizeHandle.d.ts +1 -0
- package/dist/types/src/components/StackItemResizeHandle.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +21 -20
- package/src/components/LayoutControls.tsx +1 -3
- package/src/components/Stack.stories.tsx +5 -4
- package/src/components/Stack.tsx +56 -8
- package/src/components/StackContext.tsx +13 -4
- package/src/components/StackItem.tsx +18 -17
- package/src/components/StackItemContent.tsx +2 -7
- package/src/components/StackItemDragHandle.tsx +22 -0
- package/src/components/StackItemHeading.tsx +1 -3
- package/src/components/StackItemResizeHandle.tsx +7 -6
- package/src/components/StackItemSigil.tsx +1 -1
- package/src/components/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-stack",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5-main.937ce75",
|
|
4
4
|
"description": "A stack component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -43,14 +43,15 @@
|
|
|
43
43
|
"@radix-ui/react-compose-refs": "^1.0.0",
|
|
44
44
|
"@radix-ui/react-context": "^1.0.0",
|
|
45
45
|
"@radix-ui/react-menu": "^2.0.6",
|
|
46
|
+
"@radix-ui/react-slot": "^1.0.1",
|
|
46
47
|
"@radix-ui/react-use-controllable-state": "^1.0.0",
|
|
47
48
|
"react-resize-detector": "^11.0.1",
|
|
48
|
-
"@dxos/echo-schema": "0.7.
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/live-object": "0.7.
|
|
51
|
-
"@dxos/react-ui-
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
49
|
+
"@dxos/echo-schema": "0.7.5-main.937ce75",
|
|
50
|
+
"@dxos/keyboard": "0.7.5-main.937ce75",
|
|
51
|
+
"@dxos/live-object": "0.7.5-main.937ce75",
|
|
52
|
+
"@dxos/react-ui-attention": "0.7.5-main.937ce75",
|
|
53
|
+
"@dxos/react-ui-mosaic": "0.7.5-main.937ce75",
|
|
54
|
+
"@dxos/util": "0.7.5-main.937ce75"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
57
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -59,24 +60,24 @@
|
|
|
59
60
|
"react": "~18.2.0",
|
|
60
61
|
"react-dom": "~18.2.0",
|
|
61
62
|
"vite": "5.4.7",
|
|
62
|
-
"@dxos/app-graph": "0.7.
|
|
63
|
-
"@dxos/client": "0.7.
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/react-ui-
|
|
68
|
-
"@dxos/react-ui-
|
|
69
|
-
"@dxos/storybook-utils": "0.7.
|
|
70
|
-
"@dxos/test-utils": "0.7.
|
|
63
|
+
"@dxos/app-graph": "0.7.5-main.937ce75",
|
|
64
|
+
"@dxos/client": "0.7.5-main.937ce75",
|
|
65
|
+
"@dxos/react-ui": "0.7.5-main.937ce75",
|
|
66
|
+
"@dxos/random": "0.7.5-main.937ce75",
|
|
67
|
+
"@dxos/echo-schema": "0.7.5-main.937ce75",
|
|
68
|
+
"@dxos/react-ui-editor": "0.7.5-main.937ce75",
|
|
69
|
+
"@dxos/react-ui-theme": "0.7.5-main.937ce75",
|
|
70
|
+
"@dxos/storybook-utils": "0.7.5-main.937ce75",
|
|
71
|
+
"@dxos/test-utils": "0.7.5-main.937ce75"
|
|
71
72
|
},
|
|
72
73
|
"peerDependencies": {
|
|
73
74
|
"@phosphor-icons/react": "^2.1.5",
|
|
74
75
|
"react": "~18.2.0",
|
|
75
76
|
"react-dom": "~18.2.0",
|
|
76
|
-
"@dxos/client": "0.7.
|
|
77
|
-
"@dxos/random": "0.7.
|
|
78
|
-
"@dxos/react-ui": "0.7.
|
|
79
|
-
"@dxos/react-ui-theme": "0.7.
|
|
77
|
+
"@dxos/client": "0.7.5-main.937ce75",
|
|
78
|
+
"@dxos/random": "0.7.5-main.937ce75",
|
|
79
|
+
"@dxos/react-ui": "0.7.5-main.937ce75",
|
|
80
|
+
"@dxos/react-ui-theme": "0.7.5-main.937ce75"
|
|
80
81
|
},
|
|
81
82
|
"publishConfig": {
|
|
82
83
|
"access": "public"
|
|
@@ -44,9 +44,7 @@ const LayoutControl = ({ icon, label, ...props }: Omit<ButtonProps, 'children'>
|
|
|
44
44
|
</Button>
|
|
45
45
|
</Tooltip.Trigger>
|
|
46
46
|
<Tooltip.Portal>
|
|
47
|
-
<Tooltip.Content side='bottom'
|
|
48
|
-
{label}
|
|
49
|
-
</Tooltip.Content>
|
|
47
|
+
<Tooltip.Content side='bottom'>{label}</Tooltip.Content>
|
|
50
48
|
</Tooltip.Portal>
|
|
51
49
|
</Tooltip.Root>
|
|
52
50
|
);
|
|
@@ -10,7 +10,8 @@ import { faker } from '@dxos/random';
|
|
|
10
10
|
import { withTheme } from '@dxos/storybook-utils';
|
|
11
11
|
|
|
12
12
|
import { Stack } from './Stack';
|
|
13
|
-
import {
|
|
13
|
+
import { type StackItemData } from './StackContext';
|
|
14
|
+
import { StackItem } from './StackItem';
|
|
14
15
|
|
|
15
16
|
type StoryStackItem = {
|
|
16
17
|
id: string;
|
|
@@ -93,15 +94,15 @@ const StorybookStack = () => {
|
|
|
93
94
|
|
|
94
95
|
return (
|
|
95
96
|
<main className='fixed inset-0'>
|
|
96
|
-
<Stack orientation='horizontal' size='contain'>
|
|
97
|
+
<Stack orientation='horizontal' size='contain' onRearrange={reorderItem}>
|
|
97
98
|
{columns.map((column) => (
|
|
98
|
-
<StackItem.Root key={column.id} item={column}
|
|
99
|
+
<StackItem.Root key={column.id} item={column}>
|
|
99
100
|
<StackItem.Heading>
|
|
100
101
|
<StackItem.ResizeHandle />
|
|
101
102
|
</StackItem.Heading>
|
|
102
103
|
<Stack orientation='vertical' size='contain'>
|
|
103
104
|
{column.items?.map((card) => (
|
|
104
|
-
<StackItem.Root key={card.id} item={card}
|
|
105
|
+
<StackItem.Root key={card.id} item={card}>
|
|
105
106
|
<StackItem.Heading>
|
|
106
107
|
<StackItem.ResizeHandle />
|
|
107
108
|
</StackItem.Heading>
|
package/src/components/Stack.tsx
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
//
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
|
-
|
|
4
|
+
import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
5
|
+
import { attachClosestEdge, extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
5
6
|
import { useArrowNavigationGroup } from '@fluentui/react-tabster';
|
|
6
|
-
import
|
|
7
|
+
import { composeRefs } from '@radix-ui/react-compose-refs';
|
|
8
|
+
import React, {
|
|
9
|
+
Children,
|
|
10
|
+
type CSSProperties,
|
|
11
|
+
type ComponentPropsWithRef,
|
|
12
|
+
forwardRef,
|
|
13
|
+
useLayoutEffect,
|
|
14
|
+
useState,
|
|
15
|
+
} from 'react';
|
|
7
16
|
|
|
8
|
-
import { type ThemedClassName } from '@dxos/react-ui';
|
|
17
|
+
import { type ThemedClassName, ListItem } from '@dxos/react-ui';
|
|
9
18
|
import { mx } from '@dxos/react-ui-theme';
|
|
10
19
|
|
|
11
|
-
import { type StackContextValue, StackContext } from './StackContext';
|
|
20
|
+
import { type StackContextValue, StackContext, type StackItemData } from './StackContext';
|
|
12
21
|
|
|
13
22
|
export type Orientation = 'horizontal' | 'vertical';
|
|
14
23
|
export type Size = 'intrinsic' | 'contain';
|
|
@@ -28,13 +37,17 @@ export const Stack = forwardRef<HTMLDivElement, StackProps>(
|
|
|
28
37
|
style,
|
|
29
38
|
orientation = 'vertical',
|
|
30
39
|
rail = true,
|
|
31
|
-
separators = true,
|
|
32
40
|
size = 'intrinsic',
|
|
41
|
+
onRearrange,
|
|
33
42
|
itemsCount = Children.count(children),
|
|
34
43
|
...props
|
|
35
44
|
},
|
|
36
45
|
forwardedRef,
|
|
37
46
|
) => {
|
|
47
|
+
const [stackElement, stackRef] = useState<HTMLDivElement | null>(null);
|
|
48
|
+
const composedItemRef = composeRefs<HTMLDivElement>(stackRef, forwardedRef);
|
|
49
|
+
const [dropping, setDropping] = useState(false);
|
|
50
|
+
|
|
38
51
|
const arrowNavigationGroup = useArrowNavigationGroup({ axis: orientation });
|
|
39
52
|
|
|
40
53
|
const styles: CSSProperties = {
|
|
@@ -42,8 +55,43 @@ export const Stack = forwardRef<HTMLDivElement, StackProps>(
|
|
|
42
55
|
...style,
|
|
43
56
|
};
|
|
44
57
|
|
|
58
|
+
const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
|
|
59
|
+
|
|
60
|
+
useLayoutEffect(() => {
|
|
61
|
+
if (!stackElement || !selfDroppable) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const acceptSourceType = orientation === 'horizontal' ? 'column' : 'card';
|
|
65
|
+
return dropTargetForElements({
|
|
66
|
+
element: stackElement,
|
|
67
|
+
getData: ({ input, element }) => {
|
|
68
|
+
return attachClosestEdge(
|
|
69
|
+
{ id: props.id, type: orientation === 'horizontal' ? 'card' : 'column' },
|
|
70
|
+
{ input, element, allowedEdges: [orientation === 'horizontal' ? 'left' : 'top'] },
|
|
71
|
+
);
|
|
72
|
+
},
|
|
73
|
+
onDragEnter: ({ source }) => {
|
|
74
|
+
if (source.data.type === acceptSourceType) {
|
|
75
|
+
setDropping(true);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
onDrag: ({ source }) => {
|
|
79
|
+
if (source.data.type === acceptSourceType) {
|
|
80
|
+
setDropping(true);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
onDragLeave: () => setDropping(false),
|
|
84
|
+
onDrop: ({ self, source }) => {
|
|
85
|
+
setDropping(false);
|
|
86
|
+
if (source.data.type === acceptSourceType && selfDroppable) {
|
|
87
|
+
onRearrange(source.data as StackItemData, self.data as StackItemData, extractClosestEdge(self.data));
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}, [stackElement, selfDroppable]);
|
|
92
|
+
|
|
45
93
|
return (
|
|
46
|
-
<StackContext.Provider value={{ orientation, rail, size,
|
|
94
|
+
<StackContext.Provider value={{ orientation, rail, size, onRearrange }}>
|
|
47
95
|
<div
|
|
48
96
|
{...props}
|
|
49
97
|
{...arrowNavigationGroup}
|
|
@@ -60,14 +108,14 @@ export const Stack = forwardRef<HTMLDivElement, StackProps>(
|
|
|
60
108
|
(orientation === 'horizontal'
|
|
61
109
|
? 'overflow-x-auto min-bs-0 bs-full max-bs-full'
|
|
62
110
|
: 'overflow-y-auto min-is-0 is-full max-is-full'),
|
|
63
|
-
separators && (orientation === 'horizontal' ? 'divide-separator divide-x' : 'divide-separator divide-y'),
|
|
64
111
|
classNames,
|
|
65
112
|
)}
|
|
66
113
|
aria-orientation={orientation}
|
|
67
114
|
style={styles}
|
|
68
|
-
ref={
|
|
115
|
+
ref={composedItemRef}
|
|
69
116
|
>
|
|
70
117
|
{children}
|
|
118
|
+
{selfDroppable && dropping && <ListItem.DropIndicator edge={orientation === 'horizontal' ? 'left' : 'top'} />}
|
|
71
119
|
</div>
|
|
72
120
|
</StackContext.Provider>
|
|
73
121
|
);
|
|
@@ -2,28 +2,37 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import type { Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
5
6
|
import { createContext, useContext } from 'react';
|
|
6
7
|
|
|
7
8
|
import { type Orientation, type Size } from './Stack';
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
export type StackItemSize = number | 'min-content';
|
|
11
|
+
|
|
12
|
+
export type StackItemData = { id: string; type: 'column' | 'card' };
|
|
13
|
+
|
|
14
|
+
export type StackItemRearrangeHandler = (
|
|
15
|
+
source: StackItemData,
|
|
16
|
+
target: StackItemData,
|
|
17
|
+
closestEdge: Edge | null,
|
|
18
|
+
) => void;
|
|
9
19
|
|
|
10
20
|
export type StackContextValue = {
|
|
11
21
|
orientation: Orientation;
|
|
12
|
-
separators: boolean;
|
|
13
22
|
rail: boolean;
|
|
14
23
|
size: Size;
|
|
24
|
+
onRearrange?: StackItemRearrangeHandler;
|
|
15
25
|
};
|
|
16
26
|
|
|
17
27
|
export const StackContext = createContext<StackContextValue>({
|
|
18
28
|
orientation: 'vertical',
|
|
19
29
|
rail: true,
|
|
20
30
|
size: 'intrinsic',
|
|
21
|
-
separators: true,
|
|
22
31
|
});
|
|
23
32
|
|
|
24
33
|
export const useStack = () => useContext(StackContext);
|
|
25
34
|
|
|
26
|
-
type StackItemContextValue = {
|
|
35
|
+
export type StackItemContextValue = {
|
|
27
36
|
selfDragHandleRef: (element: HTMLDivElement | null) => void;
|
|
28
37
|
size: StackItemSize;
|
|
29
38
|
setSize: (nextSize: StackItemSize, commit?: boolean) => void;
|
|
@@ -4,29 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
|
6
6
|
import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
7
|
+
import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview';
|
|
8
|
+
import { preventUnhandled } from '@atlaskit/pragmatic-drag-and-drop/prevent-unhandled';
|
|
7
9
|
import {
|
|
8
10
|
attachClosestEdge,
|
|
9
11
|
extractClosestEdge,
|
|
10
12
|
type Edge,
|
|
11
13
|
} from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
12
|
-
// TODO(wittjosiah): Drop indicator that doesn't depend on emotion. See react-ui-list DropIndicator.
|
|
13
|
-
// import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
|
|
14
14
|
import { useFocusableGroup } from '@fluentui/react-tabster';
|
|
15
15
|
import { composeRefs } from '@radix-ui/react-compose-refs';
|
|
16
16
|
import React, { forwardRef, useLayoutEffect, useState, type ComponentPropsWithRef, useCallback } from 'react';
|
|
17
17
|
|
|
18
|
-
import { type ThemedClassName } from '@dxos/react-ui';
|
|
18
|
+
import { type ThemedClassName, ListItem } from '@dxos/react-ui';
|
|
19
19
|
import { mx } from '@dxos/react-ui-theme';
|
|
20
20
|
|
|
21
|
-
import { useStack, StackItemContext } from './StackContext';
|
|
21
|
+
import { useStack, StackItemContext, type StackItemSize, type StackItemData } from './StackContext';
|
|
22
22
|
import { StackItemContent, type StackItemContentProps } from './StackItemContent';
|
|
23
|
+
import { StackItemDragHandle, type StackItemDragHandleProps } from './StackItemDragHandle';
|
|
23
24
|
import {
|
|
24
25
|
StackItemHeading,
|
|
25
26
|
StackItemHeadingLabel,
|
|
26
27
|
type StackItemHeadingProps,
|
|
27
28
|
type StackItemHeadingLabelProps,
|
|
28
29
|
} from './StackItemHeading';
|
|
29
|
-
import { StackItemResizeHandle } from './StackItemResizeHandle';
|
|
30
|
+
import { StackItemResizeHandle, type StackItemResizeHandleProps } from './StackItemResizeHandle';
|
|
30
31
|
import {
|
|
31
32
|
StackItemSigil,
|
|
32
33
|
type StackItemSigilProps,
|
|
@@ -35,31 +36,24 @@ import {
|
|
|
35
36
|
StackItemSigilButton,
|
|
36
37
|
} from './StackItemSigil';
|
|
37
38
|
|
|
38
|
-
export type StackItemSize = number | 'min-content';
|
|
39
39
|
export const DEFAULT_HORIZONTAL_SIZE = 44 satisfies StackItemSize;
|
|
40
40
|
export const DEFAULT_VERTICAL_SIZE = 'min-content' satisfies StackItemSize;
|
|
41
41
|
export const DEFAULT_EXTRINSIC_SIZE = DEFAULT_HORIZONTAL_SIZE satisfies StackItemSize;
|
|
42
42
|
|
|
43
|
-
export type StackItemData = { id: string; type: 'column' | 'card' };
|
|
44
|
-
|
|
45
43
|
export type StackItemRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
|
|
46
44
|
item: Omit<StackItemData, 'type'>;
|
|
47
45
|
order?: number;
|
|
48
|
-
onRearrange?: (source: StackItemData, target: StackItemData, closestEdge: Edge | null) => void;
|
|
49
46
|
size?: StackItemSize;
|
|
50
47
|
onSizeChange?: (nextSize: StackItemSize) => void;
|
|
51
48
|
role?: 'article' | 'section';
|
|
52
49
|
};
|
|
53
50
|
|
|
54
51
|
const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
55
|
-
(
|
|
56
|
-
{ item, children, classNames, onRearrange, size: propsSize, onSizeChange, role, order, style, ...props },
|
|
57
|
-
forwardedRef,
|
|
58
|
-
) => {
|
|
52
|
+
({ item, children, classNames, size: propsSize, onSizeChange, role, order, style, ...props }, forwardedRef) => {
|
|
59
53
|
const [itemElement, itemRef] = useState<HTMLDivElement | null>(null);
|
|
60
54
|
const [selfDragHandleElement, selfDragHandleRef] = useState<HTMLDivElement | null>(null);
|
|
61
|
-
const [
|
|
62
|
-
const { orientation, rail,
|
|
55
|
+
const [closestEdge, setEdge] = useState<Edge | null>(null);
|
|
56
|
+
const { orientation, rail, onRearrange } = useStack();
|
|
63
57
|
const [size = orientation === 'horizontal' ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] =
|
|
64
58
|
useState(propsSize);
|
|
65
59
|
|
|
@@ -88,6 +82,11 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
88
82
|
element: itemElement,
|
|
89
83
|
...(selfDragHandleElement && { dragHandle: selfDragHandleElement }),
|
|
90
84
|
getInitialData: () => ({ id: item.id, type }),
|
|
85
|
+
// TODO(thure): tabster focus honeypots are causing the preview to render with the wrong dimensions; what do?
|
|
86
|
+
onGenerateDragPreview: ({ nativeSetDragImage }) => {
|
|
87
|
+
disableNativeDragPreview({ nativeSetDragImage });
|
|
88
|
+
preventUnhandled.start();
|
|
89
|
+
},
|
|
91
90
|
}),
|
|
92
91
|
dropTargetForElements({
|
|
93
92
|
element: itemElement,
|
|
@@ -131,7 +130,6 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
131
130
|
size === 'min-content' && (orientation === 'horizontal' ? 'is-min' : 'bs-min'),
|
|
132
131
|
orientation === 'horizontal' ? 'grid-rows-subgrid' : 'grid-cols-subgrid',
|
|
133
132
|
rail && (orientation === 'horizontal' ? 'row-span-2' : 'col-span-2'),
|
|
134
|
-
separators && (orientation === 'horizontal' ? 'divide-separator divide-y' : 'divide-separator divide-x'),
|
|
135
133
|
classNames,
|
|
136
134
|
)}
|
|
137
135
|
data-dx-stack-item
|
|
@@ -147,7 +145,7 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
|
|
|
147
145
|
ref={composedItemRef}
|
|
148
146
|
>
|
|
149
147
|
{children}
|
|
150
|
-
{
|
|
148
|
+
{closestEdge && <ListItem.DropIndicator edge={closestEdge} />}
|
|
151
149
|
</Root>
|
|
152
150
|
</StackItemContext.Provider>
|
|
153
151
|
);
|
|
@@ -160,6 +158,7 @@ export const StackItem = {
|
|
|
160
158
|
Heading: StackItemHeading,
|
|
161
159
|
HeadingLabel: StackItemHeadingLabel,
|
|
162
160
|
ResizeHandle: StackItemResizeHandle,
|
|
161
|
+
DragHandle: StackItemDragHandle,
|
|
163
162
|
Sigil: StackItemSigil,
|
|
164
163
|
SigilButton: StackItemSigilButton,
|
|
165
164
|
};
|
|
@@ -168,6 +167,8 @@ export type {
|
|
|
168
167
|
StackItemContentProps,
|
|
169
168
|
StackItemHeadingProps,
|
|
170
169
|
StackItemHeadingLabelProps,
|
|
170
|
+
StackItemResizeHandleProps,
|
|
171
|
+
StackItemDragHandleProps,
|
|
171
172
|
StackItemSigilProps,
|
|
172
173
|
StackItemSigilButtonProps,
|
|
173
174
|
StackItemSigilAction,
|
|
@@ -21,18 +21,13 @@ export const StackItemContent = ({
|
|
|
21
21
|
classNames,
|
|
22
22
|
...props
|
|
23
23
|
}: StackItemContentProps) => {
|
|
24
|
-
const { size
|
|
24
|
+
const { size } = useStack();
|
|
25
25
|
|
|
26
26
|
return (
|
|
27
27
|
<div
|
|
28
28
|
role='none'
|
|
29
29
|
{...props}
|
|
30
|
-
className={mx(
|
|
31
|
-
'group grid grid-cols-[100%]',
|
|
32
|
-
size === 'contain' && 'min-bs-0 overflow-hidden',
|
|
33
|
-
separators && 'divide-separator divide-y',
|
|
34
|
-
classNames,
|
|
35
|
-
)}
|
|
30
|
+
className={mx('group grid grid-cols-[100%]', size === 'contain' && 'min-bs-0 overflow-hidden', classNames)}
|
|
36
31
|
style={{
|
|
37
32
|
gridTemplateRows: [
|
|
38
33
|
...(toolbar ? ['var(--rail-action)'] : []),
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
6
|
+
import React, { type ComponentPropsWithoutRef } from 'react';
|
|
7
|
+
|
|
8
|
+
import { useStackItem } from './StackContext';
|
|
9
|
+
|
|
10
|
+
export type StackItemDragHandleProps = ComponentPropsWithoutRef<'button'> & { asChild: boolean };
|
|
11
|
+
|
|
12
|
+
export const StackItemDragHandle = ({ asChild, children }: StackItemDragHandleProps) => {
|
|
13
|
+
const { selfDragHandleRef } = useStackItem();
|
|
14
|
+
|
|
15
|
+
const Root = asChild ? Slot : 'div';
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Root ref={selfDragHandleRef} role='button'>
|
|
19
|
+
{children}
|
|
20
|
+
</Root>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -9,13 +9,12 @@ import { type ThemedClassName } from '@dxos/react-ui';
|
|
|
9
9
|
import { useAttention, type AttendableId, type Related } from '@dxos/react-ui-attention';
|
|
10
10
|
import { mx } from '@dxos/react-ui-theme';
|
|
11
11
|
|
|
12
|
-
import { useStack
|
|
12
|
+
import { useStack } from './StackContext';
|
|
13
13
|
|
|
14
14
|
export type StackItemHeadingProps = ThemedClassName<ComponentPropsWithoutRef<'div'>>;
|
|
15
15
|
|
|
16
16
|
export const StackItemHeading = ({ children, classNames, ...props }: StackItemHeadingProps) => {
|
|
17
17
|
const { orientation } = useStack();
|
|
18
|
-
const { selfDragHandleRef } = useStackItem();
|
|
19
18
|
const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited' });
|
|
20
19
|
return (
|
|
21
20
|
<div
|
|
@@ -28,7 +27,6 @@ export const StackItemHeading = ({ children, classNames, ...props }: StackItemHe
|
|
|
28
27
|
orientation === 'horizontal' ? 'bs-[--rail-size]' : 'is-[--rail-size] flex-col',
|
|
29
28
|
classNames,
|
|
30
29
|
)}
|
|
31
|
-
ref={selfDragHandleRef}
|
|
32
30
|
>
|
|
33
31
|
{children}
|
|
34
32
|
</div>
|
|
@@ -10,8 +10,8 @@ import React, { useLayoutEffect, useRef } from 'react';
|
|
|
10
10
|
|
|
11
11
|
import { mx } from '@dxos/react-ui-theme';
|
|
12
12
|
|
|
13
|
-
import { useStack, useStackItem } from './StackContext';
|
|
14
|
-
import { DEFAULT_EXTRINSIC_SIZE
|
|
13
|
+
import { useStack, useStackItem, type StackItemSize } from './StackContext';
|
|
14
|
+
import { DEFAULT_EXTRINSIC_SIZE } from './StackItem';
|
|
15
15
|
|
|
16
16
|
const REM = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
17
17
|
|
|
@@ -26,6 +26,8 @@ const getNextSize = (startSize: number, location: DragLocationHistory, client: '
|
|
|
26
26
|
return Math.max(MIN_SIZE, startSize + (location.current.input[client] - location.initial.input[client]) / REM);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
export type StackItemResizeHandleProps = {};
|
|
30
|
+
|
|
29
31
|
export const StackItemResizeHandle = () => {
|
|
30
32
|
const { orientation } = useStack();
|
|
31
33
|
const { setSize, size } = useStackItem();
|
|
@@ -42,11 +44,10 @@ export const StackItemResizeHandle = () => {
|
|
|
42
44
|
draggable({
|
|
43
45
|
element: buttonRef.current,
|
|
44
46
|
onGenerateDragPreview: ({ nativeSetDragImage }) => {
|
|
45
|
-
//
|
|
46
|
-
// we can disable the native drag preview
|
|
47
|
+
// We will be moving the line to indicate a drag; we can disable the native drag preview.
|
|
47
48
|
disableNativeDragPreview({ nativeSetDragImage });
|
|
48
|
-
//
|
|
49
|
-
//
|
|
49
|
+
// We don't want any native drop animation for when the user does not drop on a drop target.
|
|
50
|
+
// We want the drag to finish immediately.
|
|
50
51
|
preventUnhandled.start();
|
|
51
52
|
},
|
|
52
53
|
onDragStart: () => {
|
|
@@ -159,7 +159,7 @@ export const StackItemSigil = forwardRef<HTMLButtonElement, StackItemSigilProps>
|
|
|
159
159
|
</DropdownMenu.Portal>
|
|
160
160
|
</DropdownMenu.Root>
|
|
161
161
|
<Tooltip.Portal>
|
|
162
|
-
<Tooltip.Content
|
|
162
|
+
<Tooltip.Content side='bottom'>
|
|
163
163
|
{triggerLabel}
|
|
164
164
|
<Tooltip.Arrow />
|
|
165
165
|
</Tooltip.Content>
|
package/src/components/index.ts
CHANGED