stk-table-vue 0.2.3 → 0.2.5
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 +18 -2
- package/lib/src/StkTable/StkTable.vue.d.ts +10 -1
- package/lib/src/StkTable/index.d.ts +1 -0
- package/lib/src/StkTable/types/index.d.ts +5 -0
- package/lib/src/StkTable/useFixedStyle.d.ts +3 -3
- package/lib/src/StkTable/useVirtualScroll.d.ts +3 -2
- package/lib/src/StkTable/utils.d.ts +3 -1
- package/lib/stk-table-vue.js +165 -91
- package/package.json +60 -60
- package/src/StkTable/StkTable.vue +41 -17
- package/src/StkTable/types/index.ts +5 -0
- package/src/StkTable/useFixedStyle.ts +49 -28
- package/src/StkTable/useHighlight.ts +3 -3
- package/src/StkTable/useKeyboardArrowScroll.ts +8 -4
- package/src/StkTable/useVirtualScroll.ts +42 -11
- package/src/StkTable/utils.ts +66 -41
package/src/StkTable/utils.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { Default_Col_Width } from './const';
|
|
2
2
|
import { Order, SortConfig, SortOption, SortState, StkTableColumn } from './types';
|
|
3
3
|
|
|
4
|
+
/** 是否空值 */
|
|
5
|
+
function isEmptyValue(val: any, isNumber?: boolean) {
|
|
6
|
+
let isEmpty = val === null || val === '';
|
|
7
|
+
if (isNumber) {
|
|
8
|
+
isEmpty ||= typeof val === 'boolean' || Number.isNaN(+val);
|
|
9
|
+
}
|
|
10
|
+
return isEmpty;
|
|
11
|
+
}
|
|
12
|
+
|
|
4
13
|
/**
|
|
5
14
|
* 对有序数组插入新数据
|
|
6
15
|
* @param sortState
|
|
@@ -10,15 +19,30 @@ import { Order, SortConfig, SortOption, SortState, StkTableColumn } from './type
|
|
|
10
19
|
* @param newItem 要插入的数据
|
|
11
20
|
* @param targetArray 表格数据
|
|
12
21
|
*/
|
|
13
|
-
export function insertToOrderedArray<T extends object>(
|
|
22
|
+
export function insertToOrderedArray<T extends object>(
|
|
23
|
+
sortState: SortState<keyof T>,
|
|
24
|
+
newItem: any,
|
|
25
|
+
targetArray: T[],
|
|
26
|
+
sortConfig: SortConfig<T> = {},
|
|
27
|
+
) {
|
|
14
28
|
const { dataIndex, order } = sortState;
|
|
29
|
+
sortConfig = { emptyToBottom: false, ...sortConfig };
|
|
15
30
|
let { sortType } = sortState;
|
|
16
31
|
if (!sortType) sortType = typeof newItem[dataIndex] as 'number' | 'string';
|
|
32
|
+
const isNumber = sortType === 'number';
|
|
17
33
|
const data = [...targetArray];
|
|
34
|
+
|
|
18
35
|
if (!order) {
|
|
36
|
+
// 没有排序的情况,插入在最上方
|
|
19
37
|
data.unshift(newItem);
|
|
20
38
|
return data;
|
|
21
39
|
}
|
|
40
|
+
|
|
41
|
+
if (sortConfig.emptyToBottom && isEmptyValue(data)) {
|
|
42
|
+
// 空值排在最下方
|
|
43
|
+
data.push(newItem);
|
|
44
|
+
}
|
|
45
|
+
|
|
22
46
|
// 二分插入
|
|
23
47
|
let sIndex = 0;
|
|
24
48
|
let eIndex = data.length - 1;
|
|
@@ -27,7 +51,7 @@ export function insertToOrderedArray<T extends object>(sortState: SortState<keyo
|
|
|
27
51
|
// console.log(sIndex, eIndex);
|
|
28
52
|
const midIndex = Math.floor((sIndex + eIndex) / 2);
|
|
29
53
|
const midVal: any = data[midIndex][dataIndex];
|
|
30
|
-
const compareRes = strCompare(midVal, targetVal,
|
|
54
|
+
const compareRes = strCompare(midVal, targetVal, isNumber, sortConfig.stringLocaleCompare);
|
|
31
55
|
if (compareRes === 0) {
|
|
32
56
|
//midVal == targetVal
|
|
33
57
|
sIndex = midIndex;
|
|
@@ -47,27 +71,34 @@ export function insertToOrderedArray<T extends object>(sortState: SortState<keyo
|
|
|
47
71
|
}
|
|
48
72
|
/**
|
|
49
73
|
* 字符串比较
|
|
50
|
-
* @param
|
|
51
|
-
* @param
|
|
52
|
-
* @param
|
|
74
|
+
* @param a
|
|
75
|
+
* @param b
|
|
76
|
+
* @param type 类型
|
|
77
|
+
* @param isNumber 是否是数字类型
|
|
78
|
+
* @param localeCompare 是否 使用Array.prototype.localeCompare
|
|
53
79
|
* @return {-1|0|1}
|
|
54
80
|
*/
|
|
55
|
-
function strCompare(a: string, b: string,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
81
|
+
function strCompare(a: string, b: string, isNumber: boolean, localeCompare = false): number {
|
|
82
|
+
let _a: number | string = a;
|
|
83
|
+
let _b: number | string = b;
|
|
84
|
+
if (isNumber) {
|
|
85
|
+
// 是数字就转数字
|
|
86
|
+
_a = +a;
|
|
87
|
+
_b = +b;
|
|
88
|
+
} else if (localeCompare) {
|
|
89
|
+
// 字符串才可以localeCompare
|
|
62
90
|
return String(a).localeCompare(b);
|
|
63
91
|
}
|
|
92
|
+
if (_a > _b) return 1;
|
|
93
|
+
else if (_a === _b) return 0;
|
|
94
|
+
else return -1;
|
|
64
95
|
}
|
|
65
96
|
|
|
66
97
|
/**
|
|
67
|
-
*
|
|
98
|
+
* 分离出空数据和非空数据成两个数组。NaN视为空数据。
|
|
68
99
|
* @param sortOption
|
|
69
100
|
* @param targetDataSource
|
|
70
|
-
* @param isNumber
|
|
101
|
+
* @param isNumber 是否数字
|
|
71
102
|
* @return [值数组,空数组]
|
|
72
103
|
*/
|
|
73
104
|
function separatedData<T extends Record<string, any>>(sortOption: SortOption<T>, targetDataSource: T[], isNumber?: boolean) {
|
|
@@ -77,11 +108,7 @@ function separatedData<T extends Record<string, any>>(sortOption: SortOption<T>,
|
|
|
77
108
|
for (let i = 0; i < targetDataSource.length; i++) {
|
|
78
109
|
const row = targetDataSource[i];
|
|
79
110
|
const sortField = sortOption.sortField || sortOption.dataIndex;
|
|
80
|
-
|
|
81
|
-
if (isNumber) {
|
|
82
|
-
isEmpty ||= typeof row[sortField] === 'boolean' || Number.isNaN(+row[sortField]);
|
|
83
|
-
}
|
|
84
|
-
|
|
111
|
+
const isEmpty = isEmptyValue(row[sortField], isNumber);
|
|
85
112
|
if (isEmpty) {
|
|
86
113
|
emptyArr.push(row);
|
|
87
114
|
} else {
|
|
@@ -127,30 +154,18 @@ export function tableSort<T extends Record<string, any>>(
|
|
|
127
154
|
if (!sortType) sortType = typeof dataSource[0][sortField] as 'number' | 'string';
|
|
128
155
|
|
|
129
156
|
const [valueArr, emptyArr] = separatedData(sortOption, targetDataSource, sortType === 'number');
|
|
157
|
+
const isNumber = sortType === 'number';
|
|
130
158
|
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
// 非数字当作最小值处理
|
|
134
|
-
if (order === 'asc') {
|
|
135
|
-
valueArr.sort((a, b) => +a[sortField] - +b[sortField]);
|
|
136
|
-
targetDataSource = [...emptyArr, ...valueArr];
|
|
137
|
-
} else {
|
|
138
|
-
valueArr.sort((a, b) => +b[sortField] - +a[sortField]);
|
|
139
|
-
targetDataSource = [...valueArr, ...emptyArr];
|
|
140
|
-
}
|
|
159
|
+
if (order === 'asc') {
|
|
160
|
+
valueArr.sort((a, b) => strCompare(a[sortField], b[sortField], isNumber, sortConfig.stringLocaleCompare));
|
|
141
161
|
} else {
|
|
142
|
-
|
|
143
|
-
if (order === 'asc') {
|
|
144
|
-
valueArr.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]));
|
|
145
|
-
targetDataSource = [...emptyArr, ...valueArr];
|
|
146
|
-
} else {
|
|
147
|
-
valueArr.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]) * -1);
|
|
148
|
-
targetDataSource = [...valueArr, ...emptyArr];
|
|
149
|
-
}
|
|
162
|
+
valueArr.sort((a, b) => strCompare(b[sortField], a[sortField], isNumber, sortConfig.stringLocaleCompare));
|
|
150
163
|
}
|
|
151
164
|
|
|
152
|
-
if (sortConfig.emptyToBottom) {
|
|
165
|
+
if (order === 'desc' || sortConfig.emptyToBottom) {
|
|
153
166
|
targetDataSource = [...valueArr, ...emptyArr];
|
|
167
|
+
} else {
|
|
168
|
+
targetDataSource = [...emptyArr, ...valueArr];
|
|
154
169
|
}
|
|
155
170
|
}
|
|
156
171
|
return targetDataSource;
|
|
@@ -169,8 +184,18 @@ export function howDeepTheHeader(arr: StkTableColumn<any>[], level = 1) {
|
|
|
169
184
|
|
|
170
185
|
/** 获取列宽 */
|
|
171
186
|
export function getColWidth(col: StkTableColumn<any> | null): number {
|
|
172
|
-
|
|
173
|
-
|
|
187
|
+
const val = col?.width ?? Default_Col_Width;
|
|
188
|
+
if (typeof val === 'number') {
|
|
189
|
+
return Math.floor(val);
|
|
190
|
+
}
|
|
191
|
+
return parseInt(val);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** 获取列宽配置。用于支持列宽配置数字 */
|
|
195
|
+
export function getColWidthStr(col: StkTableColumn<any> | null | undefined, key: 'width' | 'minWidth' | 'maxWidth' = 'width') {
|
|
196
|
+
const val = col?.[key];
|
|
197
|
+
if (typeof val === 'number') {
|
|
198
|
+
return val + 'px';
|
|
174
199
|
}
|
|
175
|
-
return
|
|
200
|
+
return val;
|
|
176
201
|
}
|