From c5d5a17962b1347bee77516c741fbe24ee73917f Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Mon, 5 Feb 2024 10:17:08 -0500 Subject: [PATCH] [DataGrid] Add slot typings (#11795) Co-authored-by: Andrew Cherniavskyi Co-authored-by: Bilal Shafi --- .../data-grid/components/CustomColumnMenu.tsx | 3 +- .../components/CustomLoadingOverlayGrid.tsx | 4 +- .../CustomLoadingOverlayGrid.tsx.preview | 2 +- docs/data/data-grid/components/components.md | 18 ++- .../editing/FullFeaturedCrudGrid.tsx | 3 +- .../editing/FullFeaturedCrudGrid.tsx.preview | 2 +- .../data-grid/editing/StartEditButtonGrid.tsx | 3 +- .../filtering/CustomFilterPanelPosition.tsx | 3 +- .../CustomFilterPanelPosition.tsx.preview | 2 +- .../row-updates/InfiniteLoadingGrid.tsx | 4 +- .../InfiniteLoadingGrid.tsx.preview | 2 +- .../state/RestoreStateInitialState.tsx | 3 +- .../RestoreStateInitialState.tsx.preview | 2 +- .../migration-data-grid-v6.md | 1 + .../src/DataGridPremium/DataGridPremium.tsx | 2 + .../src/DataGridPro/DataGridPro.tsx | 2 + .../GridHeaderFilterMenuContainer.tsx | 7 +- .../x-data-grid/src/DataGrid/DataGrid.tsx | 2 + .../src/components/GridPagination.tsx | 2 +- .../x-data-grid/src/components/GridRow.tsx | 2 +- .../components/base/GridFooterPlaceholder.tsx | 4 +- .../GridCellCheckboxRenderer.tsx | 4 +- .../columnSelection/GridHeaderCheckbox.tsx | 2 +- .../panel/filterPanel/GridFilterForm.tsx | 6 +- .../filterPanel/GridFilterInputBoolean.tsx | 4 +- .../GridFilterInputSingleSelect.tsx | 6 +- .../grid/x-data-grid/src/joy/joySlots.tsx | 29 ++-- .../src/models/api/gridLocaleTextApi.ts | 6 +- .../src/models/gridSlotsComponent.ts | 74 +++++------ .../src/models/gridSlotsComponentsProps.ts | 125 ++++++++++-------- .../src/tests/filtering.DataGrid.test.tsx | 5 +- scripts/x-data-grid-premium.exports.json | 8 +- scripts/x-data-grid-pro.exports.json | 8 +- scripts/x-data-grid.exports.json | 8 +- 34 files changed, 208 insertions(+), 150 deletions(-) diff --git a/docs/data/data-grid/components/CustomColumnMenu.tsx b/docs/data/data-grid/components/CustomColumnMenu.tsx index 70275eb92d00..9a0a7fa8d4f3 100644 --- a/docs/data/data-grid/components/CustomColumnMenu.tsx +++ b/docs/data/data-grid/components/CustomColumnMenu.tsx @@ -10,6 +10,7 @@ import { GridColumnMenuSortItem, useGridApiRef, DataGridPro, + GridSlots, } from '@mui/x-data-grid-pro'; import StarOutlineIcon from '@mui/icons-material/StarOutline'; @@ -119,7 +120,7 @@ export default function CustomColumnMenu() { }, ]} slots={{ - columnMenu: CustomColumnMenuComponent, + columnMenu: CustomColumnMenuComponent as GridSlots['columnMenu'], }} slotProps={{ columnMenu: { color }, diff --git a/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx b/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx index fef9a8145a76..c278f02c68a4 100644 --- a/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx +++ b/docs/data/data-grid/components/CustomLoadingOverlayGrid.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { DataGrid } from '@mui/x-data-grid'; +import { DataGrid, GridSlots } from '@mui/x-data-grid'; import LinearProgress from '@mui/material/LinearProgress'; import { useDemoData } from '@mui/x-data-grid-generator'; @@ -14,7 +14,7 @@ export default function CustomLoadingOverlayGrid() {
``` +If you want to ensure type safety, you can declare your component using the slot props typings: + +```tsx +import { GridSlotProps } from '@mui/x-data-grid'; + +function MyCustomColumnMenu( + props: GridSlotProps['columnMenu'] & { background: string; counter: number }, +) { + // ... +} +``` + ### Interacting with the data grid The grid exposes two hooks to help you to access the data grid data while overriding component slots. diff --git a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx index a3f845377b15..ea0680357f04 100644 --- a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx +++ b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx @@ -18,6 +18,7 @@ import { GridRowId, GridRowModel, GridRowEditStopReasons, + GridSlots, } from '@mui/x-data-grid'; import { randomCreatedDate, @@ -237,7 +238,7 @@ export default function FullFeaturedCrudGrid() { onRowEditStop={handleRowEditStop} processRowUpdate={processRowUpdate} slots={{ - toolbar: EditToolbar, + toolbar: EditToolbar as GridSlots['toolbar'], }} slotProps={{ toolbar: { setRows, setRowModesModel }, diff --git a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview index b060ee3cfc32..269309309210 100644 --- a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview +++ b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx.preview @@ -7,7 +7,7 @@ onRowEditStop={handleRowEditStop} processRowUpdate={processRowUpdate} slots={{ - toolbar: EditToolbar, + toolbar: EditToolbar as GridSlots['toolbar'], }} slotProps={{ toolbar: { setRows, setRowModesModel }, diff --git a/docs/data/data-grid/editing/StartEditButtonGrid.tsx b/docs/data/data-grid/editing/StartEditButtonGrid.tsx index 6397547acaac..98f848fd4e14 100644 --- a/docs/data/data-grid/editing/StartEditButtonGrid.tsx +++ b/docs/data/data-grid/editing/StartEditButtonGrid.tsx @@ -9,6 +9,7 @@ import { GridCellModes, GridEventListener, GridCellModesModel, + GridSlots, } from '@mui/x-data-grid'; import { randomCreatedDate, @@ -147,7 +148,7 @@ export default function StartEditButtonGrid() { onCellEditStop={handleCellEditStop} onCellModesModelChange={(model) => setCellModesModel(model)} slots={{ - toolbar: EditToolbar, + toolbar: EditToolbar as GridSlots['toolbar'], }} slotProps={{ toolbar: { diff --git a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx b/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx index 65f85ed66171..2f686357b240 100644 --- a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx +++ b/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { DataGrid, + GridSlots, GridToolbarContainer, GridToolbarFilterButton, } from '@mui/x-data-grid'; @@ -35,7 +36,7 @@ export default function CustomFilterPanelPosition() {
diff --git a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview index db0cc47aa791..d8a614229f5c 100644 --- a/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview +++ b/docs/data/data-grid/row-updates/InfiniteLoadingGrid.tsx.preview @@ -5,6 +5,6 @@ hideFooterPagination onRowsScrollEnd={handleOnRowsScrollEnd} slots={{ - loadingOverlay: LinearProgress, + loadingOverlay: LinearProgress as GridSlots['loadingOverlay'], }} /> \ No newline at end of file diff --git a/docs/data/data-grid/state/RestoreStateInitialState.tsx b/docs/data/data-grid/state/RestoreStateInitialState.tsx index 7e576cec4eb9..d953a4a8e5a5 100644 --- a/docs/data/data-grid/state/RestoreStateInitialState.tsx +++ b/docs/data/data-grid/state/RestoreStateInitialState.tsx @@ -5,6 +5,7 @@ import Stack from '@mui/material/Stack'; import { DataGridPro, GridInitialState, + GridSlots, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarFilterButton, @@ -62,7 +63,7 @@ export default function RestoreStateInitialState() { diff --git a/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview b/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview index cb7e99c92deb..a02338eabb0b 100644 --- a/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview +++ b/docs/data/data-grid/state/RestoreStateInitialState.tsx.preview @@ -2,7 +2,7 @@ diff --git a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md index 907ccdf3398a..6e9df3de4b2f 100644 --- a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md +++ b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md @@ -457,5 +457,6 @@ Here's the list of affected features, colDef flags and props to disable them and - The slot `row` has had these props removed: `containerWidth`, `position`. - The slot `row` has typed props now. - The slot `headerFilterCell` has had these props removed: `filterOperators`. +- All slots are now strongly typed, previously were `React.JSXElementConstructor`. diff --git a/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index e4958093925c..f013899888d8 100644 --- a/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/grid/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -23,6 +23,8 @@ import { import { useDataGridPremiumProps } from './useDataGridPremiumProps'; import { getReleaseInfo } from '../utils/releaseInfo'; +export type { GridPremiumSlotsComponent as GridSlots } from '../models'; + const releaseInfo = getReleaseInfo(); const dataGridPremiumPropValidators: PropValidator[] = [ diff --git a/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx b/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx index b6623f1c4d26..e14b2b41380d 100644 --- a/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx +++ b/packages/grid/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx @@ -16,6 +16,8 @@ import { useDataGridProProps } from './useDataGridProProps'; import { getReleaseInfo } from '../utils/releaseInfo'; import { propValidatorsDataGridPro } from '../internals/propValidation'; +export type { GridProSlotsComponent as GridSlots } from '../models'; + const releaseInfo = getReleaseInfo(); const DataGridProRaw = React.forwardRef(function DataGridPro( diff --git a/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx b/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx index 4e89cdfd4d6c..ac8188dd7226 100644 --- a/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx +++ b/packages/grid/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx @@ -53,13 +53,16 @@ function GridHeaderFilterMenuContainer(props: { return null; } + const label = apiRef.current.getLocaleText('filterPanelOperator'); + const labelString = label ? String(label) : undefined; + return ( [] = [ ...propValidatorsDataGrid, // Only validate in MIT version diff --git a/packages/grid/x-data-grid/src/components/GridPagination.tsx b/packages/grid/x-data-grid/src/components/GridPagination.tsx index 92c2717b2eae..f7a45091220c 100644 --- a/packages/grid/x-data-grid/src/components/GridPagination.tsx +++ b/packages/grid/x-data-grid/src/components/GridPagination.tsx @@ -26,7 +26,7 @@ const GridPaginationRoot = styled(TablePagination)(({ theme }) => ({ }, })) as typeof TablePagination; -export const GridPagination = React.forwardRef>( +export const GridPagination = React.forwardRef>( function GridPagination(props, ref) { const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); diff --git a/packages/grid/x-data-grid/src/components/GridRow.tsx b/packages/grid/x-data-grid/src/components/GridRow.tsx index c66b72793ff3..457218861b73 100644 --- a/packages/grid/x-data-grid/src/components/GridRow.tsx +++ b/packages/grid/x-data-grid/src/components/GridRow.tsx @@ -389,7 +389,7 @@ const GridRow = React.forwardRef(function GridRow( width={width} contentWidth={contentWidth} field={column.field} - align={column.align} + align={column.align ?? 'left'} /> ); } diff --git a/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx b/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx index 5974991f1bf8..d27336afc865 100644 --- a/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx +++ b/packages/grid/x-data-grid/src/components/base/GridFooterPlaceholder.tsx @@ -8,5 +8,7 @@ export function GridFooterPlaceholder() { return null; } - return ; + return ( + + ); } diff --git a/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx b/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx index 7353974fabb9..db1ea9d1d3eb 100644 --- a/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx +++ b/packages/grid/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx @@ -49,7 +49,7 @@ const GridCellCheckboxForwardRef = React.forwardRef(null); + const checkboxElement = React.useRef(null); const rippleRef = React.useRef(null); const handleRef = useForkRef(checkboxElement, ref); @@ -104,7 +104,7 @@ const GridCellCheckboxForwardRef = React.forwardRef diff --git a/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx b/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx index b62cc90fed94..215608379c39 100644 --- a/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx +++ b/packages/grid/x-data-grid/src/components/columnSelection/GridHeaderCheckbox.tsx @@ -27,7 +27,7 @@ const useUtilityClasses = (ownerState: OwnerState) => { return composeClasses(slots, getDataGridUtilityClass, classes); }; -const GridHeaderCheckbox = React.forwardRef( +const GridHeaderCheckbox = React.forwardRef( function GridHeaderCheckbox(props, ref) { const { field, colDef, ...other } = props; const [, forceUpdate] = React.useState(false); diff --git a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx index bc6bfdc1c354..9ff36187ec42 100644 --- a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx +++ b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx @@ -316,7 +316,7 @@ const GridFilterForm = React.forwardRef( }, [item, currentColumn]); const changeColumn = React.useCallback( - (event: SelectChangeEvent) => { + (event: SelectChangeEvent) => { const field = event.target.value as string; const column = apiRef.current.getColumn(field)!; @@ -369,7 +369,7 @@ const GridFilterForm = React.forwardRef( ); const changeOperator = React.useCallback( - (event: SelectChangeEvent) => { + (event: SelectChangeEvent) => { const operator = event.target.value as string; const newOperator = currentColumn?.filterOperators!.find((op) => op.value === operator); @@ -388,7 +388,7 @@ const GridFilterForm = React.forwardRef( ); const changeLogicOperator = React.useCallback( - (event: SelectChangeEvent) => { + (event: SelectChangeEvent) => { const logicOperator = (event.target.value as string) === GridLogicOperator.And.toString() ? GridLogicOperator.And diff --git a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx index 32c79a69e6b7..f8dc457521aa 100644 --- a/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx +++ b/packages/grid/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx @@ -85,7 +85,9 @@ function GridFilterInputBoolean(props: GridFilterInputBooleanProps) { native={isSelectNative} displayEmpty inputProps={{ ref: focusElementRef, tabIndex }} - {...others} + { + ...(others as any) /* FIXME: typing error */ + } {...baseSelectProps} > { + (event: SelectChangeEvent) => { let value = event.target.value; // NativeSelect casts the value to a string. @@ -146,7 +146,9 @@ function GridFilterInputSingleSelect(props: GridFilterInputSingleSelectProps) { placeholder: placeholder ?? apiRef.current.getLocaleText('filterPanelInputPlaceholder'), }} native={isSelectNative} - {...others} + { + ...(others as any) /* FIXME: typing error */ + } {...rootProps.slotProps?.baseSelect} > {renderSingleSelectOptions({ diff --git a/packages/grid/x-data-grid/src/joy/joySlots.tsx b/packages/grid/x-data-grid/src/joy/joySlots.tsx index 7e245b918065..7c5819657da0 100644 --- a/packages/grid/x-data-grid/src/joy/joySlots.tsx +++ b/packages/grid/x-data-grid/src/joy/joySlots.tsx @@ -16,7 +16,7 @@ import JoyCircularProgress from '@mui/joy/CircularProgress'; import JoyTooltip from '@mui/joy/Tooltip'; import { unstable_useForkRef as useForkRef } from '@mui/utils'; import joyIconSlots, { GridKeyboardArrowRight, GridKeyboardArrowLeft } from './icons'; -import type { GridSlotsComponent, GridSlotsComponentsProps } from '../models'; +import type { GridSlotProps, GridSlotsComponent, GridSlotsComponentsProps } from '../models'; import { useGridApiContext } from '../hooks/utils/useGridApiContext'; import { useGridRootProps } from '../hooks/utils/useGridRootProps'; import { gridFilteredTopLevelRowCountSelector, gridPaginationModelSelector } from '../hooks'; @@ -116,10 +116,10 @@ const TextField = React.forwardRef< ); }); -const Button = React.forwardRef< - HTMLButtonElement, - NonNullable ->(function Button({ startIcon, color, endIcon, size, sx, variant, ...props }, ref) { +const Button = React.forwardRef(function Button( + { startIcon, color, endIcon, size, sx, variant, ...props }, + ref, +) { return ( ->(function Switch( +const Switch = React.forwardRef(function Switch( { name, checkedIcon, @@ -204,10 +201,7 @@ const Switch = React.forwardRef< ); }); -const Select = React.forwardRef< - HTMLButtonElement, - NonNullable ->( +const Select = React.forwardRef( ( { open, @@ -314,10 +308,7 @@ const getLabelDisplayedRowsTo = ({ return pageSize === -1 ? rowCount : Math.min(rowCount, (page + 1) * pageSize); }; -const Pagination = React.forwardRef< - HTMLDivElement, - NonNullable ->((props, ref) => { +const Pagination = React.forwardRef((props, ref) => { const apiRef = useGridApiContext(); const rootProps = useGridRootProps(); const paginationModel = gridPaginationModelSelector(apiRef); @@ -443,8 +434,8 @@ const joySlots: Partial = { baseSelect: Select, baseSelectOption: Option, baseInputLabel: InputLabel, - baseFormControl: JoyFormControl, - baseTooltip: JoyTooltip, + baseFormControl: JoyFormControl as any /* FIXME: typing error */, + baseTooltip: JoyTooltip as any /* FIXME: typing error */, pagination: Pagination, loadingOverlay: LoadingOverlay, }; diff --git a/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts b/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts index c77fe2f388f9..b25858988c0a 100644 --- a/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts +++ b/packages/grid/x-data-grid/src/models/api/gridLocaleTextApi.ts @@ -41,9 +41,9 @@ export interface GridLocaleText { toolbarExportExcel: string; // Columns management text - columnsManagementSearchTitle: React.ReactNode; - columnsManagementNoColumns: React.ReactNode; - columnsManagementShowHideAllText: React.ReactNode; + columnsManagementSearchTitle: string; + columnsManagementNoColumns: string; + columnsManagementShowHideAllText: string; // Filter panel text filterPanelAddFilter: React.ReactNode; diff --git a/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts b/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts index 2fec34e839a4..aedf8ceb29a9 100644 --- a/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts +++ b/packages/grid/x-data-grid/src/models/gridSlotsComponent.ts @@ -1,77 +1,75 @@ import * as React from 'react'; +import type { GridSlotProps } from './gridSlotsComponentsProps'; import type { GridIconSlotsComponent } from './gridIconSlotsComponent'; -import type { GridRowProps } from '../components/GridRow'; -import type { GridDetailPanelsProps } from '../components/GridDetailPanels'; -import type { GridPinnedRowsProps } from '../components/GridPinnedRows'; -import type { GridColumnHeadersProps } from '../components/GridColumnHeaders'; -// TODO: Convert all `any` to `Props & PropsOverrides` +export type { GridSlotProps } from './gridSlotsComponentsProps'; + export interface GridBaseSlots { /** * The custom Checkbox component used in the grid for both header and cells. * @default Checkbox */ - baseCheckbox: React.JSXElementConstructor; + baseCheckbox: React.JSXElementConstructor; /** * The custom Chip component used in the grid. * @default Chip */ - baseChip: React.JSXElementConstructor; + baseChip: React.JSXElementConstructor; /** * The custom InputAdornment component used in the grid. * @default InputAdornment */ - baseInputAdornment: React.JSXElementConstructor; + baseInputAdornment: React.JSXElementConstructor; /** * The custom TextField component used in the grid. * @default TextField */ - baseTextField: React.JSXElementConstructor; + baseTextField: React.JSXElementConstructor; /** * The custom FormControl component used in the grid. * @default FormControl */ - baseFormControl: React.JSXElementConstructor; + baseFormControl: React.JSXElementConstructor; /** * The custom Select component used in the grid. * @default Select */ - baseSelect: React.JSXElementConstructor; + baseSelect: React.JSXElementConstructor; /** * The custom Switch component used in the grid. * @default Switch */ - baseSwitch: React.JSXElementConstructor; + baseSwitch: React.JSXElementConstructor; /** * The custom Button component used in the grid. * @default Button */ - baseButton: React.JSXElementConstructor; + baseButton: React.JSXElementConstructor; /** * The custom IconButton component used in the grid. * @default IconButton */ - baseIconButton: React.JSXElementConstructor; + baseIconButton: React.JSXElementConstructor; /** * The custom Tooltip component used in the grid. * @default Tooltip */ - baseTooltip: React.JSXElementConstructor; + baseTooltip: React.JSXElementConstructor; /** * The custom Popper component used in the grid. * @default Popper */ - basePopper: React.JSXElementConstructor; + basePopper: React.JSXElementConstructor; /** * The custom InputLabel component used in the grid. * @default InputLabel */ - baseInputLabel: React.JSXElementConstructor; + baseInputLabel: React.JSXElementConstructor; /** * The custom SelectOption component used in the grid. * @default MenuItem */ - baseSelectOption: React.JSXElementConstructor; + baseSelectOption: React.JSXElementConstructor; } /** @@ -82,87 +80,89 @@ export interface GridSlotsComponent extends GridBaseSlots, GridIconSlotsComponen * The custom Chip component used in the grid. * @default Chip */ - baseChip: React.JSXElementConstructor; + baseChip: React.JSXElementConstructor; /** * Component rendered for each cell. * @default GridCell */ - cell: React.JSXElementConstructor; + cell: React.JSXElementConstructor; /** * Component rendered for each skeleton cell. * @default GridSkeletonCell */ - skeletonCell: React.JSXElementConstructor; + skeletonCell: React.JSXElementConstructor; /** * Filter icon component rendered in each column header. * @default GridColumnHeaderFilterIconButton */ - columnHeaderFilterIconButton: React.JSXElementConstructor; + columnHeaderFilterIconButton: React.JSXElementConstructor< + GridSlotProps['columnHeaderFilterIconButton'] + >; /** * Column menu component rendered by clicking on the 3 dots "kebab" icon in column headers. * @default GridColumnMenu */ - columnMenu: React.JSXElementConstructor; + columnMenu: React.JSXElementConstructor; /** * Component responsible for rendering the column headers. * @default DataGridColumnHeaders */ - columnHeaders: React.JSXElementConstructor; + columnHeaders: React.JSXElementConstructor; /** * Component responsible for rendering the detail panels. * @default GridDetailPanels */ - detailPanels: React.JSXElementConstructor; + detailPanels: React.JSXElementConstructor; /** * Footer component rendered at the bottom of the grid viewport. * @default GridFooter */ - footer: React.JSXElementConstructor; + footer: React.JSXElementConstructor; /** * Row count component rendered in the footer * @default GridRowCount */ - footerRowCount: React.JSXElementConstructor; + footerRowCount: React.JSXElementConstructor; /** * Toolbar component rendered inside the Header component. * @default null */ - toolbar: React.JSXElementConstructor | null; + toolbar: React.JSXElementConstructor | null; /** * Pinned rows container. * @ignore - do not document */ - pinnedRows: React.JSXElementConstructor; + pinnedRows: React.JSXElementConstructor; /** * Loading overlay component rendered when the grid is in a loading state. * @default GridLoadingOverlay */ - loadingOverlay: React.JSXElementConstructor; + loadingOverlay: React.JSXElementConstructor; /** * No results overlay component rendered when the grid has no results after filtering. * @default GridNoResultsOverlay */ - noResultsOverlay: React.JSXElementConstructor; + noResultsOverlay: React.JSXElementConstructor; /** * No rows overlay component rendered when the grid has no rows. * @default GridNoRowsOverlay */ - noRowsOverlay: React.JSXElementConstructor; + noRowsOverlay: React.JSXElementConstructor; /** * Pagination component rendered in the grid footer by default. * @default Pagination */ - pagination: React.JSXElementConstructor | null; + pagination: React.JSXElementConstructor | null; /** * Filter panel component rendered when clicking the filter button. * @default GridFilterPanel */ - filterPanel: React.JSXElementConstructor; + filterPanel: React.JSXElementConstructor; /** * GridColumns panel component rendered when clicking the columns button. * @default GridColumnsPanel */ - columnsPanel: React.JSXElementConstructor; + columnsPanel: React.JSXElementConstructor; /** * Component used inside Grid Columns panel to manage columns. * @default GridColumnsManagement @@ -172,10 +172,10 @@ export interface GridSlotsComponent extends GridBaseSlots, GridIconSlotsComponen * Panel component wrapping the filters and columns panels. * @default GridPanel */ - panel: React.JSXElementConstructor; + panel: React.JSXElementConstructor; /** * Component rendered for each row. * @default GridRow */ - row: React.JSXElementConstructor; + row: React.JSXElementConstructor; } diff --git a/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts b/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts index b22b600d1c4c..6623ae5d4483 100644 --- a/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts +++ b/packages/grid/x-data-grid/src/models/gridSlotsComponentsProps.ts @@ -1,26 +1,31 @@ import * as React from 'react'; -import { CheckboxProps } from '@mui/material/Checkbox'; -import { TextFieldProps } from '@mui/material/TextField'; -import { FormControlProps } from '@mui/material/FormControl'; -import { SelectProps } from '@mui/material/Select'; -import { SwitchProps } from '@mui/material/Switch'; -import { ButtonProps } from '@mui/material/Button'; -import { IconButtonProps } from '@mui/material/IconButton'; -import { TooltipProps } from '@mui/material/Tooltip'; +import type { CheckboxProps } from '@mui/material/Checkbox'; +import type { TextFieldProps } from '@mui/material/TextField'; +import type { FormControlProps } from '@mui/material/FormControl'; +import type { SelectProps } from '@mui/material/Select'; +import type { SwitchProps } from '@mui/material/Switch'; +import type { ButtonProps } from '@mui/material/Button'; +import type { IconButtonProps } from '@mui/material/IconButton'; +import type { InputAdornmentProps } from '@mui/material/InputAdornment'; +import type { TooltipProps } from '@mui/material/Tooltip'; import type { InputLabelProps } from '@mui/material/InputLabel'; -import { PopperProps } from '@mui/material/Popper'; -import { TablePaginationProps } from '@mui/material/TablePagination'; -import { ChipProps } from '@mui/material/Chip'; -import { GridToolbarProps } from '../components/toolbar/GridToolbar'; -import { ColumnHeaderFilterIconButtonProps } from '../components/columnHeaders/GridColumnHeaderFilterIconButton'; -import { GridColumnMenuProps } from '../components/menu/columnMenu/GridColumnMenuProps'; -import { GridColumnsPanelProps } from '../components/panel/GridColumnsPanel'; -import { GridFilterPanelProps } from '../components/panel/filterPanel/GridFilterPanel'; -import { GridFooterContainerProps } from '../components/containers/GridFooterContainer'; -import { GridOverlayProps } from '../components/containers/GridOverlay'; -import { GridPanelProps } from '../components/panel/GridPanel'; +import type { PopperProps } from '@mui/material/Popper'; +import type { TablePaginationProps } from '@mui/material/TablePagination'; +import type { ChipProps } from '@mui/material/Chip'; +import type { GridToolbarProps } from '../components/toolbar/GridToolbar'; +import type { ColumnHeaderFilterIconButtonProps } from '../components/columnHeaders/GridColumnHeaderFilterIconButton'; +import type { GridColumnMenuProps } from '../components/menu/columnMenu/GridColumnMenuProps'; +import type { GridColumnsPanelProps } from '../components/panel/GridColumnsPanel'; +import type { GridFilterPanelProps } from '../components/panel/filterPanel/GridFilterPanel'; +import type { GridFooterContainerProps } from '../components/containers/GridFooterContainer'; +import type { GridOverlayProps } from '../components/containers/GridOverlay'; +import type { GridPanelProps } from '../components/panel/GridPanel'; +import type { GridSkeletonCellProps } from '../components/cell/GridSkeletonCell'; import type { GridRowProps } from '../components/GridRow'; import type { GridCellProps } from '../components/cell/GridCell'; +import type { GridColumnHeadersProps } from '../components/GridColumnHeaders'; +import type { GridDetailPanelsProps } from '../components/GridDetailPanels'; +import type { GridPinnedRowsProps } from '../components/GridPinnedRows'; import type { GridColumnsManagementProps } from '../components/columnsManagement/GridColumnsManagement'; import type { GridRowCountProps } from '../components'; @@ -32,6 +37,7 @@ export interface BaseSelectPropsOverrides {} export interface BaseSwitchPropsOverrides {} export interface BaseButtonPropsOverrides {} export interface BaseIconButtonPropsOverrides {} +export interface BaseInputAdornmentPropsOverrides {} export interface BaseTooltipPropsOverrides {} export interface BasePopperPropsOverrides {} export interface BaseInputLabelPropsOverrides {} @@ -42,6 +48,7 @@ export interface ToolbarPropsOverrides {} export interface ColumnHeaderFilterIconButtonPropsOverrides {} export interface ColumnMenuPropsOverrides {} export interface ColumnsPanelPropsOverrides {} +export interface DetailPanelsPropsOverrides {} export interface ColumnsManagementPropsOverrides {} export interface FilterPanelPropsOverrides {} export interface FooterPropsOverrides {} @@ -51,45 +58,53 @@ export interface LoadingOverlayPropsOverrides {} export interface NoResultsOverlayPropsOverrides {} export interface NoRowsOverlayPropsOverrides {} export interface PanelPropsOverrides {} +export interface PinnedRowsPropsOverrides {} +export interface SkeletonCellPropsOverrides {} export interface RowPropsOverrides {} -type SlotProps = Partial; +export interface GridSlotProps { + baseCheckbox: CheckboxProps & BaseCheckboxPropsOverrides; + baseTextField: TextFieldProps & BaseTextFieldPropsOverrides; + baseFormControl: FormControlProps & BaseFormControlPropsOverrides; + baseSelect: SelectProps & BaseSelectPropsOverrides; + baseSwitch: SwitchProps & BaseSwitchPropsOverrides; + baseButton: ButtonProps & BaseButtonPropsOverrides; + baseIconButton: IconButtonProps & BaseIconButtonPropsOverrides; + basePopper: PopperProps & BasePopperPropsOverrides; + baseTooltip: TooltipProps & BaseTooltipPropsOverrides; + baseInputLabel: InputLabelProps & BaseInputLabelPropsOverrides; + baseInputAdornment: InputAdornmentProps & BaseInputAdornmentPropsOverrides; + baseSelectOption: { + native: boolean; + value: any; + children?: React.ReactNode; + } & BaseSelectOptionPropsOverrides; + baseChip: ChipProps & BaseChipPropsOverrides; + cell: GridCellProps & CellPropsOverrides; + columnHeaders: GridColumnHeadersProps; + columnHeaderFilterIconButton: ColumnHeaderFilterIconButtonProps & + ColumnHeaderFilterIconButtonPropsOverrides; + columnMenu: GridColumnMenuProps & ColumnMenuPropsOverrides; + columnsPanel: GridColumnsPanelProps & ColumnsPanelPropsOverrides; + columnsManagement: GridColumnsManagementProps & ColumnsManagementPropsOverrides; + detailPanels: GridDetailPanelsProps & DetailPanelsPropsOverrides; + filterPanel: GridFilterPanelProps & FilterPanelPropsOverrides; + footer: GridFooterContainerProps & FooterPropsOverrides; + footerRowCount: GridRowCountProps & FooterRowCountOverrides; + loadingOverlay: GridOverlayProps & LoadingOverlayPropsOverrides; + noResultsOverlay: GridOverlayProps & NoResultsOverlayPropsOverrides; + noRowsOverlay: GridOverlayProps & NoRowsOverlayPropsOverrides; + pagination: Partial & PaginationPropsOverrides; + panel: GridPanelProps & PanelPropsOverrides; + pinnedRows: GridPinnedRowsProps & PinnedRowsPropsOverrides; + row: GridRowProps & RowPropsOverrides; + skeletonCell: GridSkeletonCellProps & SkeletonCellPropsOverrides; + toolbar: GridToolbarProps & ToolbarPropsOverrides; +} /** * Overridable components props dynamically passed to the component at rendering. */ -export interface GridSlotsComponentsProps { - baseCheckbox?: SlotProps; - baseTextField?: SlotProps; - baseFormControl?: SlotProps; - baseSelect?: SlotProps; - baseSwitch?: SlotProps; - baseButton?: SlotProps; - baseIconButton?: SlotProps; - basePopper?: SlotProps; - baseTooltip?: SlotProps; - baseInputLabel?: SlotProps; - baseSelectOption?: SlotProps< - { native: boolean; value: any; children?: React.ReactNode }, - BaseSelectOptionPropsOverrides - >; - baseChip?: SlotProps; - cell?: SlotProps; - columnHeaderFilterIconButton?: SlotProps< - ColumnHeaderFilterIconButtonProps, - ColumnHeaderFilterIconButtonPropsOverrides - >; - columnMenu?: SlotProps; - columnsPanel?: SlotProps; - columnsManagement?: SlotProps; - filterPanel?: SlotProps; - footer?: SlotProps; - footerRowCount?: SlotProps; - loadingOverlay?: SlotProps; - noResultsOverlay?: SlotProps; - noRowsOverlay?: SlotProps; - pagination?: SlotProps; - panel?: SlotProps; - row?: SlotProps; - toolbar?: SlotProps; -} +export type GridSlotsComponentsProps = Partial<{ + [K in keyof GridSlotProps]: Partial; +}>; diff --git a/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx b/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx index c69bb7331eca..1c0e44a39cbf 100644 --- a/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx +++ b/packages/grid/x-data-grid/src/tests/filtering.DataGrid.test.tsx @@ -8,6 +8,7 @@ import { GridColDef, GridFilterItem, GridPreferencePanelsValue, + GridSlots, GridToolbar, GridFilterOperator, } from '@mui/x-data-grid'; @@ -1305,7 +1306,7 @@ describe(' - Filter', () => { type: 'number', }, ]} - slots={{ toolbar: GridToolbarFilterButton }} + slots={{ toolbar: GridToolbarFilterButton as GridSlots['toolbar'] }} />, ); @@ -1369,7 +1370,7 @@ describe(' - Filter', () => { ] as GridFilterOperator[], }, ]} - slots={{ toolbar: GridToolbarFilterButton }} + slots={{ toolbar: GridToolbarFilterButton as GridSlots['toolbar'] }} /> , ); diff --git a/scripts/x-data-grid-premium.exports.json b/scripts/x-data-grid-premium.exports.json index 287b954cc35c..7093d6eac2ad 100644 --- a/scripts/x-data-grid-premium.exports.json +++ b/scripts/x-data-grid-premium.exports.json @@ -4,6 +4,7 @@ { "name": "BaseChipPropsOverrides", "kind": "Interface" }, { "name": "BaseFormControlPropsOverrides", "kind": "Interface" }, { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, + { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, @@ -28,6 +29,7 @@ { "name": "DataGridPro", "kind": "Function" }, { "name": "DEFAULT_GRID_AUTOSIZE_OPTIONS", "kind": "Variable" }, { "name": "DEFAULT_GRID_COL_TYPE_KEY", "kind": "Variable" }, + { "name": "DetailPanelsPropsOverrides", "kind": "Interface" }, { "name": "ElementSize", "kind": "Interface" }, { "name": "EMPTY_PINNED_COLUMN_FIELDS", "kind": "Variable" }, { "name": "EMPTY_RENDER_CONTEXT", "kind": "Variable" }, @@ -529,8 +531,10 @@ { "name": "GridSkeletonCell", "kind": "Function" }, { "name": "GridSkeletonCellProps", "kind": "Interface" }, { "name": "GridSkeletonRowNode", "kind": "Interface" }, + { "name": "GridSlotProps", "kind": "Interface" }, + { "name": "GridSlots", "kind": "Interface" }, { "name": "GridSlotsComponent", "kind": "Interface" }, - { "name": "GridSlotsComponentsProps", "kind": "Interface" }, + { "name": "GridSlotsComponentsProps", "kind": "TypeAlias" }, { "name": "GridSortApi", "kind": "Interface" }, { "name": "GridSortCellParams", "kind": "Interface" }, { "name": "GridSortColumnLookup", "kind": "TypeAlias" }, @@ -610,6 +614,7 @@ { "name": "OutputSelector", "kind": "Interface" }, { "name": "PaginationPropsOverrides", "kind": "Interface" }, { "name": "PanelPropsOverrides", "kind": "Interface" }, + { "name": "PinnedRowsPropsOverrides", "kind": "Interface" }, { "name": "renderActionsCell", "kind": "Variable" }, { "name": "renderBooleanCell", "kind": "Variable" }, { "name": "renderEditBooleanCell", "kind": "Variable" }, @@ -621,6 +626,7 @@ { "name": "selectedGridRowsSelector", "kind": "Variable" }, { "name": "selectedIdsLookupSelector", "kind": "Variable" }, { "name": "setupExcelExportWebWorker", "kind": "Function" }, + { "name": "SkeletonCellPropsOverrides", "kind": "Interface" }, { "name": "ToolbarPropsOverrides", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, { "name": "useFirstRender", "kind": "Variable" }, diff --git a/scripts/x-data-grid-pro.exports.json b/scripts/x-data-grid-pro.exports.json index 6e1bffb88d86..7a9543c73818 100644 --- a/scripts/x-data-grid-pro.exports.json +++ b/scripts/x-data-grid-pro.exports.json @@ -4,6 +4,7 @@ { "name": "BaseChipPropsOverrides", "kind": "Interface" }, { "name": "BaseFormControlPropsOverrides", "kind": "Interface" }, { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, + { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, @@ -27,6 +28,7 @@ { "name": "DataGridProProps", "kind": "Interface" }, { "name": "DEFAULT_GRID_AUTOSIZE_OPTIONS", "kind": "Variable" }, { "name": "DEFAULT_GRID_COL_TYPE_KEY", "kind": "Variable" }, + { "name": "DetailPanelsPropsOverrides", "kind": "Interface" }, { "name": "ElementSize", "kind": "Interface" }, { "name": "EMPTY_PINNED_COLUMN_FIELDS", "kind": "Variable" }, { "name": "EMPTY_RENDER_CONTEXT", "kind": "Variable" }, @@ -483,8 +485,10 @@ { "name": "GridSkeletonCell", "kind": "Function" }, { "name": "GridSkeletonCellProps", "kind": "Interface" }, { "name": "GridSkeletonRowNode", "kind": "Interface" }, + { "name": "GridSlotProps", "kind": "Interface" }, + { "name": "GridSlots", "kind": "Interface" }, { "name": "GridSlotsComponent", "kind": "Interface" }, - { "name": "GridSlotsComponentsProps", "kind": "Interface" }, + { "name": "GridSlotsComponentsProps", "kind": "TypeAlias" }, { "name": "GridSortApi", "kind": "Interface" }, { "name": "GridSortCellParams", "kind": "Interface" }, { "name": "GridSortColumnLookup", "kind": "TypeAlias" }, @@ -562,6 +566,7 @@ { "name": "OutputSelector", "kind": "Interface" }, { "name": "PaginationPropsOverrides", "kind": "Interface" }, { "name": "PanelPropsOverrides", "kind": "Interface" }, + { "name": "PinnedRowsPropsOverrides", "kind": "Interface" }, { "name": "renderActionsCell", "kind": "Variable" }, { "name": "renderBooleanCell", "kind": "Variable" }, { "name": "renderEditBooleanCell", "kind": "Variable" }, @@ -572,6 +577,7 @@ { "name": "selectedGridRowsCountSelector", "kind": "Variable" }, { "name": "selectedGridRowsSelector", "kind": "Variable" }, { "name": "selectedIdsLookupSelector", "kind": "Variable" }, + { "name": "SkeletonCellPropsOverrides", "kind": "Interface" }, { "name": "ToolbarPropsOverrides", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, { "name": "useFirstRender", "kind": "Variable" }, diff --git a/scripts/x-data-grid.exports.json b/scripts/x-data-grid.exports.json index a14da1163acf..f55ecfd6630c 100644 --- a/scripts/x-data-grid.exports.json +++ b/scripts/x-data-grid.exports.json @@ -4,6 +4,7 @@ { "name": "BaseChipPropsOverrides", "kind": "Interface" }, { "name": "BaseFormControlPropsOverrides", "kind": "Interface" }, { "name": "BaseIconButtonPropsOverrides", "kind": "Interface" }, + { "name": "BaseInputAdornmentPropsOverrides", "kind": "Interface" }, { "name": "BaseInputLabelPropsOverrides", "kind": "Interface" }, { "name": "BasePopperPropsOverrides", "kind": "Interface" }, { "name": "BaseSelectOptionPropsOverrides", "kind": "Interface" }, @@ -24,6 +25,7 @@ { "name": "DataGrid", "kind": "Variable" }, { "name": "DataGridProps", "kind": "TypeAlias" }, { "name": "DEFAULT_GRID_COL_TYPE_KEY", "kind": "Variable" }, + { "name": "DetailPanelsPropsOverrides", "kind": "Interface" }, { "name": "ElementSize", "kind": "Interface" }, { "name": "EMPTY_PINNED_COLUMN_FIELDS", "kind": "Variable" }, { "name": "EMPTY_RENDER_CONTEXT", "kind": "Variable" }, @@ -438,8 +440,10 @@ { "name": "GridSkeletonCell", "kind": "Function" }, { "name": "GridSkeletonCellProps", "kind": "Interface" }, { "name": "GridSkeletonRowNode", "kind": "Interface" }, + { "name": "GridSlotProps", "kind": "Interface" }, + { "name": "GridSlots", "kind": "Interface" }, { "name": "GridSlotsComponent", "kind": "Interface" }, - { "name": "GridSlotsComponentsProps", "kind": "Interface" }, + { "name": "GridSlotsComponentsProps", "kind": "TypeAlias" }, { "name": "GridSortApi", "kind": "Interface" }, { "name": "GridSortCellParams", "kind": "Interface" }, { "name": "GridSortColumnLookup", "kind": "TypeAlias" }, @@ -515,6 +519,7 @@ { "name": "OutputSelector", "kind": "Interface" }, { "name": "PaginationPropsOverrides", "kind": "Interface" }, { "name": "PanelPropsOverrides", "kind": "Interface" }, + { "name": "PinnedRowsPropsOverrides", "kind": "Interface" }, { "name": "renderActionsCell", "kind": "Variable" }, { "name": "renderBooleanCell", "kind": "Variable" }, { "name": "renderEditBooleanCell", "kind": "Variable" }, @@ -525,6 +530,7 @@ { "name": "selectedGridRowsCountSelector", "kind": "Variable" }, { "name": "selectedGridRowsSelector", "kind": "Variable" }, { "name": "selectedIdsLookupSelector", "kind": "Variable" }, + { "name": "SkeletonCellPropsOverrides", "kind": "Interface" }, { "name": "ToolbarPropsOverrides", "kind": "Interface" }, { "name": "unstable_resetCleanupTracking", "kind": "Variable" }, { "name": "useFirstRender", "kind": "Variable" },