@kdcloudjs/table 1.2.2-canary.12 → 1.2.2-canary.13

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.
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.FastScrollManager = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
9
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
10
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
11
+ /**
12
+ * 快速滚动管理器
13
+ * 抽取 BaseTable 中的快速滚动相关逻辑
14
+ */
15
+ var FastScrollManager = /*#__PURE__*/function () {
16
+ function FastScrollManager(callbacks) {
17
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
18
+ (0, _classCallCheck2.default)(this, FastScrollManager);
19
+ // 快速滚动状态
20
+ this.state = {
21
+ lastScrollTime: 0,
22
+ scrollVelocity: 0,
23
+ lastOffsetY: 0
24
+ };
25
+ // 快速滚动标志 - 作为私有属性立即更新
26
+ this.isFastScrolling = false;
27
+ this.callbacks = callbacks;
28
+ // 合并默认配置
29
+ this.config = (0, _extends2.default)({
30
+ overscanSize: 100,
31
+ velocityThreshold: 3,
32
+ distanceMultiplier: 3,
33
+ fastScrollEndDelayHigh: 200,
34
+ fastScrollEndDelayNormal: 150,
35
+ highVelocityThreshold: 5
36
+ }, config);
37
+ }
38
+ /**
39
+ * 检测是否接近底部(剩余滚动距离少于两屏)
40
+ */
41
+ (0, _createClass2.default)(FastScrollManager, [{
42
+ key: "isNearBottom",
43
+ value: function isNearBottom(currentScrollTop, maxRenderHeight, totalScrollHeight) {
44
+ var remainingScrollDistance = totalScrollHeight - currentScrollTop - maxRenderHeight;
45
+ return remainingScrollDistance < maxRenderHeight;
46
+ }
47
+ /**
48
+ * 处理滚动事件 - 检测和处理快速滚动
49
+ */
50
+ }, {
51
+ key: "handleScrollEvent",
52
+ value: function handleScrollEvent(sizeAndOffset, currentState, dataLength, totalScrollHeight) {
53
+ var currentTime = performance.now();
54
+ var deltaY = Math.abs(sizeAndOffset.offsetY - this.state.lastOffsetY);
55
+ var deltaTime = currentTime - this.state.lastScrollTime;
56
+ // 计算滚动速度 (像素/毫秒)
57
+ this.state.scrollVelocity = deltaTime > 0 ? deltaY / deltaTime : 0;
58
+ // 检测是否接近底部
59
+ var isNearBottom = this.isNearBottom(sizeAndOffset.offsetY, sizeAndOffset.maxRenderHeight, totalScrollHeight);
60
+ // 如果正在快速滚动但接近底部,提前结束快速滚动
61
+ if (this.isFastScrolling && isNearBottom) {
62
+ this.endFastScrolling(sizeAndOffset);
63
+ return; // 让正常渲染逻辑接管
64
+ }
65
+ // 快速滚动判断条件:
66
+ // 1. 滚动距离超过阈值 && 滚动速度超过阈值
67
+ // 2. 当前未在快速滚动状态
68
+ // 3. 未接近底部边界
69
+ var isSignificantChange = deltaY > this.config.overscanSize * this.config.distanceMultiplier;
70
+ var isHighVelocity = this.state.scrollVelocity > this.config.velocityThreshold;
71
+ var shouldStartFastScroll = (isSignificantChange || isHighVelocity) && !this.isFastScrolling && !isNearBottom; // 接近底部时不启动快速滚动
72
+ if (shouldStartFastScroll) {
73
+ this.startFastScrolling(currentState, dataLength);
74
+ }
75
+ // 重置快速滚动结束定时器
76
+ if (this.isFastScrolling) {
77
+ this.resetFastScrollEndTimer(sizeAndOffset);
78
+ }
79
+ // 更新记录
80
+ this.state.lastOffsetY = sizeAndOffset.offsetY;
81
+ this.state.lastScrollTime = currentTime;
82
+ }
83
+ /**
84
+ * 开始快速滚动
85
+ */
86
+ }, {
87
+ key: "startFastScrolling",
88
+ value: function startFastScrolling(currentState, dataLength) {
89
+ this.isFastScrolling = true;
90
+ // 获取当前渲染范围作为缓存
91
+ var currentVerticalRange = this.callbacks.getCurrentRenderRange(currentState.offsetY, currentState.maxRenderHeight, dataLength);
92
+ // 通知外部开始快速滚动
93
+ this.callbacks.onFastScrollStart({
94
+ offsetY: currentState.offsetY,
95
+ maxRenderHeight: currentState.maxRenderHeight,
96
+ maxRenderWidth: currentState.maxRenderWidth,
97
+ verticalRenderRange: currentVerticalRange
98
+ });
99
+ }
100
+ /**
101
+ * 重置快速滚动结束定时器
102
+ */
103
+ }, {
104
+ key: "resetFastScrollEndTimer",
105
+ value: function resetFastScrollEndTimer(sizeAndOffset) {
106
+ var _this = this;
107
+ if (this.fastScrollEndTimer) {
108
+ clearTimeout(this.fastScrollEndTimer);
109
+ }
110
+ var waitTime = this.state.scrollVelocity > this.config.highVelocityThreshold ? this.config.fastScrollEndDelayHigh : this.config.fastScrollEndDelayNormal;
111
+ this.fastScrollEndTimer = window.setTimeout(function () {
112
+ _this.endFastScrolling(sizeAndOffset);
113
+ }, waitTime);
114
+ }
115
+ /**
116
+ * 结束快速滚动
117
+ */
118
+ }, {
119
+ key: "endFastScrolling",
120
+ value: function endFastScrolling(sizeAndOffset) {
121
+ this.isFastScrolling = false;
122
+ this.fastScrollEndTimer = undefined;
123
+ // 通知外部结束快速滚动
124
+ this.callbacks.onFastScrollEnd(sizeAndOffset);
125
+ }
126
+ /**
127
+ * 清理资源
128
+ */
129
+ }, {
130
+ key: "cleanup",
131
+ value: function cleanup() {
132
+ if (this.fastScrollEndTimer) {
133
+ clearTimeout(this.fastScrollEndTimer);
134
+ }
135
+ }
136
+ /**
137
+ * 获取当前是否处于快速滚动状态
138
+ */
139
+ }, {
140
+ key: "getIsFastScrolling",
141
+ value: function getIsFastScrolling() {
142
+ return this.isFastScrolling;
143
+ }
144
+ /**
145
+ * 获取当前滚动速度
146
+ */
147
+ }, {
148
+ key: "getScrollVelocity",
149
+ value: function getScrollVelocity() {
150
+ return this.state.scrollVelocity;
151
+ }
152
+ /**
153
+ * 清理资源
154
+ */
155
+ }, {
156
+ key: "destroy",
157
+ value: function destroy() {
158
+ if (this.fastScrollEndTimer) {
159
+ clearTimeout(this.fastScrollEndTimer);
160
+ this.fastScrollEndTimer = undefined;
161
+ }
162
+ this.isFastScrolling = false;
163
+ }
164
+ /**
165
+ * 获取当前配置
166
+ */
167
+ }, {
168
+ key: "getConfig",
169
+ value: function getConfig() {
170
+ return (0, _extends2.default)({}, this.config);
171
+ }
172
+ }]);
173
+ return FastScrollManager;
174
+ }();
175
+ exports.FastScrollManager = FastScrollManager;
@@ -23,6 +23,8 @@ export interface BaseTableProps {
23
23
  };
