-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement DataGridBody powered by react-window (#26081)
* feat: Implement DataGridBody powered by react-window Uses hooks to recompose `DataGridBody` that uses react-window internally. This component should be a straight replacement for the standard `DataGridBody` that supports virtualization. * remove useless import * update datagrid * refactor: render function children called in component render function Components like `DataGridBody` and `DataGridRow` only accept render functions as children. These render functions were always called during the `useComponent` hook. This was unnecessary, and makes recomposition harder because data is always processed even if the recomposed component should render children differently. * changefile * updates * remove useless story * changefile * update md * changefile * useScrollbarWidth * update changefile entry * remove unnecessary dependencies * remove TODO * expose width as prop * fix comment typo * fix datagrid virtualization story import * use unknown in * change to * add incrementing index to virtualization examples * update api md
- Loading branch information
Showing
28 changed files
with
475 additions
and
12 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
change/@fluentui-react-components-6479a8c1-a7d4-46a2-b313-29c51016d196.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "minor", | ||
"comment": "feat: Export RowIdContextProvider and useRowIdContext from react-table", | ||
"packageName": "@fluentui/react-components", | ||
"email": "[email protected]", | ||
"dependentChangeType": "patch" | ||
} |
7 changes: 7 additions & 0 deletions
7
change/@fluentui-react-table-670a84f2-9332-45fb-9051-f29c43d81101.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "prerelease", | ||
"comment": "feat: Export RowIdProvider", | ||
"packageName": "@fluentui/react-table", | ||
"email": "[email protected]", | ||
"dependentChangeType": "patch" | ||
} |
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
14 changes: 14 additions & 0 deletions
14
packages/react-components/react-data-grid-react-window/.storybook/main.js
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,14 @@ | ||
const rootMain = require('../../../../.storybook/main'); | ||
|
||
module.exports = /** @type {Omit<import('../../../../.storybook/main'), 'typescript'|'babel'>} */ ({ | ||
...rootMain, | ||
stories: [...rootMain.stories, '../stories/**/*.stories.mdx', '../stories/**/index.stories.@(ts|tsx)'], | ||
addons: [...rootMain.addons], | ||
webpackFinal: (config, options) => { | ||
const localConfig = { ...rootMain.webpackFinal(config, options) }; | ||
|
||
// add your own webpack tweaks if needed | ||
|
||
return localConfig; | ||
}, | ||
}); |
7 changes: 7 additions & 0 deletions
7
packages/react-components/react-data-grid-react-window/.storybook/preview.js
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,7 @@ | ||
import * as rootPreview from '../../../../.storybook/preview'; | ||
|
||
/** @type {typeof rootPreview.decorators} */ | ||
export const decorators = [...rootPreview.decorators]; | ||
|
||
/** @type {typeof rootPreview.parameters} */ | ||
export const parameters = { ...rootPreview.parameters }; |
10 changes: 10 additions & 0 deletions
10
packages/react-components/react-data-grid-react-window/.storybook/tsconfig.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "../tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "", | ||
"allowJs": true, | ||
"checkJs": true, | ||
"types": ["static-assets", "environment", "storybook__addons"] | ||
}, | ||
"include": ["../stories/**/*.stories.ts", "../stories/**/*.stories.tsx", "*.js"] | ||
} |
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
1 change: 1 addition & 0 deletions
1
packages/react-components/react-data-grid-react-window/src/DataGridBody.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 @@ | ||
export * from './components/DataGridBody/index'; |
15 changes: 15 additions & 0 deletions
15
...components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.test.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,15 @@ | ||
import { DataGridBody } from './DataGridBody'; | ||
import { DataGridBodyProps } from './DataGridBody.types'; | ||
import { isConformant } from '../../testing/isConformant'; | ||
|
||
describe('DataGridBody', () => { | ||
isConformant<DataGridBodyProps>({ | ||
Component: DataGridBody, | ||
displayName: 'DataGridBody', | ||
disabledTests: ['component-has-static-classnames-object'], | ||
requiredProps: { | ||
height: 50, | ||
itemSize: 1000, | ||
}, | ||
}); | ||
}); |
18 changes: 18 additions & 0 deletions
18
...eact-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.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,18 @@ | ||
import * as React from 'react'; | ||
import type { ForwardRefComponent } from '@fluentui/react-components'; | ||
import { useDataGridBodyStyles_unstable } from './useDataGridBodyStyles'; | ||
import { useDataGridBody_unstable } from './useDataGridBody'; | ||
import { renderDataGridBody_unstable } from './renderDataGridBody'; | ||
import type { DataGridBodyProps } from './DataGridBody.types'; | ||
|
||
/** | ||
* DataGridBody component | ||
*/ | ||
export const DataGridBody: ForwardRefComponent<DataGridBodyProps> = React.forwardRef((props, ref) => { | ||
const state = useDataGridBody_unstable(props, ref); | ||
|
||
useDataGridBodyStyles_unstable(state); | ||
return renderDataGridBody_unstable(state); | ||
}); | ||
|
||
DataGridBody.displayName = 'DataGridBody'; |
46 changes: 46 additions & 0 deletions
46
...components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.types.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,46 @@ | ||
import * as React from 'react'; | ||
import type { | ||
RowState, | ||
DataGridBodyProps as DataGridBodyPropsBase, | ||
DataGridBodySlots as DataGridBodySlotsBase, | ||
DataGridBodyState as DataGridBodyStateBase, | ||
} from '@fluentui/react-components/unstable'; | ||
|
||
export type DataGridBodySlots = DataGridBodySlotsBase; | ||
|
||
// Use any here since we can't know the user types | ||
// The user is responsible for narrowing the type downstream | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export type RowRenderFunction = (row: RowState<any>, style: React.CSSProperties) => React.ReactNode; | ||
|
||
/** | ||
* DataGridBody Props | ||
*/ | ||
export type DataGridBodyProps = Omit<DataGridBodyPropsBase, 'children'> & { | ||
/** | ||
* The size of each row | ||
*/ | ||
itemSize: number; | ||
/** | ||
* The height of the virtualized container | ||
*/ | ||
height: number; | ||
/** | ||
* The width of the virtualized container | ||
* @default 100% | ||
*/ | ||
width?: string | number; | ||
/** | ||
* Children render function for rows | ||
*/ | ||
children: RowRenderFunction; | ||
}; | ||
|
||
/** | ||
* State used in rendering DataGridBody | ||
*/ | ||
export type DataGridBodyState = Omit<DataGridBodyStateBase, 'renderRow'> & | ||
Pick<DataGridBodyProps, 'itemSize' | 'height'> & | ||
Pick<Required<DataGridBodyProps>, 'width'> & { | ||
renderRow: RowRenderFunction; | ||
}; |
4 changes: 4 additions & 0 deletions
4
packages/react-components/react-data-grid-react-window/src/components/DataGridBody/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,4 @@ | ||
export * from './DataGridBody'; | ||
export * from './DataGridBody.types'; | ||
export * from './renderDataGridBody'; | ||
export * from './useDataGridBody'; |
29 changes: 29 additions & 0 deletions
29
...omponents/react-data-grid-react-window/src/components/DataGridBody/renderDataGridBody.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,29 @@ | ||
import * as React from 'react'; | ||
import type { DataGridBodyState, DataGridBodySlots } from './DataGridBody.types'; | ||
import { FixedSizeList as List, ListChildComponentProps } from 'react-window'; | ||
import { getSlots } from '@fluentui/react-components'; | ||
import { RowState, RowIdContextProvider } from '@fluentui/react-components/unstable'; | ||
|
||
/** | ||
* Render the final JSX of DataGridVirtualizedBody | ||
*/ | ||
export const renderDataGridBody_unstable = (state: DataGridBodyState) => { | ||
const { slots, slotProps } = getSlots<DataGridBodySlots>(state); | ||
|
||
return ( | ||
<slots.root {...slotProps.root}> | ||
<List | ||
itemSize={state.itemSize} | ||
width={state.width} | ||
itemData={state.rows} | ||
height={state.height} | ||
itemCount={state.rows.length} | ||
> | ||
{({ data, index, style }: ListChildComponentProps) => { | ||
const row: RowState<unknown> = data[index]; | ||
return <RowIdContextProvider value={row.rowId}>{state.renderRow(row, style)}</RowIdContextProvider>; | ||
}} | ||
</List> | ||
</slots.root> | ||
); | ||
}; |
25 changes: 25 additions & 0 deletions
25
...ct-components/react-data-grid-react-window/src/components/DataGridBody/useDataGridBody.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,25 @@ | ||
import * as React from 'react'; | ||
import type { DataGridBodyProps, DataGridBodyState } from './DataGridBody.types'; | ||
import { useDataGridBody_unstable as useDataGridBodyBase_unstable } from '@fluentui/react-components/unstable'; | ||
|
||
/** | ||
* Create the state required to render DataGridBody. | ||
* | ||
* The returned state can be modified with hooks such as useDataGridBodyStyles_unstable, | ||
* before being passed to renderDataGridBody_unstable. | ||
* | ||
* @param props - props from this instance of DataGridBody | ||
* @param ref - reference to root HTMLElement of DataGridBody | ||
*/ | ||
export const useDataGridBody_unstable = (props: DataGridBodyProps, ref: React.Ref<HTMLElement>): DataGridBodyState => { | ||
const { height, itemSize, width = '100%' } = props; | ||
const baseState = useDataGridBodyBase_unstable(props, ref); | ||
|
||
return { | ||
...baseState, | ||
itemSize, | ||
height, | ||
renderRow: props.children, | ||
width, | ||
}; | ||
}; |
10 changes: 10 additions & 0 deletions
10
...ponents/react-data-grid-react-window/src/components/DataGridBody/useDataGridBodyStyles.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,10 @@ | ||
import type { DataGridBodyState } from './DataGridBody.types'; | ||
import { useDataGridBodyStyles_unstable as useDataGridBodyStylesBase_unstable } from '@fluentui/react-components/unstable'; | ||
|
||
/** | ||
* Apply styling to the DataGridBody slots based on the state | ||
*/ | ||
export const useDataGridBodyStyles_unstable = (state: DataGridBodyState): DataGridBodyState => { | ||
useDataGridBodyStylesBase_unstable({ ...state, renderRow: () => null }); | ||
return state; | ||
}; |
5 changes: 3 additions & 2 deletions
5
packages/react-components/react-data-grid-react-window/src/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,3 @@ | ||
// TODO: replace with real exports | ||
export {}; | ||
export { DataGridBody, useDataGridBody_unstable, renderDataGridBody_unstable } from './DataGridBody'; | ||
|
||
export type { DataGridBodyProps, DataGridBodyState, DataGridBodySlots } from './DataGridBody'; |
14 changes: 14 additions & 0 deletions
14
packages/react-components/react-data-grid-react-window/src/testing/isConformant.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,14 @@ | ||
import { isConformant as baseIsConformant } from '@fluentui/react-conformance'; | ||
import type { IsConformantOptions, TestObject } from '@fluentui/react-conformance'; | ||
import griffelTests from '@fluentui/react-conformance-griffel'; | ||
|
||
export function isConformant<TProps = {}>( | ||
testInfo: Omit<IsConformantOptions<TProps>, 'componentPath'> & { componentPath?: string }, | ||
) { | ||
const defaultOptions: Partial<IsConformantOptions<TProps>> = { | ||
componentPath: require.main?.filename.replace('.test', ''), | ||
extraTests: griffelTests as TestObject<TProps>, | ||
}; | ||
|
||
baseIsConformant(defaultOptions, testInfo); | ||
} |
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 |
---|---|---|
|
@@ -17,6 +17,9 @@ | |
}, | ||
{ | ||
"path": "./tsconfig.spec.json" | ||
}, | ||
{ | ||
"path": "./.storybook/tsconfig.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
Oops, something went wrong.