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

[DataGrid] Prevent column header scroll #4280

Merged
merged 5 commits into from
Apr 11, 2022

Conversation

m4theushw
Copy link
Member

@m4theushw m4theushw commented Mar 25, 2022

@mui-bot
Copy link

mui-bot commented Mar 25, 2022

These are the results for the performance tests:

Test case Unit Min Max Median Mean σ
Filter 100k rows ms 241.3 398.8 301.5 317.02 69.329
Sort 100k rows ms 409.3 836.3 800.1 701.34 162.455
Select 100k rows ms 107.3 198.9 155.4 154.54 31.693
Deselect 100k rows ms 90.4 291.2 291.2 149.26 73.74

Generated by 🚫 dangerJS against d420045

@m4theushw m4theushw requested a review from alexfauquette March 25, 2022 21:41
@m4theushw m4theushw added bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! labels Mar 25, 2022
} else {
headerCellRef.current!.focus();
const elementToFocus = focusableElement || headerCellRef.current;
elementToFocus?.focus({ preventScroll: true });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK this preventScroll is not viable because it doesn't work on Safari. What I would propose instead is to look into why the container is scrollable in the first place. We use translate 3d, so why is it possible for scrollLeft to not always be 0 in the first place?

Copy link
Member Author

@m4theushw m4theushw Mar 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even adding overflow: hidden I still can scroll a div. It's expected: https://stackoverflow.com/questions/33703204/is-scrolltop-and-scrollleft-for-overflow-hidden-elements-reliable

msedge_0wKPMSGImu

In the past, we even did a small hack by listening to scroll and calling scrollLeft=0 to prevent scrolling the container - which had overflow: hidden - when using a touchpad device.

const preventScroll = React.useCallback((event: any) => {
event.target.scrollLeft = 0;
event.target.scrollTop = 0;
}, []);
useNativeEventListener(apiRef, windowRef, 'scroll', handleScroll, { passive: true });

AFAIK this preventScroll is not viable because it doesn't work on Safari.

That's why I call scrollLeft=0 down below if preventScroll is not supported.

Copy link
Member

@oliviertassinari oliviertassinari Mar 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right ok, great points, all my previous points have been answered.

I had a closer look: did you consider this option?

  1. Only do this:

apiRef.current.columnHeadersContainerElementRef!.current!.scrollLeft = 0;

  1. Remove (seems dead code)

React.useEffect(() => {
apiRef.current.columnHeadersContainerElementRef!.current!.scrollLeft = 0;
}, [apiRef]);

I'm asking because using preventScroll here might introduce the same problems as #4282 (vertical scrolling) but for horizontal scrolling.


Actually, speaking of horizontal scrolling, I have found a bug when rows={[]} https://codesandbox.io/s/datagridprodemo-material-demo-forked-8e4l8w:

  1. focus a header cell
  2. use the arrow left or arrow right to move the focus
  3. the body doesn't scroll horizontally

Now, maybe we don't need to care. Who would try to scroll/use the arrow key? There are no data loaded 😁

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "no row" bug can be fixed. It's an early return to modify in scroll hook

https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid/src/hooks/features/scroll/useGridScroll.ts#L56:L58


Is it necessary to prevent scroll? I thought adding the hasFocus un the useLayoutEffect dependencies was enough to prevent scroll on rendering

The only bug I can think of with the scroll on rendering is when the element is unmounted because it goes out of the virtualization engine and comes back. But that's a larger problem.

For example, I set focus on a cell, I can use keyboard navigation as long as the cell is in the virtualisation buffer. As soon as it exits the buffer, the focus moves to <body> and the gird does not respond anymore to keyboard interactions
https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid/src/hooks/features/scroll/useGridScroll.ts#L56:L58

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed preventScroll and kept only scrollLeft=0. I didn't realize the side effect of using it.

I thought adding the hasFocus un the useLayoutEffect dependencies was enough to prevent scroll on rendering

It's not sufficient. If I remove scrollLeft=0 and scroll very fast to left and right the bug appears at some point. This happens because the column header component may be mounted during scroll.

The "no row" bug can be fixed. It's an early return to modify in scroll hook

Interesting, I won't fix it here. Feel free to submit a PR.

Now, maybe we don't need to care. Who would try to scroll/use the arrow key? There are no data loaded 😁

If what caused "no results" was applying a filter in a column that's outside the visible area, then the user may use the arrow keys to navigate to them. We had a issue about that when we blocked the scrollbar if rows=[]: #3795 (comment)

@m4theushw m4theushw self-assigned this Mar 28, 2022
@@ -171,7 +171,7 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => {

columns.push(
<GridColumnHeaderItem
key={i}
key={column.field}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prevents the effect triggering twice.

@m4theushw m4theushw merged commit 33db58d into mui:master Apr 11, 2022
@m4theushw m4theushw deleted the prevent-column-header-scroll branch April 11, 2022 15:42
alexfauquette pushed a commit to alexfauquette/mui-x that referenced this pull request Aug 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants