@tarojs/components-advanced 3.6.0-beta.1 → 3.6.0-beta.3
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/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +2 -1
- package/dist/components/index.js.map +1 -0
- package/dist/components/virtual-list/constants.d.ts +2 -1
- package/dist/components/virtual-list/constants.js +4 -1
- package/dist/components/virtual-list/constants.js.map +1 -0
- package/dist/components/virtual-list/dom-helpers.d.ts +2 -1
- package/dist/components/virtual-list/dom-helpers.js +33 -30
- package/dist/components/virtual-list/dom-helpers.js.map +1 -0
- package/dist/components/virtual-list/index.d.ts +3 -4
- package/dist/components/virtual-list/index.js +5 -102
- package/dist/components/virtual-list/index.js.map +1 -0
- package/dist/components/virtual-list/list-set.d.ts +4 -4
- package/dist/components/virtual-list/list-set.js +178 -223
- package/dist/components/virtual-list/list-set.js.map +1 -0
- package/dist/components/virtual-list/preset.d.ts +7 -6
- package/dist/components/virtual-list/preset.js +117 -148
- package/dist/components/virtual-list/preset.js.map +1 -0
- package/dist/components/virtual-list/react/index.d.ts +2 -2
- package/dist/components/virtual-list/react/index.js +31 -59
- package/dist/components/virtual-list/react/index.js.map +1 -0
- package/dist/components/virtual-list/react/list.d.ts +10 -5
- package/dist/components/virtual-list/react/list.js +347 -451
- package/dist/components/virtual-list/react/list.js.map +1 -0
- package/dist/components/virtual-list/react/validate.d.ts +4 -3
- package/dist/components/virtual-list/react/validate.js +60 -66
- package/dist/components/virtual-list/react/validate.js.map +1 -0
- package/dist/components/virtual-list/utils.d.ts +5 -5
- package/dist/components/virtual-list/utils.js +27 -28
- package/dist/components/virtual-list/utils.js.map +1 -0
- package/dist/components/virtual-list/vue/index.d.ts +6 -6
- package/dist/components/virtual-list/vue/index.js +10 -6
- package/dist/components/virtual-list/vue/index.js.map +1 -0
- package/dist/components/virtual-list/vue/list.d.ts +2 -2
- package/dist/components/virtual-list/vue/list.js +435 -475
- package/dist/components/virtual-list/vue/list.js.map +1 -0
- package/dist/components/virtual-list/vue/render.d.ts +2 -1
- package/dist/components/virtual-list/vue/render.js +17 -24
- package/dist/components/virtual-list/vue/render.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -0
- package/dist/utils/convert.d.ts +3 -2
- package/dist/utils/convert.js +15 -11
- package/dist/utils/convert.js.map +1 -0
- package/dist/utils/index.d.ts +4 -5
- package/dist/utils/index.js +5 -5
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/lodash.d.ts +2 -1
- package/dist/utils/lodash.js +10 -10
- package/dist/utils/lodash.js.map +1 -0
- package/dist/utils/math.d.ts +3 -2
- package/dist/utils/math.js +13 -16
- package/dist/utils/math.js.map +1 -0
- package/dist/utils/timer.d.ts +3 -3
- package/dist/utils/timer.js +21 -17
- package/dist/utils/timer.js.map +1 -0
- package/package.json +16 -8
- package/dist/utils/constants.d.ts +0 -4
- package/dist/utils/constants.js +0 -4
|
@@ -1,482 +1,378 @@
|
|
|
1
|
-
import
|
|
2
|
-
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
3
|
-
import _typeof from "@babel/runtime/helpers/esm/typeof";
|
|
4
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
5
|
-
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
6
|
-
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
7
|
-
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
|
|
8
|
-
import _inherits from "@babel/runtime/helpers/esm/inherits";
|
|
9
|
-
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
|
|
10
|
-
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
11
|
-
var _excluded = ["className", "direction", "height", "innerRef", "item", "itemCount", "itemData", "itemKey", "layout", "style", "useIsScrolling", "width", "renderTop", "renderBottom"];
|
|
1
|
+
import { __rest } from 'tslib';
|
|
12
2
|
import memoizeOne from 'memoize-one';
|
|
13
3
|
import React from 'react';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
_this.setState(function (_ref) {
|
|
37
|
-
var refreshCount = _ref.refreshCount;
|
|
38
|
-
return {
|
|
39
|
-
refreshCount: ++refreshCount
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
_defineProperty(_assertThisInitialized(_this), "_outerRef", undefined);
|
|
45
|
-
_defineProperty(_assertThisInitialized(_this), "_resetIsScrollingTimeoutId", null);
|
|
46
|
-
_defineProperty(_assertThisInitialized(_this), "_callOnItemsRendered", memoizeOne(function (overscanStartIndex, overscanStopIndex, visibleStartIndex, visibleStopIndex) {
|
|
47
|
-
return _this.props.onItemsRendered({
|
|
48
|
-
overscanStartIndex: overscanStartIndex,
|
|
49
|
-
overscanStopIndex: overscanStopIndex,
|
|
50
|
-
visibleStartIndex: visibleStartIndex,
|
|
51
|
-
visibleStopIndex: visibleStopIndex
|
|
52
|
-
});
|
|
53
|
-
}));
|
|
54
|
-
_defineProperty(_assertThisInitialized(_this), "_callOnScroll", memoizeOne(function (scrollDirection, scrollOffset, scrollUpdateWasRequested, detail) {
|
|
55
|
-
return _this.props.onScroll({
|
|
56
|
-
scrollDirection: scrollDirection,
|
|
57
|
-
scrollOffset: scrollOffset,
|
|
58
|
-
scrollUpdateWasRequested: scrollUpdateWasRequested,
|
|
59
|
-
detail: detail
|
|
60
|
-
});
|
|
61
|
-
}));
|
|
62
|
-
_defineProperty(_assertThisInitialized(_this), "_getSizeUploadSync", function (index, isHorizontal) {
|
|
63
|
-
var ID = "#".concat(_this.state.id, "-").concat(index);
|
|
64
|
-
return new Promise(function (resolve) {
|
|
65
|
-
var success = function success(_ref2) {
|
|
66
|
-
var width = _ref2.width,
|
|
67
|
-
height = _ref2.height;
|
|
68
|
-
var size = isHorizontal ? width : height;
|
|
69
|
-
if (!_this.itemList.compareSize(index, size)) {
|
|
70
|
-
_this.itemList.setSize(index, size);
|
|
71
|
-
resolve(_this.itemList.getSize(index));
|
|
72
|
-
}
|
|
4
|
+
import { convertNumber2PX } from '../../../utils/convert.js';
|
|
5
|
+
import { omit } from '../../../utils/lodash.js';
|
|
6
|
+
import { cancelTimeout, requestTimeout } from '../../../utils/timer.js';
|
|
7
|
+
import { IS_SCROLLING_DEBOUNCE_INTERVAL } from '../constants.js';
|
|
8
|
+
import { getRTLOffsetType } from '../dom-helpers.js';
|
|
9
|
+
import Preset from '../preset.js';
|
|
10
|
+
import { getRectSize, defaultItemKey } from '../utils.js';
|
|
11
|
+
import { validateListProps } from './validate.js';
|
|
12
|
+
|
|
13
|
+
class List extends React.PureComponent {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super(props);
|
|
16
|
+
// FIXME Warning: Cannot update during an existing state transition (such as within `render`).
|
|
17
|
+
this.refresh = () => {
|
|
18
|
+
if (process.env.FRAMEWORK === 'preact') {
|
|
19
|
+
this.forceUpdate();
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.setState(({ refreshCount }) => ({
|
|
23
|
+
refreshCount: ++refreshCount
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
73
26
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
27
|
+
this._outerRef = undefined;
|
|
28
|
+
this._resetIsScrollingTimeoutId = null;
|
|
29
|
+
this._callOnItemsRendered = memoizeOne((overscanStartIndex, overscanStopIndex, visibleStartIndex, visibleStopIndex) => this.props.onItemsRendered({
|
|
30
|
+
overscanStartIndex,
|
|
31
|
+
overscanStopIndex,
|
|
32
|
+
visibleStartIndex,
|
|
33
|
+
visibleStopIndex
|
|
34
|
+
}));
|
|
35
|
+
// FIXME 优化事件信息
|
|
36
|
+
this._callOnScroll = memoizeOne((scrollDirection, scrollOffset, scrollUpdateWasRequested, detail) => this.props.onScroll({
|
|
37
|
+
scrollDirection,
|
|
38
|
+
scrollOffset,
|
|
39
|
+
scrollUpdateWasRequested,
|
|
40
|
+
detail
|
|
41
|
+
}));
|
|
42
|
+
this._getSizeUploadSync = (index, isHorizontal) => {
|
|
43
|
+
const ID = `#${this.state.id}-${index}`;
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
const success = ({ width, height }) => {
|
|
46
|
+
const size = isHorizontal ? width : height;
|
|
47
|
+
if (!this.itemList.compareSize(index, size)) {
|
|
48
|
+
this.itemList.setSize(index, size);
|
|
49
|
+
resolve(this.itemList.getSize(index));
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const fail = () => {
|
|
53
|
+
const [startIndex, stopIndex] = this._getRangeToRender();
|
|
54
|
+
if (index >= startIndex && index <= stopIndex) {
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
getRectSize(ID, success, fail);
|
|
57
|
+
}, 100);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
getRectSize(ID, success, fail);
|
|
61
|
+
});
|
|
84
62
|
};
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
scrollWidth: scrollOffset
|
|
63
|
+
this._onScrollHorizontal = event => {
|
|
64
|
+
const { clientWidth, scrollTop, scrollLeft, scrollHeight, scrollWidth } = event.currentTarget;
|
|
65
|
+
this.preset.field = {
|
|
66
|
+
scrollHeight: scrollHeight,
|
|
67
|
+
scrollWidth: this.itemList.getOffsetSize(),
|
|
68
|
+
scrollTop: scrollTop,
|
|
69
|
+
scrollLeft: scrollLeft,
|
|
70
|
+
clientHeight: scrollHeight,
|
|
71
|
+
clientWidth: scrollWidth
|
|
72
|
+
};
|
|
73
|
+
this.setState((prevState) => {
|
|
74
|
+
const diffOffset = this.preset.field.scrollLeft - scrollLeft;
|
|
75
|
+
if (prevState.scrollOffset === scrollLeft || this.preset.isShaking(diffOffset)) {
|
|
76
|
+
// Scroll position may have been updated by cDM/cDU,
|
|
77
|
+
// In which case we don't need to trigger another render,
|
|
78
|
+
// And we don't want to update state.isScrolling.
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
let scrollOffset = scrollLeft;
|
|
82
|
+
if (this.preset.isRtl) {
|
|
83
|
+
// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
|
|
84
|
+
// This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
|
|
85
|
+
// It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
|
|
86
|
+
// So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
|
|
87
|
+
switch (getRTLOffsetType()) {
|
|
88
|
+
case 'negative':
|
|
89
|
+
scrollOffset = -scrollLeft;
|
|
90
|
+
break;
|
|
91
|
+
case 'positive-descending':
|
|
92
|
+
scrollOffset = scrollWidth - clientWidth - scrollLeft;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
} // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
|
|
96
|
+
this.preset.field = {
|
|
97
|
+
scrollWidth: scrollOffset,
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
isScrolling: true,
|
|
101
|
+
scrollDirection: prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
|
|
102
|
+
scrollOffset,
|
|
103
|
+
scrollUpdateWasRequested: false
|
|
104
|
+
};
|
|
105
|
+
}, this._resetIsScrollingDebounced);
|
|
129
106
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
107
|
+
this._onScrollVertical = event => {
|
|
108
|
+
const { clientHeight, scrollHeight, scrollWidth, scrollTop, scrollLeft } = event.currentTarget;
|
|
109
|
+
this.setState((prevState) => {
|
|
110
|
+
const diffOffset = this.preset.field.scrollTop - scrollTop;
|
|
111
|
+
if (prevState.scrollOffset === scrollTop || this.preset.isShaking(diffOffset)) {
|
|
112
|
+
// Scroll position may have been updated by cDM/cDU,
|
|
113
|
+
// In which case we don't need to trigger another render,
|
|
114
|
+
// And we don't want to update state.isScrolling.
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
// FIXME preact 中使用时,该组件会出现触底滚动事件重复触发导致的抖动问题,后续修复
|
|
118
|
+
// Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
|
|
119
|
+
const scrollOffset = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
|
|
120
|
+
this.preset.field = {
|
|
121
|
+
scrollHeight: this.itemList.getOffsetSize(),
|
|
122
|
+
scrollWidth: scrollWidth,
|
|
123
|
+
scrollTop: scrollOffset,
|
|
124
|
+
scrollLeft: scrollLeft,
|
|
125
|
+
clientHeight: clientHeight,
|
|
126
|
+
clientWidth: scrollWidth,
|
|
127
|
+
diffOffset: this.preset.field.scrollTop - scrollOffset,
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
isScrolling: true,
|
|
131
|
+
scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
|
|
132
|
+
scrollOffset,
|
|
133
|
+
scrollUpdateWasRequested: false
|
|
134
|
+
};
|
|
135
|
+
}, this._resetIsScrollingDebounced);
|
|
135
136
|
};
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
var diffOffset = _this.preset.field.scrollTop - scrollTop;
|
|
147
|
-
if (prevState.scrollOffset === scrollTop || _this.preset.isShaking(diffOffset)) {
|
|
148
|
-
// Scroll position may have been updated by cDM/cDU,
|
|
149
|
-
// In which case we don't need to trigger another render,
|
|
150
|
-
// And we don't want to update state.isScrolling.
|
|
151
|
-
return null;
|
|
152
|
-
}
|
|
153
|
-
// FIXME preact 中使用时,该组件会出现触底滚动事件重复触发导致的抖动问题,后续修复
|
|
154
|
-
// Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
|
|
155
|
-
var scrollOffset = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
|
|
156
|
-
_this.preset.field = {
|
|
157
|
-
scrollHeight: _this.itemList.getOffsetSize(),
|
|
158
|
-
scrollWidth: scrollWidth,
|
|
159
|
-
scrollTop: scrollOffset,
|
|
160
|
-
scrollLeft: scrollLeft,
|
|
161
|
-
clientHeight: clientHeight,
|
|
162
|
-
clientWidth: scrollWidth,
|
|
163
|
-
diffOffset: _this.preset.field.scrollTop - scrollOffset
|
|
137
|
+
this._outerRefSetter = ref => {
|
|
138
|
+
const { outerRef } = this.props;
|
|
139
|
+
this._outerRef = ref;
|
|
140
|
+
if (typeof outerRef === 'function') {
|
|
141
|
+
outerRef(ref);
|
|
142
|
+
}
|
|
143
|
+
else if (outerRef != null && typeof outerRef === 'object' && outerRef.hasOwnProperty('current')) {
|
|
144
|
+
// @ts-ignore
|
|
145
|
+
outerRef.current = ref;
|
|
146
|
+
}
|
|
164
147
|
};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
148
|
+
this._resetIsScrollingDebounced = () => {
|
|
149
|
+
if (this._resetIsScrollingTimeoutId !== null) {
|
|
150
|
+
cancelTimeout(this._resetIsScrollingTimeoutId);
|
|
151
|
+
}
|
|
152
|
+
this._resetIsScrollingTimeoutId = requestTimeout(this._resetIsScrolling, IS_SCROLLING_DEBOUNCE_INTERVAL);
|
|
170
153
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
scrollOffset: typeof _this.props.initialScrollOffset === 'number' ? _this.props.initialScrollOffset : 0,
|
|
207
|
-
scrollUpdateWasRequested: false,
|
|
208
|
-
refreshCount: 0
|
|
209
|
-
};
|
|
210
|
-
return _this;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// FIXME Warning: Cannot update during an existing state transition (such as within `render`).
|
|
214
|
-
_createClass(List, [{
|
|
215
|
-
key: "_callPropsCallbacks",
|
|
216
|
-
value: function _callPropsCallbacks() {
|
|
217
|
-
var _this2 = this;
|
|
218
|
-
var prevProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
219
|
-
var prevState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
220
|
-
if (typeof this.props.onItemsRendered === 'function') {
|
|
221
|
-
if (this.props.itemCount > 0) {
|
|
222
|
-
if (prevProps && prevProps.itemCount !== this.props.itemCount) {
|
|
223
|
-
var _this$_getRangeToRend3 = this._getRangeToRender(),
|
|
224
|
-
_this$_getRangeToRend4 = _slicedToArray(_this$_getRangeToRend3, 4),
|
|
225
|
-
overscanStartIndex = _this$_getRangeToRend4[0],
|
|
226
|
-
overscanStopIndex = _this$_getRangeToRend4[1],
|
|
227
|
-
visibleStartIndex = _this$_getRangeToRend4[2],
|
|
228
|
-
visibleStopIndex = _this$_getRangeToRend4[3];
|
|
229
|
-
this._callOnItemsRendered(overscanStartIndex, overscanStopIndex, visibleStartIndex, visibleStopIndex);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (typeof this.props.onScroll === 'function') {
|
|
234
|
-
if (!prevState || prevState.scrollDirection !== this.state.scrollDirection || prevState.scrollOffset !== this.state.scrollOffset || prevState.scrollUpdateWasRequested !== this.state.scrollUpdateWasRequested) {
|
|
235
|
-
this._callOnScroll(this.state.scrollDirection, this.state.scrollOffset, this.state.scrollUpdateWasRequested, this.preset.field);
|
|
154
|
+
this._resetIsScrolling = () => {
|
|
155
|
+
this._resetIsScrollingTimeoutId = null;
|
|
156
|
+
this.setState({
|
|
157
|
+
isScrolling: false
|
|
158
|
+
}, () => {
|
|
159
|
+
// Clear style cache after state update has been committed.
|
|
160
|
+
// This way we don't break pure sCU for items that don't use isScrolling param.
|
|
161
|
+
this.preset.getItemStyleCache(-1, null);
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
this.preset = new Preset(props, this.refresh);
|
|
165
|
+
this.itemList = this.preset.itemList;
|
|
166
|
+
this.state = {
|
|
167
|
+
id: this.props.id || this.preset.id,
|
|
168
|
+
instance: this,
|
|
169
|
+
isScrolling: false,
|
|
170
|
+
scrollDirection: 'forward',
|
|
171
|
+
scrollOffset: typeof this.props.initialScrollOffset === 'number'
|
|
172
|
+
? this.props.initialScrollOffset
|
|
173
|
+
: 0,
|
|
174
|
+
scrollUpdateWasRequested: false,
|
|
175
|
+
refreshCount: 0
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
static getDerivedStateFromProps(nextProps, prevState) {
|
|
179
|
+
return validateListProps(nextProps, prevState);
|
|
180
|
+
}
|
|
181
|
+
_callPropsCallbacks(prevProps = {}, prevState = {}) {
|
|
182
|
+
if (typeof this.props.onItemsRendered === 'function') {
|
|
183
|
+
if (this.props.itemCount > 0) {
|
|
184
|
+
if (prevProps && prevProps.itemCount !== this.props.itemCount) {
|
|
185
|
+
const [overscanStartIndex, overscanStopIndex, visibleStartIndex, visibleStopIndex] = this._getRangeToRender();
|
|
186
|
+
this._callOnItemsRendered(overscanStartIndex, overscanStopIndex, visibleStartIndex, visibleStopIndex);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
236
189
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
for (var index = startIndex; index <= stopIndex; index++) {
|
|
245
|
-
_this2._getSizeUploadSync(index, isHorizontal);
|
|
190
|
+
if (typeof this.props.onScroll === 'function') {
|
|
191
|
+
if (!prevState ||
|
|
192
|
+
prevState.scrollDirection !== this.state.scrollDirection ||
|
|
193
|
+
prevState.scrollOffset !== this.state.scrollOffset ||
|
|
194
|
+
prevState.scrollUpdateWasRequested !== this.state.scrollUpdateWasRequested) {
|
|
195
|
+
this._callOnScroll(this.state.scrollDirection, this.state.scrollOffset, this.state.scrollUpdateWasRequested, this.preset.field);
|
|
196
|
+
}
|
|
246
197
|
}
|
|
247
|
-
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
const [startIndex, stopIndex] = this._getRangeToRender();
|
|
200
|
+
const isHorizontal = this.preset.isHorizontal;
|
|
201
|
+
for (let index = startIndex; index <= stopIndex; index++) {
|
|
202
|
+
this._getSizeUploadSync(index, isHorizontal);
|
|
203
|
+
}
|
|
204
|
+
}, 0);
|
|
248
205
|
}
|
|
249
|
-
}, {
|
|
250
|
-
key: "_getRangeToRender",
|
|
251
|
-
value:
|
|
252
206
|
// Lazily create and cache item styles while scrolling,
|
|
253
207
|
// So that pure component sCU will prevent re-renders.
|
|
254
208
|
// We maintain this cache, and pass a style prop rather than index,
|
|
255
209
|
// So that List can clear cached styles and force item re-render if necessary.
|
|
256
|
-
|
|
257
|
-
|
|
210
|
+
_getRangeToRender() {
|
|
211
|
+
return this.itemList.getRangeToRender(this.state.scrollDirection, this.state.scrollOffset, this.state.isScrolling);
|
|
258
212
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
};
|
|
272
|
-
}, this._resetIsScrollingDebounced);
|
|
213
|
+
scrollTo(scrollOffset) {
|
|
214
|
+
scrollOffset = Math.max(0, scrollOffset);
|
|
215
|
+
this.setState((prevState) => {
|
|
216
|
+
if (prevState.scrollOffset === scrollOffset) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
|
|
221
|
+
scrollOffset: scrollOffset,
|
|
222
|
+
scrollUpdateWasRequested: true
|
|
223
|
+
};
|
|
224
|
+
}, this._resetIsScrollingDebounced);
|
|
273
225
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
var scrollOffset = this.state.scrollOffset;
|
|
280
|
-
index = Math.max(0, Math.min(index, itemCount - 1));
|
|
281
|
-
this.scrollTo(this.itemList.getOffsetForIndexAndAlignment(index, align, scrollOffset));
|
|
226
|
+
scrollToItem(index, align = 'auto') {
|
|
227
|
+
const { itemCount } = this.props;
|
|
228
|
+
const { scrollOffset } = this.state;
|
|
229
|
+
index = Math.max(0, Math.min(index, itemCount - 1));
|
|
230
|
+
this.scrollTo(this.itemList.getOffsetForIndexAndAlignment(index, align, scrollOffset));
|
|
282
231
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
232
|
+
componentDidMount() {
|
|
233
|
+
const { initialScrollOffset } = this.props;
|
|
234
|
+
if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
|
|
235
|
+
const outerRef = this._outerRef;
|
|
236
|
+
if (this.preset.isHorizontal) {
|
|
237
|
+
outerRef.scrollLeft = initialScrollOffset;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
outerRef.scrollTop = initialScrollOffset;
|
|
241
|
+
}
|
|
293
242
|
}
|
|
294
|
-
|
|
295
|
-
this._callPropsCallbacks();
|
|
243
|
+
this._callPropsCallbacks();
|
|
296
244
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
245
|
+
componentDidUpdate(prevProps, prevState) {
|
|
246
|
+
const { scrollOffset, scrollUpdateWasRequested } = this.state;
|
|
247
|
+
this.preset.update(this.props);
|
|
248
|
+
if (scrollUpdateWasRequested && this._outerRef != null) {
|
|
249
|
+
const outerRef = this._outerRef;
|
|
250
|
+
if (this.preset.isHorizontal) {
|
|
251
|
+
if (this.preset.isRtl) {
|
|
252
|
+
// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
|
|
253
|
+
// This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
|
|
254
|
+
// So we need to determine which browser behavior we're dealing with, and mimic it.
|
|
255
|
+
switch (getRTLOffsetType()) {
|
|
256
|
+
case 'negative':
|
|
257
|
+
outerRef.scrollLeft = -scrollOffset;
|
|
258
|
+
break;
|
|
259
|
+
case 'positive-ascending':
|
|
260
|
+
outerRef.scrollLeft = scrollOffset;
|
|
261
|
+
break;
|
|
262
|
+
default:
|
|
263
|
+
outerRef.scrollLeft = outerRef.scrollWidth - outerRef.clientWidth - scrollOffset;
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
outerRef.scrollLeft = scrollOffset;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
outerRef.scrollTop = scrollOffset;
|
|
321
273
|
}
|
|
322
|
-
} else {
|
|
323
|
-
outerRef.scrollLeft = scrollOffset;
|
|
324
|
-
}
|
|
325
|
-
} else {
|
|
326
|
-
outerRef.scrollTop = scrollOffset;
|
|
327
274
|
}
|
|
328
|
-
|
|
329
|
-
this._callPropsCallbacks(prevProps, prevState);
|
|
275
|
+
this._callPropsCallbacks(prevProps, prevState);
|
|
330
276
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
cancelTimeout(this._resetIsScrollingTimeoutId);
|
|
336
|
-
}
|
|
277
|
+
componentWillUnmount() {
|
|
278
|
+
if (this._resetIsScrollingTimeoutId !== null) {
|
|
279
|
+
cancelTimeout(this._resetIsScrollingTimeoutId);
|
|
280
|
+
}
|
|
337
281
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
itemCount
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
var placeholderCount = this.preset.placeholderCount;
|
|
366
|
-
var onScroll = isHorizontal ? this._onScrollHorizontal : this._onScrollVertical;
|
|
367
|
-
var _this$_getRangeToRend5 = this._getRangeToRender(),
|
|
368
|
-
_this$_getRangeToRend6 = _slicedToArray(_this$_getRangeToRend5, 2),
|
|
369
|
-
startIndex = _this$_getRangeToRend6[0],
|
|
370
|
-
stopIndex = _this$_getRangeToRend6[1];
|
|
371
|
-
var items = [];
|
|
372
|
-
if (itemCount > 0) {
|
|
373
|
-
var prevPlaceholder = startIndex < placeholderCount ? startIndex : placeholderCount;
|
|
374
|
-
items.push(new Array(prevPlaceholder).fill(-1).map(function (_, index) {
|
|
375
|
-
return React.createElement(_this3.preset.itemTagName, {
|
|
376
|
-
key: itemKey(index + startIndex - prevPlaceholder, itemData),
|
|
377
|
-
style: {
|
|
378
|
-
display: 'none'
|
|
282
|
+
render() {
|
|
283
|
+
const _a = omit(this.props, ['innerElementType', 'innerTagName', 'itemElementType', 'itemTagName', 'outerElementType', 'outerTagName', 'position']), { className, direction, height, innerRef, item, itemCount, itemData, itemKey = defaultItemKey, layout, style, useIsScrolling, width, renderTop, renderBottom } = _a, rest = __rest(_a, ["className", "direction", "height", "innerRef", "item", "itemCount", "itemData", "itemKey", "layout", "style", "useIsScrolling", "width", "renderTop", "renderBottom"]);
|
|
284
|
+
const { id, isScrolling, scrollOffset, scrollUpdateWasRequested } = this.state;
|
|
285
|
+
const isHorizontal = this.preset.isHorizontal;
|
|
286
|
+
const placeholderCount = this.preset.placeholderCount;
|
|
287
|
+
const onScroll = isHorizontal
|
|
288
|
+
? this._onScrollHorizontal
|
|
289
|
+
: this._onScrollVertical;
|
|
290
|
+
const [startIndex, stopIndex] = this._getRangeToRender();
|
|
291
|
+
const items = [];
|
|
292
|
+
if (itemCount > 0) {
|
|
293
|
+
const prevPlaceholder = startIndex < placeholderCount ? startIndex : placeholderCount;
|
|
294
|
+
items.push(new Array(prevPlaceholder).fill(-1).map((_, index) => React.createElement(this.preset.itemTagName, {
|
|
295
|
+
key: itemKey(index + startIndex - prevPlaceholder, itemData),
|
|
296
|
+
style: { display: 'none' }
|
|
297
|
+
})));
|
|
298
|
+
for (let index = startIndex; index <= stopIndex; index++) {
|
|
299
|
+
const style = this.preset.getItemStyle(index);
|
|
300
|
+
items.push(React.createElement(this.preset.itemTagName, {
|
|
301
|
+
key: itemKey(index, itemData),
|
|
302
|
+
style
|
|
303
|
+
}, React.createElement(item, {
|
|
304
|
+
id: `${id}-${index}`,
|
|
305
|
+
data: itemData,
|
|
306
|
+
index,
|
|
307
|
+
isScrolling: useIsScrolling ? isScrolling : undefined
|
|
308
|
+
})));
|
|
379
309
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
310
|
+
const restCount = itemCount - stopIndex;
|
|
311
|
+
const postPlaceholder = restCount < placeholderCount ? restCount : placeholderCount;
|
|
312
|
+
items.push(new Array(postPlaceholder).fill(-1).map((_, index) => React.createElement(this.preset.itemTagName, {
|
|
313
|
+
key: itemKey(1 + index + stopIndex, itemData),
|
|
314
|
+
style: { display: 'none' }
|
|
315
|
+
})));
|
|
316
|
+
}
|
|
317
|
+
// Read this value AFTER items have been created,
|
|
318
|
+
// So their actual sizes (if variable) are taken into consideration.
|
|
319
|
+
const estimatedTotalSize = convertNumber2PX(this.itemList.getOffsetSize());
|
|
320
|
+
const outerElementProps = Object.assign(Object.assign({}, rest), { id,
|
|
321
|
+
className,
|
|
322
|
+
onScroll, ref: this._outerRefSetter, layout, style: Object.assign({ position: 'relative', height: convertNumber2PX(height), width: convertNumber2PX(width), overflow: 'auto', WebkitOverflowScrolling: 'touch', willChange: 'transform', direction }, style) });
|
|
323
|
+
if (isHorizontal) {
|
|
324
|
+
outerElementProps.scrollLeft = scrollUpdateWasRequested ? scrollOffset : this.preset.field.scrollLeft;
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
outerElementProps.scrollTop = scrollUpdateWasRequested ? scrollOffset : this.preset.field.scrollTop;
|
|
328
|
+
}
|
|
329
|
+
if (this.preset.isRelative) {
|
|
330
|
+
const pre = convertNumber2PX(this.itemList.getOffsetSize(startIndex));
|
|
331
|
+
return React.createElement(this.preset.outerTagName, outerElementProps, renderTop, React.createElement(this.preset.itemTagName, {
|
|
332
|
+
key: `${id}-pre`,
|
|
333
|
+
id: `${id}-pre`,
|
|
334
|
+
style: {
|
|
335
|
+
height: isHorizontal ? '100%' : pre,
|
|
336
|
+
width: !isHorizontal ? '100%' : pre
|
|
337
|
+
}
|
|
338
|
+
}), React.createElement(this.preset.innerTagName, {
|
|
339
|
+
ref: innerRef,
|
|
340
|
+
key: `${id}-inner`,
|
|
341
|
+
id: `${id}-inner`,
|
|
342
|
+
style: {
|
|
343
|
+
pointerEvents: isScrolling ? 'none' : 'auto',
|
|
344
|
+
position: 'relative',
|
|
345
|
+
}
|
|
346
|
+
}, items), renderBottom);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
return React.createElement(this.preset.outerTagName, outerElementProps, renderTop, React.createElement(this.preset.innerTagName, {
|
|
350
|
+
ref: innerRef,
|
|
351
|
+
key: `${id}-inner`,
|
|
352
|
+
id: `${id}-inner`,
|
|
353
|
+
style: {
|
|
354
|
+
height: isHorizontal ? '100%' : estimatedTotalSize,
|
|
355
|
+
pointerEvents: isScrolling ? 'none' : 'auto',
|
|
356
|
+
position: 'relative',
|
|
357
|
+
width: !isHorizontal ? '100%' : estimatedTotalSize
|
|
358
|
+
}
|
|
359
|
+
}, items), renderBottom);
|
|
393
360
|
}
|
|
394
|
-
var restCount = itemCount - stopIndex;
|
|
395
|
-
var postPlaceholder = restCount < placeholderCount ? restCount : placeholderCount;
|
|
396
|
-
items.push(new Array(postPlaceholder).fill(-1).map(function (_, index) {
|
|
397
|
-
return React.createElement(_this3.preset.itemTagName, {
|
|
398
|
-
key: itemKey(1 + index + stopIndex, itemData),
|
|
399
|
-
style: {
|
|
400
|
-
display: 'none'
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
}));
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// Read this value AFTER items have been created,
|
|
407
|
-
// So their actual sizes (if variable) are taken into consideration.
|
|
408
|
-
var estimatedTotalSize = convertNumber2PX(this.itemList.getOffsetSize());
|
|
409
|
-
var outerElementProps = _objectSpread(_objectSpread({}, rest), {}, {
|
|
410
|
-
id: id,
|
|
411
|
-
className: className,
|
|
412
|
-
onScroll: onScroll,
|
|
413
|
-
ref: this._outerRefSetter,
|
|
414
|
-
layout: layout,
|
|
415
|
-
style: _objectSpread({
|
|
416
|
-
position: 'relative',
|
|
417
|
-
height: convertNumber2PX(height),
|
|
418
|
-
width: convertNumber2PX(width),
|
|
419
|
-
overflow: 'auto',
|
|
420
|
-
WebkitOverflowScrolling: 'touch',
|
|
421
|
-
willChange: 'transform',
|
|
422
|
-
direction: direction
|
|
423
|
-
}, style)
|
|
424
|
-
});
|
|
425
|
-
if (isHorizontal) {
|
|
426
|
-
outerElementProps.scrollLeft = scrollUpdateWasRequested ? scrollOffset : this.preset.field.scrollLeft;
|
|
427
|
-
} else {
|
|
428
|
-
outerElementProps.scrollTop = scrollUpdateWasRequested ? scrollOffset : this.preset.field.scrollTop;
|
|
429
|
-
}
|
|
430
|
-
if (this.preset.isRelative) {
|
|
431
|
-
var pre = convertNumber2PX(this.itemList.getOffsetSize(startIndex));
|
|
432
|
-
return React.createElement(this.preset.outerTagName, outerElementProps, renderTop, React.createElement(this.preset.itemTagName, {
|
|
433
|
-
key: "".concat(id, "-pre"),
|
|
434
|
-
id: "".concat(id, "-pre"),
|
|
435
|
-
style: {
|
|
436
|
-
height: isHorizontal ? '100%' : pre,
|
|
437
|
-
width: !isHorizontal ? '100%' : pre
|
|
438
|
-
}
|
|
439
|
-
}), React.createElement(this.preset.innerTagName, {
|
|
440
|
-
ref: innerRef,
|
|
441
|
-
key: "".concat(id, "-inner"),
|
|
442
|
-
id: "".concat(id, "-inner"),
|
|
443
|
-
style: {
|
|
444
|
-
pointerEvents: isScrolling ? 'none' : 'auto',
|
|
445
|
-
position: 'relative'
|
|
446
|
-
}
|
|
447
|
-
}, items), renderBottom);
|
|
448
|
-
} else {
|
|
449
|
-
return React.createElement(this.preset.outerTagName, outerElementProps, renderTop, React.createElement(this.preset.innerTagName, {
|
|
450
|
-
ref: innerRef,
|
|
451
|
-
key: "".concat(id, "-inner"),
|
|
452
|
-
id: "".concat(id, "-inner"),
|
|
453
|
-
style: {
|
|
454
|
-
height: isHorizontal ? '100%' : estimatedTotalSize,
|
|
455
|
-
pointerEvents: isScrolling ? 'none' : 'auto',
|
|
456
|
-
position: 'relative',
|
|
457
|
-
width: !isHorizontal ? '100%' : estimatedTotalSize
|
|
458
|
-
}
|
|
459
|
-
}, items), renderBottom);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}], [{
|
|
463
|
-
key: "getDerivedStateFromProps",
|
|
464
|
-
value: function getDerivedStateFromProps(nextProps, prevState) {
|
|
465
|
-
return validateListProps(nextProps, prevState);
|
|
466
361
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
362
|
+
}
|
|
363
|
+
List.defaultProps = {
|
|
364
|
+
direction: 'ltr',
|
|
365
|
+
itemData: undefined,
|
|
366
|
+
layout: 'vertical',
|
|
367
|
+
overscanCount: 2,
|
|
368
|
+
useIsScrolling: false,
|
|
369
|
+
shouldResetStyleCacheOnItemSizeChange: true
|
|
370
|
+
};
|
|
371
|
+
// NOTE: I considered further wrapping individual items with a pure ListItem component.
|
|
470
372
|
// This would avoid ever calling the render function for the same index more than once,
|
|
471
373
|
// But it would also add the overhead of a lot of components/fibers.
|
|
472
374
|
// I assume people already do this (render function returning a class component),
|
|
473
375
|
// So my doing it would just unnecessarily double the wrappers.
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
layout: 'vertical',
|
|
478
|
-
overscanCount: 2,
|
|
479
|
-
useIsScrolling: false,
|
|
480
|
-
shouldResetStyleCacheOnItemSizeChange: true
|
|
481
|
-
});
|
|
482
|
-
export { List as default };
|
|
376
|
+
|
|
377
|
+
export { List as default };
|
|
378
|
+
//# sourceMappingURL=list.js.map
|