deepsea-components 5.16.1 → 5.16.3
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.
|
@@ -63,6 +63,7 @@ function getOrderMap({ prev, orders, keys }) {
|
|
|
63
63
|
orderSet.delete(prevOrder);
|
|
64
64
|
return false;
|
|
65
65
|
}
|
|
66
|
+
return true;
|
|
66
67
|
});
|
|
67
68
|
orders = Array.from(orderSet);
|
|
68
69
|
newKeys.forEach((key, index)=>orderMap.set(key, orders[index]));
|
|
@@ -82,10 +83,10 @@ function getOrderToKey(keyToOrder) {
|
|
|
82
83
|
key
|
|
83
84
|
]));
|
|
84
85
|
}
|
|
85
|
-
|
|
86
|
+
function DraggableGridItem({ item, itemKey, handle, onDragMoveStart, onDragMove, onDragMoveEnd, ...rest }) {
|
|
86
87
|
const element = (0, external_react_namespaceObject.useRef)(null);
|
|
87
88
|
(0, external_soda_hooks_namespaceObject.useDragMove)({
|
|
88
|
-
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),
|
|
89
90
|
onDragMoveStart,
|
|
90
91
|
onDragMove,
|
|
91
92
|
onDragMoveEnd
|
|
@@ -94,20 +95,15 @@ const DraggableGridItem = ({ onDragMoveStart, onDragMove, onDragMoveEnd, ...rest
|
|
|
94
95
|
ref: element,
|
|
95
96
|
...rest
|
|
96
97
|
});
|
|
97
|
-
}
|
|
98
|
-
function DraggableGrid({ className, classNames, style, items = [], disabled, columns, rows, gap = 0, gapX = gap, gapY = gap, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled, isOrderDisabled, orderPriority, ...rest }) {
|
|
99
|
-
const
|
|
100
|
-
const itemToKey = new Map();
|
|
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
|
+
const keyToItem = (0, external_react_namespaceObject.useMemo)(()=>{
|
|
101
101
|
const keyToItem = new Map();
|
|
102
|
-
items.forEach((item
|
|
102
|
+
items.forEach((item)=>{
|
|
103
103
|
const key = keyExtractor ? keyExtractor(item) : item;
|
|
104
|
-
itemToKey.set(item, key);
|
|
105
104
|
keyToItem.set(key, item);
|
|
106
105
|
});
|
|
107
|
-
return
|
|
108
|
-
itemToKey,
|
|
109
|
-
keyToItem
|
|
110
|
-
];
|
|
106
|
+
return keyToItem;
|
|
111
107
|
}, [
|
|
112
108
|
items,
|
|
113
109
|
keyExtractor
|
|
@@ -140,11 +136,11 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
140
136
|
keys: Array.from(keyToItem.keys())
|
|
141
137
|
});
|
|
142
138
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
143
|
-
if (!isTheSameArray(cache.orders, orders) || !isTheSameIterable(cache.keys, keyToItem.keys())) {
|
|
139
|
+
if (!isTheSameArray(dragging?.orders ?? cache.orders, orders) || !isTheSameIterable(dragging?.keyToOrder.keys() ?? cache.keys, keyToItem.keys())) {
|
|
144
140
|
cache.orders = orders;
|
|
145
|
-
cache.keys = Array.from(keyToItem.keys());
|
|
141
|
+
cache.keys = Array.from((dragging?.keyToOrder ?? keyToItem).keys());
|
|
146
142
|
const newOrderMap = getOrderMap({
|
|
147
|
-
prev: keyToOrder,
|
|
143
|
+
prev: dragging?.keyToOrder ?? keyToOrder,
|
|
148
144
|
orders,
|
|
149
145
|
keys: cache.keys
|
|
150
146
|
});
|
|
@@ -155,6 +151,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
155
151
|
}
|
|
156
152
|
}, [
|
|
157
153
|
dragging,
|
|
154
|
+
cache,
|
|
158
155
|
orders,
|
|
159
156
|
keyToItem,
|
|
160
157
|
keyToOrder,
|
|
@@ -171,7 +168,14 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
171
168
|
}
|
|
172
169
|
}
|
|
173
170
|
}, [
|
|
171
|
+
dragging,
|
|
174
172
|
orders,
|
|
173
|
+
columns,
|
|
174
|
+
rows,
|
|
175
|
+
gapX,
|
|
176
|
+
gapY,
|
|
177
|
+
itemWidth,
|
|
178
|
+
itemHeight,
|
|
175
179
|
keyToItem,
|
|
176
180
|
keyToOrder,
|
|
177
181
|
onOrderMapChange
|
|
@@ -186,6 +190,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
186
190
|
onOrderMapChange
|
|
187
191
|
]);
|
|
188
192
|
function onDragMoveStart(key, event) {
|
|
193
|
+
_onDragMoveStart?.(event);
|
|
189
194
|
const position = getPosition({
|
|
190
195
|
order: keyToOrder.get(key),
|
|
191
196
|
columns,
|
|
@@ -199,8 +204,8 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
199
204
|
key,
|
|
200
205
|
startX: position.x,
|
|
201
206
|
startY: position.y,
|
|
202
|
-
deltaX:
|
|
203
|
-
deltaY:
|
|
207
|
+
deltaX: event.deltaX,
|
|
208
|
+
deltaY: event.deltaY,
|
|
204
209
|
orders,
|
|
205
210
|
columns,
|
|
206
211
|
rows,
|
|
@@ -212,6 +217,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
212
217
|
});
|
|
213
218
|
}
|
|
214
219
|
function onDragMove(event) {
|
|
220
|
+
_onDragMove?.(event);
|
|
215
221
|
if (!dragging) return;
|
|
216
222
|
const { deltaX, deltaY } = event;
|
|
217
223
|
const { key, orders, keyToOrder, startX, startY, columns, gapX, gapY, itemWidth, itemHeight } = dragging;
|
|
@@ -277,10 +283,16 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
277
283
|
setKeyToOrder(newKeyToOrder);
|
|
278
284
|
onOrderMapChange?.(newKeyToOrder);
|
|
279
285
|
}
|
|
280
|
-
function onDragMoveEnd() {
|
|
286
|
+
function onDragMoveEnd(event) {
|
|
287
|
+
_onDragMoveEnd?.(event);
|
|
281
288
|
if (!dragging) return;
|
|
282
289
|
setDragging(void 0);
|
|
283
290
|
}
|
|
291
|
+
function isItemDisabled(key) {
|
|
292
|
+
if (!_isItemDisabled) return false;
|
|
293
|
+
if (Array.isArray(_isItemDisabled)) return _isItemDisabled.includes(key);
|
|
294
|
+
return _isItemDisabled(keyToItem.get(key), key);
|
|
295
|
+
}
|
|
284
296
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
285
297
|
className: (0, external_deepsea_tools_namespaceObject.clsx)(external_DraggableGrid_module_cjs_default().draggableGrid, "function" == typeof className ? className({
|
|
286
298
|
isDragging: !!dragging
|
|
@@ -327,14 +339,17 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
327
339
|
isDragging: isDragging
|
|
328
340
|
}) : item;
|
|
329
341
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(DraggableGridItem, {
|
|
342
|
+
item: item,
|
|
343
|
+
itemKey: key,
|
|
344
|
+
handle: handle,
|
|
330
345
|
className: (0, external_deepsea_tools_namespaceObject.clsx)(external_DraggableGrid_module_cjs_default().draggableGridItem, "function" == typeof classNames?.item ? classNames.item({
|
|
331
346
|
order,
|
|
332
347
|
isDragging: isDragging
|
|
333
348
|
}) : classNames?.item),
|
|
334
349
|
style: style,
|
|
335
|
-
onDragMoveStart: disabled ? void 0 : (event)=>onDragMoveStart(key, event),
|
|
336
|
-
onDragMove: disabled ? void 0 : onDragMove,
|
|
337
|
-
onDragMoveEnd: disabled ? void 0 : onDragMoveEnd,
|
|
350
|
+
onDragMoveStart: disabled || isItemDisabled(key) ? void 0 : (event)=>onDragMoveStart(key, event),
|
|
351
|
+
onDragMove: disabled || isItemDisabled(key) ? void 0 : onDragMove,
|
|
352
|
+
onDragMoveEnd: disabled || isItemDisabled(key) ? void 0 : onDragMoveEnd,
|
|
338
353
|
children: children
|
|
339
354
|
}, key);
|
|
340
355
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CSSProperties, ComponentProps, Key, ReactNode } from "react";
|
|
2
|
+
import { DragMoveEvents } from "soda-hooks";
|
|
2
3
|
export type DraggableGridClassName = string | ((status: ContainerStatus) => string);
|
|
3
4
|
export type DraggableGridItemClassName = string | ((status: DraggableGridItemStatus) => string);
|
|
4
5
|
export type DraggableGridStyle = CSSProperties | ((status: ContainerStatus) => CSSProperties);
|
|
@@ -22,7 +23,7 @@ export interface DraggableGridItemStatus {
|
|
|
22
23
|
export type DraggableGridKeyToOrder = Map<Key, number>;
|
|
23
24
|
/** 次序到元素的 key 的映射 */
|
|
24
25
|
export type DraggableGridOrderToKey = Map<number, Key>;
|
|
25
|
-
export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "children"> & {
|
|
26
|
+
export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "children"> & DragMoveEvents<HTMLDivElement> & {
|
|
26
27
|
/** 类名 */
|
|
27
28
|
className?: DraggableGridClassName;
|
|
28
29
|
/** 类名 */
|
|
@@ -61,11 +62,13 @@ export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "c
|
|
|
61
62
|
/** 次序变化时回调 */
|
|
62
63
|
onOrderMapChange?: (orderMap: DraggableGridKeyToOrder) => void;
|
|
63
64
|
/** 禁用的元素 */
|
|
64
|
-
isItemDisabled?: Key[] | ((item: T) => boolean);
|
|
65
|
+
isItemDisabled?: Key[] | ((item: T, key: Key) => boolean);
|
|
65
66
|
/** 禁用的次序 */
|
|
66
67
|
isOrderDisabled?: number[] | ((order: number) => boolean);
|
|
67
68
|
/** 次序的优先级,可以通过此函数调整元素的优先放置的方向,左上,右上,左下,右下,中心,顺时针,逆时针等等 */
|
|
68
69
|
orderPriority?: (a: number, b: number) => number;
|
|
70
|
+
/** 触发移动的元素 */
|
|
71
|
+
handle?: string | HTMLElement | ((item: T, key: Key, element: HTMLDivElement) => HTMLElement | undefined | null) | undefined | null;
|
|
69
72
|
} & (T extends ReactNode ? {
|
|
70
73
|
/** 渲染函数,当 T 为 ReactNode 时,render 为可选 */
|
|
71
74
|
render?: (item: T, status: DraggableGridItemStatus) => ReactNode;
|
|
@@ -79,4 +82,4 @@ export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "c
|
|
|
79
82
|
/** 获取 key 的函数,当 T 为 Key 时,keyExtractor 为可选 */
|
|
80
83
|
keyExtractor: (item: T) => Key;
|
|
81
84
|
});
|
|
82
|
-
export declare function DraggableGrid<T>({ className, classNames, style, items, disabled, columns, rows, gap, gapX, gapY, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled, isOrderDisabled, orderPriority, ...rest }: DraggableGridProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
85
|
+
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, handle, onDragMoveStart: _onDragMoveStart, onDragMove: _onDragMove, onDragMoveEnd: _onDragMoveEnd, ...rest }: DraggableGridProps<T>): 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) {
|
|
@@ -25,6 +25,7 @@ function getOrderMap({ prev, orders, keys }) {
|
|
|
25
25
|
orderSet.delete(prevOrder);
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
|
+
return true;
|
|
28
29
|
});
|
|
29
30
|
orders = Array.from(orderSet);
|
|
30
31
|
newKeys.forEach((key, index)=>orderMap.set(key, orders[index]));
|
|
@@ -44,10 +45,10 @@ function getOrderToKey(keyToOrder) {
|
|
|
44
45
|
key
|
|
45
46
|
]));
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
function DraggableGridItem({ item, itemKey, handle, onDragMoveStart, onDragMove, onDragMoveEnd, ...rest }) {
|
|
48
49
|
const element = useRef(null);
|
|
49
50
|
useDragMove({
|
|
50
|
-
element,
|
|
51
|
+
element: isNullable(handle) ? element : ()=>element.current && ("string" == typeof handle ? element.current.querySelector(handle) : "function" == typeof handle ? handle(item, itemKey, element.current) : handle),
|
|
51
52
|
onDragMoveStart,
|
|
52
53
|
onDragMove,
|
|
53
54
|
onDragMoveEnd
|
|
@@ -56,20 +57,15 @@ const DraggableGridItem = ({ onDragMoveStart, onDragMove, onDragMoveEnd, ...rest
|
|
|
56
57
|
ref: element,
|
|
57
58
|
...rest
|
|
58
59
|
});
|
|
59
|
-
}
|
|
60
|
-
function DraggableGrid({ className, classNames, style, items = [], disabled, columns, rows, gap = 0, gapX = gap, gapY = gap, itemWidth, itemHeight, orderMap, onOrderMapChange, render, keyExtractor, isItemDisabled, isOrderDisabled, orderPriority, ...rest }) {
|
|
61
|
-
const
|
|
62
|
-
const itemToKey = new Map();
|
|
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
|
+
const keyToItem = useMemo(()=>{
|
|
63
63
|
const keyToItem = new Map();
|
|
64
|
-
items.forEach((item
|
|
64
|
+
items.forEach((item)=>{
|
|
65
65
|
const key = keyExtractor ? keyExtractor(item) : item;
|
|
66
|
-
itemToKey.set(item, key);
|
|
67
66
|
keyToItem.set(key, item);
|
|
68
67
|
});
|
|
69
|
-
return
|
|
70
|
-
itemToKey,
|
|
71
|
-
keyToItem
|
|
72
|
-
];
|
|
68
|
+
return keyToItem;
|
|
73
69
|
}, [
|
|
74
70
|
items,
|
|
75
71
|
keyExtractor
|
|
@@ -102,11 +98,11 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
102
98
|
keys: Array.from(keyToItem.keys())
|
|
103
99
|
});
|
|
104
100
|
useEffect(()=>{
|
|
105
|
-
if (!isTheSameArray(cache.orders, orders) || !isTheSameIterable(cache.keys, keyToItem.keys())) {
|
|
101
|
+
if (!isTheSameArray(dragging?.orders ?? cache.orders, orders) || !isTheSameIterable(dragging?.keyToOrder.keys() ?? cache.keys, keyToItem.keys())) {
|
|
106
102
|
cache.orders = orders;
|
|
107
|
-
cache.keys = Array.from(keyToItem.keys());
|
|
103
|
+
cache.keys = Array.from((dragging?.keyToOrder ?? keyToItem).keys());
|
|
108
104
|
const newOrderMap = getOrderMap({
|
|
109
|
-
prev: keyToOrder,
|
|
105
|
+
prev: dragging?.keyToOrder ?? keyToOrder,
|
|
110
106
|
orders,
|
|
111
107
|
keys: cache.keys
|
|
112
108
|
});
|
|
@@ -117,6 +113,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
117
113
|
}
|
|
118
114
|
}, [
|
|
119
115
|
dragging,
|
|
116
|
+
cache,
|
|
120
117
|
orders,
|
|
121
118
|
keyToItem,
|
|
122
119
|
keyToOrder,
|
|
@@ -133,7 +130,14 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
133
130
|
}
|
|
134
131
|
}
|
|
135
132
|
}, [
|
|
133
|
+
dragging,
|
|
136
134
|
orders,
|
|
135
|
+
columns,
|
|
136
|
+
rows,
|
|
137
|
+
gapX,
|
|
138
|
+
gapY,
|
|
139
|
+
itemWidth,
|
|
140
|
+
itemHeight,
|
|
137
141
|
keyToItem,
|
|
138
142
|
keyToOrder,
|
|
139
143
|
onOrderMapChange
|
|
@@ -148,6 +152,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
148
152
|
onOrderMapChange
|
|
149
153
|
]);
|
|
150
154
|
function onDragMoveStart(key, event) {
|
|
155
|
+
_onDragMoveStart?.(event);
|
|
151
156
|
const position = getPosition({
|
|
152
157
|
order: keyToOrder.get(key),
|
|
153
158
|
columns,
|
|
@@ -161,8 +166,8 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
161
166
|
key,
|
|
162
167
|
startX: position.x,
|
|
163
168
|
startY: position.y,
|
|
164
|
-
deltaX:
|
|
165
|
-
deltaY:
|
|
169
|
+
deltaX: event.deltaX,
|
|
170
|
+
deltaY: event.deltaY,
|
|
166
171
|
orders,
|
|
167
172
|
columns,
|
|
168
173
|
rows,
|
|
@@ -174,6 +179,7 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
174
179
|
});
|
|
175
180
|
}
|
|
176
181
|
function onDragMove(event) {
|
|
182
|
+
_onDragMove?.(event);
|
|
177
183
|
if (!dragging) return;
|
|
178
184
|
const { deltaX, deltaY } = event;
|
|
179
185
|
const { key, orders, keyToOrder, startX, startY, columns, gapX, gapY, itemWidth, itemHeight } = dragging;
|
|
@@ -239,10 +245,16 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
239
245
|
setKeyToOrder(newKeyToOrder);
|
|
240
246
|
onOrderMapChange?.(newKeyToOrder);
|
|
241
247
|
}
|
|
242
|
-
function onDragMoveEnd() {
|
|
248
|
+
function onDragMoveEnd(event) {
|
|
249
|
+
_onDragMoveEnd?.(event);
|
|
243
250
|
if (!dragging) return;
|
|
244
251
|
setDragging(void 0);
|
|
245
252
|
}
|
|
253
|
+
function isItemDisabled(key) {
|
|
254
|
+
if (!_isItemDisabled) return false;
|
|
255
|
+
if (Array.isArray(_isItemDisabled)) return _isItemDisabled.includes(key);
|
|
256
|
+
return _isItemDisabled(keyToItem.get(key), key);
|
|
257
|
+
}
|
|
246
258
|
return /*#__PURE__*/ jsx("div", {
|
|
247
259
|
className: clsx(DraggableGrid_module.draggableGrid, "function" == typeof className ? className({
|
|
248
260
|
isDragging: !!dragging
|
|
@@ -289,14 +301,17 @@ function DraggableGrid({ className, classNames, style, items = [], disabled, col
|
|
|
289
301
|
isDragging: isDragging
|
|
290
302
|
}) : item;
|
|
291
303
|
return /*#__PURE__*/ jsx(DraggableGridItem, {
|
|
304
|
+
item: item,
|
|
305
|
+
itemKey: key,
|
|
306
|
+
handle: handle,
|
|
292
307
|
className: clsx(DraggableGrid_module.draggableGridItem, "function" == typeof classNames?.item ? classNames.item({
|
|
293
308
|
order,
|
|
294
309
|
isDragging: isDragging
|
|
295
310
|
}) : classNames?.item),
|
|
296
311
|
style: style,
|
|
297
|
-
onDragMoveStart: disabled ? void 0 : (event)=>onDragMoveStart(key, event),
|
|
298
|
-
onDragMove: disabled ? void 0 : onDragMove,
|
|
299
|
-
onDragMoveEnd: disabled ? void 0 : onDragMoveEnd,
|
|
312
|
+
onDragMoveStart: disabled || isItemDisabled(key) ? void 0 : (event)=>onDragMoveStart(key, event),
|
|
313
|
+
onDragMove: disabled || isItemDisabled(key) ? void 0 : onDragMove,
|
|
314
|
+
onDragMoveEnd: disabled || isItemDisabled(key) ? void 0 : onDragMoveEnd,
|
|
300
315
|
children: children
|
|
301
316
|
}, key);
|
|
302
317
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepsea-components",
|
|
3
|
-
"version": "5.16.
|
|
3
|
+
"version": "5.16.3",
|
|
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,6 +1,6 @@
|
|
|
1
|
-
import { CSSProperties, ComponentProps,
|
|
2
|
-
import { clsx,
|
|
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
|
|
|
@@ -50,13 +50,13 @@ function isTheSameIterable<T>(a: Iterable<T>, b: Iterable<T>) {
|
|
|
50
50
|
return aSet.difference(bSet).size === 0
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
interface GetOrderMapParams
|
|
53
|
+
interface GetOrderMapParams {
|
|
54
54
|
prev?: DraggableGridKeyToOrder
|
|
55
55
|
orders: number[]
|
|
56
56
|
keys: Key[]
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function getOrderMap
|
|
59
|
+
function getOrderMap({ prev, orders, keys }: GetOrderMapParams) {
|
|
60
60
|
const orderSet = new Set(orders)
|
|
61
61
|
const orderMap = new Map<Key, number>()
|
|
62
62
|
const newKeys = keys.filter(key => {
|
|
@@ -67,6 +67,7 @@ function getOrderMap<T>({ prev, orders, keys }: GetOrderMapParams<T>) {
|
|
|
67
67
|
orderSet.delete(prevOrder)
|
|
68
68
|
return false
|
|
69
69
|
}
|
|
70
|
+
return true
|
|
70
71
|
})
|
|
71
72
|
orders = Array.from(orderSet)
|
|
72
73
|
newKeys.forEach((key, index) => orderMap.set(key, orders[index]))
|
|
@@ -100,51 +101,54 @@ function getOrderToKey(keyToOrder: DraggableGridKeyToOrder) {
|
|
|
100
101
|
return new Map(Array.from(keyToOrder.entries()).map(([key, order]) => [order, key]))
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "children"> &
|
|
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
|
-
|
|
147
|
-
|
|
104
|
+
export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "children"> &
|
|
105
|
+
DragMoveEvents<HTMLDivElement> & {
|
|
106
|
+
/** 类名 */
|
|
107
|
+
className?: DraggableGridClassName
|
|
108
|
+
/** 类名 */
|
|
109
|
+
classNames?: DraggableGridClassNames
|
|
110
|
+
/** 样式 */
|
|
111
|
+
style?: DraggableGridStyle
|
|
112
|
+
/** 数据源 */
|
|
113
|
+
items?: T[]
|
|
114
|
+
/** 是否禁用拖拽 */
|
|
115
|
+
disabled?: boolean
|
|
116
|
+
/** 列数 */
|
|
117
|
+
columns: number
|
|
118
|
+
/** 行数 */
|
|
119
|
+
rows: number
|
|
120
|
+
/**
|
|
121
|
+
* 间距
|
|
122
|
+
* @default 0
|
|
123
|
+
*/
|
|
124
|
+
gap?: number
|
|
125
|
+
/**
|
|
126
|
+
* 水平间距
|
|
127
|
+
* @default 0
|
|
128
|
+
*/
|
|
129
|
+
gapX?: number
|
|
130
|
+
/**
|
|
131
|
+
* 垂直间距
|
|
132
|
+
* @default 0
|
|
133
|
+
*/
|
|
134
|
+
gapY?: number
|
|
135
|
+
/** 元素宽度 */
|
|
136
|
+
itemWidth: number
|
|
137
|
+
/** 元素高度 */
|
|
138
|
+
itemHeight: number
|
|
139
|
+
/** 元素的 key 到次序的映射 */
|
|
140
|
+
orderMap?: DraggableGridKeyToOrder
|
|
141
|
+
/** 次序变化时回调 */
|
|
142
|
+
onOrderMapChange?: (orderMap: DraggableGridKeyToOrder) => void
|
|
143
|
+
/** 禁用的元素 */
|
|
144
|
+
isItemDisabled?: Key[] | ((item: T, key: Key) => boolean)
|
|
145
|
+
/** 禁用的次序 */
|
|
146
|
+
isOrderDisabled?: number[] | ((order: number) => boolean)
|
|
147
|
+
/** 次序的优先级,可以通过此函数调整元素的优先放置的方向,左上,右上,左下,右下,中心,顺时针,逆时针等等 */
|
|
148
|
+
orderPriority?: (a: number, b: number) => number
|
|
149
|
+
/** 触发移动的元素 */
|
|
150
|
+
handle?: string | HTMLElement | ((item: T, key: Key, element: HTMLDivElement) => HTMLElement | undefined | null) | undefined | null
|
|
151
|
+
} & (T extends ReactNode
|
|
148
152
|
? {
|
|
149
153
|
/** 渲染函数,当 T 为 ReactNode 时,render 为可选 */
|
|
150
154
|
render?: (item: T, status: DraggableGridItemStatus) => ReactNode
|
|
@@ -163,13 +167,26 @@ export type DraggableGridProps<T> = Omit<ComponentProps<"div">, "className" | "c
|
|
|
163
167
|
keyExtractor: (item: T) => Key
|
|
164
168
|
})
|
|
165
169
|
|
|
166
|
-
interface DraggableGridItemProps extends ComponentProps<"div">,
|
|
170
|
+
interface DraggableGridItemProps<T> extends ComponentProps<"div">, DragMoveEvents<HTMLDivElement> {
|
|
171
|
+
item: T
|
|
172
|
+
itemKey: Key
|
|
173
|
+
/** 触发移动的元素 */
|
|
174
|
+
handle?: string | HTMLElement | ((item: T, key: Key, element: HTMLDivElement) => HTMLElement | undefined | null) | undefined | null
|
|
175
|
+
}
|
|
167
176
|
|
|
168
|
-
|
|
177
|
+
function DraggableGridItem<T>({ item, itemKey, handle, onDragMoveStart, onDragMove, onDragMoveEnd, ...rest }: DraggableGridItemProps<T>) {
|
|
169
178
|
const element = useRef<HTMLDivElement>(null)
|
|
170
179
|
|
|
171
180
|
useDragMove({
|
|
172
|
-
element
|
|
181
|
+
element: isNullable(handle)
|
|
182
|
+
? element
|
|
183
|
+
: () =>
|
|
184
|
+
element.current &&
|
|
185
|
+
(typeof handle === "string"
|
|
186
|
+
? (element.current.querySelector(handle) as HTMLElement)
|
|
187
|
+
: typeof handle === "function"
|
|
188
|
+
? handle(item, itemKey, element.current)
|
|
189
|
+
: handle),
|
|
173
190
|
onDragMoveStart,
|
|
174
191
|
onDragMove,
|
|
175
192
|
onDragMoveEnd,
|
|
@@ -211,20 +228,22 @@ export function DraggableGrid<T>({
|
|
|
211
228
|
onOrderMapChange,
|
|
212
229
|
render,
|
|
213
230
|
keyExtractor,
|
|
214
|
-
isItemDisabled,
|
|
231
|
+
isItemDisabled: _isItemDisabled,
|
|
215
232
|
isOrderDisabled,
|
|
216
233
|
orderPriority,
|
|
234
|
+
handle,
|
|
235
|
+
onDragMoveStart: _onDragMoveStart,
|
|
236
|
+
onDragMove: _onDragMove,
|
|
237
|
+
onDragMoveEnd: _onDragMoveEnd,
|
|
217
238
|
...rest
|
|
218
239
|
}: DraggableGridProps<T>) {
|
|
219
|
-
const
|
|
220
|
-
const itemToKey = new Map<T, Key>()
|
|
240
|
+
const keyToItem = useMemo(() => {
|
|
221
241
|
const keyToItem = new Map<Key, T>()
|
|
222
|
-
items.forEach(
|
|
242
|
+
items.forEach(item => {
|
|
223
243
|
const key = keyExtractor ? keyExtractor(item) : (item as Key)
|
|
224
|
-
itemToKey.set(item, key)
|
|
225
244
|
keyToItem.set(key, item)
|
|
226
245
|
})
|
|
227
|
-
return
|
|
246
|
+
return keyToItem
|
|
228
247
|
}, [items, keyExtractor])
|
|
229
248
|
|
|
230
249
|
/** 检查 items 中是否有重复的 key */
|
|
@@ -258,16 +277,16 @@ export function DraggableGrid<T>({
|
|
|
258
277
|
})
|
|
259
278
|
|
|
260
279
|
useEffect(() => {
|
|
261
|
-
if (!isTheSameArray(cache.orders, orders) || !isTheSameIterable(cache.keys, keyToItem.keys())) {
|
|
280
|
+
if (!isTheSameArray(dragging?.orders ?? cache.orders, orders) || !isTheSameIterable(dragging?.keyToOrder.keys() ?? cache.keys, keyToItem.keys())) {
|
|
262
281
|
cache.orders = orders
|
|
263
|
-
cache.keys = Array.from(keyToItem.keys())
|
|
264
|
-
const newOrderMap = getOrderMap({ prev: keyToOrder, orders, keys: cache.keys })
|
|
282
|
+
cache.keys = Array.from((dragging?.keyToOrder ?? keyToItem).keys())
|
|
283
|
+
const newOrderMap = getOrderMap({ prev: dragging?.keyToOrder ?? keyToOrder, orders, keys: cache.keys })
|
|
265
284
|
setKeyToOrder(newOrderMap)
|
|
266
285
|
onOrderMapChange?.(newOrderMap)
|
|
267
286
|
const newRenderKeys = new Set(newOrderMap.keys())
|
|
268
287
|
setRenderKeys(prev => prev.intersection(newRenderKeys).union(newRenderKeys.difference(prev)))
|
|
269
288
|
}
|
|
270
|
-
}, [dragging, orders, keyToItem, keyToOrder, onOrderMapChange])
|
|
289
|
+
}, [dragging, cache, orders, keyToItem, keyToOrder, onOrderMapChange])
|
|
271
290
|
|
|
272
291
|
/** 渲染的元素的 key,不会随着 keyToOrder 的变化而变化 */
|
|
273
292
|
const [renderKeys, setRenderKeys] = useState(() => new Set(keyToOrder.keys()))
|
|
@@ -293,7 +312,7 @@ export function DraggableGrid<T>({
|
|
|
293
312
|
onOrderMapChange?.(dragging.keyToOrder)
|
|
294
313
|
}
|
|
295
314
|
}
|
|
296
|
-
}, [orders, keyToItem, keyToOrder, onOrderMapChange])
|
|
315
|
+
}, [dragging, orders, columns, rows, gapX, gapY, itemWidth, itemHeight, keyToItem, keyToOrder, onOrderMapChange])
|
|
297
316
|
|
|
298
317
|
/** 受控 */
|
|
299
318
|
useEffect(() => {
|
|
@@ -303,14 +322,15 @@ export function DraggableGrid<T>({
|
|
|
303
322
|
}, [orderMap, keyToOrder, onOrderMapChange])
|
|
304
323
|
|
|
305
324
|
function onDragMoveStart(key: Key, event: DragMoveEvent<HTMLDivElement>) {
|
|
325
|
+
_onDragMoveStart?.(event)
|
|
306
326
|
const position = getPosition({ order: keyToOrder.get(key)!, columns, gapX, gapY, itemWidth, itemHeight })
|
|
307
327
|
recent.current = key
|
|
308
328
|
setDragging({
|
|
309
329
|
key,
|
|
310
330
|
startX: position.x,
|
|
311
331
|
startY: position.y,
|
|
312
|
-
deltaX:
|
|
313
|
-
deltaY:
|
|
332
|
+
deltaX: event.deltaX,
|
|
333
|
+
deltaY: event.deltaY,
|
|
314
334
|
orders,
|
|
315
335
|
columns,
|
|
316
336
|
rows,
|
|
@@ -323,6 +343,7 @@ export function DraggableGrid<T>({
|
|
|
323
343
|
}
|
|
324
344
|
|
|
325
345
|
function onDragMove(event: DragMoveEvent<HTMLDivElement>) {
|
|
346
|
+
_onDragMove?.(event)
|
|
326
347
|
if (!dragging) return
|
|
327
348
|
|
|
328
349
|
const { deltaX, deltaY } = event
|
|
@@ -396,11 +417,18 @@ export function DraggableGrid<T>({
|
|
|
396
417
|
onOrderMapChange?.(newKeyToOrder)
|
|
397
418
|
}
|
|
398
419
|
|
|
399
|
-
function onDragMoveEnd() {
|
|
420
|
+
function onDragMoveEnd(event: DragMoveEvent<HTMLDivElement>) {
|
|
421
|
+
_onDragMoveEnd?.(event)
|
|
400
422
|
if (!dragging) return
|
|
401
423
|
setDragging(undefined)
|
|
402
424
|
}
|
|
403
425
|
|
|
426
|
+
function isItemDisabled(key: Key) {
|
|
427
|
+
if (!_isItemDisabled) return false
|
|
428
|
+
if (Array.isArray(_isItemDisabled)) return _isItemDisabled.includes(key)
|
|
429
|
+
return _isItemDisabled(keyToItem.get(key)!, key)
|
|
430
|
+
}
|
|
431
|
+
|
|
404
432
|
return (
|
|
405
433
|
<div
|
|
406
434
|
className={clsx(
|
|
@@ -446,14 +474,17 @@ export function DraggableGrid<T>({
|
|
|
446
474
|
return (
|
|
447
475
|
<DraggableGridItem
|
|
448
476
|
key={key}
|
|
477
|
+
item={item}
|
|
478
|
+
itemKey={key}
|
|
479
|
+
handle={handle}
|
|
449
480
|
className={clsx(
|
|
450
481
|
styles.draggableGridItem,
|
|
451
482
|
typeof classNames?.item === "function" ? classNames.item({ order, isDragging: isDragging }) : classNames?.item,
|
|
452
483
|
)}
|
|
453
484
|
style={style}
|
|
454
|
-
onDragMoveStart={!disabled ? event => onDragMoveStart(key, event) : undefined}
|
|
455
|
-
onDragMove={!disabled ? onDragMove : undefined}
|
|
456
|
-
onDragMoveEnd={!disabled ? onDragMoveEnd : undefined}
|
|
485
|
+
onDragMoveStart={!disabled && !isItemDisabled(key) ? event => onDragMoveStart(key, event) : undefined}
|
|
486
|
+
onDragMove={!disabled && !isItemDisabled(key) ? onDragMove : undefined}
|
|
487
|
+
onDragMoveEnd={!disabled && !isItemDisabled(key) ? onDragMoveEnd : undefined}
|
|
457
488
|
children={children}
|
|
458
489
|
/>
|
|
459
490
|
)
|