forked from microsoft/fluentui-contrib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Keep header and body in sync when the DataGrid columns are overflowing …
…microsoft#176 Previously, when using resizableColumns and resizableColumnsOptions.autoFitColumns = false, only the body or the header could be scrolled and they would be out of sync This changes synchronies the scrolling between the two so scrolling horizontally on either affects the other as if you were scrolling on a shared parent
- Loading branch information
1 parent
70b19d2
commit b3af165
Showing
16 changed files
with
278 additions
and
22 deletions.
There are no files selected for viewing
5 changes: 3 additions & 2 deletions
5
packages/react-data-grid-react-window/src/components/DataGrid/DataGrid.tsx
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
27 changes: 27 additions & 0 deletions
27
packages/react-data-grid-react-window/src/components/DataGrid/renderDataGrid.tsx
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,27 @@ | ||
import * as React from 'react'; | ||
import { | ||
DataGridContextValues, | ||
DataGridState, | ||
renderDataGrid_unstable as baseRender, | ||
} from '@fluentui/react-components'; | ||
import { HeaderRefContextProvider } from '../../contexts/headerRefContext'; | ||
import { BodyRefContextProvider } from '../../contexts/bodyRefContext'; | ||
|
||
/** | ||
* Render the final JSX of DataGrid | ||
*/ | ||
export const renderDataGrid_unstable = ( | ||
state: DataGridState, | ||
contextValues: DataGridContextValues | ||
) => { | ||
const headerRef = React.useRef<HTMLDivElement | null>(null); | ||
const bodyRef = React.useRef<HTMLDivElement | null>(null); | ||
|
||
return ( | ||
<HeaderRefContextProvider value={headerRef}> | ||
<BodyRefContextProvider value={bodyRef}> | ||
{baseRender(state, contextValues)} | ||
</BodyRefContextProvider> | ||
</HeaderRefContextProvider> | ||
); | ||
}; |
27 changes: 27 additions & 0 deletions
27
packages/react-data-grid-react-window/src/components/DataGrid/useDataGridStyles.styles.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,27 @@ | ||
import { | ||
DataGridState, | ||
makeStyles, | ||
mergeClasses, | ||
useDataGridStyles_unstable as useDataGridStylesBase_unstable, | ||
} from '@fluentui/react-components'; | ||
|
||
const useStyles = makeStyles({ | ||
root: { | ||
// DataGrid gets min-width: fit-content applied directly to the element, thus the need for !important | ||
// without auto width, the DataGrid will not scroll | ||
minWidth: 'auto !important', | ||
}, | ||
}); | ||
|
||
/** | ||
* Apply styling to the DataGrid slots based on the state | ||
*/ | ||
export const useDataGridStyles_unstable = ( | ||
state: DataGridState | ||
): DataGridState => { | ||
const classes = useStyles(); | ||
state.root.className = mergeClasses(classes.root, state.root.className); | ||
|
||
useDataGridStylesBase_unstable(state); | ||
return state; | ||
}; |
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
24 changes: 24 additions & 0 deletions
24
packages/react-data-grid-react-window/src/components/DataGridHeader/DataGridHeader.tsx
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,24 @@ | ||
import * as React from 'react'; | ||
import { | ||
renderDataGridHeader_unstable, | ||
type DataGridHeaderProps, | ||
type ForwardRefComponent, | ||
} from '@fluentui/react-components'; | ||
import { useDataGridHeader_unstable } from './useDataGridHeader'; | ||
import { useDataGridHeaderStyles_unstable } from './useDataGridHeaderStyles.styles'; | ||
|
||
/** | ||
* DataGridHeader component | ||
*/ | ||
export const DataGridHeader: ForwardRefComponent<DataGridHeaderProps> & | ||
((props: DataGridHeaderProps) => JSX.Element) = React.forwardRef( | ||
(props, ref) => { | ||
const state = useDataGridHeader_unstable(props, ref); | ||
|
||
useDataGridHeaderStyles_unstable(state); | ||
return renderDataGridHeader_unstable(state); | ||
} | ||
) as ForwardRefComponent<DataGridHeaderProps> & | ||
((props: DataGridHeaderProps) => JSX.Element); | ||
|
||
DataGridHeader.displayName = 'DataGridHeader'; |
2 changes: 2 additions & 0 deletions
2
packages/react-data-grid-react-window/src/components/DataGridHeader/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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './DataGridHeader'; | ||
export * from './useDataGridHeader'; |
58 changes: 58 additions & 0 deletions
58
packages/react-data-grid-react-window/src/components/DataGridHeader/useDataGridHeader.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,58 @@ | ||
import * as React from 'react'; | ||
import { | ||
useDataGridHeader_unstable as useBaseState, | ||
DataGridHeaderProps, | ||
DataGridHeaderState, | ||
} from '@fluentui/react-components'; | ||
import { useBodyRefContext } from '../../contexts/bodyRefContext'; | ||
import { useHeaderRefContext } from '../../contexts/headerRefContext'; | ||
|
||
const setRef = (ref: React.Ref<HTMLElement>, value: HTMLElement | null) => { | ||
if (typeof ref === 'function') { | ||
ref(value); | ||
} else if (ref) { | ||
(ref as React.MutableRefObject<HTMLElement | null>).current = value; | ||
} | ||
}; | ||
|
||
/** | ||
* Create the state required to render DataGridHeader. | ||
* | ||
* The returned state can be modified with hooks such as useDataGridHeaderStyles_unstable, | ||
* before being passed to renderDataGridHeader_unstable. | ||
* | ||
* @param props - props from this instance of DataGridHeader | ||
* @param ref - reference to root HTMLElement of DataGridHeader | ||
*/ | ||
export const useDataGridHeader_unstable = ( | ||
props: DataGridHeaderProps, | ||
ref: React.Ref<HTMLElement> | ||
): DataGridHeaderState => { | ||
const bodyRef = useBodyRefContext(); | ||
const headerRef = useHeaderRefContext(); | ||
|
||
const onScroll = React.useCallback(() => { | ||
if (bodyRef.current && headerRef.current) { | ||
bodyRef.current.scroll({ | ||
left: headerRef.current.scrollLeft, | ||
behavior: 'instant', | ||
}); | ||
} | ||
}, []); | ||
|
||
const setupRef = React.useCallback((element: HTMLElement | null) => { | ||
setRef(ref, element); | ||
headerRef.current?.removeEventListener('scroll', onScroll); | ||
|
||
headerRef.current = element; | ||
if (element) { | ||
element.addEventListener('scroll', onScroll); | ||
} | ||
}, []); | ||
|
||
const baseState = useBaseState(props, setupRef); | ||
|
||
return { | ||
...baseState, | ||
}; | ||
}; |
31 changes: 31 additions & 0 deletions
31
...ct-data-grid-react-window/src/components/DataGridHeader/useDataGridHeaderStyles.styles.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,31 @@ | ||
import { | ||
makeStyles, | ||
mergeClasses, | ||
useDataGridHeaderStyles_unstable as useDataGridHeaderStylesBase_unstable, | ||
DataGridHeaderState, | ||
} from '@fluentui/react-components'; | ||
|
||
const useStyles = makeStyles({ | ||
root: { | ||
overflowX: 'auto', | ||
// Hide the scrollbar in the header, it is synced to the scrollbar of the body so shouldn't be shown | ||
scrollbarWidth: 'none', | ||
'::-webkit-scrollbar': { | ||
width: 0, | ||
height: 0, | ||
}, | ||
}, | ||
}); | ||
|
||
/** | ||
* Apply styling to the DataGridHeader slots based on the state | ||
*/ | ||
export const useDataGridHeaderStyles_unstable = ( | ||
state: DataGridHeaderState | ||
): DataGridHeaderState => { | ||
const classes = useStyles(); | ||
state.root.className = mergeClasses(classes.root, state.root.className); | ||
|
||
useDataGridHeaderStylesBase_unstable(state); | ||
return state; | ||
}; |
4 changes: 2 additions & 2 deletions
4
packages/react-data-grid-react-window/src/components/DataGridRow/DataGridRow.tsx
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
35 changes: 18 additions & 17 deletions
35
packages/react-data-grid-react-window/src/components/DataGridRow/useDataGridRow.styles.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,24 +1,25 @@ | ||
import * as React from 'react'; | ||
import type { | ||
DataGridRowProps, | ||
import { | ||
makeStyles, | ||
mergeClasses, | ||
useDataGridRowStyles_unstable as useDataGridRowStylesBase_unstable, | ||
DataGridRowState, | ||
} from '@fluentui/react-components'; | ||
import { useDataGridRow_unstable as useBaseState } from '@fluentui/react-components'; | ||
import { useTableRowIndexContext } from '../../contexts/rowIndexContext'; | ||
|
||
const useStyles = makeStyles({ | ||
root: { | ||
minWidth: 'fit-content', | ||
}, | ||
}); | ||
|
||
/** | ||
* Create the state required to render DataGridRow. | ||
* | ||
* The returned state can be modified with hooks such as useDataGridRowStyles_unstable, | ||
* before being passed to renderDataGridRow_unstable. | ||
* | ||
* @param props - props from this instance of DataGridRow | ||
* @param ref - reference to root HTMLElement of DataGridRow | ||
* Apply styling to the DataGridRow slots based on the state | ||
*/ | ||
export const useDataGridRow_unstable = ( | ||
props: DataGridRowProps, | ||
ref: React.Ref<HTMLElement> | ||
export const useDataGridRowStyles_unstable = ( | ||
state: DataGridRowState | ||
): DataGridRowState => { | ||
const rowIndex = useTableRowIndexContext(); | ||
return useBaseState({ ...props, 'aria-rowindex': rowIndex }, ref); | ||
const classes = useStyles(); | ||
state.root.className = mergeClasses(classes.root, state.root.className); | ||
|
||
useDataGridRowStylesBase_unstable(state); | ||
return state; | ||
}; |
24 changes: 24 additions & 0 deletions
24
packages/react-data-grid-react-window/src/components/DataGridRow/useDataGridRow.tsx
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,24 @@ | ||
import * as React from 'react'; | ||
import type { | ||
DataGridRowProps, | ||
DataGridRowState, | ||
} from '@fluentui/react-components'; | ||
import { useDataGridRow_unstable as useBaseState } from '@fluentui/react-components'; | ||
import { useTableRowIndexContext } from '../../contexts/rowIndexContext'; | ||
|
||
/** | ||
* Create the state required to render DataGridRow. | ||
* | ||
* The returned state can be modified with hooks such as useDataGridRowStyles_unstable, | ||
* before being passed to renderDataGridRow_unstable. | ||
* | ||
* @param props - props from this instance of DataGridRow | ||
* @param ref - reference to root HTMLElement of DataGridRow | ||
*/ | ||
export const useDataGridRow_unstable = ( | ||
props: DataGridRowProps, | ||
ref: React.Ref<HTMLElement> | ||
): DataGridRowState => { | ||
const rowIndex = useTableRowIndexContext(); | ||
return useBaseState({ ...props, 'aria-rowindex': rowIndex }, ref); | ||
}; |
15 changes: 15 additions & 0 deletions
15
packages/react-data-grid-react-window/src/contexts/bodyRefContext.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,15 @@ | ||
import * as React from 'react'; | ||
|
||
const bodyRefContext: React.Context< | ||
React.MutableRefObject<HTMLElement | null> | ||
> = React.createContext<React.MutableRefObject<HTMLElement | null>>({ | ||
current: null, | ||
}); | ||
|
||
export const bodyRefContextDefaultValue: React.MutableRefObject<HTMLElement | null> = | ||
{ current: null }; | ||
|
||
export const useBodyRefContext = () => | ||
React.useContext(bodyRefContext) ?? bodyRefContextDefaultValue; | ||
|
||
export const BodyRefContextProvider = bodyRefContext.Provider; |
15 changes: 15 additions & 0 deletions
15
packages/react-data-grid-react-window/src/contexts/headerRefContext.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,15 @@ | ||
import * as React from 'react'; | ||
|
||
const headerRefContext: React.Context< | ||
React.MutableRefObject<HTMLElement | null> | ||
> = React.createContext<React.MutableRefObject<HTMLElement | null>>({ | ||
current: null, | ||
}); | ||
|
||
export const headerRefContextDefaultValue: React.MutableRefObject<HTMLElement | null> = | ||
{ current: null }; | ||
|
||
export const useHeaderRefContext = () => | ||
React.useContext(headerRefContext) ?? headerRefContextDefaultValue; | ||
|
||
export const HeaderRefContextProvider = headerRefContext.Provider; |
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