@gx-design-vue/pro-table 0.2.0-alpha.2 → 0.2.0-alpha.21

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.
Files changed (160) hide show
  1. package/dist/ProTable.d.ts +14 -493
  2. package/dist/ProTable.js +902 -511
  3. package/dist/components/Drag/Handle.d.ts +90 -0
  4. package/dist/components/Drag/Handle.js +64 -0
  5. package/dist/components/Drag/Tbody.d.ts +17 -0
  6. package/dist/components/Drag/Tbody.js +27 -0
  7. package/dist/components/EllipsisText/index.d.ts +50 -0
  8. package/dist/components/EllipsisText/index.js +65 -0
  9. package/dist/components/ScrollBar/Bar.d.ts +79 -0
  10. package/dist/components/ScrollBar/Bar.js +84 -0
  11. package/dist/components/ScrollBar/Thumb.d.ts +50 -0
  12. package/dist/components/ScrollBar/{Thumb/index.js → Thumb.js} +67 -58
  13. package/dist/components/ScrollBar/context.d.ts +3 -4
  14. package/dist/components/ScrollBar/context.js +3 -5
  15. package/dist/components/ScrollBar/util.d.ts +6 -5
  16. package/dist/components/ScrollBar/util.js +1 -14
  17. package/dist/components/SearchForm/CollapseToggle.d.ts +53 -0
  18. package/dist/components/SearchForm/CollapseToggle.js +47 -0
  19. package/dist/components/SearchForm/FormItemContainer.d.ts +73 -0
  20. package/dist/components/SearchForm/FormItemContainer.js +225 -0
  21. package/dist/components/SearchForm/FormItemWrapper.d.ts +80 -0
  22. package/dist/components/SearchForm/FormItemWrapper.js +62 -0
  23. package/dist/components/SearchForm/SearchForm.d.ts +128 -0
  24. package/dist/components/SearchForm/SearchForm.js +319 -0
  25. package/dist/components/SearchForm/index.d.ts +2 -0
  26. package/dist/components/SearchForm/index.js +2 -0
  27. package/dist/components/Toolbar/FullscreenIcon.d.ts +24 -0
  28. package/dist/components/Toolbar/FullscreenIcon.js +22 -0
  29. package/dist/components/Toolbar/ListToolBar.d.ts +109 -0
  30. package/dist/components/Toolbar/ListToolBar.js +101 -0
  31. package/dist/components/Toolbar/index.d.ts +101 -0
  32. package/dist/components/Toolbar/index.js +101 -0
  33. package/dist/components/Toolbar/style.d.ts +8 -0
  34. package/dist/components/{ListToolBar → Toolbar}/style.js +32 -27
  35. package/dist/context/TableContext.d.ts +15 -27
  36. package/dist/context/TableContext.js +3 -5
  37. package/dist/hooks/index.d.ts +19 -0
  38. package/dist/hooks/index.js +19 -0
  39. package/dist/hooks/useAutoScroll.d.ts +32 -0
  40. package/dist/hooks/useAutoScroll.js +127 -0
  41. package/dist/hooks/useBreakpoints.d.ts +13 -0
  42. package/dist/hooks/useBreakpoints.js +65 -0
  43. package/dist/hooks/useCellRender.d.ts +13 -0
  44. package/dist/hooks/useCellRender.js +40 -0
  45. package/dist/hooks/useColumnResize.d.ts +29 -0
  46. package/dist/hooks/useColumnResize.js +112 -0
  47. package/dist/hooks/useColumns.d.ts +35 -24
  48. package/dist/hooks/useColumns.js +89 -58
  49. package/dist/hooks/useDragHandleColumn.d.ts +26 -0
  50. package/dist/hooks/useDragHandleColumn.js +52 -0
  51. package/dist/hooks/useEllipsis.d.ts +20 -0
  52. package/dist/hooks/useEllipsis.js +51 -0
  53. package/dist/hooks/useFetchData.d.ts +42 -65
  54. package/dist/hooks/useFetchData.js +160 -176
  55. package/dist/hooks/useFitPage.d.ts +19 -0
  56. package/dist/hooks/useFitPage.js +90 -0
  57. package/dist/hooks/useKeepAliveReload.d.ts +21 -0
  58. package/dist/hooks/useKeepAliveReload.js +24 -0
  59. package/dist/hooks/useLoading.d.ts +18 -7
  60. package/dist/hooks/useLoading.js +27 -11
  61. package/dist/hooks/usePagination.d.ts +10 -7
  62. package/dist/hooks/usePagination.js +38 -29
  63. package/dist/hooks/useRequestOptions.d.ts +18 -0
  64. package/dist/hooks/useRequestOptions.js +39 -0
  65. package/dist/hooks/useRowDrag.d.ts +42 -0
  66. package/dist/hooks/useRowDrag.js +268 -0
  67. package/dist/hooks/useRowSelection.d.ts +27 -15
  68. package/dist/hooks/useRowSelection.js +93 -80
  69. package/dist/hooks/useTable.d.ts +35 -77
  70. package/dist/hooks/useTable.js +76 -49
  71. package/dist/hooks/useTableForm.d.ts +17 -82
  72. package/dist/hooks/useTableForm.js +137 -52
  73. package/dist/hooks/useTableScroll.d.ts +33 -31
  74. package/dist/hooks/useTableScroll.js +71 -28
  75. package/dist/hooks/useTableSize.d.ts +17 -7
  76. package/dist/hooks/useTableSize.js +21 -9
  77. package/dist/index.d.ts +11 -7
  78. package/dist/index.js +10 -4
  79. package/dist/interface.d.ts +537 -0
  80. package/dist/interface.js +1 -0
  81. package/dist/pro-table.esm.js +8897 -4012
  82. package/dist/pro-table.js +4 -1
  83. package/dist/style/ellipsis.d.ts +13 -0
  84. package/dist/style/ellipsis.js +16 -0
  85. package/dist/style/fit-page.d.ts +4 -2
  86. package/dist/style/fit-page.js +10 -5
  87. package/dist/style/index.d.ts +3 -7
  88. package/dist/style/index.js +38 -76
  89. package/dist/style/list.d.ts +4 -2
  90. package/dist/style/list.js +2 -12
  91. package/dist/style/resizable.d.ts +8 -0
  92. package/dist/style/resizable.js +18 -0
  93. package/dist/style/row-drag.d.ts +8 -0
  94. package/dist/style/row-drag.js +44 -0
  95. package/dist/style/scroll.d.ts +4 -2
  96. package/dist/style/scroll.js +9 -9
  97. package/dist/style/search.d.ts +8 -0
  98. package/dist/{components/Form/style.js → style/search.js} +22 -9
  99. package/dist/theme/augment.d.ts +8 -0
  100. package/dist/theme/augment.js +1 -0
  101. package/dist/theme/interface/components.d.ts +8 -0
  102. package/dist/theme/interface/components.js +1 -0
  103. package/dist/utils/arrayMove.d.ts +9 -0
  104. package/dist/utils/arrayMove.js +15 -0
  105. package/dist/utils/dateFormat.d.ts +9 -0
  106. package/dist/utils/dateFormat.js +29 -0
  107. package/dist/utils/ellipsis.d.ts +19 -0
  108. package/dist/utils/ellipsis.js +30 -0
  109. package/dist/utils/flipAnimate.d.ts +25 -0
  110. package/dist/utils/flipAnimate.js +40 -0
  111. package/dist/utils/formConstants.d.ts +9 -0
  112. package/dist/utils/formConstants.js +29 -0
  113. package/dist/utils/valueFormat.d.ts +9 -0
  114. package/dist/utils/valueFormat.js +27 -0
  115. package/package.json +23 -11
  116. package/dist/components/Form/components/RequestSelect.d.ts +0 -50
  117. package/dist/components/Form/components/RequestSelect.js +0 -58
  118. package/dist/components/Form/hooks/useForm.d.ts +0 -11
  119. package/dist/components/Form/hooks/useForm.js +0 -32
  120. package/dist/components/Form/index.d.ts +0 -33
  121. package/dist/components/Form/index.js +0 -479
  122. package/dist/components/Form/style.d.ts +0 -6
  123. package/dist/components/Form/utils/config.d.ts +0 -9
  124. package/dist/components/Form/utils/config.js +0 -30
  125. package/dist/components/Form/utils/dateFormat.d.ts +0 -22
  126. package/dist/components/Form/utils/dateFormat.js +0 -45
  127. package/dist/components/ListToolBar/index.d.ts +0 -60
  128. package/dist/components/ListToolBar/index.js +0 -123
  129. package/dist/components/ListToolBar/style.d.ts +0 -6
  130. package/dist/components/ScrollBar/Bar/index.d.ts +0 -49
  131. package/dist/components/ScrollBar/Bar/index.js +0 -71
  132. package/dist/components/ScrollBar/Bar/props.d.ts +0 -25
  133. package/dist/components/ScrollBar/Bar/props.js +0 -18
  134. package/dist/components/ScrollBar/Thumb/index.d.ts +0 -40
  135. package/dist/components/ScrollBar/Thumb/props.d.ts +0 -20
  136. package/dist/components/ScrollBar/Thumb/props.js +0 -18
  137. package/dist/components/TableCell/index.d.ts +0 -37
  138. package/dist/components/TableCell/index.js +0 -72
  139. package/dist/components/ToolBar/FullscreenIcon.d.ts +0 -7
  140. package/dist/components/ToolBar/FullscreenIcon.js +0 -14
  141. package/dist/components/ToolBar/index.d.ts +0 -34
  142. package/dist/components/ToolBar/index.js +0 -100
  143. package/dist/hooks/tryOnActivated.d.ts +0 -6
  144. package/dist/hooks/tryOnActivated.js +0 -14
  145. package/dist/hooks/useDebounceFn.d.ts +0 -8
  146. package/dist/hooks/useDebounceFn.js +0 -34
  147. package/dist/hooks/useScrollArea.d.ts +0 -24
  148. package/dist/hooks/useScrollArea.js +0 -104
  149. package/dist/props.d.ts +0 -340
  150. package/dist/props.js +0 -251
  151. package/dist/types/ColumnTypings.d.ts +0 -129
  152. package/dist/types/ColumnTypings.js +0 -1
  153. package/dist/types/SlotsTypings.d.ts +0 -63
  154. package/dist/types/SlotsTypings.js +0 -13
  155. package/dist/types/TableTypings.d.ts +0 -359
  156. package/dist/types/TableTypings.js +0 -1
  157. package/dist/types/index.d.ts +0 -9
  158. package/dist/types/index.js +0 -1
  159. package/dist/utils/utils.d.ts +0 -10
  160. package/dist/utils/utils.js +0 -91
