stk-table-vue 0.4.0 → 0.4.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 CHANGED
@@ -8,8 +8,11 @@ repo:
8
8
  - [Github](https://github.com/ja-plus/stk-table-vue)
9
9
  - [Gitee](https://gitee.com/japlus/stk-table-vue) 🇨🇳
10
10
 
11
+ [<span style="font-size: 16px;font-weight: bold;">Online Demo</span>](https://stackblitz.com/edit/vitejs-vite-ad91hh?file=src%2FDemo%2Findex.vue)
12
+
11
13
  ## Bug TODO:
12
14
  * [x] props.dataSource 为 shallowRef 时,高亮行不生效。(bug:2024.02.21)(resolved:0.2.3)
15
+ * [] 固定列列宽拖动目标。
13
16
 
14
17
  ## Feature TODO:
15
18
  * [x] 高亮行,单元格。使用css @keyframes实现。
@@ -217,7 +220,7 @@ export type StkProps = {
217
220
  */
218
221
  stringLocaleCompare?: boolean;
219
222
  },
220
- /** 隐藏头部title。可传入dataIndex数组 */
223
+ /** 隐藏头部鼠标悬浮title。可传入dataIndex数组 */
221
224
  hideHeaderTitle?: boolean | string[];
222
225
  /** 高亮配置 */
223
226
  highlightConfig?: {
@@ -232,8 +235,8 @@ export type StkProps = {
232
235
  startIndex?: number;
233
236
  };
234
237
  /**
235
- * 固定头,固定列实现方式。(非响应式)
236
- *
238
+ * 固定头,固定列实现方式。
239
+ * [非响应式]
237
240
  * relative:固定列只能放在props.columns的两侧。
238
241
  * - 如果列宽会变动则谨慎使用。
239
242
  * - 多级表头固定列慎用
@@ -464,20 +467,20 @@ export type SortConfig<T extends Record<string, any>> = {
464
467
  )
465
468
  ```
466
469
  #### option
467
- | key |value| desc |
468
- | ---- | ---- | ---- |
469
- | method | `css` `animation` `js` | 设置高亮方式。虚拟滚动默认js。否则css |
470
- | ~~useCss~~ `deprecated` | `boolean`| ~~是否使用css~~ |
471
- | className | `string` | 设置高亮样式。method == 'css' 生效 |
472
- | keyframe | `Parameters<Animatable['animate']>['0']` | 设置高亮动画。method == 'animation' 生效。 |
473
- | duration | `number` | 设置高亮动画持续时间。 method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。|
470
+ | key |value| default |desc |
471
+ | ---- | ---- | ---- | ---- |
472
+ | method | `css` `animation` `js` | `animation` | 设置高亮方式。 |
473
+ | ~~useCss~~ `deprecated` | `boolean`| false | ~~是否使用css~~ |
474
+ | className | `string` | `highlight-row`/`highlight-cell` | 自定义 css 动画。method == 'css' 生效 |
475
+ | keyframe | `Parameters<Animatable['animate']>['0']` | ... | 自定义高亮动画。method == 'animation' 生效。 |
476
+ | duration | `number` | 2000 | 设置高亮动画持续时间ms。 method='css'状态下,用于移除class,如果传入了className则需要与自定义的动画时间一致。|
474
477
 
475
478
  ##### option.method
476
479
  | `option.method`| desc |
477
480
  | ---- | ---- |
478
- | css | 使用css class 实现高亮。 |
479
- | animation | 使用 animation api 实现高亮。 |
480
- | js | 使用 js 循环计算颜色实现高亮。虚拟滚动默认使用js。 |
481
+ | animation | animation api 实现高亮。(default) |
482
+ | css | css @keyframes 实现高亮。 |
483
+ | js | js 循环计算颜色实现高亮。 |
481
484
 
482
485
  ### Example
483
486
  ```vue
@@ -21,6 +21,6 @@ export declare const HIGHLIGHT_FREQ: number;
21
21
  export declare const HIGHLIGHT_ROW_CLASS = "highlight-row";
22
22
  /** 高连单元格class */
23
23
  export declare const HIGHLIGHT_CELL_CLASS = "highlight-cell";
24
- /** 是否兼容低版本模式 */
24
+ /** 低版本sticky兼容模式 */
25
25
  export declare const IS_LEGACY_MODE: boolean;
26
26
  export declare const STK_ID_PREFIX = "stk";
@@ -35,3 +35,4 @@ export declare function getCalculatedColWidth(col: StkTableColumn<any> | null):
35
35
  export declare function transformWidthToStr(width?: string | number): string | undefined;
36
36
  /** 创建组件唯一标识 */
37
37
  export declare function createStkTableId(): string;
38
+ export declare function getBrowsersVersion(browserName: string): number;
@@ -1,83 +1,5 @@
1
1
  import { onMounted, onBeforeUnmount, watch, ref, shallowRef, computed, defineComponent, nextTick, toRaw, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, createCommentVNode, createElementVNode, Fragment, renderList, createBlock, resolveDynamicComponent, toDisplayString, renderSlot, createTextVNode } from "vue";
2
2
  import { interpolateRgb } from "d3-interpolate";
3
- const DEFAULT_COL_WIDTH = "100";
4
- const DEFAULT_TABLE_HEIGHT = 100;
5
- const DEFAULT_TABLE_WIDTH = 200;
6
- const DEFAULT_ROW_HEIGHT = 28;
7
- const HIGHLIGHT_COLOR = {
8
- light: { from: "#71a2fd", to: "#fff" },
9
- dark: { from: "#1e4c99", to: "#181c21" }
10
- };
11
- const HIGHLIGHT_DURATION = 2e3;
12
- const HIGHLIGHT_FREQ = 1e3 / 30;
13
- const HIGHLIGHT_ROW_CLASS = "highlight-row";
14
- const HIGHLIGHT_CELL_CLASS = "highlight-cell";
15
- let _chromeVersion = 0;
16
- try {
17
- const userAgent = navigator.userAgent.match(/chrome\/\d+/i);
18
- if (userAgent) {
19
- _chromeVersion = +userAgent[0].split("/")[1];
20
- }
21
- } catch (e) {
22
- console.error("Cannot get Chrome version", e);
23
- }
24
- const IS_LEGACY_MODE = _chromeVersion < 56;
25
- const STK_ID_PREFIX = "stk";
26
- var TagType = /* @__PURE__ */ ((TagType2) => {
27
- TagType2[TagType2["TH"] = 0] = "TH";
28
- TagType2[TagType2["TD"] = 1] = "TD";
29
- return TagType2;
30
- })(TagType || {});
31
- function useAutoResize({ tableContainerRef, initVirtualScroll, props, debounceMs }) {
32
- let resizeObserver = null;
33
- onMounted(() => {
34
- initResizeObserver();
35
- });
36
- onBeforeUnmount(() => {
37
- removeResizeObserver();
38
- });
39
- function initResizeObserver() {
40
- if (window.ResizeObserver) {
41
- if (!tableContainerRef.value) {
42
- const watchDom = watch(
43
- () => tableContainerRef,
44
- () => {
45
- initResizeObserver();
46
- watchDom();
47
- }
48
- );
49
- return;
50
- }
51
- resizeObserver = new ResizeObserver(resizeCallback);
52
- resizeObserver.observe(tableContainerRef.value);
53
- } else {
54
- window.addEventListener("resize", resizeCallback);
55
- }
56
- }
57
- function removeResizeObserver() {
58
- if (resizeObserver) {
59
- resizeObserver.disconnect();
60
- resizeObserver = null;
61
- } else {
62
- window.removeEventListener("resize", resizeCallback);
63
- }
64
- }
65
- let debounceTime = 0;
66
- function resizeCallback() {
67
- if (debounceTime) {
68
- window.clearTimeout(debounceTime);
69
- }
70
- debounceTime = window.setTimeout(() => {
71
- if (props.autoResize) {
72
- initVirtualScroll();
73
- if (typeof props.autoResize === "function") {
74
- props.autoResize();
75
- }
76
- }
77
- debounceTime = 0;
78
- }, debounceMs);
79
- }
80
- }
81
3
  function isEmptyValue(val, isNumber) {
82
4
  let isEmpty = val === null || val === "";
83
5
  if (isNumber) {
@@ -216,11 +138,95 @@ function transformWidthToStr(width) {
216
138
  return width;
217
139
  }
218
140
  function createStkTableId() {
219
- if (!window.__STK_TB_ID_COUNT__) {
220
- window.__STK_TB_ID_COUNT__ = 0;
141
+ let id = window.__STK_TB_ID_COUNT__;
142
+ if (!id)
143
+ id = 0;
144
+ id += 1;
145
+ window.__STK_TB_ID_COUNT__ = id;
146
+ return STK_ID_PREFIX + id.toString(36);
147
+ }
148
+ function getBrowsersVersion(browserName) {
149
+ try {
150
+ const reg = new RegExp(`${browserName}/\\d+`, "i");
151
+ const userAgent = navigator.userAgent.match(reg);
152
+ if (userAgent) {
153
+ return +userAgent[0].split("/")[1];
154
+ }
155
+ } catch (e) {
156
+ console.error("Cannot get version", e);
157
+ }
158
+ return 100;
159
+ }
160
+ const DEFAULT_COL_WIDTH = "100";
161
+ const DEFAULT_TABLE_HEIGHT = 100;
162
+ const DEFAULT_TABLE_WIDTH = 200;
163
+ const DEFAULT_ROW_HEIGHT = 28;
164
+ const HIGHLIGHT_COLOR = {
165
+ light: { from: "#71a2fd", to: "#fff" },
166
+ dark: { from: "#1e4c99", to: "#181c21" }
167
+ };
168
+ const HIGHLIGHT_DURATION = 2e3;
169
+ const HIGHLIGHT_FREQ = 1e3 / 30;
170
+ const HIGHLIGHT_ROW_CLASS = "highlight-row";
171
+ const HIGHLIGHT_CELL_CLASS = "highlight-cell";
172
+ const _chromeVersion = getBrowsersVersion("chrome");
173
+ const _firefoxVersion = getBrowsersVersion("firefox");
174
+ const IS_LEGACY_MODE = _chromeVersion < 56 || _firefoxVersion < 59;
175
+ const STK_ID_PREFIX = "stk";
176
+ var TagType = /* @__PURE__ */ ((TagType2) => {
177
+ TagType2[TagType2["TH"] = 0] = "TH";
178
+ TagType2[TagType2["TD"] = 1] = "TD";
179
+ return TagType2;
180
+ })(TagType || {});
181
+ function useAutoResize({ tableContainerRef, initVirtualScroll, props, debounceMs }) {
182
+ let resizeObserver = null;
183
+ onMounted(() => {
184
+ initResizeObserver();
185
+ });
186
+ onBeforeUnmount(() => {
187
+ removeResizeObserver();
188
+ });
189
+ function initResizeObserver() {
190
+ if (window.ResizeObserver) {
191
+ if (!tableContainerRef.value) {
192
+ const watchDom = watch(
193
+ () => tableContainerRef,
194
+ () => {
195
+ initResizeObserver();
196
+ watchDom();
197
+ }
198
+ );
199
+ return;
200
+ }
201
+ resizeObserver = new ResizeObserver(resizeCallback);
202
+ resizeObserver.observe(tableContainerRef.value);
203
+ } else {
204
+ window.addEventListener("resize", resizeCallback);
205
+ }
206
+ }
207
+ function removeResizeObserver() {
208
+ if (resizeObserver) {
209
+ resizeObserver.disconnect();
210
+ resizeObserver = null;
211
+ } else {
212
+ window.removeEventListener("resize", resizeCallback);
213
+ }
214
+ }
215
+ let debounceTime = 0;
216
+ function resizeCallback() {
217
+ if (debounceTime) {
218
+ window.clearTimeout(debounceTime);
219
+ }
220
+ debounceTime = window.setTimeout(() => {
221
+ if (props.autoResize) {
222
+ initVirtualScroll();
223
+ if (typeof props.autoResize === "function") {
224
+ props.autoResize();
225
+ }
226
+ }
227
+ debounceTime = 0;
228
+ }, debounceMs);
221
229
  }
222
- window.__STK_TB_ID_COUNT__ += 1;
223
- return STK_ID_PREFIX + window.__STK_TB_ID_COUNT__.toString(36);
224
230
  }
225
231
  function useColResize({
226
232
  tableContainerRef,
@@ -1477,11 +1483,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1477
1483
  emits("cell-mouseover", e, row, col);
1478
1484
  }
1479
1485
  function onTableWheel(e) {
1486
+ e.preventDefault();
1480
1487
  if (isColResizing.value) {
1481
- e.preventDefault();
1482
1488
  e.stopPropagation();
1483
1489
  return;
1484
1490
  }
1491
+ const dom = tableContainerRef.value;
1492
+ if (!dom)
1493
+ return;
1494
+ const { deltaY, deltaX } = e;
1495
+ if (deltaY)
1496
+ dom.scrollTop += deltaY;
1497
+ if (deltaX)
1498
+ dom.scrollLeft += deltaX;
1485
1499
  }
1486
1500
  function onTableScroll(e) {
1487
1501
  if (!(e == null ? void 0 : e.target))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stk-table-vue",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
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",
@@ -920,21 +920,28 @@ function onCellMouseOver(e: MouseEvent, row: DT, col: StkTableColumn<DT>) {
920
920
  }
921
921
 
922
922
  /**
923
- * 鼠标滚轮事件监听
924
- * @param {MouseEvent} e
923
+ * 鼠标滚轮事件监听。代理滚轮事件,防止滚动过快出现白屏。
924
+ * @param e
925
925
  */
926
- function onTableWheel(e: MouseEvent) {
926
+ function onTableWheel(e: WheelEvent) {
927
+ e.preventDefault();
927
928
  if (isColResizing.value) {
928
929
  // 正在调整列宽时,不允许用户滚动
929
- e.preventDefault();
930
930
  e.stopPropagation();
931
931
  return;
932
932
  }
933
+ // #region ---- 控制滚动,防止出现白屏--
934
+ const dom = tableContainerRef.value;
935
+ if (!dom) return;
936
+ const { deltaY, deltaX } = e;
937
+ if (deltaY) dom.scrollTop += deltaY;
938
+ if (deltaX) dom.scrollLeft += deltaX;
939
+ //#endregion
933
940
  }
934
941
 
935
942
  /**
936
943
  * 滚动条监听
937
- * @param {Event} e scrollEvent
944
+ * @param e scrollEvent
938
945
  */
939
946
  function onTableScroll(e: Event) {
940
947
  if (!e?.target) return;
@@ -1,3 +1,5 @@
1
+ import { getBrowsersVersion } from './utils';
2
+
1
3
  export const DEFAULT_COL_WIDTH = '100';
2
4
 
3
5
  export const DEFAULT_TABLE_HEIGHT = 100;
@@ -20,16 +22,10 @@ export const HIGHLIGHT_ROW_CLASS = 'highlight-row';
20
22
  /** 高连单元格class */
21
23
  export const HIGHLIGHT_CELL_CLASS = 'highlight-cell';
22
24
 
23
- let _chromeVersion = 0;
24
- try {
25
- const userAgent = navigator.userAgent.match(/chrome\/\d+/i);
26
- if (userAgent) {
27
- _chromeVersion = +userAgent[0].split('/')[1];
28
- }
29
- } catch (e) {
30
- console.error('Cannot get Chrome version', e);
31
- }
32
- /** 是否兼容低版本模式 */
33
- export const IS_LEGACY_MODE = _chromeVersion < 56;
25
+ const _chromeVersion = getBrowsersVersion('chrome');
26
+ const _firefoxVersion = getBrowsersVersion('firefox');
27
+
28
+ /** 低版本sticky兼容模式 */
29
+ export const IS_LEGACY_MODE = _chromeVersion < 56 || _firefoxVersion < 59;
34
30
 
35
31
  export const STK_ID_PREFIX = 'stk';
@@ -210,10 +210,22 @@ export function transformWidthToStr(width?: string | number) {
210
210
 
211
211
  /** 创建组件唯一标识 */
212
212
  export function createStkTableId() {
213
- if (!window.__STK_TB_ID_COUNT__) {
214
- window.__STK_TB_ID_COUNT__ = 0;
215
- }
216
- window.__STK_TB_ID_COUNT__ += 1;
213
+ let id = window.__STK_TB_ID_COUNT__;
214
+ if (!id) id = 0;
215
+ id += 1;
216
+ window.__STK_TB_ID_COUNT__ = id;
217
+ return STK_ID_PREFIX + id.toString(36);
218
+ }
217
219
 
218
- return STK_ID_PREFIX + window.__STK_TB_ID_COUNT__.toString(36);
220
+ export function getBrowsersVersion(browserName: string) {
221
+ try {
222
+ const reg = new RegExp(`${browserName}/\\d+`, 'i');
223
+ const userAgent = navigator.userAgent.match(reg);
224
+ if (userAgent) {
225
+ return +userAgent[0].split('/')[1];
226
+ }
227
+ } catch (e) {
228
+ console.error('Cannot get version', e);
229
+ }
230
+ return 100;
219
231
  }