Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@tanstack/virtual-core

Package Overview
Dependencies
Maintainers
2
Versions
87
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tanstack/virtual-core - npm Package Compare versions

Comparing version 3.3.0 to 3.4.0

11

dist/esm/index.d.ts

@@ -34,4 +34,4 @@ export * from './utils.js';

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 observeElementOffset: <T extends Element>(instance: Virtualizer<T, any>, cb: (offset: number, isScrolling: boolean) => void) => (() => void) | undefined;
export declare const observeWindowOffset: (instance: Virtualizer<Window, any>, cb: (offset: number, isScrolling: boolean) => void) => (() => void) | undefined;
export declare const measureElement: <TItemElement extends Element>(element: TItemElement, entry: ResizeObserverEntry | undefined, instance: Virtualizer<any, TItemElement>) => number;

@@ -55,3 +55,3 @@ export declare const windowScroll: <T extends Window>(offset: number, { adjustments, behavior, }: {

observeElementRect: (instance: Virtualizer<TScrollElement, TItemElement>, cb: (rect: Rect) => void) => void | (() => void);
observeElementOffset: (instance: Virtualizer<TScrollElement, TItemElement>, cb: (offset: number) => void) => void | (() => void);
observeElementOffset: (instance: Virtualizer<TScrollElement, TItemElement>, cb: (offset: number, isScrolling: boolean) => void) => void | (() => void);
debug?: any;

@@ -72,3 +72,2 @@ initialRect?: Rect;

gap?: number;
scrollingDelay?: number;
indexAttribute?: string;

@@ -83,3 +82,2 @@ initialMeasurementsCache?: VirtualItem[];

isScrolling: boolean;
private isScrollingTimeoutId;
private scrollToIndexTimeoutId;

@@ -103,3 +101,2 @@ measurementsCache: VirtualItem[];

private notify;
private maybeNotify;
private cleanup;

@@ -109,3 +106,3 @@ _didMount: () => () => void;

private getSize;
private memoOptions;
private getMeasurementOptions;
private getFurthestMeasurement;

@@ -112,0 +109,0 @@ private getMeasurements;

@@ -1,2 +0,2 @@

import { memo, notUndefined, approxEqual } from "./utils.js";
import { memo, notUndefined, approxEqual, debounce } from "./utils.js";
const defaultKeyExtractor = (index) => index;

@@ -42,2 +42,5 @@ const defaultRangeExtractor = (range) => {

};
const addEventListenerOptions = {
passive: true
};
const observeWindowRect = (instance, cb) => {

@@ -52,5 +55,3 @@ const element = instance.scrollElement;

handler();
element.addEventListener("resize", handler, {
passive: true
});
element.addEventListener("resize", handler, addEventListenerOptions);
return () => {

@@ -60,2 +61,3 @@ element.removeEventListener("resize", handler);

};
const supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
const observeElementOffset = (instance, cb) => {

@@ -66,11 +68,19 @@ const element = instance.scrollElement;

}
const handler = () => {
cb(element[instance.options.horizontal ? "scrollLeft" : "scrollTop"]);
let offset = 0;
const fallback = supportsScrollend ? () => void 0 : debounce(() => {
cb(offset, false);
}, 150);
const createHandler = (isScrolling) => () => {
offset = element[instance.options.horizontal ? "scrollLeft" : "scrollTop"];
fallback();
cb(offset, isScrolling);
};
handler();
element.addEventListener("scroll", handler, {
passive: true
});
const handler = createHandler(true);
const endHandler = createHandler(false);
endHandler();
element.addEventListener("scroll", handler, addEventListenerOptions);
element.addEventListener("scrollend", endHandler, addEventListenerOptions);
return () => {
element.removeEventListener("scroll", handler);
element.removeEventListener("scrollend", endHandler);
};

@@ -83,11 +93,19 @@ };

}
const handler = () => {
cb(element[instance.options.horizontal ? "scrollX" : "scrollY"]);
let offset = 0;
const fallback = supportsScrollend ? () => void 0 : debounce(() => {
cb(offset, false);
}, 150);
const createHandler = (isScrolling) => () => {
offset = element[instance.options.horizontal ? "scrollX" : "scrollY"];
fallback();
cb(offset, isScrolling);
};
handler();
element.addEventListener("scroll", handler, {
passive: true
});
const handler = createHandler(true);
const endHandler = createHandler(false);
endHandler();
element.addEventListener("scroll", handler, addEventListenerOptions);
element.addEventListener("scrollend", endHandler, addEventListenerOptions);
return () => {
element.removeEventListener("scroll", handler);
element.removeEventListener("scrollend", endHandler);
};

@@ -136,3 +154,2 @@ };

this.isScrolling = false;
this.isScrollingTimeoutId = null;
this.scrollToIndexTimeoutId = null;

@@ -198,3 +215,2 @@ this.measurementsCache = [];

gap: 0,
scrollingDelay: 150,
indexAttribute: "data-index",

@@ -206,28 +222,13 @@ initialMeasurementsCache: [],

};
this.notify = (sync) => {
this.notify = (force, sync) => {
var _a, _b;
(_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);
const { startIndex, endIndex } = this.range ?? {
startIndex: void 0,
endIndex: void 0
};
const range = this.calculateRange();
if (force || startIndex !== (range == null ? void 0 : range.startIndex) || endIndex !== (range == null ? void 0 : range.endIndex)) {
(_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);
}
};
this.maybeNotify = memo(
() => {
this.calculateRange();
return [
this.isScrolling,
this.range ? this.range.startIndex : null,
this.range ? this.range.endIndex : null
];
},
(isScrolling) => {
this.notify(isScrolling);
},
{
key: process.env.NODE_ENV !== "production" && "maybeNotify",
debug: () => this.options.debug,
initialDeps: [
this.isScrolling,
this.range ? this.range.startIndex : null,
this.range ? this.range.endIndex : null
]
}
);
this.cleanup = () => {

@@ -257,25 +258,13 @@ this.unsubs.filter(Boolean).forEach((d) => d());

this.scrollRect = rect;
this.maybeNotify();
this.notify(false, false);
})
);
this.unsubs.push(
this.options.observeElementOffset(this, (offset) => {
this.options.observeElementOffset(this, (offset, isScrolling) => {
this.scrollAdjustments = 0;
if (this.scrollOffset === offset) {
return;
}
if (this.isScrollingTimeoutId !== null) {
clearTimeout(this.isScrollingTimeoutId);
this.isScrollingTimeoutId = null;
}
this.isScrolling = true;
this.scrollDirection = this.scrollOffset < offset ? "forward" : "backward";
this.scrollDirection = isScrolling ? this.scrollOffset < offset ? "forward" : "backward" : null;
this.scrollOffset = offset;
this.maybeNotify();
this.isScrollingTimeoutId = setTimeout(() => {
this.isScrollingTimeoutId = null;
this.isScrolling = false;
this.scrollDirection = null;
this.maybeNotify();
}, this.options.scrollingDelay);
const prevIsScrolling = this.isScrolling;
this.isScrolling = isScrolling;
this.notify(prevIsScrolling !== isScrolling, isScrolling);
})

@@ -288,3 +277,3 @@ );

};
this.memoOptions = memo(
this.getMeasurementOptions = memo(
() => [

@@ -337,3 +326,3 @@ this.options.count,

this.getMeasurements = memo(
() => [this.memoOptions(), this.itemSizeCache],
() => [this.getMeasurementOptions(), this.itemSizeCache],
({ count, paddingStart, scrollMargin, getItemKey }, itemSizeCache) => {

@@ -391,3 +380,4 @@ const min = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;

return range === null ? [] : rangeExtractor({
...range,
startIndex: range.startIndex,
endIndex: range.endIndex,
overscan,

@@ -450,3 +440,3 @@ count

this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));
this.notify(false);
this.notify(true, false);
}

@@ -603,4 +593,5 @@ };

this.measure = () => {
var _a, _b;
this.itemSizeCache = /* @__PURE__ */ new Map();
this.notify(false);
(_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, false);
};

@@ -614,3 +605,3 @@ this.setOptions(opts);

});
this.maybeNotify();
this.notify(false, false);
}

@@ -653,2 +644,3 @@ }