@@ -0,0 +1,268 @@
1
+ import { arrayMove } from "../utils/arrayMove.js";
2
+ import { flipAnimate } from "../utils/flipAnimate.js";
3
+ import { useAutoScroll } from "./useAutoScroll.js";
4
+ import { nextTick, ref } from "vue";
5
+ import { useEventListener } from "@vueuse/core";
6
+ //#region src/hooks/useRowDrag.ts
7
+ /** 移动阈值(px),超过才视为拖拽,避免误触影响点击 */
8
+ const DRAG_THRESHOLD = 3;
9
+ const SCROLL_RESTORE_FRAMES = 2;
10
+ const DISPLACEMENT_DURATION = 160;
11
+ const DISPLACEMENT_EASING = "cubic-bezier(0.2, 0, 0, 1)";
12
+ const DRAGGING_Z_INDEX = "1000";
13
+ function isFromDragHandle(target) {
14
+ const el = target;
15
+ if (!el || typeof el.closest !== "function") return false;
16
+ const handle = el.closest("[data-drag-handle]");
17
+ if (!handle) return false;
18
+ return handle.getAttribute("data-drag-disabled") !== "true";
19
+ }
20
+ /**
21
+ * 表格行拖拽排序 —— 精简复刻 `useTabDrag` 的垂直版本。
22
+ *
23
+ * - 仅从把手列(`[data-drag-handle]`)发起拖拽,单元格交互不受影响
24
+ * - 移动阈值(3px)区分点击与拖拽
25
+ * - 拖拽行 `transform: translateY(delta)` 跟随指针
26
+ * - 同列表其他行按虚拟插入位置实时 `translate` 让位(CSS translate 属性 + WAAPI)
27
+ * - drop 锚点用最近中心法(被拖行中心 Y 与全量各行中心比距离取最近者;含自身,半身位即换位)
28
+ * - 松手 → onSortEnd(仅 emit 排序结果,由使用方回写数据源)→ nextTick 用 flipAnimate 平滑归位
29
+ * - 拖拽结束后捕获抑制下一次 click
30
+ * - 指针接近滚动容器上下边缘时自动滚动(垂直版 detectScrollIntent)
31
+ */
32
+ function useRowDrag(options) {
33
+ const { tbodyEl, scrollEl, dataSource, rowKey, rowDraggable, onSortEnd } = options;
34
+ const isDragging = ref(false);
35
+ const draggingRowKey = ref("");
36
+ let dragStartClientY = 0;
37
+ let dragStartScrollTop = 0;
38
+ let dragPointerOffsetY = 0;
39
+ let pointerClientY = 0;
40
+ let dragEl = null;
41
+ let rowRects = [];
42
+ let pendingKey = "";
43
+ let pendingStartY = 0;
44
+ let pendingRecord = null;
45
+ const { scroll: scrollOnDragMove, start: startAutoScroll, stop: stopAutoScroll } = useAutoScroll(scrollEl, () => pointerClientY, { onScroll: updateDragPosition });
46
+ function queryRowEl(key) {
47
+ return tbodyEl.value?.querySelector(`tr[data-row-key="${key}"]`) ?? null;
48
+ }
49
+ function recordRowRects() {
50
+ rowRects = [];
51
+ const data = dataSource.value;
52
+ for (const record of data) {
53
+ const key = record?.[rowKey.value];
54
+ if (key == null) continue;
55
+ const el = queryRowEl(key);
56
+ if (!el) continue;
57
+ const rect = el.getBoundingClientRect();
58
+ rowRects.push({
59
+ el,
60
+ key,
61
+ top: rect.top,
62
+ height: rect.height,
63
+ translate: 0
64
+ });
65
+ }
66
+ }
67
+ function getCurrentScrollOffset() {
68
+ return (scrollEl.value?.scrollTop ?? 0) - dragStartScrollTop;
69
+ }
70
+ function getVisualPointerY() {
71
+ return pointerClientY + getCurrentScrollOffset();
72
+ }
73
+ function getDragCenterY() {
74
+ const dragRect = rowRects.find((r) => r.key === draggingRowKey.value);
75
+ if (!dragRect) return getVisualPointerY();
76
+ return getVisualPointerY() - dragPointerOffsetY + dragRect.height / 2;
77
+ }
78
+ /**
79
+ * 计算拖拽行应去的目标索引(最近中心法,对齐 dnd-kit `closestCenter`)。
80
+ *
81
+ * 在全量行(含拖拽行自身)里找离拖拽行视觉中心最近的行,返回其索引作为
82
+ * `arrayMove(data, fromIdx, 返回值)` 的 to。返回值的几何意义即"拖拽行想占据的位置":
83
+ * - 最近行是自己(fromIdx) → from===to,不移动
84
+ * - 最近行在下方 → 向下移动占据其位置
85
+ * - 最近行在上方 → 向上移动占据其位置
86
+ *
87
+ * 关键:拖拽行自身必须参与比较,否则切换阈值会从「半个身位」退化成「一个身位」——
88
+ * 缺少起始参考点后,需要整行越过下一行中心才会换位(表现为完全覆盖才触发);
89
+ * 含自身时切换点落在相邻两行中心的中点,即拖动半个行高即换位。
90
+ */
91
+ function computeTargetIdx(dragCenterY) {
92
+ const fromIdx = rowRects.findIndex((r) => r.key === draggingRowKey.value);
93
+ if (fromIdx < 0) return -1;
94
+ let nearestIdx = fromIdx;
95
+ let nearestDist = Infinity;
96
+ for (let i = 0; i < rowRects.length; i++) {
97
+ const center = rowRects[i].top + rowRects[i].height / 2;
98
+ const dist = Math.abs(dragCenterY - center);
99
+ if (dist < nearestDist) {
100
+ nearestDist = dist;
101
+ nearestIdx = i;
102
+ }
103
+ }
104
+ return nearestIdx;
105
+ }
106
+ /** 同区间其他行实时让位 */
107
+ function applyDisplacement(targetIdx) {
108
+ const fromIdx = rowRects.findIndex((r) => r.key === draggingRowKey.value);
109
+ if (fromIdx < 0) return;
110
+ const dragHeight = rowRects.find((r) => r.key === draggingRowKey.value)?.height ?? 0;
111
+ for (let i = 0; i < rowRects.length; i++) {
112
+ const rect = rowRects[i];
113
+ if (rect.key === draggingRowKey.value) continue;
114
+ let translate = 0;
115
+ if (fromIdx < targetIdx && i > fromIdx && i <= targetIdx) translate = -dragHeight;
116
+ else if (fromIdx > targetIdx && i >= targetIdx && i < fromIdx) translate = dragHeight;
117
+ applyRowTranslate(rect, translate);
118
+ }
119
+ }
120
+ function applyRowTranslate(rect, nextTranslate) {
121
+ const prevTranslate = rect.translate;
122
+ if (prevTranslate === nextTranslate) return;
123
+ rect.animation?.cancel();
124
+ rect.translate = nextTranslate;
125
+ rect.el.style.translate = nextTranslate ? `0px ${nextTranslate}px` : "";
126
+ if (typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches || typeof rect.el.animate !== "function") return;
127
+ rect.animation = rect.el.animate({ translate: [`0px ${prevTranslate}px`, `0px ${nextTranslate}px`] }, {
128
+ duration: DISPLACEMENT_DURATION,
129
+ easing: DISPLACEMENT_EASING
130
+ });
131
+ const clear = () => {
132
+ rect.animation = void 0;
133
+ };
134
+ rect.animation.addEventListener("finish", clear, { once: true });
135
+ rect.animation.addEventListener("cancel", clear, { once: true });
136
+ }
137
+ function updateDragPosition() {
138
+ if (!isDragging.value) return;
139
+ if (dragEl) dragEl.style.transform = `translateY(${getVisualPointerY() - dragStartClientY}px)`;
140
+ applyDisplacement(computeTargetIdx(getDragCenterY()));
141
+ }
142
+ function clearInlineStyles(rects = rowRects, activeDragEl = dragEl) {
143
+ for (const rect of rects) {
144
+ rect.animation?.cancel();
145
+ rect.animation = void 0;
146
+ rect.translate = 0;
147
+ rect.el.style.translate = "";
148
+ rect.el.style.zIndex = "";
149
+ }
150
+ if (activeDragEl) {
151
+ activeDragEl.style.transform = "";
152
+ activeDragEl.classList.remove("row-dragging");
153
+ }
154
+ }
155
+ function restoreScrollTop(scrollTop, frames = SCROLL_RESTORE_FRAMES) {
156
+ const el = scrollEl.value;
157
+ if (!el) return;
158
+ el.scrollTop = scrollTop;
159
+ if (frames <= 0 || typeof requestAnimationFrame === "undefined") return;
160
+ requestAnimationFrame(() => restoreScrollTop(scrollTop, frames - 1));
161
+ }
162
+ function beginDrag(clientY) {
163
+ isDragging.value = true;
164
+ dragStartClientY = clientY;
165
+ dragStartScrollTop = scrollEl.value?.scrollTop ?? 0;
166
+ pointerClientY = clientY;
167
+ dragEl = queryRowEl(draggingRowKey.value);
168
+ recordRowRects();
169
+ const dragRect = rowRects.find((r) => r.key === draggingRowKey.value);
170
+ dragPointerOffsetY = dragRect ? clientY - dragRect.top : 0;
171
+ if (dragEl) {
172
+ dragEl.classList.add("row-dragging");
173
+ dragEl.style.zIndex = DRAGGING_Z_INDEX;
174
+ }
175
+ startAutoScroll();
176
+ }
177
+ /** 捕获阶段抑制拖拽结束后的下一次 click */
178
+ function suppressNextClick() {
179
+ const target = dragEl;
180
+ if (!target) return;
181
+ const suppress = (event) => {
182
+ event.stopPropagation();
183
+ event.preventDefault();
184
+ target.removeEventListener("click", suppress, true);
185
+ };
186
+ target.addEventListener("click", suppress, {
187
+ capture: true,
188
+ once: true
189
+ });
190
+ }
191
+ function handleMousedown(event, record) {
192
+ if (event.button !== 0) return;
193
+ if (!isFromDragHandle(event.target)) return;
194
+ const cfg = rowDraggable.value;
195
+ if (!cfg) return;
196
+ if ((typeof cfg === "object" ? cfg : {}).disabled?.(record)) return;
197
+ event.preventDefault();
198
+ const key = record?.[rowKey.value];
199
+ pendingKey = key;
200
+ pendingStartY = event.clientY;
201
+ pendingRecord = record;
202
+ draggingRowKey.value = key;
203
+ }
204
+ function handleMousemove(event) {
205
+ if (!isDragging.value) {
206
+ if (!pendingKey) return;
207
+ if (Math.abs(event.clientY - pendingStartY) < DRAG_THRESHOLD) return;
208
+ beginDrag(pendingStartY);
209
+ }
210
+ pointerClientY = event.clientY;
211
+ updateDragPosition();
212
+ scrollOnDragMove();
213
+ }
214
+ function endDrag() {
215
+ const targetIdx = computeTargetIdx(getDragCenterY());
216
+ const fromIdx = rowRects.findIndex((r) => r.key === draggingRowKey.value);
217
+ const data = dataSource.value;
218
+ const prevRects = /* @__PURE__ */ new Map();
219
+ for (const { key, el } of rowRects) prevRects.set(key, el.getBoundingClientRect());
220
+ stopAutoScroll();
221
+ const currentRowRects = rowRects;
222
+ const currentDragEl = dragEl;
223
+ const currentScrollTop = scrollEl.value?.scrollTop ?? 0;
224
+ const record = pendingRecord;
225
+ if (targetIdx >= 0 && targetIdx !== fromIdx && targetIdx < data.length) {
226
+ const newData = arrayMove(data, fromIdx, targetIdx);
227
+ onSortEnd?.(fromIdx, targetIdx, newData, record);
228
+ nextTick(() => {
229
+ restoreScrollTop(currentScrollTop);
230
+ clearInlineStyles(currentRowRects, currentDragEl);
231
+ flipAnimate(data.map((r) => ({
232
+ key: r[rowKey.value],
233
+ el: queryRowEl(r[rowKey.value])
234
+ })).filter((entry) => Boolean(entry.el)), prevRects);
235
+ restoreScrollTop(currentScrollTop);
236
+ });
237
+ } else clearInlineStyles();
238
+ suppressNextClick();
239
+ isDragging.value = false;
240
+ draggingRowKey.value = "";
241
+ dragEl = null;
242
+ rowRects = [];
243
+ dragPointerOffsetY = 0;
244
+ pendingKey = "";
245
+ pendingRecord = null;
246
+ }
247
+ function handleMouseup() {
248
+ if (isDragging.value) endDrag();
249
+ else if (pendingKey) {
250
+ pendingKey = "";
251
+ draggingRowKey.value = "";
252
+ pendingRecord = null;
253
+ }
254
+ }
255
+ const documentTarget = typeof document === "undefined" ? void 0 : document;
256
+ useEventListener(documentTarget, "mousemove", handleMousemove);
257
+ useEventListener(documentTarget, "mouseup", handleMouseup);
258
+ function getRowProps(record, _index) {
259
+ return { onMousedown: (event) => handleMousedown(event, record) };
260
+ }
261
+ return {
262
+ isDragging,
263
+ draggingRowKey,
264
+ getRowProps
265
+ };
266
+ }
267
+ //#endregion
268
+ export { useRowDrag };
@@ -1,19 +1,31 @@
1
- import { ProTableRowSelection } from "../types/TableTypings.js";
2
- import { Ref } from "vue";
1
+ import { ComputedRef } from "vue";
3
2
  import { RecordType } from "@gx-design-vue/pro-utils";
