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] Fix first row flickering with autoHeight enabled #14235

Merged
merged 8 commits into from
Aug 30, 2024

Conversation

KenanYusuf
Copy link
Contributor

@KenanYusuf KenanYusuf commented Aug 16, 2024

Fixes the first row flickering when a new, editable row is added to a grid with autoHeight enabled.

Fixes #13270

The problem

1. User adds a new row

Screenshot 2024-08-16 at 14 06 21

2. The new row gets rendered in the correct position, but the original row is hidden

This happens because the newly added editable cell calls .focus() when it mounts. The virtual scroller has a scroll event listener that listens to scroll events in order to recalculate which rows are in view to render. The browser tries to scroll the editable cell into view, and triggers the scroll event callback.

The scroll event handler receives an event.scrollTop position of 52px, and decides that the first row does not need rendering because based on this value, it is out of view. This is what leads to the temporary state of a hidden first row.

Why is this only a problem with autoHeight enabled?

When autoHeight is not enabled, the scroll event listener only fires when the virtual scroller content actually becomes scrollable. This means the editable cell moves into focus and there is no visible flicker.

With autoHeight enabled, the virtual scroller content temporarily overflows when a new row is added whilst it recalculates the virtual scroller content height.

Screenshot 2024-08-16 at 14 06 30

3. The virtual scroller recalculates and re-renders both rows in the correct position

Screenshot 2024-08-16 at 14 06 38

The solution

Disable row virtualization when autoHeight is enabled. Row virtualization has no performance gains when autoHeight is enabled as the list of rows never becomes scrollable. This in turn fixes the issue of the virtual scroller miscalculating which elements are in view.

@mui-bot
Copy link

mui-bot commented Aug 16, 2024

@KenanYusuf KenanYusuf added bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! labels Aug 16, 2024
@KenanYusuf KenanYusuf marked this pull request as ready for review August 16, 2024 13:46
@KenanYusuf KenanYusuf requested a review from a team August 16, 2024 13:46
@KenanYusuf KenanYusuf marked this pull request as draft August 20, 2024 11:14
KenanYusuf and others added 2 commits August 20, 2024 17:02
@@ -47,6 +51,8 @@ export function useGridVirtualization(
virtualization: {
...state.virtualization,
enabled,
enabledForColumns: enabled,
enabledForRows: enabled && !props.autoHeight,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure how to feel about putting the !prop.autoheight logic in the state setter. I would have maybe gone for keeping the state setter as simple as possible. But I also don't find a satisfying place to put it, so I don't know.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could we move the !autoheight somewhere it doesn't need to be repeated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any suggestions where/how @romgrk?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, feel free to ignore if there's no other good place.

@@ -168,7 +168,7 @@ export const useGridColumnHeaders = (props: UseGridColumnHeadersProps) => {
maxLastColumn = visibleColumns.length,
} = params || {};

const firstColumnToRender = !hasVirtualization ? 0 : currentContext.firstColumnIndex;
const firstColumnToRender = currentContext.firstColumnIndex;
Copy link
Contributor Author

@KenanYusuf KenanYusuf Aug 28, 2024

Choose a reason for hiding this comment

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

There was a bug here. hasVirtualization is using gridVirtualizationColumnEnabledSelector to get the column virtualization state. This was previously always true, even when the disableVirtualization prop was passed to DataGrid. The 0 here meant that pinned column headers were duplicated were not being removed from the middle section of columns.

@KenanYusuf KenanYusuf marked this pull request as ready for review August 28, 2024 10:23
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Aug 28, 2024
@KenanYusuf KenanYusuf merged commit 2378e90 into mui:master Aug 30, 2024
20 checks passed
@KenanYusuf KenanYusuf deleted the fix-auto-height-row-flicker branch August 30, 2024 10:06
@Luis-Ramirez21x
Copy link

Thank you guys for bashing this bug !

Our users will be happy to have this fixed 🙏 !!

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! size:L This PR changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[data grid] adding a new row with the autoHeight prop causes first row flicker
5 participants