stk-table-vue 1.0.0-beta.5 → 1.0.1
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 +174 -173
- package/lib/{Dropdown-Clc70S1z.js → Dropdown-wEI6qpCx.js} +2 -2
- package/lib/{StkTable-QUd4TJCF.js → StkTable-BK4VNsvG.js} +124 -20
- package/lib/src/StkTable/custom-cells/ChangeCell/createChangeCell.d.ts +55 -0
- package/lib/src/StkTable/custom-cells/ChangeCell/index.d.ts +2 -0
- package/lib/src/StkTable/custom-cells/NumberCell/createNumberCell.d.ts +44 -0
- package/lib/src/StkTable/custom-cells/NumberCell/index.d.ts +2 -0
- package/lib/src/StkTable/custom-cells/utils/formatNumber.d.ts +35 -0
- package/lib/src/StkTable/index.d.ts +7 -1
- package/lib/stk-table-vue.js +192 -12
- package/lib/style.css +41 -10
- package/package.json +89 -85
- package/src/StkTable/StkTable.vue +1849 -1849
- 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 -0
- package/src/StkTable/custom-cells/ChangeCell/createChangeCell.ts +90 -0
- package/src/StkTable/custom-cells/ChangeCell/index.ts +4 -0
- package/src/StkTable/custom-cells/CheckboxCell/{Checkbox.less → CheckboxCell.less} +14 -14
- package/src/StkTable/custom-cells/CheckboxCell/{Checkbox.vue → CheckboxCell.vue} +56 -41
- 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/EditableCell/EditableCell.less +1 -0
- package/src/StkTable/custom-cells/FilterCell/Dropdown/index.ts +16 -16
- package/src/StkTable/custom-cells/FilterCell/Dropdown/index.vue +184 -184
- 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 -0
- package/src/StkTable/custom-cells/NumberCell/index.ts +2 -0
- package/src/StkTable/custom-cells/utils/formatNumber.ts +137 -0
- package/src/StkTable/features/const.ts +1 -1
- package/src/StkTable/features/index.ts +1 -1
- package/src/StkTable/features/useAreaSelection.bak.ts +951 -951
- package/src/StkTable/features/useAreaSelection.ts +1224 -1079
- package/src/StkTable/index.ts +20 -14
- package/src/StkTable/registerFeature.ts +40 -40
- package/src/StkTable/style.less +776 -767
- package/src/StkTable/types/highlightDimOptions.ts +28 -28
- package/src/StkTable/types/index.ts +452 -452
- package/src/StkTable/useAutoResize.ts +87 -87
- package/src/StkTable/useColResize.ts +202 -202
- package/src/StkTable/useFixedCol.ts +142 -142
- 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 +50 -50
- package/src/StkTable/useMergeCells.ts +138 -138
- 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 +259 -259
- package/src/StkTable/useTableColumns.ts +131 -131
- package/src/StkTable/useThDrag.ts +94 -94
- package/src/StkTable/useTrDrag.ts +100 -100
- package/src/StkTable/useTree.ts +152 -152
- package/src/StkTable/useVirtualScroll.ts +693 -693
- package/src/StkTable/useWheeling.ts +23 -23
- package/src/StkTable/utils/constRefUtils.ts +29 -29
- 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
- /package/lib/src/StkTable/custom-cells/CheckboxCell/{Checkbox.vue.d.ts → CheckboxCell.vue.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,173 +1,174 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<a href="https://ja-plus.github.io/stk-table-vue/">
|
|
3
|
-
<img src="./docs-src/public/assets/logo.svg" width="152">
|
|
4
|
-
</a>
|
|
5
|
-
<h3 align='center'>Stk Table Vue</h3>
|
|
6
|
-
<p align="center">
|
|
7
|
-
<a href="https://www.npmjs.com/package/stk-table-vue"><img src="https://img.shields.io/npm/v/stk-table-vue"></a>
|
|
8
|
-
<a href="https://www.npmjs.com/package/stk-table-vue"><img src="https://img.shields.io/npm/dw/stk-table-vue"></a>
|
|
9
|
-
<a href="https://github.com/ja-plus/stk-table-vue/stargazers"><img src="https://img.shields.io/github/stars/ja-plus/stk-table-vue.svg"></a>
|
|
10
|
-
<a href="https://raw.githubusercontent.com/ja-plus/stk-table-vue/master/LICENSE"><img src="https://img.shields.io/npm/l/stk-table-vue"></a>
|
|
11
|
-
<a href="https://github.com/ja-plus/stk-table-vue"><img src="https://img.shields.io/npm/types/stk-table-vue"></a>
|
|
12
|
-
</p>
|
|
13
|
-
</p>
|
|
14
|
-
|
|
15
|
-
Stk Table Vue(Sticky Table) is a high-performance virtual list component based on Vue.
|
|
16
|
-
|
|
17
|
-
Smooth performance with tens of thousands of rows
|
|
18
|
-
|
|
19
|
-
Used for real-time data display, with data highlighting and dynamic effects.
|
|
20
|
-
|
|
21
|
-
Support Vue3 and Vue2.7
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## Documentation
|
|
25
|
-
### [Stk Table Vue Official](https://ja-plus.github.io/stk-table-vue/)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
{title: '
|
|
64
|
-
{title: '
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{id:
|
|
70
|
-
{id:
|
|
71
|
-
{id:
|
|
72
|
-
{id:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
:
|
|
113
|
-
:show-
|
|
114
|
-
:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
virtual
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
:
|
|
125
|
-
:
|
|
126
|
-
|
|
127
|
-
@
|
|
128
|
-
@
|
|
129
|
-
@row-
|
|
130
|
-
@row-
|
|
131
|
-
@
|
|
132
|
-
@
|
|
133
|
-
@
|
|
134
|
-
@
|
|
135
|
-
@scroll
|
|
136
|
-
@
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Compare
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://ja-plus.github.io/stk-table-vue/">
|
|
3
|
+
<img src="./docs-src/public/assets/logo.svg" width="152">
|
|
4
|
+
</a>
|
|
5
|
+
<h3 align='center'>Stk Table Vue</h3>
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://www.npmjs.com/package/stk-table-vue"><img src="https://img.shields.io/npm/v/stk-table-vue"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/stk-table-vue"><img src="https://img.shields.io/npm/dw/stk-table-vue"></a>
|
|
9
|
+
<a href="https://github.com/ja-plus/stk-table-vue/stargazers"><img src="https://img.shields.io/github/stars/ja-plus/stk-table-vue.svg"></a>
|
|
10
|
+
<a href="https://raw.githubusercontent.com/ja-plus/stk-table-vue/master/LICENSE"><img src="https://img.shields.io/npm/l/stk-table-vue"></a>
|
|
11
|
+
<a href="https://github.com/ja-plus/stk-table-vue"><img src="https://img.shields.io/npm/types/stk-table-vue"></a>
|
|
12
|
+
</p>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
Stk Table Vue(Sticky Table) is a high-performance virtual list component based on Vue.
|
|
16
|
+
|
|
17
|
+
Smooth performance with tens of thousands of rows
|
|
18
|
+
|
|
19
|
+
Used for real-time data display, with data highlighting and dynamic effects.
|
|
20
|
+
|
|
21
|
+
Support Vue3 and Vue2.7
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Documentation
|
|
25
|
+
### [Stk Table Vue Official](https://ja-plus.github.io/stk-table-vue/)
|
|
26
|
+
### [Stk Table React Official](https://ja-plus.github.io/stk-table-react/)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Repo:
|
|
30
|
+
- [Github](https://github.com/ja-plus/stk-table-vue)
|
|
31
|
+
- [Gitee](https://gitee.com/japlus/stk-table-vue)
|
|
32
|
+
|
|
33
|
+
## Demo
|
|
34
|
+
[<span style="font-size: 16px;font-weight: bold;">Online Demo in stackblitz</span>](https://stackblitz.com/edit/vitejs-vite-ad91hh?file=src%2FDemo%2Findex.vue)
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
> npm install stk-table-vue
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<script setup>
|
|
41
|
+
import { StkTable } from 'stk-table-vue'
|
|
42
|
+
import { ref, useTemplateRef } from 'vue'
|
|
43
|
+
const stkTableRef = ref<InstanceType<typeof StkTable>>();
|
|
44
|
+
// or Vue 3.5 useTemplateRef
|
|
45
|
+
const stkTableRef = useTemplateRef('stkTableRef');
|
|
46
|
+
|
|
47
|
+
// highlight row
|
|
48
|
+
stkTableRef.value.setHighlightDimRow([rowKey], {
|
|
49
|
+
method: 'css' | 'animation', // default animation
|
|
50
|
+
className: 'custom-class-name', // for method 'css'
|
|
51
|
+
keyframe: [{ backgroundColor: '#aaa' }, { backgroundColor: '#222' }], // same as https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Animations_API/Keyframe_Formats
|
|
52
|
+
duration: 2000,
|
|
53
|
+
});
|
|
54
|
+
// highlight cell
|
|
55
|
+
stkTableRef.value.setHighlightDimCell(rowKey, colDataIndex, {
|
|
56
|
+
method: 'css' | 'animation',
|
|
57
|
+
className: 'custom-class-name', // for method 'css'
|
|
58
|
+
keyframe: [{ backgroundColor: '#aaa' }, { backgroundColor: '#222' }], // for method 'animation'
|
|
59
|
+
duration: 2000,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const columns = [
|
|
63
|
+
{title: 'name', dataIndex: 'name'},
|
|
64
|
+
{title: 'age', dataIndex: 'age'},
|
|
65
|
+
{title: 'address', dataIndex: 'address'},
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
const dataSource = [
|
|
69
|
+
{id: 1, name: 'John', age: 32, address: 'New York'},
|
|
70
|
+
{id: 2, name: 'Jim', age: 42, address: 'London'},
|
|
71
|
+
{id: 3, name: 'Joe', age: 52, address: 'Tokyo'},
|
|
72
|
+
{id: 4, name: 'Jack', age: 62, address: 'Sydney'},
|
|
73
|
+
{id: 5, name: 'Jill', age: 72, address: 'Paris'},
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<template>
|
|
79
|
+
<StkTable ref='stkTableRef' row-key="id" :data-source="dataSource" :columns="columns"></StkTable>
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Vue2.7 Usage
|
|
85
|
+
[Vue2.7 Usage](https://ja-plus.github.io/stk-table-vue/main/start/vue2-usage.html)
|
|
86
|
+
|
|
87
|
+
## API
|
|
88
|
+
* [Props](https://ja-plus.github.io/stk-table-vue/main/api/table-props.html)
|
|
89
|
+
|
|
90
|
+
* [Emits](https://ja-plus.github.io/stk-table-vue/main/api/emits.html)
|
|
91
|
+
|
|
92
|
+
* [Slots](https://ja-plus.github.io/stk-table-vue/main/api/slots.html)
|
|
93
|
+
|
|
94
|
+
* [Expose](https://ja-plus.github.io/stk-table-vue/main/api/expose.html)
|
|
95
|
+
|
|
96
|
+
* [StkTableColumn: Define column type](https://ja-plus.github.io/stk-table-vue/main/api/stk-table-column.html)
|
|
97
|
+
|
|
98
|
+
* [Highlight: setHighlightDimCell & setHighlightDimRow](https://ja-plus.github.io/stk-table-vue/main/api/expose.html#sethighlightdimcell)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
### Example
|
|
102
|
+
```vue
|
|
103
|
+
<template>
|
|
104
|
+
<StkTable
|
|
105
|
+
ref="stkTable"
|
|
106
|
+
row-key="name"
|
|
107
|
+
v-model:columns="columns"
|
|
108
|
+
:style="{height:props.height}"
|
|
109
|
+
theme='dark'
|
|
110
|
+
height='200px'
|
|
111
|
+
bordered="h"
|
|
112
|
+
:row-height="28"
|
|
113
|
+
:show-overflow="false"
|
|
114
|
+
:show-header-overflow="false"
|
|
115
|
+
:sort-remote="false"
|
|
116
|
+
col-resizable
|
|
117
|
+
header-drag
|
|
118
|
+
virtual
|
|
119
|
+
virtual-x
|
|
120
|
+
no-data-full
|
|
121
|
+
col-resizable
|
|
122
|
+
auto-resize
|
|
123
|
+
fixed-col-shadow
|
|
124
|
+
:col-min-width="10"
|
|
125
|
+
:headless="false"
|
|
126
|
+
:data-source="dataSource"
|
|
127
|
+
@current-change="onCurrentChange"
|
|
128
|
+
@row-menu="onRowMenu"
|
|
129
|
+
@header-row-menu="onHeaderRowMenu"
|
|
130
|
+
@row-click="onRowClick"
|
|
131
|
+
@row-dblclick="onRowDblclick"
|
|
132
|
+
@sort-change="handleSortChange"
|
|
133
|
+
@cell-click="onCellClick"
|
|
134
|
+
@header-cell-click="onHeaderCellClick"
|
|
135
|
+
@scroll="onTableScroll"
|
|
136
|
+
@scroll-x="onTableScrollX"
|
|
137
|
+
@col-order-change="onColOrderChange"
|
|
138
|
+
/>
|
|
139
|
+
</template>
|
|
140
|
+
<script setup>
|
|
141
|
+
import { h, defineComponent } from 'vue';
|
|
142
|
+
const columns = [
|
|
143
|
+
{
|
|
144
|
+
title: 'Name',
|
|
145
|
+
dataIndex: 'name',
|
|
146
|
+
fixed: 'left',
|
|
147
|
+
width: '200px',
|
|
148
|
+
headerClassName: 'my-th',
|
|
149
|
+
className: 'my-td',
|
|
150
|
+
sorter: true,
|
|
151
|
+
customHeaderCell: function FunctionalComponent(props){
|
|
152
|
+
return h(
|
|
153
|
+
'span',
|
|
154
|
+
{ style: 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap' },
|
|
155
|
+
props.col.title + '(render) text-overflow,',
|
|
156
|
+
);
|
|
157
|
+
},
|
|
158
|
+
customCell: defineComponent({
|
|
159
|
+
setup(){
|
|
160
|
+
//...
|
|
161
|
+
return () => <div></div> // vue jsx
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
},
|
|
165
|
+
]
|
|
166
|
+
</script>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Compare
|
|
170
|
+
Compare performance with other vue table [vue-table-compare](https://github.com/ja-plus/vue-table-compare)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
## Other
|
|
174
|
+
* `$*$`
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* name: stk-table-vue
|
|
3
|
-
* version: v1.0.0
|
|
3
|
+
* version: v1.0.0
|
|
4
4
|
* description: High performance realtime virtual table for vue3 and vue2.7
|
|
5
5
|
* author: japlus
|
|
6
6
|
* homepage: https://ja-plus.github.io/stk-table-vue/
|
|
7
7
|
* license: MIT
|
|
8
8
|
*/
|
|
9
|
-
import { t as StkTable_default } from "./StkTable-
|
|
9
|
+
import { t as StkTable_default } from "./StkTable-BK4VNsvG.js";
|
|
10
10
|
import { createElementBlock, createElementVNode, createVNode, defineComponent, h, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, reactive, ref, withModifiers } from "vue";
|
|
11
11
|
//#region src/StkTable/custom-cells/FilterCell/Dropdown/index.vue?vue&type=script&setup=true&lang.ts
|
|
12
12
|
var DROPDOWN_DEFAULT_WIDTH = 300;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* name: stk-table-vue
|
|
3
|
-
* version: v1.0.0
|
|
3
|
+
* version: v1.0.0
|
|
4
4
|
* description: High performance realtime virtual table for vue3 and vue2.7
|
|
5
5
|
* author: japlus
|
|
6
6
|
* homepage: https://ja-plus.github.io/stk-table-vue/
|
|
@@ -347,12 +347,12 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
347
347
|
const KEY_ESCAPE = "Escape";
|
|
348
348
|
const KEY_ESC = "Esc";
|
|
349
349
|
const KEY_C = "c";
|
|
350
|
-
const
|
|
351
|
-
const
|
|
352
|
-
const
|
|
353
|
-
const
|
|
354
|
-
const
|
|
355
|
-
const
|
|
350
|
+
const ATTR_CELL_SELECTED = "data-cs-s";
|
|
351
|
+
const ATTR_CELL_TOP = "data-cs-t";
|
|
352
|
+
const ATTR_CELL_BOTTOM = "data-cs-b";
|
|
353
|
+
const ATTR_CELL_LEFT = "data-cs-l";
|
|
354
|
+
const ATTR_CELL_RIGHT = "data-cs-r";
|
|
355
|
+
const ATTR_ROW_SELECTED = "data-rs-s";
|
|
356
356
|
const selectionRanges = ref([]);
|
|
357
357
|
const isSelecting = ref(false);
|
|
358
358
|
/** start cell */
|
|
@@ -478,10 +478,17 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
478
478
|
if (!container) return;
|
|
479
479
|
const cellHighlight = highlightCellEnabled.value;
|
|
480
480
|
const rowHighlight = highlightRowEnabled.value;
|
|
481
|
-
const oldSelectedCells = container.querySelectorAll(
|
|
482
|
-
for (let i = 0; i < oldSelectedCells.length; i++)
|
|
483
|
-
|
|
484
|
-
|
|
481
|
+
const oldSelectedCells = container.querySelectorAll(`[${ATTR_CELL_SELECTED}]`);
|
|
482
|
+
for (let i = 0; i < oldSelectedCells.length; i++) {
|
|
483
|
+
const el = oldSelectedCells[i];
|
|
484
|
+
el.removeAttribute(ATTR_CELL_SELECTED);
|
|
485
|
+
el.removeAttribute(ATTR_CELL_TOP);
|
|
486
|
+
el.removeAttribute(ATTR_CELL_BOTTOM);
|
|
487
|
+
el.removeAttribute(ATTR_CELL_LEFT);
|
|
488
|
+
el.removeAttribute(ATTR_CELL_RIGHT);
|
|
489
|
+
}
|
|
490
|
+
const oldSelectedRows = container.querySelectorAll(`[${ATTR_ROW_SELECTED}]`);
|
|
491
|
+
for (let i = 0; i < oldSelectedRows.length; i++) oldSelectedRows[i].removeAttribute(ATTR_ROW_SELECTED);
|
|
485
492
|
recomputeSelectedCellKeys();
|
|
486
493
|
const ranges = selectionRanges.value;
|
|
487
494
|
if (!ranges.length) return;
|
|
@@ -491,7 +498,7 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
491
498
|
const { minRow, maxRow } = normalizeRange(range);
|
|
492
499
|
for (let r = minRow; r <= maxRow; r++) {
|
|
493
500
|
const tr = tbody.querySelector(`tr[data-row-i="${r}"]`);
|
|
494
|
-
if (tr) tr.
|
|
501
|
+
if (tr) tr.setAttribute(ATTR_ROW_SELECTED, "");
|
|
495
502
|
}
|
|
496
503
|
}
|
|
497
504
|
if (cellHighlight) {
|
|
@@ -521,12 +528,14 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
521
528
|
if (!row || !cols[colIndex]) continue;
|
|
522
529
|
const ck = cellKeyGen(row, cols[colIndex]);
|
|
523
530
|
if (!selectedCellKeys.has(ck)) continue;
|
|
524
|
-
td.
|
|
531
|
+
td.setAttribute(ATTR_CELL_SELECTED, "");
|
|
525
532
|
if (rowIndex >= lrMinRow && rowIndex <= lrMaxRow && colIndex >= lrMinCol && colIndex <= lrMaxCol) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (
|
|
529
|
-
if (
|
|
533
|
+
const effEndRow = rowIndex + (parseInt(td.getAttribute("rowspan") || "1", 10) || 1) - 1;
|
|
534
|
+
const effEndCol = colIndex + (parseInt(td.getAttribute("colspan") || "1", 10) || 1) - 1;
|
|
535
|
+
if (rowIndex === lrMinRow) td.setAttribute(ATTR_CELL_TOP, "");
|
|
536
|
+
if (effEndRow === lrMaxRow) td.setAttribute(ATTR_CELL_BOTTOM, "");
|
|
537
|
+
if (colIndex === lrMinCol) td.setAttribute(ATTR_CELL_LEFT, "");
|
|
538
|
+
if (effEndCol === lrMaxCol) td.setAttribute(ATTR_CELL_RIGHT, "");
|
|
530
539
|
}
|
|
531
540
|
}
|
|
532
541
|
}
|
|
@@ -642,6 +651,92 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
642
651
|
if (!colKey) return -1;
|
|
643
652
|
return colKeyToIndexMap.value.get(colKey) ?? -1;
|
|
644
653
|
}
|
|
654
|
+
/** 获取指定单元格的合并信息 [rowspan, colspan],无合并返回 [1, 1] */
|
|
655
|
+
function getMergeSpan(rowIndex, colIndex) {
|
|
656
|
+
const data = dataSourceCopy.value;
|
|
657
|
+
const cols = tableHeaderLast.value;
|
|
658
|
+
const row = data[rowIndex];
|
|
659
|
+
const col = cols[colIndex];
|
|
660
|
+
if (!row || !col || !col.mergeCells) return [1, 1];
|
|
661
|
+
const { rowspan = 1, colspan = 1 } = col.mergeCells({
|
|
662
|
+
row,
|
|
663
|
+
col,
|
|
664
|
+
rowIndex,
|
|
665
|
+
colIndex
|
|
666
|
+
}) || {};
|
|
667
|
+
return [rowspan || 1, colspan || 1];
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* 扩展选区范围,使其完整覆盖边界上部分选中的合并单元格
|
|
671
|
+
* en: Expand selection range to fully cover merged cells that are partially selected at boundaries
|
|
672
|
+
*/
|
|
673
|
+
function expandRangeToCoverMergedCells(range) {
|
|
674
|
+
const { minRow, maxRow, minCol, maxCol } = normalizeRange(range);
|
|
675
|
+
const data = dataSourceCopy.value;
|
|
676
|
+
const cols = tableHeaderLast.value;
|
|
677
|
+
const rowCount = data.length;
|
|
678
|
+
const colCount = cols.length;
|
|
679
|
+
const mergeColIndices = [];
|
|
680
|
+
for (let c = 0; c < colCount; c++) {
|
|
681
|
+
var _cols$c;
|
|
682
|
+
if ((_cols$c = cols[c]) === null || _cols$c === void 0 ? void 0 : _cols$c.mergeCells) mergeColIndices.push(c);
|
|
683
|
+
}
|
|
684
|
+
if (!mergeColIndices.length) return range;
|
|
685
|
+
let [eMinRow, eMaxRow, eMinCol, eMaxCol] = [
|
|
686
|
+
minRow,
|
|
687
|
+
maxRow,
|
|
688
|
+
minCol,
|
|
689
|
+
maxCol
|
|
690
|
+
];
|
|
691
|
+
let changed = true;
|
|
692
|
+
let guard = 0;
|
|
693
|
+
while (changed && guard++ < 100) {
|
|
694
|
+
changed = false;
|
|
695
|
+
for (const c of mergeColIndices) {
|
|
696
|
+
if (c < eMinCol || c > eMaxCol) continue;
|
|
697
|
+
const [rs] = getMergeSpan(eMaxRow, c);
|
|
698
|
+
if (rs > 1 && eMaxRow + rs - 1 < rowCount && eMaxRow + rs - 1 > eMaxRow) {
|
|
699
|
+
eMaxRow = eMaxRow + rs - 1;
|
|
700
|
+
changed = true;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
for (let r = eMinRow; r <= eMaxRow; r++) {
|
|
704
|
+
const [, cs] = getMergeSpan(r, eMaxCol);
|
|
705
|
+
if (cs > 1 && eMaxCol + cs - 1 < colCount && eMaxCol + cs - 1 > eMaxCol) {
|
|
706
|
+
eMaxCol = eMaxCol + cs - 1;
|
|
707
|
+
changed = true;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
for (const c of mergeColIndices) {
|
|
711
|
+
if (c < eMinCol || c > eMaxCol) continue;
|
|
712
|
+
for (let r = eMinRow - 1; r >= 0 && r > eMinRow - 500; r--) {
|
|
713
|
+
const [rs] = getMergeSpan(r, c);
|
|
714
|
+
if (rs <= 1) continue;
|
|
715
|
+
if (r + rs - 1 >= eMinRow) {
|
|
716
|
+
if (r < eMinRow) {
|
|
717
|
+
eMinRow = r;
|
|
718
|
+
changed = true;
|
|
719
|
+
}
|
|
720
|
+
} else break;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
for (let r = eMinRow; r <= eMaxRow; r++) for (let c = eMinCol - 1; c >= 0 && c > eMinCol - 500; c--) {
|
|
724
|
+
const [, cs] = getMergeSpan(r, c);
|
|
725
|
+
if (cs <= 1) continue;
|
|
726
|
+
if (c + cs - 1 >= eMinCol) {
|
|
727
|
+
if (c < eMinCol) {
|
|
728
|
+
eMinCol = c;
|
|
729
|
+
changed = true;
|
|
730
|
+
}
|
|
731
|
+
} else break;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
if (eMinRow === minRow && eMaxRow === maxRow && eMinCol === minCol && eMaxCol === maxCol) return range;
|
|
735
|
+
const { begin, end } = range.index;
|
|
736
|
+
const newBeginRow = begin.row < end.row || begin.row === end.row ? eMinRow : eMaxRow;
|
|
737
|
+
const newEndRow = begin.row < end.row || begin.row === end.row ? eMaxRow : eMinRow;
|
|
738
|
+
return makeRange(newBeginRow, begin.col <= end.col ? eMinCol : eMaxCol, newEndRow, begin.col <= end.col ? eMaxCol : eMinCol);
|
|
739
|
+
}
|
|
645
740
|
/** 获取列的左边距和宽度
|
|
646
741
|
* @param colIndex 列的绝对索引
|
|
647
742
|
* @returns [left, width]
|
|
@@ -720,10 +815,10 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
720
815
|
const colIndex = getColIndexByKey(getClosestColKey(e.target));
|
|
721
816
|
if (rowIndex < 0 || colIndex < 0) return;
|
|
722
817
|
const ctrlKey = e.ctrlKey || e.metaKey;
|
|
723
|
-
const range = makeRange(rowIndex, colIndex, rowIndex, colIndex);
|
|
818
|
+
const range = expandRangeToCoverMergedCells(makeRange(rowIndex, colIndex, rowIndex, colIndex));
|
|
724
819
|
if (e.shiftKey && anchorCell && shiftEnabled.value) {
|
|
725
820
|
const ranges = selectionRanges.value.slice();
|
|
726
|
-
const shiftRange = makeRange(anchorCell.rowIndex, anchorCell.colIndex, rowIndex, colIndex);
|
|
821
|
+
const shiftRange = expandRangeToCoverMergedCells(makeRange(anchorCell.rowIndex, anchorCell.colIndex, rowIndex, colIndex));
|
|
727
822
|
if (ranges.length) ranges[ranges.length - 1] = shiftRange;
|
|
728
823
|
else ranges.push(shiftRange);
|
|
729
824
|
selectionRanges.value = ranges;
|
|
@@ -762,7 +857,7 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
762
857
|
/** 更新最后一个选区的终点(拖拽过程中) */
|
|
763
858
|
function updateSelectionEnd(endRowIndex, endColIndex) {
|
|
764
859
|
if (!anchorCell) return;
|
|
765
|
-
const newRange = makeRange(anchorCell.rowIndex, anchorCell.colIndex, endRowIndex, endColIndex);
|
|
860
|
+
const newRange = expandRangeToCoverMergedCells(makeRange(anchorCell.rowIndex, anchorCell.colIndex, endRowIndex, endColIndex));
|
|
766
861
|
const ranges = [...selectionRanges.value];
|
|
767
862
|
if (ranges.length > 0) ranges[ranges.length - 1] = newRange;
|
|
768
863
|
else ranges.push(newRange);
|
|
@@ -825,6 +920,15 @@ function useAreaSelection(props, emits, tableContainerRef, dataSourceCopy, table
|
|
|
825
920
|
stopAutoScroll();
|
|
826
921
|
document.removeEventListener("mousemove", onDocumentMouseMove);
|
|
827
922
|
document.removeEventListener("mouseup", onDocumentMouseUp);
|
|
923
|
+
const ranges = selectionRanges.value;
|
|
924
|
+
if (ranges.length) {
|
|
925
|
+
const expanded = expandRangeToCoverMergedCells(ranges[ranges.length - 1]);
|
|
926
|
+
if (expanded !== ranges[ranges.length - 1]) {
|
|
927
|
+
const newRanges = [...ranges];
|
|
928
|
+
newRanges[newRanges.length - 1] = expanded;
|
|
929
|
+
selectionRanges.value = newRanges;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
828
932
|
emitSelectionChange();
|
|
829
933
|
}
|
|
830
934
|
function emitSelectionChange() {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FormatNumberOptions } from '../utils/formatNumber';
|
|
2
|
+
|
|
3
|
+
/** createChangeCell 配置选项 */
|
|
4
|
+
export interface CreateChangeCellOptions extends FormatNumberOptions {
|
|
5
|
+
/** 涨跌颜色是否反转:false=A股(涨红跌绿,默认),true=国际(涨绿跌红) */
|
|
6
|
+
colorReverse?: boolean;
|
|
7
|
+
/** 是否显示涨跌箭头 ▲/▼,默认 false */
|
|
8
|
+
arrow?: boolean;
|
|
9
|
+
/** 自定义上涨颜色(覆盖默认配色,传入后不受 colorReverse 影响) */
|
|
10
|
+
riseColor?: string;
|
|
11
|
+
/** 自定义下跌颜色 */
|
|
12
|
+
fallColor?: string;
|
|
13
|
+
/** 自定义平盘颜色 */
|
|
14
|
+
flatColor?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 涨跌单元格工厂函数
|
|
18
|
+
*
|
|
19
|
+
* 在 {@link formatNumber} 的基础上叠加涨跌染色与箭头。染色按 `cellValue` 正负判断,
|
|
20
|
+
* 颜色方向可通过 `colorReverse` 切换(A股 / 国际),也可用 `riseColor` 等自定义。
|
|
21
|
+
* 数字对齐请在列配置上设置 `align: 'right'`。
|
|
22
|
+
*
|
|
23
|
+
* @param options 格式化 + 染色/箭头选项
|
|
24
|
+
* @returns `ChangeCell` 组件构造函数,使用时需调用一次:`customCell: ChangeCell()`
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const { ChangeCell } = createChangeCell({ decimals: 2, showSign: true, arrow: true });
|
|
29
|
+
* const ChangeCellComp = ChangeCell();
|
|
30
|
+
* const columns = [
|
|
31
|
+
* { title: '涨跌额', dataIndex: 'change', align: 'right', customCell: ChangeCellComp },
|
|
32
|
+
* ];
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function createChangeCell(options?: CreateChangeCellOptions): {
|
|
36
|
+
ChangeCell: () => import('vue').Raw<import('vue').DefineComponent<{
|
|
37
|
+
row: any;
|
|
38
|
+
col: import('../..').StkTableColumn<any>;
|
|
39
|
+
cellValue: any;
|
|
40
|
+
rowIndex: number;
|
|
41
|
+
colIndex: number;
|
|
42
|
+
expanded?: import('../..').StkTableColumn<any> | undefined;
|
|
43
|
+
treeExpanded?: boolean | undefined;
|
|
44
|
+
}, () => import('vue').VNode<import('vue').RendererNode, import('vue').RendererElement, {
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
}>, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{
|
|
47
|
+
row: any;
|
|
48
|
+
col: import('../..').StkTableColumn<any>;
|
|
49
|
+
cellValue: any;
|
|
50
|
+
rowIndex: number;
|
|
51
|
+
colIndex: number;
|
|
52
|
+
expanded?: import('../..').StkTableColumn<any> | undefined;
|
|
53
|
+
treeExpanded?: boolean | undefined;
|
|
54
|
+
}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>>;
|
|
55
|
+
};
|