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.
Files changed (68) hide show
  1. package/README.md +194 -194
  2. package/lib/{Dropdown-D_9cB0rD.js → Dropdown-BAANgg_5.js} +2 -2
  3. package/lib/{StkTable-CVcmlZi9.js → StkTable-CGcxwpdb.js} +22 -6
  4. package/lib/src/StkTable/StkTable.vue.d.ts +18 -4
  5. package/lib/src/StkTable/types/index.d.ts +4 -1
  6. package/lib/src/StkTable/useVirtualScroll.d.ts +6 -1
  7. package/lib/stk-table-vue.js +3 -3
  8. package/lib/style.css +1 -1
  9. package/package.json +93 -93
  10. package/src/StkTable/StkTable.vue +2362 -2338
  11. package/src/StkTable/components/DragHandle.vue +9 -9
  12. package/src/StkTable/components/SortIcon.vue +6 -6
  13. package/src/StkTable/components/TreeNodeCell.vue +19 -19
  14. package/src/StkTable/components/TriangleIcon.vue +3 -3
  15. package/src/StkTable/const.ts +50 -50
  16. package/src/StkTable/custom-cells/ChangeCell/ChangeCell.less +34 -34
  17. package/src/StkTable/custom-cells/ChangeCell/createChangeCell.ts +90 -90
  18. package/src/StkTable/custom-cells/ChangeCell/index.ts +4 -4
  19. package/src/StkTable/custom-cells/CheckboxCell/CheckboxCell.less +14 -14
  20. package/src/StkTable/custom-cells/CheckboxCell/CheckboxCell.vue +56 -56
  21. package/src/StkTable/custom-cells/CheckboxCell/createCheckboxCell.ts +146 -146
  22. package/src/StkTable/custom-cells/CheckboxCell/index.ts +5 -5
  23. package/src/StkTable/custom-cells/FilterCell/Dropdown/index.ts +16 -16
  24. package/src/StkTable/custom-cells/FilterCell/Dropdown/index.vue +186 -186
  25. package/src/StkTable/custom-cells/FilterCell/Filter.less +118 -118
  26. package/src/StkTable/custom-cells/FilterCell/Filter.vue +66 -66
  27. package/src/StkTable/custom-cells/FilterCell/createFilterCell.ts +120 -120
  28. package/src/StkTable/custom-cells/FilterCell/index.ts +6 -6
  29. package/src/StkTable/custom-cells/FilterCell/types.ts +43 -43
  30. package/src/StkTable/custom-cells/NumberCell/createNumberCell.ts +43 -43
  31. package/src/StkTable/custom-cells/NumberCell/index.ts +2 -2
  32. package/src/StkTable/custom-cells/utils/formatNumber.ts +137 -137
  33. package/src/StkTable/features/const.ts +1 -1
  34. package/src/StkTable/features/index.ts +1 -1
  35. package/src/StkTable/features/useAreaSelection.ts +1240 -1239
  36. package/src/StkTable/index.ts +20 -20
  37. package/src/StkTable/mergeCellsCache.ts +69 -69
  38. package/src/StkTable/registerFeature.ts +40 -40
  39. package/src/StkTable/style.less +791 -791
  40. package/src/StkTable/types/highlightDimOptions.ts +28 -28
  41. package/src/StkTable/types/index.ts +503 -500
  42. package/src/StkTable/useAutoResize.ts +87 -87
  43. package/src/StkTable/useColResize.ts +202 -202
  44. package/src/StkTable/useFixedCol.ts +168 -168
  45. package/src/StkTable/useFixedStyle.ts +75 -75
  46. package/src/StkTable/useGetFixedColPosition.ts +63 -63
  47. package/src/StkTable/useHighlight.ts +270 -270
  48. package/src/StkTable/useIndexResolver.ts +29 -29
  49. package/src/StkTable/useKeyboardArrowScroll.ts +114 -114
  50. package/src/StkTable/useMaxRowSpan.ts +60 -60
  51. package/src/StkTable/useMergeCells.ts +541 -541
  52. package/src/StkTable/useRowExpand.ts +81 -81
  53. package/src/StkTable/useScrollRowByRow.ts +96 -96
  54. package/src/StkTable/useScrollbar.ts +177 -177
  55. package/src/StkTable/useSorter.ts +267 -267
  56. package/src/StkTable/useTableColumns.ts +142 -142
  57. package/src/StkTable/useThDrag.ts +94 -94
  58. package/src/StkTable/useTrDrag.ts +100 -100
  59. package/src/StkTable/useTree.ts +253 -253
  60. package/src/StkTable/useVirtualScroll.ts +1032 -1025
  61. package/src/StkTable/useWheeling.ts +23 -23
  62. package/src/StkTable/utils/constRefUtils.ts +29 -29
  63. package/src/StkTable/utils/index.ts +331 -331
  64. package/src/StkTable/utils/rowHeightFenwickTree.ts +74 -74
  65. package/src/StkTable/utils/useTriggerRef.ts +33 -33
  66. package/src/VirtualTree.vue +622 -622
  67. package/src/VirtualTreeSelect.vue +367 -367
  68. package/src/vite-env.d.ts +10 -10
