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