diff --git a/change/@fluentui-react-components-6479a8c1-a7d4-46a2-b313-29c51016d196.json b/change/@fluentui-react-components-6479a8c1-a7d4-46a2-b313-29c51016d196.json new file mode 100644 index 00000000000000..5a11866f235b11 --- /dev/null +++ b/change/@fluentui-react-components-6479a8c1-a7d4-46a2-b313-29c51016d196.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: Export RowIdContextProvider and useRowIdContext from react-table", + "packageName": "@fluentui/react-components", + "email": "lingfangao@hotmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-table-670a84f2-9332-45fb-9051-f29c43d81101.json b/change/@fluentui-react-table-670a84f2-9332-45fb-9051-f29c43d81101.json new file mode 100644 index 00000000000000..8e7038216fad63 --- /dev/null +++ b/change/@fluentui-react-table-670a84f2-9332-45fb-9051-f29c43d81101.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "feat: Export RowIdProvider", + "packageName": "@fluentui/react-table", + "email": "lingfangao@hotmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-components/etc/react-components.unstable.api.md b/packages/react-components/react-components/etc/react-components.unstable.api.md index f52d5fea7f2df2..b03c8f7d13fe43 100644 --- a/packages/react-components/react-components/etc/react-components.unstable.api.md +++ b/packages/react-components/react-components/etc/react-components.unstable.api.md @@ -178,6 +178,7 @@ import { renderTableSelectionCell_unstable } from '@fluentui/react-table'; import { renderToolbar_unstable } from '@fluentui/react-toolbar'; import { renderToolbarGroup_unstable } from '@fluentui/react-toolbar'; import { RowId } from '@fluentui/react-table'; +import { RowIdContextProvider } from '@fluentui/react-table'; import { RowState } from '@fluentui/react-table'; import { Select } from '@fluentui/react-select'; import { selectClassNames } from '@fluentui/react-select'; @@ -325,6 +326,7 @@ import { useOptionStyles_unstable } from '@fluentui/react-combobox'; import { useOverflowMenu } from '@fluentui/react-overflow'; import { useProgressBar_unstable } from '@fluentui/react-progress'; import { useProgressBarStyles_unstable } from '@fluentui/react-progress'; +import { useRowIdContext } from '@fluentui/react-table'; import { useSelect_unstable } from '@fluentui/react-select'; import { useSelectStyles_unstable } from '@fluentui/react-select'; import { useTable_unstable } from '@fluentui/react-table'; @@ -711,6 +713,8 @@ export { renderToolbarGroup_unstable } export { RowId } +export { RowIdContextProvider } + export { RowState } export { Select } @@ -1006,6 +1010,8 @@ export { useProgressBar_unstable } export { useProgressBarStyles_unstable } +export { useRowIdContext } + export { useSelect_unstable } export { useSelectStyles_unstable } diff --git a/packages/react-components/react-components/src/unstable/index.ts b/packages/react-components/react-components/src/unstable/index.ts index 22d07f68647728..f924683a441b2c 100644 --- a/packages/react-components/react-components/src/unstable/index.ts +++ b/packages/react-components/react-components/src/unstable/index.ts @@ -270,6 +270,8 @@ export { useDataGridSelectionCell_unstable, renderDataGridSelectionCell_unstable, dataGridSelectionCellClassNames, + RowIdContextProvider, + useRowIdContext, } from '@fluentui/react-table'; export type { diff --git a/packages/react-components/react-data-grid-react-window/.storybook/main.js b/packages/react-components/react-data-grid-react-window/.storybook/main.js new file mode 100644 index 00000000000000..26536b61b387f6 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/.storybook/main.js @@ -0,0 +1,14 @@ +const rootMain = require('../../../../.storybook/main'); + +module.exports = /** @type {Omit} */ ({ + ...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; + }, +}); diff --git a/packages/react-components/react-data-grid-react-window/.storybook/preview.js b/packages/react-components/react-data-grid-react-window/.storybook/preview.js new file mode 100644 index 00000000000000..1939500a3d18c7 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/.storybook/preview.js @@ -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 }; diff --git a/packages/react-components/react-data-grid-react-window/.storybook/tsconfig.json b/packages/react-components/react-data-grid-react-window/.storybook/tsconfig.json new file mode 100644 index 00000000000000..ea89218a3d916f --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/.storybook/tsconfig.json @@ -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"] +} diff --git a/packages/react-components/react-data-grid-react-window/etc/react-data-grid-react-window.api.md b/packages/react-components/react-data-grid-react-window/etc/react-data-grid-react-window.api.md index 93cd269424f58c..18359a03f337a1 100644 --- a/packages/react-components/react-data-grid-react-window/etc/react-data-grid-react-window.api.md +++ b/packages/react-components/react-data-grid-react-window/etc/react-data-grid-react-window.api.md @@ -4,6 +4,40 @@ ```ts +/// + +import type { DataGridBodyProps as DataGridBodyProps_2 } from '@fluentui/react-components/unstable'; +import type { DataGridBodySlots as DataGridBodySlots_2 } from '@fluentui/react-components/unstable'; +import type { DataGridBodyState as DataGridBodyState_2 } from '@fluentui/react-components/unstable'; +import type { ForwardRefComponent } from '@fluentui/react-components'; +import * as React_2 from 'react'; +import type { RowState } from '@fluentui/react-components/unstable'; + +// @public +export const DataGridBody: ForwardRefComponent; + +// @public +export type DataGridBodyProps = Omit & { + itemSize: number; + height: number; + width?: string | number; + children: RowRenderFunction; +}; + +// @public (undocumented) +export type DataGridBodySlots = DataGridBodySlots_2; + +// @public +export type DataGridBodyState = Omit & Pick & Pick, 'width'> & { + renderRow: RowRenderFunction; +}; + +// @public +export const renderDataGridBody_unstable: (state: DataGridBodyState) => JSX.Element; + +// @public +export const useDataGridBody_unstable: (props: DataGridBodyProps, ref: React_2.Ref) => DataGridBodyState; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/react-components/react-data-grid-react-window/package.json b/packages/react-components/react-data-grid-react-window/package.json index a98453ab1592c0..9f08b2771d2d33 100644 --- a/packages/react-components/react-data-grid-react-window/package.json +++ b/packages/react-components/react-data-grid-react-window/package.json @@ -2,7 +2,7 @@ "name": "@fluentui/react-data-grid-react-window", "version": "9.0.0-alpha.0", "private": true, - "description": "Components and utilities to virtualize the Fluent UI DataGrid component", + "description": "Virtualized DataGrid components and utilities powered by react-window", "main": "lib-commonjs/index.js", "module": "lib/index.js", "typings": "./dist/index.d.ts", @@ -20,7 +20,9 @@ "lint": "just-scripts lint", "test": "jest --passWithNoTests", "type-check": "tsc -b tsconfig.json", - "generate-api": "tsc -p ./tsconfig.lib.json --emitDeclarationOnly && just-scripts api-extractor" + "generate-api": "tsc -p ./tsconfig.lib.json --emitDeclarationOnly && just-scripts api-extractor", + "storybook": "start-storybook", + "start": "yarn storybook" }, "devDependencies": { "@fluentui/eslint-plugin": "*", @@ -30,12 +32,11 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/react-theme": "^9.1.5", - "@fluentui/react-utilities": "^9.4.0", - "@griffel/react": "^1.5.2", + "react-window": "^1.8.6", "tslib": "^2.1.0" }, "peerDependencies": { + "@fluentui/react-components": "^9.7.4", "@types/react": ">=16.8.0 <19.0.0", "@types/react-dom": ">=16.8.0 <19.0.0", "react": ">=16.8.0 <19.0.0", diff --git a/packages/react-components/react-data-grid-react-window/src/DataGridBody.ts b/packages/react-components/react-data-grid-react-window/src/DataGridBody.ts new file mode 100644 index 00000000000000..67d8574eceebc8 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/DataGridBody.ts @@ -0,0 +1 @@ +export * from './components/DataGridBody/index'; diff --git a/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.test.tsx b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.test.tsx new file mode 100644 index 00000000000000..4bc16e449b3b03 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.test.tsx @@ -0,0 +1,15 @@ +import { DataGridBody } from './DataGridBody'; +import { DataGridBodyProps } from './DataGridBody.types'; +import { isConformant } from '../../testing/isConformant'; + +describe('DataGridBody', () => { + isConformant({ + Component: DataGridBody, + displayName: 'DataGridBody', + disabledTests: ['component-has-static-classnames-object'], + requiredProps: { + height: 50, + itemSize: 1000, + }, + }); +}); diff --git a/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.tsx b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.tsx new file mode 100644 index 00000000000000..2daf505f218c46 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.tsx @@ -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 = React.forwardRef((props, ref) => { + const state = useDataGridBody_unstable(props, ref); + + useDataGridBodyStyles_unstable(state); + return renderDataGridBody_unstable(state); +}); + +DataGridBody.displayName = 'DataGridBody'; diff --git a/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.types.ts b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.types.ts new file mode 100644 index 00000000000000..99545ef945c598 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/DataGridBody.types.ts @@ -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, style: React.CSSProperties) => React.ReactNode; + +/** + * DataGridBody Props + */ +export type DataGridBodyProps = Omit & { + /** + * 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 & + Pick & + Pick, 'width'> & { + renderRow: RowRenderFunction; + }; diff --git a/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/index.ts b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/index.ts new file mode 100644 index 00000000000000..5c9c471c5141a1 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/index.ts @@ -0,0 +1,4 @@ +export * from './DataGridBody'; +export * from './DataGridBody.types'; +export * from './renderDataGridBody'; +export * from './useDataGridBody'; diff --git a/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/renderDataGridBody.tsx b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/renderDataGridBody.tsx new file mode 100644 index 00000000000000..c267b0acc8ce6e --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/renderDataGridBody.tsx @@ -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(state); + + return ( + + + {({ data, index, style }: ListChildComponentProps) => { + const row: RowState = data[index]; + return {state.renderRow(row, style)}; + }} + + + ); +}; diff --git a/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/useDataGridBody.ts b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/useDataGridBody.ts new file mode 100644 index 00000000000000..88104effe8c6a4 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/useDataGridBody.ts @@ -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): DataGridBodyState => { + const { height, itemSize, width = '100%' } = props; + const baseState = useDataGridBodyBase_unstable(props, ref); + + return { + ...baseState, + itemSize, + height, + renderRow: props.children, + width, + }; +}; diff --git a/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/useDataGridBodyStyles.ts b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/useDataGridBodyStyles.ts new file mode 100644 index 00000000000000..17dad476c41228 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/components/DataGridBody/useDataGridBodyStyles.ts @@ -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; +}; diff --git a/packages/react-components/react-data-grid-react-window/src/index.ts b/packages/react-components/react-data-grid-react-window/src/index.ts index aacbad0068e241..c3328a9b2c49b4 100644 --- a/packages/react-components/react-data-grid-react-window/src/index.ts +++ b/packages/react-components/react-data-grid-react-window/src/index.ts @@ -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'; diff --git a/packages/react-components/react-data-grid-react-window/src/testing/isConformant.ts b/packages/react-components/react-data-grid-react-window/src/testing/isConformant.ts new file mode 100644 index 00000000000000..77f88408cbd839 --- /dev/null +++ b/packages/react-components/react-data-grid-react-window/src/testing/isConformant.ts @@ -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( + testInfo: Omit, 'componentPath'> & { componentPath?: string }, +) { + const defaultOptions: Partial> = { + componentPath: require.main?.filename.replace('.test', ''), + extraTests: griffelTests as TestObject, + }; + + baseIsConformant(defaultOptions, testInfo); +} diff --git a/packages/react-components/react-data-grid-react-window/tsconfig.json b/packages/react-components/react-data-grid-react-window/tsconfig.json index 12ca516af1c5b2..1941a041d46c19 100644 --- a/packages/react-components/react-data-grid-react-window/tsconfig.json +++ b/packages/react-components/react-data-grid-react-window/tsconfig.json @@ -17,6 +17,9 @@ }, { "path": "./tsconfig.spec.json" + }, + { + "path": "./.storybook/tsconfig.json" } ] } diff --git a/packages/react-components/react-data-grid-react-window/tsconfig.lib.json b/packages/react-components/react-data-grid-react-window/tsconfig.lib.json index b2da24eff1b32f..6f90cf95c005bd 100644 --- a/packages/react-components/react-data-grid-react-window/tsconfig.lib.json +++ b/packages/react-components/react-data-grid-react-window/tsconfig.lib.json @@ -9,6 +9,14 @@ "inlineSources": true, "types": ["static-assets", "environment"] }, - "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"], + "exclude": [ + "./src/testing/**", + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.stories.ts", + "**/*.stories.tsx" + ], "include": ["./src/**/*.ts", "./src/**/*.tsx"] } diff --git a/packages/react-components/react-data-grid-react-window/tsconfig.spec.json b/packages/react-components/react-data-grid-react-window/tsconfig.spec.json index 469fcba4d7ba75..911456fe4b4d91 100644 --- a/packages/react-components/react-data-grid-react-window/tsconfig.spec.json +++ b/packages/react-components/react-data-grid-react-window/tsconfig.spec.json @@ -5,5 +5,13 @@ "outDir": "dist", "types": ["jest", "node"] }, - "include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx", "**/*.d.ts"] + "include": [ + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.d.ts", + "./src/testing/**/*.ts", + "./src/testing/**/*.tsx" + ] } diff --git a/packages/react-components/react-table/etc/react-table.api.md b/packages/react-components/react-table/etc/react-table.api.md index 91f2eab30c7464..16312cb2e9c825 100644 --- a/packages/react-components/react-table/etc/react-table.api.md +++ b/packages/react-components/react-table/etc/react-table.api.md @@ -250,7 +250,10 @@ export const renderTableSelectionCell_unstable: (state: TableSelectionCellState) export type RowId = string | number; // @public (undocumented) -export type RowRenderFunction = (row: RowState) => React_2.ReactNode; +export const RowIdContextProvider: React_2.Provider; + +// @public (undocumented) +export type RowRenderFunction = (row: RowState, ...rest: any[]) => React_2.ReactNode; // @public (undocumented) export interface RowState { @@ -541,6 +544,9 @@ export const useDataGridSelectionCellStyles_unstable: (state: DataGridSelectionC // @public export const useDataGridStyles_unstable: (state: DataGridState) => DataGridState; +// @public (undocumented) +export const useRowIdContext: () => RowId; + // @public export const useTable_unstable: (props: TableProps, ref: React_2.Ref) => TableState; diff --git a/packages/react-components/react-table/src/components/DataGridBody/DataGridBody.types.ts b/packages/react-components/react-table/src/components/DataGridBody/DataGridBody.types.ts index 620aec2ce1e277..999b4d46ed9490 100644 --- a/packages/react-components/react-table/src/components/DataGridBody/DataGridBody.types.ts +++ b/packages/react-components/react-table/src/components/DataGridBody/DataGridBody.types.ts @@ -7,7 +7,7 @@ export type DataGridBodySlots = TableBodySlots; // 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) => React.ReactNode; +export type RowRenderFunction = (row: RowState, ...rest: any[]) => React.ReactNode; /** * DataGridBody Props diff --git a/packages/react-components/react-table/src/index.ts b/packages/react-components/react-table/src/index.ts index a9bd968656b8b8..b4314d66966197 100644 --- a/packages/react-components/react-table/src/index.ts +++ b/packages/react-components/react-table/src/index.ts @@ -73,6 +73,7 @@ export { export type { TableHeaderCellProps, TableHeaderCellSlots, TableHeaderCellState } from './TableHeaderCell'; export { TableContextProvider, useTableContext } from './contexts/tableContext'; +export { useRowIdContext, RowIdContextProvider } from './contexts/rowIdContext'; export { TableSelectionCell, useTableSelectionCellStyles_unstable, diff --git a/packages/react-components/react-table/stories/DataGrid/Virtualization.stories.tsx b/packages/react-components/react-table/stories/DataGrid/Virtualization.stories.tsx new file mode 100644 index 00000000000000..03e801cd9bf553 --- /dev/null +++ b/packages/react-components/react-table/stories/DataGrid/Virtualization.stories.tsx @@ -0,0 +1,181 @@ +import * as React from 'react'; +import { + FolderRegular, + EditRegular, + OpenRegular, + DocumentRegular, + PeopleRegular, + DocumentPdfRegular, + VideoRegular, +} from '@fluentui/react-icons'; +import { PresenceBadgeStatus, Avatar, useScrollbarWidth, useFluent } from '@fluentui/react-components'; +import { + DataGridRow, + DataGrid, + DataGridHeader, + DataGridHeaderCell, + DataGridCell, + ColumnDefinition, + RowState, + createColumn, + TableCellLayout, +} from '@fluentui/react-components/unstable'; +import { DataGridBody } from '@fluentui/react-data-grid-react-window'; + +type FileCell = { + label: string; + icon: JSX.Element; +}; + +type LastUpdatedCell = { + label: string; + timestamp: number; +}; + +type LastUpdateCell = { + label: string; + icon: JSX.Element; +}; + +type AuthorCell = { + label: string; + status: PresenceBadgeStatus; +}; + +type Item = { + index: number; + file: FileCell; + author: AuthorCell; + lastUpdated: LastUpdatedCell; + lastUpdate: LastUpdateCell; +}; + +export const Virtualization = () => { + const { targetDocument } = useFluent(); + const scrollbarWidth = useScrollbarWidth({ targetDocument }); + const columns: ColumnDefinition[] = React.useMemo( + () => [ + createColumn({ + columnId: 'file', + compare: (a, b) => { + return a.file.label.localeCompare(b.file.label); + }, + renderHeaderCell: () => { + return 'File'; + }, + renderCell: item => { + return ( + + [{item.index}] + {item.file.label} + + ); + }, + }), + createColumn({ + columnId: 'author', + compare: (a, b) => { + return a.author.label.localeCompare(b.author.label); + }, + renderHeaderCell: () => { + return 'Author'; + }, + renderCell: item => { + return ( + }> + {item.author.label} + + ); + }, + }), + createColumn({ + columnId: 'lastUpdated', + compare: (a, b) => { + return a.lastUpdated.timestamp - b.lastUpdated.timestamp; + }, + renderHeaderCell: () => { + return 'Last updated'; + }, + + renderCell: item => { + return item.lastUpdated.label; + }, + }), + createColumn({ + columnId: 'lastUpdate', + compare: (a, b) => { + return a.lastUpdate.label.localeCompare(b.lastUpdate.label); + }, + renderHeaderCell: () => { + return 'Last update'; + }, + renderCell: item => { + return {item.lastUpdate.label}; + }, + }), + ], + [], + ); + + const items = React.useMemo(() => { + const baseItems = [ + { + file: { label: 'Meeting notes', icon: }, + author: { label: 'Max Mustermann', status: 'available' }, + lastUpdated: { label: '7h ago', timestamp: 1 }, + lastUpdate: { + label: 'You edited this', + icon: , + }, + }, + { + file: { label: 'Thursday presentation', icon: }, + author: { label: 'Erika Mustermann', status: 'busy' }, + lastUpdated: { label: 'Yesterday at 1:45 PM', timestamp: 2 }, + lastUpdate: { + label: 'You recently opened this', + icon: , + }, + }, + { + file: { label: 'Training recording', icon: }, + author: { label: 'John Doe', status: 'away' }, + lastUpdated: { label: 'Yesterday at 1:45 PM', timestamp: 2 }, + lastUpdate: { + label: 'You recently opened this', + icon: , + }, + }, + { + file: { label: 'Purchase order', icon: }, + author: { label: 'Jane Doe', status: 'offline' }, + lastUpdated: { label: 'Tue at 9:30 AM', timestamp: 3 }, + lastUpdate: { + label: 'You shared this in a Teams chat', + icon: , + }, + }, + ]; + + return new Array(1500).fill(0).map((_, i) => ({ ...baseItems[i % baseItems.length], index: i })); + }, []); + + return ( + + + + {({ renderHeaderCell }: ColumnDefinition) => ( + {renderHeaderCell()} + )} + + + + {({ item, rowId }: RowState, style) => ( + + {({ renderCell }: ColumnDefinition) => {renderCell(item)}} + + )} + + + ); +}; diff --git a/packages/react-components/react-table/stories/DataGrid/index.stories.tsx b/packages/react-components/react-table/stories/DataGrid/index.stories.tsx index c025ee60b77ccb..52291642cfe332 100644 --- a/packages/react-components/react-table/stories/DataGrid/index.stories.tsx +++ b/packages/react-components/react-table/stories/DataGrid/index.stories.tsx @@ -19,7 +19,9 @@ export { SingleSelect } from './SingleSelect.stories'; export { SingleSelectControlled } from './SingleSelectControlled.stories'; export { SubtleSelection } from './SubtleSelection.stories'; export { SelectionAppearance } from './SelectionAppearance.stories'; +export { Virtualization } from './Virtualization.stories'; export { CustomRowId } from './CustomRowId.stories'; + export default { title: 'Preview Components/DataGrid', component: DataGrid, diff --git a/packages/react-components/react-table/stories/Table/Virtualization.stories.tsx b/packages/react-components/react-table/stories/Table/Virtualization.stories.tsx index afa079dc2d6030..d2f041b6ae55ef 100644 --- a/packages/react-components/react-table/stories/Table/Virtualization.stories.tsx +++ b/packages/react-components/react-table/stories/Table/Virtualization.stories.tsx @@ -194,7 +194,10 @@ export const Virtualization = () => { > - {item.file.label} + + [{index}] + {item.file.label} +