Code Monkey home page Code Monkey logo

Comments (5)

riptusk331 avatar riptusk331 commented on June 9, 2024 2

I found a way to fix this, and am linking a working example. The trick is to calculate the height difference between the table element and the scrollable div, and then append an invisible pseudo-element to the table with that calculated height. This results in the table having the same height as the scrollable div, and stops the header from vanishing since you'll no longer scroll past the "end" of table element.

Doing this is a little bit tricky since pseudo elements can't be controlled directly through React/JSX inline styling, and directly adding new styles to the DOM is super expensive and forces the browser to recalculate the layout (which will make scrolling janky). The best way I found to do this was with with CSS variables, which the browser is very efficient at handling and it doesn't force a full layout recalc. I added a virtual-table::after CSS class with a variable height, and made sure to class my <table> element with virtual-table. Then just set that height from your handlers in your React table component.

Also, since the number of table rows (<tr>) being rendered to the DOM by the virtualizer at any given time varies (and therefore the height of the table + your originally set pseudo element varies), you need to pay attention to this as you near the bottom of your scrollable area as this could result in a large divergence (meaning you'll over-scroll past the table, or the pseudo element will be too short and the header will disappear again). The way I did this was set up an event listener for the scroll that flags when we're near the bottom 5% of the list, and triggers the pseudo element height recalculation.

Sticky Table Header Example

I'm sure this can be improved and there are further efficiencies, but it works buttery smooth for me.

As for the "issue" itself, I would argue that this isn't really a react-virtual issue. I don't think there's anything the library could really do for you. This is just a quirk of virtualizing that you need to account for. Virtualizing tables is kind of a bastardization of things. That said, it would be good to include this as an example in the existing docs, as none of this is immediately obvious.

from virtual.

piecyk avatar piecyk commented on June 9, 2024 2

There are few issues here, overfall tables don't quite like when rows are positions absolute, one option is to change the positioning strategy by adding before/after row that will move items when scrolling

https://codesandbox.io/p/devbox/zealous-firefly-8vm5y2?file=%2Fsrc%2Fmain.tsx%3A91%2C19

btw there is no clear answer what positioning strategy is better, it's really hard to compare performance in a significant way.

from virtual.

wjthieme avatar wjthieme commented on June 9, 2024 1

@ryanjoycemacq if you add position: sticky to the <thead> element in the example you can reproduce this.

@riptusk331 I'll check if this works!

from virtual.

ryanjoycemacq avatar ryanjoycemacq commented on June 9, 2024

@wjthieme i think the example you linked is just the regular virtual table example...there's nothing with sticky headers in it.

from virtual.

aronedwards avatar aronedwards commented on June 9, 2024

TEMP Workaround - issues see post below
Cleaner "hack/solution", but not super smooth
can use parentRef (ref of scrolling component) to generate your own code version of sticky
less performant, but more maintainable until bug solved

<TableRow
    key={headerGroup.id}
    className="relative z-20"
    style={{
      transform: `translateY(${
        parentRef.current?.scrollTop || 0
      }px)`,
    }} >
           

from virtual.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.