stk-table-vue 0.7.1 → 0.8.0
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/lib/src/StkTable/StkTable.vue.d.ts +25 -16
- package/lib/src/StkTable/types/index.d.ts +22 -5
- package/lib/src/StkTable/useMergeCells.d.ts +20 -0
- package/lib/src/StkTable/useRowExpand.d.ts +2 -2
- package/lib/src/StkTable/useScrollRowByRow.d.ts +11 -0
- package/lib/src/StkTable/useThDrag.d.ts +5 -6
- package/lib/src/StkTable/useTree.d.ts +2 -2
- package/lib/src/StkTable/useVirtualScroll.d.ts +5 -5
- package/lib/src/StkTable/utils/index.d.ts +2 -1
- package/lib/{style.css → stk-table-vue.css} +6 -0
- package/lib/stk-table-vue.js +378 -211
- package/package.json +6 -6
- package/src/StkTable/StkTable.vue +134 -91
- package/src/StkTable/style.less +11 -6
- package/src/StkTable/types/index.ts +24 -5
- package/src/StkTable/useHighlight.ts +12 -75
- package/src/StkTable/useMergeCells.ts +125 -0
- package/src/StkTable/useRowExpand.ts +2 -2
- package/src/StkTable/useScrollRowByRow.ts +79 -0
- package/src/StkTable/useThDrag.ts +6 -6
- package/src/StkTable/useTree.ts +2 -2
- package/src/StkTable/useVirtualScroll.ts +6 -6
- package/src/StkTable/utils/index.ts +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stk-table-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Simple 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",
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
"postcss-discard-comments": "^6.0.2",
|
|
60
60
|
"postcss-preset-env": "^9.5.11",
|
|
61
61
|
"prettier": "^3.2.5",
|
|
62
|
-
"stk-table-vue": "^0.
|
|
62
|
+
"stk-table-vue": "^0.7.1",
|
|
63
63
|
"typescript": "^5.4.5",
|
|
64
|
-
"vite": "^
|
|
64
|
+
"vite": "^6.3.5",
|
|
65
65
|
"vite-plugin-dts": "3.9.1",
|
|
66
|
-
"vitepress": "^1.
|
|
67
|
-
"vitepress-demo-plugin": "^1.
|
|
68
|
-
"vitepress-plugin-llms": "^1.1
|
|
66
|
+
"vitepress": "^1.6.3",
|
|
67
|
+
"vitepress-demo-plugin": "^1.4.5",
|
|
68
|
+
"vitepress-plugin-llms": "^1.5.1",
|
|
69
69
|
"vitest": "^2.1.3",
|
|
70
70
|
"vue": "^3.5.12",
|
|
71
71
|
"vue-eslint-parser": "^9.4.2"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
'header-text-overflow': props.showHeaderOverflow,
|
|
26
26
|
'fixed-relative-mode': isRelativeMode,
|
|
27
27
|
'auto-row-height': props.autoRowHeight,
|
|
28
|
-
'scroll-row-by-row':
|
|
28
|
+
'scroll-row-by-row': isSRBRActive,
|
|
29
29
|
}"
|
|
30
30
|
:style="{
|
|
31
31
|
'--row-height': props.autoRowHeight ? void 0 : virtualScroll.rowHeight + 'px',
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
>
|
|
39
39
|
<!-- 这个元素用于整数行虚拟滚动时,撑开父容器的高度) -->
|
|
40
40
|
<div
|
|
41
|
-
v-if="
|
|
41
|
+
v-if="isSRBRActive && virtual"
|
|
42
42
|
class="row-by-row-table-height"
|
|
43
43
|
:style="{ height: dataSourceCopy.length * virtualScroll.rowHeight + 'px' }"
|
|
44
44
|
></div>
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
:key="colKeyGen(col)"
|
|
68
68
|
:data-col-key="colKeyGen(col)"
|
|
69
69
|
:draggable="isHeaderDraggable(col) ? 'true' : 'false'"
|
|
70
|
-
:rowspan="virtualX_on ? 1 : col.
|
|
71
|
-
:colspan="col.
|
|
70
|
+
:rowspan="virtualX_on ? 1 : col.__R_SP__"
|
|
71
|
+
:colspan="col.__C_SP__"
|
|
72
72
|
:style="cellStyleMap[TagType.TH].get(colKeyGen(col))"
|
|
73
73
|
:title="getHeaderTitle(col)"
|
|
74
74
|
:class="[
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
class="table-header-resizer left"
|
|
94
94
|
@mousedown="onThResizeMouseDown($event, col, true)"
|
|
95
95
|
></div>
|
|
96
|
-
<div class="table-header-cell-wrapper" :style="{ '--row-span': virtualX_on ? 1 : col.
|
|
96
|
+
<div class="table-header-cell-wrapper" :style="{ '--row-span': virtualX_on ? 1 : col.__R_SP__ }">
|
|
97
97
|
<component :is="col.customHeaderCell" v-if="col.customHeaderCell" :col="col" :colIndex="colIndex" :rowIndex="rowIndex" />
|
|
98
98
|
<template v-else>
|
|
99
99
|
<slot name="tableHeader" :col="col">
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
<!-- <tbody v-if="virtual_on" :style="{ height: `${virtualScroll.offsetTop}px` }"></tbody> -->
|
|
115
115
|
<!-- <tbody :style="{ transform: `translateY(${virtualScroll.offsetTop}px)` }"> -->
|
|
116
116
|
<tbody class="stk-tbody-main" @dragover="onTrDragOver" @dragenter="onTrDragEnter" @dragend="onTrDragEnd">
|
|
117
|
-
<tr v-if="virtual_on && !
|
|
117
|
+
<tr v-if="virtual_on && !isSRBRActive" :style="`height:${virtualScroll.offsetTop}px`" class="padding-top-tr">
|
|
118
118
|
<!--这个td用于配合虚拟滚动的th对应,防止列错位-->
|
|
119
119
|
<td v-if="virtualX_on && fixedMode && headless" class="vt-x-left"></td>
|
|
120
120
|
<template v-if="fixedMode && headless">
|
|
@@ -142,6 +142,7 @@
|
|
|
142
142
|
@dblclick="onRowDblclick($event, row, getRowIndex(rowIndex))"
|
|
143
143
|
@contextmenu="onRowMenu($event, row, getRowIndex(rowIndex))"
|
|
144
144
|
@mouseover="onTrMouseOver($event, row)"
|
|
145
|
+
@mouseleave="onTrMouseLeave($event)"
|
|
145
146
|
@drop="onTrDrop($event, getRowIndex(rowIndex))"
|
|
146
147
|
>
|
|
147
148
|
<!--这个td用于配合虚拟滚动的th对应,防止列错位-->
|
|
@@ -155,90 +156,96 @@
|
|
|
155
156
|
</div>
|
|
156
157
|
</td>
|
|
157
158
|
<template v-else>
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
>
|
|
159
|
+
<template v-for="(col, colIndex) in virtualX_columnPart">
|
|
160
|
+
<td
|
|
161
|
+
v-if="!hiddenCellMap[rowKeyGen(row)]?.has(colKeyGen(col))"
|
|
162
|
+
:key="colKeyGen(col)"
|
|
163
|
+
:data-cell-key="cellKeyGen(row, col)"
|
|
164
|
+
:style="cellStyleMap[TagType.TD].get(colKeyGen(col))"
|
|
165
|
+
:class="[
|
|
166
|
+
col.className,
|
|
167
|
+
fixedColClassMap.get(colKeyGen(col)),
|
|
168
|
+
{
|
|
169
|
+
'cell-hover': col.mergeCells && hoverMergedCells.has(cellKeyGen(row, col)),
|
|
170
|
+
'cell-active': col.mergeCells && activeMergedCells.has(cellKeyGen(row, col)),
|
|
171
|
+
'seq-column': col.type === 'seq',
|
|
172
|
+
active: props.cellActive && currentSelectedCellKey === cellKeyGen(row, col),
|
|
173
|
+
expanded:
|
|
174
|
+
col.type === 'expand' && (row.__EXPANDED__ ? colKeyGen(row.__EXPANDED__) === colKeyGen(col) : false),
|
|
175
|
+
'tree-expanded': col.type === 'tree-node' && row.__T_EXPANDED__,
|
|
176
|
+
'drag-row-cell': col.type === 'dragRow',
|
|
177
|
+
},
|
|
178
|
+
]"
|
|
179
|
+
v-bind="mergeCellsWrapper(row, col, rowIndex, colIndex)"
|
|
180
|
+
@click="onCellClick($event, row, col, getRowIndex(rowIndex))"
|
|
181
|
+
@mousedown="onCellMouseDown($event, row, col, getRowIndex(rowIndex))"
|
|
182
|
+
@mouseenter="onCellMouseEnter($event, row, col)"
|
|
183
|
+
@mouseleave="onCellMouseLeave($event, row, col)"
|
|
184
|
+
@mouseover="onCellMouseOver($event, row, col)"
|
|
185
|
+
>
|
|
186
|
+
<template v-if="col.type === 'expand' || col.type === 'tree-node'">
|
|
187
|
+
<div
|
|
188
|
+
class="table-cell-wrapper"
|
|
189
|
+
:title="row?.[col.dataIndex]"
|
|
190
|
+
:style="{ paddingLeft: row.__T_LV__ && row.__T_LV__ * 16 + 'px' }"
|
|
191
|
+
>
|
|
192
|
+
<component
|
|
193
|
+
:is="col.customCell"
|
|
194
|
+
v-if="col.customCell"
|
|
195
|
+
:col="col"
|
|
196
|
+
:row="row"
|
|
197
|
+
:rowIndex="getRowIndex(rowIndex)"
|
|
198
|
+
:colIndex="colIndex"
|
|
199
|
+
:cellValue="row && row[col.dataIndex]"
|
|
200
|
+
:expanded="(row && row.__EXPANDED__) || null"
|
|
201
|
+
:tree-expanded="(row && row.__T_EXPANDED__) || null"
|
|
202
|
+
>
|
|
203
|
+
<template #foldIcon>
|
|
204
|
+
<TriangleIcon></TriangleIcon>
|
|
205
|
+
</template>
|
|
206
|
+
</component>
|
|
207
|
+
<template v-else>
|
|
208
|
+
<TriangleIcon
|
|
209
|
+
v-if="col.type === 'expand' || (col.type === 'tree-node' && row.children !== void 0)"
|
|
210
|
+
@click="triangleClick($event, row, col)"
|
|
211
|
+
/>
|
|
212
|
+
<span :style="col.type === 'tree-node' && !row.children ? 'padding-left: 16px;' : ''">
|
|
213
|
+
{{ row?.[col.dataIndex] ?? '' }}
|
|
214
|
+
</span>
|
|
215
|
+
</template>
|
|
216
|
+
</div>
|
|
217
|
+
</template>
|
|
218
|
+
<template v-else>
|
|
186
219
|
<component
|
|
187
220
|
:is="col.customCell"
|
|
188
221
|
v-if="col.customCell"
|
|
222
|
+
class="table-cell-wrapper"
|
|
189
223
|
:col="col"
|
|
190
224
|
:row="row"
|
|
191
225
|
:rowIndex="getRowIndex(rowIndex)"
|
|
192
226
|
:colIndex="colIndex"
|
|
193
227
|
:cellValue="row && row[col.dataIndex]"
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
<TriangleIcon></TriangleIcon>
|
|
228
|
+
/>
|
|
229
|
+
<div v-else class="table-cell-wrapper" :title="col.type !== 'seq' ? row?.[col.dataIndex] : ''">
|
|
230
|
+
<template v-if="col.type === 'seq'">
|
|
231
|
+
{{ (props.seqConfig.startIndex || 0) + getRowIndex(rowIndex) + 1 }}
|
|
199
232
|
</template>
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
<
|
|
207
|
-
{{ row?.[col.dataIndex] ??
|
|
208
|
-
</
|
|
209
|
-
</
|
|
210
|
-
</
|
|
211
|
-
</
|
|
212
|
-
|
|
213
|
-
<component
|
|
214
|
-
:is="col.customCell"
|
|
215
|
-
v-if="col.customCell"
|
|
216
|
-
class="table-cell-wrapper"
|
|
217
|
-
:col="col"
|
|
218
|
-
:row="row"
|
|
219
|
-
:rowIndex="getRowIndex(rowIndex)"
|
|
220
|
-
:colIndex="colIndex"
|
|
221
|
-
:cellValue="row && row[col.dataIndex]"
|
|
222
|
-
/>
|
|
223
|
-
<div v-else class="table-cell-wrapper" :title="col.type !== 'seq' ? row?.[col.dataIndex] : ''">
|
|
224
|
-
<template v-if="col.type === 'seq'">
|
|
225
|
-
{{ (props.seqConfig.startIndex || 0) + getRowIndex(rowIndex) + 1 }}
|
|
226
|
-
</template>
|
|
227
|
-
<template v-else-if="col.type === 'dragRow'">
|
|
228
|
-
<DragHandle @dragstart="onTrDragStart($event, getRowIndex(rowIndex))" />
|
|
229
|
-
<span>
|
|
230
|
-
{{ row?.[col.dataIndex] ?? '' }}
|
|
231
|
-
</span>
|
|
232
|
-
</template>
|
|
233
|
-
<template v-else>
|
|
234
|
-
{{ row?.[col.dataIndex] ?? getEmptyCellText(col, row) }}
|
|
235
|
-
</template>
|
|
236
|
-
</div>
|
|
237
|
-
</template>
|
|
238
|
-
</td>
|
|
233
|
+
<template v-else-if="col.type === 'dragRow'">
|
|
234
|
+
<DragHandle @dragstart="onTrDragStart($event, getRowIndex(rowIndex))" />
|
|
235
|
+
<span>
|
|
236
|
+
{{ row?.[col.dataIndex] ?? '' }}
|
|
237
|
+
</span>
|
|
238
|
+
</template>
|
|
239
|
+
<template v-else>
|
|
240
|
+
{{ row?.[col.dataIndex] ?? getEmptyCellText(col, row) }}
|
|
241
|
+
</template>
|
|
242
|
+
</div>
|
|
243
|
+
</template>
|
|
244
|
+
</td>
|
|
245
|
+
</template>
|
|
239
246
|
</template>
|
|
240
247
|
</tr>
|
|
241
|
-
<tr v-if="virtual_on && !
|
|
248
|
+
<tr v-if="virtual_on && !isSRBRActive" :style="`height: ${virtual_offsetBottom}px`"></tr>
|
|
242
249
|
</tbody>
|
|
243
250
|
</table>
|
|
244
251
|
<div v-if="(!dataSourceCopy || !dataSourceCopy.length) && showNoData" class="stk-table-no-data" :class="{ 'no-data-full': noDataFull }">
|
|
@@ -273,6 +280,7 @@ import {
|
|
|
273
280
|
StkTableColumn,
|
|
274
281
|
TagType,
|
|
275
282
|
TreeConfig,
|
|
283
|
+
UniqKey,
|
|
276
284
|
UniqKeyProp,
|
|
277
285
|
} from './types/index';
|
|
278
286
|
import { useAutoResize } from './useAutoResize';
|
|
@@ -283,12 +291,14 @@ import { useGetFixedColPosition } from './useGetFixedColPosition';
|
|
|
283
291
|
import { useHighlight } from './useHighlight';
|
|
284
292
|
import { useKeyboardArrowScroll } from './useKeyboardArrowScroll';
|
|
285
293
|
import { useRowExpand } from './useRowExpand';
|
|
294
|
+
import { useScrollRowByRow } from './useScrollRowByRow';
|
|
286
295
|
import { useThDrag } from './useThDrag';
|
|
287
296
|
import { useTrDrag } from './useTrDrag';
|
|
297
|
+
import { useTree } from './useTree';
|
|
288
298
|
import { useVirtualScroll } from './useVirtualScroll';
|
|
299
|
+
import { useMergeCells } from './useMergeCells';
|
|
289
300
|
import { createStkTableId, getCalculatedColWidth, getColWidth } from './utils/constRefUtils';
|
|
290
|
-
import { howDeepTheHeader, tableSort, transformWidthToStr } from './utils/index';
|
|
291
|
-
import { useTree } from './useTree';
|
|
301
|
+
import { howDeepTheHeader, isEmptyValue, tableSort, transformWidthToStr } from './utils/index';
|
|
292
302
|
|
|
293
303
|
/** Generic stands for DataType */
|
|
294
304
|
type DT = any & PrivateRowDT;
|
|
@@ -331,7 +341,7 @@ const props = withDefaults(
|
|
|
331
341
|
/** 当前行再次点击否可以取消 (rowActive=true)*/
|
|
332
342
|
rowCurrentRevokable?: boolean;
|
|
333
343
|
/** 表头行高。default = rowHeight */
|
|
334
|
-
headerRowHeight?: number | null;
|
|
344
|
+
headerRowHeight?: number | string | null;
|
|
335
345
|
/** 虚拟滚动 */
|
|
336
346
|
virtual?: boolean;
|
|
337
347
|
/** x轴虚拟滚动(必须设置列宽)*/
|
|
@@ -428,8 +438,11 @@ const props = withDefaults(
|
|
|
428
438
|
* - true: 不使用 onwheel 滚动。鼠标滚轮滚动时更加平滑。滚动过快时会白屏。
|
|
429
439
|
*/
|
|
430
440
|
smoothScroll?: boolean;
|
|
431
|
-
/**
|
|
432
|
-
|
|
441
|
+
/**
|
|
442
|
+
* 按整数行纵向滚动
|
|
443
|
+
* - scrollbar:仅拖动滚动条生效
|
|
444
|
+
*/
|
|
445
|
+
scrollRowByRow?: boolean | 'scrollbar';
|
|
433
446
|
}>(),
|
|
434
447
|
{
|
|
435
448
|
width: '',
|
|
@@ -450,6 +463,7 @@ const props = withDefaults(
|
|
|
450
463
|
columns: () => [],
|
|
451
464
|
dataSource: () => [],
|
|
452
465
|
rowKey: '',
|
|
466
|
+
colKey: void 0,
|
|
453
467
|
emptyCellText: '--',
|
|
454
468
|
noDataFull: false,
|
|
455
469
|
showNoData: true,
|
|
@@ -648,9 +662,9 @@ const currentRow = shallowRef<DT>();
|
|
|
648
662
|
* 保存当前选中行的key<br>
|
|
649
663
|
* 原因:vue3 不用ref包dataSource时,row为原始对象,与currentItem(Ref)相比会不相等。
|
|
650
664
|
*/
|
|
651
|
-
const currentRowKey = ref<
|
|
665
|
+
const currentRowKey = ref<UniqKey | undefined>();
|
|
652
666
|
/** 当前选中的单元格key */
|
|
653
|
-
const currentSelectedCellKey = ref<
|
|
667
|
+
const currentSelectedCellKey = ref<string | undefined>();
|
|
654
668
|
/** 当前hover行 */
|
|
655
669
|
let currentHoverRow: DT | null = null;
|
|
656
670
|
/** 当前hover的行的key */
|
|
@@ -676,7 +690,7 @@ const sortSwitchOrder: Order[] = [null, 'desc', 'asc'];
|
|
|
676
690
|
* ]
|
|
677
691
|
* ```
|
|
678
692
|
*/
|
|
679
|
-
const tableHeaders = shallowRef<
|
|
693
|
+
const tableHeaders = shallowRef<PrivateStkTableColumn<DT>[][]>([]);
|
|
680
694
|
|
|
681
695
|
/**
|
|
682
696
|
* 用于计算多级表头的tableHeaders。模拟rowSpan 位置的辅助数组。用于计算固定列。
|
|
@@ -738,6 +752,8 @@ const getEmptyCellText = computed(() => {
|
|
|
738
752
|
|
|
739
753
|
const rowKeyGenCache = new WeakMap();
|
|
740
754
|
|
|
755
|
+
const { isSRBRActive } = useScrollRowByRow({ props, tableContainerRef });
|
|
756
|
+
|
|
741
757
|
const { onThDragStart, onThDragOver, onThDrop, isHeaderDraggable } = useThDrag({ props, emits, colKeyGen });
|
|
742
758
|
|
|
743
759
|
const { onTrDragStart, onTrDrop, onTrDragOver, onTrDragEnd, onTrDragEnter } = useTrDrag({ props, emits, dataSourceCopy });
|
|
@@ -812,6 +828,14 @@ const { toggleExpandRow, setRowExpand } = useRowExpand({ dataSourceCopy, rowKeyG
|
|
|
812
828
|
|
|
813
829
|
const { toggleTreeNode, setTreeExpand, flatTreeData } = useTree({ props, dataSourceCopy, rowKeyGen, emits });
|
|
814
830
|
|
|
831
|
+
const { hiddenCellMap, mergeCellsWrapper, hoverMergedCells, updateHoverMergedCells, activeMergedCells, updateActiveMergedCells } = useMergeCells({
|
|
832
|
+
props,
|
|
833
|
+
tableHeaderLast,
|
|
834
|
+
rowKeyGen,
|
|
835
|
+
colKeyGen,
|
|
836
|
+
virtual_dataSourcePart,
|
|
837
|
+
});
|
|
838
|
+
|
|
815
839
|
watch(
|
|
816
840
|
() => props.columns,
|
|
817
841
|
() => {
|
|
@@ -870,7 +894,7 @@ watch(
|
|
|
870
894
|
nextTick(() => initVirtualScrollY());
|
|
871
895
|
}
|
|
872
896
|
const sortColValue = sortCol.value;
|
|
873
|
-
if (sortColValue) {
|
|
897
|
+
if (!isEmptyValue(sortColValue) && !props.sortRemote) {
|
|
874
898
|
// sort
|
|
875
899
|
const colKey = colKeyGen.value;
|
|
876
900
|
const column = tableHeaderLast.value.find(it => colKey(it) === sortColValue);
|
|
@@ -987,10 +1011,10 @@ function dealColumns() {
|
|
|
987
1011
|
const rowSpan = col.children ? 1 : maxDeep - depth + 1;
|
|
988
1012
|
const colSpan = colChildrenLen;
|
|
989
1013
|
if (rowSpan > 1) {
|
|
990
|
-
col.
|
|
1014
|
+
col.__R_SP__ = rowSpan;
|
|
991
1015
|
}
|
|
992
1016
|
if (colSpan > 1) {
|
|
993
|
-
col.
|
|
1017
|
+
col.__C_SP__ = colSpan;
|
|
994
1018
|
}
|
|
995
1019
|
|
|
996
1020
|
allChildrenLen += colChildrenLen;
|
|
@@ -1148,9 +1172,11 @@ function onRowClick(e: MouseEvent, row: DT, rowIndex: number) {
|
|
|
1148
1172
|
// 点击同一行,取消当前选中行。
|
|
1149
1173
|
currentRow.value = void 0;
|
|
1150
1174
|
currentRowKey.value = void 0;
|
|
1175
|
+
updateActiveMergedCells(true);
|
|
1151
1176
|
} else {
|
|
1152
1177
|
currentRow.value = row;
|
|
1153
1178
|
currentRowKey.value = rowKeyGen(row);
|
|
1179
|
+
updateActiveMergedCells();
|
|
1154
1180
|
}
|
|
1155
1181
|
emits('current-change', e, row, { select: !isCurrentRow });
|
|
1156
1182
|
}
|
|
@@ -1331,7 +1357,24 @@ function onTableScroll(e: Event) {
|
|
|
1331
1357
|
function onTrMouseOver(_e: MouseEvent, row: DT) {
|
|
1332
1358
|
if (currentHoverRow === row) return;
|
|
1333
1359
|
currentHoverRow = row;
|
|
1334
|
-
|
|
1360
|
+
const rowKey = rowKeyGen(row);
|
|
1361
|
+
if (props.showTrHoverClass) {
|
|
1362
|
+
currentHoverRowKey.value = rowKey;
|
|
1363
|
+
}
|
|
1364
|
+
if (props.rowHover) {
|
|
1365
|
+
updateHoverMergedCells(rowKey);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
function onTrMouseLeave(e: MouseEvent) {
|
|
1370
|
+
if ((e.target as HTMLTableRowElement).tagName !== 'TR') return;
|
|
1371
|
+
currentHoverRow = null;
|
|
1372
|
+
if (props.showTrHoverClass) {
|
|
1373
|
+
currentHoverRowKey.value = null;
|
|
1374
|
+
}
|
|
1375
|
+
if (props.rowHover) {
|
|
1376
|
+
updateHoverMergedCells(void 0);
|
|
1377
|
+
}
|
|
1335
1378
|
}
|
|
1336
1379
|
|
|
1337
1380
|
/**
|
package/src/StkTable/style.less
CHANGED
|
@@ -151,7 +151,6 @@
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
/* 斑马纹*/
|
|
155
154
|
&.stripe {
|
|
156
155
|
&:not(.vt-on) .stk-tbody-main tr:nth-child(even) {
|
|
157
156
|
background-color: var(--stripe-bgc);
|
|
@@ -557,11 +556,17 @@
|
|
|
557
556
|
transition: transform 0.2s ease;
|
|
558
557
|
}
|
|
559
558
|
|
|
560
|
-
&:hover {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
border-left: 5px solid var(--fold-icon-hover-color);
|
|
564
|
-
}
|
|
559
|
+
&:hover::before {
|
|
560
|
+
border-left: 5px solid var(--fold-icon-hover-color);
|
|
565
561
|
}
|
|
566
562
|
}
|
|
563
|
+
|
|
564
|
+
td.cell-hover {
|
|
565
|
+
background-color: var(--tr-hover-bgc);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
td.cell-active {
|
|
569
|
+
background-color: var(--tr-active-bgc);
|
|
570
|
+
}
|
|
571
|
+
|
|
567
572
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, ConcreteComponent } from 'vue';
|
|
1
|
+
import { Component, ComputedRef, ConcreteComponent } from 'vue';
|
|
2
2
|
|
|
3
3
|
/** 排序方式,asc-正序,desc-倒序,null-默认顺序 */
|
|
4
4
|
export type Order = null | 'asc' | 'desc';
|
|
@@ -26,6 +26,15 @@ export type CustomHeaderCellProps<T extends Record<string, any>> = {
|
|
|
26
26
|
colIndex: number;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
export type MergeCellsParam<T extends Record<string, any>> = {
|
|
30
|
+
row: T;
|
|
31
|
+
col: StkTableColumn<T>;
|
|
32
|
+
rowIndex: number;
|
|
33
|
+
colIndex: number;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type MergeCellsFn<T extends Record<string, any>> = (data: MergeCellsParam<T>) => { rowspan?: number; colspan?: number } | undefined;
|
|
37
|
+
|
|
29
38
|
/**
|
|
30
39
|
* 自定义渲染单元格
|
|
31
40
|
*
|
|
@@ -82,8 +91,6 @@ export type StkTableColumn<T extends Record<string, any>> = {
|
|
|
82
91
|
sortConfig?: Pick<SortConfig<T>, 'emptyToBottom' | 'stringLocaleCompare'>;
|
|
83
92
|
/** 固定列 */
|
|
84
93
|
fixed?: 'left' | 'right' | null;
|
|
85
|
-
/** private */ rowSpan?: number;
|
|
86
|
-
/** private */ colSpan?: number;
|
|
87
94
|
/**
|
|
88
95
|
* 自定义 td 渲染内容。
|
|
89
96
|
*
|
|
@@ -106,17 +113,23 @@ export type StkTableColumn<T extends Record<string, any>> = {
|
|
|
106
113
|
customHeaderCell?: CustomCell<CustomHeaderCellProps<T>, T>;
|
|
107
114
|
/** 二级表头 */
|
|
108
115
|
children?: StkTableColumn<T>[];
|
|
116
|
+
/** 单元格合并 */
|
|
117
|
+
mergeCells?: MergeCellsFn<T>;
|
|
109
118
|
};
|
|
110
119
|
|
|
111
120
|
/** private StkTableColumn type. Add some private key */
|
|
112
121
|
export type PrivateStkTableColumn<T extends Record<string, any>> = StkTableColumn<T> & {
|
|
122
|
+
/** header rowSpan */
|
|
123
|
+
__R_SP__?: number;
|
|
124
|
+
/** header colSpan */
|
|
125
|
+
__C_SP__?: number;
|
|
113
126
|
/**
|
|
114
|
-
*
|
|
127
|
+
* parent not ref
|
|
115
128
|
* @private
|
|
116
129
|
*/
|
|
117
130
|
__PARENT__?: StkTableColumn<T> | null;
|
|
118
131
|
/**
|
|
119
|
-
*
|
|
132
|
+
* Save the calculated width. Used for horizontal virtual scrolling.
|
|
120
133
|
* @private
|
|
121
134
|
*/
|
|
122
135
|
__WIDTH__?: number;
|
|
@@ -258,3 +271,9 @@ export type AutoRowHeightConfig<DT> = {
|
|
|
258
271
|
export type ColResizableConfig<DT extends Record<string, any>> = {
|
|
259
272
|
disabled: (col: StkTableColumn<DT>) => boolean;
|
|
260
273
|
};
|
|
274
|
+
|
|
275
|
+
export type RowKeyGen = (row: any) => UniqKey;
|
|
276
|
+
|
|
277
|
+
export type ColKeyGen = ComputedRef<(col: StkTableColumn<any>) => UniqKey>;
|
|
278
|
+
|
|
279
|
+
export type CellKeyGen = (row: any, col: StkTableColumn<any>) => string;
|