From fabc0a829435ac3dd782bb7c9e55ab5f8b66f1fa Mon Sep 17 00:00:00 2001 From: inokawa <48897392+inokawa@users.noreply.github.com> Date: Sun, 23 Jun 2024 23:18:20 +0900 Subject: [PATCH] Support dynamic startMargin --- src/core/store.ts | 4 ++-- src/react/Virtualizer.tsx | 9 ++++++--- src/vue/Virtualizer.tsx | 12 +++++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/core/store.ts b/src/core/store.ts index af183c377..a51a586f6 100644 --- a/src/core/store.ts +++ b/src/core/store.ts @@ -140,12 +140,12 @@ export const createVirtualStore = ( itemSize: number = 40, ssrCount: number = 0, cacheSnapshot?: CacheSnapshot | undefined, - shouldAutoEstimateItemSize: boolean = false, - startSpacerSize: number = 0 + shouldAutoEstimateItemSize: boolean = false ): VirtualStore => { let isSSR = !!ssrCount; let stateVersion: StateVersion = []; let viewportSize = 0; + let startSpacerSize = 0; let scrollOffset = 0; let jumpCount = 0; let jump = 0; diff --git a/src/react/Virtualizer.tsx b/src/react/Virtualizer.tsx index 4ff19f6d2..5a638c0d9 100644 --- a/src/react/Virtualizer.tsx +++ b/src/react/Virtualizer.tsx @@ -16,6 +16,7 @@ import { SCROLL_IDLE, UPDATE_SCROLL_END_EVENT, getScrollSize, + ACTION_START_OFFSET_CHANGE, } from "../core/store"; import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect"; import { createScroller } from "../core/scroller"; @@ -178,7 +179,7 @@ export const Virtualizer = forwardRef( shift, horizontal: horizontalProp, cache, - startMargin, + startMargin = 0, ssrCount, as: Element = "div", item: ItemElement = "div", @@ -207,8 +208,7 @@ export const Virtualizer = forwardRef( itemSize, ssrCount, cache, - !itemSize, - startMargin + !itemSize ); return [ _store, @@ -222,6 +222,9 @@ export const Virtualizer = forwardRef( if (count !== store._getItemsLength()) { store._update(ACTION_ITEMS_LENGTH_CHANGE, [count, shift]); } + if (startMargin !== store._getStartSpacerSize()) { + store._update(ACTION_START_OFFSET_CHANGE, startMargin); + } const rerender = useRerender(store); diff --git a/src/vue/Virtualizer.tsx b/src/vue/Virtualizer.tsx index 280490e39..0eeb288f2 100644 --- a/src/vue/Virtualizer.tsx +++ b/src/vue/Virtualizer.tsx @@ -21,6 +21,7 @@ import { createVirtualStore, ACTION_ITEMS_LENGTH_CHANGE, getScrollSize, + ACTION_START_OFFSET_CHANGE, } from "../core/store"; import { createResizer } from "../core/resizer"; import { createScroller } from "../core/scroller"; @@ -93,7 +94,7 @@ const props = { /** * If you put an element before virtualizer, you have to define its height with this prop. */ - startMargin: Number, + startMargin: { type: Number, default: 0 }, /** * A prop for SSR. If set, the specified amount of items will be mounted in the initial rendering regardless of the container size until hydrated. */ @@ -117,8 +118,7 @@ export const Virtualizer = /*#__PURE__*/ defineComponent({ props.itemSize ?? 40, props.ssrCount, undefined, - !props.itemSize, - props.startMargin + !props.itemSize ); const resizer = createResizer(store, isHorizontal); const scroller = createScroller(store, isHorizontal); @@ -168,6 +168,12 @@ export const Virtualizer = /*#__PURE__*/ defineComponent({ store._update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]); } ); + watch( + () => props.startMargin, + (value) => { + store._update(ACTION_START_OFFSET_CHANGE, value); + } + ); watch( [rerender, store._getJumpCount],