-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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] Add disableVirtualization
to disable virtualization completely
#2326
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
cf7ac77
move scroll methods to useGridScroll
m4theushw 624352e
rename useGridVirtualRows -> useGridVirtualization
m4theushw fe60f82
allow to disable virtualization
m4theushw 0dbfb0b
one more test
m4theushw ce0ea65
Merge branch 'master' into disable-virtualization
m4theushw 35533ae
Merge branch 'master' into disable-virtualization
m4theushw 8217286
explain why to disable virtualization
m4theushw c2bd419
Merge branch 'next' into disable-virtualization
m4theushw 2ecb417
yarn docs:api
m4theushw 3adc483
pageSize is never null
m4theushw 006e147
Merge branch 'next' into disable-virtualization
m4theushw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
...cs/data-grid/grid-virtualization-api.json → ...s/api-docs/data-grid/grid-scroll-api.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 0 additions & 7 deletions
7
docs/src/pages/components/data-grid/virtualization/VirtualizationApiNoSnap.js
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './useGridScroll'; |
151 changes: 151 additions & 0 deletions
151
packages/grid/_modules_/grid/hooks/features/scroll/useGridScroll.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import * as React from 'react'; | ||
import { GridCellIndexCoordinates } from '../../../models/gridCell'; | ||
import { GridApiRef } from '../../../models/api/gridApiRef'; | ||
import { useLogger } from '../../utils/useLogger'; | ||
import { | ||
gridColumnsMetaSelector, | ||
visibleGridColumnsSelector, | ||
} from '../columns/gridColumnsSelector'; | ||
import { useGridSelector } from '../core/useGridSelector'; | ||
import { GridComponentProps } from '../../../GridComponentProps'; | ||
import { gridPaginationSelector } from '../pagination/gridPaginationSelector'; | ||
import { gridRowCountSelector } from '../rows/gridRowsSelector'; | ||
import { gridDensityRowHeightSelector } from '../density/densitySelector'; | ||
import { GridScrollParams } from '../../../models/params/gridScrollParams'; | ||
import { GridScrollApi } from '../../../models/api/gridScrollApi'; | ||
import { scrollStateSelector } from '../virtualization/renderingStateSelector'; | ||
import { useGridApiMethod } from '../../root/useGridApiMethod'; | ||
import { useNativeEventListener } from '../../root/useNativeEventListener'; | ||
|
||
// Logic copied from https://www.w3.org/TR/wai-aria-practices/examples/listbox/js/listbox.js | ||
// Similar to https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView | ||
function scrollIntoView(dimensions) { | ||
const { clientHeight, scrollTop, offsetHeight, offsetTop } = dimensions; | ||
|
||
const elementBottom = offsetTop + offsetHeight; | ||
if (elementBottom - clientHeight > scrollTop) { | ||
return elementBottom - clientHeight; | ||
} | ||
if (offsetTop < scrollTop) { | ||
return offsetTop; | ||
} | ||
return undefined; | ||
} | ||
|
||
export const useGridScroll = ( | ||
apiRef: GridApiRef, | ||
props: Pick<GridComponentProps, 'pagination'>, | ||
): void => { | ||
const logger = useLogger('useGridScroll'); | ||
const colRef = apiRef.current.columnHeadersElementRef!; | ||
const windowRef = apiRef.current.windowRef!; | ||
|
||
const rowHeight = useGridSelector(apiRef, gridDensityRowHeightSelector); | ||
const paginationState = useGridSelector(apiRef, gridPaginationSelector); | ||
const totalRowCount = useGridSelector(apiRef, gridRowCountSelector); | ||
const visibleColumns = useGridSelector(apiRef, visibleGridColumnsSelector); | ||
const columnsMeta = useGridSelector(apiRef, gridColumnsMetaSelector); | ||
|
||
const scrollToIndexes = React.useCallback<GridScrollApi['scrollToIndexes']>( | ||
(params: Partial<GridCellIndexCoordinates>) => { | ||
if (totalRowCount === 0 || visibleColumns.length === 0) { | ||
return false; | ||
} | ||
|
||
logger.debug(`Scrolling to cell at row ${params.rowIndex}, col: ${params.colIndex} `); | ||
|
||
const scrollCoordinates: any = {}; | ||
|
||
if (params.colIndex != null) { | ||
scrollCoordinates.left = scrollIntoView({ | ||
clientHeight: windowRef.current!.clientWidth, | ||
scrollTop: windowRef.current!.scrollLeft, | ||
offsetHeight: visibleColumns[params.colIndex].computedWidth, | ||
offsetTop: columnsMeta.positions[params.colIndex], | ||
}); | ||
} | ||
|
||
if (params.rowIndex != null) { | ||
const elementIndex = !props.pagination | ||
? params.rowIndex | ||
: params.rowIndex - paginationState.page * paginationState.pageSize; | ||
|
||
scrollCoordinates.top = scrollIntoView({ | ||
clientHeight: windowRef.current!.clientHeight, | ||
scrollTop: windowRef.current!.scrollTop, | ||
offsetHeight: rowHeight, | ||
offsetTop: rowHeight * elementIndex, | ||
}); | ||
} | ||
|
||
if ( | ||
typeof scrollCoordinates.left !== undefined || | ||
typeof scrollCoordinates.top !== undefined | ||
) { | ||
apiRef.current.scroll(scrollCoordinates); | ||
return true; | ||
} | ||
|
||
return false; | ||
}, | ||
[ | ||
totalRowCount, | ||
visibleColumns, | ||
logger, | ||
apiRef, | ||
props.pagination, | ||
paginationState.page, | ||
paginationState.pageSize, | ||
windowRef, | ||
columnsMeta.positions, | ||
rowHeight, | ||
], | ||
); | ||
|
||
const scroll = React.useCallback<GridScrollApi['scroll']>( | ||
(params: Partial<GridScrollParams>) => { | ||
if (windowRef.current && params.left != null && colRef.current) { | ||
colRef.current.scrollLeft = params.left; | ||
windowRef.current.scrollLeft = params.left; | ||
logger.debug(`Scrolling left: ${params.left}`); | ||
} | ||
if (windowRef.current && params.top != null) { | ||
windowRef.current.scrollTop = params.top; | ||
logger.debug(`Scrolling top: ${params.top}`); | ||
} | ||
logger.debug(`Scrolling, updating container, and viewport`); | ||
}, | ||
[windowRef, colRef, logger], | ||
); | ||
|
||
const getScrollPosition = React.useCallback<GridScrollApi['getScrollPosition']>( | ||
() => scrollStateSelector(apiRef.current.getState()), | ||
[apiRef], | ||
); | ||
|
||
const scrollApi: GridScrollApi = { | ||
scroll, | ||
scrollToIndexes, | ||
getScrollPosition, | ||
}; | ||
useGridApiMethod(apiRef, scrollApi, 'GridScrollApi'); | ||
|
||
const preventScroll = React.useCallback((event: any) => { | ||
event.target.scrollLeft = 0; | ||
event.target.scrollTop = 0; | ||
}, []); | ||
|
||
useNativeEventListener( | ||
apiRef, | ||
() => apiRef.current?.renderingZoneRef?.current?.parentElement, | ||
'scroll', | ||
preventScroll, | ||
); | ||
|
||
useNativeEventListener( | ||
apiRef, | ||
() => apiRef.current?.columnHeadersContainerElementRef?.current, | ||
'scroll', | ||
preventScroll, | ||
); | ||
}; |
2 changes: 1 addition & 1 deletion
2
packages/grid/_modules_/grid/hooks/features/virtualization/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export * from './useGridVirtualRows'; | ||
export * from './useGridVirtualization'; | ||
export * from './renderingState'; |
81 changes: 81 additions & 0 deletions
81
packages/grid/_modules_/grid/hooks/features/virtualization/useGridNoVirtualization.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import * as React from 'react'; | ||
import { GridComponentProps } from '../../../GridComponentProps'; | ||
import { GridApiRef } from '../../../models/api/gridApiRef'; | ||
import { useNativeEventListener } from '../../root/useNativeEventListener'; | ||
import { useGridScrollFn } from '../../utils/useGridScrollFn'; | ||
import { visibleGridColumnsSelector } from '../columns/gridColumnsSelector'; | ||
import { useGridSelector } from '../core'; | ||
import { useGridState } from '../core/useGridState'; | ||
import { gridPaginationSelector } from '../pagination/gridPaginationSelector'; | ||
|
||
export const useGridNoVirtualization = ( | ||
apiRef: GridApiRef, | ||
props: Pick<GridComponentProps, 'disableVirtualization' | 'pagination' | 'paginationMode'>, | ||
): void => { | ||
const windowRef = apiRef.current.windowRef; | ||
const columnsHeaderRef = apiRef.current.columnHeadersElementRef; | ||
const renderingZoneRef = apiRef.current.renderingZoneRef; | ||
const [gridState, setGridState, forceUpdate] = useGridState(apiRef); | ||
const [scrollTo] = useGridScrollFn(renderingZoneRef!, columnsHeaderRef!); | ||
const paginationState = useGridSelector(apiRef, gridPaginationSelector); | ||
const visibleColumns = useGridSelector(apiRef, visibleGridColumnsSelector); | ||
|
||
const syncState = React.useCallback(() => { | ||
if (!gridState.containerSizes || !windowRef?.current) { | ||
return; | ||
} | ||
|
||
let firstRowIdx = 0; | ||
const { page, pageSize } = paginationState; | ||
if (props.pagination && props.paginationMode === 'client') { | ||
firstRowIdx = pageSize * page; | ||
} | ||
const lastRowIdx = firstRowIdx + gridState.containerSizes.virtualRowsCount; | ||
const lastColIdx = visibleColumns.length > 0 ? visibleColumns.length - 1 : 0; | ||
const renderContext = { firstRowIdx, lastRowIdx, firstColIdx: 0, lastColIdx }; | ||
|
||
const scrollParams = { | ||
top: windowRef.current!.scrollTop, | ||
left: windowRef.current!.scrollLeft, | ||
}; | ||
|
||
setGridState((state) => ({ | ||
...state, | ||
rendering: { | ||
...state.rendering, | ||
virtualPage: 0, | ||
renderContext, | ||
realScroll: scrollParams, | ||
renderingZoneScroll: scrollParams, | ||
}, | ||
})); | ||
forceUpdate(); | ||
}, [ | ||
gridState.containerSizes, | ||
paginationState, | ||
props.pagination, | ||
props.paginationMode, | ||
setGridState, | ||
forceUpdate, | ||
visibleColumns.length, | ||
windowRef, | ||
]); | ||
|
||
React.useEffect(() => { | ||
if (!props.disableVirtualization) { | ||
return; | ||
} | ||
syncState(); | ||
}, [props.disableVirtualization, syncState]); | ||
|
||
const handleScroll = React.useCallback(() => { | ||
if (!props.disableVirtualization || !windowRef?.current) { | ||
return; | ||
} | ||
const { scrollLeft, scrollTop } = windowRef.current; | ||
scrollTo({ top: scrollTop, left: scrollLeft }); | ||
syncState(); | ||
}, [props.disableVirtualization, scrollTo, windowRef, syncState]); | ||
|
||
useNativeEventListener(apiRef, windowRef!, 'scroll', handleScroll, { passive: true }); | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you remove this section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the changes is to move the scroll methods to a separated hook. Since this interface is empty now I removed it. Maybe we should add a page for scrolling with a demo: #1103 (comment). In this new page we could document the API available.