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
- const DraggableGridItem = ({ onDragMoveStart, onDragMove, onDragMoveEnd, ...rest })=>{
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 [itemToKey, keyToItem] = (0, external_react_namespaceObject.useMemo)(()=>{
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, index)=>{
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: 0,
203
- deltaY: 0,
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
- const DraggableGridItem = ({ onDragMoveStart, onDragMove, onDragMoveEnd, ...rest })=>{
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 [itemToKey, keyToItem] = useMemo(()=>{
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, index)=>{
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: 0,
165
- deltaY: 0,
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.1",
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
- "soda-hooks": "6.13.3",
44
- "deepsea-tools": "5.40.6"
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, FC, Key, ReactNode, useEffect, useMemo, useRef, useState } from "react"
2
- import { clsx, equal, getArray } from "deepsea-tools"
3
- import { DragMoveEvent, UseDragMoveParams, useDragMove } from "soda-hooks"
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<T> {
53
+ interface GetOrderMapParams {
54
54
  prev?: DraggableGridKeyToOrder
55
55
  orders: number[]
56
56
  keys: Key[]
57
57
  }
58
58
 
59
- function getOrderMap<T>({ prev, orders, keys }: GetOrderMapParams<T>) {
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
- className?: DraggableGridClassName
106
- /** 类名 */
107
- classNames?: DraggableGridClassNames
108
- /** 样式 */
109
- style?: DraggableGridStyle
110
- /** 数据源 */
111
- items?: T[]
112
- /** 是否禁用拖拽 */
113
- disabled?: boolean
114
- /** 列数 */
115
- columns: number
116
- /** 行数 */
117
- rows: number
118
- /**
119
- * 间距
120
- * @default 0
121
- */
122
- gap?: number
123
- /**
124
- * 水平间距
125
- * @default 0
126
- */
127
- gapX?: number
128
- /**
129
- * 垂直间距
130
- * @default 0
131
- */
132
- gapY?: number
133
- /** 元素宽度 */
134
- itemWidth: number
135
- /** 元素高度 */
136
- itemHeight: number
137
- /** 元素的 key 到次序的映射 */
138
- orderMap?: DraggableGridKeyToOrder
139
- /** 次序变化时回调 */
140
- onOrderMapChange?: (orderMap: DraggableGridKeyToOrder) => void
141
- /** 禁用的元素 */
142
- isItemDisabled?: Key[] | ((item: T) => boolean)
143
- /** 禁用的次序 */
144
- isOrderDisabled?: number[] | ((order: number) => boolean)
145
- /** 次序的优先级,可以通过此函数调整元素的优先放置的方向,左上,右上,左下,右下,中心,顺时针,逆时针等等 */
146
- orderPriority?: (a: number, b: number) => number
147
- } & (T extends ReactNode
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">, Omit<UseDragMoveParams<HTMLDivElement>, "element"> {}
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
- const DraggableGridItem: FC<DraggableGridItemProps> = ({ onDragMoveStart, onDragMove, onDragMoveEnd, ...rest }) => {
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 [itemToKey, keyToItem] = useMemo(() => {
220
- const itemToKey = new Map<T, Key>()
240
+ const keyToItem = useMemo(() => {
221
241
  const keyToItem = new Map<Key, T>()
222
- items.forEach((item, index) => {
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 [itemToKey, keyToItem] as const
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: 0,
313
- deltaY: 0,
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
  )