3
votes

I have implemented an Infinite scrolling table with react-window (based on #60) and material UI.

The table seems to be fulfilling the main objective but there are few issues with it -

  1. header is not sticking on the top in spite of having styles in place (stickyHeader prop).
  2. header is flashing/flickering while scrolling quickly towards up direction. [Steps to reproduce - scroll 50% down then do fast scroll up and observe the header movement ].

Here's the codesandbox example - https://codesandbox.io/s/react-window-with-table-elements-forked-huti6?file=/src/index.tsx:514-542

3
The flickering is a feature, not a bug...... What's happening is react-window-infinite-loader is displaying only the data currently visible in the viewport, in order to speed up load times. As you scroll up, new data is loaded, and the old data is removed, but if you scroll very fast it can't keep up. Take a look at what's happening inside .MuiTableBody-root - Eliezer Berlin
@EliezerBerlin what you said is correct, there are lots of add-delete in the TBody section so flickering there is fine but there are no changes in the header section so it supposed to be freeze, right? - Dev AKS
Again, it's from react-window-infinite-loader. The table moves around using position:absolute and top. The real cause of the flickering is that the top attribute on the table.MuiTable-root isn't fast enough to keep up with your scrolling. - Eliezer Berlin
Though you might also want to add the css: table-layout:fixed; to your table so that the width of the header isn't determined by the width of the currently visible content. - Eliezer Berlin
Tried table-layout: fixed;, didn't see any difference. - Dev AKS

3 Answers

0
votes

Use default value for TableContainer overflow-x and the sticky header should work

import { makeStyles } from '@material-ui/core/styles'

const useStyles = makeStyles({
  tableContainer: {
    overflowX: "initial"
  }
})

function Inner({ children, ...rest }, ref) {
  const { header, footer, top } = useContext(VirtualTableContext)
  const classes = useStyles();
  return (
    <TableContainer classes={{root: classes.tableContainer}} {...rest} ref={ref}>
    ...

Edit React-Window with table elements (forked)

0
votes

As an alternative to your implementation, the Material UI docs have a working example of a virtualized table which achieves what you're looking for using react-virtualized. That is, the header is sticky and there is no flashing/flickering of the header during scroll.

Below is a codesandbox containing a working example to reflect your desired layout.

 Material demo (forked)

0
votes

First about the react-window: The Scollbars in the react-window are for the outercontainer not for InnerContainer. Now don't try to replace the outer container itself, unless you want to handle everything yourself. All the scroll events a few more things are attached to the outercontainer.

Think of it like outer container decides/takes the size and the larger inner container gets scrolled inside it.

Now looking at your case I assume you are trying to make the table behave like any other grid where headers are fixed and content is scrolled if it's getting overflow. your table header is way lower in the element hierarchy than the inner container, so no way you can write any simple css (or js logic) to achieve in current hierarchy.

that's why even though you have set the stickyheader for the MaterialUI table, it won't stick. Cause your whole table (MaterialUI table) is getting scrolled inside the outer container of react-window.

I would suggest you to move your table header outside of the react-window and only place the rows in the react-widow. that's the way it's suppose to behave (i.e. react window treats everything in it as scrollable content). See one of the presentation below:

ReactWindow

A little tip on redesigning of your table (guess the alignment can be improved by additional css)

header outside of reactwindow