@tarojs/components 3.6.0-canary.6 → 3.6.0-canary.8
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/react/component-lib/index.js +20 -10
- package/dist/react/component-lib/input.js +3 -4
- package/dist/react/component-lib/reactify-wc.js +9 -46
- package/dist/react/components.js +0 -2
- package/dist/react/react-component-lib/createComponent.js +10 -30
- package/dist/react/react-component-lib/createOverlayComponent.js +8 -37
- package/dist/react/react-component-lib/utils/attachProps.js +9 -18
- package/dist/react/react-component-lib/utils/index.js +6 -9
- package/dist/vue2/component-lib/components.js +22 -11
- package/dist/vue2/component-lib/createFormsComponent.js +0 -5
- package/dist/vue2/component-lib/index.js +6 -8
- package/dist/vue2/component-lib/mixins/refs.js +0 -5
- package/dist/vue2/components.js +0 -3
- package/dist/vue2/index.js +3 -7
- package/dist/vue2/vue-component-lib/utils.js +0 -1
- package/dist/vue3/component-lib/createComponent.js +1 -1
- package/dist/vue3/component-lib/createFormsComponent.js +3 -8
- package/dist/vue3/component-lib/forwardRef.js +0 -2
- package/dist/vue3/component-lib/icon.js +2 -2
- package/dist/vue3/component-lib/image.js +2 -2
- package/dist/vue3/component-lib/index.js +22 -11
- package/dist/vue3/component-lib/scroll-view.js +2 -2
- package/dist/vue3/component-lib/text.js +2 -2
- package/dist/vue3/components.js +0 -2
- package/dist/vue3/index.js +2 -4
- package/dist/vue3/vue-component-lib/utils.js +7 -29
- package/package.json +4 -3
- package/types/Button.d.ts +1 -1
- package/types/Camera.d.ts +1 -1
- package/types/Checkbox.d.ts +1 -1
- package/types/CheckboxGroup.d.ts +1 -1
- package/types/CoverImage.d.ts +1 -1
- package/types/CustomWrapper.d.ts +1 -0
- package/types/Form.d.ts +1 -1
- package/types/Icon.d.ts +1 -1
- package/types/Image.d.ts +1 -1
- package/types/Input.d.ts +15 -1
- package/types/Label.d.ts +1 -1
- package/types/NativeSlot.d.ts +1 -0
- package/types/NavigationBar.d.ts +2 -1
- package/types/Navigator.d.ts +1 -1
- package/types/Picker.d.ts +1 -1
- package/types/PickerView.d.ts +1 -1
- package/types/PickerViewColumn.d.ts +1 -1
- package/types/Progress.d.ts +1 -1
- package/types/Radio.d.ts +1 -1
- package/types/RadioGroup.d.ts +1 -1
- package/types/RichText.d.ts +1 -1
- package/types/ScrollView.d.ts +1 -1
- package/types/ShareElement.d.ts +3 -3
- package/types/Slider.d.ts +1 -1
- package/types/Slot.d.ts +2 -1
- package/types/Swiper.d.ts +1 -1
- package/types/SwiperItem.d.ts +1 -1
- package/types/Switch.d.ts +1 -1
- package/types/Textarea.d.ts +1 -1
- package/types/Video.d.ts +1 -1
- package/types/View.d.ts +1 -1
- package/types/WebView.d.ts +1 -1
- package/virtual-list/index.d.ts +3 -120
- package/virtual-list/index.js +3 -7
- package/virtual-list/domHelpers.js +0 -40
- package/virtual-list/memoize.js +0 -38
- package/virtual-list/react/FixedSizeList.js +0 -193
- package/virtual-list/react/createListComponent.js +0 -654
- package/virtual-list/react/index.d.ts +0 -123
- package/virtual-list/react/index.js +0 -67
- package/virtual-list/timer.js +0 -24
- package/virtual-list/vue/index.js +0 -589
|
@@ -1,589 +0,0 @@
|
|
|
1
|
-
import { getRTLOffsetType } from '../domHelpers'
|
|
2
|
-
import { memoizeOne } from '../memoize'
|
|
3
|
-
import { cancelTimeout, requestTimeout } from '../timer'
|
|
4
|
-
|
|
5
|
-
const IS_SCROLLING_DEBOUNCE_INTERVAL = 150
|
|
6
|
-
|
|
7
|
-
const defaultItemKey = (index) => index
|
|
8
|
-
|
|
9
|
-
function createListComponent ({
|
|
10
|
-
getItemOffset,
|
|
11
|
-
getEstimatedTotalSize,
|
|
12
|
-
getItemSize,
|
|
13
|
-
getOffsetForIndexAndAlignment,
|
|
14
|
-
getStartIndexForOffset,
|
|
15
|
-
getStopIndexForStartIndex,
|
|
16
|
-
initInstanceProps,
|
|
17
|
-
shouldResetStyleCacheOnItemSizeChange,
|
|
18
|
-
Vue
|
|
19
|
-
}) {
|
|
20
|
-
return {
|
|
21
|
-
props: {
|
|
22
|
-
direction: {
|
|
23
|
-
type: String,
|
|
24
|
-
default: 'ltr'
|
|
25
|
-
},
|
|
26
|
-
itemData: Array,
|
|
27
|
-
layout: {
|
|
28
|
-
type: String,
|
|
29
|
-
default: 'vertical'
|
|
30
|
-
},
|
|
31
|
-
useIsScrolling: {
|
|
32
|
-
type: Boolean,
|
|
33
|
-
default: false
|
|
34
|
-
},
|
|
35
|
-
overscanCount: {
|
|
36
|
-
type: Number,
|
|
37
|
-
default: 1
|
|
38
|
-
},
|
|
39
|
-
wclass: String,
|
|
40
|
-
height: {},
|
|
41
|
-
innerRef: String,
|
|
42
|
-
innerElementType: {
|
|
43
|
-
type: String,
|
|
44
|
-
default: 'view'
|
|
45
|
-
},
|
|
46
|
-
itemCount: Number,
|
|
47
|
-
wstyle: String,
|
|
48
|
-
width: String,
|
|
49
|
-
itemSize: {
|
|
50
|
-
required: true
|
|
51
|
-
},
|
|
52
|
-
item: {
|
|
53
|
-
required: true
|
|
54
|
-
},
|
|
55
|
-
initialScrollOffset: {
|
|
56
|
-
type: String,
|
|
57
|
-
defalt: 0
|
|
58
|
-
},
|
|
59
|
-
scrollNative: Function
|
|
60
|
-
},
|
|
61
|
-
data () {
|
|
62
|
-
return {
|
|
63
|
-
instance: this,
|
|
64
|
-
isScrolling: false,
|
|
65
|
-
scrollDirection: 'forward',
|
|
66
|
-
scrollOffset:
|
|
67
|
-
typeof this.$props.initialScrollOffset === 'number'
|
|
68
|
-
? this.$props.initialScrollOffset
|
|
69
|
-
: 0,
|
|
70
|
-
scrollUpdateWasRequested: false,
|
|
71
|
-
resetIsScrollingTimeoutId: null
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
methods: {
|
|
75
|
-
_instanceProps () {
|
|
76
|
-
initInstanceProps(this.$props, this)
|
|
77
|
-
},
|
|
78
|
-
scrollTo (scrollOffset) {
|
|
79
|
-
scrollOffset = Math.max(0, scrollOffset)
|
|
80
|
-
|
|
81
|
-
if (this.scrollOffset === scrollOffset) {
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
this.scrollDirection = this.scrollOffset < scrollOffset ? 'forward' : 'backward'
|
|
86
|
-
this.scrollOffset = scrollOffset
|
|
87
|
-
this.scrollUpdateWasRequested = true
|
|
88
|
-
|
|
89
|
-
Vue.nextTick(this._resetIsScrollingDebounced)
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
scrollToItem (index, align = 'auto') {
|
|
93
|
-
const { itemCount } = this.$props
|
|
94
|
-
const { scrollOffset } = this.$data
|
|
95
|
-
|
|
96
|
-
index = Math.max(0, Math.min(index, itemCount - 1))
|
|
97
|
-
|
|
98
|
-
this.scrollTo(
|
|
99
|
-
getOffsetForIndexAndAlignment(
|
|
100
|
-
this.$props,
|
|
101
|
-
index,
|
|
102
|
-
align,
|
|
103
|
-
scrollOffset,
|
|
104
|
-
this._instanceProps()
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
_callOnItemsRendered: memoizeOne(
|
|
110
|
-
function (
|
|
111
|
-
overscanStartIndex,
|
|
112
|
-
overscanStopIndex,
|
|
113
|
-
visibleStartIndex,
|
|
114
|
-
visibleStopIndex
|
|
115
|
-
) {
|
|
116
|
-
return this.$props.onItemsRendered({
|
|
117
|
-
overscanStartIndex,
|
|
118
|
-
overscanStopIndex,
|
|
119
|
-
visibleStartIndex,
|
|
120
|
-
visibleStopIndex
|
|
121
|
-
})
|
|
122
|
-
}
|
|
123
|
-
),
|
|
124
|
-
|
|
125
|
-
_callOnScroll: memoizeOne(
|
|
126
|
-
function (
|
|
127
|
-
scrollDirection,
|
|
128
|
-
scrollOffset,
|
|
129
|
-
scrollUpdateWasRequested
|
|
130
|
-
) {
|
|
131
|
-
this.$emit('scroll', {
|
|
132
|
-
scrollDirection,
|
|
133
|
-
scrollOffset,
|
|
134
|
-
scrollUpdateWasRequested
|
|
135
|
-
})
|
|
136
|
-
}
|
|
137
|
-
),
|
|
138
|
-
|
|
139
|
-
_callPropsCallbacks () {
|
|
140
|
-
if (typeof this.$props.onItemsRendered === 'function') {
|
|
141
|
-
const { itemCount } = this.$props
|
|
142
|
-
if (itemCount > 0) {
|
|
143
|
-
const [
|
|
144
|
-
overscanStartIndex,
|
|
145
|
-
overscanStopIndex,
|
|
146
|
-
visibleStartIndex,
|
|
147
|
-
visibleStopIndex
|
|
148
|
-
] = this._getRangeToRender()
|
|
149
|
-
this._callOnItemsRendered(
|
|
150
|
-
overscanStartIndex,
|
|
151
|
-
overscanStopIndex,
|
|
152
|
-
visibleStartIndex,
|
|
153
|
-
visibleStopIndex
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
this._callOnScroll(
|
|
159
|
-
this.scrollDirection,
|
|
160
|
-
this.scrollOffset,
|
|
161
|
-
this.scrollUpdateWasRequested
|
|
162
|
-
)
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
_getStyleValue (value) {
|
|
166
|
-
return typeof value === 'number'
|
|
167
|
-
? value + 'px'
|
|
168
|
-
: value == null
|
|
169
|
-
? ''
|
|
170
|
-
: value
|
|
171
|
-
},
|
|
172
|
-
|
|
173
|
-
_getItemStyle (index) {
|
|
174
|
-
const { direction, itemSize, layout } = this.$props
|
|
175
|
-
|
|
176
|
-
const itemStyleCache = this._getItemStyleCache(
|
|
177
|
-
shouldResetStyleCacheOnItemSizeChange && itemSize,
|
|
178
|
-
shouldResetStyleCacheOnItemSizeChange && layout,
|
|
179
|
-
shouldResetStyleCacheOnItemSizeChange && direction
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
let style
|
|
183
|
-
if (itemStyleCache.hasOwnProperty(index)) {
|
|
184
|
-
style = itemStyleCache[index]
|
|
185
|
-
} else {
|
|
186
|
-
const offset = getItemOffset(this.$props, index, this._instanceProps())
|
|
187
|
-
const size = getItemSize(this.$props, index, this._instanceProps())
|
|
188
|
-
|
|
189
|
-
// TODO Deprecate direction "horizontal"
|
|
190
|
-
const isHorizontal =
|
|
191
|
-
direction === 'horizontal' || layout === 'horizontal'
|
|
192
|
-
|
|
193
|
-
const isRtl = direction === 'rtl'
|
|
194
|
-
const offsetHorizontal = isHorizontal ? offset : 0
|
|
195
|
-
itemStyleCache[index] = style = {
|
|
196
|
-
position: 'absolute',
|
|
197
|
-
left: isRtl ? undefined : offsetHorizontal,
|
|
198
|
-
right: isRtl ? offsetHorizontal : undefined,
|
|
199
|
-
top: !isHorizontal ? offset : 0,
|
|
200
|
-
height: !isHorizontal ? size : '100%',
|
|
201
|
-
width: isHorizontal ? size : '100%'
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
for (const k in style) {
|
|
206
|
-
if (style.hasOwnProperty(k)) {
|
|
207
|
-
style[k] = this._getStyleValue(style[k])
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return style
|
|
212
|
-
},
|
|
213
|
-
|
|
214
|
-
_getItemStyleCache: memoizeOne(() => ({})),
|
|
215
|
-
|
|
216
|
-
_getRangeToRender () {
|
|
217
|
-
const { itemCount, overscanCount } = this.$props
|
|
218
|
-
const { isScrolling, scrollDirection, scrollOffset } = this.$data
|
|
219
|
-
|
|
220
|
-
if (itemCount === 0) {
|
|
221
|
-
return [0, 0, 0, 0]
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const startIndex = getStartIndexForOffset(
|
|
225
|
-
this.$props,
|
|
226
|
-
scrollOffset,
|
|
227
|
-
this._instanceProps()
|
|
228
|
-
)
|
|
229
|
-
const stopIndex = getStopIndexForStartIndex(
|
|
230
|
-
this.$props,
|
|
231
|
-
startIndex,
|
|
232
|
-
scrollOffset,
|
|
233
|
-
this._instanceProps()
|
|
234
|
-
)
|
|
235
|
-
|
|
236
|
-
// Overscan by one item in each direction so that tab/focus works.
|
|
237
|
-
// If there isn't at least one extra item, tab loops back around.
|
|
238
|
-
const overscanBackward =
|
|
239
|
-
!isScrolling || scrollDirection === 'backward'
|
|
240
|
-
? Math.max(1, overscanCount)
|
|
241
|
-
: 1
|
|
242
|
-
const overscanForward =
|
|
243
|
-
!isScrolling || scrollDirection === 'forward'
|
|
244
|
-
? Math.max(1, overscanCount)
|
|
245
|
-
: 1
|
|
246
|
-
|
|
247
|
-
return [
|
|
248
|
-
Math.max(0, startIndex - overscanBackward),
|
|
249
|
-
Math.max(0, Math.min(itemCount - 1, stopIndex + overscanForward)),
|
|
250
|
-
startIndex,
|
|
251
|
-
stopIndex
|
|
252
|
-
]
|
|
253
|
-
},
|
|
254
|
-
|
|
255
|
-
_onScrollHorizontal (event) {
|
|
256
|
-
const clientWidth = this.$props.width
|
|
257
|
-
const { scrollLeft, scrollWidth } = event.currentTarget
|
|
258
|
-
if (this.$props.scrollNative) {
|
|
259
|
-
this.$props.scrollNative(event)
|
|
260
|
-
}
|
|
261
|
-
if (this.scrollOffset === scrollLeft) {
|
|
262
|
-
return
|
|
263
|
-
}
|
|
264
|
-
const { direction } = this.$props
|
|
265
|
-
|
|
266
|
-
let scrollOffset = scrollLeft
|
|
267
|
-
if (direction === 'rtl') {
|
|
268
|
-
// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
|
|
269
|
-
// This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
|
|
270
|
-
// It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
|
|
271
|
-
// So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
|
|
272
|
-
switch (getRTLOffsetType()) {
|
|
273
|
-
case 'negative':
|
|
274
|
-
scrollOffset = -scrollLeft
|
|
275
|
-
break
|
|
276
|
-
case 'positive-descending':
|
|
277
|
-
scrollOffset = scrollWidth - clientWidth - scrollLeft
|
|
278
|
-
break
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
|
|
283
|
-
scrollOffset = Math.max(
|
|
284
|
-
0,
|
|
285
|
-
Math.min(scrollOffset, scrollWidth - clientWidth)
|
|
286
|
-
)
|
|
287
|
-
this.isScrolling = true
|
|
288
|
-
this.scrollDirection = this.scrollOffset < scrollLeft ? 'forward' : 'backward'
|
|
289
|
-
this.scrollOffset = scrollOffset
|
|
290
|
-
this.scrollUpdateWasRequested = false
|
|
291
|
-
Vue.nextTick(this._resetIsScrollingDebounced)
|
|
292
|
-
},
|
|
293
|
-
|
|
294
|
-
_onScrollVertical (event) {
|
|
295
|
-
const clientHeight = this.$props.height
|
|
296
|
-
const { scrollHeight, scrollTop } = event.currentTarget
|
|
297
|
-
if (this.$props.scrollNative) {
|
|
298
|
-
this.$props.scrollNative(event)
|
|
299
|
-
}
|
|
300
|
-
if (this.scrollOffset === scrollTop) {
|
|
301
|
-
return
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
|
|
305
|
-
const scrollOffset = Math.max(
|
|
306
|
-
0,
|
|
307
|
-
Math.min(scrollTop, scrollHeight - clientHeight)
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
this.isScrolling = true
|
|
311
|
-
this.scrollDirection = this.scrollOffset < scrollOffset ? 'forward' : 'backward'
|
|
312
|
-
this.scrollOffset = scrollOffset
|
|
313
|
-
this.scrollUpdateWasRequested = false
|
|
314
|
-
Vue.nextTick(this._resetIsScrollingDebounced)
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
_resetIsScrollingDebounced () {
|
|
318
|
-
if (this.resetIsScrollingTimeoutId !== null) {
|
|
319
|
-
cancelTimeout(this.resetIsScrollingTimeoutId)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
this.resetIsScrollingTimeoutId = requestTimeout(
|
|
323
|
-
this._resetIsScrolling,
|
|
324
|
-
IS_SCROLLING_DEBOUNCE_INTERVAL
|
|
325
|
-
)
|
|
326
|
-
},
|
|
327
|
-
|
|
328
|
-
_resetIsScrolling () {
|
|
329
|
-
this.resetIsScrollingTimeoutId = null
|
|
330
|
-
this.isScrolling = false
|
|
331
|
-
Vue.nextTick(() => {
|
|
332
|
-
this._getItemStyleCache(-1, null)
|
|
333
|
-
})
|
|
334
|
-
}
|
|
335
|
-
},
|
|
336
|
-
mounted () {
|
|
337
|
-
const { direction, initialScrollOffset, layout } = this.$props
|
|
338
|
-
|
|
339
|
-
if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
|
|
340
|
-
const outerRef = this._outerRef
|
|
341
|
-
// TODO Deprecate direction "horizontal"
|
|
342
|
-
if (direction === 'horizontal' || layout === 'horizontal') {
|
|
343
|
-
outerRef.scrollLeft = initialScrollOffset
|
|
344
|
-
} else {
|
|
345
|
-
outerRef.scrollTop = initialScrollOffset
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
this._callPropsCallbacks()
|
|
350
|
-
},
|
|
351
|
-
updated () {
|
|
352
|
-
const { direction, layout } = this.$props
|
|
353
|
-
const { scrollOffset, scrollUpdateWasRequested } = this.$data
|
|
354
|
-
|
|
355
|
-
if (scrollUpdateWasRequested && this._outerRef != null) {
|
|
356
|
-
const outerRef = this._outerRef
|
|
357
|
-
|
|
358
|
-
// TODO Deprecate direction "horizontal"
|
|
359
|
-
if (direction === 'horizontal' || layout === 'horizontal') {
|
|
360
|
-
if (direction === 'rtl') {
|
|
361
|
-
// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
|
|
362
|
-
// This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
|
|
363
|
-
// So we need to determine which browser behavior we're dealing with, and mimic it.
|
|
364
|
-
switch (getRTLOffsetType()) {
|
|
365
|
-
case 'negative':
|
|
366
|
-
outerRef.scrollLeft = -scrollOffset
|
|
367
|
-
break
|
|
368
|
-
case 'positive-ascending':
|
|
369
|
-
outerRef.scrollLeft = scrollOffset
|
|
370
|
-
break
|
|
371
|
-
default: {
|
|
372
|
-
const { clientWidth, scrollWidth } = outerRef
|
|
373
|
-
outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset
|
|
374
|
-
break
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
} else {
|
|
378
|
-
outerRef.scrollLeft = scrollOffset
|
|
379
|
-
}
|
|
380
|
-
} else {
|
|
381
|
-
outerRef.scrollTop = scrollOffset
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
this._callPropsCallbacks()
|
|
386
|
-
},
|
|
387
|
-
|
|
388
|
-
beforeDestroy () {
|
|
389
|
-
if (this.resetIsScrollingTimeoutId !== null) {
|
|
390
|
-
cancelTimeout(this.resetIsScrollingTimeoutId)
|
|
391
|
-
}
|
|
392
|
-
},
|
|
393
|
-
|
|
394
|
-
render (h) {
|
|
395
|
-
const {
|
|
396
|
-
item,
|
|
397
|
-
wclass,
|
|
398
|
-
direction,
|
|
399
|
-
height,
|
|
400
|
-
innerRef,
|
|
401
|
-
innerElementType,
|
|
402
|
-
itemCount,
|
|
403
|
-
itemData,
|
|
404
|
-
itemKey = defaultItemKey,
|
|
405
|
-
layout,
|
|
406
|
-
wstyle,
|
|
407
|
-
useIsScrolling,
|
|
408
|
-
width
|
|
409
|
-
} = this.$props
|
|
410
|
-
const { isScrolling } = this.$data
|
|
411
|
-
|
|
412
|
-
// TODO Deprecate direction "horizontal"
|
|
413
|
-
const isHorizontal =
|
|
414
|
-
direction === 'horizontal' || layout === 'horizontal'
|
|
415
|
-
|
|
416
|
-
const onScroll = isHorizontal
|
|
417
|
-
? this._onScrollHorizontal
|
|
418
|
-
: this._onScrollVertical
|
|
419
|
-
|
|
420
|
-
const [startIndex, stopIndex] = this._getRangeToRender()
|
|
421
|
-
|
|
422
|
-
const items = []
|
|
423
|
-
if (itemCount > 0) {
|
|
424
|
-
for (let index = startIndex; index <= stopIndex; index++) {
|
|
425
|
-
items.push(
|
|
426
|
-
h(item, {
|
|
427
|
-
key: itemKey(index, itemData),
|
|
428
|
-
props: {
|
|
429
|
-
data: itemData,
|
|
430
|
-
index,
|
|
431
|
-
isScrolling: useIsScrolling ? isScrolling : undefined,
|
|
432
|
-
css: this._getItemStyle(index)
|
|
433
|
-
}
|
|
434
|
-
})
|
|
435
|
-
)
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Read this value AFTER items have been created,
|
|
440
|
-
// So their actual sizes (if variable) are taken into consideration.
|
|
441
|
-
const estimatedTotalSize = getEstimatedTotalSize(
|
|
442
|
-
this.$props,
|
|
443
|
-
this._instanceProps()
|
|
444
|
-
)
|
|
445
|
-
|
|
446
|
-
const scrollViewName = process.env.TARO_ENV === 'h5' ? 'taro-scroll-view' : 'scroll-view'
|
|
447
|
-
return h(
|
|
448
|
-
scrollViewName,
|
|
449
|
-
{
|
|
450
|
-
class: wclass,
|
|
451
|
-
ref: this._outerRefSetter,
|
|
452
|
-
style: {
|
|
453
|
-
position: 'relative',
|
|
454
|
-
height: this._getStyleValue(height),
|
|
455
|
-
width: this._getStyleValue(width),
|
|
456
|
-
overflow: 'auto',
|
|
457
|
-
WebkitOverflowScrolling: 'touch',
|
|
458
|
-
willChange: 'transform',
|
|
459
|
-
direction,
|
|
460
|
-
...wstyle
|
|
461
|
-
},
|
|
462
|
-
attrs: {
|
|
463
|
-
scrollY: layout === 'vertical',
|
|
464
|
-
scrollX: layout === 'horizontal'
|
|
465
|
-
},
|
|
466
|
-
on: {
|
|
467
|
-
scroll: onScroll
|
|
468
|
-
}
|
|
469
|
-
},
|
|
470
|
-
[
|
|
471
|
-
h(
|
|
472
|
-
innerElementType,
|
|
473
|
-
{
|
|
474
|
-
ref: innerRef,
|
|
475
|
-
style: {
|
|
476
|
-
height: this._getStyleValue(isHorizontal ? '100%' : estimatedTotalSize),
|
|
477
|
-
pointerEvents: isScrolling ? 'none' : undefined,
|
|
478
|
-
width: this._getStyleValue(isHorizontal ? estimatedTotalSize : '100%')
|
|
479
|
-
}
|
|
480
|
-
},
|
|
481
|
-
items
|
|
482
|
-
)
|
|
483
|
-
]
|
|
484
|
-
)
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
export default {
|
|
490
|
-
install: (Vue) => {
|
|
491
|
-
const VirtualList = createListComponent({
|
|
492
|
-
Vue,
|
|
493
|
-
getItemOffset: ({
|
|
494
|
-
itemSize
|
|
495
|
-
}, index) => index * itemSize,
|
|
496
|
-
getItemSize: ({
|
|
497
|
-
itemSize
|
|
498
|
-
}) => itemSize,
|
|
499
|
-
getEstimatedTotalSize: ({
|
|
500
|
-
itemCount,
|
|
501
|
-
itemSize
|
|
502
|
-
}) => itemSize * itemCount,
|
|
503
|
-
getOffsetForIndexAndAlignment: ({
|
|
504
|
-
direction,
|
|
505
|
-
height,
|
|
506
|
-
itemCount,
|
|
507
|
-
itemSize,
|
|
508
|
-
layout,
|
|
509
|
-
width
|
|
510
|
-
}, index, align, scrollOffset) => {
|
|
511
|
-
// TODO Deprecate direction "horizontal"
|
|
512
|
-
const isHorizontal = direction === 'horizontal' || layout === 'horizontal'
|
|
513
|
-
const size = isHorizontal ? width : height
|
|
514
|
-
const lastItemOffset = Math.max(0, itemCount * itemSize - size)
|
|
515
|
-
const maxOffset = Math.min(lastItemOffset, index * itemSize)
|
|
516
|
-
const minOffset = Math.max(0, index * itemSize - size + itemSize)
|
|
517
|
-
|
|
518
|
-
if (align === 'smart') {
|
|
519
|
-
if (scrollOffset >= minOffset - size && scrollOffset <= maxOffset + size) {
|
|
520
|
-
align = 'auto'
|
|
521
|
-
} else {
|
|
522
|
-
align = 'center'
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
switch (align) {
|
|
527
|
-
case 'start':
|
|
528
|
-
return maxOffset
|
|
529
|
-
|
|
530
|
-
case 'end':
|
|
531
|
-
return minOffset
|
|
532
|
-
|
|
533
|
-
case 'center':
|
|
534
|
-
{
|
|
535
|
-
// "Centered" offset is usually the average of the min and max.
|
|
536
|
-
// But near the edges of the list, this doesn't hold true.
|
|
537
|
-
const middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2)
|
|
538
|
-
|
|
539
|
-
if (middleOffset < Math.ceil(size / 2)) {
|
|
540
|
-
return 0 // near the beginning
|
|
541
|
-
} else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
|
|
542
|
-
return lastItemOffset // near the end
|
|
543
|
-
} else {
|
|
544
|
-
return middleOffset
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
case 'auto':
|
|
549
|
-
default:
|
|
550
|
-
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
|
|
551
|
-
return scrollOffset
|
|
552
|
-
} else if (scrollOffset < minOffset) {
|
|
553
|
-
return minOffset
|
|
554
|
-
} else {
|
|
555
|
-
return maxOffset
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
},
|
|
559
|
-
getStartIndexForOffset: ({
|
|
560
|
-
itemCount,
|
|
561
|
-
itemSize
|
|
562
|
-
}, offset) => {
|
|
563
|
-
return Math.max(0, Math.min(itemCount - 1, Math.floor(offset / itemSize)))
|
|
564
|
-
},
|
|
565
|
-
getStopIndexForStartIndex: ({
|
|
566
|
-
direction,
|
|
567
|
-
height,
|
|
568
|
-
itemCount,
|
|
569
|
-
itemSize,
|
|
570
|
-
layout,
|
|
571
|
-
width
|
|
572
|
-
}, startIndex, scrollOffset) => {
|
|
573
|
-
// TODO Deprecate direction "horizontal"
|
|
574
|
-
const isHorizontal = direction === 'horizontal' || layout === 'horizontal'
|
|
575
|
-
const offset = startIndex * itemSize
|
|
576
|
-
const size = isHorizontal ? width : height
|
|
577
|
-
const numVisibleItems = Math.ceil((size + scrollOffset - offset) / itemSize)
|
|
578
|
-
return Math.max(0, Math.min(itemCount - 1, startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
|
|
579
|
-
))
|
|
580
|
-
},
|
|
581
|
-
|
|
582
|
-
initInstanceProps () { // Noop
|
|
583
|
-
},
|
|
584
|
-
|
|
585
|
-
shouldResetStyleCacheOnItemSizeChange: true
|
|
586
|
-
})
|
|
587
|
-
Vue.component('virtual-list', VirtualList)
|
|
588
|
-
}
|
|
589
|
-
}
|