4
- import { SelectionSelectFn } from "ant-design-vue/es/table/interface";
5
- import { Key } from "ant-design-vue/es/vc-table/interface";
3
+ import { Key, TableRowSelection } from "antdv-next/dist/table/interface";
6
4
 
7
5
  //#region src/hooks/useRowSelection.d.ts
8
- declare function useRowSelection(rowKey: Ref<string>, rowSelection: Ref<ProTableRowSelection | undefined>): {
9
- selectedKeys: Ref<Key[], Key[]>;
10
- selectedItems: Ref<RecordType[], RecordType[]>;
11
- selectRowKey: SelectionSelectFn<RecordType>;
12
- selectAllRowKey: (selected: boolean, selectedRows: RecordType[], changeRows: RecordType[]) => void;
13
- removeRowKeys: (keys: (string | number)[]) => void;
14
- changeRowKey: () => void;
15
- syncSelectedRows: (dataList: RecordType[]) => void;
16
- clearAllRowKeys: () => void;
17
- };
6
+ interface UseRowSelectionOptions<T = RecordType> {
7
+ rowKey: ComputedRef<string>;
8
+ rowSelection: ComputedRef<TableRowSelection<T> | undefined>;
9
+ dataSource: ComputedRef<T[]>;
10
+ }
11
+ interface UseRowSelectionReturn<T = RecordType> {
12
+ selectedRowKeys: ComputedRef<Key[]>;
13
+ selectedItems: ComputedRef<T[]>;
14
+ mergedRowSelection: ComputedRef<TableRowSelection<T> | undefined>;
15
+ select: (record: T, selected: boolean) => void;
16
+ selectAll: (records: T[], selected: boolean) => void;
17
+ remove: (keys: Key[]) => void;
18
+ clear: () => void;
19
+ sync: () => void;
20
+ }
21
+ /**
22
+ * 行选择状态管理。内部使用 reactive Map 作为唯一数据源,
23
+ * selectedRowKeys / selectedItems 均从 Map 派生,保证 keys 与 items 永远同步。
24
+ *
25
+ * antdv-next 已废弃 onSelectAll / onSelectInvert / onSelectNone,
26
+ * 所有选中变化统一通过 onChange 回调,因此 mergedRowSelection 只拦截 onChange,
27
+ * 不拦截 onSelect / onSelectAll。
28
+ */
29
+ declare function useRowSelection<T = RecordType>(options: UseRowSelectionOptions<T>): UseRowSelectionReturn<T>;
18
30
  //#endregion
