@pyreon/virtual 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["elementScroll","Virtualizer","observeWindowRect","observeWindowOffset","windowScroll","Virtualizer"],"sources":["../src/use-virtualizer.ts","../src/use-window-virtualizer.ts"],"sourcesContent":["import { onMount, onUnmount } from '@pyreon/core'\nimport type { Signal } from '@pyreon/reactivity'\nimport { batch, effect, signal } from '@pyreon/reactivity'\nimport {\n elementScroll,\n observeElementOffset,\n observeElementRect,\n type VirtualItem,\n Virtualizer,\n type VirtualizerOptions,\n} from '@tanstack/virtual-core'\n\nexport type UseVirtualizerOptions<\n TScrollElement extends Element,\n TItemElement extends Element,\n> = () => Omit<\n VirtualizerOptions<TScrollElement, TItemElement>,\n 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'\n> &\n Partial<\n Pick<\n VirtualizerOptions<TScrollElement, TItemElement>,\n 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'\n >\n >\n\nexport interface UseVirtualizerResult<\n TScrollElement extends Element,\n TItemElement extends Element,\n> {\n /** The virtualizer instance — read to access all methods. */\n instance: Virtualizer<TScrollElement, TItemElement>\n /** Reactive signal of currently visible virtual items. */\n virtualItems: Signal<VirtualItem[]>\n /** Reactive signal of the total scrollable size in pixels. */\n totalSize: Signal<number>\n /** Reactive signal indicating whether the user is scrolling. */\n isScrolling: Signal<boolean>\n}\n\n/**\n * Create a reactive TanStack Virtual virtualizer for element-based scrolling.\n *\n * Options are passed as a function so reactive signals (e.g. count, estimateSize)\n * can be read inside, and the virtualizer updates automatically when they change.\n *\n * @example\n * const parentRef = signal<HTMLDivElement | null>(null)\n * const virtual = useVirtualizer(() => ({\n * count: 10000,\n * getScrollElement: () => parentRef(),\n * estimateSize: () => 35,\n * }))\n * // virtual.virtualItems() — array of visible VirtualItem\n * // virtual.totalSize() — total height/width for the inner container\n */\nexport function useVirtualizer<\n TScrollElement extends Element,\n TItemElement extends Element,\n>(\n options: UseVirtualizerOptions<TScrollElement, TItemElement>,\n): UseVirtualizerResult<TScrollElement, TItemElement> {\n const resolvedOptions: VirtualizerOptions<TScrollElement, TItemElement> = {\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll,\n ...options(),\n }\n\n const virtualItems = signal<VirtualItem[]>([])\n const totalSize = signal(0)\n const isScrolling = signal(false)\n\n // Store latest user options so onChange always reads the freshest reference\n let latestUserOpts = options()\n\n const instance = new Virtualizer<TScrollElement, TItemElement>(\n resolvedOptions,\n )\n\n // Track reactive options: when signals inside options() change, update the virtualizer.\n const effectCleanup = effect(() => {\n latestUserOpts = options()\n instance.setOptions({\n ...instance.options,\n ...latestUserOpts,\n onChange: (inst, sync) => {\n batch(() => {\n virtualItems.set(inst.getVirtualItems())\n totalSize.set(inst.getTotalSize())\n isScrolling.set(inst.isScrolling)\n })\n // Read latest opts to avoid stale closure\n latestUserOpts.onChange?.(inst, sync)\n },\n })\n\n // After updating options, recalculate and re-emit\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n })\n\n // Lifecycle: mount observers, clean up on unmount.\n let mountCleanup: (() => void) | undefined\n onMount(() => {\n mountCleanup = instance._didMount()\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n return undefined\n })\n\n onUnmount(() => {\n effectCleanup.dispose()\n mountCleanup?.()\n })\n\n return { instance, virtualItems, totalSize, isScrolling }\n}\n","import { onMount, onUnmount } from '@pyreon/core'\nimport type { Signal } from '@pyreon/reactivity'\nimport { batch, effect, signal } from '@pyreon/reactivity'\nimport {\n observeWindowOffset,\n observeWindowRect,\n type VirtualItem,\n Virtualizer,\n type VirtualizerOptions,\n windowScroll,\n} from '@tanstack/virtual-core'\n\nexport type UseWindowVirtualizerOptions<TItemElement extends Element> =\n () => Omit<\n VirtualizerOptions<Window, TItemElement>,\n | 'observeElementRect'\n | 'observeElementOffset'\n | 'scrollToFn'\n | 'getScrollElement'\n > &\n Partial<\n Pick<\n VirtualizerOptions<Window, TItemElement>,\n 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'\n >\n >\n\nexport interface UseWindowVirtualizerResult<TItemElement extends Element> {\n instance: Virtualizer<Window, TItemElement>\n virtualItems: Signal<VirtualItem[]>\n totalSize: Signal<number>\n isScrolling: Signal<boolean>\n}\n\n/**\n * Create a reactive TanStack Virtual virtualizer for window-based scrolling.\n *\n * @example\n * const virtual = useWindowVirtualizer(() => ({\n * count: 10000,\n * estimateSize: () => 35,\n * }))\n */\nexport function useWindowVirtualizer<TItemElement extends Element>(\n options: UseWindowVirtualizerOptions<TItemElement>,\n): UseWindowVirtualizerResult<TItemElement> {\n const virtualItems = signal<VirtualItem[]>([])\n const totalSize = signal(0)\n const isScrolling = signal(false)\n\n const resolvedOptions: VirtualizerOptions<Window, TItemElement> = {\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: typeof document !== 'undefined' ? window.scrollY : 0,\n getScrollElement: () =>\n typeof window !== 'undefined' ? window : (null as unknown as Window),\n ...options(),\n }\n\n // Store latest user options so onChange always reads the freshest reference\n let latestUserOpts = options()\n\n const instance = new Virtualizer<Window, TItemElement>(resolvedOptions)\n\n const effectCleanup = effect(() => {\n latestUserOpts = options()\n instance.setOptions({\n ...instance.options,\n ...latestUserOpts,\n onChange: (inst, sync) => {\n batch(() => {\n virtualItems.set(inst.getVirtualItems())\n totalSize.set(inst.getTotalSize())\n isScrolling.set(inst.isScrolling)\n })\n // Read latest opts to avoid stale closure\n latestUserOpts.onChange?.(inst, sync)\n },\n })\n\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n })\n\n let mountCleanup: (() => void) | undefined\n onMount(() => {\n mountCleanup = instance._didMount()\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n return undefined\n })\n\n onUnmount(() => {\n effectCleanup.dispose()\n mountCleanup?.()\n })\n\n return { instance, virtualItems, totalSize, isScrolling }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwDA,SAAgB,eAId,SACoD;CACpD,MAAM,kBAAoE;EACxE;EACA;EACA,YAAYA;EACZ,GAAG,SAAS;EACb;CAED,MAAM,eAAe,OAAsB,EAAE,CAAC;CAC9C,MAAM,YAAY,OAAO,EAAE;CAC3B,MAAM,cAAc,OAAO,MAAM;CAGjC,IAAI,iBAAiB,SAAS;CAE9B,MAAM,WAAW,IAAIC,cACnB,gBACD;CAGD,MAAM,gBAAgB,aAAa;AACjC,mBAAiB,SAAS;AAC1B,WAAS,WAAW;GAClB,GAAG,SAAS;GACZ,GAAG;GACH,WAAW,MAAM,SAAS;AACxB,gBAAY;AACV,kBAAa,IAAI,KAAK,iBAAiB,CAAC;AACxC,eAAU,IAAI,KAAK,cAAc,CAAC;AAClC,iBAAY,IAAI,KAAK,YAAY;MACjC;AAEF,mBAAe,WAAW,MAAM,KAAK;;GAExC,CAAC;AAGF,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GACF;CAGF,IAAI;AACJ,eAAc;AACZ,iBAAe,SAAS,WAAW;AACnC,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GAEF;AAEF,iBAAgB;AACd,gBAAc,SAAS;AACvB,kBAAgB;GAChB;AAEF,QAAO;EAAE;EAAU;EAAc;EAAW;EAAa;;;;;;;;;;;;;;AC/E3D,SAAgB,qBACd,SAC0C;CAC1C,MAAM,eAAe,OAAsB,EAAE,CAAC;CAC9C,MAAM,YAAY,OAAO,EAAE;CAC3B,MAAM,cAAc,OAAO,MAAM;CAEjC,MAAM,kBAA4D;EAChE,oBAAoBC;EACpB,sBAAsBC;EACtB,YAAYC;EACZ,eAAe,OAAO,aAAa,cAAc,OAAO,UAAU;EAClE,wBACE,OAAO,WAAW,cAAc,SAAU;EAC5C,GAAG,SAAS;EACb;CAGD,IAAI,iBAAiB,SAAS;CAE9B,MAAM,WAAW,IAAIC,cAAkC,gBAAgB;CAEvE,MAAM,gBAAgB,aAAa;AACjC,mBAAiB,SAAS;AAC1B,WAAS,WAAW;GAClB,GAAG,SAAS;GACZ,GAAG;GACH,WAAW,MAAM,SAAS;AACxB,gBAAY;AACV,kBAAa,IAAI,KAAK,iBAAiB,CAAC;AACxC,eAAU,IAAI,KAAK,cAAc,CAAC;AAClC,iBAAY,IAAI,KAAK,YAAY;MACjC;AAEF,mBAAe,WAAW,MAAM,KAAK;;GAExC,CAAC;AAEF,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GACF;CAEF,IAAI;AACJ,eAAc;AACZ,iBAAe,SAAS,WAAW;AACnC,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GAEF;AAEF,iBAAgB;AACd,gBAAc,SAAS;AACvB,kBAAgB;GAChB;AAEF,QAAO;EAAE;EAAU;EAAc;EAAW;EAAa"}
1
+ {"version":3,"file":"index.js","names":["elementScroll","Virtualizer","observeWindowRect","observeWindowOffset","windowScroll","Virtualizer"],"sources":["../src/use-virtualizer.ts","../src/use-window-virtualizer.ts"],"sourcesContent":["import { onMount, onUnmount } from \"@pyreon/core\"\nimport type { Signal } from \"@pyreon/reactivity\"\nimport { batch, effect, signal } from \"@pyreon/reactivity\"\nimport {\n elementScroll,\n observeElementOffset,\n observeElementRect,\n type VirtualItem,\n Virtualizer,\n type VirtualizerOptions,\n} from \"@tanstack/virtual-core\"\n\nexport type UseVirtualizerOptions<\n TScrollElement extends Element,\n TItemElement extends Element,\n> = () => Omit<\n VirtualizerOptions<TScrollElement, TItemElement>,\n \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\"\n> &\n Partial<\n Pick<\n VirtualizerOptions<TScrollElement, TItemElement>,\n \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\"\n >\n >\n\nexport interface UseVirtualizerResult<\n TScrollElement extends Element,\n TItemElement extends Element,\n> {\n /** The virtualizer instance — read to access all methods. */\n instance: Virtualizer<TScrollElement, TItemElement>\n /** Reactive signal of currently visible virtual items. */\n virtualItems: Signal<VirtualItem[]>\n /** Reactive signal of the total scrollable size in pixels. */\n totalSize: Signal<number>\n /** Reactive signal indicating whether the user is scrolling. */\n isScrolling: Signal<boolean>\n}\n\n/**\n * Create a reactive TanStack Virtual virtualizer for element-based scrolling.\n *\n * Options are passed as a function so reactive signals (e.g. count, estimateSize)\n * can be read inside, and the virtualizer updates automatically when they change.\n *\n * @example\n * const parentRef = signal<HTMLDivElement | null>(null)\n * const virtual = useVirtualizer(() => ({\n * count: 10000,\n * getScrollElement: () => parentRef(),\n * estimateSize: () => 35,\n * }))\n * // virtual.virtualItems() — array of visible VirtualItem\n * // virtual.totalSize() — total height/width for the inner container\n */\nexport function useVirtualizer<TScrollElement extends Element, TItemElement extends Element>(\n options: UseVirtualizerOptions<TScrollElement, TItemElement>,\n): UseVirtualizerResult<TScrollElement, TItemElement> {\n const resolvedOptions: VirtualizerOptions<TScrollElement, TItemElement> = {\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll,\n ...options(),\n }\n\n const virtualItems = signal<VirtualItem[]>([])\n const totalSize = signal(0)\n const isScrolling = signal(false)\n\n // Store latest user options so onChange always reads the freshest reference\n let latestUserOpts = options()\n\n const instance = new Virtualizer<TScrollElement, TItemElement>(resolvedOptions)\n\n // Track reactive options: when signals inside options() change, update the virtualizer.\n const effectCleanup = effect(() => {\n latestUserOpts = options()\n instance.setOptions({\n ...instance.options,\n ...latestUserOpts,\n onChange: (inst, sync) => {\n batch(() => {\n virtualItems.set(inst.getVirtualItems())\n totalSize.set(inst.getTotalSize())\n isScrolling.set(inst.isScrolling)\n })\n // Read latest opts to avoid stale closure\n latestUserOpts.onChange?.(inst, sync)\n },\n })\n\n // After updating options, recalculate and re-emit\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n })\n\n // Lifecycle: mount observers, clean up on unmount.\n let mountCleanup: (() => void) | undefined\n onMount(() => {\n mountCleanup = instance._didMount()\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n return undefined\n })\n\n onUnmount(() => {\n effectCleanup.dispose()\n mountCleanup?.()\n })\n\n return { instance, virtualItems, totalSize, isScrolling }\n}\n","import { onMount, onUnmount } from \"@pyreon/core\"\nimport type { Signal } from \"@pyreon/reactivity\"\nimport { batch, effect, signal } from \"@pyreon/reactivity\"\nimport {\n observeWindowOffset,\n observeWindowRect,\n type VirtualItem,\n Virtualizer,\n type VirtualizerOptions,\n windowScroll,\n} from \"@tanstack/virtual-core\"\n\nexport type UseWindowVirtualizerOptions<TItemElement extends Element> = () => Omit<\n VirtualizerOptions<Window, TItemElement>,\n \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\" | \"getScrollElement\"\n> &\n Partial<\n Pick<\n VirtualizerOptions<Window, TItemElement>,\n \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\"\n >\n >\n\nexport interface UseWindowVirtualizerResult<TItemElement extends Element> {\n instance: Virtualizer<Window, TItemElement>\n virtualItems: Signal<VirtualItem[]>\n totalSize: Signal<number>\n isScrolling: Signal<boolean>\n}\n\n/**\n * Create a reactive TanStack Virtual virtualizer for window-based scrolling.\n *\n * @example\n * const virtual = useWindowVirtualizer(() => ({\n * count: 10000,\n * estimateSize: () => 35,\n * }))\n */\nexport function useWindowVirtualizer<TItemElement extends Element>(\n options: UseWindowVirtualizerOptions<TItemElement>,\n): UseWindowVirtualizerResult<TItemElement> {\n const virtualItems = signal<VirtualItem[]>([])\n const totalSize = signal(0)\n const isScrolling = signal(false)\n\n const resolvedOptions: VirtualizerOptions<Window, TItemElement> = {\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: typeof document !== \"undefined\" ? window.scrollY : 0,\n getScrollElement: () => (typeof window !== \"undefined\" ? window : (null as unknown as Window)),\n ...options(),\n }\n\n // Store latest user options so onChange always reads the freshest reference\n let latestUserOpts = options()\n\n const instance = new Virtualizer<Window, TItemElement>(resolvedOptions)\n\n const effectCleanup = effect(() => {\n latestUserOpts = options()\n instance.setOptions({\n ...instance.options,\n ...latestUserOpts,\n onChange: (inst, sync) => {\n batch(() => {\n virtualItems.set(inst.getVirtualItems())\n totalSize.set(inst.getTotalSize())\n isScrolling.set(inst.isScrolling)\n })\n // Read latest opts to avoid stale closure\n latestUserOpts.onChange?.(inst, sync)\n },\n })\n\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n })\n\n let mountCleanup: (() => void) | undefined\n onMount(() => {\n mountCleanup = instance._didMount()\n instance._willUpdate()\n batch(() => {\n virtualItems.set(instance.getVirtualItems())\n totalSize.set(instance.getTotalSize())\n })\n return undefined\n })\n\n onUnmount(() => {\n effectCleanup.dispose()\n mountCleanup?.()\n })\n\n return { instance, virtualItems, totalSize, isScrolling }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwDA,SAAgB,eACd,SACoD;CACpD,MAAM,kBAAoE;EACxE;EACA;EACA,YAAYA;EACZ,GAAG,SAAS;EACb;CAED,MAAM,eAAe,OAAsB,EAAE,CAAC;CAC9C,MAAM,YAAY,OAAO,EAAE;CAC3B,MAAM,cAAc,OAAO,MAAM;CAGjC,IAAI,iBAAiB,SAAS;CAE9B,MAAM,WAAW,IAAIC,cAA0C,gBAAgB;CAG/E,MAAM,gBAAgB,aAAa;AACjC,mBAAiB,SAAS;AAC1B,WAAS,WAAW;GAClB,GAAG,SAAS;GACZ,GAAG;GACH,WAAW,MAAM,SAAS;AACxB,gBAAY;AACV,kBAAa,IAAI,KAAK,iBAAiB,CAAC;AACxC,eAAU,IAAI,KAAK,cAAc,CAAC;AAClC,iBAAY,IAAI,KAAK,YAAY;MACjC;AAEF,mBAAe,WAAW,MAAM,KAAK;;GAExC,CAAC;AAGF,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GACF;CAGF,IAAI;AACJ,eAAc;AACZ,iBAAe,SAAS,WAAW;AACnC,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GAEF;AAEF,iBAAgB;AACd,gBAAc,SAAS;AACvB,kBAAgB;GAChB;AAEF,QAAO;EAAE;EAAU;EAAc;EAAW;EAAa;;;;;;;;;;;;;;AC9E3D,SAAgB,qBACd,SAC0C;CAC1C,MAAM,eAAe,OAAsB,EAAE,CAAC;CAC9C,MAAM,YAAY,OAAO,EAAE;CAC3B,MAAM,cAAc,OAAO,MAAM;CAEjC,MAAM,kBAA4D;EAChE,oBAAoBC;EACpB,sBAAsBC;EACtB,YAAYC;EACZ,eAAe,OAAO,aAAa,cAAc,OAAO,UAAU;EAClE,wBAAyB,OAAO,WAAW,cAAc,SAAU;EACnE,GAAG,SAAS;EACb;CAGD,IAAI,iBAAiB,SAAS;CAE9B,MAAM,WAAW,IAAIC,cAAkC,gBAAgB;CAEvE,MAAM,gBAAgB,aAAa;AACjC,mBAAiB,SAAS;AAC1B,WAAS,WAAW;GAClB,GAAG,SAAS;GACZ,GAAG;GACH,WAAW,MAAM,SAAS;AACxB,gBAAY;AACV,kBAAa,IAAI,KAAK,iBAAiB,CAAC;AACxC,eAAU,IAAI,KAAK,cAAc,CAAC;AAClC,iBAAY,IAAI,KAAK,YAAY;MACjC;AAEF,mBAAe,WAAW,MAAM,KAAK;;GAExC,CAAC;AAEF,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GACF;CAEF,IAAI;AACJ,eAAc;AACZ,iBAAe,SAAS,WAAW;AACnC,WAAS,aAAa;AACtB,cAAY;AACV,gBAAa,IAAI,SAAS,iBAAiB,CAAC;AAC5C,aAAU,IAAI,SAAS,cAAc,CAAC;IACtC;GAEF;AAEF,iBAAgB;AACd,gBAAc,SAAS;AACvB,kBAAgB;GAChB;AAEF,QAAO;EAAE;EAAU;EAAc;EAAW;EAAa"}
@@ -2,7 +2,7 @@ import { Range, Rect, ScrollToOptions, VirtualItem, VirtualItem as VirtualItem$1
2
2
  import { Signal } from "@pyreon/reactivity";
3
3
 
4
4
  //#region src/use-virtualizer.d.ts
5
- type UseVirtualizerOptions<TScrollElement extends Element, TItemElement extends Element> = () => Omit<VirtualizerOptions$1<TScrollElement, TItemElement>, 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'> & Partial<Pick<VirtualizerOptions$1<TScrollElement, TItemElement>, 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'>>;
5
+ type UseVirtualizerOptions<TScrollElement extends Element, TItemElement extends Element> = () => Omit<VirtualizerOptions$1<TScrollElement, TItemElement>, "observeElementRect" | "observeElementOffset" | "scrollToFn"> & Partial<Pick<VirtualizerOptions$1<TScrollElement, TItemElement>, "observeElementRect" | "observeElementOffset" | "scrollToFn">>;
6
6
  interface UseVirtualizerResult<TScrollElement extends Element, TItemElement extends Element> {
7
7
  /** The virtualizer instance — read to access all methods. */
8
8
  instance: Virtualizer$1<TScrollElement, TItemElement>;
@@ -32,7 +32,7 @@ interface UseVirtualizerResult<TScrollElement extends Element, TItemElement exte
32
32
  declare function useVirtualizer<TScrollElement extends Element, TItemElement extends Element>(options: UseVirtualizerOptions<TScrollElement, TItemElement>): UseVirtualizerResult<TScrollElement, TItemElement>;
33
33
  //#endregion
34
34
  //#region src/use-window-virtualizer.d.ts
35
- type UseWindowVirtualizerOptions<TItemElement extends Element> = () => Omit<VirtualizerOptions$1<Window, TItemElement>, 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' | 'getScrollElement'> & Partial<Pick<VirtualizerOptions$1<Window, TItemElement>, 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'>>;
35
+ type UseWindowVirtualizerOptions<TItemElement extends Element> = () => Omit<VirtualizerOptions$1<Window, TItemElement>, "observeElementRect" | "observeElementOffset" | "scrollToFn" | "getScrollElement"> & Partial<Pick<VirtualizerOptions$1<Window, TItemElement>, "observeElementRect" | "observeElementOffset" | "scrollToFn">>;
36
36
  interface UseWindowVirtualizerResult<TItemElement extends Element> {
37
37
  instance: Virtualizer$1<Window, TItemElement>;
38
38
  virtualItems: Signal<VirtualItem$1[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/use-virtualizer.ts","../../../src/use-window-virtualizer.ts"],"mappings":";;;;KAYY,qBAAA,wBACa,OAAA,uBACF,OAAA,UACb,IAAA,CACR,oBAAA,CAAmB,cAAA,EAAgB,YAAA,mEAGnC,OAAA,CACE,IAAA,CACE,oBAAA,CAAmB,cAAA,EAAgB,YAAA;AAAA,UAKxB,oBAAA,wBACQ,OAAA,uBACF,OAAA;EAhBX;EAmBV,QAAA,EAAU,aAAA,CAAY,cAAA,EAAgB,YAAA;EAnBP;EAqB/B,YAAA,EAAc,MAAA,CAAO,aAAA;EAnBA;EAqBrB,SAAA,EAAW,MAAA;EAnBwB;EAqBnC,WAAA,EAAa,MAAA;AAAA;;;;;;;;;;;;;;;;;iBAmBC,cAAA,wBACS,OAAA,uBACF,OAAA,CAAA,CAErB,OAAA,EAAS,qBAAA,CAAsB,cAAA,EAAgB,YAAA,IAC9C,oBAAA,CAAqB,cAAA,EAAgB,YAAA;;;KCjD5B,2BAAA,sBAAiD,OAAA,UACrD,IAAA,CACJ,oBAAA,CAAmB,MAAA,EAAQ,YAAA,wFAM3B,OAAA,CACE,IAAA,CACE,oBAAA,CAAmB,MAAA,EAAQ,YAAA;AAAA,UAKlB,0BAAA,sBAAgD,OAAA;EAC/D,QAAA,EAAU,aAAA,CAAY,MAAA,EAAQ,YAAA;EAC9B,YAAA,EAAc,MAAA,CAAO,aAAA;EACrB,SAAA,EAAW,MAAA;EACX,WAAA,EAAa,MAAA;AAAA;;;;;;;;;;iBAYC,oBAAA,sBAA0C,OAAA,CAAA,CACxD,OAAA,EAAS,2BAAA,CAA4B,YAAA,IACpC,0BAAA,CAA2B,YAAA"}
1
+ {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/use-virtualizer.ts","../../../src/use-window-virtualizer.ts"],"mappings":";;;;KAYY,qBAAA,wBACa,OAAA,uBACF,OAAA,UACb,IAAA,CACR,oBAAA,CAAmB,cAAA,EAAgB,YAAA,mEAGnC,OAAA,CACE,IAAA,CACE,oBAAA,CAAmB,cAAA,EAAgB,YAAA;AAAA,UAKxB,oBAAA,wBACQ,OAAA,uBACF,OAAA;EAhBX;EAmBV,QAAA,EAAU,aAAA,CAAY,cAAA,EAAgB,YAAA;EAnBP;EAqB/B,YAAA,EAAc,MAAA,CAAO,aAAA;EAnBA;EAqBrB,SAAA,EAAW,MAAA;EAnBwB;EAqBnC,WAAA,EAAa,MAAA;AAAA;;;;;;;;;;;;;;;;;iBAmBC,cAAA,wBAAsC,OAAA,uBAA8B,OAAA,CAAA,CAClF,OAAA,EAAS,qBAAA,CAAsB,cAAA,EAAgB,YAAA,IAC9C,oBAAA,CAAqB,cAAA,EAAgB,YAAA;;;KC9C5B,2BAAA,sBAAiD,OAAA,UAAiB,IAAA,CAC5E,oBAAA,CAAmB,MAAA,EAAQ,YAAA,wFAG3B,OAAA,CACE,IAAA,CACE,oBAAA,CAAmB,MAAA,EAAQ,YAAA;AAAA,UAKhB,0BAAA,sBAAgD,OAAA;EAC/D,QAAA,EAAU,aAAA,CAAY,MAAA,EAAQ,YAAA;EAC9B,YAAA,EAAc,MAAA,CAAO,aAAA;EACrB,SAAA,EAAW,MAAA;EACX,WAAA,EAAa,MAAA;AAAA;;;;;;;;;;iBAYC,oBAAA,sBAA0C,OAAA,CAAA,CACxD,OAAA,EAAS,2BAAA,CAA4B,YAAA,IACpC,0BAAA,CAA2B,YAAA"}
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@pyreon/virtual",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Pyreon adapter for TanStack Virtual",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/pyreon/fundamentals.git",
9
- "directory": "packages/virtual"
8
+ "url": "https://github.com/pyreon/pyreon.git",
9
+ "directory": "packages/fundamentals/virtual"
10
10
  },
11
11
  "homepage": "https://github.com/pyreon/fundamentals/tree/main/packages/virtual#readme",
12
12
  "bugs": {
13
- "url": "https://github.com/pyreon/fundamentals/issues"
13
+ "url": "https://github.com/pyreon/pyreon/issues"
14
14
  },
15
15
  "publishConfig": {
16
16
  "access": "public"
@@ -37,13 +37,20 @@
37
37
  "build": "vl_rolldown_build",
38
38
  "dev": "vl_rolldown_build-watch",
39
39
  "test": "vitest run",
40
- "typecheck": "tsc --noEmit"
40
+ "typecheck": "tsc --noEmit",
41
+ "lint": "biome check ."
41
42
  },
42
43
  "dependencies": {
43
44
  "@tanstack/virtual-core": "^3.0.0"
44
45
  },
45
46
  "peerDependencies": {
46
- "@pyreon/core": ">=0.7.0 <0.8.0",
47
- "@pyreon/reactivity": ">=0.7.0 <0.8.0"
47
+ "@pyreon/core": "^0.11.0",
48
+ "@pyreon/reactivity": "^0.11.0"
49
+ },
50
+ "devDependencies": {
51
+ "@happy-dom/global-registrator": "^20.8.3",
52
+ "@pyreon/core": "^0.11.0",
53
+ "@pyreon/reactivity": "^0.11.0",
54
+ "@pyreon/runtime-dom": "^0.11.0"
48
55
  }
49
56
  }
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@ export type {
7
7
  ScrollToOptions,
8
8
  VirtualItem,
9
9
  VirtualizerOptions,
10
- } from '@tanstack/virtual-core'
10
+ } from "@tanstack/virtual-core"
11
11
  export {
12
12
  defaultKeyExtractor,
13
13
  defaultRangeExtractor,
@@ -19,17 +19,17 @@ export {
19
19
  observeWindowRect,
20
20
  Virtualizer,
21
21
  windowScroll,
22
- } from '@tanstack/virtual-core'
22
+ } from "@tanstack/virtual-core"
23
23
 
24
24
  // ─── Pyreon adapter ─────────────────────────────────────────────────────────────
25
25
 
26
26
  export type {
27
27
  UseVirtualizerOptions,
28
28
  UseVirtualizerResult,
29
- } from './use-virtualizer'
30
- export { useVirtualizer } from './use-virtualizer'
29
+ } from "./use-virtualizer"
30
+ export { useVirtualizer } from "./use-virtualizer"
31
31
  export type {
32
32
  UseWindowVirtualizerOptions,
33
33
  UseWindowVirtualizerResult,
34
- } from './use-window-virtualizer'
35
- export { useWindowVirtualizer } from './use-window-virtualizer'
34
+ } from "./use-window-virtualizer"
35
+ export { useWindowVirtualizer } from "./use-window-virtualizer"
@@ -1,12 +1,12 @@
1
- import { signal } from '@pyreon/reactivity'
2
- import { mount } from '@pyreon/runtime-dom'
3
- import { useVirtualizer, useWindowVirtualizer } from '../index'
1
+ import { signal } from "@pyreon/reactivity"
2
+ import { mount } from "@pyreon/runtime-dom"
3
+ import { useVirtualizer, useWindowVirtualizer } from "../index"
4
4
 
5
5
  // ─── Helpers ──────────────────────────────────────────────────────────────────
6
6
 
7
7
  function mountWith<T>(fn: () => T): { result: T; unmount: () => void } {
8
8
  let result: T | undefined
9
- const el = document.createElement('div')
9
+ const el = document.createElement("div")
10
10
  document.body.appendChild(el)
11
11
  const Wrapper = () => {
12
12
  result = fn()
@@ -24,20 +24,20 @@ function mountWith<T>(fn: () => T): { result: T; unmount: () => void } {
24
24
 
25
25
  /** Create a mock scroll container with a known size. */
26
26
  function createScrollContainer(height = 200): HTMLDivElement {
27
- const container = document.createElement('div')
27
+ const container = document.createElement("div")
28
28
  // happy-dom doesn't have real layout, but we can set properties
29
- Object.defineProperty(container, 'offsetHeight', { value: height })
30
- Object.defineProperty(container, 'offsetWidth', { value: 300 })
31
- Object.defineProperty(container, 'scrollHeight', { value: 10000 })
32
- Object.defineProperty(container, 'clientHeight', { value: height })
29
+ Object.defineProperty(container, "offsetHeight", { value: height })
30
+ Object.defineProperty(container, "offsetWidth", { value: 300 })
31
+ Object.defineProperty(container, "scrollHeight", { value: 10000 })
32
+ Object.defineProperty(container, "clientHeight", { value: height })
33
33
  document.body.appendChild(container)
34
34
  return container
35
35
  }
36
36
 
37
37
  // ─── useVirtualizer ──────────────────────────────────────────────────────────
38
38
 
39
- describe('useVirtualizer', () => {
40
- it('creates a virtualizer with virtual items', () => {
39
+ describe("useVirtualizer", () => {
40
+ it("creates a virtualizer with virtual items", () => {
41
41
  const container = createScrollContainer()
42
42
  const { result: virt, unmount } = mountWith(() =>
43
43
  useVirtualizer(() => ({
@@ -54,7 +54,7 @@ describe('useVirtualizer', () => {
54
54
  container.remove()
55
55
  })
56
56
 
57
- it('returns correct total size', () => {
57
+ it("returns correct total size", () => {
58
58
  const container = createScrollContainer()
59
59
  const { result: virt, unmount } = mountWith(() =>
60
60
  useVirtualizer(() => ({
@@ -70,7 +70,7 @@ describe('useVirtualizer', () => {
70
70
  container.remove()
71
71
  })
72
72
 
73
- it('reactive count — updates when count signal changes', () => {
73
+ it("reactive count — updates when count signal changes", () => {
74
74
  const container = createScrollContainer()
75
75
  const count = signal(100)
76
76
  const { result: virt, unmount } = mountWith(() =>
@@ -89,7 +89,7 @@ describe('useVirtualizer', () => {
89
89
  container.remove()
90
90
  })
91
91
 
92
- it('reactive estimateSize — updates total size', () => {
92
+ it("reactive estimateSize — updates total size", () => {
93
93
  const container = createScrollContainer()
94
94
  const itemSize = signal(50)
95
95
  const { result: virt, unmount } = mountWith(() =>
@@ -110,7 +110,7 @@ describe('useVirtualizer', () => {
110
110
  container.remove()
111
111
  })
112
112
 
113
- it('exposes the virtualizer instance', () => {
113
+ it("exposes the virtualizer instance", () => {
114
114
  const container = createScrollContainer()
115
115
  const { result: virt, unmount } = mountWith(() =>
116
116
  useVirtualizer(() => ({
@@ -121,14 +121,14 @@ describe('useVirtualizer', () => {
121
121
  )
122
122
 
123
123
  expect(virt.instance).toBeDefined()
124
- expect(typeof virt.instance.scrollToIndex).toBe('function')
125
- expect(typeof virt.instance.scrollToOffset).toBe('function')
126
- expect(typeof virt.instance.measureElement).toBe('function')
124
+ expect(typeof virt.instance.scrollToIndex).toBe("function")
125
+ expect(typeof virt.instance.scrollToOffset).toBe("function")
126
+ expect(typeof virt.instance.measureElement).toBe("function")
127
127
  unmount()
128
128
  container.remove()
129
129
  })
130
130
 
131
- it('virtual items have correct structure', () => {
131
+ it("virtual items have correct structure", () => {
132
132
  const container = createScrollContainer()
133
133
  const { result: virt, unmount } = mountWith(() =>
134
134
  useVirtualizer(() => ({
@@ -141,17 +141,17 @@ describe('useVirtualizer', () => {
141
141
  const items = virt.virtualItems()
142
142
  if (items.length > 0) {
143
143
  const item = items[0]!
144
- expect(typeof item.index).toBe('number')
145
- expect(typeof item.start).toBe('number')
146
- expect(typeof item.end).toBe('number')
147
- expect(typeof item.size).toBe('number')
144
+ expect(typeof item.index).toBe("number")
145
+ expect(typeof item.start).toBe("number")
146
+ expect(typeof item.end).toBe("number")
147
+ expect(typeof item.size).toBe("number")
148
148
  expect(typeof item.key).toBeDefined()
149
149
  }
150
150
  unmount()
151
151
  container.remove()
152
152
  })
153
153
 
154
- it('overscan controls extra items rendered', () => {
154
+ it("overscan controls extra items rendered", () => {
155
155
  const container = createScrollContainer(200)
156
156
  const { result: small, unmount: unmount1 } = mountWith(() =>
157
157
  useVirtualizer(() => ({
@@ -172,15 +172,13 @@ describe('useVirtualizer', () => {
172
172
  )
173
173
 
174
174
  // More overscan = more virtual items
175
- expect(large.virtualItems().length).toBeGreaterThanOrEqual(
176
- small.virtualItems().length,
177
- )
175
+ expect(large.virtualItems().length).toBeGreaterThanOrEqual(small.virtualItems().length)
178
176
  unmount1()
179
177
  unmount2()
180
178
  container.remove()
181
179
  })
182
180
 
183
- it('gap option affects total size', () => {
181
+ it("gap option affects total size", () => {
184
182
  const container = createScrollContainer()
185
183
  const { result: noGap, unmount: unmount1 } = mountWith(() =>
186
184
  useVirtualizer(() => ({
@@ -208,7 +206,7 @@ describe('useVirtualizer', () => {
208
206
  container.remove()
209
207
  })
210
208
 
211
- it('horizontal mode works', () => {
209
+ it("horizontal mode works", () => {
212
210
  const container = createScrollContainer()
213
211
  const { result: virt, unmount } = mountWith(() =>
214
212
  useVirtualizer(() => ({
@@ -225,7 +223,7 @@ describe('useVirtualizer', () => {
225
223
  container.remove()
226
224
  })
227
225
 
228
- it('padding affects total size', () => {
226
+ it("padding affects total size", () => {
229
227
  const container = createScrollContainer()
230
228
  const { result: virt, unmount } = mountWith(() =>
231
229
  useVirtualizer(() => ({
@@ -243,7 +241,7 @@ describe('useVirtualizer', () => {
243
241
  container.remove()
244
242
  })
245
243
 
246
- it('isScrolling starts as false', () => {
244
+ it("isScrolling starts as false", () => {
247
245
  const container = createScrollContainer()
248
246
  const { result: virt, unmount } = mountWith(() =>
249
247
  useVirtualizer(() => ({
@@ -258,7 +256,7 @@ describe('useVirtualizer', () => {
258
256
  container.remove()
259
257
  })
260
258
 
261
- it('enabled: false produces empty virtual items', () => {
259
+ it("enabled: false produces empty virtual items", () => {
262
260
  const container = createScrollContainer()
263
261
  const { result: virt, unmount } = mountWith(() =>
264
262
  useVirtualizer(() => ({
@@ -275,7 +273,7 @@ describe('useVirtualizer', () => {
275
273
  container.remove()
276
274
  })
277
275
 
278
- it('onChange callback updates signals when triggered', () => {
276
+ it("onChange callback updates signals when triggered", () => {
279
277
  const container = createScrollContainer()
280
278
  const onChangeSpy = vi.fn()
281
279
  const { result: virt, unmount } = mountWith(() =>
@@ -295,15 +293,15 @@ describe('useVirtualizer', () => {
295
293
  }
296
294
 
297
295
  expect(virt.virtualItems()).toBeDefined()
298
- expect(typeof virt.totalSize()).toBe('number')
299
- expect(typeof virt.isScrolling()).toBe('boolean')
296
+ expect(typeof virt.totalSize()).toBe("number")
297
+ expect(typeof virt.isScrolling()).toBe("boolean")
300
298
  // The user's onChange should have been forwarded
301
299
  expect(onChangeSpy).toHaveBeenCalled()
302
300
  unmount()
303
301
  container.remove()
304
302
  })
305
303
 
306
- it('onChange callback works without user-provided onChange', () => {
304
+ it("onChange callback works without user-provided onChange", () => {
307
305
  const container = createScrollContainer()
308
306
  const { result: virt, unmount } = mountWith(() =>
309
307
  useVirtualizer(() => ({
@@ -328,27 +326,27 @@ describe('useVirtualizer', () => {
328
326
 
329
327
  // ─── useWindowVirtualizer ─────────────────────────────────────────────────────
330
328
 
331
- describe('useWindowVirtualizer', () => {
329
+ describe("useWindowVirtualizer", () => {
332
330
  beforeEach(() => {
333
331
  // Ensure window has layout-like properties for happy-dom
334
- Object.defineProperty(window, 'innerHeight', {
332
+ Object.defineProperty(window, "innerHeight", {
335
333
  value: 768,
336
334
  writable: true,
337
335
  configurable: true,
338
336
  })
339
- Object.defineProperty(window, 'innerWidth', {
337
+ Object.defineProperty(window, "innerWidth", {
340
338
  value: 1024,
341
339
  writable: true,
342
340
  configurable: true,
343
341
  })
344
- Object.defineProperty(window, 'scrollY', {
342
+ Object.defineProperty(window, "scrollY", {
345
343
  value: 0,
346
344
  writable: true,
347
345
  configurable: true,
348
346
  })
349
347
  })
350
348
 
351
- it('creates an instance and returns virtualItems, totalSize, isScrolling signals', () => {
349
+ it("creates an instance and returns virtualItems, totalSize, isScrolling signals", () => {
352
350
  const { result: virt, unmount } = mountWith(() =>
353
351
  useWindowVirtualizer(() => ({
354
352
  count: 1000,
@@ -359,12 +357,12 @@ describe('useWindowVirtualizer', () => {
359
357
  expect(virt.instance).toBeDefined()
360
358
  expect(virt.virtualItems()).toBeDefined()
361
359
  expect(Array.isArray(virt.virtualItems())).toBe(true)
362
- expect(typeof virt.totalSize()).toBe('number')
360
+ expect(typeof virt.totalSize()).toBe("number")
363
361
  expect(virt.isScrolling()).toBe(false)
364
362
  unmount()
365
363
  })
366
364
 
367
- it('returns correct total size', () => {
365
+ it("returns correct total size", () => {
368
366
  const { result: virt, unmount } = mountWith(() =>
369
367
  useWindowVirtualizer(() => ({
370
368
  count: 100,
@@ -376,7 +374,7 @@ describe('useWindowVirtualizer', () => {
376
374
  unmount()
377
375
  })
378
376
 
379
- it('reactive count — updates when count signal changes', () => {
377
+ it("reactive count — updates when count signal changes", () => {
380
378
  const count = signal(100)
381
379
  const { result: virt, unmount } = mountWith(() =>
382
380
  useWindowVirtualizer(() => ({
@@ -392,7 +390,7 @@ describe('useWindowVirtualizer', () => {
392
390
  unmount()
393
391
  })
394
392
 
395
- it('reactive estimateSize — updates total size after measure()', () => {
393
+ it("reactive estimateSize — updates total size after measure()", () => {
396
394
  const itemSize = signal(50)
397
395
  const { result: virt, unmount } = mountWith(() =>
398
396
  useWindowVirtualizer(() => ({
@@ -409,7 +407,7 @@ describe('useWindowVirtualizer', () => {
409
407
  unmount()
410
408
  })
411
409
 
412
- it('exposes instance methods (scrollToIndex, scrollToOffset, measureElement)', () => {
410
+ it("exposes instance methods (scrollToIndex, scrollToOffset, measureElement)", () => {
413
411
  const { result: virt, unmount } = mountWith(() =>
414
412
  useWindowVirtualizer(() => ({
415
413
  count: 50,
@@ -417,13 +415,13 @@ describe('useWindowVirtualizer', () => {
417
415
  })),
418
416
  )
419
417
 
420
- expect(typeof virt.instance.scrollToIndex).toBe('function')
421
- expect(typeof virt.instance.scrollToOffset).toBe('function')
422
- expect(typeof virt.instance.measureElement).toBe('function')
418
+ expect(typeof virt.instance.scrollToIndex).toBe("function")
419
+ expect(typeof virt.instance.scrollToOffset).toBe("function")
420
+ expect(typeof virt.instance.measureElement).toBe("function")
423
421
  unmount()
424
422
  })
425
423
 
426
- it('virtual items have correct structure', () => {
424
+ it("virtual items have correct structure", () => {
427
425
  const { result: virt, unmount } = mountWith(() =>
428
426
  useWindowVirtualizer(() => ({
429
427
  count: 1000,
@@ -434,16 +432,16 @@ describe('useWindowVirtualizer', () => {
434
432
  const items = virt.virtualItems()
435
433
  if (items.length > 0) {
436
434
  const item = items[0]!
437
- expect(typeof item.index).toBe('number')
438
- expect(typeof item.start).toBe('number')
439
- expect(typeof item.end).toBe('number')
440
- expect(typeof item.size).toBe('number')
435
+ expect(typeof item.index).toBe("number")
436
+ expect(typeof item.start).toBe("number")
437
+ expect(typeof item.end).toBe("number")
438
+ expect(typeof item.size).toBe("number")
441
439
  expect(typeof item.key).toBeDefined()
442
440
  }
443
441
  unmount()
444
442
  })
445
443
 
446
- it('gap option affects total size', () => {
444
+ it("gap option affects total size", () => {
447
445
  const { result: noGap, unmount: unmount1 } = mountWith(() =>
448
446
  useWindowVirtualizer(() => ({
449
447
  count: 10,
@@ -467,7 +465,7 @@ describe('useWindowVirtualizer', () => {
467
465
  unmount2()
468
466
  })
469
467
 
470
- it('padding affects total size', () => {
468
+ it("padding affects total size", () => {
471
469
  const { result: virt, unmount } = mountWith(() =>
472
470
  useWindowVirtualizer(() => ({
473
471
  count: 10,
@@ -482,7 +480,7 @@ describe('useWindowVirtualizer', () => {
482
480
  unmount()
483
481
  })
484
482
 
485
- it('horizontal mode works', () => {
483
+ it("horizontal mode works", () => {
486
484
  const { result: virt, unmount } = mountWith(() =>
487
485
  useWindowVirtualizer(() => ({
488
486
  count: 100,
@@ -496,7 +494,7 @@ describe('useWindowVirtualizer', () => {
496
494
  unmount()
497
495
  })
498
496
 
499
- it('enabled: false produces empty virtual items', () => {
497
+ it("enabled: false produces empty virtual items", () => {
500
498
  const { result: virt, unmount } = mountWith(() =>
501
499
  useWindowVirtualizer(() => ({
502
500
  count: 100,
@@ -510,7 +508,7 @@ describe('useWindowVirtualizer', () => {
510
508
  unmount()
511
509
  })
512
510
 
513
- it('calls user-provided onChange callback', () => {
511
+ it("calls user-provided onChange callback", () => {
514
512
  const onChangeSpy = vi.fn()
515
513
  const count = signal(10)
516
514
  const { result: virt, unmount } = mountWith(() =>
@@ -529,7 +527,7 @@ describe('useWindowVirtualizer', () => {
529
527
  unmount()
530
528
  })
531
529
 
532
- it('overscan controls extra items rendered', () => {
530
+ it("overscan controls extra items rendered", () => {
533
531
  const { result: small, unmount: unmount1 } = mountWith(() =>
534
532
  useWindowVirtualizer(() => ({
535
533
  count: 1000,
@@ -546,14 +544,12 @@ describe('useWindowVirtualizer', () => {
546
544
  })),
547
545
  )
548
546
 
549
- expect(large.virtualItems().length).toBeGreaterThanOrEqual(
550
- small.virtualItems().length,
551
- )
547
+ expect(large.virtualItems().length).toBeGreaterThanOrEqual(small.virtualItems().length)
552
548
  unmount1()
553
549
  unmount2()
554
550
  })
555
551
 
556
- it('onChange callback updates signals when triggered directly', () => {
552
+ it("onChange callback updates signals when triggered directly", () => {
557
553
  const onChangeSpy = vi.fn()
558
554
  const { result: virt, unmount } = mountWith(() =>
559
555
  useWindowVirtualizer(() => ({
@@ -570,13 +566,13 @@ describe('useWindowVirtualizer', () => {
570
566
  }
571
567
 
572
568
  expect(virt.virtualItems()).toBeDefined()
573
- expect(typeof virt.totalSize()).toBe('number')
574
- expect(typeof virt.isScrolling()).toBe('boolean')
569
+ expect(typeof virt.totalSize()).toBe("number")
570
+ expect(typeof virt.isScrolling()).toBe("boolean")
575
571
  expect(onChangeSpy).toHaveBeenCalled()
576
572
  unmount()
577
573
  })
578
574
 
579
- it('onChange works without user-provided onChange', () => {
575
+ it("onChange works without user-provided onChange", () => {
580
576
  const { result: virt, unmount } = mountWith(() =>
581
577
  useWindowVirtualizer(() => ({
582
578
  count: 100,
@@ -593,7 +589,7 @@ describe('useWindowVirtualizer', () => {
593
589
  unmount()
594
590
  })
595
591
 
596
- it('handles missing document/window gracefully', () => {
592
+ it("handles missing document/window gracefully", () => {
597
593
  const origDoc = globalThis.document
598
594
  const origWin = globalThis.window
599
595
  try {
@@ -1,6 +1,6 @@
1
- import { onMount, onUnmount } from '@pyreon/core'
2
- import type { Signal } from '@pyreon/reactivity'
3
- import { batch, effect, signal } from '@pyreon/reactivity'
1
+ import { onMount, onUnmount } from "@pyreon/core"
2
+ import type { Signal } from "@pyreon/reactivity"
3
+ import { batch, effect, signal } from "@pyreon/reactivity"
4
4
  import {
5
5
  elementScroll,
6
6
  observeElementOffset,
@@ -8,19 +8,19 @@ import {
8
8
  type VirtualItem,
9
9
  Virtualizer,
10
10
  type VirtualizerOptions,
11
- } from '@tanstack/virtual-core'
11
+ } from "@tanstack/virtual-core"
12
12
 
13
13
  export type UseVirtualizerOptions<
14
14
  TScrollElement extends Element,
15
15
  TItemElement extends Element,
16
16
  > = () => Omit<
17
17
  VirtualizerOptions<TScrollElement, TItemElement>,
18
- 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'
18
+ "observeElementRect" | "observeElementOffset" | "scrollToFn"
19
19
  > &
20
20
  Partial<
21
21
  Pick<
22
22
  VirtualizerOptions<TScrollElement, TItemElement>,
23
- 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'
23
+ "observeElementRect" | "observeElementOffset" | "scrollToFn"
24
24
  >
25
25
  >
26
26
 
@@ -54,10 +54,7 @@ export interface UseVirtualizerResult<
54
54
  * // virtual.virtualItems() — array of visible VirtualItem
55
55
  * // virtual.totalSize() — total height/width for the inner container
56
56
  */
57
- export function useVirtualizer<
58
- TScrollElement extends Element,
59
- TItemElement extends Element,
60
- >(
57
+ export function useVirtualizer<TScrollElement extends Element, TItemElement extends Element>(
61
58
  options: UseVirtualizerOptions<TScrollElement, TItemElement>,
62
59
  ): UseVirtualizerResult<TScrollElement, TItemElement> {
63
60
  const resolvedOptions: VirtualizerOptions<TScrollElement, TItemElement> = {
@@ -74,9 +71,7 @@ export function useVirtualizer<
74
71
  // Store latest user options so onChange always reads the freshest reference
75
72
  let latestUserOpts = options()
76
73
 
77
- const instance = new Virtualizer<TScrollElement, TItemElement>(
78
- resolvedOptions,
79
- )
74
+ const instance = new Virtualizer<TScrollElement, TItemElement>(resolvedOptions)
80
75
 
81
76
  // Track reactive options: when signals inside options() change, update the virtualizer.
82
77
  const effectCleanup = effect(() => {
@@ -1,6 +1,6 @@
1
- import { onMount, onUnmount } from '@pyreon/core'
2
- import type { Signal } from '@pyreon/reactivity'
3
- import { batch, effect, signal } from '@pyreon/reactivity'
1
+ import { onMount, onUnmount } from "@pyreon/core"
2
+ import type { Signal } from "@pyreon/reactivity"
3
+ import { batch, effect, signal } from "@pyreon/reactivity"
4
4
  import {
5
5
  observeWindowOffset,
6
6
  observeWindowRect,
@@ -8,22 +8,18 @@ import {
8
8
  Virtualizer,
9
9
  type VirtualizerOptions,
10
10
  windowScroll,
11
- } from '@tanstack/virtual-core'
11
+ } from "@tanstack/virtual-core"
12
12
 
13
- export type UseWindowVirtualizerOptions<TItemElement extends Element> =
14
- () => Omit<
15
- VirtualizerOptions<Window, TItemElement>,
16
- | 'observeElementRect'
17
- | 'observeElementOffset'
18
- | 'scrollToFn'
19
- | 'getScrollElement'
20
- > &
21
- Partial<
22
- Pick<
23
- VirtualizerOptions<Window, TItemElement>,
24
- 'observeElementRect' | 'observeElementOffset' | 'scrollToFn'
25
- >
13
+ export type UseWindowVirtualizerOptions<TItemElement extends Element> = () => Omit<
14
+ VirtualizerOptions<Window, TItemElement>,
15
+ "observeElementRect" | "observeElementOffset" | "scrollToFn" | "getScrollElement"
16
+ > &
17
+ Partial<
18
+ Pick<
19
+ VirtualizerOptions<Window, TItemElement>,
20
+ "observeElementRect" | "observeElementOffset" | "scrollToFn"
26
21
  >
22
+ >
27
23
 
28
24
  export interface UseWindowVirtualizerResult<TItemElement extends Element> {
29
25
  instance: Virtualizer<Window, TItemElement>
@@ -52,9 +48,8 @@ export function useWindowVirtualizer<TItemElement extends Element>(
52
48
  observeElementRect: observeWindowRect,
53
49
  observeElementOffset: observeWindowOffset,
54
50
  scrollToFn: windowScroll,
55
- initialOffset: typeof document !== 'undefined' ? window.scrollY : 0,
56
- getScrollElement: () =>
57
- typeof window !== 'undefined' ? window : (null as unknown as Window),
51
+ initialOffset: typeof document !== "undefined" ? window.scrollY : 0,
52
+ getScrollElement: () => (typeof window !== "undefined" ? window : (null as unknown as Window)),
58
53
  ...options(),
59
54
  }
60
55