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

How can I implement pinned table headers? #180

Closed
strich opened this issue Aug 10, 2021 · 8 comments
Closed

How can I implement pinned table headers? #180

strich opened this issue Aug 10, 2021 · 8 comments

Comments

@strich
Copy link

strich commented Aug 10, 2021

Similar issue: #115

Thanks to the above issue, it is now possible to pin certain list items in the virtual list which I have successfully tested. However I cannot use position: sticky as far as I can tell, because of the way react-virtual renders each cell as its own div?

As an example, here is a table using position: sticky to pin both vertical and horizontal cells: https://codepen.io/chriscoyier/pen/yLVNErX

How would we achieve the same effect with react-virtual?

@piecyk
Copy link
Collaborator

piecyk commented Aug 10, 2021

One option is to use pseudo elements on tbody and control them via css custom properties, checkout the comment #10 (comment)

@strich
Copy link
Author

strich commented Aug 11, 2021

Thanks thats a great start. I had a read over the example code and I have a concern: In the example the columns are small and are a simple array. In my scenario, my table is 100s of cells wide and deep. How would I output just the top row and its cells in the table head?

<thead>
          <tr>
            {columns.map((col) => (
              <th key={col.id}>{col.label}</th>
            ))}
          </tr>
        </thead>

Would something like this work?

        <thead>
          <tr>
          {rowVirtualizer.virtualItems.map(virtualRow => (            
              columnVirtualizer.virtualItems.map(virtualColumn => (            
                (virtualRow.index === 0) ?? <th key={virtualColumn.index}>{virtualColumn.index}</th>
              ))
          ))}
          </tr>
        </thead>

@piecyk
Copy link
Collaborator

piecyk commented Aug 11, 2021

@strich imho no, it's not possible. I would say checkout grid example to virtualise columns and rows at the same time.

@strich
Copy link
Author

strich commented Aug 11, 2021

@strich imho no, it's not possible. I would say checkout grid example to virtualise columns and rows at the same time.

Yeah the grid example is where I started. But then I cannot pin certain rows/columns with "sticky" position. I'm not sure how I can implement a virtual grid with pinned heard rows/columns? I think trying to use the "sticky" css position is causing more pain than it needs to. Is there a way to know the visible row/column indexes elsewhere in react? If so, maybe I could iterate that and generate a series of divs that would outside of the "parent" div?

@piecyk
Copy link
Collaborator

piecyk commented Aug 11, 2021

But then I cannot pin certain rows/columns with "sticky" position. I'm not sure how I can implement a virtual grid with pinned heard rows/columns

hmm having first row as sticky can be done for example like https://codesandbox.io/s/react-virtual-grid-sticky-first-row-p1yy9, hard to say what exactly is your use case, if something fyi with rangeExtractor you can keep items rendered even if they are out of viewport.

@strich
Copy link
Author

strich commented Aug 12, 2021

Thanks that's an interesting way of doing it. I've tried to expand it to include both the top and left headers but AFAIK position: sticky doesn't work in this situation?

My fork: https://codesandbox.io/s/react-virtual-grid-sticky-first-row-forked-41q8m?file=/src/index.js

@bestwebdeveloper
Copy link

bestwebdeveloper commented Aug 14, 2021

@strich It works, you just need to set it's width. https://codesandbox.io/s/react-virtual-grid-sticky-first-row-forked-b64ss?file=/src/index.js

@achalagarwal
Copy link

@bestwebdeveloper would you happen to know how one could make the pinned headers stay when the browser is scaled (view port scale)?

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

5 participants