@@ -1,270 +1,270 @@
1
- import { Ref, computed } from 'vue';
2
- import { HIGHLIGHT_CELL_CLASS, HIGHLIGHT_COLOR, HIGHLIGHT_DURATION, HIGHLIGHT_ROW_CLASS } from './const';
3
- import { HighlightConfig, UniqKey } from './types';
4
- import { HighlightDimCellOption, HighlightDimRowOption } from './types/highlightDimOptions';
5
-
6
- /** 存放高亮行信息 */
7
- type HighlightDimRowStore = {
8
- /** 动画开始时间戳 */
9
- readonly ts: number;
10
- /** 行是否可见 */
11
- visible: boolean;
12
- /** 动画关键帧 */
13
- keyframe: Parameters<Animatable['animate']>['0'];
14
- /** 动画初始持续时间 */
15
- readonly duration: number;
16
- /** 忽略不可见元素:获取不到dom时直接丢弃,不再循环计算 */
17
- ignoreInvisible?: boolean;
18
- };
19
-
20
- /**
21
- * 高亮单元格,行
22
- */
23
- export function useHighlight(props: any, stkTableId: string, tableContainerRef: Ref<HTMLDivElement | undefined>) {
24
- const config: HighlightConfig = props.highlightConfig;
25
-
26
- /** 高亮颜色 */
27
- const highlightColor = {
28
- light: HIGHLIGHT_COLOR.light,
29
- dark: HIGHLIGHT_COLOR.dark,
30
- };
31
- /** 持续时间 */
32
- const highlightDuration = computed(() => (config.duration ? config.duration * 1000 : HIGHLIGHT_DURATION));
33
- /** 高亮频率*/
34
- const highlightFrequency = computed(() => (config.fps && config.fps > 0 ? 1000 / config.fps : null));
35
- /** 高亮帧数(非帧率),用于 timing-function: steps() */
36
- const highlightSteps = computed(() => (highlightFrequency.value ? Math.round(highlightDuration.value / highlightFrequency.value) : null));
37
- /** 高亮开始 */
38
- const highlightFrom = computed(() => highlightColor[props.theme as 'light' | 'dark'].from);
39
-
40
- /**
41
- * 存放高亮行的状态-使用animation api实现
42
- * @key 行唯一键
43
- * @value 记录高亮配置
44
- */
45
- const highlightDimRowsAnimation = new Map<UniqKey, HighlightDimRowStore>();
46
- /** 是否正在计算高亮行的循环-使用animation api实现 */
47
- let calcHighlightDimLoopAnimation = false;
48
-
49
- /** 高亮后渐暗的行定时器 */
50
- const highlightDimRowsTimeout = new Map();
51
- /** 高亮后渐暗的单元格定时器 */
52
- const highlightDimCellsTimeout = new Map();
53
-
54
- /** 高亮函数的默认参数 */
55
- const defaultHighlightDimOption = computed(() => {
56
- const keyframe: PropertyIndexedKeyframes = { backgroundColor: [highlightFrom.value, ''] };
57
- if (highlightSteps.value) {
58
- keyframe.easing = `steps(${highlightSteps.value})`;
59
- }
60
- return { duration: highlightDuration.value, keyframe };
61
- });
62
-
63
- /**
64
- * 计算高亮渐暗颜色的循环
65
- */
66
- function calcRowHighlightLoop() {
67
- if (calcHighlightDimLoopAnimation) return;
68
- calcHighlightDimLoopAnimation = true;
69
- const recursion = () => {
70
- window.requestAnimationFrame(
71
- () => {
72
- const nowTs = performance.now();
73
- const keysToDelete: UniqKey[] = [];
74
- highlightDimRowsAnimation.forEach((store, rowKeyValue) => {
75
- const { ts, duration } = store;
76
- const timeOffset = nowTs - ts;
77
- if (timeOffset < duration) {
78
- const shouldDelete = updateRowAnimation(rowKeyValue, store, timeOffset);
79
- if (shouldDelete) {
80
- keysToDelete.push(rowKeyValue);
81
- }
82
- } else {
83
- keysToDelete.push(rowKeyValue);
84
- }
85
- });
86
- keysToDelete.forEach(key => highlightDimRowsAnimation.delete(key));
87
-
88
- if (highlightDimRowsAnimation.size) {
89
- recursion();
90
- } else {
91
- // 没有则停止循环
92
- calcHighlightDimLoopAnimation = false;
93
- highlightDimRowsAnimation.clear();
94
- }
95
- } /* , highlightFrequency */,
96
- );
97
- };
98
- recursion();
99
- }
100
-
101
- /**
102
- * 高亮一个单元格。暂不支持虚拟滚动高亮状态记忆。
103
- * @param rowKeyValue 一行的key
104
- * @param colKeyValue 列key
105
- * @param options.method css-使用css渲染,animation-使用animation api。默认animation;
106
- * @param option.className 自定义css动画的class。
107
- * @param option.keyframe 如果自定义keyframe,则 highlightConfig.fps 将会失效。Keyframe:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Animations_API/Keyframe_Formats
108
- * @param option.duration 动画时长。method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。
109
- */
110
- function setHighlightDimCell(rowKeyValue: UniqKey, colKeyValue: string, option: HighlightDimCellOption = {}) {
111
- const cellEl = tableContainerRef.value?.querySelector<HTMLElement>(`[data-row-key="${rowKeyValue}"] [data-col-key="${colKeyValue}"]`);
112
- if (!cellEl) return;
113
- const { className, method, duration, keyframe } = {
114
- className: HIGHLIGHT_CELL_CLASS,
115
- method: 'animation',
116
- ...defaultHighlightDimOption.value,
117
- ...option,
118
- };
119
- if (method === 'animation') {
120
- cellEl.animate(keyframe, duration);
121
- } else {
122
- highlightCellsInCssKeyFrame(cellEl, rowKeyValue, colKeyValue, className, duration);
123
- }
124
- }
125
-
126
- /**
127
- * 高亮一行
128
- * @param rowKeyValues 行唯一键的数组
129
- * @param option.method css-使用css渲染,animation-使用animation api,js-使用js计算颜色。默认animation
130
- * @param option.className 自定义css动画的class。
131
- * @param option.keyframe 如果自定义keyframe,则 highlightConfig.fps 将会失效。Keyframe:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Animations_API/Keyframe_Formats。
132
- * @param option.duration 动画时长。method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。。
133
- */
134
- function setHighlightDimRow(rowKeyValues: UniqKey[], option: HighlightDimRowOption = {}) {
135
- if (!Array.isArray(rowKeyValues)) rowKeyValues = [rowKeyValues];
136
- if (!rowKeyValues.length) return;
137
- const { className, method, keyframe, duration } = {
138
- className: HIGHLIGHT_ROW_CLASS,
139
- method: 'animation',
140
- ...defaultHighlightDimOption.value,
141
- ...option,
142
- };
143
-
144
- const ignoreInvisible = Boolean(option.ignoreInvisible);
145
- if (method === 'animation') {
146
- if (props.virtual) {
147
- // -------- 用animation 接口实现动画
148
- const nowTs = performance.now();
149
- for (let i = 0; i < rowKeyValues.length; i++) {
150
- const rowKeyValue = rowKeyValues[i];
151
- const store: HighlightDimRowStore = { ts: nowTs, visible: false, keyframe, duration, ignoreInvisible };
152
- const shouldDelete = updateRowAnimation(rowKeyValue, store, 0);
153
- // ignoreInvisible: 获取不到dom则直接丢弃,不放入store;已存在也删除
154
- if (ignoreInvisible && shouldDelete) {
155
- highlightDimRowsAnimation.delete(rowKeyValue);
156
- } else {
157
- highlightDimRowsAnimation.set(rowKeyValue, store);
158
- }
159
- }
160
- calcRowHighlightLoop();
161
- } else {
162
- // -------- use Element.animate
163
- for (let i = 0; i < rowKeyValues.length; i++) {
164
- const rowEl = document.getElementById(stkTableId + '-' + String(rowKeyValues[i])) as HTMLTableRowElement | null;
165
- if (!rowEl) continue;
166
- rowEl.animate(keyframe, duration);
167
- }
168
- }
169
- } else {
170
- // -------- use css keyframe
171
- highlightRowsInCssKeyframe(rowKeyValues, className, duration);
172
- }
173
- }
174
-
175
- /**
176
- * 使用css @keyframes动画,实现高亮行动画
177
- * 此方案作为兼容方式。v0.3.4 将使用Element.animate 接口实现动画。
178
- */
179
- function highlightRowsInCssKeyframe(rowKeyValues: UniqKey[], className: string, duration: number) {
180
- /**是否需要重绘 */
181
- let needRepaint = false;
182
- const rowElTemp: HTMLTableRowElement[] = [];
183
- for (let i = 0; i < rowKeyValues.length; i++) {
184
- const rowKeyValue = rowKeyValues[i];
185
- const rowEl = document.getElementById(stkTableId + '-' + String(rowKeyValue)) as HTMLTableRowElement | null;
186
- if (!rowEl) continue;
187
- if (rowEl.classList.contains(className)) {
188
- rowEl.classList.remove(className);
189
- needRepaint = true;
190
- }
191
- rowElTemp.push(rowEl);
192
- // 动画结束移除class
193
- window.clearTimeout(highlightDimRowsTimeout.get(rowKeyValue));
194
- highlightDimRowsTimeout.set(
195
- rowKeyValue,
196
- window.setTimeout(() => {
197
- rowEl.classList.remove(className);
198
- highlightDimRowsTimeout.delete(rowKeyValue); // 回收内存
199
- }, duration),
200
- );
201
- }
202
- if (needRepaint) {
203
- void tableContainerRef.value?.offsetWidth; //强制浏览器重绘
204
- }
205
- rowElTemp.forEach(el => el.classList.add(className)); // 统一添加动画
206
- }
207
-
208
- /**
209
- * 使用css @keyframes动画,实现高亮单元格动画
210
- * 此方案作为兼容方式。v0.3.4 将使用Element.animate 接口实现动画。
211
- */
212
- function highlightCellsInCssKeyFrame(cellEl: HTMLElement, rowKeyValue: UniqKey, colKeyValue: string, className: string, duration: number) {
213
- if (cellEl.classList.contains(className)) {
214
- cellEl.classList.remove(className);
215
- void cellEl.offsetHeight; // 通知浏览器重绘
216
- }
217
- cellEl.classList.add(className);
218
- const cellKey = `${rowKeyValue}-${colKeyValue}`;
219
- window.clearTimeout(highlightDimCellsTimeout.get(cellKey));
220
- if (!duration) {
221
- return;
222
- }
223
- highlightDimCellsTimeout.set(
224
- cellKey,
225
- window.setTimeout(() => {
226
- cellEl.classList.remove(className);
227
- highlightDimCellsTimeout.delete(cellKey);
228
- }, duration),
229
- );
230
- }
231
-
232
- /**
233
- * 更新行状态
234
- * @param rowKeyValue 行唯一键
235
- * @param store highlightDimRowStore 的引用对象
236
- * @param timeOffset 距动画开始经过的时长
237
- * @returns 是否应该从store中删除(ignoreInvisible为true且DOM不存在时返回true)
238
- */
239
- function updateRowAnimation(rowKeyValue: UniqKey, store: HighlightDimRowStore, timeOffset: number): boolean {
240
- const rowEl = document.getElementById(stkTableId + '-' + String(rowKeyValue));
241
- const { visible, ignoreInvisible } = store;
242
- if (!rowEl) {
243
- // ignoreInvisible: 获取不到dom则直接丢弃,不再循环计算
244
- if (ignoreInvisible) {
245
- return true;
246
- }
247
- if (visible) {
248
- store.visible = false; // 标记为不可见
249
- }
250
- return false;
251
- }
252
- const { keyframe, duration: initialDuration } = store;
253
- // 只有元素 不可见 -> 可见 时才需要更新
254
- if (!visible) {
255
- store.visible = true; // 标记为可见
256
- /** 经过的时间 ÷ 高亮持续时间 计算出 颜色过渡进度 (0-1) */
257
- const iterationStart = timeOffset / initialDuration;
258
- rowEl.animate(keyframe, {
259
- duration: initialDuration - timeOffset,
260
- /** 从什么时候开始,0-1 */
261
- iterationStart,
262
- /** 持续多久 0-1 */
263
- iterations: 1 - iterationStart,
264
- });
265
- }
266
- return false;
267
- }
268
-
269
- return [highlightSteps, setHighlightDimRow, setHighlightDimCell] as const;
270
- }
1
+ import { Ref, computed } from 'vue';
2
+ import { HIGHLIGHT_CELL_CLASS, HIGHLIGHT_COLOR, HIGHLIGHT_DURATION, HIGHLIGHT_ROW_CLASS } from './const';
3
+ import { HighlightConfig, UniqKey } from './types';
4
+ import { HighlightDimCellOption, HighlightDimRowOption } from './types/highlightDimOptions';
5
+
6
+ /** 存放高亮行信息 */
7
+ type HighlightDimRowStore = {
8
+ /** 动画开始时间戳 */
9
+ readonly ts: number;
10
+ /** 行是否可见 */
11
+ visible: boolean;
12
+ /** 动画关键帧 */
13
+ keyframe: Parameters<Animatable['animate']>['0'];
14
+ /** 动画初始持续时间 */
15
+ readonly duration: number;
16
+ /** 忽略不可见元素:获取不到dom时直接丢弃,不再循环计算 */
17
+ ignoreInvisible?: boolean;
18
+ };
19
+
20
+ /**
21
+ * 高亮单元格,行
22
+ */
23
+ export function useHighlight(props: any, stkTableId: string, tableContainerRef: Ref<HTMLDivElement | undefined>) {
24
+ const config: HighlightConfig = props.highlightConfig;
25
+
26
+ /** 高亮颜色 */
27
+ const highlightColor = {
28
+ light: HIGHLIGHT_COLOR.light,
29
+ dark: HIGHLIGHT_COLOR.dark,
30
+ };
31
+ /** 持续时间 */
32
+ const highlightDuration = computed(() => (config.duration ? config.duration * 1000 : HIGHLIGHT_DURATION));
33
+ /** 高亮频率*/
34
+ const highlightFrequency = computed(() => (config.fps && config.fps > 0 ? 1000 / config.fps : null));
35
+ /** 高亮帧数(非帧率),用于 timing-function: steps() */
36
+ const highlightSteps = computed(() => (highlightFrequency.value ? Math.round(highlightDuration.value / highlightFrequency.value) : null));
37
+ /** 高亮开始 */
38
+ const highlightFrom = computed(() => highlightColor[props.theme as 'light' | 'dark'].from);
39
+
40
+ /**
41
+ * 存放高亮行的状态-使用animation api实现
42
+ * @key 行唯一键
43
+ * @value 记录高亮配置
44
+ */
45
+ const highlightDimRowsAnimation = new Map<UniqKey, HighlightDimRowStore>();
46
+ /** 是否正在计算高亮行的循环-使用animation api实现 */
47
+ let calcHighlightDimLoopAnimation = false;
48
+
49
+ /** 高亮后渐暗的行定时器 */
50
+ const highlightDimRowsTimeout = new Map();
51
+ /** 高亮后渐暗的单元格定时器 */
52
+ const highlightDimCellsTimeout = new Map();
53
+
54
+ /** 高亮函数的默认参数 */
55
+ const defaultHighlightDimOption = computed(() => {
56
+ const keyframe: PropertyIndexedKeyframes = { backgroundColor: [highlightFrom.value, ''] };
57
+ if (highlightSteps.value) {
58
+ keyframe.easing = `steps(${highlightSteps.value})`;
59
+ }
60
+ return { duration: highlightDuration.value, keyframe };
61
+ });
62
+
63
+ /**
64
+ * 计算高亮渐暗颜色的循环
65
+ */
66
+ function calcRowHighlightLoop() {
67
+ if (calcHighlightDimLoopAnimation) return;
68
+ calcHighlightDimLoopAnimation = true;
69
+ const recursion = () => {
70
+ window.requestAnimationFrame(
71
+ () => {
72
+ const nowTs = performance.now();
73
+ const keysToDelete: UniqKey[] = [];
74
+ highlightDimRowsAnimation.forEach((store, rowKeyValue) => {
75
+ const { ts, duration } = store;
76
+ const timeOffset = nowTs - ts;
77
+ if (timeOffset < duration) {
78
+ const shouldDelete = updateRowAnimation(rowKeyValue, store, timeOffset);
79
+ if (shouldDelete) {
80
+ keysToDelete.push(rowKeyValue);
81
+ }
82
+ } else {
83
+ keysToDelete.push(rowKeyValue);
84
+ }
85
+ });
86
+ keysToDelete.forEach(key => highlightDimRowsAnimation.delete(key));
87
+
88
+ if (highlightDimRowsAnimation.size) {
89
+ recursion();
90
+ } else {
91
+ // 没有则停止循环
92
+ calcHighlightDimLoopAnimation = false;
93
+ highlightDimRowsAnimation.clear();
94
+ }
95
+ } /* , highlightFrequency */,
96
+ );
97
+ };
98
+ recursion();
99
+ }
100
+
101
+ /**
102
+ * 高亮一个单元格。暂不支持虚拟滚动高亮状态记忆。
103
+ * @param rowKeyValue 一行的key
104
+ * @param colKeyValue 列key
105
+ * @param options.method css-使用css渲染,animation-使用animation api。默认animation;
106
+ * @param option.className 自定义css动画的class。
107
+ * @param option.keyframe 如果自定义keyframe,则 highlightConfig.fps 将会失效。Keyframe:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Animations_API/Keyframe_Formats
108
+ * @param option.duration 动画时长。method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。
109
+ */
110
+ function setHighlightDimCell(rowKeyValue: UniqKey, colKeyValue: string, option: HighlightDimCellOption = {}) {
111
+ const cellEl = tableContainerRef.value?.querySelector<HTMLElement>(`[data-row-key="${rowKeyValue}"] [data-col-key="${colKeyValue}"]`);
112
+ if (!cellEl) return;
113
+ const { className, method, duration, keyframe } = {
114
+ className: HIGHLIGHT_CELL_CLASS,
115
+ method: 'animation',
116
+ ...defaultHighlightDimOption.value,
117
+ ...option,
118
+ };
119
+ if (method === 'animation') {
120
+ cellEl.animate(keyframe, duration);
121
+ } else {
122
+ highlightCellsInCssKeyFrame(cellEl, rowKeyValue, colKeyValue, className, duration);
123
+ }
124
+ }
125
+
126
+ /**
127
+ * 高亮一行
128
+ * @param rowKeyValues 行唯一键的数组
129
+ * @param option.method css-使用css渲染,animation-使用animation api,js-使用js计算颜色。默认animation
130
+ * @param option.className 自定义css动画的class。
131
+ * @param option.keyframe 如果自定义keyframe,则 highlightConfig.fps 将会失效。Keyframe:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Animations_API/Keyframe_Formats。
132
+ * @param option.duration 动画时长。method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。。
133
+ */
134
+ function setHighlightDimRow(rowKeyValues: UniqKey[], option: HighlightDimRowOption = {}) {
135
+ if (!Array.isArray(rowKeyValues)) rowKeyValues = [rowKeyValues];
136
+ if (!rowKeyValues.length) return;
137
+ const { className, method, keyframe, duration } = {
138
+ className: HIGHLIGHT_ROW_CLASS,
139
+ method: 'animation',
140
+ ...defaultHighlightDimOption.value,
141
+ ...option,
142
+ };
143
+
144
+ const ignoreInvisible = Boolean(option.ignoreInvisible);
145
+ if (method === 'animation') {
146
+ if (props.virtual) {
147
+ // -------- 用animation 接口实现动画
148
+ const nowTs = performance.now();
149
+ for (let i = 0; i < rowKeyValues.length; i++) {
150
+ const rowKeyValue = rowKeyValues[i];
151
+ const store: HighlightDimRowStore = { ts: nowTs, visible: false, keyframe, duration, ignoreInvisible };
152
+ const shouldDelete = updateRowAnimation(rowKeyValue, store, 0);
153
+ // ignoreInvisible: 获取不到dom则直接丢弃,不放入store;已存在也删除
154
+ if (ignoreInvisible && shouldDelete) {
155
+ highlightDimRowsAnimation.delete(rowKeyValue);
156
+ } else {
157
+ highlightDimRowsAnimation.set(rowKeyValue, store);
158
+ }
159
+ }
160
+ calcRowHighlightLoop();
161
+ } else {
162
+ // -------- use Element.animate
163
+ for (let i = 0; i < rowKeyValues.length; i++) {
164
+ const rowEl = document.getElementById(stkTableId + '-' + String(rowKeyValues[i])) as HTMLTableRowElement | null;
165
+ if (!rowEl) continue;
166
+ rowEl.animate(keyframe, duration);
167
+ }
168
+ }
169
+ } else {
170
+ // -------- use css keyframe
171
+ highlightRowsInCssKeyframe(rowKeyValues, className, duration);
172
+ }
173
+ }
174
+
175
+ /**
176
+ * 使用css @keyframes动画,实现高亮行动画
177
+ * 此方案作为兼容方式。v0.3.4 将使用Element.animate 接口实现动画。
178
+ */
179
+ function highlightRowsInCssKeyframe(rowKeyValues: UniqKey[], className: string, duration: number) {
180
+ /**是否需要重绘 */
181
+ let needRepaint = false;
182
+ const rowElTemp: HTMLTableRowElement[] = [];
183
+ for (let i = 0; i < rowKeyValues.length; i++) {
184
+ const rowKeyValue = rowKeyValues[i];
185
+ const rowEl = document.getElementById(stkTableId + '-' + String(rowKeyValue)) as HTMLTableRowElement | null;
186
+ if (!rowEl) continue;
187
+ if (rowEl.classList.contains(className)) {
188
+ rowEl.classList.remove(className);
189
+ needRepaint = true;
190
+ }
191
+ rowElTemp.push(rowEl);
192
+ // 动画结束移除class
193
+ window.clearTimeout(highlightDimRowsTimeout.get(rowKeyValue));
194
+ highlightDimRowsTimeout.set(
195
+ rowKeyValue,
196
+ window.setTimeout(() => {
197
+ rowEl.classList.remove(className);
198
+ highlightDimRowsTimeout.delete(rowKeyValue); // 回收内存
199
+ }, duration),
200
+ );
201
+ }
202
+ if (needRepaint) {
203
+ void tableContainerRef.value?.offsetWidth; //强制浏览器重绘
204
+ }
205
+ rowElTemp.forEach(el => el.classList.add(className)); // 统一添加动画
206
+ }
207
+
208
+ /**
209
+ * 使用css @keyframes动画,实现高亮单元格动画
210
+ * 此方案作为兼容方式。v0.3.4 将使用Element.animate 接口实现动画。
211
+ */
212
+ function highlightCellsInCssKeyFrame(cellEl: HTMLElement, rowKeyValue: UniqKey, colKeyValue: string, className: string, duration: number) {
213
+ if (cellEl.classList.contains(className)) {
214
+ cellEl.classList.remove(className);
215
+ void cellEl.offsetHeight; // 通知浏览器重绘
216
+ }
217
+ cellEl.classList.add(className);
218
+ const cellKey = `${rowKeyValue}-${colKeyValue}`;
219
+ window.clearTimeout(highlightDimCellsTimeout.get(cellKey));
220
+ if (!duration) {
221
+ return;
222
+ }
223
+ highlightDimCellsTimeout.set(
224
+ cellKey,
225
+ window.setTimeout(() => {
226
+ cellEl.classList.remove(className);
227
+ highlightDimCellsTimeout.delete(cellKey);
228
+ }, duration),
229
+ );
230
+ }
231
+
232
+ /**
233
+ * 更新行状态
234
+ * @param rowKeyValue 行唯一键
235
+ * @param store highlightDimRowStore 的引用对象
236
+ * @param timeOffset 距动画开始经过的时长
237
+ * @returns 是否应该从store中删除(ignoreInvisible为true且DOM不存在时返回true)
238
+ */
239
+ function updateRowAnimation(rowKeyValue: UniqKey, store: HighlightDimRowStore, timeOffset: number): boolean {
240
+ const rowEl = document.getElementById(stkTableId + '-' + String(rowKeyValue));
241
+ const { visible, ignoreInvisible } = store;
242
+ if (!rowEl) {
243
+ // ignoreInvisible: 获取不到dom则直接丢弃,不再循环计算
244
+ if (ignoreInvisible) {
245
+ return true;
246
+ }
247
+ if (visible) {
248
+ store.visible = false; // 标记为不可见
249
+ }
250
+ return false;
251
+ }
252
+ const { keyframe, duration: initialDuration } = store;
253
+ // 只有元素 不可见 -> 可见 时才需要更新
254
+ if (!visible) {
255
+ store.visible = true; // 标记为可见
256
+ /** 经过的时间 ÷ 高亮持续时间 计算出 颜色过渡进度 (0-1) */
257
+ const iterationStart = timeOffset / initialDuration;
258
+ rowEl.animate(keyframe, {
259
+ duration: initialDuration - timeOffset,
260
+ /** 从什么时候开始,0-1 */
261
+ iterationStart,
262
+ /** 持续多久 0-1 */
263
+ iterations: 1 - iterationStart,
264
+ });
265
+ }
266
+ return false;
267
+ }
268
+
269
+ return [highlightSteps, setHighlightDimRow, setHighlightDimCell] as const;
270
+ }
@@ -1,29 +1,29 @@
1
- import type { Ref } from 'vue';
2
- import type { StkTableColumn, UniqKey } from './types';
3
-
4
- export function useIndexResolver<DT extends Record<string, any>>(
5
- dataSourceRef: Ref<DT[]>,
6
- columnsRef: Ref<StkTableColumn<DT>[]>,
7
- rowKeyGen: (row: DT | null | undefined) => UniqKey,
8
- ) {
9
- function getRowIndex(row: DT): number {
10
- const targetKey = rowKeyGen(row);
11
- const data = dataSourceRef.value;
12
- for (let i = 0; i < data.length; i++) {
13
- if (rowKeyGen(data[i]) === targetKey) return i;
14
- }
15
- return -1;
16
- }
17
-
18
- function getColumnIndex(column: StkTableColumn<DT>): number {
19
- const targetDataIndex = column?.dataIndex;
20
- if (targetDataIndex === void 0 || targetDataIndex === null) return -1;
21
- const columns = columnsRef.value;
22
- for (let i = 0; i < columns.length; i++) {
23
- if (columns[i]?.dataIndex === targetDataIndex) return i;
24
- }
25
- return -1;
26
- }
27
-
28
- return [getRowIndex, getColumnIndex] as const;
29
- }
1
+ import type { Ref } from 'vue';
2
+ import type { StkTableColumn, UniqKey } from './types';
3
+
4
+ export function useIndexResolver<DT extends Record<string, any>>(
5
+ dataSourceRef: Ref<DT[]>,
6
+ columnsRef: Ref<StkTableColumn<DT>[]>,
7
+ rowKeyGen: (row: DT | null | undefined) => UniqKey,
8
+ ) {
9
+ function getRowIndex(row: DT): number {
10
+ const targetKey = rowKeyGen(row);
11
+ const data = dataSourceRef.value;
12
+ for (let i = 0; i < data.length; i++) {
13
+ if (rowKeyGen(data[i]) === targetKey) return i;
14
+ }
15
+ return -1;
16
+ }
17
+
18
+ function getColumnIndex(column: StkTableColumn<DT>): number {
19
+ const targetDataIndex = column?.dataIndex;
20
+ if (targetDataIndex === void 0 || targetDataIndex === null) return -1;
21
+ const columns = columnsRef.value;
22
+ for (let i = 0; i < columns.length; i++) {
23
+ if (columns[i]?.dataIndex === targetDataIndex) return i;
24
+ }
25
+ return -1;
26
+ }
27
+
28
+ return [getRowIndex, getColumnIndex] as const;
29
+ }