-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bump React #15255
Bump React #15255
Conversation
…optypes` generation
… flaky proptypes generation
Deploy preview: https://deploy-preview-15255--material-ui-x.netlify.app/ |
}: { | ||
syncState: (stateToSave: GridInitialState) => void; | ||
}) { | ||
declare module '@mui/x-data-grid' { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If pro
and premium
package module augmentation are mixed in a single project—it goes haywire. 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some of this dogfooding—this is my main gripe with module augmentation. 🙈
If users extend the same types for different package versions—they come to experience unexpected behavior. 🤷
@mui/code-infra @flaviendelangle do you have any idea on how to resolve the TS problem?
|
@@ -64,7 +64,7 @@ export interface GridRowProps extends React.HTMLAttributes<HTMLDivElement> { | |||
onDoubleClick?: React.MouseEventHandler<HTMLDivElement>; | |||
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>; | |||
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>; | |||
[x: string]: any; // Allow custom attributes like data-* and aria-* | |||
[x: `data-${string}`]: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mui/xgrid Are you sure we need to do this?
What problem is it solving? 🤔
No other X package is doing it, and neither Core
is doing it. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For context—no other package is providing this explicit type, if anyone needs to provide it, they are probably fighting TS as well.
Such props work on HTML and JSX elements as any prop with a -
is ignored by TS.
Given that in our case these props are passed through slotProps
, this causes slightly more problems, because they will show an error. 🤔
[x: `data-${string}`]: string; | ||
[x: `${string}Options`]: any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WDYT about this approach?
Can we keep just the second line?
Or only excelOptions
? 🤔
CompromiseIf we want to unblock the bump and revert back to almost the current approach (casting everything) for demos using a custom toolbar here is a diff. diff --git a/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx b/docs/data/data-grid/editing/FullFeaturedCrudGrid.tsx
index b74a768045..12cd6cc9be 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,
GridSlotProps,
} from '@mui/x-data-grid';
import {
@@ -70,16 +71,14 @@ const initialRows: GridRowsProp = [
},
];
-declare module '@mui/x-data-grid' {
- interface ToolbarPropsOverrides {
- setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
- setRowModesModel: (
- newModel: (oldModel: GridRowModesModel) => GridRowModesModel,
- ) => void;
- }
+interface EditToolbarProps {
+ setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void;
+ setRowModesModel: (
+ newModel: (oldModel: GridRowModesModel) => GridRowModesModel,
+ ) => void;
}
-function EditToolbar(props: GridSlotProps['toolbar']) {
+function EditToolbar(props: EditToolbarProps) {
const { setRows, setRowModesModel } = props;
const handleClick = () => {
@@ -242,9 +241,9 @@ export default function FullFeaturedCrudGrid() {
onRowModesModelChange={handleRowModesModelChange}
onRowEditStop={handleRowEditStop}
processRowUpdate={processRowUpdate}
- slots={{ toolbar: EditToolbar }}
+ slots={{ toolbar: EditToolbar as unknown as GridSlots['toolbar'] }}
slotProps={{
- toolbar: { setRows, setRowModesModel },
+ toolbar: { setRows, setRowModesModel } as GridSlotProps['toolbar'],
}}
/>
</Box>
diff --git a/docs/data/data-grid/editing/StartEditButtonGrid.tsx b/docs/data/data-grid/editing/StartEditButtonGrid.tsx
index a1e7a86e69..45da690258 100644
--- a/docs/data/data-grid/editing/StartEditButtonGrid.tsx
+++ b/docs/data/data-grid/editing/StartEditButtonGrid.tsx
@@ -10,6 +10,7 @@ import {
GridEventListener,
GridCellModesModel,
GridSlotProps,
+ GridSlots,
} from '@mui/x-data-grid';
import {
randomCreatedDate,
@@ -22,16 +23,14 @@ interface SelectedCellParams {
field: string;
}
-declare module '@mui/x-data-grid' {
- interface ToolbarPropsOverrides {
- selectedCellParams: SelectedCellParams | null;
- cellModesModel: GridCellModesModel;
- setCellModesModel: (value: GridCellModesModel) => void;
- cellMode: 'view' | 'edit';
- }
+interface EditToolbarProps {
+ selectedCellParams?: SelectedCellParams;
+ cellModesModel: GridCellModesModel;
+ setCellModesModel: (value: GridCellModesModel) => void;
+ cellMode: 'view' | 'edit';
}
-function EditToolbar(props: GridSlotProps['toolbar']) {
+function EditToolbar(props: EditToolbarProps) {
const { selectedCellParams, cellMode, cellModesModel, setCellModesModel } = props;
const handleSaveOrEdit = () => {
@@ -149,14 +148,14 @@ export default function StartEditButtonGrid() {
cellModesModel={cellModesModel}
onCellEditStop={handleCellEditStop}
onCellModesModelChange={(model) => setCellModesModel(model)}
- slots={{ toolbar: EditToolbar }}
+ slots={{ toolbar: EditToolbar as unknown as GridSlots['toolbar'] }}
slotProps={{
toolbar: {
cellMode,
selectedCellParams,
cellModesModel,
setCellModesModel,
- },
+ } as GridSlotProps['toolbar'],
cell: {
onFocus: handleCellFocus,
},
diff --git a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx b/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx
index 6dfc79cb74..d300354a99 100644
--- a/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx
+++ b/docs/data/data-grid/filtering/CustomFilterPanelPosition.tsx
@@ -2,6 +2,7 @@ import * as React from 'react';
import {
DataGrid,
GridSlotProps,
+ GridSlots,
GridToolbarContainer,
GridToolbarFilterButton,
} from '@mui/x-data-grid';
@@ -9,15 +10,11 @@ import { useDemoData } from '@mui/x-data-grid-generator';
const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin'];
-declare module '@mui/x-data-grid' {
- interface ToolbarPropsOverrides {
- setFilterButtonEl: React.Dispatch<
- React.SetStateAction<HTMLButtonElement | null>
- >;
- }
+interface CustomToolbarProps {
+ setFilterButtonEl: React.Dispatch<React.SetStateAction<HTMLButtonElement | null>>;
}
-function CustomToolbar({ setFilterButtonEl }: GridSlotProps['toolbar']) {
+function CustomToolbar({ setFilterButtonEl }: CustomToolbarProps) {
return (
<GridToolbarContainer>
<GridToolbarFilterButton ref={setFilterButtonEl} />
@@ -39,12 +36,12 @@ export default function CustomFilterPanelPosition() {
<div style={{ height: 400, width: '100%' }}>
<DataGrid
{...data}
- slots={{ toolbar: CustomToolbar }}
+ slots={{ toolbar: CustomToolbar as unknown as GridSlots['toolbar'] }}
slotProps={{
panel: {
anchorEl: filterButtonEl,
},
- toolbar: { setFilterButtonEl },
+ toolbar: { setFilterButtonEl } as GridSlotProps['toolbar'],
}}
/>
</div>
diff --git a/docs/data/data-grid/list-view/ListViewAdvanced.tsx b/docs/data/data-grid/list-view/ListViewAdvanced.tsx
index c53a525c0a..a5263f36dc 100644
--- a/docs/data/data-grid/list-view/ListViewAdvanced.tsx
+++ b/docs/data/data-grid/list-view/ListViewAdvanced.tsx
@@ -8,6 +8,7 @@ import {
GridRowId,
gridClasses,
GridRowModel,
+ GridSlotProps,
} from '@mui/x-data-grid-premium';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
@@ -28,15 +29,6 @@ import { formatDate, formatSize, stringAvatar } from './utils';
import { ActionDrawer } from './components/ActionDrawer';
import { RenameDialog } from './components/RenameDialog';
-declare module '@mui/x-data-grid' {
- interface ToolbarPropsOverrides {
- listView: boolean;
- container: () => HTMLElement;
- handleDelete: (ids: GridRowId[]) => void;
- handleUpload: (event: React.ChangeEvent<HTMLInputElement>) => void;
- }
-}
-
export default function ListViewAdvanced() {
// This is used only for the example - renders the drawer inside the container
const containerRef = React.useRef<HTMLDivElement>(null);
@@ -298,7 +290,7 @@ export default function ListViewAdvanced() {
container,
handleDelete,
handleUpload,
- },
+ } as GridSlotProps['toolbar'],
loadingOverlay: {
variant: 'linear-progress',
},
diff --git a/docs/data/data-grid/state/RestoreStateInitialState.tsx b/docs/data/data-grid/state/RestoreStateInitialState.tsx
index 5e50289ac8..359750d904 100644
--- a/docs/data/data-grid/state/RestoreStateInitialState.tsx
+++ b/docs/data/data-grid/state/RestoreStateInitialState.tsx
@@ -6,6 +6,7 @@ import {
DataGridPro,
GridInitialState,
GridSlotProps,
+ GridSlots,
GridToolbarContainer,
GridToolbarDensitySelector,
GridToolbarFilterButton,
@@ -14,13 +15,11 @@ import {
} from '@mui/x-data-grid-pro';
import { useDemoData } from '@mui/x-data-grid-generator';
-declare module '@mui/x-data-grid' {
- interface ToolbarPropsOverrides {
- syncState: (stateToSave: GridInitialState) => void;
- }
+interface CustomToolbarProps {
+ syncState: (stateToSave: GridInitialState) => void;
}
-function GridCustomToolbar({ syncState }: GridSlotProps['toolbar']) {
+function GridCustomToolbar({ syncState }: CustomToolbarProps) {
const rootProps = useGridRootProps();
const apiRef = useGridApiContext();
@@ -65,8 +64,8 @@ export default function RestoreStateInitialState() {
<DataGridPro
{...data}
loading={loading}
- slots={{ toolbar: GridCustomToolbar }}
- slotProps={{ toolbar: { syncState } }}
+ slots={{ toolbar: GridCustomToolbar as unknown as GridSlots['toolbar'] }}
+ slotProps={{ toolbar: { syncState } as GridSlotProps['toolbar'] }}
/>
</Box>
<Box sx={{ height: 300 }}> |
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
I don't have a great solution 😬 The more I think about it, the more I like @michaldudak proposal of migrating away from the <DataGrid rows={rows} columns={columns}>
<DataGrid.UIParts.Toolbar>
{toolbarProps => (
<GridCustomToolbar {...toolbarProps} syncState={syncState} />
)}
</DataGrid.Slots.Toolbar>
</DataGrid> The exact DX can of course vary: <DataGrid rows={rows} columns={columns}>
<DataGrid.UIParts.Toolbar
render={toolbarProps => (
<GridCustomToolbar {...toolbarProps} syncState={syncState} />
)}
/>
</DataGrid> or <DataGrid rows={rows} columns={columns}>
<DataGrid.Toolbar
render={toolbarProps => (
<GridCustomToolbar {...toolbarProps} syncState={syncState} />
)}
/>
</DataGrid> or <DataGrid
rows={rows}
columns={columns}>
uiParts={{
toolbar: toolbarProps => (
<GridCustomToolbar {...toolbarProps} syncState={syncState} />
)
}}
/> etc... The idea being that those big UI parts have very different trade-offs than what slots have been designed for. Big pieces of UI, I'm refering to things like Not saying that we should change it tomorrow and maybe an "ugly fix" is enough for now, but we should spend some time working on https://www.notion.so/mui-org/Element-override-patterns-121cbfe7b66080efa637e41a1063343f#121cbfe7b66080299076de3e6ac03056 at some point to improve the customization experience around those topics. |
I fully agree with your comments. |
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
{rootProps.slots.toolbar && ( | ||
<rootProps.slots.toolbar | ||
// Fixes error augmentation issue https://github.com/mui/mui-x/pull/15255#issuecomment-2454721612 | ||
{...(rootProps.slotProps?.toolbar as any)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this to make the types work, I think it's an acceptable solution as it's internal only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine if you are happy with this solution. 👌
The component is public, but do you mean that if someone wants to override this slot, they will create their component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I meant that as any
above doesn't impact the users passing the slot props
BTW, shouldn't this PR be cherry-picked to |
That's a good question. 🤔 |
@joserodolfofreitas is in favor of supporting it yes |
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Andrew Cherniavskyi <[email protected]>
Closes #14424.
Re-create #14424 with custom changes.
I can't force push the local branch version to
upstream
, creating a replica on my repo instead.