@v-c/virtual-list 0.0.1 → 1.0.0
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/bump.config.ts +6 -0
- package/dist/Filler.cjs +51 -1
- package/dist/Filler.js +47 -56
- package/dist/Item.cjs +26 -1
- package/dist/Item.js +23 -26
- package/dist/List.cjs +408 -1
- package/dist/List.d.ts +45 -9
- package/dist/List.js +403 -274
- package/dist/ScrollBar.cjs +259 -1
- package/dist/ScrollBar.d.ts +3 -97
- package/dist/ScrollBar.js +254 -191
- package/dist/_virtual/rolldown_runtime.cjs +21 -0
- package/dist/hooks/useDiffItem.cjs +19 -1
- package/dist/hooks/useDiffItem.js +16 -20
- package/dist/hooks/useFrameWheel.cjs +63 -1
- package/dist/hooks/useFrameWheel.js +60 -51
- package/dist/hooks/useGetSize.cjs +29 -1
- package/dist/hooks/useGetSize.d.ts +2 -2
- package/dist/hooks/useGetSize.js +27 -23
- package/dist/hooks/useHeights.cjs +66 -1
- package/dist/hooks/useHeights.d.ts +1 -1
- package/dist/hooks/useHeights.js +62 -41
- package/dist/hooks/useMobileTouchMove.cjs +82 -1
- package/dist/hooks/useMobileTouchMove.js +79 -43
- package/dist/hooks/useOriginScroll.cjs +23 -1
- package/dist/hooks/useOriginScroll.js +20 -16
- package/dist/hooks/useScrollDrag.cjs +83 -1
- package/dist/hooks/useScrollDrag.js +77 -48
- package/dist/hooks/useScrollTo.cjs +97 -0
- package/dist/hooks/useScrollTo.d.ts +19 -0
- package/dist/hooks/useScrollTo.js +94 -0
- package/dist/index.cjs +4 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -4
- package/dist/interface.cjs +0 -1
- package/dist/interface.d.ts +1 -1
- package/dist/interface.js +0 -1
- package/dist/utils/CacheMap.cjs +25 -1
- package/dist/utils/CacheMap.d.ts +1 -1
- package/dist/utils/CacheMap.js +23 -28
- package/dist/utils/isFirefox.cjs +4 -1
- package/dist/utils/isFirefox.js +2 -4
- package/dist/utils/scrollbarUtil.cjs +8 -1
- package/dist/utils/scrollbarUtil.js +7 -6
- package/docs/animate.less +31 -0
- package/docs/animate.vue +159 -0
- package/docs/basic.vue +2 -1
- package/docs/nest.vue +1 -1
- package/docs/switch.vue +2 -1
- package/docs/virtual-list.stories.vue +4 -0
- package/package.json +16 -14
- package/src/Filler.tsx +2 -1
- package/src/Item.tsx +2 -1
- package/src/List.tsx +189 -124
- package/src/ScrollBar.tsx +33 -44
- package/src/hooks/useDiffItem.ts +3 -2
- package/src/hooks/useFrameWheel.ts +2 -1
- package/src/hooks/useGetSize.ts +5 -4
- package/src/hooks/useHeights.ts +7 -6
- package/src/hooks/useMobileTouchMove.ts +2 -1
- package/src/hooks/useOriginScroll.ts +2 -1
- package/src/hooks/useScrollDrag.ts +2 -1
- package/src/hooks/useScrollTo.tsx +184 -0
- package/src/index.ts +1 -1
- package/tsconfig.json +7 -0
- package/vitest.config.ts +1 -1
package/src/List.tsx
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import type { Key } from '@v-c/util/dist/type'
|
|
2
2
|
|
|
3
|
+
import type { CSSProperties, PropType, VNode } from 'vue'
|
|
4
|
+
import type { InnerProps } from './Filler'
|
|
3
5
|
import type { ExtraRenderInfo } from './interface'
|
|
6
|
+
import type { ScrollBarDirectionType, ScrollBarRef } from './ScrollBar'
|
|
4
7
|
import ResizeObserver from '@v-c/resize-observer'
|
|
8
|
+
import { pureAttrs } from '@v-c/util/dist/props-util'
|
|
5
9
|
import {
|
|
6
10
|
computed,
|
|
7
|
-
type CSSProperties,
|
|
8
11
|
defineComponent,
|
|
9
|
-
type PropType,
|
|
10
12
|
ref,
|
|
11
13
|
shallowRef,
|
|
12
|
-
type VNode,
|
|
13
14
|
watch,
|
|
14
15
|
} from 'vue'
|
|
15
|
-
import Filler
|
|
16
|
+
import Filler from './Filler'
|
|
16
17
|
import useDiffItem from './hooks/useDiffItem'
|
|
17
18
|
import useFrameWheel from './hooks/useFrameWheel'
|
|
18
19
|
import { useGetSize } from './hooks/useGetSize'
|
|
19
20
|
import useHeights from './hooks/useHeights'
|
|
20
21
|
import useMobileTouchMove from './hooks/useMobileTouchMove'
|
|
21
22
|
import useScrollDrag from './hooks/useScrollDrag'
|
|
23
|
+
import useScrollTo from './hooks/useScrollTo'
|
|
22
24
|
import Item from './Item'
|
|
23
|
-
import ScrollBar
|
|
25
|
+
import ScrollBar from './ScrollBar'
|
|
24
26
|
import { getSpinSize } from './utils/scrollbarUtil'
|
|
25
27
|
|
|
26
28
|
const EMPTY_DATA: any[] = []
|
|
@@ -35,9 +37,11 @@ export interface ScrollInfo {
|
|
|
35
37
|
y: number
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
export type ScrollTo = (arg?: number | ScrollConfig | null) => void
|
|
41
|
+
|
|
38
42
|
export interface ListRef {
|
|
39
43
|
nativeElement?: HTMLDivElement
|
|
40
|
-
scrollTo:
|
|
44
|
+
scrollTo: ScrollTo
|
|
41
45
|
getScrollInfo: () => ScrollInfo
|
|
42
46
|
}
|
|
43
47
|
|
|
@@ -55,18 +59,33 @@ export interface ScrollTarget {
|
|
|
55
59
|
|
|
56
60
|
export type ScrollConfig = ScrollTarget | ScrollPos
|
|
57
61
|
|
|
58
|
-
export interface ListProps
|
|
62
|
+
export interface ListProps {
|
|
59
63
|
prefixCls?: string
|
|
60
|
-
data?:
|
|
64
|
+
data?: any[]
|
|
61
65
|
height?: number
|
|
62
66
|
itemHeight?: number
|
|
63
67
|
fullHeight?: boolean
|
|
64
|
-
itemKey: Key | ((item:
|
|
68
|
+
itemKey: Key | ((item: any) => Key)
|
|
65
69
|
component?: string
|
|
66
70
|
virtual?: boolean
|
|
71
|
+
direction?: ScrollBarDirectionType
|
|
72
|
+
/**
|
|
73
|
+
* By default `scrollWidth` is same as container.
|
|
74
|
+
* When set this, it will show the horizontal scrollbar and
|
|
75
|
+
* `scrollWidth` will be used as the real width instead of container width.
|
|
76
|
+
* When set, `virtual` will always be enabled.
|
|
77
|
+
*/
|
|
78
|
+
scrollWidth?: number
|
|
79
|
+
styles?: {
|
|
80
|
+
horizontalScrollBar?: CSSProperties
|
|
81
|
+
horizontalScrollBarThumb?: CSSProperties
|
|
82
|
+
verticalScrollBar?: CSSProperties
|
|
83
|
+
verticalScrollBarThumb?: CSSProperties
|
|
84
|
+
}
|
|
85
|
+
showScrollBar?: boolean | 'optional'
|
|
67
86
|
onScroll?: (e: Event) => void
|
|
68
87
|
onVirtualScroll?: (info: ScrollInfo) => void
|
|
69
|
-
onVisibleChange?: (visibleList:
|
|
88
|
+
onVisibleChange?: (visibleList: any[], fullList: any[]) => void
|
|
70
89
|
innerProps?: InnerProps
|
|
71
90
|
extraRender?: (info: ExtraRenderInfo) => VNode
|
|
72
91
|
}
|
|
@@ -81,6 +100,10 @@ export default defineComponent({
|
|
|
81
100
|
fullHeight: { type: Boolean, default: true },
|
|
82
101
|
itemKey: { type: [String, Number, Function] as PropType<Key | ((item: any) => Key)>, required: true },
|
|
83
102
|
component: { type: String, default: 'div' },
|
|
103
|
+
direction: { type: String as PropType<ScrollBarDirectionType> },
|
|
104
|
+
scrollWidth: Number,
|
|
105
|
+
styles: Object,
|
|
106
|
+
showScrollBar: { type: [Boolean, String] as PropType<boolean | 'optional'>, default: 'optional' },
|
|
84
107
|
virtual: { type: Boolean, default: true },
|
|
85
108
|
onScroll: Function as PropType<(e: Event) => void>,
|
|
86
109
|
onVirtualScroll: Function as PropType<(info: ScrollInfo) => void>,
|
|
@@ -88,7 +111,9 @@ export default defineComponent({
|
|
|
88
111
|
innerProps: Object as PropType<InnerProps>,
|
|
89
112
|
extraRender: Function as PropType<(info: ExtraRenderInfo) => VNode>,
|
|
90
113
|
},
|
|
114
|
+
inheritAttrs: false,
|
|
91
115
|
setup(props, { expose, attrs, slots }) {
|
|
116
|
+
const itemHeight = computed(() => props.itemHeight)
|
|
92
117
|
// =============================== Item Key ===============================
|
|
93
118
|
const getKey = (item: any): Key => {
|
|
94
119
|
if (typeof props.itemKey === 'function') {
|
|
@@ -120,7 +145,8 @@ export default defineComponent({
|
|
|
120
145
|
return (
|
|
121
146
|
useVirtual.value
|
|
122
147
|
&& data
|
|
123
|
-
&& Math.max(props.itemHeight! * data.length, containerHeight.value) > props.height!
|
|
148
|
+
&& (Math.max(props.itemHeight! * data.length, containerHeight.value) > props.height!
|
|
149
|
+
|| !!props.scrollWidth)
|
|
124
150
|
)
|
|
125
151
|
})
|
|
126
152
|
|
|
@@ -128,6 +154,7 @@ export default defineComponent({
|
|
|
128
154
|
const fillerInnerRef = ref<HTMLDivElement>()
|
|
129
155
|
const containerRef = ref<HTMLDivElement>()
|
|
130
156
|
const verticalScrollBarRef = shallowRef<ScrollBarRef>()
|
|
157
|
+
const horizontalScrollBarRef = shallowRef<ScrollBarRef>()
|
|
131
158
|
|
|
132
159
|
const offsetTop = ref(0)
|
|
133
160
|
const offsetLeft = ref(0)
|
|
@@ -135,7 +162,14 @@ export default defineComponent({
|
|
|
135
162
|
|
|
136
163
|
// ScrollBar related
|
|
137
164
|
const verticalScrollBarSpinSize = ref(0)
|
|
138
|
-
const
|
|
165
|
+
const horizontalScrollBarSpinSize = ref(0)
|
|
166
|
+
const contentScrollWidth = ref<number>(props.scrollWidth || 0)
|
|
167
|
+
|
|
168
|
+
// ========================== Visible Calculation =========================
|
|
169
|
+
const scrollHeight = ref(0)
|
|
170
|
+
const start = ref(0)
|
|
171
|
+
const end = ref(0)
|
|
172
|
+
const fillerOffset = ref<number | undefined>(undefined)
|
|
139
173
|
|
|
140
174
|
// ================================ Scroll ================================
|
|
141
175
|
function syncScrollTop(newTop: number | ((prev: number) => number)) {
|
|
@@ -159,19 +193,13 @@ export default defineComponent({
|
|
|
159
193
|
// ================================ Range ================================
|
|
160
194
|
useDiffItem(mergedData, getKey)
|
|
161
195
|
|
|
162
|
-
// ========================== Visible Calculation =========================
|
|
163
|
-
const scrollHeight = ref(0)
|
|
164
|
-
const start = ref(0)
|
|
165
|
-
const end = ref(0)
|
|
166
|
-
const fillerOffset = ref<number | undefined>(undefined)
|
|
167
|
-
|
|
168
196
|
watch(
|
|
169
197
|
[
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
198
|
+
inVirtual,
|
|
199
|
+
useVirtual,
|
|
200
|
+
offsetTop,
|
|
201
|
+
mergedData,
|
|
202
|
+
heightUpdatedMark,
|
|
175
203
|
() => props.height,
|
|
176
204
|
],
|
|
177
205
|
() => {
|
|
@@ -239,7 +267,7 @@ export default defineComponent({
|
|
|
239
267
|
|
|
240
268
|
// Sync scroll top when height changes
|
|
241
269
|
watch(
|
|
242
|
-
|
|
270
|
+
scrollHeight,
|
|
243
271
|
() => {
|
|
244
272
|
const changedRecord = heights.getRecord()
|
|
245
273
|
if (changedRecord.size === 1) {
|
|
@@ -269,11 +297,14 @@ export default defineComponent({
|
|
|
269
297
|
width: sizeInfo.offsetWidth,
|
|
270
298
|
height: sizeInfo.offsetHeight,
|
|
271
299
|
}
|
|
300
|
+
contentScrollWidth.value = props.scrollWidth ?? sizeInfo.offsetWidth
|
|
272
301
|
}
|
|
273
302
|
|
|
274
303
|
// =============================== Scroll ===============================
|
|
304
|
+
const isRTL = computed(() => props.direction === 'rtl')
|
|
305
|
+
|
|
275
306
|
const getVirtualScrollInfo = () => ({
|
|
276
|
-
x: offsetLeft.value,
|
|
307
|
+
x: isRTL.value ? -offsetLeft.value : offsetLeft.value,
|
|
277
308
|
y: offsetTop.value,
|
|
278
309
|
})
|
|
279
310
|
|
|
@@ -294,14 +325,24 @@ export default defineComponent({
|
|
|
294
325
|
}
|
|
295
326
|
|
|
296
327
|
// ========================== Scroll Position ===========================
|
|
328
|
+
const horizontalRange = computed(() =>
|
|
329
|
+
Math.max(0, (contentScrollWidth.value || 0) - size.value.width),
|
|
330
|
+
)
|
|
331
|
+
|
|
297
332
|
const isScrollAtTop = computed(() => offsetTop.value === 0)
|
|
298
333
|
const isScrollAtBottom = computed(() => offsetTop.value + props.height! >= scrollHeight.value)
|
|
299
334
|
const isScrollAtLeft = computed(() => offsetLeft.value === 0)
|
|
300
|
-
const isScrollAtRight = computed(() => offsetLeft.value
|
|
335
|
+
const isScrollAtRight = computed(() => offsetLeft.value >= horizontalRange.value)
|
|
336
|
+
|
|
337
|
+
const keepInHorizontalRange = (nextOffsetLeft: number) => {
|
|
338
|
+
const max = horizontalRange.value
|
|
339
|
+
return Math.max(0, Math.min(nextOffsetLeft, max))
|
|
340
|
+
}
|
|
301
341
|
|
|
302
342
|
// ========================== Wheel & Touch =========================
|
|
303
343
|
const delayHideScrollBar = () => {
|
|
304
344
|
verticalScrollBarRef.value?.delayHidden()
|
|
345
|
+
horizontalScrollBarRef.value?.delayHidden()
|
|
305
346
|
}
|
|
306
347
|
|
|
307
348
|
const [onWheel] = useFrameWheel(
|
|
@@ -310,10 +351,13 @@ export default defineComponent({
|
|
|
310
351
|
isScrollAtBottom,
|
|
311
352
|
isScrollAtLeft,
|
|
312
353
|
isScrollAtRight,
|
|
313
|
-
|
|
354
|
+
horizontalRange.value > 0,
|
|
314
355
|
(offsetY, isHorizontal) => {
|
|
315
356
|
if (isHorizontal) {
|
|
316
|
-
|
|
357
|
+
const next = isRTL.value ? offsetLeft.value - offsetY : offsetLeft.value + offsetY
|
|
358
|
+
const aligned = keepInHorizontalRange(next)
|
|
359
|
+
offsetLeft.value = aligned
|
|
360
|
+
triggerScroll({ x: isRTL.value ? -aligned : aligned })
|
|
317
361
|
}
|
|
318
362
|
else {
|
|
319
363
|
syncScrollTop(top => top + offsetY)
|
|
@@ -326,8 +370,11 @@ export default defineComponent({
|
|
|
326
370
|
componentRef,
|
|
327
371
|
(isHorizontal, offset, _smoothOffset, _e) => {
|
|
328
372
|
if (isHorizontal) {
|
|
329
|
-
|
|
330
|
-
|
|
373
|
+
const next = isRTL.value ? offsetLeft.value - offset : offsetLeft.value + offset
|
|
374
|
+
const aligned = keepInHorizontalRange(next)
|
|
375
|
+
offsetLeft.value = aligned
|
|
376
|
+
triggerScroll({ x: isRTL.value ? -aligned : aligned })
|
|
377
|
+
return true
|
|
331
378
|
}
|
|
332
379
|
else {
|
|
333
380
|
syncScrollTop(top => top + offset)
|
|
@@ -348,7 +395,8 @@ export default defineComponent({
|
|
|
348
395
|
const onScrollBar = (newScrollOffset: number, horizontal?: boolean) => {
|
|
349
396
|
const newOffset = newScrollOffset
|
|
350
397
|
if (horizontal) {
|
|
351
|
-
|
|
398
|
+
offsetLeft.value = newOffset
|
|
399
|
+
triggerScroll({ x: isRTL.value ? -newOffset : newOffset })
|
|
352
400
|
}
|
|
353
401
|
else {
|
|
354
402
|
syncScrollTop(newOffset)
|
|
@@ -365,16 +413,34 @@ export default defineComponent({
|
|
|
365
413
|
|
|
366
414
|
// Calculate ScrollBar spin size
|
|
367
415
|
watch(
|
|
368
|
-
[() => props.height,
|
|
416
|
+
[() => props.height, scrollHeight, inVirtual, () => size.value.height],
|
|
369
417
|
() => {
|
|
370
418
|
if (inVirtual.value && props.height && scrollHeight.value) {
|
|
371
|
-
// First parameter is container size, second is scroll range
|
|
372
419
|
verticalScrollBarSpinSize.value = getSpinSize(size.value.height, scrollHeight.value)
|
|
373
420
|
}
|
|
374
421
|
},
|
|
375
422
|
{ immediate: true },
|
|
376
423
|
)
|
|
377
424
|
|
|
425
|
+
watch(
|
|
426
|
+
[() => size.value.width, () => contentScrollWidth.value],
|
|
427
|
+
() => {
|
|
428
|
+
if (inVirtual.value && contentScrollWidth.value) {
|
|
429
|
+
horizontalScrollBarSpinSize.value = getSpinSize(size.value.width, contentScrollWidth.value)
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
{ immediate: true },
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
watch(
|
|
436
|
+
() => props.scrollWidth,
|
|
437
|
+
(val) => {
|
|
438
|
+
contentScrollWidth.value = val ?? size.value.width
|
|
439
|
+
offsetLeft.value = keepInHorizontalRange(offsetLeft.value)
|
|
440
|
+
},
|
|
441
|
+
{ immediate: true },
|
|
442
|
+
)
|
|
443
|
+
|
|
378
444
|
function onFallbackScroll(e: Event) {
|
|
379
445
|
const target = e.currentTarget as HTMLDivElement
|
|
380
446
|
const newScrollTop = target.scrollTop
|
|
@@ -387,65 +453,39 @@ export default defineComponent({
|
|
|
387
453
|
}
|
|
388
454
|
|
|
389
455
|
// ================================= Ref ==================================
|
|
390
|
-
const scrollTo = (
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if ('left' in config) {
|
|
402
|
-
offsetLeft.value = config.left || 0
|
|
403
|
-
}
|
|
456
|
+
const scrollTo = useScrollTo(
|
|
457
|
+
componentRef as any,
|
|
458
|
+
mergedData,
|
|
459
|
+
heights,
|
|
460
|
+
itemHeight as any,
|
|
461
|
+
getKey,
|
|
462
|
+
() => collectHeight(true),
|
|
463
|
+
syncScrollTop,
|
|
464
|
+
delayHideScrollBar,
|
|
465
|
+
)
|
|
404
466
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
if (item) {
|
|
412
|
-
let itemTop = 0
|
|
413
|
-
for (let i = 0; i < index; i += 1) {
|
|
414
|
-
const key = getKey(mergedData.value[i])
|
|
415
|
-
const cacheHeight = heights.get(key)
|
|
416
|
-
itemTop += cacheHeight === undefined ? props.itemHeight! : cacheHeight
|
|
417
|
-
}
|
|
418
|
-
scrollTop = itemTop
|
|
419
|
-
}
|
|
467
|
+
expose({
|
|
468
|
+
nativeElement: containerRef,
|
|
469
|
+
getScrollInfo: getVirtualScrollInfo,
|
|
470
|
+
scrollTo: (config: any) => {
|
|
471
|
+
function isPosScroll(arg: any): arg is ScrollPos {
|
|
472
|
+
return arg && typeof arg === 'object' && ('left' in arg || 'top' in arg)
|
|
420
473
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
let itemTop = 0
|
|
425
|
-
for (let i = 0; i < index; i += 1) {
|
|
426
|
-
const key = getKey(mergedData.value[i])
|
|
427
|
-
const cacheHeight = heights.get(key)
|
|
428
|
-
itemTop += cacheHeight === undefined ? props.itemHeight! : cacheHeight
|
|
429
|
-
}
|
|
430
|
-
scrollTop = itemTop
|
|
474
|
+
if (isPosScroll(config)) {
|
|
475
|
+
if (config.left !== undefined) {
|
|
476
|
+
offsetLeft.value = keepInHorizontalRange(config.left)
|
|
431
477
|
}
|
|
478
|
+
scrollTo(config.top as any)
|
|
432
479
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
syncScrollTop(scrollTop)
|
|
480
|
+
else {
|
|
481
|
+
scrollTo(config)
|
|
436
482
|
}
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
expose({
|
|
441
|
-
nativeElement: containerRef,
|
|
442
|
-
getScrollInfo: getVirtualScrollInfo,
|
|
443
|
-
scrollTo,
|
|
483
|
+
},
|
|
444
484
|
})
|
|
445
485
|
|
|
446
486
|
// ================================ Effect ================================
|
|
447
487
|
watch(
|
|
448
|
-
[
|
|
488
|
+
[start, end, mergedData],
|
|
449
489
|
() => {
|
|
450
490
|
if (props.onVisibleChange) {
|
|
451
491
|
const renderList = mergedData.value.slice(start.value, end.value + 1)
|
|
@@ -454,54 +494,52 @@ export default defineComponent({
|
|
|
454
494
|
},
|
|
455
495
|
)
|
|
456
496
|
|
|
457
|
-
|
|
458
|
-
const renderChildren = () => {
|
|
459
|
-
const children: VNode[] = []
|
|
460
|
-
const data = mergedData.value
|
|
461
|
-
const defaultSlot = slots.default
|
|
497
|
+
const getSize = useGetSize(mergedData, getKey, heights, itemHeight as any)
|
|
462
498
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
499
|
+
return () => {
|
|
500
|
+
// ================================ Render ================================
|
|
501
|
+
const renderChildren = () => {
|
|
502
|
+
const children: VNode[] = []
|
|
503
|
+
const data = mergedData.value
|
|
504
|
+
const defaultSlot = slots.default
|
|
466
505
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
const key = getKey(item)
|
|
470
|
-
// Call the slot function with item, index, and props
|
|
471
|
-
const nodes = defaultSlot({
|
|
472
|
-
item,
|
|
473
|
-
index: i,
|
|
474
|
-
style: {},
|
|
475
|
-
offsetX: offsetLeft.value,
|
|
476
|
-
})
|
|
477
|
-
|
|
478
|
-
// Wrap each node in Item component
|
|
479
|
-
const node = Array.isArray(nodes) ? nodes[0] : nodes
|
|
480
|
-
if (node) {
|
|
481
|
-
children.push(
|
|
482
|
-
<Item key={key} setRef={ele => setInstanceRef(item, ele)}>
|
|
483
|
-
{node}
|
|
484
|
-
</Item>,
|
|
485
|
-
)
|
|
506
|
+
if (!defaultSlot) {
|
|
507
|
+
return children
|
|
486
508
|
}
|
|
487
|
-
}
|
|
488
509
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
510
|
+
for (let i = start.value; i <= end.value; i += 1) {
|
|
511
|
+
const item = data[i]
|
|
512
|
+
const key = getKey(item)
|
|
513
|
+
// Call the slot function with item, index, and props
|
|
514
|
+
const nodes = defaultSlot({
|
|
515
|
+
item,
|
|
516
|
+
index: i,
|
|
517
|
+
style: {},
|
|
518
|
+
offsetX: offsetLeft.value,
|
|
519
|
+
})
|
|
520
|
+
|
|
521
|
+
// Wrap each node in Item component
|
|
522
|
+
const node = Array.isArray(nodes) ? nodes[0] : nodes
|
|
523
|
+
if (node) {
|
|
524
|
+
children.push(
|
|
525
|
+
<Item key={key} setRef={ele => setInstanceRef(item, ele)}>
|
|
526
|
+
{node}
|
|
527
|
+
</Item>,
|
|
528
|
+
)
|
|
529
|
+
}
|
|
530
|
+
}
|
|
493
531
|
|
|
494
|
-
|
|
532
|
+
return children
|
|
533
|
+
}
|
|
495
534
|
const componentStyle: CSSProperties = {}
|
|
496
535
|
if (props.height) {
|
|
497
536
|
componentStyle[props.fullHeight ? 'height' : 'maxHeight'] = `${props.height}px`
|
|
498
537
|
Object.assign(componentStyle, ScrollStyle)
|
|
499
538
|
|
|
500
|
-
// Use custom ScrollBar when virtual scrolling is enabled
|
|
501
539
|
if (useVirtual.value) {
|
|
502
540
|
componentStyle.overflowY = 'hidden'
|
|
503
541
|
|
|
504
|
-
if (
|
|
542
|
+
if (horizontalRange.value > 0) {
|
|
505
543
|
componentStyle.overflowX = 'hidden'
|
|
506
544
|
}
|
|
507
545
|
|
|
@@ -517,7 +555,7 @@ export default defineComponent({
|
|
|
517
555
|
virtual: inVirtual.value,
|
|
518
556
|
offsetX: offsetLeft.value,
|
|
519
557
|
offsetY: fillerOffset.value || 0,
|
|
520
|
-
rtl:
|
|
558
|
+
rtl: isRTL.value,
|
|
521
559
|
getSize: getSize.value,
|
|
522
560
|
})
|
|
523
561
|
|
|
@@ -526,8 +564,14 @@ export default defineComponent({
|
|
|
526
564
|
return (
|
|
527
565
|
<div
|
|
528
566
|
ref={containerRef}
|
|
567
|
+
{...pureAttrs(attrs)}
|
|
529
568
|
style={{ position: 'relative', ...(attrs.style as CSSProperties) }}
|
|
530
|
-
|
|
569
|
+
dir={isRTL.value ? 'rtl' : undefined}
|
|
570
|
+
class={[
|
|
571
|
+
props.prefixCls,
|
|
572
|
+
{ [`${props.prefixCls}-rtl`]: isRTL.value },
|
|
573
|
+
attrs.class,
|
|
574
|
+
]}
|
|
531
575
|
>
|
|
532
576
|
<ResizeObserver onResize={onHolderResize}>
|
|
533
577
|
<Component
|
|
@@ -543,10 +587,11 @@ export default defineComponent({
|
|
|
543
587
|
height={scrollHeight.value}
|
|
544
588
|
offsetX={offsetLeft.value}
|
|
545
589
|
offsetY={fillerOffset.value}
|
|
590
|
+
scrollWidth={contentScrollWidth.value}
|
|
546
591
|
onInnerResize={collectHeight}
|
|
547
592
|
ref={fillerInnerRef}
|
|
548
593
|
innerProps={props.innerProps}
|
|
549
|
-
rtl={
|
|
594
|
+
rtl={isRTL.value}
|
|
550
595
|
extra={extraContent}
|
|
551
596
|
>
|
|
552
597
|
{renderChildren()}
|
|
@@ -554,20 +599,40 @@ export default defineComponent({
|
|
|
554
599
|
</Component>
|
|
555
600
|
</ResizeObserver>
|
|
556
601
|
|
|
557
|
-
{/* ScrollBar */}
|
|
558
602
|
{inVirtual.value && scrollHeight.value > (props.height || 0) && (
|
|
559
603
|
<ScrollBar
|
|
560
604
|
ref={verticalScrollBarRef}
|
|
561
605
|
prefixCls={props.prefixCls}
|
|
562
606
|
scrollOffset={offsetTop.value}
|
|
563
607
|
scrollRange={scrollHeight.value}
|
|
564
|
-
rtl={
|
|
608
|
+
rtl={isRTL.value}
|
|
565
609
|
onScroll={onScrollBar}
|
|
566
610
|
onStartMove={onScrollbarStartMove}
|
|
567
611
|
onStopMove={onScrollbarStopMove}
|
|
568
612
|
spinSize={verticalScrollBarSpinSize.value}
|
|
569
613
|
containerSize={size.value.height}
|
|
570
|
-
showScrollBar=
|
|
614
|
+
showScrollBar={props.showScrollBar}
|
|
615
|
+
style={(props.styles as any)?.verticalScrollBar}
|
|
616
|
+
thumbStyle={(props.styles as any)?.verticalScrollBarThumb}
|
|
617
|
+
/>
|
|
618
|
+
)}
|
|
619
|
+
|
|
620
|
+
{inVirtual.value && contentScrollWidth.value > size.value.width && (
|
|
621
|
+
<ScrollBar
|
|
622
|
+
ref={horizontalScrollBarRef}
|
|
623
|
+
prefixCls={props.prefixCls}
|
|
624
|
+
scrollOffset={offsetLeft.value}
|
|
625
|
+
scrollRange={contentScrollWidth.value}
|
|
626
|
+
rtl={isRTL.value}
|
|
627
|
+
onScroll={onScrollBar}
|
|
628
|
+
onStartMove={onScrollbarStartMove}
|
|
629
|
+
onStopMove={onScrollbarStopMove}
|
|
630
|
+
spinSize={horizontalScrollBarSpinSize.value}
|
|
631
|
+
containerSize={size.value.width}
|
|
632
|
+
horizontal
|
|
633
|
+
showScrollBar={props.showScrollBar}
|
|
634
|
+
style={(props.styles as any)?.horizontalScrollBar}
|
|
635
|
+
thumbStyle={(props.styles as any)?.horizontalScrollBarThumb}
|
|
571
636
|
/>
|
|
572
637
|
)}
|
|
573
638
|
</div>
|