@tanstack/angular-virtual
Version:
Headless UI for virtualizing scrollable elements in Angular
140 lines (139 loc) • 4.52 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const core = require("@angular/core");
const virtualCore = require("@tanstack/virtual-core");
const proxy = require("./proxy.cjs");
function injectScheduleDomFlushViaAppRefTick() {
const appRef = core.inject(core.ApplicationRef);
const destroyRef = core.inject(core.DestroyRef);
let hostDestroyed = false;
destroyRef.onDestroy(() => {
hostDestroyed = true;
});
let domFlushQueued = false;
return () => {
if (domFlushQueued) return;
domFlushQueued = true;
queueMicrotask(() => {
domFlushQueued = false;
if (hostDestroyed) return;
appRef.tick();
});
};
}
function injectVirtualizerBase(options, extensions = {}) {
let injector = extensions.injector;
if (!injector) {
core.assertInInjectionContext(injectVirtualizerBase);
injector = core.inject(core.Injector);
}
return core.runInInjectionContext(injector, () => {
const scheduleDomFlush = injectScheduleDomFlushViaAppRefTick();
const resolvedOptions = core.computed(() => {
const { useApplicationRefTick = true, ..._options } = options();
return {
..._options,
onChange: (instance, sync) => {
var _a;
reactiveVirtualizer.set(instance);
if (useApplicationRefTick) {
scheduleDomFlush();
}
(_a = _options.onChange) == null ? void 0 : _a.call(_options, instance, sync);
}
};
});
const lazyVirtualizer = core.computed(
() => new virtualCore.Virtualizer(core.untracked(resolvedOptions))
);
const reactiveVirtualizer = core.linkedSignal(
() => {
const virtualizer = lazyVirtualizer();
virtualizer.setOptions(resolvedOptions());
return virtualizer;
},
{ equal: () => false }
);
core.afterRenderEffect((cleanup) => {
cleanup(lazyVirtualizer()._didMount());
});
core.afterRenderEffect(() => {
reactiveVirtualizer()._willUpdate();
});
return proxy.signalProxy(
reactiveVirtualizer,
// Methods that pass through: call on the instance without tracking the signal read
[
"_didMount",
"_willUpdate",
"calculateRange",
"getVirtualIndexes",
"measure",
"measureElement",
"resizeItem",
"scrollBy",
"scrollToIndex",
"scrollToOffset",
"setOptions"
],
// Attributes that will be transformed to signals
[
"isScrolling",
"measurementsCache",
"options",
"range",
"scrollDirection",
"scrollElement",
"scrollOffset",
"scrollRect"
],
// Methods that will be tracked to the virtualizer signal
[
"getOffsetForAlignment",
"getOffsetForIndex",
"getVirtualItemForOffset",
"indexFromElement"
],
// Zero-arg methods exposed as computed signals
["getTotalSize", "getVirtualItems"]
// The rest is passed as is, and can be accessed or called before initialization
);
});
}
function injectVirtualizer(options) {
return injectVirtualizerBase(() => {
const _options = options();
return {
observeElementRect: virtualCore.observeElementRect,
observeElementOffset: virtualCore.observeElementOffset,
scrollToFn: virtualCore.elementScroll,
getScrollElement: () => {
const elementOrRef = _options.scrollElement;
return (isElementRef(elementOrRef) ? elementOrRef.nativeElement : elementOrRef) ?? null;
},
..._options
};
});
}
function isElementRef(elementOrRef) {
return elementOrRef != null && "nativeElement" in elementOrRef;
}
function injectWindowVirtualizer(options) {
return injectVirtualizerBase(() => ({
getScrollElement: () => typeof document !== "undefined" ? window : null,
observeElementRect: virtualCore.observeWindowRect,
observeElementOffset: virtualCore.observeWindowOffset,
scrollToFn: virtualCore.windowScroll,
initialOffset: () => typeof document !== "undefined" ? window.scrollY : 0,
...options()
}));
}
exports.injectVirtualizer = injectVirtualizer;
exports.injectWindowVirtualizer = injectWindowVirtualizer;
Object.keys(virtualCore).forEach((k) => {
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
enumerable: true,
get: () => virtualCore[k]
});
});
//# sourceMappingURL=index.cjs.map