19
- export { useRowSelection };
31
+ export { UseRowSelectionOptions, UseRowSelectionReturn, useRowSelection };
@@ -1,89 +1,102 @@
1
- import { ref, watch } from "vue";
2
- import { arrayUnique, cloneDeep } from "@gx-design-vue/pro-utils";
3
-
1
+ import { computed, onScopeDispose, reactive, watch } from "vue";
4
2
  //#region src/hooks/useRowSelection.ts
5
- function useRowSelection(rowKey, rowSelection) {
6
- const selectedKeys = ref([]);
7
- const selectedItems = ref([]);
8
- watch(() => rowSelection.value?.selectedRows, (keys) => {
9
- selectedItems.value = cloneDeep(keys || []);
10
- }, {
11
- deep: true,
12
- immediate: true
13
- });
14
- watch(() => rowSelection.value?.selectedRowKeys, (keys) => {
15
- selectedKeys.value = arrayUnique([...keys || []]);
16
- }, {
17
- deep: true,
18
- immediate: true
19
- });
20
- const selectRowKey = (record, selected) => {
21
- const type = rowSelection.value?.type || "checkbox";
22
- if (rowKey.value) if (selected) if (record?.[rowKey.value] && type === "checkbox") {
23
- selectedKeys.value.push(record[rowKey.value]);
24
- selectedItems.value.push(record);
25
- } else {
26
- selectedKeys.value = [record[rowKey.value]];
27
- selectedItems.value = [record];
3
+ function getKey(record, rowKey) {
4
+ return record[rowKey];
5
+ }
6
+ /**
7
+ * 行选择状态管理。内部使用 reactive Map 作为唯一数据源,
8
+ * selectedRowKeys / selectedItems 均从 Map 派生,保证 keys 与 items 永远同步。
9
+ *
10
+ * antdv-next 已废弃 onSelectAll / onSelectInvert / onSelectNone,
11
+ * 所有选中变化统一通过 onChange 回调,因此 mergedRowSelection 只拦截 onChange,
12
+ * 不拦截 onSelect / onSelectAll。
13
+ */
14
+ function useRowSelection(options) {
15
+ const selectedMap = reactive(/* @__PURE__ */ new Map());
16
+ const stopWatch = watch(() => options.rowSelection.value?.selectedRowKeys, (keys) => {
17
+ if (!keys) return;
18
+ const newMap = /* @__PURE__ */ new Map();
19
+ const currentDataSource = options.dataSource.value;
20
+ for (const key of keys) {
21
+ const existing = selectedMap.get(key);
22
+ const matched = currentDataSource.find((record) => getKey(record, options.rowKey.value) === key);
23
+ newMap.set(key, matched ?? existing);
28
24
  }
29
- else {
30
- selectedKeys.value = selectedKeys.value.filter((item) => item !== record[rowKey.value]);
31
- selectedItems.value = selectedItems.value.filter((item) => item[rowKey.value] !== record[rowKey.value]);
25
+ selectedMap.clear();
26
+ for (const [key, item] of newMap) selectedMap.set(key, item);
27
+ }, { immediate: true });
28
+ onScopeDispose(() => stopWatch());
29
+ const selectedRowKeys = computed(() => Array.from(selectedMap.keys()));
30
+ const selectedItems = computed(() => Array.from(selectedMap.values()).filter((item) => item != null));
31
+ function emitChange(type) {
32
+ options.rowSelection.value?.onChange?.(selectedRowKeys.value, selectedItems.value, { type });
33
+ }
34
+ function select(record, selected) {
35
+ const key = getKey(record, options.rowKey.value);
36
+ const selectionType = options.rowSelection.value?.type ?? "checkbox";
37
+ if (selected) if (selectionType === "radio") {
38
+ selectedMap.clear();
39
+ selectedMap.set(key, record);
40
+ } else selectedMap.set(key, record);
41
+ else selectedMap.delete(key);
42
+ emitChange(selected ? selectionType === "radio" ? "single" : "multiple" : "none");
43
+ }
44
+ function selectAll(records, selected) {
45
+ if (selected) for (const record of records) selectedMap.set(getKey(record, options.rowKey.value), record);
46
+ else for (const record of records) selectedMap.delete(getKey(record, options.rowKey.value));
47
+ emitChange(selected ? "all" : "none");
48
+ }
49
+ function remove(keys) {
50
+ for (const key of keys) selectedMap.delete(key);
51
+ emitChange("none");
52
+ }
53
+ function clear() {
54
+ selectedMap.clear();
55
+ emitChange("none");
56
+ }
57
+ /** 从当前 dataSource 补全 Map 中 value 为空的条目(分页切换后调用) */
58
+ function sync() {
59
+ const currentDataSource = options.dataSource.value;
60
+ const rowKeyField = options.rowKey.value;
61
+ for (const [key, item] of selectedMap) if (item == null) {
62
+ const matched = currentDataSource.find((record) => getKey(record, rowKeyField) === key);
63
+ if (matched) selectedMap.set(key, matched);
32
64
  }
33
- };
34
- const changeRowKey = () => {
35
- if (rowSelection.value) rowSelection.value?.onChange?.(selectedKeys.value, selectedItems.value);
36
- };
37
- const selectAllRowKey = (selected, selectedRows, changeRows) => {
38
- if (rowKey.value) if (selected) selectedRows.map((item) => {
39
- if (selectedKeys.value.every((el) => el !== item?.[rowKey.value])) {
40
- if (item?.[rowKey.value]) {
41
- selectedKeys.value.push(item[rowKey.value]);
42
- selectedItems.value.push(item);
43
- }
44
- }
45
- return item;
46
- });
47
- else changeRows.map((item) => {
48
- if (selectedKeys.value.includes(item?.[rowKey.value])) {
49
- selectedKeys.value = selectedKeys.value.filter((el) => el !== item[rowKey.value]);
50
- selectedItems.value = selectedItems.value.filter((el) => el[rowKey.value] !== item[rowKey.value]);
51
- }
52
- return item;
53
- });
54
- };
55
- const removeRowKeys = (keys) => {
56
- selectedKeys.value = selectedKeys.value.filter((el) => !keys.includes(el));
57
- selectedItems.value = selectedItems.value.filter((el) => !keys.includes(el?.[rowKey.value || ""]));
58
- changeRowKey();
59
- };
60
- const syncSelectedRows = (dataList) => {
61
- if (rowKey.value) {
62
- if (selectedKeys.value.length !== selectedItems.value.length) {
63
- const itemsKeys = selectedItems.value.map((item) => item[rowKey.value]);
64
- const notIncludes = selectedKeys.value.filter((item) => !itemsKeys.includes(item));
65
- dataList.forEach((item) => {
66
- if (notIncludes.includes(item[rowKey.value])) selectedItems.value.push(cloneDeep(item));
67
- });
68
- }
65
+ }
66
+ /**
67
+ * 处理 antdv Table 的 onChange 回调。
68
+ * antd 传入的 rows 只包含当前页数据,需与已有 Map 合并以保留跨页选中项。
69
+ */
70
+ function handleAntdChange(keys, rows, info) {
71
+ const rowKeyField = options.rowKey.value;
72
+ const newMap = /* @__PURE__ */ new Map();
73
+ for (const key of keys) {
74
+ const fromRows = rows.find((record) => getKey(record, rowKeyField) === key);
75
+ const existing = selectedMap.get(key);
76
+ newMap.set(key, fromRows ?? existing);
69
77
  }
70
- };
71
- const clearAllRowKeys = () => {
72
- selectedKeys.value = [];
73
- selectedItems.value = [];
74
- changeRowKey();
75
- };
78
+ selectedMap.clear();
79
+ for (const [key, item] of newMap) selectedMap.set(key, item);
80
+ options.rowSelection.value?.onChange?.(selectedRowKeys.value, selectedItems.value, info);
81
+ }
76
82
  return {
77
- selectedKeys,
83
+ selectedRowKeys,
78
84
  selectedItems,
79
- selectRowKey,
80
- selectAllRowKey,
81
- removeRowKeys,
82
- changeRowKey,
83
- syncSelectedRows,
84
- clearAllRowKeys
85
+ mergedRowSelection: computed(() => {
86
+ const rowSelectionConfig = options.rowSelection.value;
87
+ if (!rowSelectionConfig) return void 0;
88
+ return {
89
+ ...rowSelectionConfig,
90
+ selectedRowKeys: selectedRowKeys.value,
91
+ onChange: handleAntdChange
92
+ };
93
+ }),
94
+ select,
95
+ selectAll,
96
+ remove,
97
+ clear,
98
+ sync
85
99
  };
86
100
  }
87
-
88
101
  //#endregion
89
- export { useRowSelection };
102
+ export { useRowSelection };
@@ -1,90 +1,48 @@
1
- import { ProColumnType, ProColumnsType, ProSearchMap } from "../types/ColumnTypings.js";
2
- import { ProCoreActionType, ProCoreFormType, ProTableProps, ProTableRef, ProTableRowSelection, RequestConfig, RequestFunction } from "../types/TableTypings.js";
3
- import { BaseTableProps } from "../props.js";
1
+ import { PageState, ProCoreActionType, ProCoreFormType, ProSearchMap, ProTablePaginationConfig, ProTableProps, ProTableRef, RequestFunction, RowSelectionActions } from "../interface.js";
4
2
  import { ComputedRef, MaybeRef, Reactive, Ref } from "vue";
5
- import { RecordType } from "@gx-design-vue/pro-utils";
3
+ import { FilterValue, SorterResult, TableCurrentDataSource } from "antdv-next/dist/table/interface";
6
4
 
7
5
  //#region src/hooks/useTable.d.ts
8
- type ProTableState<T extends object = RecordType, R extends object = RecordType> = Omit<BaseTableProps, 'columns' | 'params' | 'dataSource' | 'rowSelection' | 'searchMap' | 'rowKey' | 'postData' | 'onReset' | 'onReload' | 'onSubmit' | 'onExpand' | 'title' | 'footer' | 'rowExpandable' | 'transformCellText' | 'expandIcon' | 'rowClassName' | 'customRow' | 'customHeaderRow' | 'expandedRowRender' | 'onBeforeSearchSubmit'> & {
9
- params: R;
10
- columns: ProColumnsType<T, R>;
11
- dataSource: T[];
12
- rowSelection: ProTableRowSelection<T>;
13
- searchMap: ProSearchMap<undefined, keyof R | keyof T>[];
14
- rowKey?: keyof T;
15
- title?: (data: T[]) => any;
16
- footer?: (data: T[]) => any;
17
- postData?: (data: T[]) => any;
18
- rowExpandable?: (record: T) => boolean;
19
- transformCellText?: (opt: {
20
- text: any;
21
- column: ProColumnType<T, R>;
22
- record: any;
23
- index: number;
24
- }) => any;
25
- expandIcon?: (props: {
26
- prefixCls: string;
27
- expanded: boolean;
28
- record: T;
29
- expandable: boolean;
30
- onExpand: (record: T, event: MouseEvent) => void;
31
- }) => any;
32
- customRow?: (data: T, index?: number, column?: ProColumnType<T, R>) => any;
33
- customHeaderRow?: (data: T, index?: number, column?: ProColumnType<T, R>) => any;
34
- expandedRowRender: (opt: {
35
- record: T;
36
- index: number;
37
- indent: number;
38
- expanded: boolean;
39
- }) => any;
40
- rowClassName?: string | ((record: T, index: number, indent: number) => string);
41
- onReset?: (params?: Partial<R>) => void;
42
- onReload?: (params?: Partial<R>) => void;
43
- onSubmit?: (params?: Partial<R>) => void;
44
- onExpand?: (expanded: boolean, record: T) => void;
45
- onResizeColumn?: (w: number, col: ProColumnType<T, R>) => void;
46
- onBeforeSearchSubmit?: RequestFunction<T, R>;
47
- };
48
- type BaseTableState<T extends object = RecordType, R extends object = RecordType> = Omit<ProTableProps<T, R>, 'request'>;
49
- interface UseTableReturn<T extends object = RecordType, R extends object = RecordType> {
50
- /** @name loading 状态,可以直接进行修改 */
6
+ interface UseTableOptions<T = any, R = any> {
7
+ state?: MaybeRef<Partial<ProTableProps<T, R>>> | Reactive<Partial<ProTableProps<T, R>>>;
8
+ request?: RequestFunction<T, R>;
9
+ }
10
+ interface UseTableReturn<T = any, R = any> {
11
+ /** loading 状态,可直接赋值 */
51
12
  loading: Ref<boolean>;
52
- /** @name 只读表格数据,不能修改 */
13
+ /** 只读表格数据 */
53
14
  dataSource: ComputedRef<T[]>;
54
- /** @name 表格列选择keys,只读 */
55
- selectedKeys: ProCoreActionType<T, R>['selectedKeys'];
56
- /** @name 表格列选择rows,只读 */
57
- selectedItems: ProCoreActionType<T, R>['selectedItems'];
58
- /** @name 表格列选项操作 */
59
- rowsSelection: ProCoreActionType<T, R>['rowsSelection'];
60
- /** @name 表格请求参数 */
61
- requestSearch: ComputedRef<RequestConfig<R>['params']>;
62
- /** @name 主动刷新,按照当前的参数在当前页重新请求下 */
15
+ /** 表格请求参数(含分页 + 表单搜索参数) */
16
+ requestSearch: ComputedRef<Partial<R> & Partial<PageState>>;
17
+ /** 表格行选择 keys */
18
+ selectedKeys: ComputedRef<(string | number)[]>;
19
+ /** 表格行选择 rows */
20
+ selectedItems: ComputedRef<T[]>;
21
+ /** 表格行选择操作 */
22
+ rowsSelection: RowSelectionActions<T>;
23
+ /** action 表格实例 */
24
+ actionRef: ComputedRef<ProCoreActionType<T, R>>;
25
+ /** form 查询表单实例 */
26
+ formRef: ComputedRef<ProCoreFormType<R>>;
27
+ /** 主动刷新 */
63
28
  reload: ProCoreActionType<T, R>['reload'];
64
- /** @name 更新表格数据,直接替换,谨慎操作 */
29
+ /** 更新表格数据 */
65
30
  setTableDataList: ProCoreActionType<T, R>['setTableDataList'];
66
- /** @name 更新TableData属性值 */
31
+ /** 更新表格行数据 */
67
32
  operateTableDataRow: ProCoreActionType<T, R>['operateTableDataRow'];
68
- /** @name 设置翻页、排序、筛选、并且刷新(reload) */
69
- setPageInfo: ProCoreActionType<T, R>['setPageInfo'];
70
- /** @name 设置翻页 */
33
+ /** 设置翻页、排序、筛选并刷新 */
34
+ setPageInfo: (pagination: ProTablePaginationConfig, filters?: Record<string, FilterValue | null>, sorter?: SorterResult | SorterResult[], extra?: TableCurrentDataSource) => void;
35
+ /** 设置翻页 */
71
36
  setPagination: ProCoreActionType<T, R>['setPagination'];
72
- /** @name 刷新并清空表单,重置为第一页 */
37
+ /** 刷新并清空表单,重置为第一页 */
73
38
  reloadAndReset: ProCoreActionType<T, R>['reloadAndReset'];
74
- /** @name 改变loading状态 */
39
+ /** 改变 loading 状态 */
75
40
  setLoading: ProCoreActionType<T, R>['setLoading'];
76
- /** @name action表格实例 */
77
- actionRef: ComputedRef<ProCoreActionType<T, R>>;
78
- /** @name form查询表单实例 */
79
- formRef: ComputedRef<ProCoreFormType<R>>;
80
- /** @name 表格参数,用于传递给ProTable组件使用,可以对其进行修改 */
81
- tableState: Reactive<ProTableState<T, R>>;
82
- /** @name 更新表格参数 SearchMap,key为SearchMap唯一字段,value是更新的参数,会merge */
83
- updateSearchMap: (key: keyof R | keyof T, value: Partial<ProSearchMap<any>>) => void;
41
+ /** 表格参数,传递给 ProTable 组件 */
42
+ tableState: Reactive<Partial<ProTableProps<T, R>>>;
43
+ /** 更新 searchMap 中指定字段的配置 */
44
+ updateSearchMap: (key: keyof T | keyof R, value: Partial<ProSearchMap<any>>) => void;
84
45
  }
85
- declare function useTable<T extends object = RecordType, R extends object = RecordType>(tableRef: Ref<ProTableRef<T> | undefined>, options?: {
86
- state?: MaybeRef<BaseTableState<T, R>> | Reactive<BaseTableState<T, R>> | ComputedRef<BaseTableState<T, R>>;
87
- request?: RequestFunction<T, R>;
88
- }): UseTableReturn<T, R>;
46
+ declare function useTable<T = any, R = any>(tableRef: Ref<ProTableRef<T, R> | undefined>, options?: UseTableOptions<T, R>): UseTableReturn<T, R>;
89
47
  //#endregion
90
- export { BaseTableState, ProTableState, UseTableReturn, useTable };
48
+ export { UseTableOptions, UseTableReturn, useTable };