11import { Box , Table , type MantineSize } from '@mantine/core' ;
2- import { useDebouncedCallback , useMergedRef } from '@mantine/hooks' ;
2+ import { useMergedRef } from '@mantine/hooks' ;
33import clsx from 'clsx' ;
4- import { useCallback , useMemo , useState } from 'react' ;
4+ import { useCallback , useMemo } from 'react' ;
55import { DataTableColumnsProvider } from './DataTableDragToggleProvider' ;
66import { DataTableEmptyRow } from './DataTableEmptyRow' ;
77import { DataTableEmptyState } from './DataTableEmptyState' ;
@@ -14,8 +14,7 @@ import { DataTableScrollArea } from './DataTableScrollArea';
1414import { getTableCssVariables } from './cssVariables' ;
1515import {
1616 useDataTableColumns ,
17- useElementOuterSize ,
18- useIsomorphicLayoutEffect ,
17+ useDataTableInjectCssVariables ,
1918 useLastSelectionChangeIndex ,
2019 useRowExpansion ,
2120} from './hooks' ;
@@ -131,12 +130,6 @@ export function DataTable<T>({
131130 tableWrapper,
132131 ...otherProps
133132} : DataTableProps < T > ) {
134- const {
135- ref : localScrollViewportRef ,
136- width : scrollViewportWidth ,
137- height : scrollViewportHeight ,
138- } = useElementOuterSize < HTMLDivElement > ( ) ;
139-
140133 const effectiveColumns = useMemo ( ( ) => {
141134 return groups ?. flatMap ( ( group ) => group . columns ) ?? columns ! ;
142135 } , [ columns , groups ] ) ;
@@ -150,84 +143,28 @@ export function DataTable<T>({
150143 columns : effectiveColumns ,
151144 } ) ;
152145
153- const { ref : headerRef , height : headerHeight } = useElementOuterSize < HTMLTableSectionElement > ( ) ;
154- const { ref : localTableRef , width : tableWidth , height : tableHeight } = useElementOuterSize < HTMLTableElement > ( ) ;
155- const { ref : footerRef , height : footerHeight } = useElementOuterSize < HTMLTableSectionElement > ( ) ;
156- const { ref : paginationRef , height : paginationHeight } = useElementOuterSize < HTMLDivElement > ( ) ;
157- const { ref : selectionColumnHeaderRef , width : selectionColumnWidth } = useElementOuterSize < HTMLTableCellElement > ( ) ;
158-
159- const mergedTableRef = useMergedRef ( localTableRef , tableRef ) ;
160- const mergedViewportRef = useMergedRef ( localScrollViewportRef , scrollViewportRef ) ;
146+ const { refs, onScroll : handleScrollPositionChange } = useDataTableInjectCssVariables ( {
147+ scrollCallbacks : {
148+ onScroll,
149+ onScrollToTop,
150+ onScrollToBottom,
151+ onScrollToLeft,
152+ onScrollToRight,
153+ } ,
154+ withRowBorders : otherProps . withRowBorders ,
155+ } ) ;
161156
162- const [ scrolledToTop , setScrolledToTop ] = useState ( true ) ;
163- const [ scrolledToBottom , setScrolledToBottom ] = useState ( true ) ;
164- const [ scrolledToLeft , setScrolledToLeft ] = useState ( true ) ;
165- const [ scrolledToRight , setScrolledToRight ] = useState ( true ) ;
157+ const mergedTableRef = useMergedRef ( refs . table , tableRef ) ;
158+ const mergedViewportRef = useMergedRef ( refs . scrollViewport , scrollViewportRef ) ;
166159
167160 const rowExpansionInfo = useRowExpansion < T > ( { rowExpansion, records, idAccessor } ) ;
168161
169- const processScrolling = useCallback ( ( ) => {
170- const scrollTop = localScrollViewportRef . current ?. scrollTop ?? 0 ;
171- const scrollLeft = localScrollViewportRef . current ?. scrollLeft ?? 0 ;
172-
173- if ( fetching || tableHeight <= scrollViewportHeight ) {
174- setScrolledToTop ( true ) ;
175- setScrolledToBottom ( true ) ;
176- } else {
177- const newScrolledToTop = scrollTop === 0 ;
178- const newScrolledToBottom = tableHeight - scrollTop - scrollViewportHeight < 1 ;
179- setScrolledToTop ( newScrolledToTop ) ;
180- setScrolledToBottom ( newScrolledToBottom ) ;
181- if ( newScrolledToTop && newScrolledToTop !== scrolledToTop ) onScrollToTop ?.( ) ;
182- if ( newScrolledToBottom && newScrolledToBottom !== scrolledToBottom ) onScrollToBottom ?.( ) ;
183- }
184-
185- if ( fetching || tableWidth === scrollViewportWidth ) {
186- setScrolledToLeft ( true ) ;
187- setScrolledToRight ( true ) ;
188- } else {
189- const newScrolledToLeft = scrollLeft === 0 ;
190- const newScrolledToRight = tableWidth - scrollLeft - scrollViewportWidth < 1 ;
191- setScrolledToLeft ( newScrolledToLeft ) ;
192- setScrolledToRight ( newScrolledToRight ) ;
193- if ( newScrolledToLeft && newScrolledToLeft !== scrolledToLeft ) onScrollToLeft ?.( ) ;
194- if ( newScrolledToRight && newScrolledToRight !== scrolledToRight ) onScrollToRight ?.( ) ;
195- }
196- } , [
197- fetching ,
198- onScrollToBottom ,
199- onScrollToLeft ,
200- onScrollToRight ,
201- onScrollToTop ,
202- scrollViewportHeight ,
203- localScrollViewportRef ,
204- scrollViewportWidth ,
205- scrolledToBottom ,
206- scrolledToLeft ,
207- scrolledToRight ,
208- scrolledToTop ,
209- tableHeight ,
210- tableWidth ,
211- ] ) ;
212-
213- useIsomorphicLayoutEffect ( processScrolling , [ processScrolling ] ) ;
214-
215- const debouncedProcessScrolling = useDebouncedCallback ( processScrolling , 50 ) ;
216-
217- const handleScrollPositionChange = useCallback (
218- ( e : { x : number ; y : number } ) => {
219- onScroll ?.( e ) ;
220- debouncedProcessScrolling ( ) ;
221- } ,
222- [ debouncedProcessScrolling , onScroll ]
223- ) ;
224-
225162 const handlePageChange = useCallback (
226163 ( page : number ) => {
227- localScrollViewportRef . current ?. scrollTo ( { top : 0 , left : 0 } ) ;
164+ refs . scrollViewport . current ?. scrollTo ( { top : 0 , left : 0 } ) ;
228165 onPageChange ! ( page ) ;
229166 } ,
230- [ onPageChange , localScrollViewportRef ]
167+ [ onPageChange , refs . scrollViewport ]
231168 ) ;
232169
233170 const recordsLength = records ?. length ;
@@ -263,7 +200,7 @@ export function DataTable<T>({
263200 ] ) ;
264201
265202 const { lastSelectionChangeIndex, setLastSelectionChangeIndex } = useLastSelectionChangeIndex ( recordIds ) ;
266- const selectorCellShadowVisible = selectionColumnVisible && ! scrolledToLeft && ! pinFirstColumn ;
203+ const selectorCellShadowVisible = selectionColumnVisible && ! pinFirstColumn ;
267204
268205 const marginProperties = { m, my, mx, mt, mb, ml, mr } ;
269206
@@ -278,6 +215,7 @@ export function DataTable<T>({
278215 return (
279216 < DataTableColumnsProvider { ...dragToggle } >
280217 < Box
218+ ref = { refs . root }
281219 { ...marginProperties }
282220 className = { clsx (
283221 'mantine-datatable' ,
@@ -311,14 +249,8 @@ export function DataTable<T>({
311249 >
312250 < DataTableScrollArea
313251 viewportRef = { mergedViewportRef }
314- topShadowVisible = { ! scrolledToTop }
315- leftShadowVisible = { ! scrolledToLeft }
316252 leftShadowBehind = { selectionColumnVisible || ! ! pinFirstColumn }
317- rightShadowVisible = { ! scrolledToRight }
318253 rightShadowBehind = { pinLastColumn }
319- bottomShadowVisible = { ! scrolledToBottom }
320- headerHeight = { headerHeight }
321- footerHeight = { footerHeight }
322254 onScrollPositionChange = { handleScrollPositionChange }
323255 scrollAreaProps = { scrollAreaProps }
324256 >
@@ -332,20 +264,15 @@ export function DataTable<T>({
332264 [ TEXT_SELECTION_DISABLED ] : textSelectionDisabled ,
333265 'mantine-datatable-vertical-align-top' : verticalAlign === 'top' ,
334266 'mantine-datatable-vertical-align-bottom' : verticalAlign === 'bottom' ,
335- 'mantine-datatable-last-row-border-bottom-visible' :
336- otherProps . withRowBorders && tableHeight < scrollViewportHeight ,
337267 'mantine-datatable-pin-last-column' : pinLastColumn ,
338- 'mantine-datatable-pin-last-column-scrolled' : ! scrolledToRight && pinLastColumn ,
339268 'mantine-datatable-selection-column-visible' : selectionColumnVisible ,
340269 'mantine-datatable-pin-first-column' : pinFirstColumn ,
341- 'mantine-datatable-pin-first-column-scrolled' : ! scrolledToLeft && pinFirstColumn ,
342270 'mantine-datatable-resizable-columns' : hasResizableColumns ,
343271 } ,
344272 classNames ?. table
345273 ) }
346274 style = { {
347275 ...styles ?. table ,
348- '--mantine-datatable-selection-column-width' : `${ selectionColumnWidth } px` ,
349276 } }
350277 data-striped = { ( recordsLength && striped ) || undefined }
351278 data-highlight-on-hover = { highlightOnHover || undefined }
@@ -354,8 +281,8 @@ export function DataTable<T>({
354281 { noHeader ? null : (
355282 < DataTableColumnsProvider { ...dragToggle } >
356283 < DataTableHeader < T >
357- ref = { headerRef }
358- selectionColumnHeaderRef = { selectionColumnHeaderRef }
284+ ref = { refs . header }
285+ selectionColumnHeaderRef = { refs . selectionColumnHeader }
359286 className = { classNames ?. header }
360287 style = { styles ?. header }
361288 columns = { effectiveColumns }
@@ -456,14 +383,13 @@ export function DataTable<T>({
456383
457384 { effectiveColumns . some ( ( { footer } ) => footer ) && (
458385 < DataTableFooter < T >
459- ref = { footerRef }
386+ ref = { refs . footer }
460387 className = { classNames ?. footer }
461388 style = { styles ?. footer }
462389 columns = { effectiveColumns }
463390 defaultColumnProps = { defaultColumnProps }
464391 selectionVisible = { selectionColumnVisible }
465392 selectorCellShadowVisible = { selectorCellShadowVisible }
466- scrollDiff = { tableHeight - scrollViewportHeight }
467393 />
468394 ) }
469395 </ Table >
@@ -472,7 +398,6 @@ export function DataTable<T>({
472398
473399 { page && (
474400 < DataTablePagination
475- ref = { paginationRef }
476401 className = { classNames ?. pagination }
477402 style = { styles ?. pagination }
478403 horizontalSpacing = { horizontalSpacing }
@@ -498,22 +423,14 @@ export function DataTable<T>({
498423 />
499424 ) }
500425 < DataTableLoader
501- pt = { headerHeight }
502- pb = { paginationHeight }
503426 fetching = { fetching }
504427 backgroundBlur = { loaderBackgroundBlur }
505428 customContent = { customLoader }
506429 size = { loaderSize }
507430 type = { loaderType }
508431 color = { loaderColor }
509432 />
510- < DataTableEmptyState
511- pt = { headerHeight }
512- pb = { paginationHeight }
513- icon = { noRecordsIcon }
514- text = { noRecordsText }
515- active = { ! fetching && ! recordsLength }
516- >
433+ < DataTableEmptyState icon = { noRecordsIcon } text = { noRecordsText } active = { ! fetching && ! recordsLength } >
517434 { emptyState }
518435 </ DataTableEmptyState >
519436 </ Box >
0 commit comments