approxEqual,
debounce,
defaultKeyExtractor,

@@ -655,0 +647,0 @@ defaultRangeExtractor,

@@ -11,1 +11,2 @@ export type NoInfer<A extends any> = [A][A extends any ? 0 : never];

export declare const approxEqual: (a: number, b: number) => boolean;
export declare const debounce: (fn: Function, ms: number) => (this: any, ...args: any[]) => void;

@@ -54,4 +54,12 @@ function memo(getDeps, fn, opts) {

const approxEqual = (a, b) => Math.abs(a - b) < 1;
const debounce = (fn, ms) => {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), ms);
};
};
export {
approxEqual,
debounce,
memo,

@@ -58,0 +66,0 @@ notUndefined

{
"name": "@tanstack/virtual-core",
"version": "3.3.0",
"version": "3.4.0",
"description": "Headless UI for virtualizing scrollable elements in TS/JS + Frameworks",

@@ -5,0 +5,0 @@ "author": "Tanner Linsley",

@@ -1,2 +0,2 @@

import { approxEqual, memo, notUndefined } from './utils'
import { approxEqual, memo, notUndefined, debounce } from './utils'

@@ -101,2 +101,6 @@ export * from './utils'

const addEventListenerOptions = {
passive: true,
}
export const observeWindowRect = (

@@ -116,5 +120,3 @@ instance: Virtualizer<Window, any>,

element.addEventListener('resize', handler, {
passive: true,
})
element.addEventListener('resize', handler, addEventListenerOptions)

@@ -126,5 +128,8 @@ return () => {

const supportsScrollend =
typeof window == 'undefined' ? true : 'onscrollend' in window
export const observeElementOffset = <T extends Element>(
instance: Virtualizer<T, any>,
cb: (offset: number) => void,
cb: (offset: number, isScrolling: boolean) => void,
) => {

@@ -136,13 +141,24 @@ const element = instance.scrollElement

const handler = () => {
cb(element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop'])
let offset = 0
const fallback = supportsScrollend
? () => undefined
: debounce(() => {
cb(offset, false)
}, 150)
const createHandler = (isScrolling: boolean) => () => {
offset = element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop']
fallback()
cb(offset, isScrolling)
}
handler()
const handler = createHandler(true)
const endHandler = createHandler(false)
endHandler()
element.addEventListener('scroll', handler, {
passive: true,
})
element.addEventListener('scroll', handler, addEventListenerOptions)
element.addEventListener('scrollend', endHandler, addEventListenerOptions)
return () => {
element.removeEventListener('scroll', handler)
element.removeEventListener('scrollend', endHandler)
}

@@ -153,3 +169,3 @@ }

instance: Virtualizer<Window, any>,
cb: (offset: number) => void,
cb: (offset: number, isScrolling: boolean) => void,
) => {

@@ -161,13 +177,24 @@ const element = instance.scrollElement

const handler = () => {
cb(element[instance.options.horizontal ? 'scrollX' : 'scrollY'])
let offset = 0
const fallback = supportsScrollend
? () => undefined
: debounce(() => {
cb(offset, false)
}, 150)
const createHandler = (isScrolling: boolean) => () => {
offset = element[instance.options.horizontal ? 'scrollX' : 'scrollY']
fallback()
cb(offset, isScrolling)
}
handler()
const handler = createHandler(true)
const endHandler = createHandler(false)
endHandler()
element.addEventListener('scroll', handler, {
passive: true,
})
element.addEventListener('scroll', handler, addEventListenerOptions)
element.addEventListener('scrollend', endHandler, addEventListenerOptions)
return () => {
element.removeEventListener('scroll', handler)
element.removeEventListener('scrollend', endHandler)
}

@@ -250,3 +277,3 @@ }

instance: Virtualizer<TScrollElement, TItemElement>,
cb: (offset: number) => void,
cb: (offset: number, isScrolling: boolean) => void,
) => void | (() => void)

@@ -277,3 +304,2 @@

gap?: number
scrollingDelay?: number
indexAttribute?: string

@@ -292,3 +318,2 @@ initialMeasurementsCache?: VirtualItem[]

isScrolling: boolean = false
private isScrollingTimeoutId: ReturnType<typeof setTimeout> | null = null
private scrollToIndexTimeoutId: ReturnType<typeof setTimeout> | null = null

@@ -348,3 +373,3 @@ measurementsCache: VirtualItem[] = []

this.maybeNotify()
this.notify(false, false)
}

@@ -373,3 +398,2 @@

gap: 0,
scrollingDelay: 150,
indexAttribute: 'data-index',

@@ -382,30 +406,18 @@ initialMeasurementsCache: [],

private notify = (sync: boolean) => {
this.options.onChange?.(this, sync)
private notify = (force: boolean, sync: boolean) => {
const { startIndex, endIndex } = this.range ?? {
startIndex: undefined,
endIndex: undefined,
}
const range = this.calculateRange()
if (
force ||
startIndex !== range?.startIndex ||
endIndex !== range?.endIndex
) {
this.options.onChange?.(this, sync)
}
}
private maybeNotify = memo(
() => {
this.calculateRange()
return [
this.isScrolling,
this.range ? this.range.startIndex : null,
this.range ? this.range.endIndex : null,
]
},
(isScrolling) => {
this.notify(isScrolling)
},
{
key: process.env.NODE_ENV !== 'production' && 'maybeNotify',
debug: () => this.options.debug,
initialDeps: [
this.isScrolling,
this.range ? this.range.startIndex : null,
this.range ? this.range.endIndex : null,
] as [boolean, number | null, number | null],
},
)
private cleanup = () => {

@@ -441,3 +453,3 @@ this.unsubs.filter(Boolean).forEach((d) => d!())

this.scrollRect = rect
this.maybeNotify()
this.notify(false, false)
}),

@@ -447,28 +459,15 @@ )

this.unsubs.push(
this.options.observeElementOffset(this, (offset) => {
this.options.observeElementOffset(this, (offset, isScrolling) => {
this.scrollAdjustments = 0
if (this.scrollOffset === offset) {
return
}
if (this.isScrollingTimeoutId !== null) {
clearTimeout(this.isScrollingTimeoutId)
this.isScrollingTimeoutId = null
}
this.isScrolling = true
this.scrollDirection =
this.scrollOffset < offset ? 'forward' : 'backward'
this.scrollDirection = isScrolling
? this.scrollOffset < offset
? 'forward'
: 'backward'
: null
this.scrollOffset = offset
this.maybeNotify()
const prevIsScrolling = this.isScrolling
this.isScrolling = isScrolling
this.isScrollingTimeoutId = setTimeout(() => {
this.isScrollingTimeoutId = null
this.isScrolling = false
this.scrollDirection = null
this.maybeNotify()
}, this.options.scrollingDelay)
this.notify(prevIsScrolling !== isScrolling, isScrolling)
}),

@@ -483,3 +482,3 @@ )

private memoOptions = memo(
private getMeasurementOptions = memo(
() => [

@@ -547,3 +546,3 @@ this.options.count,

private getMeasurements = memo(
() => [this.memoOptions(), this.itemSizeCache],
() => [this.getMeasurementOptions(), this.itemSizeCache],
({ count, paddingStart, scrollMargin, getItemKey }, itemSizeCache) => {

@@ -631,3 +630,4 @@ const min =

: rangeExtractor({
...range,
startIndex: range.startIndex,
endIndex: range.endIndex,
overscan,

@@ -711,3 +711,3 @@ count,

this.notify(false)
this.notify(true, false)
}

@@ -939,3 +939,3 @@ }

this.itemSizeCache = new Map()
this.notify(false)
this.options.onChange?.(this, false)
}

@@ -942,0 +942,0 @@ }

@@ -80,1 +80,9 @@ export type NoInfer<A extends any> = [A][A extends any ? 0 : never]

export const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1
export const debounce = (fn: Function, ms: number) => {
let timeoutId: ReturnType<typeof setTimeout>
return function (this: any, ...args: any[]) {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => fn.apply(this, args), ms)
}
}

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc