virtua 0.51.0 → 0.51.2

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.
@@ -1,5 +1,5 @@
1
1
  import { For, createComputed, createEffect, createMemo, createSignal, mergeProps, on, onCleanup, onMount, splitProps, untrack } from "solid-js";
2
- import { Dynamic } from "solid-js/web";
2
+ import { Dynamic, isServer } from "solid-js/web";
3
3
 
4
4
  //#region src/core/utils.ts
5
5
  var NULL = null;
@@ -20,28 +20,19 @@ var createPromise = () => {
20
20
  });
21
21
  return [promise, resolve];
22
22
  };
23
- var once = (fn) => {
24
- let cache;
25
- return () => {
26
- if (fn) {
27
- cache = fn();
28
- fn = undefined;
29
- }
30
- return cache;
31
- };
32
- };
33
23
 
34
24
  //#endregion
35
25
  //#region src/core/environment.ts
36
26
  var isBrowser = typeof window !== "undefined";
37
27
  var getCurrentDocument = (node) => node.ownerDocument;
38
28
  var getCurrentWindow = (doc) => doc.defaultView;
39
- var isIOSWebKit = /*#__PURE__*/ once(() => {
40
- if (/iP(hone|od|ad)/.test(navigator.userAgent)) {
41
- return true;
29
+ var isIOS;
30
+ var isIOSWebKit = () => {
31
+ if (isIOS == null) {
32
+ isIOS = /iP(hone|od|ad)/.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 0;
42
33
  }
43
- return navigator.platform === "MacIntel" && navigator.maxTouchPoints > 0;
44
- });
34
+ return isIOS;
35
+ };
45
36
 
46
37
  //#endregion
47
38
  //#region src/core/store.ts
@@ -418,17 +409,27 @@ var createResizeObserver = (cb) => {
418
409
  }
419
410
  };
420
411
  };
