stk-table-vue 0.8.12 → 0.8.14
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 +9 -17
- package/lib/src/StkTable/StkTable.vue.d.ts +6 -4
- package/lib/src/StkTable/utils/index.d.ts +3 -0
- package/lib/stk-table-vue.js +263 -159
- package/lib/style.css +8 -2
- package/package.json +3 -1
- package/src/StkTable/StkTable.vue +169 -128
- package/src/StkTable/const.ts +2 -2
- package/src/StkTable/style.less +0 -2
- package/src/StkTable/useFixedCol.ts +10 -8
- package/src/StkTable/useHighlight.ts +1 -1
- package/src/StkTable/useMergeCells.ts +19 -18
- package/src/StkTable/useScrollRowByRow.ts +53 -18
- package/src/StkTable/useTrDrag.ts +1 -6
- package/src/StkTable/utils/index.ts +16 -0
package/lib/style.css
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* name: stk-table-vue
|
|
3
|
+
* version: v0.8.13
|
|
4
|
+
* description: High performance realtime virtual table for vue3 and vue2.7
|
|
5
|
+
* author: japlus
|
|
6
|
+
* homepage: https://ja-plus.github.io/stk-table-vue/
|
|
7
|
+
* license: MIT
|
|
8
|
+
*/
|
|
1
9
|
@keyframes stk-table-dim{
|
|
2
10
|
from{
|
|
3
11
|
background-color:var(--highlight-color);
|
|
@@ -242,8 +250,6 @@
|
|
|
242
250
|
.stk-table .vt-x-left,
|
|
243
251
|
.stk-table .vt-x-right{
|
|
244
252
|
padding:0;
|
|
245
|
-
background:none;
|
|
246
|
-
pointer-events:none;
|
|
247
253
|
}
|
|
248
254
|
.stk-table .column-resize-indicator{
|
|
249
255
|
width:0;
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stk-table-vue",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.14",
|
|
4
4
|
"description": "High performance realtime virtual table for vue3 and vue2.7",
|
|
5
5
|
"main": "./lib/stk-table-vue.js",
|
|
6
6
|
"types": "./lib/src/StkTable/index.d.ts",
|
|
7
|
+
"homepage": "https://ja-plus.github.io/stk-table-vue/",
|
|
7
8
|
"packageManager": "pnpm@10.7.0",
|
|
8
9
|
"directories": {
|
|
9
10
|
"test": "test"
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"stk-table-vue": "^0.8.7",
|
|
63
64
|
"typescript": "^5.8.3",
|
|
64
65
|
"vite": "^7.2.2",
|
|
66
|
+
"vite-plugin-banner": "^0.8.1",
|
|
65
67
|
"vite-plugin-dts": "3.9.1",
|
|
66
68
|
"vitepress": "^1.6.4",
|
|
67
69
|
"vitepress-demo-plugin": "^1.4.7",
|
|
@@ -43,6 +43,13 @@
|
|
|
43
43
|
:class="{
|
|
44
44
|
'fixed-mode': props.fixedMode,
|
|
45
45
|
}"
|
|
46
|
+
@dragover="onTrDragOver"
|
|
47
|
+
@dragenter="onTrDragEnter"
|
|
48
|
+
@dragend="onTrDragEnd"
|
|
49
|
+
@click="onRowClick"
|
|
50
|
+
@dblclick="onRowDblclick"
|
|
51
|
+
@contextmenu="onRowMenu"
|
|
52
|
+
@mouseover="onTrMouseOver"
|
|
46
53
|
>
|
|
47
54
|
<thead v-if="!headless">
|
|
48
55
|
<tr v-for="(row, rowIndex) in tableHeaders" :key="rowIndex" @contextmenu="onHeaderMenu($event)">
|
|
@@ -54,34 +61,18 @@
|
|
|
54
61
|
<th
|
|
55
62
|
v-for="(col, colIndex) in virtualX_on && rowIndex === tableHeaders.length - 1 ? virtualX_columnPart : row"
|
|
56
63
|
:key="colKeyGen(col)"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
:title="getHeaderTitle(col)"
|
|
63
|
-
:class="[
|
|
64
|
-
col.sorter ? 'sortable' : '',
|
|
65
|
-
colKeyGen(col) === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
|
|
66
|
-
col.headerClassName,
|
|
67
|
-
fixedColClassMap.get(colKeyGen(col)),
|
|
68
|
-
]"
|
|
69
|
-
@click="
|
|
70
|
-
e => {
|
|
71
|
-
onColumnSort(col);
|
|
72
|
-
onHeaderCellClick(e, col);
|
|
73
|
-
}
|
|
74
|
-
"
|
|
75
|
-
@dragstart="onThDragStart"
|
|
76
|
-
@drop="onThDrop"
|
|
77
|
-
@dragover="onThDragOver"
|
|
64
|
+
v-bind="getTHProps(col)"
|
|
65
|
+
@click="e => onHeaderCellClick(e, col)"
|
|
66
|
+
@dragstart="headerDrag ? onThDragStart : void 0"
|
|
67
|
+
@drop="headerDrag ? onThDrop : void 0"
|
|
68
|
+
@dragover="headerDrag ? onThDragOver : void 0"
|
|
78
69
|
>
|
|
79
70
|
<div
|
|
80
71
|
v-if="colResizeOn(col) && colIndex > 0"
|
|
81
72
|
class="table-header-resizer left"
|
|
82
73
|
@mousedown="onThResizeMouseDown($event, col, true)"
|
|
83
74
|
></div>
|
|
84
|
-
<div class="table-header-cell-wrapper" :style="
|
|
75
|
+
<div class="table-header-cell-wrapper" :style="`--row-span:${virtualX_on ? 1 : col.__R_SP__}`">
|
|
85
76
|
<component :is="col.customHeaderCell" v-if="col.customHeaderCell" :col="col" :colIndex="colIndex" :rowIndex="rowIndex" />
|
|
86
77
|
<template v-else>
|
|
87
78
|
<slot name="tableHeader" :col="col">
|
|
@@ -96,7 +87,7 @@
|
|
|
96
87
|
</tr>
|
|
97
88
|
</thead>
|
|
98
89
|
|
|
99
|
-
<tbody class="stk-tbody-main" @
|
|
90
|
+
<tbody class="stk-tbody-main" @click="onCellClick" @mousedown="onCellMouseDown" @mouseover="onCellMouseOver">
|
|
100
91
|
<tr v-if="virtual_on && !isSRBRActive" :style="`height:${virtualScroll.offsetTop}px`" class="padding-top-tr">
|
|
101
92
|
<td v-if="virtualX_on && fixedMode && headless" class="vt-x-left"></td>
|
|
102
93
|
<template v-if="fixedMode && headless">
|
|
@@ -105,26 +96,11 @@
|
|
|
105
96
|
</tr>
|
|
106
97
|
<tr
|
|
107
98
|
v-for="(row, rowIndex) in virtual_dataSourcePart"
|
|
108
|
-
:id="stkTableId + '-' + (rowKey ? rowKeyGen(row) : getRowIndex(rowIndex))"
|
|
109
99
|
ref="trRef"
|
|
110
|
-
:key="
|
|
111
|
-
|
|
112
|
-
:class="{
|
|
113
|
-
active: rowKey ? rowKeyGen(row) === currentRowKey : row === currentRow,
|
|
114
|
-
hover: props.showTrHoverClass && (rowKey ? rowKeyGen(row) === currentHoverRowKey : row === currentHoverRowKey),
|
|
115
|
-
[rowClassName(row, getRowIndex(rowIndex)) || '']: true,
|
|
116
|
-
expanded: row && row.__EXP__,
|
|
117
|
-
'expanded-row': row && row.__EXP_R__,
|
|
118
|
-
}"
|
|
119
|
-
:style="{
|
|
120
|
-
'--row-height': row && row.__EXP_R__ && props.virtual && props.expandConfig?.height && props.expandConfig?.height + 'px',
|
|
121
|
-
}"
|
|
122
|
-
@click="onRowClick($event, row, getRowIndex(rowIndex))"
|
|
123
|
-
@dblclick="onRowDblclick($event, row, getRowIndex(rowIndex))"
|
|
124
|
-
@contextmenu="onRowMenu($event, row, getRowIndex(rowIndex))"
|
|
125
|
-
@mouseover="onTrMouseOver($event, row)"
|
|
126
|
-
@mouseleave="onTrMouseLeave($event)"
|
|
100
|
+
:key="rowKeyGen(row)"
|
|
101
|
+
v-bind="getTRProps(row, rowIndex)"
|
|
127
102
|
@drop="onTrDrop($event, getRowIndex(rowIndex))"
|
|
103
|
+
@mouseleave="onTrMouseLeave"
|
|
128
104
|
>
|
|
129
105
|
<td v-if="virtualX_on" class="vt-x-left"></td>
|
|
130
106
|
<td v-if="row && row.__EXP_R__" :colspan="virtualX_columnPart.length">
|
|
@@ -139,27 +115,9 @@
|
|
|
139
115
|
<td
|
|
140
116
|
v-if="!hiddenCellMap[rowKeyGen(row)]?.has(colKeyGen(col))"
|
|
141
117
|
:key="colKeyGen(col)"
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
col.className,
|
|
146
|
-
fixedColClassMap.get(colKeyGen(col)),
|
|
147
|
-
{
|
|
148
|
-
'cell-hover': col.mergeCells && hoverMergedCells.has(cellKeyGen(row, col)),
|
|
149
|
-
'cell-active': col.mergeCells && activeMergedCells.has(cellKeyGen(row, col)),
|
|
150
|
-
'seq-column': col.type === 'seq',
|
|
151
|
-
active: props.cellActive && currentSelectedCellKey === cellKeyGen(row, col),
|
|
152
|
-
expanded: col.type === 'expand' && (row.__EXP__ ? colKeyGen(row.__EXP__) === colKeyGen(col) : false),
|
|
153
|
-
'tree-expanded': col.type === 'tree-node' && row.__T_EXP__,
|
|
154
|
-
'drag-row-cell': col.type === 'dragRow',
|
|
155
|
-
},
|
|
156
|
-
]"
|
|
157
|
-
v-bind="mergeCellsWrapper(row, col, rowIndex, colIndex)"
|
|
158
|
-
@click="onCellClick($event, row, col, getRowIndex(rowIndex))"
|
|
159
|
-
@mousedown="onCellMouseDown($event, row, col, getRowIndex(rowIndex))"
|
|
160
|
-
@mouseenter="onCellMouseEnter($event, row, col)"
|
|
161
|
-
@mouseleave="onCellMouseLeave($event, row, col)"
|
|
162
|
-
@mouseover="onCellMouseOver($event, row, col)"
|
|
118
|
+
v-bind="getTDProps(row, col, rowIndex, colIndex)"
|
|
119
|
+
@mouseenter="onCellMouseEnter"
|
|
120
|
+
@mouseleave="onCellMouseLeave"
|
|
163
121
|
>
|
|
164
122
|
<component
|
|
165
123
|
:is="col.customCell"
|
|
@@ -184,7 +142,7 @@
|
|
|
184
142
|
v-else
|
|
185
143
|
class="table-cell-wrapper"
|
|
186
144
|
:title="col.type !== 'seq' ? row?.[col.dataIndex] : ''"
|
|
187
|
-
:style="col.type === 'tree-node'
|
|
145
|
+
:style="col.type === 'tree-node' && row.__T_LV__ ? `padding-left:${row.__T_LV__ * 16}px` : ''"
|
|
188
146
|
>
|
|
189
147
|
<template v-if="col.type === 'seq'">
|
|
190
148
|
{{ (props.seqConfig.startIndex || 0) + getRowIndex(rowIndex) + 1 }}
|
|
@@ -211,6 +169,7 @@
|
|
|
211
169
|
</td>
|
|
212
170
|
</template>
|
|
213
171
|
</template>
|
|
172
|
+
<td v-if="virtualX_on" class="vt-x-right"></td>
|
|
214
173
|
</tr>
|
|
215
174
|
<tr v-if="virtual_on && !isSRBRActive" :style="`height: ${virtual_offsetBottom}px`"></tr>
|
|
216
175
|
<tr v-if="SRBRBottomHeight" :style="`height: ${SRBRBottomHeight}px`"></tr>
|
|
@@ -275,7 +234,7 @@ import { useTrDrag } from './useTrDrag';
|
|
|
275
234
|
import { useTree } from './useTree';
|
|
276
235
|
import { useVirtualScroll } from './useVirtualScroll';
|
|
277
236
|
import { createStkTableId, getCalculatedColWidth, getColWidth } from './utils/constRefUtils';
|
|
278
|
-
import { howDeepTheHeader, isEmptyValue, tableSort, transformWidthToStr } from './utils/index';
|
|
237
|
+
import { getClosestColKey, getClosestTr, getClosestTrIndex, howDeepTheHeader, isEmptyValue, tableSort, transformWidthToStr } from './utils/index';
|
|
279
238
|
|
|
280
239
|
/** Generic stands for DataType */
|
|
281
240
|
type DT = any & PrivateRowDT;
|
|
@@ -376,7 +335,7 @@ const props = withDefaults(
|
|
|
376
335
|
* "v" - 仅展示竖线
|
|
377
336
|
* "body-v" - 仅表体展示竖线
|
|
378
337
|
*/
|
|
379
|
-
bordered?: boolean | 'h' | 'v' | 'body-v';
|
|
338
|
+
bordered?: boolean | 'h' | 'v' | 'body-v' | 'body-h';
|
|
380
339
|
/**
|
|
381
340
|
* 自动重新计算虚拟滚动高度宽度。默认true
|
|
382
341
|
* [非响应式]
|
|
@@ -643,7 +602,7 @@ const currentSelectedCellKey = ref<string | undefined>();
|
|
|
643
602
|
/** 当前hover行 */
|
|
644
603
|
let currentHoverRow: DT | null = null;
|
|
645
604
|
/** 当前hover的行的key */
|
|
646
|
-
const currentHoverRowKey = ref(null);
|
|
605
|
+
const currentHoverRowKey = ref<UniqKey | null>(null);
|
|
647
606
|
/** 当前hover的列的key */
|
|
648
607
|
// const currentColHoverKey = ref(null);
|
|
649
608
|
|
|
@@ -1038,9 +997,7 @@ function updateDataSource(val: DT[]) {
|
|
|
1038
997
|
}
|
|
1039
998
|
}
|
|
1040
999
|
|
|
1041
|
-
/**
|
|
1042
|
-
* 行唯一值生成
|
|
1043
|
-
*/
|
|
1000
|
+
/** tr key */
|
|
1044
1001
|
function rowKeyGen(row: DT | null | undefined) {
|
|
1045
1002
|
if (!row) return row;
|
|
1046
1003
|
let key = rowKeyGenCache.get(row) || (row as PrivateRowDT).__ROW_K__;
|
|
@@ -1056,12 +1013,11 @@ function rowKeyGen(row: DT | null | undefined) {
|
|
|
1056
1013
|
return key;
|
|
1057
1014
|
}
|
|
1058
1015
|
|
|
1059
|
-
/**
|
|
1016
|
+
/** td key */
|
|
1060
1017
|
function cellKeyGen(row: DT | null | undefined, col: StkTableColumn<DT>) {
|
|
1061
1018
|
return rowKeyGen(row) + CELL_KEY_SEPARATE + colKeyGen.value(col);
|
|
1062
1019
|
}
|
|
1063
1020
|
|
|
1064
|
-
/** 单元格样式 */
|
|
1065
1021
|
const cellStyleMap = computed(() => {
|
|
1066
1022
|
const thMap = new Map();
|
|
1067
1023
|
const tdMap = new Map();
|
|
@@ -1092,9 +1048,8 @@ const cellStyleMap = computed(() => {
|
|
|
1092
1048
|
});
|
|
1093
1049
|
|
|
1094
1050
|
function getRowIndex(rowIndex: number) {
|
|
1095
|
-
return rowIndex +
|
|
1051
|
+
return rowIndex + virtualScroll.value.startIndex;
|
|
1096
1052
|
}
|
|
1097
|
-
|
|
1098
1053
|
/** th title */
|
|
1099
1054
|
function getHeaderTitle(col: StkTableColumn<DT>): string {
|
|
1100
1055
|
const colKey = colKeyGen.value(col);
|
|
@@ -1105,8 +1060,97 @@ function getHeaderTitle(col: StkTableColumn<DT>): string {
|
|
|
1105
1060
|
return col.title || '';
|
|
1106
1061
|
}
|
|
1107
1062
|
|
|
1063
|
+
function getTRProps(row: PrivateRowDT | null | undefined, index: number) {
|
|
1064
|
+
const rowIndex = getRowIndex(index);
|
|
1065
|
+
const rowKey = rowKeyGen(row);
|
|
1066
|
+
|
|
1067
|
+
let classStr = props.rowClassName(row, rowIndex) || '' + ' ' + (row?.__EXP__ ? 'expanded' : '') + ' ' + (row?.__EXP_R__ ? 'expanded-row' : '');
|
|
1068
|
+
if (currentRowKey.value === rowKey || row === currentRow.value) {
|
|
1069
|
+
classStr += ' active';
|
|
1070
|
+
}
|
|
1071
|
+
if (props.showTrHoverClass && (rowKey === currentHoverRowKey.value || row === currentHoverRow)) {
|
|
1072
|
+
classStr += ' hover';
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
const result = {
|
|
1076
|
+
id: stkTableId + '-' + rowKey,
|
|
1077
|
+
'data-row-key': rowKey,
|
|
1078
|
+
'data-row-i': rowIndex,
|
|
1079
|
+
class: classStr,
|
|
1080
|
+
style: '',
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
const needRowHeight = row?.__EXP_R__ && props.virtual && props.expandConfig?.height;
|
|
1084
|
+
|
|
1085
|
+
if (needRowHeight) {
|
|
1086
|
+
result.style = `--row-height: ${props.expandConfig?.height}px`;
|
|
1087
|
+
}
|
|
1088
|
+
return result;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
function getTHProps(col: PrivateStkTableColumn<DT>) {
|
|
1092
|
+
const colKey = colKeyGen.value(col);
|
|
1093
|
+
return {
|
|
1094
|
+
'data-col-key': colKey,
|
|
1095
|
+
draggable: Boolean(isHeaderDraggable(col)),
|
|
1096
|
+
rowspan: virtualX_on.value ? 1 : col.__R_SP__,
|
|
1097
|
+
colspan: col.__C_SP__,
|
|
1098
|
+
style: cellStyleMap.value[TagType.TH].get(colKey),
|
|
1099
|
+
title: getHeaderTitle(col),
|
|
1100
|
+
class: [
|
|
1101
|
+
col.sorter ? 'sortable' : '',
|
|
1102
|
+
colKey === sortCol.value && sortOrderIndex.value !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex.value],
|
|
1103
|
+
col.headerClassName,
|
|
1104
|
+
fixedColClassMap.value.get(colKey),
|
|
1105
|
+
],
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
function getTDProps(row: PrivateRowDT | null | undefined, col: StkTableColumn<PrivateRowDT>, rowIndex: number, colIndex: number) {
|
|
1110
|
+
const colKey = colKeyGen.value(col);
|
|
1111
|
+
if (!row) {
|
|
1112
|
+
return {
|
|
1113
|
+
style: cellStyleMap.value[TagType.TD].get(colKey),
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
const cellKey = cellKeyGen(row, col);
|
|
1118
|
+
const classList = [col.className, fixedColClassMap.value.get(colKey)];
|
|
1119
|
+
if (col.mergeCells) {
|
|
1120
|
+
if (hoverMergedCells.value.has(cellKey)) {
|
|
1121
|
+
classList.push('cell-hover');
|
|
1122
|
+
}
|
|
1123
|
+
if (activeMergedCells.value.has(cellKey)) {
|
|
1124
|
+
classList.push('cell-active');
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
if (props.cellActive && currentSelectedCellKey.value === cellKey) {
|
|
1129
|
+
classList.push('active');
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
if (col.type === 'seq') {
|
|
1133
|
+
classList.push('seq-column');
|
|
1134
|
+
} else if (col.type === 'expand' && (row.__EXP__ ? colKeyGen.value(row.__EXP__) === colKey : false)) {
|
|
1135
|
+
classList.push('expanded');
|
|
1136
|
+
} else if (row.__T_EXP__ && col.type === 'tree-node') {
|
|
1137
|
+
classList.push('tree-expanded');
|
|
1138
|
+
} else if (col.type === 'dragRow') {
|
|
1139
|
+
classList.push('drag-row-cell');
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
return {
|
|
1143
|
+
'data-col-key': colKey,
|
|
1144
|
+
style: cellStyleMap.value[TagType.TD].get(colKey),
|
|
1145
|
+
class: classList,
|
|
1146
|
+
...mergeCellsWrapper(row, col, rowIndex, colIndex),
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1108
1150
|
/**
|
|
1109
1151
|
* 表头点击排序
|
|
1152
|
+
*
|
|
1153
|
+
* en: Sort a column
|
|
1110
1154
|
* @param click 是否为点击表头触发
|
|
1111
1155
|
* @param options.force sort-remote 开启后是否强制排序
|
|
1112
1156
|
* @param options.emit 是否触发回调
|
|
@@ -1173,7 +1217,10 @@ function onColumnSort(col: StkTableColumn<DT> | undefined | null, click = true,
|
|
|
1173
1217
|
}
|
|
1174
1218
|
}
|
|
1175
1219
|
|
|
1176
|
-
function onRowClick(e: MouseEvent
|
|
1220
|
+
function onRowClick(e: MouseEvent) {
|
|
1221
|
+
const rowIndex = getClosestTrIndex(e);
|
|
1222
|
+
const row = dataSourceCopy.value[rowIndex];
|
|
1223
|
+
if (!row) return;
|
|
1177
1224
|
emits('row-click', e, row, { rowIndex });
|
|
1178
1225
|
if (rowActiveProp.value.disabled?.(row)) return;
|
|
1179
1226
|
const isCurrentRow = props.rowKey ? currentRowKey.value === rowKeyGen(row) : currentRow.value === row;
|
|
@@ -1188,50 +1235,24 @@ function onRowClick(e: MouseEvent, row: DT, rowIndex: number) {
|
|
|
1188
1235
|
emits('current-change', e, row, { select: !isCurrentRow });
|
|
1189
1236
|
}
|
|
1190
1237
|
|
|
1191
|
-
function onRowDblclick(e: MouseEvent
|
|
1238
|
+
function onRowDblclick(e: MouseEvent) {
|
|
1239
|
+
const rowIndex = getClosestTrIndex(e);
|
|
1240
|
+
const row = dataSourceCopy.value[rowIndex];
|
|
1241
|
+
if (!row) return;
|
|
1192
1242
|
emits('row-dblclick', e, row, { rowIndex });
|
|
1193
1243
|
}
|
|
1194
1244
|
|
|
1195
|
-
/** 表头行右键 */
|
|
1196
1245
|
function onHeaderMenu(e: MouseEvent) {
|
|
1197
1246
|
emits('header-row-menu', e);
|
|
1198
1247
|
}
|
|
1199
1248
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1249
|
+
function onRowMenu(e: MouseEvent) {
|
|
1250
|
+
const rowIndex = getClosestTrIndex(e);
|
|
1251
|
+
const row = dataSourceCopy.value[rowIndex];
|
|
1252
|
+
if (!row) return;
|
|
1202
1253
|
emits('row-menu', e, row, { rowIndex });
|
|
1203
1254
|
}
|
|
1204
1255
|
|
|
1205
|
-
/**
|
|
1206
|
-
* proxy events
|
|
1207
|
-
*/
|
|
1208
|
-
// function onTbodyClick(e: MouseEvent, type: 1 | 2) {
|
|
1209
|
-
// const el = (e.target as HTMLElement).closest<HTMLElement>('td,tr');
|
|
1210
|
-
// if (!el) return;
|
|
1211
|
-
// if (el.tagName === 'TD') {
|
|
1212
|
-
// const [rowKey, colKey] = el.dataset.cellKey?.split(CELL_KEY_SEPARATE) || [];
|
|
1213
|
-
// const row = dataSourceCopy.value.find(item => rowKeyGen(item) === rowKey);
|
|
1214
|
-
// const col = tableHeaderLast.value.find(item => colKeyGen.value(item) === colKey);
|
|
1215
|
-
// if (col) {
|
|
1216
|
-
// if (col.type === 'expand') {
|
|
1217
|
-
// toggleExpandRow(row, col);
|
|
1218
|
-
// }
|
|
1219
|
-
// if (type === 1) {
|
|
1220
|
-
// onCellClick(e, row, col);
|
|
1221
|
-
// } else if (type === 2) {
|
|
1222
|
-
// onCellMouseDown(e, row, col);
|
|
1223
|
-
// }
|
|
1224
|
-
// }
|
|
1225
|
-
// if (type === 1) {
|
|
1226
|
-
// onRowClick(e, row);
|
|
1227
|
-
// }
|
|
1228
|
-
// } else if (el.tagName === 'TR') {
|
|
1229
|
-
// const rowKey = el.dataset.rowKey;
|
|
1230
|
-
// const row = dataSourceCopy.value.find(item => rowKeyGen(item) === rowKey);
|
|
1231
|
-
// onRowClick(e, row);
|
|
1232
|
-
// }
|
|
1233
|
-
// }
|
|
1234
|
-
|
|
1235
1256
|
function triangleClick(e: MouseEvent, row: DT, col: StkTableColumn<DT>) {
|
|
1236
1257
|
if (col.type === 'expand') {
|
|
1237
1258
|
toggleExpandRow(row, col);
|
|
@@ -1240,8 +1261,13 @@ function triangleClick(e: MouseEvent, row: DT, col: StkTableColumn<DT>) {
|
|
|
1240
1261
|
}
|
|
1241
1262
|
}
|
|
1242
1263
|
|
|
1243
|
-
|
|
1244
|
-
|
|
1264
|
+
function onCellClick(e: MouseEvent) {
|
|
1265
|
+
const rowIndex = getClosestTrIndex(e);
|
|
1266
|
+
const row = dataSourceCopy.value[rowIndex];
|
|
1267
|
+
if (!row) return;
|
|
1268
|
+
const colKey = getClosestColKey(e);
|
|
1269
|
+
const col = tableHeaderLast.value.find(item => colKeyGen.value(item) === colKey);
|
|
1270
|
+
if (!col) return;
|
|
1245
1271
|
if (props.cellActive) {
|
|
1246
1272
|
const cellKey = cellKeyGen(row, col);
|
|
1247
1273
|
const result = { row, col, select: false, rowIndex };
|
|
@@ -1256,27 +1282,39 @@ function onCellClick(e: MouseEvent, row: DT, col: StkTableColumn<DT>, rowIndex:
|
|
|
1256
1282
|
emits('cell-click', e, row, col, { rowIndex });
|
|
1257
1283
|
}
|
|
1258
1284
|
|
|
1259
|
-
|
|
1285
|
+
function getCellEventData(e: MouseEvent) {
|
|
1286
|
+
const rowIndex = getClosestTrIndex(e) || 0;
|
|
1287
|
+
const row = dataSourceCopy.value[rowIndex];
|
|
1288
|
+
const colKey = getClosestColKey(e);
|
|
1289
|
+
const col = tableHeaderLast.value.find(item => colKeyGen.value(item) === colKey) as any;
|
|
1290
|
+
return { row, col, rowIndex };
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/** th click */
|
|
1260
1294
|
function onHeaderCellClick(e: MouseEvent, col: StkTableColumn<DT>) {
|
|
1295
|
+
onColumnSort(col);
|
|
1261
1296
|
emits('header-cell-click', e, col);
|
|
1262
1297
|
}
|
|
1263
1298
|
|
|
1264
1299
|
/** td mouseenter */
|
|
1265
|
-
function onCellMouseEnter(e: MouseEvent
|
|
1300
|
+
function onCellMouseEnter(e: MouseEvent) {
|
|
1301
|
+
const { row, col } = getCellEventData(e);
|
|
1266
1302
|
emits('cell-mouseenter', e, row, col);
|
|
1267
1303
|
}
|
|
1268
1304
|
|
|
1269
1305
|
/** td mouseleave */
|
|
1270
|
-
function onCellMouseLeave(e: MouseEvent
|
|
1306
|
+
function onCellMouseLeave(e: MouseEvent) {
|
|
1307
|
+
const { row, col } = getCellEventData(e);
|
|
1271
1308
|
emits('cell-mouseleave', e, row, col);
|
|
1272
1309
|
}
|
|
1273
|
-
|
|
1274
1310
|
/** td mouseover event */
|
|
1275
|
-
function onCellMouseOver(e: MouseEvent
|
|
1311
|
+
function onCellMouseOver(e: MouseEvent) {
|
|
1312
|
+
const { row, col } = getCellEventData(e);
|
|
1276
1313
|
emits('cell-mouseover', e, row, col);
|
|
1277
1314
|
}
|
|
1278
1315
|
|
|
1279
|
-
function onCellMouseDown(e: MouseEvent
|
|
1316
|
+
function onCellMouseDown(e: MouseEvent) {
|
|
1317
|
+
const { row, col, rowIndex } = getCellEventData(e);
|
|
1280
1318
|
emits('cell-mousedown', e, row, col, { rowIndex });
|
|
1281
1319
|
}
|
|
1282
1320
|
|
|
@@ -1294,22 +1332,21 @@ function onTableWheel(e: WheelEvent) {
|
|
|
1294
1332
|
return;
|
|
1295
1333
|
}
|
|
1296
1334
|
const dom = tableContainerRef.value;
|
|
1297
|
-
if (!dom) return;
|
|
1298
|
-
if (!virtual_on.value && !virtualX_on.value) return;
|
|
1335
|
+
if ((!virtual_on.value && !virtualX_on.value) || !dom) return;
|
|
1299
1336
|
|
|
1300
|
-
const { containerHeight, scrollTop, scrollHeight } = virtualScroll.value;
|
|
1301
|
-
const { containerWidth, scrollLeft, scrollWidth } = virtualScrollX.value;
|
|
1302
|
-
const isScrollBottom = scrollHeight - containerHeight - scrollTop < 10;
|
|
1303
|
-
const isScrollRight = scrollWidth - containerWidth - scrollLeft < 10;
|
|
1304
1337
|
const { deltaY, deltaX, shiftKey } = e;
|
|
1305
1338
|
|
|
1306
1339
|
if (virtual_on.value && deltaY && !shiftKey) {
|
|
1340
|
+
const { containerHeight, scrollTop, scrollHeight } = virtualScroll.value;
|
|
1341
|
+
const isScrollBottom = scrollHeight - containerHeight - scrollTop < 10;
|
|
1307
1342
|
if ((deltaY > 0 && !isScrollBottom) || (deltaY < 0 && scrollTop > 0)) {
|
|
1308
1343
|
e.preventDefault(); // parent element scroll
|
|
1309
1344
|
}
|
|
1310
1345
|
dom.scrollTop += deltaY;
|
|
1311
1346
|
}
|
|
1312
1347
|
if (virtualX_on.value) {
|
|
1348
|
+
const { containerWidth, scrollLeft, scrollWidth } = virtualScrollX.value;
|
|
1349
|
+
const isScrollRight = scrollWidth - containerWidth - scrollLeft < 10;
|
|
1313
1350
|
let distance = deltaX;
|
|
1314
1351
|
if (shiftKey && deltaY) {
|
|
1315
1352
|
distance = deltaY;
|
|
@@ -1333,12 +1370,10 @@ function onTableScroll(e: Event) {
|
|
|
1333
1370
|
const isYScroll = scrollTop !== vScrollTop;
|
|
1334
1371
|
const isXScroll = scrollLeft !== vScrollLeft;
|
|
1335
1372
|
|
|
1336
|
-
// 纵向滚动有变化
|
|
1337
1373
|
if (isYScroll) {
|
|
1338
1374
|
updateVirtualScrollY(scrollTop);
|
|
1339
1375
|
}
|
|
1340
1376
|
|
|
1341
|
-
// 横向滚动有变化
|
|
1342
1377
|
if (isXScroll) {
|
|
1343
1378
|
if (virtualX_on.value) {
|
|
1344
1379
|
updateVirtualScrollX(scrollLeft);
|
|
@@ -1359,12 +1394,16 @@ function onTableScroll(e: Event) {
|
|
|
1359
1394
|
}
|
|
1360
1395
|
|
|
1361
1396
|
/** tr hover */
|
|
1362
|
-
function onTrMouseOver(
|
|
1397
|
+
function onTrMouseOver(e: MouseEvent) {
|
|
1398
|
+
const tr = getClosestTr(e);
|
|
1399
|
+
if (!tr) return;
|
|
1400
|
+
const rowIndex = Number(tr.dataset.rowI);
|
|
1401
|
+
const row = dataSourceCopy.value[rowIndex];
|
|
1363
1402
|
if (currentHoverRow === row) return;
|
|
1364
1403
|
currentHoverRow = row;
|
|
1365
|
-
const rowKey =
|
|
1404
|
+
const rowKey = tr.dataset.rowKey;
|
|
1366
1405
|
if (props.showTrHoverClass) {
|
|
1367
|
-
currentHoverRowKey.value = rowKey;
|
|
1406
|
+
currentHoverRowKey.value = rowKey || null;
|
|
1368
1407
|
}
|
|
1369
1408
|
if (props.rowHover) {
|
|
1370
1409
|
updateHoverMergedCells(rowKey);
|
|
@@ -1372,7 +1411,7 @@ function onTrMouseOver(_e: MouseEvent, row: DT) {
|
|
|
1372
1411
|
}
|
|
1373
1412
|
|
|
1374
1413
|
function onTrMouseLeave(e: MouseEvent) {
|
|
1375
|
-
if ((e.target as
|
|
1414
|
+
if ((e.target as HTMLElement).tagName !== 'TR') return;
|
|
1376
1415
|
currentHoverRow = null;
|
|
1377
1416
|
if (props.showTrHoverClass) {
|
|
1378
1417
|
currentHoverRowKey.value = null;
|
|
@@ -1384,6 +1423,8 @@ function onTrMouseLeave(e: MouseEvent) {
|
|
|
1384
1423
|
|
|
1385
1424
|
/**
|
|
1386
1425
|
* 选中一行
|
|
1426
|
+
*
|
|
1427
|
+
* en: Select a row
|
|
1387
1428
|
* @param {string} rowKeyOrRow selected rowKey, undefined to unselect
|
|
1388
1429
|
* @param {boolean} option.silent if set true not emit `current-change`. default:false
|
|
1389
1430
|
* @param {boolean} option.deep if set true, deep search in children. default:false
|
package/src/StkTable/const.ts
CHANGED
|
@@ -44,7 +44,7 @@ export const DEFAULT_SORT_CONFIG = {
|
|
|
44
44
|
} satisfies SortConfig<any>;
|
|
45
45
|
|
|
46
46
|
export const DEFAULT_ROW_ACTIVE_CONFIG: Required<RowActiveOption<any>> = {
|
|
47
|
-
enabled:
|
|
47
|
+
enabled: true,
|
|
48
48
|
disabled: () => false,
|
|
49
|
-
revokable:
|
|
49
|
+
revokable: true,
|
|
50
50
|
};
|
package/src/StkTable/style.less
CHANGED
|
@@ -40,18 +40,20 @@ export function useFixedCol<DT extends Record<string, any>>({
|
|
|
40
40
|
tableHeaders.value.forEach(cols => {
|
|
41
41
|
cols.forEach(col => {
|
|
42
42
|
const fixed = col.fixed;
|
|
43
|
-
const showShadow =
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
const showShadow = fixed && fixedColShadow && fixedShadowColsValue.includes(col);
|
|
44
|
+
const classList = [];
|
|
45
|
+
if (fixedColsValue.includes(col)) {
|
|
46
|
+
// 表示该列正在被固定
|
|
47
|
+
classList.push('fixed-cell--active');
|
|
48
|
+
}
|
|
47
49
|
if (fixed) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
classList.push('fixed-cell');
|
|
51
|
+
classList.push('fixed-cell--' + fixed);
|
|
50
52
|
}
|
|
51
53
|
if (showShadow) {
|
|
52
|
-
|
|
54
|
+
classList.push('fixed-cell--shadow');
|
|
53
55
|
}
|
|
54
|
-
colMap.set(colKey(col),
|
|
56
|
+
colMap.set(colKey(col), classList);
|
|
55
57
|
});
|
|
56
58
|
});
|
|
57
59
|
return colMap;
|
|
@@ -108,7 +108,7 @@ export function useHighlight({ props, stkTableId, tableContainerRef }: Params) {
|
|
|
108
108
|
* @param option.duration 动画时长。method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。
|
|
109
109
|
*/
|
|
110
110
|
function setHighlightDimCell(rowKeyValue: UniqKey, colKeyValue: string, option: HighlightDimCellOption = {}) {
|
|
111
|
-
const cellEl = tableContainerRef.value?.querySelector<HTMLElement>(`[data-
|
|
111
|
+
const cellEl = tableContainerRef.value?.querySelector<HTMLElement>(`[data-row-key="${rowKeyValue}"] [data-col-key="${colKeyValue}"]`);
|
|
112
112
|
if (!cellEl) return;
|
|
113
113
|
const { className, method, duration, keyframe } = {
|
|
114
114
|
className: HIGHLIGHT_CELL_CLASS,
|