virtua@0.49.1.patch 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. diff --git a/lib/solid/Virtualizer.d.ts b/lib/solid/Virtualizer.d.ts
  2. index 144dd7f..819aab9 100644
  3. --- a/lib/solid/Virtualizer.d.ts
  4. +++ b/lib/solid/Virtualizer.d.ts
  5. @@ -38,6 +38,10 @@ export interface VirtualizerHandle {
  6. * @param index index of item
  7. */
  8. getItemSize(index: number): number;
  9. + /**
  10. + * Synchronously measure currently mounted items and update cached item sizes.
  11. + */
  12. + measure(): void;
  13. /**
  14. * Scroll to the item specified by index.
  15. * @param index index of item
  16. diff --git a/lib/solid/index.jsx b/lib/solid/index.jsx
  17. index 029201a..3949cd4 100644
  18. --- a/lib/solid/index.jsx
  19. +++ b/lib/solid/index.jsx
  20. @@ -1085,6 +1085,7 @@ const createResizer = (store, isHorizontal) => {
  21. let viewportElement;
  22. const sizeKey = isHorizontal ? "width" : "height";
  23. const mountedIndexes = new WeakMap();
  24. + const mountedItems = new Map();
  25. const resizeObserver = createResizeObserver((entries) => {
  26. const resizes = [];
  27. for (const { target, contentRect } of entries) {
  28. @@ -1111,12 +1112,27 @@ const createResizer = (store, isHorizontal) => {
  29. },
  30. $observeItem: (el, i) => {
  31. mountedIndexes.set(el, i);
  32. + mountedItems.set(i, el);
  33. resizeObserver._observe(el);
  34. return () => {
  35. mountedIndexes.delete(el);
  36. + if (mountedItems.get(i) === el) {
  37. + mountedItems.delete(i);
  38. + }
  39. resizeObserver._unobserve(el);
  40. };
  41. },
  42. + $measureItems: () => {
  43. + const resizes = [];
  44. + mountedItems.forEach((el, index) => {
  45. + if (!el.offsetParent)
  46. + return;
  47. + resizes.push([index, el.getBoundingClientRect()[sizeKey]]);
  48. + });
  49. + if (resizes.length) {
  50. + store.$update(ACTION_ITEM_RESIZE, resizes);
  51. + }
  52. + },
  53. $dispose: resizeObserver._dispose,
  54. };
  55. };
  56. @@ -1354,6 +1370,8 @@ const Virtualizer = (props) => {
  57. const range = createMemo((prev) => {
  58. stateVersion();
  59. const next = store.$getRange(props.bufferSize);
  60. + next[0] = Math.max(0, next[0]);
  61. + next[1] = Math.min(props.data.length - 1, next[1]);
  62. if (prev && isSameRange(prev, next)) {
  63. return prev;
  64. }
  65. @@ -1380,6 +1398,7 @@ const Virtualizer = (props) => {
  66. findItemIndex: store.$findItemIndex,
  67. getItemOffset: store.$getItemOffset,
  68. getItemSize: store.$getItemSize,
  69. + measure: resizer.$measureItems,
  70. scrollToIndex: scroller.$scrollToIndex,
  71. scrollTo: scroller.$scrollTo,
  72. scrollBy: scroller.$scrollBy,
  73. @@ -1417,6 +1436,11 @@ const Virtualizer = (props) => {
  74. const indexes = [];
  75. if (props.keepMounted) {
  76. const mounted = new Set(props.keepMounted);
  77. + mounted.forEach((index) => {
  78. + if (index < 0 || index >= count) {
  79. + mounted.delete(index);
  80. + }
  81. + });
  82. for (let [i, j] = range(); i <= j; i++) {
  83. mounted.add(i);
  84. }
  85. @@ -1528,6 +1552,8 @@ const WindowVirtualizer = (props) => {
  86. const range = createMemo((prev) => {
  87. stateVersion();
  88. const next = store.$getRange(props.bufferSize);
  89. + next[0] = Math.max(0, next[0]);
  90. + next[1] = Math.min(props.data.length - 1, next[1]);
  91. if (prev && isSameRange(prev, next)) {
  92. return prev;
  93. }