stk-table-vue 1.2.4 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +194 -194
- package/lib/{Dropdown-D_9cB0rD.js → Dropdown-BAANgg_5.js} +2 -2
- package/lib/{StkTable-CVcmlZi9.js → StkTable-CGcxwpdb.js} +22 -6
- package/lib/src/StkTable/StkTable.vue.d.ts +18 -4
- package/lib/src/StkTable/types/index.d.ts +4 -1
- package/lib/src/StkTable/useVirtualScroll.d.ts +6 -1
- package/lib/stk-table-vue.js +3 -3
- package/lib/style.css +1 -1
- package/package.json +93 -93
- package/src/StkTable/StkTable.vue +2362 -2338
- package/src/StkTable/components/DragHandle.vue +9 -9
- package/src/StkTable/components/SortIcon.vue +6 -6
- package/src/StkTable/components/TreeNodeCell.vue +19 -19
- package/src/StkTable/components/TriangleIcon.vue +3 -3
- package/src/StkTable/const.ts +50 -50
- package/src/StkTable/custom-cells/ChangeCell/ChangeCell.less +34 -34
- package/src/StkTable/custom-cells/ChangeCell/createChangeCell.ts +90 -90
- package/src/StkTable/custom-cells/ChangeCell/index.ts +4 -4
- package/src/StkTable/custom-cells/CheckboxCell/CheckboxCell.less +14 -14
- package/src/StkTable/custom-cells/CheckboxCell/CheckboxCell.vue +56 -56
- package/src/StkTable/custom-cells/CheckboxCell/createCheckboxCell.ts +146 -146
- package/src/StkTable/custom-cells/CheckboxCell/index.ts +5 -5
- package/src/StkTable/custom-cells/FilterCell/Dropdown/index.ts +16 -16
- package/src/StkTable/custom-cells/FilterCell/Dropdown/index.vue +186 -186
- package/src/StkTable/custom-cells/FilterCell/Filter.less +118 -118
- package/src/StkTable/custom-cells/FilterCell/Filter.vue +66 -66
- package/src/StkTable/custom-cells/FilterCell/createFilterCell.ts +120 -120
- package/src/StkTable/custom-cells/FilterCell/index.ts +6 -6
- package/src/StkTable/custom-cells/FilterCell/types.ts +43 -43
- package/src/StkTable/custom-cells/NumberCell/createNumberCell.ts +43 -43
- package/src/StkTable/custom-cells/NumberCell/index.ts +2 -2
- package/src/StkTable/custom-cells/utils/formatNumber.ts +137 -137
- package/src/StkTable/features/const.ts +1 -1
- package/src/StkTable/features/index.ts +1 -1
- package/src/StkTable/features/useAreaSelection.ts +1240 -1239
- package/src/StkTable/index.ts +20 -20
- package/src/StkTable/mergeCellsCache.ts +69 -69
- package/src/StkTable/registerFeature.ts +40 -40
- package/src/StkTable/style.less +791 -791
- package/src/StkTable/types/highlightDimOptions.ts +28 -28
- package/src/StkTable/types/index.ts +503 -500
- package/src/StkTable/useAutoResize.ts +87 -87
- package/src/StkTable/useColResize.ts +202 -202
- package/src/StkTable/useFixedCol.ts +168 -168
- package/src/StkTable/useFixedStyle.ts +75 -75
- package/src/StkTable/useGetFixedColPosition.ts +63 -63
- package/src/StkTable/useHighlight.ts +270 -270
- package/src/StkTable/useIndexResolver.ts +29 -29
- package/src/StkTable/useKeyboardArrowScroll.ts +114 -114
- package/src/StkTable/useMaxRowSpan.ts +60 -60
- package/src/StkTable/useMergeCells.ts +541 -541
- package/src/StkTable/useRowExpand.ts +81 -81
- package/src/StkTable/useScrollRowByRow.ts +96 -96
- package/src/StkTable/useScrollbar.ts +177 -177
- package/src/StkTable/useSorter.ts +267 -267
- package/src/StkTable/useTableColumns.ts +142 -142
- package/src/StkTable/useThDrag.ts +94 -94
- package/src/StkTable/useTrDrag.ts +100 -100
- package/src/StkTable/useTree.ts +253 -253
- package/src/StkTable/useVirtualScroll.ts +1032 -1025
- package/src/StkTable/useWheeling.ts +23 -23
- package/src/StkTable/utils/constRefUtils.ts +29 -29
- package/src/StkTable/utils/index.ts +331 -331
- package/src/StkTable/utils/rowHeightFenwickTree.ts +74 -74
- package/src/StkTable/utils/useTriggerRef.ts +33 -33
- package/src/VirtualTree.vue +622 -622
- package/src/VirtualTreeSelect.vue +367 -367
- package/src/vite-env.d.ts +10 -10
|
@@ -1,142 +1,142 @@
|
|
|
1
|
-
import { Ref, shallowRef } from 'vue';
|
|
2
|
-
import { PrivateRowDT, PrivateStkTableColumn, StkTableColumn } from './types';
|
|
3
|
-
import { getColWidth } from './utils/constRefUtils';
|
|
4
|
-
import { howDeepTheHeader } from './utils/index';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Table Columns Processing Hook
|
|
8
|
-
* Handles multi-level header processing and column flattening
|
|
9
|
-
*
|
|
10
|
-
* 核心职责:
|
|
11
|
-
* - 将用户传入的 `columns`(可能含 children 多级表头)摊平为「按层级划分」的二维数组 `tableHeaders`,
|
|
12
|
-
* 每层是同一行的 th 集合;同时生成 `tableHeadersForCalc`(复制 rowSpan 位置)用于固定列计算。
|
|
13
|
-
* - 为每个列补充私有元数据(@private 字段):
|
|
14
|
-
* - __P__ 父列引用(双向链表)
|
|
15
|
-
* - __LF_S__ / __LF_E__ 该列在叶子列中的起止索引,用于多级表头横向虚拟滚动
|
|
16
|
-
* - __W__ 计算宽度(子列累加 / 叶子列取配置宽度)
|
|
17
|
-
* - __R_SP__ / __C_SP__ th 的 rowSpan / colSpan
|
|
18
|
-
* - 在 relative 模式(isRelativeMode)下,固定列不再用 sticky,而是重排到左右两侧。
|
|
19
|
-
* - 叶子列宽度是 X 轴虚拟滚动的依据(getColWidth)。
|
|
20
|
-
*/
|
|
21
|
-
export function useTableColumns<DT extends Record<string, any>>(virtualX: boolean, isRelativeMode: Ref<boolean>) {
|
|
22
|
-
/**
|
|
23
|
-
* 表头.内容是 props.columns 的引用集合
|
|
24
|
-
* @eg
|
|
25
|
-
* ```js
|
|
26
|
-
* [
|
|
27
|
-
* [{dataIndex:'id',...}], // 第0行列配置
|
|
28
|
-
* [], // 第一行列配置
|
|
29
|
-
* //...
|
|
30
|
-
* ]
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
const tableHeaders = shallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>([]);
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* 用于计算多级表头的tableHeaders。模拟rowSpan 位置的辅助数组。用于计算固定列。
|
|
37
|
-
*/
|
|
38
|
-
const tableHeadersForCalc = shallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>([]);
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 处理多级表头
|
|
42
|
-
* @param columns 原始列配置
|
|
43
|
-
*/
|
|
44
|
-
function dealColumns(columns: StkTableColumn<DT>[]) {
|
|
45
|
-
// reset
|
|
46
|
-
const tableHeadersTemp: PrivateStkTableColumn<PrivateRowDT>[][] = [];
|
|
47
|
-
const tableHeadersForCalcTemp: PrivateStkTableColumn<PrivateRowDT>[][] = [];
|
|
48
|
-
let copyColumn: StkTableColumn<DT>[] = columns; // do not deep clone
|
|
49
|
-
|
|
50
|
-
// relative 模式下不支持sticky列。因此就放在左右两侧。
|
|
51
|
-
if (isRelativeMode.value) {
|
|
52
|
-
const leftCol: StkTableColumn<DT>[] = [];
|
|
53
|
-
const centerCol: StkTableColumn<DT>[] = [];
|
|
54
|
-
const rightCol: StkTableColumn<DT>[] = [];
|
|
55
|
-
|
|
56
|
-
for (let i = 0, len = copyColumn.length; i < len; i++) {
|
|
57
|
-
const col = copyColumn[i];
|
|
58
|
-
if (col.fixed === 'left') {
|
|
59
|
-
leftCol.push(col);
|
|
60
|
-
} else if (col.fixed === 'right') {
|
|
61
|
-
rightCol.push(col);
|
|
62
|
-
} else {
|
|
63
|
-
centerCol.push(col);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
copyColumn = leftCol.concat(centerCol).concat(rightCol);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const maxDeep = howDeepTheHeader(copyColumn);
|
|
70
|
-
|
|
71
|
-
for (let i = 0; i <= maxDeep; i++) {
|
|
72
|
-
tableHeadersTemp[i] = [];
|
|
73
|
-
tableHeadersForCalcTemp[i] = [];
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** 叶子列索引计数器,用于标注每个列在 tableHeaderLast 中的叶子范围 */
|
|
77
|
-
let leafIndex = 0;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* flat columns
|
|
81
|
-
* @param arr
|
|
82
|
-
* @param depth 深度
|
|
83
|
-
* @param parent 父节点引用,用于构建双向链表。
|
|
84
|
-
*/
|
|
85
|
-
function flat(arr: PrivateStkTableColumn<PrivateRowDT>[], parent: PrivateStkTableColumn<PrivateRowDT> | null, depth = 0): [number, number] {
|
|
86
|
-
/** 所有子节点数量 */
|
|
87
|
-
let allChildrenLen = 0;
|
|
88
|
-
let allChildrenWidthSum = 0;
|
|
89
|
-
|
|
90
|
-
for (let i = 0, len = arr.length; i < len; i++) {
|
|
91
|
-
const col = arr[i];
|
|
92
|
-
if (col.hidden) continue;
|
|
93
|
-
col.__P__ = parent;
|
|
94
|
-
col.__LF_S__ = leafIndex;
|
|
95
|
-
|
|
96
|
-
/** 一列中的子节点数量 */
|
|
97
|
-
let colChildrenLen = 1;
|
|
98
|
-
/** 多级表头的父节点宽度,通过叶子节点宽度计算得到 */
|
|
99
|
-
let colWidth = 0;
|
|
100
|
-
|
|
101
|
-
if (col.children) {
|
|
102
|
-
// DFS
|
|
103
|
-
const [len, widthSum] = flat(col.children, col, depth + 1);
|
|
104
|
-
colChildrenLen = len;
|
|
105
|
-
colWidth = widthSum;
|
|
106
|
-
tableHeadersForCalcTemp[depth].push(col);
|
|
107
|
-
} else {
|
|
108
|
-
colWidth = getColWidth(col);
|
|
109
|
-
leafIndex++;
|
|
110
|
-
for (let j = depth; j <= maxDeep; j++) {
|
|
111
|
-
// 如有rowSpan 向下复制一个表头col,用于计算固定列
|
|
112
|
-
tableHeadersForCalcTemp[j].push(col);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// 回溯
|
|
117
|
-
col.__LF_E__ = leafIndex;
|
|
118
|
-
col.__W__ = colWidth;
|
|
119
|
-
tableHeadersTemp[depth].push(col);
|
|
120
|
-
const rowSpan = col.children ? 1 : maxDeep - depth + 1;
|
|
121
|
-
const colSpan = colChildrenLen;
|
|
122
|
-
|
|
123
|
-
if (rowSpan > 1) {
|
|
124
|
-
col.__R_SP__ = rowSpan;
|
|
125
|
-
}
|
|
126
|
-
if (colSpan > 1) {
|
|
127
|
-
col.__C_SP__ = colSpan;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
allChildrenLen += colChildrenLen;
|
|
131
|
-
allChildrenWidthSum += colWidth;
|
|
132
|
-
}
|
|
133
|
-
return [allChildrenLen, allChildrenWidthSum];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
flat(copyColumn as PrivateStkTableColumn<PrivateRowDT>[], null);
|
|
137
|
-
tableHeaders.value = tableHeadersTemp;
|
|
138
|
-
tableHeadersForCalc.value = tableHeadersForCalcTemp;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return [tableHeaders, tableHeadersForCalc, dealColumns] as const;
|
|
142
|
-
}
|
|
1
|
+
import { Ref, shallowRef } from 'vue';
|
|
2
|
+
import { PrivateRowDT, PrivateStkTableColumn, StkTableColumn } from './types';
|
|
3
|
+
import { getColWidth } from './utils/constRefUtils';
|
|
4
|
+
import { howDeepTheHeader } from './utils/index';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Table Columns Processing Hook
|
|
8
|
+
* Handles multi-level header processing and column flattening
|
|
9
|
+
*
|
|
10
|
+
* 核心职责:
|
|
11
|
+
* - 将用户传入的 `columns`(可能含 children 多级表头)摊平为「按层级划分」的二维数组 `tableHeaders`,
|
|
12
|
+
* 每层是同一行的 th 集合;同时生成 `tableHeadersForCalc`(复制 rowSpan 位置)用于固定列计算。
|
|
13
|
+
* - 为每个列补充私有元数据(@private 字段):
|
|
14
|
+
* - __P__ 父列引用(双向链表)
|
|
15
|
+
* - __LF_S__ / __LF_E__ 该列在叶子列中的起止索引,用于多级表头横向虚拟滚动
|
|
16
|
+
* - __W__ 计算宽度(子列累加 / 叶子列取配置宽度)
|
|
17
|
+
* - __R_SP__ / __C_SP__ th 的 rowSpan / colSpan
|
|
18
|
+
* - 在 relative 模式(isRelativeMode)下,固定列不再用 sticky,而是重排到左右两侧。
|
|
19
|
+
* - 叶子列宽度是 X 轴虚拟滚动的依据(getColWidth)。
|
|
20
|
+
*/
|
|
21
|
+
export function useTableColumns<DT extends Record<string, any>>(virtualX: boolean, isRelativeMode: Ref<boolean>) {
|
|
22
|
+
/**
|
|
23
|
+
* 表头.内容是 props.columns 的引用集合
|
|
24
|
+
* @eg
|
|
25
|
+
* ```js
|
|
26
|
+
* [
|
|
27
|
+
* [{dataIndex:'id',...}], // 第0行列配置
|
|
28
|
+
* [], // 第一行列配置
|
|
29
|
+
* //...
|
|
30
|
+
* ]
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
const tableHeaders = shallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>([]);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 用于计算多级表头的tableHeaders。模拟rowSpan 位置的辅助数组。用于计算固定列。
|
|
37
|
+
*/
|
|
38
|
+
const tableHeadersForCalc = shallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>([]);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 处理多级表头
|
|
42
|
+
* @param columns 原始列配置
|
|
43
|
+
*/
|
|
44
|
+
function dealColumns(columns: StkTableColumn<DT>[]) {
|
|
45
|
+
// reset
|
|
46
|
+
const tableHeadersTemp: PrivateStkTableColumn<PrivateRowDT>[][] = [];
|
|
47
|
+
const tableHeadersForCalcTemp: PrivateStkTableColumn<PrivateRowDT>[][] = [];
|
|
48
|
+
let copyColumn: StkTableColumn<DT>[] = columns; // do not deep clone
|
|
49
|
+
|
|
50
|
+
// relative 模式下不支持sticky列。因此就放在左右两侧。
|
|
51
|
+
if (isRelativeMode.value) {
|
|
52
|
+
const leftCol: StkTableColumn<DT>[] = [];
|
|
53
|
+
const centerCol: StkTableColumn<DT>[] = [];
|
|
54
|
+
const rightCol: StkTableColumn<DT>[] = [];
|
|
55
|
+
|
|
56
|
+
for (let i = 0, len = copyColumn.length; i < len; i++) {
|
|
57
|
+
const col = copyColumn[i];
|
|
58
|
+
if (col.fixed === 'left') {
|
|
59
|
+
leftCol.push(col);
|
|
60
|
+
} else if (col.fixed === 'right') {
|
|
61
|
+
rightCol.push(col);
|
|
62
|
+
} else {
|
|
63
|
+
centerCol.push(col);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
copyColumn = leftCol.concat(centerCol).concat(rightCol);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const maxDeep = howDeepTheHeader(copyColumn);
|
|
70
|
+
|
|
71
|
+
for (let i = 0; i <= maxDeep; i++) {
|
|
72
|
+
tableHeadersTemp[i] = [];
|
|
73
|
+
tableHeadersForCalcTemp[i] = [];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** 叶子列索引计数器,用于标注每个列在 tableHeaderLast 中的叶子范围 */
|
|
77
|
+
let leafIndex = 0;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* flat columns
|
|
81
|
+
* @param arr
|
|
82
|
+
* @param depth 深度
|
|
83
|
+
* @param parent 父节点引用,用于构建双向链表。
|
|
84
|
+
*/
|
|
85
|
+
function flat(arr: PrivateStkTableColumn<PrivateRowDT>[], parent: PrivateStkTableColumn<PrivateRowDT> | null, depth = 0): [number, number] {
|
|
86
|
+
/** 所有子节点数量 */
|
|
87
|
+
let allChildrenLen = 0;
|
|
88
|
+
let allChildrenWidthSum = 0;
|
|
89
|
+
|
|
90
|
+
for (let i = 0, len = arr.length; i < len; i++) {
|
|
91
|
+
const col = arr[i];
|
|
92
|
+
if (col.hidden) continue;
|
|
93
|
+
col.__P__ = parent;
|
|
94
|
+
col.__LF_S__ = leafIndex;
|
|
95
|
+
|
|
96
|
+
/** 一列中的子节点数量 */
|
|
97
|
+
let colChildrenLen = 1;
|
|
98
|
+
/** 多级表头的父节点宽度,通过叶子节点宽度计算得到 */
|
|
99
|
+
let colWidth = 0;
|
|
100
|
+
|
|
101
|
+
if (col.children) {
|
|
102
|
+
// DFS
|
|
103
|
+
const [len, widthSum] = flat(col.children, col, depth + 1);
|
|
104
|
+
colChildrenLen = len;
|
|
105
|
+
colWidth = widthSum;
|
|
106
|
+
tableHeadersForCalcTemp[depth].push(col);
|
|
107
|
+
} else {
|
|
108
|
+
colWidth = getColWidth(col);
|
|
109
|
+
leafIndex++;
|
|
110
|
+
for (let j = depth; j <= maxDeep; j++) {
|
|
111
|
+
// 如有rowSpan 向下复制一个表头col,用于计算固定列
|
|
112
|
+
tableHeadersForCalcTemp[j].push(col);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 回溯
|
|
117
|
+
col.__LF_E__ = leafIndex;
|
|
118
|
+
col.__W__ = colWidth;
|
|
119
|
+
tableHeadersTemp[depth].push(col);
|
|
120
|
+
const rowSpan = col.children ? 1 : maxDeep - depth + 1;
|
|
121
|
+
const colSpan = colChildrenLen;
|
|
122
|
+
|
|
123
|
+
if (rowSpan > 1) {
|
|
124
|
+
col.__R_SP__ = rowSpan;
|
|
125
|
+
}
|
|
126
|
+
if (colSpan > 1) {
|
|
127
|
+
col.__C_SP__ = colSpan;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
allChildrenLen += colChildrenLen;
|
|
131
|
+
allChildrenWidthSum += colWidth;
|
|
132
|
+
}
|
|
133
|
+
return [allChildrenLen, allChildrenWidthSum];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
flat(copyColumn as PrivateStkTableColumn<PrivateRowDT>[], null);
|
|
137
|
+
tableHeaders.value = tableHeadersTemp;
|
|
138
|
+
tableHeadersForCalc.value = tableHeadersForCalcTemp;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return [tableHeaders, tableHeadersForCalc, dealColumns] as const;
|
|
142
|
+
}
|
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
import { computed } from 'vue';
|
|
2
|
-
import { ColKeyGen, StkTableColumn } from './types';
|
|
3
|
-
import { getClosestTh, isEmptyValue } from './utils';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 列顺序拖动
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
|
-
export function useThDrag(props: any, emits: any, colKeyGen: ColKeyGen) {
|
|
10
|
-
const dragConfig = computed(() => {
|
|
11
|
-
const headerDrag = props.headerDrag;
|
|
12
|
-
const draggable = headerDrag !== false; // true or object
|
|
13
|
-
return {
|
|
14
|
-
draggable,
|
|
15
|
-
mode: 'insert',
|
|
16
|
-
disabled: () => false,
|
|
17
|
-
...headerDrag,
|
|
18
|
-
};
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
/** 开始拖动记录th位置 */
|
|
22
|
-
function onThDragStart(e: DragEvent) {
|
|
23
|
-
const th = getClosestTh(e.target as HTMLElement);
|
|
24
|
-
if (!th) return;
|
|
25
|
-
const dragStartKey = th.dataset.colKey || '';
|
|
26
|
-
const dt = e.dataTransfer;
|
|
27
|
-
if (dt) {
|
|
28
|
-
dt.effectAllowed = 'move';
|
|
29
|
-
dt.setData('text/plain', dragStartKey);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
emits('th-drag-start', dragStartKey);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function onThDragOver(e: DragEvent) {
|
|
36
|
-
const th = getClosestTh(e.target as HTMLElement);
|
|
37
|
-
if (!th) return;
|
|
38
|
-
|
|
39
|
-
const isHeaderDraggable = th.getAttribute('draggable') === 'true';
|
|
40
|
-
if (!isHeaderDraggable) return;
|
|
41
|
-
|
|
42
|
-
const dt = e.dataTransfer;
|
|
43
|
-
if (dt) {
|
|
44
|
-
dt.dropEffect = 'move';
|
|
45
|
-
}
|
|
46
|
-
e.preventDefault();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** th拖动释放时 */
|
|
50
|
-
function onThDrop(e: DragEvent) {
|
|
51
|
-
const th = getClosestTh(e.target as HTMLElement);
|
|
52
|
-
if (!th) return;
|
|
53
|
-
const dragStartKey = e.dataTransfer?.getData('text');
|
|
54
|
-
if (dragStartKey !== th.dataset.colKey) {
|
|
55
|
-
handleColOrderChange(dragStartKey, th.dataset.colKey);
|
|
56
|
-
}
|
|
57
|
-
emits('th-drop', th.dataset.colKey);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** 列拖动交换顺序 */
|
|
61
|
-
function handleColOrderChange(dragStartKey: string | undefined, dragEndKey: string | undefined) {
|
|
62
|
-
if (isEmptyValue(dragStartKey) || isEmptyValue(dragEndKey)) return;
|
|
63
|
-
|
|
64
|
-
if (dragConfig.value.mode !== 'none') {
|
|
65
|
-
const columns: StkTableColumn<any>[] = props.columns.slice();
|
|
66
|
-
|
|
67
|
-
const dragStartIndex = columns.findIndex(col => colKeyGen.value(col) === dragStartKey);
|
|
68
|
-
const dragEndIndex = columns.findIndex(col => colKeyGen.value(col) === dragEndKey);
|
|
69
|
-
|
|
70
|
-
if (dragStartIndex === -1 || dragEndIndex === -1) return;
|
|
71
|
-
|
|
72
|
-
const dragStartCol = columns[dragStartIndex];
|
|
73
|
-
// if mode is none, do nothing
|
|
74
|
-
if (dragConfig.value.mode === 'swap') {
|
|
75
|
-
columns[dragStartIndex] = columns[dragEndIndex];
|
|
76
|
-
columns[dragEndIndex] = dragStartCol;
|
|
77
|
-
} else {
|
|
78
|
-
// default is insert
|
|
79
|
-
columns.splice(dragStartIndex, 1);
|
|
80
|
-
columns.splice(dragEndIndex, 0, dragStartCol);
|
|
81
|
-
}
|
|
82
|
-
emits('update:columns', columns);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
emits('col-order-change', dragStartKey, dragEndKey);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** 是否可拖拽 */
|
|
89
|
-
function isHeaderDraggable(col: StkTableColumn<any>) {
|
|
90
|
-
return dragConfig.value.draggable && !dragConfig.value.disabled(col);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return [onThDragStart, onThDragOver, onThDrop, isHeaderDraggable] as const;
|
|
94
|
-
}
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
import { ColKeyGen, StkTableColumn } from './types';
|
|
3
|
+
import { getClosestTh, isEmptyValue } from './utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 列顺序拖动
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export function useThDrag(props: any, emits: any, colKeyGen: ColKeyGen) {
|
|
10
|
+
const dragConfig = computed(() => {
|
|
11
|
+
const headerDrag = props.headerDrag;
|
|
12
|
+
const draggable = headerDrag !== false; // true or object
|
|
13
|
+
return {
|
|
14
|
+
draggable,
|
|
15
|
+
mode: 'insert',
|
|
16
|
+
disabled: () => false,
|
|
17
|
+
...headerDrag,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
/** 开始拖动记录th位置 */
|
|
22
|
+
function onThDragStart(e: DragEvent) {
|
|
23
|
+
const th = getClosestTh(e.target as HTMLElement);
|
|
24
|
+
if (!th) return;
|
|
25
|
+
const dragStartKey = th.dataset.colKey || '';
|
|
26
|
+
const dt = e.dataTransfer;
|
|
27
|
+
if (dt) {
|
|
28
|
+
dt.effectAllowed = 'move';
|
|
29
|
+
dt.setData('text/plain', dragStartKey);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
emits('th-drag-start', dragStartKey);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function onThDragOver(e: DragEvent) {
|
|
36
|
+
const th = getClosestTh(e.target as HTMLElement);
|
|
37
|
+
if (!th) return;
|
|
38
|
+
|
|
39
|
+
const isHeaderDraggable = th.getAttribute('draggable') === 'true';
|
|
40
|
+
if (!isHeaderDraggable) return;
|
|
41
|
+
|
|
42
|
+
const dt = e.dataTransfer;
|
|
43
|
+
if (dt) {
|
|
44
|
+
dt.dropEffect = 'move';
|
|
45
|
+
}
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** th拖动释放时 */
|
|
50
|
+
function onThDrop(e: DragEvent) {
|
|
51
|
+
const th = getClosestTh(e.target as HTMLElement);
|
|
52
|
+
if (!th) return;
|
|
53
|
+
const dragStartKey = e.dataTransfer?.getData('text');
|
|
54
|
+
if (dragStartKey !== th.dataset.colKey) {
|
|
55
|
+
handleColOrderChange(dragStartKey, th.dataset.colKey);
|
|
56
|
+
}
|
|
57
|
+
emits('th-drop', th.dataset.colKey);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 列拖动交换顺序 */
|
|
61
|
+
function handleColOrderChange(dragStartKey: string | undefined, dragEndKey: string | undefined) {
|
|
62
|
+
if (isEmptyValue(dragStartKey) || isEmptyValue(dragEndKey)) return;
|
|
63
|
+
|
|
64
|
+
if (dragConfig.value.mode !== 'none') {
|
|
65
|
+
const columns: StkTableColumn<any>[] = props.columns.slice();
|
|
66
|
+
|
|
67
|
+
const dragStartIndex = columns.findIndex(col => colKeyGen.value(col) === dragStartKey);
|
|
68
|
+
const dragEndIndex = columns.findIndex(col => colKeyGen.value(col) === dragEndKey);
|
|
69
|
+
|
|
70
|
+
if (dragStartIndex === -1 || dragEndIndex === -1) return;
|
|
71
|
+
|
|
72
|
+
const dragStartCol = columns[dragStartIndex];
|
|
73
|
+
// if mode is none, do nothing
|
|
74
|
+
if (dragConfig.value.mode === 'swap') {
|
|
75
|
+
columns[dragStartIndex] = columns[dragEndIndex];
|
|
76
|
+
columns[dragEndIndex] = dragStartCol;
|
|
77
|
+
} else {
|
|
78
|
+
// default is insert
|
|
79
|
+
columns.splice(dragStartIndex, 1);
|
|
80
|
+
columns.splice(dragEndIndex, 0, dragStartCol);
|
|
81
|
+
}
|
|
82
|
+
emits('update:columns', columns);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
emits('col-order-change', dragStartKey, dragEndKey);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** 是否可拖拽 */
|
|
89
|
+
function isHeaderDraggable(col: StkTableColumn<any>) {
|
|
90
|
+
return dragConfig.value.draggable && !dragConfig.value.disabled(col);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return [onThDragStart, onThDragOver, onThDrop, isHeaderDraggable] as const;
|
|
94
|
+
}
|