@dxos/react-ui-stack 0.7.5-main.9d2a38b → 0.7.5-main.b19bfc8
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 +159 -163
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +195 -198
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +159 -163
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/MenuSignifier.d.ts +2 -3
- package/dist/types/src/components/MenuSignifier.d.ts.map +1 -1
- package/dist/types/src/components/Stack.d.ts +6 -1
- package/dist/types/src/components/Stack.d.ts.map +1 -1
- package/dist/types/src/components/Stack.stories.d.ts +1 -2
- package/dist/types/src/components/Stack.stories.d.ts.map +1 -1
- package/dist/types/src/components/StackContext.d.ts +2 -1
- package/dist/types/src/components/StackContext.d.ts.map +1 -1
- package/dist/types/src/components/StackItem.d.ts +7 -5
- package/dist/types/src/components/StackItem.d.ts.map +1 -1
- package/dist/types/src/components/StackItemContent.d.ts +1 -1
- package/dist/types/src/components/StackItemContent.d.ts.map +1 -1
- package/dist/types/src/components/StackItemDragHandle.d.ts +2 -2
- package/dist/types/src/components/StackItemDragHandle.d.ts.map +1 -1
- package/dist/types/src/components/StackItemHeading.d.ts +1 -1
- package/dist/types/src/components/StackItemHeading.d.ts.map +1 -1
- package/dist/types/src/components/StackItemResizeHandle.d.ts +1 -2
- package/dist/types/src/components/StackItemResizeHandle.d.ts.map +1 -1
- package/dist/types/src/components/StackItemSigil.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useStackDropForElements.d.ts +15 -0
- package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -0
- package/package.json +29 -27
- package/src/components/Stack.stories.tsx +1 -1
- package/src/components/Stack.tsx +44 -57
- package/src/components/StackContext.tsx +3 -1
- package/src/components/StackItem.tsx +45 -14
- package/src/components/StackItemContent.tsx +2 -0
- package/src/components/StackItemHeading.tsx +1 -1
- package/src/components/StackItemResizeHandle.tsx +12 -98
- package/src/components/StackItemSigil.tsx +90 -103
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useStackDropForElements.ts +73 -0
- package/dist/types/src/playwright/playwright.config.d.ts +0 -3
- package/dist/types/src/playwright/playwright.config.d.ts.map +0 -1
- /package/src/playwright/{playwright.config.ts → playwright.config.cts} +0 -0
|
@@ -6,15 +6,7 @@ import React, { Fragment, type PropsWithChildren, forwardRef, useRef, useState }
|
|
|
6
6
|
|
|
7
7
|
import { type ActionLike } from '@dxos/app-graph';
|
|
8
8
|
import { keySymbols } from '@dxos/keyboard';
|
|
9
|
-
import {
|
|
10
|
-
Button,
|
|
11
|
-
type ButtonProps,
|
|
12
|
-
DropdownMenu,
|
|
13
|
-
Icon,
|
|
14
|
-
toLocalizedString,
|
|
15
|
-
Tooltip,
|
|
16
|
-
useTranslation,
|
|
17
|
-
} from '@dxos/react-ui';
|
|
9
|
+
import { Button, type ButtonProps, DropdownMenu, Icon, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
18
10
|
import { type AttendableId, type Related, useAttention } from '@dxos/react-ui-attention';
|
|
19
11
|
import { descriptionText, mx } from '@dxos/react-ui-theme';
|
|
20
12
|
import { getHostPlatform } from '@dxos/util';
|
|
@@ -42,7 +34,7 @@ export const StackItemSigilButton = forwardRef<HTMLButtonElement, StackItemSigil
|
|
|
42
34
|
<Button
|
|
43
35
|
{...props}
|
|
44
36
|
variant={variant}
|
|
45
|
-
classNames={['shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative', classNames]}
|
|
37
|
+
classNames={['shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag', classNames]}
|
|
46
38
|
ref={forwardedRef}
|
|
47
39
|
>
|
|
48
40
|
<MenuSignifierHorizontal />
|
|
@@ -68,103 +60,98 @@ export const StackItemSigil = forwardRef<HTMLButtonElement, StackItemSigilProps>
|
|
|
68
60
|
const suppressNextTooltip = useRef(false);
|
|
69
61
|
|
|
70
62
|
const [optionsMenuOpen, setOptionsMenuOpen] = useState(false);
|
|
71
|
-
|
|
63
|
+
|
|
64
|
+
const hasActions = actionGroups && actionGroups.length > 0;
|
|
65
|
+
|
|
66
|
+
const button = (
|
|
67
|
+
<StackItemSigilButton
|
|
68
|
+
attendableId={attendableId}
|
|
69
|
+
related={related}
|
|
70
|
+
// TODO(wittjosiah): Better disabling of interactive styles when no action are available.
|
|
71
|
+
// Remove underscore icon when no actions are available?
|
|
72
|
+
classNames={!hasActions && 'cursor-default'}
|
|
73
|
+
>
|
|
74
|
+
<span className='sr-only'>{triggerLabel}</span>
|
|
75
|
+
<Icon icon={icon} size={5} />
|
|
76
|
+
</StackItemSigilButton>
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (!hasActions) {
|
|
80
|
+
return button;
|
|
81
|
+
}
|
|
72
82
|
|
|
73
83
|
return (
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
84
|
+
<DropdownMenu.Root
|
|
85
|
+
{...{
|
|
86
|
+
open: optionsMenuOpen,
|
|
87
|
+
onOpenChange: (nextOpen: boolean) => {
|
|
88
|
+
if (!nextOpen) {
|
|
89
|
+
suppressNextTooltip.current = true;
|
|
90
|
+
}
|
|
91
|
+
return setOptionsMenuOpen(nextOpen);
|
|
92
|
+
},
|
|
83
93
|
}}
|
|
84
94
|
>
|
|
85
|
-
<DropdownMenu.
|
|
86
|
-
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
)}
|
|
146
|
-
{shortcut && (
|
|
147
|
-
<span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>
|
|
148
|
-
)}
|
|
149
|
-
</Root>
|
|
150
|
-
);
|
|
151
|
-
})}
|
|
152
|
-
</Fragment>
|
|
153
|
-
);
|
|
154
|
-
})}
|
|
155
|
-
{children}
|
|
156
|
-
</DropdownMenu.Viewport>
|
|
157
|
-
<DropdownMenu.Arrow />
|
|
158
|
-
</DropdownMenu.Content>
|
|
159
|
-
</DropdownMenu.Portal>
|
|
160
|
-
</DropdownMenu.Root>
|
|
161
|
-
<Tooltip.Portal>
|
|
162
|
-
<Tooltip.Content side='bottom'>
|
|
163
|
-
{triggerLabel}
|
|
164
|
-
<Tooltip.Arrow />
|
|
165
|
-
</Tooltip.Content>
|
|
166
|
-
</Tooltip.Portal>
|
|
167
|
-
</Tooltip.Root>
|
|
95
|
+
<DropdownMenu.Trigger asChild ref={forwardedRef}>
|
|
96
|
+
{button}
|
|
97
|
+
</DropdownMenu.Trigger>
|
|
98
|
+
<DropdownMenu.Portal>
|
|
99
|
+
<DropdownMenu.Content classNames='z-[31]'>
|
|
100
|
+
<DropdownMenu.Viewport>
|
|
101
|
+
{actionGroups?.map((actions, index) => {
|
|
102
|
+
const separator = index > 0 ? <DropdownMenu.Separator /> : null;
|
|
103
|
+
return (
|
|
104
|
+
<Fragment key={index}>
|
|
105
|
+
{separator}
|
|
106
|
+
{actions.map((action) => {
|
|
107
|
+
const shortcut =
|
|
108
|
+
typeof action.properties.keyBinding === 'string'
|
|
109
|
+
? action.properties.keyBinding
|
|
110
|
+
: action.properties.keyBinding?.[getHostPlatform()];
|
|
111
|
+
|
|
112
|
+
const menuItemType = action.properties.menuItemType;
|
|
113
|
+
const Root = menuItemType === 'toggle' ? DropdownMenu.CheckboxItem : DropdownMenu.Item;
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<Root
|
|
117
|
+
key={action.id}
|
|
118
|
+
onClick={(event) => {
|
|
119
|
+
if (action.properties.disabled) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
event.stopPropagation();
|
|
123
|
+
// TODO(thure): Why does Dialog’s modal-ness cause issues if we don’t explicitly close the menu here?
|
|
124
|
+
suppressNextTooltip.current = true;
|
|
125
|
+
setOptionsMenuOpen(false);
|
|
126
|
+
onAction?.(action);
|
|
127
|
+
}}
|
|
128
|
+
classNames='gap-2'
|
|
129
|
+
disabled={action.properties.disabled}
|
|
130
|
+
checked={menuItemType === 'toggle' ? action.properties.isChecked : undefined}
|
|
131
|
+
{...(action.properties?.testId && { 'data-testid': action.properties.testId })}
|
|
132
|
+
>
|
|
133
|
+
<Icon icon={action.properties.icon ?? 'ph--placeholder--regular'} size={4} />
|
|
134
|
+
<span className='grow truncate'>{toLocalizedString(action.properties.label ?? '', t)}</span>
|
|
135
|
+
{menuItemType === 'toggle' && (
|
|
136
|
+
<DropdownMenu.ItemIndicator asChild>
|
|
137
|
+
<Icon icon='ph--check--regular' size={4} />
|
|
138
|
+
</DropdownMenu.ItemIndicator>
|
|
139
|
+
)}
|
|
140
|
+
{shortcut && (
|
|
141
|
+
<span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>
|
|
142
|
+
)}
|
|
143
|
+
</Root>
|
|
144
|
+
);
|
|
145
|
+
})}
|
|
146
|
+
</Fragment>
|
|
147
|
+
);
|
|
148
|
+
})}
|
|
149
|
+
{children}
|
|
150
|
+
</DropdownMenu.Viewport>
|
|
151
|
+
<DropdownMenu.Arrow />
|
|
152
|
+
</DropdownMenu.Content>
|
|
153
|
+
</DropdownMenu.Portal>
|
|
154
|
+
</DropdownMenu.Root>
|
|
168
155
|
);
|
|
169
156
|
},
|
|
170
157
|
);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
|
6
|
+
import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
7
|
+
import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-scroll/element';
|
|
8
|
+
import { attachClosestEdge, extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
9
|
+
import { useLayoutEffect, useState } from 'react';
|
|
10
|
+
|
|
11
|
+
import { type Orientation } from '../components/Stack';
|
|
12
|
+
import { type StackItemRearrangeHandler, type StackItemData } from '../components/StackContext';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Hook to handle drag and drop functionality for Stack components.
|
|
16
|
+
*/
|
|
17
|
+
export const useStackDropForElements = ({
|
|
18
|
+
element,
|
|
19
|
+
selfDroppable,
|
|
20
|
+
orientation,
|
|
21
|
+
id,
|
|
22
|
+
onRearrange,
|
|
23
|
+
}: {
|
|
24
|
+
element: HTMLDivElement | null;
|
|
25
|
+
selfDroppable: boolean;
|
|
26
|
+
orientation: Orientation;
|
|
27
|
+
id?: string;
|
|
28
|
+
onRearrange?: StackItemRearrangeHandler;
|
|
29
|
+
}) => {
|
|
30
|
+
const [dropping, setDropping] = useState(false);
|
|
31
|
+
|
|
32
|
+
useLayoutEffect(() => {
|
|
33
|
+
if (!element || !selfDroppable) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const acceptSourceType = orientation === 'horizontal' ? 'column' : 'card';
|
|
38
|
+
|
|
39
|
+
return combine(
|
|
40
|
+
dropTargetForElements({
|
|
41
|
+
element,
|
|
42
|
+
getData: ({ input, element }) => {
|
|
43
|
+
return attachClosestEdge(
|
|
44
|
+
{ id, type: orientation === 'horizontal' ? 'card' : 'column' },
|
|
45
|
+
{ input, element, allowedEdges: [orientation === 'horizontal' ? 'left' : 'top'] },
|
|
46
|
+
);
|
|
47
|
+
},
|
|
48
|
+
onDragEnter: ({ source }) => {
|
|
49
|
+
if (source.data.type === acceptSourceType) {
|
|
50
|
+
setDropping(true);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
onDrag: ({ source }) => {
|
|
54
|
+
if (source.data.type === acceptSourceType) {
|
|
55
|
+
setDropping(true);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
onDragLeave: () => {
|
|
59
|
+
return setDropping(false);
|
|
60
|
+
},
|
|
61
|
+
onDrop: ({ self, source }) => {
|
|
62
|
+
setDropping(false);
|
|
63
|
+
if (source.data.type === acceptSourceType && selfDroppable && onRearrange) {
|
|
64
|
+
onRearrange(source.data as StackItemData, self.data as StackItemData, extractClosestEdge(self.data));
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
autoScrollForElements({ element, getAllowedAxis: () => orientation }),
|
|
69
|
+
);
|
|
70
|
+
}, [element, selfDroppable, orientation, id, onRearrange]);
|
|
71
|
+
|
|
72
|
+
return { dropping };
|
|
73
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.config.d.ts","sourceRoot":"","sources":["../../../../src/playwright/playwright.config.ts"],"names":[],"mappings":";AASA,wBAQG"}
|
|
File without changes
|