deepsea-components 5.16.2 → 5.16.4
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.
|
@@ -83,10 +83,10 @@ function getOrderToKey(keyToOrder) {
|
|
|
83
83
|
key
|
|
84
84
|
]));
|
|
85
85
|
}
|
|
86
|
-
|
|
86
|
+
function DraggableGridItem({ item, itemKey, handle, onDragMoveStart, onDragMove, onDragMoveEnd, ...rest }) {
|
|
87
87
|
const element = (0, external_react_namespaceObject.useRef)(null);
|
|
88
88
|
(0, external_soda_hooks_namespaceObject.useDragMove)({
|
|
89
|
-
element,
|
|
89
|
+
element: (0, external_deepsea_tools_namespaceObject.isNullable)(handle) ? element : ()=>element.current && ("string" == typeof handle ? element.current.querySelector(handle) : "function" == typeof handle ? handle(item, itemKey, element.current) : handle),
|
|
90
90
|
onDragMoveStart,
|
|
91
91
|
onDragMove,
|
|
92
92
|
onDragMoveEnd
|
|
@@ -95,8 +95,8 @@ const DraggableGridItem = ({ onDragMoveStart, onDragMove, onDragMoveEnd, ...rest
|
|
|
95
95
|
ref: element,
|
|
96
96
|
...rest
|
|
97
97
|
});
|
|
98
|
-
}
|
|
99
|
-
function DraggableGrid({ className, classNames, style, items = [], disabled, columns, rows, gap = 0, gapX = gap, gapY = gap, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled: _isItemDisabled, isOrderDisabled, orderPriority, ...rest }) {
|
|
98
|
+
}
|
|
99
|
+
function DraggableGrid({ className, classNames, style, items = [], disabled, columns, rows, gap = 0, gapX = gap, gapY = gap, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled: _isItemDisabled, isOrderDisabled, orderPriority, handle, onDragMoveStart: _onDragMoveStart, onDragMove: _onDragMove, onDragMoveEnd: _onDragMoveEnd, ...rest }) {
|
|
100
100
|
const keyToItem = (0, external_react_namespaceObject.useMemo)(()=>{
|
|
101
101
|
const keyToItem = new Map();
|
|
102
102
|
items.forEach((item)=>{
|
|
@@ -190,6 +190,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
190
190
|
onOrderMapChange
|
|
191
191
|
]);
|
|
192
192
|
function onDragMoveStart(key, event) {
|
|
193
|
+
_onDragMoveStart?.(event);
|
|
193
194
|
const position = getPosition({
|
|
194
195
|
order: keyToOrder.get(key),
|
|
195
196
|
columns,
|
|
@@ -216,6 +217,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
216
217
|
});
|
|
217
218
|
}
|
|
218
219
|
function onDragMove(event) {
|
|
220
|
+
_onDragMove?.(event);
|
|
219
221
|
if (!dragging) return;
|
|
220
222
|
const { deltaX, deltaY } = event;
|
|
221
223
|
const { key, orders, keyToOrder, startX, startY, columns, gapX, gapY, itemWidth, itemHeight } = dragging;
|
|
@@ -281,7 +283,8 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
281
283
|
setKeyToOrder(newKeyToOrder);
|
|
282
284
|
onOrderMapChange?.(newKeyToOrder);
|
|
283
285
|
}
|
|
284
|
-
function onDragMoveEnd() {
|
|
286
|
+
function onDragMoveEnd(event) {
|
|
287
|
+
_onDragMoveEnd?.(event);
|
|
285
288
|
if (!dragging) return;
|
|
286
289
|
setDragging(void 0);
|
|
287
290
|
}
|
|
@@ -336,6 +339,9 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
336
339
|
isDragging: isDragging
|
|
337
340
|
}) : item;
|
|
338
341
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(DraggableGridItem, {
|
|
342
|
+
item: item,
|
|
343
|
+
itemKey: key,
|
|
344
|
+
handle: handle,
|
|
339
345
|
className: (0, external_deepsea_tools_namespaceObject.clsx)(external_DraggableGrid_module_cjs_default().draggableGridItem, "function" == typeof classNames?.item ? classNames.item({
|
|
340
346
|
order,
|
|
341
347
|
isDragging: isDragging
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { CSSProperties, ComponentProps, Key, ReactNode } from "react";
|
|
2
|
+
import { DragMoveEvents } from "soda-hooks";
|
|
3
|
+
export type MustBeReactNode<T> = false extends (T extends ReactNode ? true : false) ? false : true;
|
|
4
|
+
export type MustBeReactKey<T> = false extends (T extends Key ? true : false) ? false : true;
|
|
2
5
|
export type DraggableGridClassName = string | ((status: ContainerStatus) => string);
|
|
3
6
|
export type DraggableGridItemClassName = string | ((status: DraggableGridItemStatus) => string);
|
|
4
7
|
export type DraggableGridStyle = CSSProperties | ((status: ContainerStatus) => CSSProperties);
|
|
@@ -19,10 +22,10 @@ export interface DraggableGridItemStatus {
|
|
|
19
22
|
isDragging: boolean;
|
|
20
23
|
}
|
|
21
24
|
/** 元素的 key 到次序的映射 */
|
|
22
|
-
export type DraggableGridKeyToOrder = Map<
|
|
25
|
+
export type DraggableGridKeyToOrder<K extends Key> = Map<K, number>;
|
|
23
26
|
/** 次序到元素的 key 的映射 */
|
|
24
|
-
export type DraggableGridOrderToKey = Map<number,
|
|
25
|
-
export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "children"> & {
|
|
27
|
+
export type DraggableGridOrderToKey<K extends Key> = Map<number, K>;
|
|
28
|
+
export type DraggableGridProps<T, K extends Key = T extends Key ? T : never> = Omit<ComponentProps<"div">, "className" | "children"> & DragMoveEvents<HTMLDivElement> & {
|
|
26
29
|
/** 类名 */
|
|
27
30
|
className?: DraggableGridClassName;
|
|
28
31
|
/** 类名 */
|
|
@@ -57,26 +60,28 @@ export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "c
|
|
|
57
60
|
/** 元素高度 */
|
|
58
61
|
itemHeight: number;
|
|
59
62
|
/** 元素的 key 到次序的映射 */
|
|
60
|
-
orderMap?: DraggableGridKeyToOrder
|
|
63
|
+
orderMap?: DraggableGridKeyToOrder<K>;
|
|
61
64
|
/** 次序变化时回调 */
|
|
62
|
-
onOrderMapChange?: (orderMap: DraggableGridKeyToOrder) => void;
|
|
65
|
+
onOrderMapChange?: (orderMap: DraggableGridKeyToOrder<K>) => void;
|
|
63
66
|
/** 禁用的元素 */
|
|
64
|
-
isItemDisabled?:
|
|
67
|
+
isItemDisabled?: K[] | ((item: T, key: K) => boolean);
|
|
65
68
|
/** 禁用的次序 */
|
|
66
69
|
isOrderDisabled?: number[] | ((order: number) => boolean);
|
|
67
70
|
/** 次序的优先级,可以通过此函数调整元素的优先放置的方向,左上,右上,左下,右下,中心,顺时针,逆时针等等 */
|
|
68
71
|
orderPriority?: (a: number, b: number) => number;
|
|
69
|
-
|
|
72
|
+
/** 触发移动的元素 */
|
|
73
|
+
handle?: string | HTMLElement | ((item: T, key: K, element: HTMLDivElement) => HTMLElement | undefined | null) | undefined | null;
|
|
74
|
+
} & (MustBeReactNode<T> extends true ? {
|
|
70
75
|
/** 渲染函数,当 T 为 ReactNode 时,render 为可选 */
|
|
71
76
|
render?: (item: T, status: DraggableGridItemStatus) => ReactNode;
|
|
72
77
|
} : {
|
|
73
78
|
/** 渲染函数,当 T 为 ReactNode 时,render 为可选 */
|
|
74
79
|
render: (item: T, status: DraggableGridItemStatus) => ReactNode;
|
|
75
|
-
}) & (T extends
|
|
80
|
+
}) & (MustBeReactKey<T> extends true ? {
|
|
76
81
|
/** 获取 key 的函数,当 T 为 Key 时,keyExtractor 为可选 */
|
|
77
|
-
keyExtractor?: (item: T) =>
|
|
82
|
+
keyExtractor?: (item: T) => K;
|
|
78
83
|
} : {
|
|
79
84
|
/** 获取 key 的函数,当 T 为 Key 时,keyExtractor 为可选 */
|
|
80
|
-
keyExtractor: (item: T) =>
|
|
85
|
+
keyExtractor: (item: T) => K;
|
|
81
86
|
});
|
|
82
|
-
export declare function DraggableGrid<T>({ className, classNames, style, items, disabled, columns, rows, gap, gapX, gapY, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled: _isItemDisabled, isOrderDisabled, orderPriority, ...rest }: DraggableGridProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
87
|
+
export declare function DraggableGrid<T, K extends Key = T extends Key ? T : never>({ className, classNames, style, items, disabled, columns, rows, gap, gapX, gapY, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled: _isItemDisabled, isOrderDisabled, orderPriority, handle, onDragMoveStart: _onDragMoveStart, onDragMove: _onDragMove, onDragMoveEnd: _onDragMoveEnd, ...rest }: DraggableGridProps<T, K>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { clsx, getArray } from "deepsea-tools";
|
|
3
|
+
import { clsx, getArray, isNullable } from "deepsea-tools";
|
|
4
4
|
import { useDragMove } from "soda-hooks";
|
|
5
5
|
import DraggableGrid_module from "./DraggableGrid.module.js";
|
|
6
6
|
function isTheSameArray(a, b) {
|
|
@@ -45,10 +45,10 @@ function getOrderToKey(keyToOrder) {
|
|
|
45
45
|
key
|
|
46
46
|
]));
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
function DraggableGridItem({ item, itemKey, handle, onDragMoveStart, onDragMove, onDragMoveEnd, ...rest }) {
|
|
49
49
|
const element = useRef(null);
|
|
50
50
|
useDragMove({
|
|
51
|
-
element,
|
|
51
|
+
element: isNullable(handle) ? element : ()=>element.current && ("string" == typeof handle ? element.current.querySelector(handle) : "function" == typeof handle ? handle(item, itemKey, element.current) : handle),
|
|
52
52
|
onDragMoveStart,
|
|
53
53
|
onDragMove,
|
|
54
54
|
onDragMoveEnd
|
|
@@ -57,8 +57,8 @@ const DraggableGridItem = ({ onDragMoveStart, onDragMove, onDragMoveEnd, ...rest
|
|
|
57
57
|
ref: element,
|
|
58
58
|
...rest
|
|
59
59
|
});
|
|
60
|
-
}
|
|
61
|
-
function DraggableGrid({ className, classNames, style, items = [], disabled, columns, rows, gap = 0, gapX = gap, gapY = gap, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled: _isItemDisabled, isOrderDisabled, orderPriority, ...rest }) {
|
|
60
|
+
}
|
|
61
|
+
function DraggableGrid({ className, classNames, style, items = [], disabled, columns, rows, gap = 0, gapX = gap, gapY = gap, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled: _isItemDisabled, isOrderDisabled, orderPriority, handle, onDragMoveStart: _onDragMoveStart, onDragMove: _onDragMove, onDragMoveEnd: _onDragMoveEnd, ...rest }) {
|
|
62
62
|
const keyToItem = useMemo(()=>{
|
|
63
63
|
const keyToItem = new Map();
|
|
64
64
|
items.forEach((item)=>{
|
|
@@ -152,6 +152,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
152
152
|
onOrderMapChange
|
|
153
153
|
]);
|
|
154
154
|
function onDragMoveStart(key, event) {
|
|
155
|
+
_onDragMoveStart?.(event);
|
|
155
156
|
const position = getPosition({
|
|
156
157
|
order: keyToOrder.get(key),
|
|
157
158
|
columns,
|
|
@@ -178,6 +179,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
178
179
|
});
|
|
179
180
|
}
|
|
180
181
|
function onDragMove(event) {
|
|
182
|
+
_onDragMove?.(event);
|
|
181
183
|
if (!dragging) return;
|
|
182
184
|
const { deltaX, deltaY } = event;
|
|
183
185
|
const { key, orders, keyToOrder, startX, startY, columns, gapX, gapY, itemWidth, itemHeight } = dragging;
|
|
@@ -243,7 +245,8 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
243
245
|
setKeyToOrder(newKeyToOrder);
|
|
244
246
|
onOrderMapChange?.(newKeyToOrder);
|
|
245
247
|
}
|
|
246
|
-
function onDragMoveEnd() {
|
|
248
|
+
function onDragMoveEnd(event) {
|
|
249
|
+
_onDragMoveEnd?.(event);
|
|
247
250
|
if (!dragging) return;
|
|
248
251
|
setDragging(void 0);
|
|
249
252
|
}
|
|
@@ -298,6 +301,9 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
298
301
|
isDragging: isDragging
|
|
299
302
|
}) : item;
|
|
300
303
|
return /*#__PURE__*/ jsx(DraggableGridItem, {
|
|
304
|
+
item: item,
|
|
305
|
+
itemKey: key,
|
|
306
|
+
handle: handle,
|
|
301
307
|
className: clsx(DraggableGrid_module.draggableGridItem, "function" == typeof classNames?.item ? classNames.item({
|
|
302
308
|
order,
|
|
303
309
|
isDragging: isDragging
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepsea-components",
|
|
3
|
-
"version": "5.16.
|
|
3
|
+
"version": "5.16.4",
|
|
4
4
|
"description": "格数科技自用组件库",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"echarts": "^5.6.0",
|
|
41
41
|
"hls.js": "^1.6.9",
|
|
42
42
|
"smooth-scrollbar": "^8.8.4",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
43
|
+
"deepsea-tools": "5.41.0",
|
|
44
|
+
"soda-hooks": "6.13.4"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"typescript": "^5.9.2"
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { CSSProperties, ComponentProps,
|
|
2
|
-
import { clsx, getArray } from "deepsea-tools"
|
|
3
|
-
import { DragMoveEvent,
|
|
1
|
+
import { CSSProperties, ComponentProps, Key, ReactNode, useEffect, useMemo, useRef, useState } from "react"
|
|
2
|
+
import { clsx, getArray, isNullable } from "deepsea-tools"
|
|
3
|
+
import { DragMoveEvent, DragMoveEvents, useDragMove } from "soda-hooks"
|
|
4
4
|
|
|
5
5
|
import styles from "./DraggableGrid.module.css"
|
|
6
6
|
|
|
7
|
+
export type MustBeReactNode<T> = false extends (T extends ReactNode ? true : false) ? false : true
|
|
8
|
+
|
|
9
|
+
export type MustBeReactKey<T> = false extends (T extends Key ? true : false) ? false : true
|
|
10
|
+
|
|
7
11
|
export type DraggableGridClassName = string | ((status: ContainerStatus) => string)
|
|
8
12
|
|
|
9
13
|
export type DraggableGridItemClassName = string | ((status: DraggableGridItemStatus) => string)
|
|
@@ -30,10 +34,10 @@ export interface DraggableGridItemStatus {
|
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
/** 元素的 key 到次序的映射 */
|
|
33
|
-
export type DraggableGridKeyToOrder = Map<
|
|
37
|
+
export type DraggableGridKeyToOrder<K extends Key> = Map<K, number>
|
|
34
38
|
|
|
35
39
|
/** 次序到元素的 key 的映射 */
|
|
36
|
-
export type DraggableGridOrderToKey = Map<number,
|
|
40
|
+
export type DraggableGridOrderToKey<K extends Key> = Map<number, K>
|
|
37
41
|
|
|
38
42
|
function isTheSameArray<T>(a: T[], b: T[]) {
|
|
39
43
|
if (a.length !== b.length) return false
|
|
@@ -50,15 +54,15 @@ function isTheSameIterable<T>(a: Iterable<T>, b: Iterable<T>) {
|
|
|
50
54
|
return aSet.difference(bSet).size === 0
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
interface GetOrderMapParams {
|
|
54
|
-
prev?: DraggableGridKeyToOrder
|
|
57
|
+
interface GetOrderMapParams<K extends Key> {
|
|
58
|
+
prev?: DraggableGridKeyToOrder<K>
|
|
55
59
|
orders: number[]
|
|
56
|
-
keys:
|
|
60
|
+
keys: K[]
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
function getOrderMap({ prev, orders, keys }: GetOrderMapParams) {
|
|
63
|
+
function getOrderMap<K extends Key>({ prev, orders, keys }: GetOrderMapParams<K>) {
|
|
60
64
|
const orderSet = new Set(orders)
|
|
61
|
-
const orderMap = new Map<
|
|
65
|
+
const orderMap = new Map<K, number>()
|
|
62
66
|
const newKeys = keys.filter(key => {
|
|
63
67
|
if (!prev) return true
|
|
64
68
|
if (prev.has(key)) {
|
|
@@ -97,55 +101,58 @@ function getPosition({ order, columns, gapX, gapY, itemWidth, itemHeight }: GetP
|
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
|
|
100
|
-
function getOrderToKey(keyToOrder: DraggableGridKeyToOrder) {
|
|
104
|
+
function getOrderToKey<K extends Key>(keyToOrder: DraggableGridKeyToOrder<K>) {
|
|
101
105
|
return new Map(Array.from(keyToOrder.entries()).map(([key, order]) => [order, key]))
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "children"> &
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
108
|
+
export type DraggableGridProps<T, K extends Key = T extends Key ? T : never> = Omit<ComponentProps<"div">, "className" | "children"> &
|
|
109
|
+
DragMoveEvents<HTMLDivElement> & {
|
|
110
|
+
/** 类名 */
|
|
111
|
+
className?: DraggableGridClassName
|
|
112
|
+
/** 类名 */
|
|
113
|
+
classNames?: DraggableGridClassNames
|
|
114
|
+
/** 样式 */
|
|
115
|
+
style?: DraggableGridStyle
|
|
116
|
+
/** 数据源 */
|
|
117
|
+
items?: T[]
|
|
118
|
+
/** 是否禁用拖拽 */
|
|
119
|
+
disabled?: boolean
|
|
120
|
+
/** 列数 */
|
|
121
|
+
columns: number
|
|
122
|
+
/** 行数 */
|
|
123
|
+
rows: number
|
|
124
|
+
/**
|
|
125
|
+
* 间距
|
|
126
|
+
* @default 0
|
|
127
|
+
*/
|
|
128
|
+
gap?: number
|
|
129
|
+
/**
|
|
130
|
+
* 水平间距
|
|
131
|
+
* @default 0
|
|
132
|
+
*/
|
|
133
|
+
gapX?: number
|
|
134
|
+
/**
|
|
135
|
+
* 垂直间距
|
|
136
|
+
* @default 0
|
|
137
|
+
*/
|
|
138
|
+
gapY?: number
|
|
139
|
+
/** 元素宽度 */
|
|
140
|
+
itemWidth: number
|
|
141
|
+
/** 元素高度 */
|
|
142
|
+
itemHeight: number
|
|
143
|
+
/** 元素的 key 到次序的映射 */
|
|
144
|
+
orderMap?: DraggableGridKeyToOrder<K>
|
|
145
|
+
/** 次序变化时回调 */
|
|
146
|
+
onOrderMapChange?: (orderMap: DraggableGridKeyToOrder<K>) => void
|
|
147
|
+
/** 禁用的元素 */
|
|
148
|
+
isItemDisabled?: K[] | ((item: T, key: K) => boolean)
|
|
149
|
+
/** 禁用的次序 */
|
|
150
|
+
isOrderDisabled?: number[] | ((order: number) => boolean)
|
|
151
|
+
/** 次序的优先级,可以通过此函数调整元素的优先放置的方向,左上,右上,左下,右下,中心,顺时针,逆时针等等 */
|
|
152
|
+
orderPriority?: (a: number, b: number) => number
|
|
153
|
+
/** 触发移动的元素 */
|
|
154
|
+
handle?: string | HTMLElement | ((item: T, key: K, element: HTMLDivElement) => HTMLElement | undefined | null) | undefined | null
|
|
155
|
+
} & (MustBeReactNode<T> extends true
|
|
149
156
|
? {
|
|
150
157
|
/** 渲染函数,当 T 为 ReactNode 时,render 为可选 */
|
|
151
158
|
render?: (item: T, status: DraggableGridItemStatus) => ReactNode
|
|
@@ -154,23 +161,44 @@ export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "c
|
|
|
154
161
|
/** 渲染函数,当 T 为 ReactNode 时,render 为可选 */
|
|
155
162
|
render: (item: T, status: DraggableGridItemStatus) => ReactNode
|
|
156
163
|
}) &
|
|
157
|
-
(T extends
|
|
164
|
+
(MustBeReactKey<T> extends true
|
|
158
165
|
? {
|
|
159
166
|
/** 获取 key 的函数,当 T 为 Key 时,keyExtractor 为可选 */
|
|
160
|
-
keyExtractor?: (item: T) =>
|
|
167
|
+
keyExtractor?: (item: T) => K
|
|
161
168
|
}
|
|
162
169
|
: {
|
|
163
170
|
/** 获取 key 的函数,当 T 为 Key 时,keyExtractor 为可选 */
|
|
164
|
-
keyExtractor: (item: T) =>
|
|
171
|
+
keyExtractor: (item: T) => K
|
|
165
172
|
})
|
|
166
173
|
|
|
167
|
-
interface DraggableGridItemProps extends ComponentProps<"div">,
|
|
174
|
+
interface DraggableGridItemProps<T, K extends Key = T extends Key ? T : never> extends ComponentProps<"div">, DragMoveEvents<HTMLDivElement> {
|
|
175
|
+
item: T
|
|
176
|
+
itemKey: K
|
|
177
|
+
/** 触发移动的元素 */
|
|
178
|
+
handle?: string | HTMLElement | ((item: T, key: K, element: HTMLDivElement) => HTMLElement | undefined | null) | undefined | null
|
|
179
|
+
}
|
|
168
180
|
|
|
169
|
-
|
|
181
|
+
function DraggableGridItem<T, K extends Key = T extends Key ? T : never>({
|
|
182
|
+
item,
|
|
183
|
+
itemKey,
|
|
184
|
+
handle,
|
|
185
|
+
onDragMoveStart,
|
|
186
|
+
onDragMove,
|
|
187
|
+
onDragMoveEnd,
|
|
188
|
+
...rest
|
|
189
|
+
}: DraggableGridItemProps<T, K>) {
|
|
170
190
|
const element = useRef<HTMLDivElement>(null)
|
|
171
191
|
|
|
172
192
|
useDragMove({
|
|
173
|
-
element
|
|
193
|
+
element: isNullable(handle)
|
|
194
|
+
? element
|
|
195
|
+
: () =>
|
|
196
|
+
element.current &&
|
|
197
|
+
(typeof handle === "string"
|
|
198
|
+
? (element.current.querySelector(handle) as HTMLElement)
|
|
199
|
+
: typeof handle === "function"
|
|
200
|
+
? handle(item, itemKey, element.current)
|
|
201
|
+
: handle),
|
|
174
202
|
onDragMoveStart,
|
|
175
203
|
onDragMove,
|
|
176
204
|
onDragMoveEnd,
|
|
@@ -179,8 +207,8 @@ const DraggableGridItem: FC<DraggableGridItemProps> = ({ onDragMoveStart, onDrag
|
|
|
179
207
|
return <div ref={element} {...rest} />
|
|
180
208
|
}
|
|
181
209
|
|
|
182
|
-
interface DraggingItem {
|
|
183
|
-
key:
|
|
210
|
+
interface DraggingItem<K extends Key> {
|
|
211
|
+
key: K
|
|
184
212
|
startX: number
|
|
185
213
|
startY: number
|
|
186
214
|
deltaX: number
|
|
@@ -192,10 +220,10 @@ interface DraggingItem {
|
|
|
192
220
|
gapY: number
|
|
193
221
|
itemWidth: number
|
|
194
222
|
itemHeight: number
|
|
195
|
-
keyToOrder: DraggableGridKeyToOrder
|
|
223
|
+
keyToOrder: DraggableGridKeyToOrder<K>
|
|
196
224
|
}
|
|
197
225
|
|
|
198
|
-
export function DraggableGrid<T>({
|
|
226
|
+
export function DraggableGrid<T, K extends Key = T extends Key ? T : never>({
|
|
199
227
|
className,
|
|
200
228
|
classNames,
|
|
201
229
|
style,
|
|
@@ -215,12 +243,16 @@ export function DraggableGrid<T>({
|
|
|
215
243
|
isItemDisabled: _isItemDisabled,
|
|
216
244
|
isOrderDisabled,
|
|
217
245
|
orderPriority,
|
|
246
|
+
handle,
|
|
247
|
+
onDragMoveStart: _onDragMoveStart,
|
|
248
|
+
onDragMove: _onDragMove,
|
|
249
|
+
onDragMoveEnd: _onDragMoveEnd,
|
|
218
250
|
...rest
|
|
219
|
-
}: DraggableGridProps<T>) {
|
|
251
|
+
}: DraggableGridProps<T, K>) {
|
|
220
252
|
const keyToItem = useMemo(() => {
|
|
221
|
-
const keyToItem = new Map<
|
|
253
|
+
const keyToItem = new Map<K, T>()
|
|
222
254
|
items.forEach(item => {
|
|
223
|
-
const key = keyExtractor ? keyExtractor(item) : (item as
|
|
255
|
+
const key = keyExtractor ? keyExtractor(item) : (item as unknown as K)
|
|
224
256
|
keyToItem.set(key, item)
|
|
225
257
|
})
|
|
226
258
|
return keyToItem
|
|
@@ -249,7 +281,7 @@ export function DraggableGrid<T>({
|
|
|
249
281
|
})
|
|
250
282
|
|
|
251
283
|
/** 拖拽中的元素 */
|
|
252
|
-
const [dragging, setDragging] = useState<DraggingItem | undefined>(undefined)
|
|
284
|
+
const [dragging, setDragging] = useState<DraggingItem<K> | undefined>(undefined)
|
|
253
285
|
|
|
254
286
|
const { current: cache } = useRef({
|
|
255
287
|
orders,
|
|
@@ -301,7 +333,8 @@ export function DraggableGrid<T>({
|
|
|
301
333
|
else onOrderMapChange?.(keyToOrder)
|
|
302
334
|
}, [orderMap, keyToOrder, onOrderMapChange])
|
|
303
335
|
|
|
304
|
-
function onDragMoveStart(key:
|
|
336
|
+
function onDragMoveStart(key: K, event: DragMoveEvent<HTMLDivElement>) {
|
|
337
|
+
_onDragMoveStart?.(event)
|
|
305
338
|
const position = getPosition({ order: keyToOrder.get(key)!, columns, gapX, gapY, itemWidth, itemHeight })
|
|
306
339
|
recent.current = key
|
|
307
340
|
setDragging({
|
|
@@ -322,6 +355,7 @@ export function DraggableGrid<T>({
|
|
|
322
355
|
}
|
|
323
356
|
|
|
324
357
|
function onDragMove(event: DragMoveEvent<HTMLDivElement>) {
|
|
358
|
+
_onDragMove?.(event)
|
|
325
359
|
if (!dragging) return
|
|
326
360
|
|
|
327
361
|
const { deltaX, deltaY } = event
|
|
@@ -395,12 +429,13 @@ export function DraggableGrid<T>({
|
|
|
395
429
|
onOrderMapChange?.(newKeyToOrder)
|
|
396
430
|
}
|
|
397
431
|
|
|
398
|
-
function onDragMoveEnd() {
|
|
432
|
+
function onDragMoveEnd(event: DragMoveEvent<HTMLDivElement>) {
|
|
433
|
+
_onDragMoveEnd?.(event)
|
|
399
434
|
if (!dragging) return
|
|
400
435
|
setDragging(undefined)
|
|
401
436
|
}
|
|
402
437
|
|
|
403
|
-
function isItemDisabled(key:
|
|
438
|
+
function isItemDisabled(key: K) {
|
|
404
439
|
if (!_isItemDisabled) return false
|
|
405
440
|
if (Array.isArray(_isItemDisabled)) return _isItemDisabled.includes(key)
|
|
406
441
|
return _isItemDisabled(keyToItem.get(key)!, key)
|
|
@@ -451,6 +486,9 @@ export function DraggableGrid<T>({
|
|
|
451
486
|
return (
|
|
452
487
|
<DraggableGridItem
|
|
453
488
|
key={key}
|
|
489
|
+
item={item}
|
|
490
|
+
itemKey={key}
|
|
491
|
+
handle={handle}
|
|
454
492
|
className={clsx(
|
|
455
493
|
styles.draggableGridItem,
|
|
456
494
|
typeof classNames?.item === "function" ? classNames.item({ order, isDragging: isDragging }) : classNames?.item,
|