Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing startMargin causes empty space to appear before the rendered list items #458

Open
szszoke opened this issue Jun 19, 2024 · 1 comment
Assignees

Comments

@szszoke
Copy link

szszoke commented Jun 19, 2024

Describe the bug
Virtualizer doesn't seem to handle when startMargin changes and you get empty space before the rendered list items.

See the video below. It is showing a modified version of the nested example where I am periodically changing the value that is passed to startMargin. This is meant to simulate a page where the value of startMargin depends on a responsive element what might change it's height.

Screencast.from.2024-06-19.17-14-31.webm

To Reproduce
Source code of the modified nested example:

export const Nested: StoryObj = {
  render: () => {
    const ref = useRef<HTMLDivElement>(null);
    const [paddingTop, setPaddingTop] = useState(0);

    useEffect(() => {
      let i = 0;
      const handle = window.setInterval(() => {
        if (i++ % 2 === 0) {
          setPaddingTop(0);
        } else {
          setPaddingTop(400);
        }
      }, 5000);

      return () => {
        window.clearInterval(handle);
      };
    }, []);

    const outerPadding = 40;
    const innerPadding = 60;
    return (
      <div
        ref={ref}
        style={{
          width: "100%",
          height: "100vh",
          overflowY: "auto",
          // opt out browser's scroll anchoring on header/footer because it will conflict to scroll anchoring of virtualizer
          overflowAnchor: "none",
        }}
      >
        <div
          style={{
            backgroundColor: "burlywood",
            padding: outerPadding,
            paddingTop,
          }}
        >
          <div style={{ backgroundColor: "steelblue", padding: innerPadding }}>
            <Virtualizer
              scrollRef={ref}
              startMargin={outerPadding + innerPadding + paddingTop}
            >
              {createRows(1000)}
            </Virtualizer>
          </div>
        </div>
      </div>
    );
  },
};

In reality I am using a resize observer to detect when the size of a div that is rendered before the Virtualizer changes and use its height for startMargin. The initial value is 0 and then it changes to something positive.

Expected behavior
There should not be empty space before the rendered list items.

Platform:

  • OS: Linux
  • Browser: Firefox and Chromium
  • Version of this package: latest main (currently a9d55e2)
  • Version of framework: react

Additional context

It is possible to fill in the empty space by increasing the overscan but there is still flashing while the list is scrolled.

@inokawa
Copy link
Owner

inokawa commented Jun 20, 2024

Hi, I'm planning to support dynamic startMargin. It can be tracked in #315

@inokawa inokawa self-assigned this Jun 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants