adf0d17497
publish / version_or_publish (push) Has been cancelled
storybook-build / changes (push) Has been cancelled
storybook-build / :storybook-build (push) Has been cancelled
Sync Gradio Skills to Hugging Face / sync-skills (push) Has been cancelled
functional / changes (push) Has been cancelled
functional / build-frontend (push) Has been cancelled
functional / functional-test-SSR=false (push) Has been cancelled
functional / functional-reload (push) Has been cancelled
js / changes (push) Has been cancelled
js / js-test (push) Has been cancelled
docs-build / changes (push) Has been cancelled
docs-build / docs-build (push) Has been cancelled
docs-build / website-build (push) Has been cancelled
functional / functional-test-SSR=true (push) Has been cancelled
hygiene / hygiene-test (push) Has been cancelled
python / changes (push) Has been cancelled
python / build (push) Has been cancelled
python / test-ubuntu-latest-flaky (push) Has been cancelled
python / test-ubuntu-latest-not-flaky (push) Has been cancelled
python / test-windows-latest-flaky (push) Has been cancelled
python / test-windows-latest-not-flaky (push) Has been cancelled
106 lines
2.3 KiB
TypeScript
106 lines
2.3 KiB
TypeScript
import {
|
|
Virtualizer,
|
|
elementScroll,
|
|
observeElementOffset,
|
|
observeElementRect,
|
|
type PartialKeys,
|
|
type VirtualizerOptions
|
|
} from "@tanstack/virtual-core";
|
|
import { untrack } from "svelte";
|
|
|
|
export type { VirtualItem } from "@tanstack/virtual-core";
|
|
|
|
/**
|
|
* Creates a reactive TanStack Virtualizer for Svelte 5.
|
|
*
|
|
* Returns a getter function that returns the virtualizer instance.
|
|
* Call the getter inside $derived or template expressions to create
|
|
* reactive dependencies on the virtualizer state.
|
|
*/
|
|
export function createSvelteVirtualizer<
|
|
TScrollElement extends Element,
|
|
TItemElement extends Element
|
|
>(
|
|
options: PartialKeys<
|
|
VirtualizerOptions<TScrollElement, TItemElement>,
|
|
"observeElementRect" | "observeElementOffset" | "scrollToFn"
|
|
>
|
|
): {
|
|
instance: Virtualizer<TScrollElement, TItemElement>;
|
|
virtualItems: () => ReturnType<
|
|
Virtualizer<TScrollElement, TItemElement>["getVirtualItems"]
|
|
>;
|
|
totalSize: () => number;
|
|
} {
|
|
let version = $state(0);
|
|
|
|
const virtualizer = new Virtualizer<TScrollElement, TItemElement>({
|
|
observeElementRect: observeElementRect,
|
|
observeElementOffset: observeElementOffset,
|
|
scrollToFn: elementScroll,
|
|
...options,
|
|
onChange: (instance, sync) => {
|
|
if (sync) {
|
|
version += 1;
|
|
} else {
|
|
queueMicrotask(() => {
|
|
version += 1;
|
|
});
|
|
}
|
|
options.onChange?.(instance, sync);
|
|
}
|
|
});
|
|
|
|
$effect(() => {
|
|
const cleanup = virtualizer._didMount();
|
|
untrack(() => {
|
|
version += 1;
|
|
});
|
|
return cleanup;
|
|
});
|
|
|
|
let prev_count = 0;
|
|
|
|
$effect(() => {
|
|
const current_count = options.count;
|
|
virtualizer.setOptions({
|
|
observeElementRect: observeElementRect,
|
|
observeElementOffset: observeElementOffset,
|
|
scrollToFn: elementScroll,
|
|
...options,
|
|
onChange: (instance, sync) => {
|
|
if (sync) {
|
|
version += 1;
|
|
} else {
|
|
queueMicrotask(() => {
|
|
version += 1;
|
|
});
|
|
}
|
|
options.onChange?.(instance, sync);
|
|
}
|
|
});
|
|
|
|
if (prev_count === 0 && current_count > 0) {
|
|
virtualizer.measure();
|
|
}
|
|
prev_count = current_count;
|
|
});
|
|
|
|
$effect.pre(() => {
|
|
void version;
|
|
virtualizer._willUpdate();
|
|
});
|
|
|
|
return {
|
|
instance: virtualizer,
|
|
virtualItems: () => {
|
|
void version;
|
|
return virtualizer.getVirtualItems();
|
|
},
|
|
totalSize: () => {
|
|
void version;
|
|
return virtualizer.getTotalSize();
|
|
}
|
|
};
|
|
}
|