@tanstack/virtual-core
Advanced tools
Comparing version 3.0.0-beta.44 to 3.0.0-beta.45
@@ -31,6 +31,6 @@ export * from './utils'; | ||
export declare const defaultRangeExtractor: (range: Range) => number[]; | ||
export declare const observeElementRect: (instance: Virtualizer<any, any>, cb: (rect: Rect) => void) => (() => void) | undefined; | ||
export declare const observeWindowRect: (instance: Virtualizer<any, any>, cb: (rect: Rect) => void) => (() => void) | undefined; | ||
export declare const observeElementOffset: (instance: Virtualizer<any, any>, cb: (offset: number) => void) => (() => void) | undefined; | ||
export declare const observeWindowOffset: (instance: Virtualizer<any, any>, cb: (offset: number) => void) => (() => void) | undefined; | ||
export declare const observeElementRect: <T extends Element>(instance: Virtualizer<T, any>, cb: (rect: Rect) => void) => (() => void) | undefined; | ||
export declare const observeWindowRect: (instance: Virtualizer<Window, any>, cb: (rect: Rect) => void) => (() => void) | undefined; | ||
export declare const observeElementOffset: <T extends Element>(instance: Virtualizer<T, any>, cb: (offset: number) => void) => (() => void) | undefined; | ||
export declare const observeWindowOffset: (instance: Virtualizer<Window, any>, cb: (offset: number) => void) => (() => void) | undefined; | ||
export declare const measureElement: <TItemElement extends Element>(element: TItemElement, instance: Virtualizer<any, TItemElement>) => number; | ||
@@ -37,0 +37,0 @@ export declare const windowScroll: <T extends Window>(offset: number, { adjustments, behavior, }: { |
@@ -31,100 +31,76 @@ /** | ||
}; | ||
var memoRectCallback = function memoRectCallback(instance, cb) { | ||
var prev = { | ||
height: -1, | ||
width: -1 | ||
}; | ||
return function (rect) { | ||
if (instance.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) { | ||
cb(rect); | ||
} | ||
prev = rect; | ||
}; | ||
}; | ||
var observeElementRect = function observeElementRect(instance, cb) { | ||
var observer = new ResizeObserver(function (entries) { | ||
var entry = entries[0]; | ||
if (entry) { | ||
var _entry$contentRect = entry.contentRect, | ||
width = _entry$contentRect.width, | ||
height = _entry$contentRect.height; | ||
cb({ | ||
width: Math.round(width), | ||
height: Math.round(height) | ||
}); | ||
} else { | ||
cb({ | ||
width: 0, | ||
height: 0 | ||
}); | ||
} | ||
}); | ||
if (!instance.scrollElement) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
cb(instance.scrollElement.getBoundingClientRect()); | ||
observer.observe(instance.scrollElement); | ||
var handler = function handler() { | ||
var _element$getBoundingC = element.getBoundingClientRect(), | ||
width = _element$getBoundingC.width, | ||
height = _element$getBoundingC.height; | ||
cb({ | ||
width: Math.round(width), | ||
height: Math.round(height) | ||
}); | ||
}; | ||
handler(); | ||
var observer = new ResizeObserver(function () { | ||
handler(); | ||
}); | ||
observer.observe(element); | ||
return function () { | ||
observer.unobserve(instance.scrollElement); | ||
observer.unobserve(element); | ||
}; | ||
}; | ||
var observeWindowRect = function observeWindowRect(instance, cb) { | ||
var memoizedCallback = memoRectCallback(instance, cb); | ||
var onResize = function onResize() { | ||
return memoizedCallback({ | ||
width: instance.scrollElement.innerWidth, | ||
height: instance.scrollElement.innerHeight | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
var handler = function handler() { | ||
cb({ | ||
width: element.innerWidth, | ||
height: element.innerHeight | ||
}); | ||
}; | ||
if (!instance.scrollElement) { | ||
handler(); | ||
element.addEventListener('resize', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
element.removeEventListener('resize', handler); | ||
}; | ||
}; | ||
var observeElementOffset = function observeElementOffset(instance, cb) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
onResize(); | ||
instance.scrollElement.addEventListener('resize', onResize, { | ||
capture: false, | ||
var handler = function handler() { | ||
cb(element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop']); | ||
}; | ||
handler(); | ||
element.addEventListener('scroll', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
instance.scrollElement.removeEventListener('resize', onResize); | ||
element.removeEventListener('scroll', handler); | ||
}; | ||
}; | ||
var scrollProps = { | ||
element: ['scrollLeft', 'scrollTop'], | ||
window: ['scrollX', 'scrollY'] | ||
}; | ||
var createOffsetObserver = function createOffsetObserver(mode) { | ||
return function (instance, cb) { | ||
if (!instance.scrollElement) { | ||
return; | ||
} | ||
var propX = scrollProps[mode][0]; | ||
var propY = scrollProps[mode][1]; | ||
var prevX = instance.scrollElement[propX]; | ||
var prevY = instance.scrollElement[propY]; | ||
var scroll = function scroll() { | ||
var offset = instance.scrollElement[instance.options.horizontal ? propX : propY]; | ||
cb(offset); | ||
}; | ||
scroll(); | ||
var onScroll = function onScroll(e) { | ||
var target = e.currentTarget; | ||
var scrollX = target[propX]; | ||
var scrollY = target[propY]; | ||
if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) { | ||
scroll(); | ||
} | ||
prevX = scrollX; | ||
prevY = scrollY; | ||
}; | ||
instance.scrollElement.addEventListener('scroll', onScroll, { | ||
capture: false, | ||
passive: true | ||
}); | ||
return function () { | ||
instance.scrollElement.removeEventListener('scroll', onScroll); | ||
}; | ||
var observeWindowOffset = function observeWindowOffset(instance, cb) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
var handler = function handler() { | ||
cb(element[instance.options.horizontal ? 'scrollX' : 'scrollY']); | ||
}; | ||
handler(); | ||
element.addEventListener('scroll', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
element.removeEventListener('scroll', handler); | ||
}; | ||
}; | ||
var observeElementOffset = createOffsetObserver('element'); | ||
var observeWindowOffset = createOffsetObserver('window'); | ||
var measureElement = function measureElement(element, instance) { | ||
@@ -241,4 +217,7 @@ return Math.round(element.getBoundingClientRect()[instance.options.horizontal ? 'width' : 'height']); | ||
_this.unsubs.push(_this.options.observeElementRect(_this, function (rect) { | ||
var prev = _this.scrollRect; | ||
_this.scrollRect = rect; | ||
_this.maybeNotify(); | ||
if (_this.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) { | ||
_this.maybeNotify(); | ||
} | ||
})); | ||
@@ -245,0 +224,0 @@ _this.unsubs.push(_this.options.observeElementOffset(_this, function (offset) { |
@@ -34,100 +34,76 @@ /** | ||
}; | ||
var memoRectCallback = function memoRectCallback(instance, cb) { | ||
var prev = { | ||
height: -1, | ||
width: -1 | ||
}; | ||
return function (rect) { | ||
if (instance.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) { | ||
cb(rect); | ||
} | ||
prev = rect; | ||
}; | ||
}; | ||
var observeElementRect = function observeElementRect(instance, cb) { | ||
var observer = new ResizeObserver(function (entries) { | ||
var entry = entries[0]; | ||
if (entry) { | ||
var _entry$contentRect = entry.contentRect, | ||
width = _entry$contentRect.width, | ||
height = _entry$contentRect.height; | ||
cb({ | ||
width: Math.round(width), | ||
height: Math.round(height) | ||
}); | ||
} else { | ||
cb({ | ||
width: 0, | ||
height: 0 | ||
}); | ||
} | ||
}); | ||
if (!instance.scrollElement) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
cb(instance.scrollElement.getBoundingClientRect()); | ||
observer.observe(instance.scrollElement); | ||
var handler = function handler() { | ||
var _element$getBoundingC = element.getBoundingClientRect(), | ||
width = _element$getBoundingC.width, | ||
height = _element$getBoundingC.height; | ||
cb({ | ||
width: Math.round(width), | ||
height: Math.round(height) | ||
}); | ||
}; | ||
handler(); | ||
var observer = new ResizeObserver(function () { | ||
handler(); | ||
}); | ||
observer.observe(element); | ||
return function () { | ||
observer.unobserve(instance.scrollElement); | ||
observer.unobserve(element); | ||
}; | ||
}; | ||
var observeWindowRect = function observeWindowRect(instance, cb) { | ||
var memoizedCallback = memoRectCallback(instance, cb); | ||
var onResize = function onResize() { | ||
return memoizedCallback({ | ||
width: instance.scrollElement.innerWidth, | ||
height: instance.scrollElement.innerHeight | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
var handler = function handler() { | ||
cb({ | ||
width: element.innerWidth, | ||
height: element.innerHeight | ||
}); | ||
}; | ||
if (!instance.scrollElement) { | ||
handler(); | ||
element.addEventListener('resize', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
element.removeEventListener('resize', handler); | ||
}; | ||
}; | ||
var observeElementOffset = function observeElementOffset(instance, cb) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
onResize(); | ||
instance.scrollElement.addEventListener('resize', onResize, { | ||
capture: false, | ||
var handler = function handler() { | ||
cb(element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop']); | ||
}; | ||
handler(); | ||
element.addEventListener('scroll', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
instance.scrollElement.removeEventListener('resize', onResize); | ||
element.removeEventListener('scroll', handler); | ||
}; | ||
}; | ||
var scrollProps = { | ||
element: ['scrollLeft', 'scrollTop'], | ||
window: ['scrollX', 'scrollY'] | ||
}; | ||
var createOffsetObserver = function createOffsetObserver(mode) { | ||
return function (instance, cb) { | ||
if (!instance.scrollElement) { | ||
return; | ||
} | ||
var propX = scrollProps[mode][0]; | ||
var propY = scrollProps[mode][1]; | ||
var prevX = instance.scrollElement[propX]; | ||
var prevY = instance.scrollElement[propY]; | ||
var scroll = function scroll() { | ||
var offset = instance.scrollElement[instance.options.horizontal ? propX : propY]; | ||
cb(offset); | ||
}; | ||
scroll(); | ||
var onScroll = function onScroll(e) { | ||
var target = e.currentTarget; | ||
var scrollX = target[propX]; | ||
var scrollY = target[propY]; | ||
if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) { | ||
scroll(); | ||
} | ||
prevX = scrollX; | ||
prevY = scrollY; | ||
}; | ||
instance.scrollElement.addEventListener('scroll', onScroll, { | ||
capture: false, | ||
passive: true | ||
}); | ||
return function () { | ||
instance.scrollElement.removeEventListener('scroll', onScroll); | ||
}; | ||
var observeWindowOffset = function observeWindowOffset(instance, cb) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
var handler = function handler() { | ||
cb(element[instance.options.horizontal ? 'scrollX' : 'scrollY']); | ||
}; | ||
handler(); | ||
element.addEventListener('scroll', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
element.removeEventListener('scroll', handler); | ||
}; | ||
}; | ||
var observeElementOffset = createOffsetObserver('element'); | ||
var observeWindowOffset = createOffsetObserver('window'); | ||
var measureElement = function measureElement(element, instance) { | ||
@@ -244,4 +220,7 @@ return Math.round(element.getBoundingClientRect()[instance.options.horizontal ? 'width' : 'height']); | ||
_this.unsubs.push(_this.options.observeElementRect(_this, function (rect) { | ||
var prev = _this.scrollRect; | ||
_this.scrollRect = rect; | ||
_this.maybeNotify(); | ||
if (_this.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) { | ||
_this.maybeNotify(); | ||
} | ||
})); | ||
@@ -248,0 +227,0 @@ _this.unsubs.push(_this.options.observeElementOffset(_this, function (offset) { |
@@ -94,100 +94,76 @@ /** | ||
}; | ||
var memoRectCallback = function memoRectCallback(instance, cb) { | ||
var prev = { | ||
height: -1, | ||
width: -1 | ||
}; | ||
return function (rect) { | ||
if (instance.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) { | ||
cb(rect); | ||
} | ||
prev = rect; | ||
}; | ||
}; | ||
var observeElementRect = function observeElementRect(instance, cb) { | ||
var observer = new ResizeObserver(function (entries) { | ||
var entry = entries[0]; | ||
if (entry) { | ||
var _entry$contentRect = entry.contentRect, | ||
width = _entry$contentRect.width, | ||
height = _entry$contentRect.height; | ||
cb({ | ||
width: Math.round(width), | ||
height: Math.round(height) | ||
}); | ||
} else { | ||
cb({ | ||
width: 0, | ||
height: 0 | ||
}); | ||
} | ||
}); | ||
if (!instance.scrollElement) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
cb(instance.scrollElement.getBoundingClientRect()); | ||
observer.observe(instance.scrollElement); | ||
var handler = function handler() { | ||
var _element$getBoundingC = element.getBoundingClientRect(), | ||
width = _element$getBoundingC.width, | ||
height = _element$getBoundingC.height; | ||
cb({ | ||
width: Math.round(width), | ||
height: Math.round(height) | ||
}); | ||
}; | ||
handler(); | ||
var observer = new ResizeObserver(function () { | ||
handler(); | ||
}); | ||
observer.observe(element); | ||
return function () { | ||
observer.unobserve(instance.scrollElement); | ||
observer.unobserve(element); | ||
}; | ||
}; | ||
var observeWindowRect = function observeWindowRect(instance, cb) { | ||
var memoizedCallback = memoRectCallback(instance, cb); | ||
var onResize = function onResize() { | ||
return memoizedCallback({ | ||
width: instance.scrollElement.innerWidth, | ||
height: instance.scrollElement.innerHeight | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
var handler = function handler() { | ||
cb({ | ||
width: element.innerWidth, | ||
height: element.innerHeight | ||
}); | ||
}; | ||
if (!instance.scrollElement) { | ||
handler(); | ||
element.addEventListener('resize', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
element.removeEventListener('resize', handler); | ||
}; | ||
}; | ||
var observeElementOffset = function observeElementOffset(instance, cb) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
onResize(); | ||
instance.scrollElement.addEventListener('resize', onResize, { | ||
capture: false, | ||
var handler = function handler() { | ||
cb(element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop']); | ||
}; | ||
handler(); | ||
element.addEventListener('scroll', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
instance.scrollElement.removeEventListener('resize', onResize); | ||
element.removeEventListener('scroll', handler); | ||
}; | ||
}; | ||
var scrollProps = { | ||
element: ['scrollLeft', 'scrollTop'], | ||
window: ['scrollX', 'scrollY'] | ||
}; | ||
var createOffsetObserver = function createOffsetObserver(mode) { | ||
return function (instance, cb) { | ||
if (!instance.scrollElement) { | ||
return; | ||
} | ||
var propX = scrollProps[mode][0]; | ||
var propY = scrollProps[mode][1]; | ||
var prevX = instance.scrollElement[propX]; | ||
var prevY = instance.scrollElement[propY]; | ||
var scroll = function scroll() { | ||
var offset = instance.scrollElement[instance.options.horizontal ? propX : propY]; | ||
cb(offset); | ||
}; | ||
scroll(); | ||
var onScroll = function onScroll(e) { | ||
var target = e.currentTarget; | ||
var scrollX = target[propX]; | ||
var scrollY = target[propY]; | ||
if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) { | ||
scroll(); | ||
} | ||
prevX = scrollX; | ||
prevY = scrollY; | ||
}; | ||
instance.scrollElement.addEventListener('scroll', onScroll, { | ||
capture: false, | ||
passive: true | ||
}); | ||
return function () { | ||
instance.scrollElement.removeEventListener('scroll', onScroll); | ||
}; | ||
var observeWindowOffset = function observeWindowOffset(instance, cb) { | ||
var element = instance.scrollElement; | ||
if (!element) { | ||
return; | ||
} | ||
var handler = function handler() { | ||
cb(element[instance.options.horizontal ? 'scrollX' : 'scrollY']); | ||
}; | ||
handler(); | ||
element.addEventListener('scroll', handler, { | ||
passive: true | ||
}); | ||
return function () { | ||
element.removeEventListener('scroll', handler); | ||
}; | ||
}; | ||
var observeElementOffset = createOffsetObserver('element'); | ||
var observeWindowOffset = createOffsetObserver('window'); | ||
var measureElement = function measureElement(element, instance) { | ||
@@ -304,4 +280,7 @@ return Math.round(element.getBoundingClientRect()[instance.options.horizontal ? 'width' : 'height']); | ||
_this.unsubs.push(_this.options.observeElementRect(_this, function (rect) { | ||
var prev = _this.scrollRect; | ||
_this.scrollRect = rect; | ||
_this.maybeNotify(); | ||
if (_this.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) { | ||
_this.maybeNotify(); | ||
} | ||
})); | ||
@@ -308,0 +287,0 @@ _this.unsubs.push(_this.options.observeElementOffset(_this, function (offset) { |
@@ -11,3 +11,3 @@ /** | ||
*/ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VirtualCore={})}(this,(function(e){"use strict";function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},t.apply(this,arguments)}function n(e,t,n){var o,i,r=null!=(o=n.initialDeps)?o:[];return function(){var o;n.key&&null!=n.debug&&n.debug()&&(o=Date.now());var s,l=e();if(!(l.length!==r.length||l.some((function(e,t){return r[t]!==e}))))return i;if(r=l,n.key&&null!=n.debug&&n.debug()&&(s=Date.now()),i=t.apply(void 0,l),n.key&&null!=n.debug&&n.debug()){var a=Math.round(100*(Date.now()-o))/100,u=Math.round(100*(Date.now()-s))/100,c=u/16,d=function(e,t){for(e=String(e);e.length<t;)e=" "+e;return e};console.info("%c⏱ "+d(u,5)+" /"+d(a,5)+" ms","\n font-size: .6rem;\n font-weight: bold;\n color: hsl("+Math.max(0,Math.min(120-120*c,120))+"deg 100% 31%);",null==n?void 0:n.key)}return null==n||null==n.onChange||n.onChange(i),i}}function o(e,t){if(void 0===e)throw new Error("Unexpected undefined"+(t?": "+t:""));return e}var i=function(e,t){return Math.abs(e-t)<1},r=function(e){return e},s=function(e){for(var t=Math.max(e.startIndex-e.overscan,0),n=Math.min(e.endIndex+e.overscan,e.count-1),o=[],i=t;i<=n;i++)o.push(i);return o},l={element:["scrollLeft","scrollTop"],window:["scrollX","scrollY"]},a=function(e){return function(t,n){if(t.scrollElement){var o=l[e][0],i=l[e][1],r=t.scrollElement[o],s=t.scrollElement[i],a=function(){var e=t.scrollElement[t.options.horizontal?o:i];n(e)};a();var u=function(e){var n=e.currentTarget,l=n[o],u=n[i];(t.options.horizontal?r-l:s-u)&&a(),r=l,s=u};return t.scrollElement.addEventListener("scroll",u,{capture:!1,passive:!0}),function(){t.scrollElement.removeEventListener("scroll",u)}}}},u=a("element"),c=a("window"),d=function(e,t){return Math.round(e.getBoundingClientRect()[t.options.horizontal?"width":"height"])};e.Virtualizer=function(e){var l,a=this;this.unsubs=[],this.scrollElement=null,this.isScrolling=!1,this.isScrollingTimeoutId=null,this.scrollToIndexTimeoutId=null,this.measurementsCache=[],this.itemSizeCache={},this.pendingMeasuredCacheIndexes=[],this.scrollDirection=null,this.scrollAdjustments=0,this.measureElementCache={},this.getResizeObserver=(l=null,function(){return l||("undefined"!=typeof ResizeObserver?l=new ResizeObserver((function(e){e.forEach((function(e){a._measureElement(e.target,!1)}))})):null)}),this.range={startIndex:0,endIndex:0},this.setOptions=function(e){Object.entries(e).forEach((function(t){var n=t[0];void 0===t[1]&&delete e[n]})),a.options=t({debug:!1,initialOffset:0,overscan:1,paddingStart:0,paddingEnd:0,scrollPaddingStart:0,scrollPaddingEnd:0,horizontal:!1,getItemKey:r,rangeExtractor:s,onChange:function(){},measureElement:d,initialRect:{width:0,height:0},scrollMargin:0,scrollingDelay:150,indexAttribute:"data-index",initialMeasurementsCache:[]},e)},this.notify=function(){null==a.options.onChange||a.options.onChange(a)},this.cleanup=function(){a.unsubs.filter(Boolean).forEach((function(e){return e()})),a.unsubs=[],a.scrollElement=null},this._didMount=function(){var e=a.getResizeObserver();return Object.values(a.measureElementCache).forEach((function(t){return null==e?void 0:e.observe(t)})),function(){null==e||e.disconnect(),a.cleanup()}},this._willUpdate=function(){var e=a.options.getScrollElement();a.scrollElement!==e&&(a.cleanup(),a.scrollElement=e,a._scrollToOffset(a.scrollOffset,{adjustments:void 0,behavior:void 0}),a.unsubs.push(a.options.observeElementRect(a,(function(e){a.scrollRect=e,a.maybeNotify()}))),a.unsubs.push(a.options.observeElementOffset(a,(function(e){a.scrollAdjustments=0,a.scrollOffset!==e&&(null!==a.isScrollingTimeoutId&&(clearTimeout(a.isScrollingTimeoutId),a.isScrollingTimeoutId=null),a.isScrolling=!0,a.scrollDirection=a.scrollOffset<e?"forward":"backward",a.scrollOffset=e,a.maybeNotify(),a.isScrollingTimeoutId=setTimeout((function(){a.isScrollingTimeoutId=null,a.isScrolling=!1,a.scrollDirection=null,a.maybeNotify()}),a.options.scrollingDelay))}))))},this.getSize=function(){return a.scrollRect[a.options.horizontal?"width":"height"]},this.getMeasurements=n((function(){return[a.options.count,a.options.paddingStart,a.options.scrollMargin,a.options.getItemKey,a.itemSizeCache]}),(function(e,t,n,o,i){var r=a.pendingMeasuredCacheIndexes.length>0?Math.min.apply(Math,a.pendingMeasuredCacheIndexes):0;a.pendingMeasuredCacheIndexes=[];for(var s=a.measurementsCache.slice(0,r),l=r;l<e;l++){var u=o(l),c=i[u],d=s[l-1]?s[l-1].end:t+n,f="number"==typeof c?c:a.options.estimateSize(l),h=d+f;s[l]={index:l,start:d,size:f,end:h,key:u}}return a.measurementsCache=s,s}),{key:!1,debug:function(){return a.options.debug}}),this.calculateRange=n((function(){return[a.getMeasurements(),a.getSize(),a.scrollOffset]}),(function(e,t,n){return a.range=function(e){var t=e.measurements,n=e.outerSize,o=e.scrollOffset,i=t.length-1,r=function(e,t,n,o){for(;e<=t;){var i=(e+t)/2|0,r=n(i);if(r<o)e=i+1;else{if(!(r>o))return i;t=i-1}}return e>0?e-1:0}(0,i,(function(e){return t[e].start}),o),s=r;for(;s<i&&t[s].end<o+n;)s++;return{startIndex:r,endIndex:s}}({measurements:e,outerSize:t,scrollOffset:n})}),{key:!1,debug:function(){return a.options.debug}}),this.maybeNotify=n((function(){return[].concat(Object.values(a.calculateRange()),[a.isScrolling])}),(function(){a.notify()}),{key:!1,debug:function(){return a.options.debug},initialDeps:[].concat(Object.values(this.range),[this.isScrolling])}),this.getIndexes=n((function(){return[a.options.rangeExtractor,a.calculateRange(),a.options.overscan,a.options.count]}),(function(e,n,o,i){return e(t({},n,{overscan:o,count:i}))}),{key:!1,debug:function(){return a.options.debug}}),this.indexFromElement=function(e){var t=a.options.indexAttribute,n=e.getAttribute(t);return n?parseInt(n,10):(console.warn("Missing attribute name '"+t+"={index}' on measured element."),-1)},this._measureElement=function(e,n){var o,i=a.indexFromElement(e),r=a.measurementsCache[i];if(r){var s=a.measureElementCache[r.key],l=a.getResizeObserver();if(!e.isConnected)return null==l||l.unobserve(e),void(e===s&&delete a.measureElementCache[r.key]);if(s!==e)s&&(null==l||l.unobserve(s)),null==l||l.observe(e),a.measureElementCache[r.key]=e;else if(!n&&!s.__virtualizerSkipFirstNotSync)return void(s.__virtualizerSkipFirstNotSync=!0);var u,c=a.options.measureElement(e,a),d=c-(null!=(o=a.itemSizeCache[r.key])?o:r.size);if(0!==d)r.start<a.scrollOffset&&a._scrollToOffset(a.scrollOffset,{adjustments:a.scrollAdjustments+=d,behavior:void 0}),a.pendingMeasuredCacheIndexes.push(i),a.itemSizeCache=t({},a.itemSizeCache,((u={})[r.key]=c,u)),a.notify()}},this.measureElement=function(e){e&&a._measureElement(e,!0)},this.getVirtualItems=n((function(){return[a.getIndexes(),a.getMeasurements()]}),(function(e,t){for(var n=[],o=0,i=e.length;o<i;o++){var r=t[e[o]];n.push(r)}return n}),{key:!1,debug:function(){return a.options.debug}}),this.getOffsetForAlignment=function(e,t){var n=a.getSize();"auto"===t&&(t=e<=a.scrollOffset?"start":e>=a.scrollOffset+n?"end":"start"),"start"===t||("end"===t?e-=n:"center"===t&&(e-=n/2));var o=a.options.horizontal?"scrollWidth":"scrollHeight",i=(a.scrollElement?"document"in a.scrollElement?a.scrollElement.document.documentElement[o]:a.scrollElement[o]:0)-a.getSize();return Math.max(Math.min(i,e),0)},this.getOffsetForIndex=function(e,t){void 0===t&&(t="auto"),e=Math.max(0,Math.min(e,a.options.count-1));var n=o(a.getMeasurements()[e]);if("auto"===t)if(n.end>=a.scrollOffset+a.getSize()-a.options.scrollPaddingEnd)t="end";else{if(!(n.start<=a.scrollOffset+a.options.scrollPaddingStart))return[a.scrollOffset,t];t="start"}var i="end"===t?n.end+a.options.scrollPaddingEnd:n.start-a.options.scrollPaddingStart;return[a.getOffsetForAlignment(i,t),t]},this.isDynamicMode=function(){return Object.keys(a.measureElementCache).length>0},this.cancelScrollToIndex=function(){null!==a.scrollToIndexTimeoutId&&(clearTimeout(a.scrollToIndexTimeoutId),a.scrollToIndexTimeoutId=null)},this.scrollToOffset=function(e,t){var n=void 0===t?{}:t,o=n.align,i=void 0===o?"start":o,r=n.behavior;a.cancelScrollToIndex(),"smooth"===r&&a.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size."),a._scrollToOffset(a.getOffsetForAlignment(e,i),{adjustments:void 0,behavior:r})},this.scrollToIndex=function(e,t){var n=void 0===t?{}:t,o=n.align,r=void 0===o?"auto":o,s=n.behavior;e=Math.max(0,Math.min(e,a.options.count-1)),a.cancelScrollToIndex(),"smooth"===s&&a.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size.");var l=a.getOffsetForIndex(e,r),u=l[0],c=l[1];a._scrollToOffset(u,{adjustments:void 0,behavior:s}),"smooth"!==s&&a.isDynamicMode()&&(a.scrollToIndexTimeoutId=setTimeout((function(){if(a.scrollToIndexTimeoutId=null,!!a.measureElementCache[a.options.getItemKey(e)]){var t=a.getOffsetForIndex(e,c)[0];i(t,a.scrollOffset)||a.scrollToIndex(e,{align:c,behavior:s})}else a.scrollToIndex(e,{align:c,behavior:s})})))},this.scrollBy=function(e,t){var n=(void 0===t?{}:t).behavior;a.cancelScrollToIndex(),"smooth"===n&&a.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size."),a._scrollToOffset(a.scrollOffset+e,{adjustments:void 0,behavior:n})},this.getTotalSize=function(){var e;return((null==(e=a.getMeasurements()[a.options.count-1])?void 0:e.end)||a.options.paddingStart)-a.options.scrollMargin+a.options.paddingEnd},this._scrollToOffset=function(e,t){var n=t.adjustments,o=t.behavior;a.options.scrollToFn(e,{behavior:o,adjustments:n},a)},this.measure=function(){a.itemSizeCache={},a.notify()},this.setOptions(e),this.scrollRect=this.options.initialRect,this.scrollOffset=this.options.initialOffset,this.measurementsCache=this.options.initialMeasurementsCache,this.measurementsCache.forEach((function(e){a.itemSizeCache[e.key]=e.size})),this.maybeNotify()},e.approxEqual=i,e.defaultKeyExtractor=r,e.defaultRangeExtractor=s,e.elementScroll=function(e,t,n){var o,i,r=t.adjustments,s=void 0===r?0:r,l=t.behavior,a=e+s;null==(o=n.scrollElement)||null==o.scrollTo||o.scrollTo(((i={})[n.options.horizontal?"left":"top"]=a,i.behavior=l,i))},e.measureElement=d,e.memo=n,e.notUndefined=o,e.observeElementOffset=u,e.observeElementRect=function(e,t){var n=new ResizeObserver((function(e){var n=e[0];if(n){var o=n.contentRect,i=o.width,r=o.height;t({width:Math.round(i),height:Math.round(r)})}else t({width:0,height:0})}));if(e.scrollElement)return t(e.scrollElement.getBoundingClientRect()),n.observe(e.scrollElement),function(){n.unobserve(e.scrollElement)}},e.observeWindowOffset=c,e.observeWindowRect=function(e,t){var n=function(e,t){var n={height:-1,width:-1};return function(o){(e.options.horizontal?o.width!==n.width:o.height!==n.height)&&t(o),n=o}}(e,t),o=function(){return n({width:e.scrollElement.innerWidth,height:e.scrollElement.innerHeight})};if(e.scrollElement)return o(),e.scrollElement.addEventListener("resize",o,{capture:!1,passive:!0}),function(){e.scrollElement.removeEventListener("resize",o)}},e.windowScroll=function(e,t,n){var o,i,r=t.adjustments,s=void 0===r?0:r,l=t.behavior,a=e+s;null==(o=n.scrollElement)||null==o.scrollTo||o.scrollTo(((i={})[n.options.horizontal?"left":"top"]=a,i.behavior=l,i))},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VirtualCore={})}(this,(function(e){"use strict";function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},t.apply(this,arguments)}function n(e,t,n){var o,i,r=null!=(o=n.initialDeps)?o:[];return function(){var o;n.key&&null!=n.debug&&n.debug()&&(o=Date.now());var s,l=e();if(!(l.length!==r.length||l.some((function(e,t){return r[t]!==e}))))return i;if(r=l,n.key&&null!=n.debug&&n.debug()&&(s=Date.now()),i=t.apply(void 0,l),n.key&&null!=n.debug&&n.debug()){var a=Math.round(100*(Date.now()-o))/100,u=Math.round(100*(Date.now()-s))/100,c=u/16,d=function(e,t){for(e=String(e);e.length<t;)e=" "+e;return e};console.info("%c⏱ "+d(u,5)+" /"+d(a,5)+" ms","\n font-size: .6rem;\n font-weight: bold;\n color: hsl("+Math.max(0,Math.min(120-120*c,120))+"deg 100% 31%);",null==n?void 0:n.key)}return null==n||null==n.onChange||n.onChange(i),i}}function o(e,t){if(void 0===e)throw new Error("Unexpected undefined"+(t?": "+t:""));return e}var i=function(e,t){return Math.abs(e-t)<1},r=function(e){return e},s=function(e){for(var t=Math.max(e.startIndex-e.overscan,0),n=Math.min(e.endIndex+e.overscan,e.count-1),o=[],i=t;i<=n;i++)o.push(i);return o},l=function(e,t){return Math.round(e.getBoundingClientRect()[t.options.horizontal?"width":"height"])};e.Virtualizer=function(e){var a,u=this;this.unsubs=[],this.scrollElement=null,this.isScrolling=!1,this.isScrollingTimeoutId=null,this.scrollToIndexTimeoutId=null,this.measurementsCache=[],this.itemSizeCache={},this.pendingMeasuredCacheIndexes=[],this.scrollDirection=null,this.scrollAdjustments=0,this.measureElementCache={},this.getResizeObserver=(a=null,function(){return a||("undefined"!=typeof ResizeObserver?a=new ResizeObserver((function(e){e.forEach((function(e){u._measureElement(e.target,!1)}))})):null)}),this.range={startIndex:0,endIndex:0},this.setOptions=function(e){Object.entries(e).forEach((function(t){var n=t[0];void 0===t[1]&&delete e[n]})),u.options=t({debug:!1,initialOffset:0,overscan:1,paddingStart:0,paddingEnd:0,scrollPaddingStart:0,scrollPaddingEnd:0,horizontal:!1,getItemKey:r,rangeExtractor:s,onChange:function(){},measureElement:l,initialRect:{width:0,height:0},scrollMargin:0,scrollingDelay:150,indexAttribute:"data-index",initialMeasurementsCache:[]},e)},this.notify=function(){null==u.options.onChange||u.options.onChange(u)},this.cleanup=function(){u.unsubs.filter(Boolean).forEach((function(e){return e()})),u.unsubs=[],u.scrollElement=null},this._didMount=function(){var e=u.getResizeObserver();return Object.values(u.measureElementCache).forEach((function(t){return null==e?void 0:e.observe(t)})),function(){null==e||e.disconnect(),u.cleanup()}},this._willUpdate=function(){var e=u.options.getScrollElement();u.scrollElement!==e&&(u.cleanup(),u.scrollElement=e,u._scrollToOffset(u.scrollOffset,{adjustments:void 0,behavior:void 0}),u.unsubs.push(u.options.observeElementRect(u,(function(e){var t=u.scrollRect;u.scrollRect=e,(u.options.horizontal?e.width!==t.width:e.height!==t.height)&&u.maybeNotify()}))),u.unsubs.push(u.options.observeElementOffset(u,(function(e){u.scrollAdjustments=0,u.scrollOffset!==e&&(null!==u.isScrollingTimeoutId&&(clearTimeout(u.isScrollingTimeoutId),u.isScrollingTimeoutId=null),u.isScrolling=!0,u.scrollDirection=u.scrollOffset<e?"forward":"backward",u.scrollOffset=e,u.maybeNotify(),u.isScrollingTimeoutId=setTimeout((function(){u.isScrollingTimeoutId=null,u.isScrolling=!1,u.scrollDirection=null,u.maybeNotify()}),u.options.scrollingDelay))}))))},this.getSize=function(){return u.scrollRect[u.options.horizontal?"width":"height"]},this.getMeasurements=n((function(){return[u.options.count,u.options.paddingStart,u.options.scrollMargin,u.options.getItemKey,u.itemSizeCache]}),(function(e,t,n,o,i){var r=u.pendingMeasuredCacheIndexes.length>0?Math.min.apply(Math,u.pendingMeasuredCacheIndexes):0;u.pendingMeasuredCacheIndexes=[];for(var s=u.measurementsCache.slice(0,r),l=r;l<e;l++){var a=o(l),c=i[a],d=s[l-1]?s[l-1].end:t+n,f="number"==typeof c?c:u.options.estimateSize(l),h=d+f;s[l]={index:l,start:d,size:f,end:h,key:a}}return u.measurementsCache=s,s}),{key:!1,debug:function(){return u.options.debug}}),this.calculateRange=n((function(){return[u.getMeasurements(),u.getSize(),u.scrollOffset]}),(function(e,t,n){return u.range=function(e){var t=e.measurements,n=e.outerSize,o=e.scrollOffset,i=t.length-1,r=function(e,t,n,o){for(;e<=t;){var i=(e+t)/2|0,r=n(i);if(r<o)e=i+1;else{if(!(r>o))return i;t=i-1}}return e>0?e-1:0}(0,i,(function(e){return t[e].start}),o),s=r;for(;s<i&&t[s].end<o+n;)s++;return{startIndex:r,endIndex:s}}({measurements:e,outerSize:t,scrollOffset:n})}),{key:!1,debug:function(){return u.options.debug}}),this.maybeNotify=n((function(){return[].concat(Object.values(u.calculateRange()),[u.isScrolling])}),(function(){u.notify()}),{key:!1,debug:function(){return u.options.debug},initialDeps:[].concat(Object.values(this.range),[this.isScrolling])}),this.getIndexes=n((function(){return[u.options.rangeExtractor,u.calculateRange(),u.options.overscan,u.options.count]}),(function(e,n,o,i){return e(t({},n,{overscan:o,count:i}))}),{key:!1,debug:function(){return u.options.debug}}),this.indexFromElement=function(e){var t=u.options.indexAttribute,n=e.getAttribute(t);return n?parseInt(n,10):(console.warn("Missing attribute name '"+t+"={index}' on measured element."),-1)},this._measureElement=function(e,n){var o,i=u.indexFromElement(e),r=u.measurementsCache[i];if(r){var s=u.measureElementCache[r.key],l=u.getResizeObserver();if(!e.isConnected)return null==l||l.unobserve(e),void(e===s&&delete u.measureElementCache[r.key]);if(s!==e)s&&(null==l||l.unobserve(s)),null==l||l.observe(e),u.measureElementCache[r.key]=e;else if(!n&&!s.__virtualizerSkipFirstNotSync)return void(s.__virtualizerSkipFirstNotSync=!0);var a,c=u.options.measureElement(e,u),d=c-(null!=(o=u.itemSizeCache[r.key])?o:r.size);if(0!==d)r.start<u.scrollOffset&&u._scrollToOffset(u.scrollOffset,{adjustments:u.scrollAdjustments+=d,behavior:void 0}),u.pendingMeasuredCacheIndexes.push(i),u.itemSizeCache=t({},u.itemSizeCache,((a={})[r.key]=c,a)),u.notify()}},this.measureElement=function(e){e&&u._measureElement(e,!0)},this.getVirtualItems=n((function(){return[u.getIndexes(),u.getMeasurements()]}),(function(e,t){for(var n=[],o=0,i=e.length;o<i;o++){var r=t[e[o]];n.push(r)}return n}),{key:!1,debug:function(){return u.options.debug}}),this.getOffsetForAlignment=function(e,t){var n=u.getSize();"auto"===t&&(t=e<=u.scrollOffset?"start":e>=u.scrollOffset+n?"end":"start"),"start"===t||("end"===t?e-=n:"center"===t&&(e-=n/2));var o=u.options.horizontal?"scrollWidth":"scrollHeight",i=(u.scrollElement?"document"in u.scrollElement?u.scrollElement.document.documentElement[o]:u.scrollElement[o]:0)-u.getSize();return Math.max(Math.min(i,e),0)},this.getOffsetForIndex=function(e,t){void 0===t&&(t="auto"),e=Math.max(0,Math.min(e,u.options.count-1));var n=o(u.getMeasurements()[e]);if("auto"===t)if(n.end>=u.scrollOffset+u.getSize()-u.options.scrollPaddingEnd)t="end";else{if(!(n.start<=u.scrollOffset+u.options.scrollPaddingStart))return[u.scrollOffset,t];t="start"}var i="end"===t?n.end+u.options.scrollPaddingEnd:n.start-u.options.scrollPaddingStart;return[u.getOffsetForAlignment(i,t),t]},this.isDynamicMode=function(){return Object.keys(u.measureElementCache).length>0},this.cancelScrollToIndex=function(){null!==u.scrollToIndexTimeoutId&&(clearTimeout(u.scrollToIndexTimeoutId),u.scrollToIndexTimeoutId=null)},this.scrollToOffset=function(e,t){var n=void 0===t?{}:t,o=n.align,i=void 0===o?"start":o,r=n.behavior;u.cancelScrollToIndex(),"smooth"===r&&u.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size."),u._scrollToOffset(u.getOffsetForAlignment(e,i),{adjustments:void 0,behavior:r})},this.scrollToIndex=function(e,t){var n=void 0===t?{}:t,o=n.align,r=void 0===o?"auto":o,s=n.behavior;e=Math.max(0,Math.min(e,u.options.count-1)),u.cancelScrollToIndex(),"smooth"===s&&u.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size.");var l=u.getOffsetForIndex(e,r),a=l[0],c=l[1];u._scrollToOffset(a,{adjustments:void 0,behavior:s}),"smooth"!==s&&u.isDynamicMode()&&(u.scrollToIndexTimeoutId=setTimeout((function(){if(u.scrollToIndexTimeoutId=null,!!u.measureElementCache[u.options.getItemKey(e)]){var t=u.getOffsetForIndex(e,c)[0];i(t,u.scrollOffset)||u.scrollToIndex(e,{align:c,behavior:s})}else u.scrollToIndex(e,{align:c,behavior:s})})))},this.scrollBy=function(e,t){var n=(void 0===t?{}:t).behavior;u.cancelScrollToIndex(),"smooth"===n&&u.isDynamicMode()&&console.warn("The `smooth` scroll behavior is not fully supported with dynamic size."),u._scrollToOffset(u.scrollOffset+e,{adjustments:void 0,behavior:n})},this.getTotalSize=function(){var e;return((null==(e=u.getMeasurements()[u.options.count-1])?void 0:e.end)||u.options.paddingStart)-u.options.scrollMargin+u.options.paddingEnd},this._scrollToOffset=function(e,t){var n=t.adjustments,o=t.behavior;u.options.scrollToFn(e,{behavior:o,adjustments:n},u)},this.measure=function(){u.itemSizeCache={},u.notify()},this.setOptions(e),this.scrollRect=this.options.initialRect,this.scrollOffset=this.options.initialOffset,this.measurementsCache=this.options.initialMeasurementsCache,this.measurementsCache.forEach((function(e){u.itemSizeCache[e.key]=e.size})),this.maybeNotify()},e.approxEqual=i,e.defaultKeyExtractor=r,e.defaultRangeExtractor=s,e.elementScroll=function(e,t,n){var o,i,r=t.adjustments,s=void 0===r?0:r,l=t.behavior,a=e+s;null==(o=n.scrollElement)||null==o.scrollTo||o.scrollTo(((i={})[n.options.horizontal?"left":"top"]=a,i.behavior=l,i))},e.measureElement=l,e.memo=n,e.notUndefined=o,e.observeElementOffset=function(e,t){var n=e.scrollElement;if(n){var o=function(){t(n[e.options.horizontal?"scrollLeft":"scrollTop"])};return o(),n.addEventListener("scroll",o,{passive:!0}),function(){n.removeEventListener("scroll",o)}}},e.observeElementRect=function(e,t){var n=e.scrollElement;if(n){var o=function(){var e=n.getBoundingClientRect(),o=e.width,i=e.height;t({width:Math.round(o),height:Math.round(i)})};o();var i=new ResizeObserver((function(){o()}));return i.observe(n),function(){i.unobserve(n)}}},e.observeWindowOffset=function(e,t){var n=e.scrollElement;if(n){var o=function(){t(n[e.options.horizontal?"scrollX":"scrollY"])};return o(),n.addEventListener("scroll",o,{passive:!0}),function(){n.removeEventListener("scroll",o)}}},e.observeWindowRect=function(e,t){var n=e.scrollElement;if(n){var o=function(){t({width:n.innerWidth,height:n.innerHeight})};return o(),n.addEventListener("resize",o,{passive:!0}),function(){n.removeEventListener("resize",o)}}},e.windowScroll=function(e,t,n){var o,i,r=t.adjustments,s=void 0===r?0:r,l=t.behavior,a=e+s;null==(o=n.scrollElement)||null==o.scrollTo||o.scrollTo(((i={})[n.options.horizontal?"left":"top"]=a,i.behavior=l,i))},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=index.production.js.map |
{ | ||
"name": "@tanstack/virtual-core", | ||
"author": "Tanner Linsley", | ||
"version": "3.0.0-beta.44", | ||
"version": "3.0.0-beta.45", | ||
"description": "Headless UI for virtualizing scrollable elements in TS/JS + Frameworks", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
163
src/index.ts
@@ -61,70 +61,66 @@ import { approxEqual, memo, notUndefined } from './utils' | ||
const memoRectCallback = ( | ||
instance: Virtualizer<any, any>, | ||
export const observeElementRect = <T extends Element>( | ||
instance: Virtualizer<T, any>, | ||
cb: (rect: Rect) => void, | ||
) => { | ||
let prev: Rect = { height: -1, width: -1 } | ||
const element = instance.scrollElement | ||
if (!element) { | ||
return | ||
} | ||
return (rect: Rect) => { | ||
if ( | ||
instance.options.horizontal | ||
? rect.width !== prev.width | ||
: rect.height !== prev.height | ||
) { | ||
cb(rect) | ||
} | ||
const handler = () => { | ||
const { width, height } = element.getBoundingClientRect() | ||
cb({ width: Math.round(width), height: Math.round(height) }) | ||
} | ||
handler() | ||
prev = rect | ||
const observer = new ResizeObserver(() => { | ||
handler() | ||
}) | ||
observer.observe(element) | ||
return () => { | ||
observer.unobserve(element) | ||
} | ||
} | ||
export const observeElementRect = ( | ||
instance: Virtualizer<any, any>, | ||
export const observeWindowRect = ( | ||
instance: Virtualizer<Window, any>, | ||
cb: (rect: Rect) => void, | ||
) => { | ||
const observer = new ResizeObserver((entries) => { | ||
const entry = entries[0] | ||
if (entry) { | ||
const { width, height } = entry.contentRect | ||
cb({ | ||
width: Math.round(width), | ||
height: Math.round(height), | ||
}) | ||
} else { | ||
cb({ width: 0, height: 0 }) | ||
} | ||
}) | ||
if (!instance.scrollElement) { | ||
const element = instance.scrollElement | ||
if (!element) { | ||
return | ||
} | ||
cb(instance.scrollElement.getBoundingClientRect()) | ||
const handler = () => { | ||
cb({ width: element.innerWidth, height: element.innerHeight }) | ||
} | ||
handler() | ||
observer.observe(instance.scrollElement) | ||
element.addEventListener('resize', handler, { | ||
passive: true, | ||
}) | ||
return () => { | ||
observer.unobserve(instance.scrollElement) | ||
element.removeEventListener('resize', handler) | ||
} | ||
} | ||
export const observeWindowRect = ( | ||
instance: Virtualizer<any, any>, | ||
cb: (rect: Rect) => void, | ||
export const observeElementOffset = <T extends Element>( | ||
instance: Virtualizer<T, any>, | ||
cb: (offset: number) => void, | ||
) => { | ||
const memoizedCallback = memoRectCallback(instance, cb) | ||
const onResize = () => | ||
memoizedCallback({ | ||
width: instance.scrollElement.innerWidth, | ||
height: instance.scrollElement.innerHeight, | ||
}) | ||
if (!instance.scrollElement) { | ||
const element = instance.scrollElement | ||
if (!element) { | ||
return | ||
} | ||
onResize() | ||
const handler = () => { | ||
cb(element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop']) | ||
} | ||
handler() | ||
instance.scrollElement.addEventListener('resize', onResize, { | ||
capture: false, | ||
element.addEventListener('scroll', handler, { | ||
passive: true, | ||
@@ -134,61 +130,29 @@ }) | ||
return () => { | ||
instance.scrollElement.removeEventListener('resize', onResize) | ||
element.removeEventListener('scroll', handler) | ||
} | ||
} | ||
type ObserverMode = 'element' | 'window' | ||
export const observeWindowOffset = ( | ||
instance: Virtualizer<Window, any>, | ||
cb: (offset: number) => void, | ||
) => { | ||
const element = instance.scrollElement | ||
if (!element) { | ||
return | ||
} | ||
const scrollProps = { | ||
element: ['scrollLeft', 'scrollTop'], | ||
window: ['scrollX', 'scrollY'], | ||
} as const | ||
const handler = () => { | ||
cb(element[instance.options.horizontal ? 'scrollX' : 'scrollY']) | ||
} | ||
handler() | ||
const createOffsetObserver = (mode: ObserverMode) => { | ||
return (instance: Virtualizer<any, any>, cb: (offset: number) => void) => { | ||
if (!instance.scrollElement) { | ||
return | ||
} | ||
element.addEventListener('scroll', handler, { | ||
passive: true, | ||
}) | ||
const propX = scrollProps[mode][0] | ||
const propY = scrollProps[mode][1] | ||
let prevX: number = instance.scrollElement[propX] | ||
let prevY: number = instance.scrollElement[propY] | ||
const scroll = () => { | ||
const offset = | ||
instance.scrollElement[instance.options.horizontal ? propX : propY] | ||
cb(offset) | ||
} | ||
scroll() | ||
const onScroll = (e: Event) => { | ||
const target = e.currentTarget as HTMLElement & Window | ||
const scrollX = target[propX] | ||
const scrollY = target[propY] | ||
if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) { | ||
scroll() | ||
} | ||
prevX = scrollX | ||
prevY = scrollY | ||
} | ||
instance.scrollElement.addEventListener('scroll', onScroll, { | ||
capture: false, | ||
passive: true, | ||
}) | ||
return () => { | ||
instance.scrollElement.removeEventListener('scroll', onScroll) | ||
} | ||
return () => { | ||
element.removeEventListener('scroll', handler) | ||
} | ||
} | ||
export const observeElementOffset = createOffsetObserver('element') | ||
export const observeWindowOffset = createOffsetObserver('window') | ||
export const measureElement = <TItemElement extends Element>( | ||
@@ -402,4 +366,11 @@ element: TItemElement, | ||
this.options.observeElementRect(this, (rect) => { | ||
const prev = this.scrollRect | ||
this.scrollRect = rect | ||
this.maybeNotify() | ||
if ( | ||
this.options.horizontal | ||
? rect.width !== prev.width | ||
: rect.height !== prev.height | ||
) { | ||
this.maybeNotify() | ||
} | ||
}), | ||
@@ -406,0 +377,0 @@ ) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
377483
3545