24
24
  /** 虚拟滚动开启情况下,表格中每一行的预估高度 */
25
25
  estimatedRowHeight?: number;
26
+ /** 性能差浏览器和处理器,性能差则启动快速滚动优化,默认为 false */
27
+ isLowPerformance?: boolean;
26
28
  /** @deprecated 表格头部是否置顶,默认为 true。请使用 isStickyHeader 代替 */
27
29
  isStickyHead?: boolean;
28
30
  /** 表格头部是否置顶,默认为 true */
@@ -107,6 +109,13 @@ export interface BaseTableState {
107
109
  offsetX: number;
108
110
  /** 横向虚拟滚动 最大渲染尺寸 */
109
111
  maxRenderWidth: number;
112
+ /** 快速滚动时保留的上一次渲染数据 */
113
+ previousRenderData?: {
114
+ offsetY: number;
115
+ maxRenderHeight: number;
116
+ maxRenderWidth: number;
117
+ verticalRenderRange: VerticalRenderRange;
118
+ };
110
119
  }
111
120
  export declare class BaseTable extends React.Component<BaseTableProps, BaseTableState> {
112
121
  static defaultProps: {
@@ -120,6 +129,7 @@ export declare class BaseTable extends React.Component<BaseTableProps, BaseTable
120
129
  stickyScrollHeight: string;
121
130
  useVirtual: string;
122
131
  estimatedRowHeight: number;
132
+ isLowPerformance: boolean;
123
133
  isLoading: boolean;
124
134
  components: {};
125
135
  getTableProps: typeof noop;
@@ -137,6 +147,9 @@ export declare class BaseTable extends React.Component<BaseTableProps, BaseTable
137
147
  private hasScrollY;
138
148
  private resizeObserver?;
139
149
  private offsetY;
150
+ private fastScrollManager;
151
+ private topBlankRef;
152
+ private bottomBlankRef;
140
153
  /** @deprecated BaseTable.getDoms() 已经过时,请勿调用 */
141
154
  getDoms(): TableDOMHelper;
142
155
  constructor(props: Readonly<BaseTableProps>);
@@ -34,6 +34,7 @@ var _header = _interopRequireDefault(require("./header"));
34
34
  var _getRichVisibleRectsStream = require("./helpers/getRichVisibleRectsStream");
35
35
  var _rowHeightManager = require("./helpers/rowHeightManager");
36
36
  var _TableDOMUtils = require("./helpers/TableDOMUtils");
37
+ var _FastScrollManager = require("./helpers/FastScrollManager");
37
38
  var _htmlTable = require("./html-table");
38
39
  var _loading = _interopRequireDefault(require("./loading"));
39
40
  var _styles = require("./styles");
@@ -41,6 +42,7 @@ var _globalStyleComponent = _interopRequireDefault(require("./globalStyleCompone
41
42
  var _utils = require("./utils");
42
43
  var _utils2 = require("../utils");
43
44
  var _renderTemplates = _interopRequireDefault(require("./renderTemplates"));
45
+ var _BlankComponent = require("./BlankComponent");
44
46
  function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
45
47
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
46
48
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
@@ -66,6 +68,9 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
66
68
  _this.artTableWrapperRef = /*#__PURE__*/_react.default.createRef();
67
69
  _this.hasScrollY = false;
68
70
  _this.offsetY = 0;
71
+ // Blank组件的引用,用于快速滚动时直接更新
72
+ _this.topBlankRef = /*#__PURE__*/_react.default.createRef();
73
+ _this.bottomBlankRef = /*#__PURE__*/_react.default.createRef();
69
74
  _this.handleRowMouseEnter = function (e) {
70
75
  var nodeList = _this.domHelper.getRowNodeListByEvent(e);
71
76
  nodeList && nodeList.forEach(function (node) {
@@ -85,8 +90,7 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
85
90
  getRowProps = _this$props.getRowProps,
86
91
  primaryKey = _this$props.primaryKey,
87
92
  isLoading = _this$props.isLoading,
88
- emptyCellHeight = _this$props.emptyCellHeight,
89
- footerDataSource = _this$props.footerDataSource;
93
+ emptyCellHeight = _this$props.emptyCellHeight;
90
94
  var tableBodyClassName = (0, _classnames.default)(_styles.Classes.tableBody, _styles.Classes.horizontalScrollContainer);
91
95
  // 低版本Edge浏览器下也会出现双滚动条,这里设置overflow: 'hidden',先去掉edge的方向键控制滚动条的功能
92
96
  var virtualStyle = _utils2.browserType.isIE || _utils2.browserType.isEdge ? {
@@ -136,12 +140,9 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
136
140
  className: _styles.Classes.virtual,
137
141
  tabIndex: -1,
138
142
  style: virtualStyle
139
- }, topBlank > 0 && /*#__PURE__*/_react.default.createElement("div", {
140
- key: "top-blank",
141
- className: (0, _classnames.default)(_styles.Classes.virtualBlank, 'top'),
142
- style: {
143
- height: topBlank
144
- }
143
+ }, /*#__PURE__*/_react.default.createElement(_BlankComponent.TopBlank, {
144
+ ref: _this.topBlankRef,
145
+ height: topBlank
145
146
  }), /*#__PURE__*/_react.default.createElement(_htmlTable.HtmlTable, {
146
147
  tbodyHtmlTag: "tbody",
147
148
  getRowProps: getRowProps,
@@ -154,12 +155,9 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
154
155
  limit: bottomIndex,
155
156
  last: dataSource.length - 1
156
157
  }
157
- }), bottomBlank > 0 && /*#__PURE__*/_react.default.createElement("div", {
158
- key: "bottom-blank",
159
- className: (0, _classnames.default)(_styles.Classes.virtualBlank, 'bottom'),
160
- style: {
161
- height: bottomBlank
162
- }
158
+ }), /*#__PURE__*/_react.default.createElement(_BlankComponent.BottomBlank, {
159
+ ref: _this.bottomBlankRef,
160
+ height: bottomBlank
163
161
  })));
164
162
  };
165
163
  _this.state = {
@@ -174,6 +172,26 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
174
172
  maxRenderHeight: 600,
175
173
  maxRenderWidth: 800
176
174
  };
175
+ // 初始化快速滚动管理器
176
+ var fastScrollCallbacks = {
177
+ onFastScrollStart: function onFastScrollStart(renderData) {
178
+ _this.setState({
179
+ previousRenderData: renderData
180
+ });
181
+ },
182
+ onFastScrollEnd: function onFastScrollEnd(scrollData) {
183
+ _this.setState({
184
+ previousRenderData: undefined,
185
+ offsetY: scrollData.offsetY,
186
+ maxRenderHeight: scrollData.maxRenderHeight,
187
+ maxRenderWidth: scrollData.maxRenderWidth
188
+ });
189
+ },
190
+ getCurrentRenderRange: function getCurrentRenderRange(offsetY, maxRenderHeight, dataLength) {
191
+ return _this.rowHeightManager.getRenderRange(offsetY, maxRenderHeight, dataLength);
192
+ }
193
+ };
194
+ _this.fastScrollManager = new _FastScrollManager.FastScrollManager(fastScrollCallbacks);
177
195
  return _this;
178
196
  }
179
197
  /** @deprecated BaseTable.getDoms() 已经过时,请勿调用 */
@@ -295,7 +313,6 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
295
313
  }, {
296
314
  key: "syncHorizontalScroll",
297
315
  value: function syncHorizontalScroll(x) {
298
- var direction = this.props.direction;
299
316
  var _x = Math.abs(x);
300
317
  this.updateOffsetX(_x);
301
318
  var flat = (0, _flat.default)(this.lastInfo);
@@ -323,11 +340,18 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
323
340
  }, {
324
341
  key: "getVerticalRenderRange",
325
342
  value: function getVerticalRenderRange(useVirtual) {
326
- var dataSource = this.props.dataSource;
343
+ var _this$props4 = this.props,
344
+ dataSource = _this$props4.dataSource,
345
+ isLowPerformance = _this$props4.isLowPerformance;
327
346
  var _this$state = this.state,
328
347
  offsetY = _this$state.offsetY,
329
- maxRenderHeight = _this$state.maxRenderHeight;
348
+ maxRenderHeight = _this$state.maxRenderHeight,
349
+ previousRenderData = _this$state.previousRenderData;
330
350
  var rowCount = dataSource.length;
351
+ // 只有在启用快速滚动时才使用 FastScrollManager 的判断
352
+ if (isLowPerformance && this.fastScrollManager.getIsFastScrolling() && (previousRenderData === null || previousRenderData === void 0 ? void 0 : previousRenderData.verticalRenderRange)) {
353
+ return previousRenderData.verticalRenderRange;
354
+ }
331
355
  if (useVirtual.vertical) {
332
356
  return this.rowHeightManager.getRenderRange(offsetY, maxRenderHeight, rowCount);
333
357
  } else {
@@ -338,12 +362,12 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
338
362
  key: "renderTableFooter",
339
363
  value: function renderTableFooter(info) {
340
364
  // console.log('render footer')
341
- var _this$props4 = this.props,
342
- _this$props4$footerDa = _this$props4.footerDataSource,
343
- footerDataSource = _this$props4$footerDa === void 0 ? [] : _this$props4$footerDa,
344
- getRowProps = _this$props4.getRowProps,
345
- primaryKey = _this$props4.primaryKey,
346
- stickyBottom = _this$props4.stickyBottom;
365
+ var _this$props5 = this.props,
366
+ _this$props5$footerDa = _this$props5.footerDataSource,
367
+ footerDataSource = _this$props5$footerDa === void 0 ? [] : _this$props5$footerDa,
368
+ getRowProps = _this$props5.getRowProps,
369
+ primaryKey = _this$props5.primaryKey,
370
+ stickyBottom = _this$props5.stickyBottom;
347
371
  var stickyRightOffset = this.hasScrollY ? this.getScrollBarWidth() : 0;
348
372
  var renderFooter = (0, _renderTemplates.default)('footer');
349
373
  if (typeof renderFooter === 'function') {
@@ -405,9 +429,9 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
405
429
  key: "renderStickyScroll",
406
430
  value: function renderStickyScroll(info) {
407
431
  // console.log('render stickyscroll')
408
- var _this$props5 = this.props,
409
- hasStickyScroll = _this$props5.hasStickyScroll,
410
- stickyBottom = _this$props5.stickyBottom;
432
+ var _this$props6 = this.props,
433
+ hasStickyScroll = _this$props6.hasStickyScroll,
434
+ stickyBottom = _this$props6.stickyBottom;
411
435
  var hasScroll = this.state.hasScroll;
412
436
  var isScroll = hasStickyScroll && hasScroll;
413
437
  var stickyScrollContainerStyle = this.getStickyScrollContainerStyle();
@@ -444,9 +468,9 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
444
468
  }, {
445
469
  key: "getStickyScrollContainerStyle",
446
470
  value: function getStickyScrollContainerStyle() {
447
- var _this$props6 = this.props,
448
- hasStickyScroll = _this$props6.hasStickyScroll,
449
- stickyScrollHeight = _this$props6.stickyScrollHeight;
471
+ var _this$props7 = this.props,
472
+ hasStickyScroll = _this$props7.hasStickyScroll,
473
+ stickyScrollHeight = _this$props7.stickyScrollHeight;
450
474
  var hasScroll = this.state.hasScroll;
451
475
  var isScroll = hasStickyScroll && hasScroll;
452
476
  var height = stickyScrollHeight === 'auto' ? this.getScrollBarWidth() : stickyScrollHeight;
@@ -464,21 +488,21 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
464
488
  // console.log('render table')
465
489
  var info = (0, _calculations.calculateRenderInfo)(this);
466
490
  this.lastInfo = info;
467
- var _this$props7 = this.props,
468
- dataSource = _this$props7.dataSource,
469
- className = _this$props7.className,
470
- style = _this$props7.style,
471
- hasHeader = _this$props7.hasHeader,
472
- useOuterBorder = _this$props7.useOuterBorder,
473
- isStickyHead = _this$props7.isStickyHead,
474
- isStickyHeader = _this$props7.isStickyHeader,
475
- isStickyFooter = _this$props7.isStickyFooter,
476
- isLoading = _this$props7.isLoading,
477
- getTableProps = _this$props7.getTableProps,
478
- footerDataSource = _this$props7.footerDataSource,
479
- components = _this$props7.components,
480
- bordered = _this$props7.bordered,
481
- direction = _this$props7.direction;
491
+ var _this$props8 = this.props,
492
+ dataSource = _this$props8.dataSource,
493
+ className = _this$props8.className,
494
+ style = _this$props8.style,
495
+ hasHeader = _this$props8.hasHeader,
496
+ useOuterBorder = _this$props8.useOuterBorder,
497
+ isStickyHead = _this$props8.isStickyHead,
498
+ isStickyHeader = _this$props8.isStickyHeader,
499
+ isStickyFooter = _this$props8.isStickyFooter,
500
+ isLoading = _this$props8.isLoading,
501
+ getTableProps = _this$props8.getTableProps,
502
+ footerDataSource = _this$props8.footerDataSource,
503
+ components = _this$props8.components,
504
+ bordered = _this$props8.bordered,
505
+ direction = _this$props8.direction;
482
506
  info.direction = direction;
483
507
  var artTableWrapperClassName = (0, _classnames.default)(_styles.Classes.artTableWrapper, (_cx = {
484
508
  'use-outer-border': useOuterBorder,
@@ -519,10 +543,10 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
519
543
  this.initSubscriptions();
520
544
  this.didMountOrUpdate();
521
545
  // console.log('did mount end')
522
- var _this$props8 = this.props,
523
- cssVariables = _this$props8.cssVariables,
524
- enableCSSVariables = _this$props8.enableCSSVariables,
525
- bordered = _this$props8.bordered;
546
+ var _this$props9 = this.props,
547
+ cssVariables = _this$props9.cssVariables,
548
+ enableCSSVariables = _this$props9.enableCSSVariables,
549
+ bordered = _this$props9.bordered;
526
550
  (0, _utils.cssPolifill)({
527
551
  variables: cssVariables || {},
528
552
  enableCSSVariables: enableCSSVariables,
@@ -537,10 +561,10 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
537
561
  value: function componentDidUpdate(prevProps, prevState) {
538
562
  var _a;
539
563
  // console.log('did update start')
540
- var _this$props9 = this.props,
541
- cssVariables = _this$props9.cssVariables,
542
- enableCSSVariables = _this$props9.enableCSSVariables,
543
- bordered = _this$props9.bordered;
564
+ var _this$props10 = this.props,
565
+ cssVariables = _this$props10.cssVariables,
566
+ enableCSSVariables = _this$props10.enableCSSVariables,
567
+ bordered = _this$props10.bordered;
544
568
  if (!(0, _utils.shallowEqual)(prevProps === null || prevProps === void 0 ? void 0 : prevProps.cssVariables, (_a = this.props) === null || _a === void 0 ? void 0 : _a.cssVariables)) {
545
569
  (0, _utils.cssPolifill)({
546
570
  variables: cssVariables || {},
@@ -556,10 +580,13 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
556
580
  }, {
557
581
  key: "didMountOrUpdate",
558
582
  value: function didMountOrUpdate(prevProps, prevState) {
559
- this.syncHorizontalScrollFromTableBody();
560
- this.updateStickyScroll();
561
- this.adjustNeedRenderLock();
562
- this.updateRowHeightManager();
583
+ var _this2 = this;
584
+ window.requestAnimationFrame(function () {
585
+ _this2.syncHorizontalScrollFromTableBody();
586
+ _this2.updateStickyScroll();
587
+ _this2.adjustNeedRenderLock();
588
+ _this2.updateRowHeightManager();
589
+ });
563
590
  this.updateScrollLeftWhenLayoutChanged(prevProps, prevState);
564
591
  }
565
592
  }, {
@@ -581,25 +608,25 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
581
608
  }, {
582
609
  key: "initSubscriptions",
583
610
  value: function initSubscriptions() {
584
- var _this2 = this;
611
+ var _this3 = this;
585
612
  var _this$domHelper2 = this.domHelper,
586
613
  virtual = _this$domHelper2.virtual,
587
614
  stickyScroll = _this$domHelper2.stickyScroll;
588
615
  this.rootSubscription.add(_utils.throttledWindowResize$.subscribe(function () {
589
- _this2.updateStickyScroll();
590
- _this2.adjustNeedRenderLock();
616
+ _this3.updateStickyScroll();
617
+ _this3.adjustNeedRenderLock();
591
618
  }));
592
619
  this.resizeSubject.pipe(op.debounceTime(100)).subscribe(function () {
593
620
  var _a, _b;
594
- (_b = (_a = _this2.props).setTableWidth) === null || _b === void 0 ? void 0 : _b.call(_a, _this2.domHelper.tableBody.clientWidth);
621
+ (_b = (_a = _this3.props).setTableWidth) === null || _b === void 0 ? void 0 : _b.call(_a, _this3.domHelper.tableBody.clientWidth);
595
622
  });
596
623
  var handleTableWrapperResize = function handleTableWrapperResize() {
597
- _this2.resizeSubject.next();
624
+ _this3.resizeSubject.next();
598
625
  };
599
626
  this.resizeObserver = (0, _utils.addResizeObserver)(this.domHelper.artTableWrapper, handleTableWrapperResize);
600
627
  // 滚动同步
601
628
  this.rootSubscription.add((0, _utils.syncScrollLeft)([(0, _utils.getTableScrollHeaderDOM)(this.domHelper), virtual, (0, _utils.getTableScrollFooterDOM)(this.domHelper), stickyScroll], function (scrollLeft) {
602
- _this2.syncHorizontalScroll(scrollLeft);
629
+ _this3.syncHorizontalScroll(scrollLeft);
603
630
  }));
604
631
  var richVisibleRects$ = (0, _getRichVisibleRectsStream.getRichVisibleRectsStream)(this.domHelper.virtual, this.props$.pipe(op.skip(1), op.mapTo('structure-may-change')), this.props.virtualDebugLabel).pipe(op.shareReplay());
605
632
  // 每当可见部分发生变化的时候,调整 loading icon 的未知(如果 loading icon 存在的话)
@@ -613,7 +640,7 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
613
640
  }))]).subscribe(function (_ref3) {
614
641
  var _ref4 = (0, _slicedToArray2.default)(_ref3, 1),
615
642
  clipRect = _ref4[0];
616
- var loadingIndicator = _this2.domHelper.getLoadingIndicator();
643
+ var loadingIndicator = _this3.domHelper.getLoadingIndicator();
617
644
  if (!loadingIndicator) {
618
645
  return;
619
646
  }
@@ -624,9 +651,9 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
624
651
  }));
625
652
  // 每当可见部分发生变化的时候,如果开启了虚拟滚动,则重新触发 render
626
653
  this.rootSubscription.add(richVisibleRects$.pipe(op.filter(function () {
627
- var _this2$lastInfo$useVi = _this2.lastInfo.useVirtual,
628
- horizontal = _this2$lastInfo$useVi.horizontal,
629
- vertical = _this2$lastInfo$useVi.vertical;
654
+ var _this3$lastInfo$useVi = _this3.lastInfo.useVirtual,
655
+ horizontal = _this3$lastInfo$useVi.horizontal,
656
+ vertical = _this3$lastInfo$useVi.vertical;
630
657
  return horizontal || vertical;
631
658
  }), op.map(function (_ref5) {
632
659
  var clipRect = _ref5.clipRect,
@@ -643,8 +670,29 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
643
670
  }
644
671
  // 因为 overscan 的存在,滚动较小的距离时不需要触发组件重渲染
645
672
  return Math.abs(x.maxRenderWidth - y.maxRenderWidth) < _utils.OVERSCAN_SIZE / 2 && Math.abs(x.maxRenderHeight - y.maxRenderHeight) < _utils.OVERSCAN_SIZE / 2 && Math.abs(x.offsetY - y.offsetY) < _utils.OVERSCAN_SIZE / 2;
673
+ }),
674
+ // 快速滚动检测和处理
675
+ op.tap(function (sizeAndOffset) {
676
+ // 只有在启用快速滚动时才使用 FastScrollManager 处理滚动事件
677
+ if (_this3.props.isLowPerformance) {
678
+ _this3.fastScrollManager.handleScrollEvent(sizeAndOffset, {
679
+ offsetY: _this3.state.offsetY,
680
+ maxRenderHeight: _this3.state.maxRenderHeight,
681
+ maxRenderWidth: _this3.state.maxRenderWidth
682
+ }, _this3.props.dataSource.length, _this3.domHelper.virtual.scrollHeight);
683
+ }
646
684
  })).subscribe(function (sizeAndOffset) {
647
- _this2.setState(sizeAndOffset);
685
+ var _a, _b;
686
+ // 正常滚动时也需要实时更新 blank 高度,确保缓慢滚动时的视觉连续性
687
+ var currentRange = _this3.rowHeightManager.getRenderRange(sizeAndOffset.offsetY, sizeAndOffset.maxRenderHeight, _this3.props.dataSource.length);
688
+ // 直接更新 DOM,避免等待下次渲染
689
+ (_a = _this3.topBlankRef.current) === null || _a === void 0 ? void 0 : _a.updateHeight(currentRange.topBlank);
690
+ (_b = _this3.bottomBlankRef.current) === null || _b === void 0 ? void 0 : _b.updateHeight(currentRange.bottomBlank);
691
+ // 只有在启用快速滚动时才检查快速滚动状态
692
+ if (_this3.props.isLowPerformance && _this3.fastScrollManager.getIsFastScrolling()) {
693
+ return;
694
+ }
695
+ _this3.setState(sizeAndOffset);
648
696
  }));
649
697
  this.rootSubscription.add(richVisibleRects$.pipe(op.map(function (_ref6) {
650
698
  var clipRect = _ref6.clipRect,
@@ -662,13 +710,13 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
662
710
  var _a;
663
711
  var offsetY = sizeAndOffset.offsetY,
664
712
  maxRenderHeight = sizeAndOffset.maxRenderHeight;
665
- var scrollDirection = offsetY - _this2.offsetY >= 0 ? 'down' : 'up';
666
- _this2.offsetY = offsetY;
667
- var rowCount = _this2.props.dataSource.length;
668
- var vertical = _this2.rowHeightManager.getRenderRange(offsetY, maxRenderHeight, rowCount);
713
+ var scrollDirection = offsetY - _this3.offsetY >= 0 ? 'down' : 'up';
714
+ _this3.offsetY = offsetY;
715
+ var rowCount = _this3.props.dataSource.length;
716
+ var vertical = _this3.rowHeightManager.getRenderRange(offsetY, maxRenderHeight, rowCount);
669
717
  var topIndex = vertical.topIndex,
670
718
  bottomIndex = vertical.bottomIndex;
671
- var blockSize = ((_a = _this2.props.scrollLoad) === null || _a === void 0 ? void 0 : _a.blockSize) || 200;
719
+ var blockSize = ((_a = _this3.props.scrollLoad) === null || _a === void 0 ? void 0 : _a.blockSize) || 200;
672
720
  var topBlockStartIndex = Math.floor(Math.max(topIndex - 1, 0) / blockSize) * blockSize;
673
721
  var bottomBlockStartIndex = Math.floor((bottomIndex + 1) / blockSize) * blockSize;
674
722
  return scrollDirection === 'down' ? [topBlockStartIndex, bottomBlockStartIndex] : [bottomBlockStartIndex, topBlockStartIndex];
@@ -683,7 +731,7 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
683
731
  // 过滤掉重复掉值
684
732
  op.distinctUntilChanged()).subscribe(function (startIndex) {
685
733
  var _a;
686
- (_a = _this2.props.scrollLoad) === null || _a === void 0 ? void 0 : _a.callback(startIndex);
734
+ (_a = _this3.props.scrollLoad) === null || _a === void 0 ? void 0 : _a.callback(startIndex);
687
735
  }));
688
736
  }
689
737
  }, {
@@ -693,6 +741,10 @@ var BaseTable = /*#__PURE__*/function (_React$Component) {
693
741
  (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
694
742
  this.rootSubscription.unsubscribe();
695
743
  this.resizeSubject.unsubscribe();
744
+ // 只有在启用快速滚动时才清理快速滚动管理器
745
+ if (this.props.isLowPerformance) {
746
+ this.fastScrollManager.cleanup();
747
+ }
696
748
  }
697
749
  /** 更新 DOM 节点的引用,方便其他方法直接操作 DOM */
698
750
  }, {
@@ -788,6 +840,7 @@ BaseTable.defaultProps = {
788
840
  stickyScrollHeight: 'auto',
789
841
  useVirtual: 'auto',
790
842
  estimatedRowHeight: 48,
843
+ isLowPerformance: false,
791
844
  isLoading: false,
792
845
  components: {},
793
846
  getTableProps: _rxjs.noop,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kdcloudjs/table",
3
- "version": "1.2.2-canary.12",
3
+ "version": "1.2.2-canary.13",
4
4
  "description": "金蝶 react table 组件",
5
5
  "title": "table",
6
6
  "keywords": [