421
- var normalizeScrollOffset = (offset, isNegative) => {
422
- return isNegative ? -offset : offset;
423
- };
424
- var createScrollObserver = (store, viewport, isHorizontal, getScrollOffset, updateScrollOffset, getStartOffset) => {
412
+ var createScrollObserver = (store, viewport, scroller, isHorizontal, isRtl, onMomentumJump, getStartOffset) => {
425
413
  let lastScrollTime = 0;
426
414
  let wheeling = false;
427
415
  let touching = false;
428
416
  let justTouchEnded = false;
429
417
  let stillMomentumScrolling = false;
418
+ let cancelScroll;
430
419
  let scrollEndTimer;
431
420
  const now = Date.now;
421
+ const scrollOffsetKey = isHorizontal ? "scrollLeft" : "scrollTop";
422
+ const scrollToKey = isHorizontal ? "left" : "top";
423
+ const normalizeScrollOffset = (offset) => {
424
+ return isRtl ? -offset : offset;
425
+ };
426
+ const getScrollOffset = () => normalizeScrollOffset(scroller[scrollOffsetKey]);
427
+ const scrollTo = (offset, smooth) => {
428
+ scroller.scrollTo({
429
+ [scrollToKey]: normalizeScrollOffset(offset),
430
+ behavior: smooth ? "smooth" : "instant"
431
+ });
432
+ };
432
433
  const onScrollEnd = () => {
433
434
  if (wheeling || touching) {
434
435
  wheeling = false;
@@ -487,94 +488,90 @@ var createScrollObserver = (store, viewport, isHorizontal, getScrollOffset, upda
487
488
  _fixScrollJump: () => {
488
489
  const [jump, shift] = store._flushJump();
489
490
  if (!jump) return;
490
- updateScrollOffset(jump, shift, stillMomentumScrolling);
491
+ if (stillMomentumScrolling && onMomentumJump) {
492
+ onMomentumJump();
493
+ }
491
494
  stillMomentumScrolling = false;
492
- if (shift && store.$getViewportSize() > store.$getTotalSize()) {
493
- store.$update(1, getScrollOffset());
495
+ const target = store.$getScrollOffset() + jump;
496
+ if (target <= 0 || target >= store.$getStartSpacerSize() + store.$getTotalSize() - store.$getViewportSize()) {
497
+ scrollTo(target);
498
+ } else {
499
+ scroller.scrollBy({
500
+ [scrollToKey]: normalizeScrollOffset(jump),
501
+ behavior: "instant"
502
+ });
494
503
  }
495
- }
496
- };
497
- };
498
-
499
- //#endregion
500
- //#region src/core/driver.ts
501
- var createScrollScheduler = (store, initialized, scroll) => {
502
- let cancelScroll;
503
- return [async (getTargetOffset, smooth) => {
504
- if (!await initialized()) {
505
- return;
506
- }
507
- if (cancelScroll) {
508
- cancelScroll();
509
- }
510
- let stopped;
511
- let timerId;
512
- let unsubscribe;
513
- const stop = cancelScroll = () => {
514
- stopped = true;
515
- cancelTimeout(timerId);
516
- unsubscribe && unsubscribe();
517
- };
518
- const onMeasured = () => {
519
- if (stopped) {
520
- return;
504
+ if (shift) {
505
+ cancelScroll && cancelScroll();
506
+ if (store.$getViewportSize() > store.$getTotalSize()) {
507
+ store.$update(1, getScrollOffset());
508
+ }
521
509
  }
522
- if (store.$getViewportSize()) {
523
- cancelTimeout(timerId);
524
- timerId = timeout(stop, 150);
510
+ },
511
+ _scroll: (getTargetOffset, smooth) => {
512
+ if (cancelScroll) {
513
+ cancelScroll();
525
514
  }
526
- if (smooth) {
527
- for (let [i, end] = store.$getRange(0); i <= end; i++) {
528
- if (store.$isUnmeasuredItem(i)) {
529
- return;
515
+ let stopped;
516
+ let timerId;
517
+ let unsubscribe;
518
+ const stop = cancelScroll = () => {
519
+ stopped = true;
520
+ cancelTimeout(timerId);
521
+ unsubscribe && unsubscribe();
522
+ };
523
+ const onMeasured = () => {
524
+ if (stopped) {
525
+ return;
526
+ }
527
+ if (store.$getViewportSize()) {
528
+ cancelTimeout(timerId);
529
+ timerId = timeout(stop, 150);
530
+ }
531
+ if (smooth) {
532
+ for (let [i, end] = store.$getRange(0); i <= end; i++) {
533
+ if (store.$isUnmeasuredItem(i)) {
534
+ return;
535
+ }
530
536
  }
537
+ stop();
531
538
  }
532
- stop();
533
- }
534
- store.$update(7);
535
- scroll(getTargetOffset(), smooth);
536
- };
537
- const start = () => {
538
- if (stopped) {
539
- return;
540
- }
541
- let queued;
542
- unsubscribe = store.$subscribe(2, () => {
543
- if (queued) {
539
+ store.$update(7);
540
+ scrollTo(getTargetOffset(), smooth);
541
+ };
542
+ const start = () => {
543
+ if (stopped) {
544
544
  return;
545
545
  }
546
- queued = true;
547
- microtask(() => {
548
- queued = false;
549
- onMeasured();
546
+ let queued;
547
+ unsubscribe = store.$subscribe(2, () => {
548
+ if (queued) {
549
+ return;
550
+ }
551
+ queued = true;
552
+ microtask(() => {
553
+ queued = false;
554
+ onMeasured();
555
+ });
550
556
  });
551
- });
552
- onMeasured();
553
- };
554
- if (smooth) {
555
- store.$update(8, getTargetOffset());
556
- microtask(start);
557
- } else {
558
- start();
557
+ onMeasured();
558
+ };
559
+ if (smooth) {
560
+ store.$update(8, getTargetOffset());
561
+ microtask(start);
562
+ } else {
563
+ start();
564
+ }
559
565
  }
560
- }, () => {
561
- cancelScroll && cancelScroll();
562
- }];
566
+ };
563
567
  };
568
+
569
+ //#endregion
570
+ //#region src/core/driver.ts
564
571
  var createContainerDriver = (store, isHorizontal) => {
565
572
  let viewportElement;
566
573
  let scrollObserver;
567
574
  let initialized = createPromise();
568
- let isRtl = false;
569
- const scrollOffsetKey = isHorizontal ? "scrollLeft" : "scrollTop";
570
- const scrollToKey = isHorizontal ? "left" : "top";
571
- const overflowKey = isHorizontal ? "overflowX" : "overflowY";
572
- const [scheduleScroll, cancelScroll] = createScrollScheduler(store, () => initialized[0], (offset, smooth) => {
573
- viewportElement.scrollTo({
574
- [scrollToKey]: normalizeScrollOffset(offset, isRtl),
575
- behavior: smooth ? "smooth" : "instant"
576
- });
577
- });
578
575
  const sizeKey = isHorizontal ? "width" : "height";
579
576
  const mountedIndexes = new WeakMap();
580
577
  const resizeObserver = createResizeObserver((entries) => {
@@ -597,33 +594,14 @@ var createContainerDriver = (store, isHorizontal) => {
597
594
  return {
598
595
  $observe(containerElement, viewport = containerElement.parentElement) {
599
596
  resizeObserver._observe(viewportElement = viewport);
600
- if (isHorizontal) {
601
- isRtl = getComputedStyle(viewport).direction === "rtl";
602
- }
603
- scrollObserver = createScrollObserver(store, viewport, isHorizontal, () => normalizeScrollOffset(viewport[scrollOffsetKey], isRtl), (jump, shift, isMomentumScrolling) => {
604
- if (isMomentumScrolling) {
605
- const style = viewport.style;
606
- const prev = style[overflowKey];
607
- style[overflowKey] = "hidden";
608
- timeout(() => {
609
- style[overflowKey] = prev;
610
- });
611
- }
612
- const target = store.$getScrollOffset() + jump;
613
- if (target <= 0 || target >= store.$getStartSpacerSize() + store.$getTotalSize() - store.$getViewportSize()) {
614
- viewport.scrollTo({
615
- [scrollToKey]: normalizeScrollOffset(target, isRtl),
616
- behavior: "instant"
617
- });
618
- } else {
619
- viewport.scrollBy({
620
- [scrollToKey]: normalizeScrollOffset(jump, isRtl),
621
- behavior: "instant"
622
- });
623
- }
624
- if (shift) {
625
- cancelScroll();
626
- }
597
+ scrollObserver = createScrollObserver(store, viewport, viewport, isHorizontal, isHorizontal && getComputedStyle(viewport).direction === "rtl", () => {
598
+ const overflowKey = isHorizontal ? "overflowX" : "overflowY";
599
+ const style = viewport.style;
600
+ const prev = style[overflowKey];
601
+ style[overflowKey] = "hidden";
602
+ timeout(() => {
603
+ style[overflowKey] = prev;
604
+ });
627
605
  });
628
606
  initialized[1](true);
629
607
  },
@@ -641,7 +619,11 @@ var createContainerDriver = (store, isHorizontal) => {
641
619
  resizeObserver._unobserve(el);
642
620
  };
643
621
  },
644
- $scroll: scheduleScroll,
622
+ async $scroll(getTargetOffset, smooth) {
623
+ if (await initialized[0]) {
624
+ scrollObserver._scroll(getTargetOffset, smooth);
625
+ }
626
+ },
645
627
  $effect() {
646
628
  scrollObserver && scrollObserver._fixScrollJump();
647
629
  },
@@ -655,15 +637,6 @@ var createWindowDriver = (store, isHorizontal) => {
655
637
  let getBaseOffset;
656
638
  let onViewportResize;
657
639
  let initialized = createPromise();
658
- let isRtl = false;
659
- const scrollOffsetKey = isHorizontal ? "scrollLeft" : "scrollTop";
660
- const scrollToKey = isHorizontal ? "left" : "top";
661
- const [scheduleScroll, cancelScroll] = createScrollScheduler(store, () => initialized[0], (offset, smooth) => {
662
- viewportElement.scrollTo({
663
- [scrollToKey]: normalizeScrollOffset(offset, isRtl),
664
- behavior: smooth ? "smooth" : "instant"
665
- });
666
- });
667
640
  const sizeKey = isHorizontal ? "width" : "height";
668
641
  const mountedIndexes = new WeakMap();
669
642
  const resizeObserver = createResizeObserver((entries) => {
@@ -683,20 +656,21 @@ var createWindowDriver = (store, isHorizontal) => {
683
656
  store.$update(3, resizes);
684
657
  }
685
658
  });
686
- const calcOffsetToViewport = (node, viewport, until, isHorizontal, offset = 0) => {
687
- const offsetKey = isHorizontal ? "offsetLeft" : "offsetTop";
688
- const offsetSum = offset + (isRtl ? viewport.clientWidth - node[offsetKey] - node.offsetWidth : node[offsetKey]);
689
- const parent = node.offsetParent;
690
- if (node === until || !parent) {
691
- return offsetSum;
692
- }
693
- return calcOffsetToViewport(parent, viewport, until, isHorizontal, offsetSum);
694
- };
695
659
  return {
696
660
  $observe(container) {
697
661
  const document = getCurrentDocument(container);
698
662
  const window = getCurrentWindow(document);
699
663
  const viewport = viewportElement = document.scrollingElement;
664
+ const isRtl = isHorizontal && getComputedStyle(viewport).direction === "rtl";
665
+ const calcOffsetToViewport = (node, viewport, until, isHorizontal, offset = 0) => {
666
+ const offsetKey = isHorizontal ? "offsetLeft" : "offsetTop";
667
+ const offsetSum = offset + (isRtl ? viewport.clientWidth - node[offsetKey] - node.offsetWidth : node[offsetKey]);
668
+ const parent = node.offsetParent;
669
+ if (node === until || !parent) {
670
+ return offsetSum;
671
+ }
672
+ return calcOffsetToViewport(parent, viewport, until, isHorizontal, offsetSum);
673
+ };
700
674
  const baseOffset = getBaseOffset = () => {
701
675
  return calcOffsetToViewport(container, viewport, document.body, isHorizontal);
702
676
  };
@@ -708,33 +682,13 @@ var createWindowDriver = (store, isHorizontal) => {
708
682
  cleanupOnWindowResize = () => {
709
683
  window.removeEventListener("resize", onWindowResize);
710
684
  };
711
- if (isHorizontal) {
712
- isRtl = getComputedStyle(viewport).direction === "rtl";
713
- }
714
- scrollObserver = createScrollObserver(store, window, isHorizontal, () => normalizeScrollOffset(viewport[scrollOffsetKey], isRtl), (jump, shift) => {
715
- const target = store.$getScrollOffset() + jump;
716
- if (target <= 0 || target >= store.$getStartSpacerSize() + store.$getTotalSize() - store.$getViewportSize()) {
717
- viewport.scrollTo({
718
- [scrollToKey]: normalizeScrollOffset(target, isRtl),
719
- behavior: "instant"
720
- });
721
- } else {
722
- viewport.scrollBy({
723
- [scrollToKey]: normalizeScrollOffset(jump, isRtl),
724
- behavior: "instant"
725
- });
726
- }
727
- if (shift) {
728
- cancelScroll();
729
- }
730
- }, baseOffset);
685
+ scrollObserver = createScrollObserver(store, window, viewport, isHorizontal, isRtl, null, baseOffset);
731
686
  initialized[1](true);
732
687
  },
733
688
  $dispose() {
734
689
  cleanupOnWindowResize && cleanupOnWindowResize();
735
690
  resizeObserver._dispose();
736
691
  scrollObserver && scrollObserver._dispose();
737
- viewportElement = undefined;
738
692
  initialized[1](false);
739
693
  initialized = createPromise();
740
694
  },
@@ -746,7 +700,11 @@ var createWindowDriver = (store, isHorizontal) => {
746
700
  resizeObserver._unobserve(el);
747
701
  };
748
702
  },
749
- $scroll: scheduleScroll,
703
+ async $scroll(getTargetOffset, smooth) {
704
+ if (await initialized[0]) {
705
+ scrollObserver._scroll(getTargetOffset, smooth);
706
+ }
707
+ },
750
708
  $effect() {
751
709
  scrollObserver && scrollObserver._fixScrollJump();
752
710
  },
@@ -760,19 +718,6 @@ var createContainerGridDriver = (rowStore, colStore) => {
760
718
  let rowScrollObserver;
761
719
  let colScrollObserver;
762
720
  let initialized = createPromise();
763
- let isRtl = false;
764
- const [scheduleScrollX, cancelScrollX] = createScrollScheduler(colStore, () => initialized[0], (offset, smooth) => {
765
- viewportElement.scrollTo({
766
- left: normalizeScrollOffset(offset, isRtl),
767
- behavior: smooth ? "smooth" : "instant"
768
- });
769
- });
770
- const [scheduleScrollY, cancelScrollY] = createScrollScheduler(rowStore, () => initialized[0], (offset, smooth) => {
771
- viewportElement.scrollTo({
772
- top: offset,
773
- behavior: smooth ? "smooth" : "instant"
774
- });
775
- });
776
721
  const mountedIndexes = new WeakMap();
777
722
  const maybeCachedRowIndexes = new Set();
778
723
  const maybeCachedColIndexes = new Set();
@@ -849,43 +794,20 @@ var createContainerGridDriver = (rowStore, colStore) => {
849
794
  colStore.$update(3, widthResizes);
850
795
  }
851
796
  });
852
- const observeAxisScroll = (store, isHorizontal, cancelScroll) => {
853
- const viewport = viewportElement;
854
- const scrollOffsetKey = isHorizontal ? "scrollLeft" : "scrollTop";
855
- const overflowKey = isHorizontal ? "overflowX" : "overflowY";
856
- const rtl = isHorizontal && isRtl;
857
- return createScrollObserver(store, viewport, isHorizontal, () => normalizeScrollOffset(viewport[scrollOffsetKey], rtl), (jump, shift, isMomentumScrolling) => {
858
- if (isMomentumScrolling) {
797
+ return {
798
+ $observe(containerElement, viewport = containerElement.parentElement) {
799
+ resizeObserver._observe(viewportElement = viewport);
800
+ const isRtl = getComputedStyle(viewport).direction === "rtl";
801
+ const hackOverflow = (overflowKey) => () => {
859
802
  const style = viewport.style;
860
803
  const prev = style[overflowKey];
861
804
  style[overflowKey] = "hidden";
862
805
  timeout(() => {
863
806
  style[overflowKey] = prev;
864
807
  });
865
- }
866
- const target = store.$getScrollOffset() + jump;
867
- if (target <= 0 || target >= store.$getStartSpacerSize() + store.$getTotalSize() - store.$getViewportSize()) {
868
- viewport.scrollTo({
869
- [isHorizontal ? "left" : "top"]: normalizeScrollOffset(target, rtl),
870
- behavior: "instant"
871
- });
872
- } else {
873
- viewport.scrollBy({
874
- [isHorizontal ? "left" : "top"]: normalizeScrollOffset(jump, rtl),
875
- behavior: "instant"
876
- });
877
- }
878
- if (shift) {
879
- cancelScroll();
880
- }
881
- });
882
- };
883
- return {
884
- $observe(containerElement, viewport = containerElement.parentElement) {
885
- resizeObserver._observe(viewportElement = viewport);
886
- isRtl = getComputedStyle(viewport).direction === "rtl";
887
- rowScrollObserver = observeAxisScroll(rowStore, false, cancelScrollY);
888
- colScrollObserver = observeAxisScroll(colStore, true, cancelScrollX);
808
+ };
809
+ rowScrollObserver = createScrollObserver(rowStore, viewport, viewport, false, false, hackOverflow("overflowY"));
810
+ colScrollObserver = createScrollObserver(colStore, viewport, viewport, true, isRtl, hackOverflow("overflowX"));
889
811
  initialized[1](true);
890
812
  },
891
813
  $dispose() {
@@ -921,8 +843,16 @@ var createContainerGridDriver = (rowStore, colStore) => {
921
843
  }
922
844
  colStore.$update(3, cols);
923
845
  },
924
- $scrollX: scheduleScrollX,
925
- $scrollY: scheduleScrollY,
846
+ async $scrollX(getTargetOffset, smooth) {
847
+ if (await initialized[0]) {
848
+ colScrollObserver._scroll(getTargetOffset, smooth);
849
+ }
850
+ },
851
+ async $scrollY(getTargetOffset, smooth) {
852
+ if (await initialized[0]) {
853
+ rowScrollObserver._scroll(getTargetOffset, smooth);
854
+ }
855
+ },
926
856
  $effect() {
927
857
  rowScrollObserver && rowScrollObserver._fixScrollJump();
928
858
  colScrollObserver && colScrollObserver._fixScrollJump();
@@ -1010,7 +940,7 @@ var ListItem = (props) => {
1010
940
  }
1011
941
  return style;
1012
942
  });
1013
- return <Dynamic component={props._as} index={props._index} ref={elementRef} style={style()}>
943
+ return <Dynamic component={props._as} index={typeof props._as === "string" ? undefined : props._index} ref={elementRef} style={style()}>
1014
944
  {props._children}
1015
945
  </Dynamic>;
1016
946
  };
@@ -1051,35 +981,34 @@ var Virtualizer = (props) => {
1051
981
  });
1052
982
  const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
1053
983
  const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
984
+ const ref = props.ref;
985
+ if (!isServer && ref) {
986
+ ref({
987
+ get cache() {
988
+ return layout.$snapshot();
989
+ },
990
+ get scrollOffset() {
991
+ return store.$getScrollOffset();
992
+ },
993
+ get scrollSize() {
994
+ return getScrollSize(store);
995
+ },
996
+ get viewportSize() {
997
+ return store.$getViewportSize();
998
+ },
999
+ findItemIndex: store.$findItemIndex,
1000
+ getItemOffset: store.$getItemOffset,
1001
+ getItemSize: store.$getItemSize,
1002
+ scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts),
1003
+ scrollTo: (offset) => scrollTo(driver, offset),
1004
+ scrollBy: (offset) => scrollBy(driver, store, offset)
1005
+ });
1006
+ onCleanup(() => ref());
1007
+ }
1054
1008
  onMount(() => {
1055
1009
  setIsSSR(false);
1056
- if (props.ref) {
1057
- props.ref({
1058
- get cache() {
1059
- return layout.$snapshot();
1060
- },
1061
- get scrollOffset() {
1062
- return store.$getScrollOffset();
1063
- },
1064
- get scrollSize() {
1065
- return getScrollSize(store);
1066
- },
1067
- get viewportSize() {
1068
- return store.$getViewportSize();
1069
- },
1070
- findItemIndex: store.$findItemIndex,
1071
- getItemOffset: store.$getItemOffset,
1072
- getItemSize: store.$getItemSize,
1073
- scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts),
1074
- scrollTo: (offset) => scrollTo(driver, offset),
1075
- scrollBy: (offset) => scrollBy(driver, store, offset)
1076
- });
1077
- }
1078
1010
  driver.$observe(containerRef, props.scrollRef);
1079
1011
  onCleanup(() => {
1080
- if (props.ref) {
1081
- props.ref();
1082
- }
1083
1012
  store.$dispose();
1084
1013
  driver.$dispose();
1085
1014
  });
@@ -1107,8 +1036,10 @@ var Virtualizer = (props) => {
1107
1036
  mounted.add(i);
1108
1037
  }
1109
1038
  sort([...mounted]).forEach((index) => {
1110
- items.push(props.data[index]);
1111
- indexes.push(index);
1039
+ if (index < count) {
1040
+ items.push(props.data[index]);
1041
+ indexes.push(index);
1042
+ }
1112
1043
  });
1113
1044
  } else {
1114
1045
  for (let [i, j] = range(); i <= j; i++) {
@@ -1215,30 +1146,29 @@ var WindowVirtualizer = (props) => {
1215
1146
  });
1216
1147
  const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
1217
1148
  const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
1149
+ const ref = props.ref;
1150
+ if (!isServer && ref) {
1151
+ ref({
1152
+ get cache() {
1153
+ return layout.$snapshot();
1154
+ },
1155
+ get scrollOffset() {
1156
+ return store.$getScrollOffset();
1157
+ },
1158
+ get viewportSize() {
1159
+ return store.$getViewportSize();
1160
+ },
1161
+ findItemIndex: store.$findItemIndex,
1162
+ getItemOffset: store.$getItemOffset,
1163
+ getItemSize: store.$getItemSize,
1164
+ scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts)
1165
+ });
1166
+ onCleanup(() => ref());
1167
+ }
1218
1168
  onMount(() => {
1219
1169
  setIsSSR(false);
1220
- if (props.ref) {
1221
- props.ref({
1222
- get cache() {
1223
- return layout.$snapshot();
1224
- },
1225
- get scrollOffset() {
1226
- return store.$getScrollOffset();
1227
- },
1228
- get viewportSize() {
1229
- return store.$getViewportSize();
1230
- },
1231
- findItemIndex: store.$findItemIndex,
1232
- getItemOffset: store.$getItemOffset,
1233
- getItemSize: store.$getItemSize,
1234
- scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts)
1235
- });
1236
- }
1237
1170
  driver.$observe(containerRef);
1238
1171
  onCleanup(() => {
1239
- if (props.ref) {
1240
- props.ref();
1241
- }
1242
1172
  store.$dispose();
1243
1173
  driver.$dispose();
1244
1174
  });