Open cherniavskii opened 1 week ago
Hey @cherniavskii I did find a solution to this:
export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
export type Overwrite<T, U> = DistributiveOmit<T, keyof U> & U;
With this you can wrap the original props in Partial
and apply the overwrite to the augmented props override:
cell: Overwrite<Partial<GridCellProps>, CellPropsOverrides>;
It then applies the type properties from the CellPropsOverrides
onto the slotProp and uses the correct type for it:
One small adjustment to this:
export type GridSlotsComponentsProps = Partial<{
[K in keyof GridSlotProps]: GridSlotProps[K];
}>;
WDYT?
Here is the diff for that:
diff --git a/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts b/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts
index 6ea9c9f27..b99ac8698 100644
--- a/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts
+++ b/packages/x-data-grid/src/models/gridSlotsComponentsProps.ts
@@ -31,6 +31,10 @@ import type { GridLoadingOverlayProps } from '../components/GridLoadingOverlay';
import type { GridRowCountProps } from '../components/GridRowCount';
import type { GridColumnHeaderSortIconProps } from '../components/columnHeaders/GridColumnHeaderSortIcon';
+export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
+
+export type Overwrite<T, U> = DistributiveOmit<T, keyof U> & U;
+
// Overrides for module augmentation
export interface BaseCheckboxPropsOverrides {}
export interface BaseTextFieldPropsOverrides {}
@@ -66,49 +70,60 @@ export interface SkeletonCellPropsOverrides {}
export interface RowPropsOverrides {}
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;
+ baseCheckbox: Overwrite<Partial<CheckboxProps>, BaseCheckboxPropsOverrides>;
+ baseTextField: Overwrite<Partial<TextFieldProps>, BaseTextFieldPropsOverrides>;
+ baseFormControl: Overwrite<Partial<FormControlProps>, BaseFormControlPropsOverrides>;
+ baseSelect: Overwrite<Partial<SelectProps>, BaseSelectPropsOverrides>;
+ baseSwitch: Overwrite<Partial<SwitchProps>, BaseSwitchPropsOverrides>;
+ baseButton: Overwrite<Partial<ButtonProps>, BaseButtonPropsOverrides>;
+ baseIconButton: Overwrite<Partial<IconButtonProps>, BaseIconButtonPropsOverrides>;
+ basePopper: Overwrite<Partial<PopperProps>, BasePopperPropsOverrides>;
+ baseTooltip: Overwrite<Partial<TooltipProps>, BaseTooltipPropsOverrides>;
+ baseInputLabel: Overwrite<Partial<InputLabelProps>, BaseInputLabelPropsOverrides>;
+ baseInputAdornment: Overwrite<Partial<InputAdornmentProps>, BaseInputAdornmentPropsOverrides>;
+ baseSelectOption: Overwrite<
+ Partial<{
+ native: boolean;
+ value: any;
+ children?: React.ReactNode;
+ }>,
+ BaseSelectOptionPropsOverrides
+ >;
+ baseChip: Overwrite<Partial<ChipProps>, BaseChipPropsOverrides>;
+ cell: Overwrite<Partial<GridCellProps>, CellPropsOverrides>;
columnHeaders: GridColumnHeadersProps;
- columnHeaderFilterIconButton: ColumnHeaderFilterIconButtonProps &
- ColumnHeaderFilterIconButtonPropsOverrides;
- columnHeaderSortIcon: GridColumnHeaderSortIconProps & ColumnHeaderSortIconPropsOverrides;
- columnMenu: GridColumnMenuProps & ColumnMenuPropsOverrides;
- columnsPanel: GridColumnsPanelProps & ColumnsPanelPropsOverrides;
- columnsManagement: GridColumnsManagementProps & ColumnsManagementPropsOverrides;
- detailPanels: GridDetailPanelsProps & DetailPanelsPropsOverrides;
- filterPanel: GridFilterPanelProps & FilterPanelPropsOverrides;
- footer: GridFooterContainerProps & FooterPropsOverrides;
- footerRowCount: GridRowCountProps & FooterRowCountOverrides;
- loadingOverlay: GridLoadingOverlayProps & LoadingOverlayPropsOverrides;
- noResultsOverlay: GridOverlayProps & NoResultsOverlayPropsOverrides;
- noRowsOverlay: GridOverlayProps & NoRowsOverlayPropsOverrides;
- pagination: Partial<TablePaginationProps> & PaginationPropsOverrides;
- panel: GridPanelProps & PanelPropsOverrides;
- pinnedRows: GridPinnedRowsProps & PinnedRowsPropsOverrides;
- row: GridRowProps & RowPropsOverrides;
- skeletonCell: GridSkeletonCellProps & SkeletonCellPropsOverrides;
- toolbar: GridToolbarProps & ToolbarPropsOverrides;
+ columnHeaderFilterIconButton: Overwrite<
+ Partial<ColumnHeaderFilterIconButtonProps>,
+ ColumnHeaderFilterIconButtonPropsOverrides
+ >;
+ columnHeaderSortIcon: Overwrite<
+ Partial<GridColumnHeaderSortIconProps>,
+ ColumnHeaderSortIconPropsOverrides
+ >;
+ columnMenu: Overwrite<Partial<GridColumnMenuProps>, ColumnMenuPropsOverrides>;
+ columnsPanel: Overwrite<Partial<GridColumnsPanelProps>, ColumnsPanelPropsOverrides>;
+ columnsManagement: Overwrite<
+ Partial<GridColumnsManagementProps>,
+ ColumnsManagementPropsOverrides
+ >;
+ detailPanels: Overwrite<Partial<GridDetailPanelsProps>, DetailPanelsPropsOverrides>;
+ filterPanel: Overwrite<Partial<GridFilterPanelProps>, FilterPanelPropsOverrides>;
+ footer: Overwrite<Partial<GridFooterContainerProps>, FooterPropsOverrides>;
+ footerRowCount: Overwrite<Partial<GridRowCountProps>, FooterRowCountOverrides>;
+ loadingOverlay: Overwrite<Partial<GridLoadingOverlayProps>, LoadingOverlayPropsOverrides>;
+ noResultsOverlay: Overwrite<Partial<GridOverlayProps>, NoResultsOverlayPropsOverrides>;
+ noRowsOverlay: Overwrite<Partial<GridOverlayProps>, NoRowsOverlayPropsOverrides>;
+ pagination: Overwrite<Partial<TablePaginationProps>, PaginationPropsOverrides>;
+ panel: Overwrite<Partial<GridPanelProps>, PanelPropsOverrides>;
+ pinnedRows: Overwrite<Partial<GridPinnedRowsProps>, PinnedRowsPropsOverrides>;
+ row: Overwrite<Partial<GridRowProps>, RowPropsOverrides>;
+ skeletonCell: Overwrite<Partial<GridSkeletonCellProps>, SkeletonCellPropsOverrides>;
+ toolbar: Overwrite<Partial<GridToolbarProps>, ToolbarPropsOverrides>;
}
/**
* Overridable components props dynamically passed to the component at rendering.
*/
export type GridSlotsComponentsProps = Partial<{
- [K in keyof GridSlotProps]: Partial<GridSlotProps[K]>;
+ [K in keyof GridSlotProps]: GridSlotProps[K];
}>;
Lets you overwrite the original props as well:
declare module '@mui/x-data-grid' {
interface CellPropsOverrides {
example1Prop?: string;
align: 'left';
}
}
Thanks @michelengelen! It looks like your proposal solves problems (1) and (3)! We still have (2) unsolved, but it's already a step forward 👍🏻
Context
I was working on https://github.com/mui/mui-x/pull/14424 and experienced issues with the current solution for
slotProps
overrides. I tried to condense the problems in the list below.What's the problem?
Custom
slotProps
are optional – there are no errors if they're not passed:Demo: https://stackblitz.com/edit/react-ceq5nm?file=Demo.tsx
Using module augmentation for custom
slotProps
affects the whole project and cannot be scoped.For example, if you have 2 DataGrids in your app, each using a different custom footer slot, all type overrides for that slot are merged. Currently, this is not causing issues, but if we solve (1), then custom footer props from both DataGrids will be required in
slotProps.footer
Demo: https://stackblitz.com/edit/react-ceq5nm-xssqym?file=Demo1.tsx,Demo2.tsx
Overriding the type of the existing prop is not possible.
For example,
loadingOverlay
has avariant: 'circular-progress' | 'linear-progress' | 'skeleton'
prop. If you try to override it withvariant: 'one' | 'two'
it won't work, even though your custom slot implementation supports the newvariant
type.Demo: https://stackblitz.com/edit/react-ceq5nm-twuqy6
What are the requirements?
A better solution for
slotProps
overrides that solves the 3 problems above.What are our options?
TBD
Proposed solution
No response
Resources and benchmarks
No response
Search keywords: