From 7eed2d352e97aed490a0b9064a02e68ba20ddcfa Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Wed, 29 Jan 2025 15:19:00 +0100 Subject: [PATCH 1/5] Do not pass null reference as inputRef prop --- .../src/components/headerFiltering/GridHeaderFilterCell.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx index 1aa17b1db3187..b0e5addcc201e 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx @@ -399,7 +399,7 @@ const GridHeaderFilterCell = forwardRef apiRef.current.startHeaderFilterEditMode(colDef.field)} onBlur={(event: React.FocusEvent) => { From 42a7ca666c08bf20771851e47e4952e288b60bf5 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Wed, 29 Jan 2025 16:01:37 +0100 Subject: [PATCH 2/5] Revert inputRef change. Update type --- .../headerFiltering/GridHeaderFilterCell.tsx | 12 ++++++++++-- .../headerFiltering/GridHeaderFilterMenu.tsx | 10 +++++++++- .../GridHeaderFilterMenuContainer.tsx | 10 +++++++++- .../panel/filterPanel/GridFilterInputBoolean.tsx | 10 +++++++++- .../panel/filterPanel/GridFilterInputDate.tsx | 10 +++++++++- .../GridFilterInputMultipleSingleSelect.tsx | 10 +++++++++- .../filterPanel/GridFilterInputMultipleValue.tsx | 10 +++++++++- .../filterPanel/GridFilterInputSingleSelect.tsx | 10 +++++++++- .../panel/filterPanel/GridFilterInputValue.tsx | 10 +++++++++- .../src/models/gridFilterInputComponent.ts | 2 +- 10 files changed, 83 insertions(+), 11 deletions(-) diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx index b0e5addcc201e..9543352491b0e 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx @@ -399,7 +399,7 @@ const GridHeaderFilterCell = forwardRef apiRef.current.startHeaderFilterEditMode(colDef.field)} onBlur={(event: React.FocusEvent) => { @@ -474,7 +474,15 @@ GridHeaderFilterCell.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), isFilterActive: PropTypes.bool, diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx index b24129a931779..ca42ac3df62b6 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx @@ -148,7 +148,15 @@ GridHeaderFilterMenu.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), isFilterActive: PropTypes.bool, diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx index e75a661ec2d26..cc7c1fd7490c5 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx @@ -137,7 +137,15 @@ GridHeaderFilterMenuContainer.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), isFilterActive: PropTypes.bool, diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx index 1f0dfc650526c..2066e94855af2 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputBoolean.tsx @@ -138,7 +138,15 @@ GridFilterInputBoolean.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), /** diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx index 2fafebd80077d..212a822d2ae1c 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputDate.tsx @@ -136,7 +136,15 @@ GridFilterInputDate.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), /** diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.tsx index 1deb5e5c5a2d6..723812f8d13f0 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.tsx @@ -134,7 +134,15 @@ GridFilterInputMultipleSingleSelect.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), /** diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleValue.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleValue.tsx index bdcc97686a3f5..811eca346200f 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleValue.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputMultipleValue.tsx @@ -111,7 +111,15 @@ GridFilterInputMultipleValue.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), /** diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx index 2a7a63ebf9e64..c710e07f7ebc3 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputSingleSelect.tsx @@ -174,7 +174,15 @@ GridFilterInputSingleSelect.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), /** diff --git a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx index 0cdc9ce880920..3b2eb5bc392a2 100644 --- a/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx +++ b/packages/x-data-grid/src/components/panel/filterPanel/GridFilterInputValue.tsx @@ -128,7 +128,15 @@ GridFilterInputValue.propTypes = { inputRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), /** diff --git a/packages/x-data-grid/src/models/gridFilterInputComponent.ts b/packages/x-data-grid/src/models/gridFilterInputComponent.ts index f41a4cd0e70fb..442700a10035e 100644 --- a/packages/x-data-grid/src/models/gridFilterInputComponent.ts +++ b/packages/x-data-grid/src/models/gridFilterInputComponent.ts @@ -18,7 +18,7 @@ export type GridFilterInputValueProps< applyValue: (value: GridFilterItem) => void; // Is any because if typed as GridApiRef a dep cycle occurs. Same happens if ApiContext is used. apiRef: RefObject; - inputRef?: React.Ref; + inputRef?: React.Ref; focusElementRef?: React.Ref; headerFilterMenu?: React.ReactNode; clearButton?: React.ReactNode | null; From f7b23689ac1ffeabb2b19709882c46988754f7ba Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Wed, 29 Jan 2025 16:20:24 +0100 Subject: [PATCH 3/5] Revert waitFor removed in #16101 --- .../tests/dataSourceAggregation.DataGridPremium.test.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/x-data-grid-premium/src/tests/dataSourceAggregation.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/dataSourceAggregation.DataGridPremium.test.tsx index 8defca0540cd1..8a67f0acf0957 100644 --- a/packages/x-data-grid-premium/src/tests/dataSourceAggregation.DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/dataSourceAggregation.DataGridPremium.test.tsx @@ -99,12 +99,18 @@ describe(' - Data source aggregation', () => { it('should show aggregation option in the column menu', async () => { const { user } = render(); + await waitFor(() => { + expect(getRowsSpy.callCount).to.be.greaterThan(0); + }); await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); expect(screen.queryByLabelText('Aggregation')).not.to.equal(null); }); it('should not show aggregation option in the column menu when no aggregation function is defined', async () => { const { user } = render(); + await waitFor(() => { + expect(getRowsSpy.callCount).to.be.greaterThan(0); + }); await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu')); expect(screen.queryByLabelText('Aggregation')).to.equal(null); }); @@ -117,6 +123,9 @@ describe(' - Data source aggregation', () => { }} />, ); + await waitFor(() => { + expect(getRowsSpy.callCount).to.be.greaterThan(0); + }); expect(getRowsSpy.args[0][0].aggregationModel).to.deep.equal({ id: 'size' }); }); From b13e35213fb613ff01c1b442547a5312cb7d1aa2 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Wed, 29 Jan 2025 16:21:24 +0100 Subject: [PATCH 4/5] Update focusElementRef type --- .../headerFiltering/GridHeaderFilterCell.tsx | 10 +++++++++- .../headerFiltering/GridHeaderFilterMenu.tsx | 10 +++++++++- .../headerFiltering/GridHeaderFilterMenuContainer.tsx | 10 +++++++++- .../x-data-grid/src/models/gridFilterInputComponent.ts | 2 +- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx index 9543352491b0e..d4fc11357c530 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx @@ -467,7 +467,15 @@ GridHeaderFilterCell.propTypes = { focusElementRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), headerFilterMenu: PropTypes.node, diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx index ca42ac3df62b6..9578244807943 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx @@ -141,7 +141,15 @@ GridHeaderFilterMenu.propTypes = { focusElementRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), headerFilterMenu: PropTypes.node, diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx index cc7c1fd7490c5..7a7624862250b 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx @@ -130,7 +130,15 @@ GridHeaderFilterMenuContainer.propTypes = { focusElementRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: PropTypes.any.isRequired, + current: (props, propName) => { + if (props[propName] == null) { + return null; + } + if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { + return new Error(`Expected prop '${propName}' to be of type Element`); + } + return null; + }, }), ]), headerFilterMenu: PropTypes.node, diff --git a/packages/x-data-grid/src/models/gridFilterInputComponent.ts b/packages/x-data-grid/src/models/gridFilterInputComponent.ts index 442700a10035e..e9db2b6b83745 100644 --- a/packages/x-data-grid/src/models/gridFilterInputComponent.ts +++ b/packages/x-data-grid/src/models/gridFilterInputComponent.ts @@ -19,7 +19,7 @@ export type GridFilterInputValueProps< // Is any because if typed as GridApiRef a dep cycle occurs. Same happens if ApiContext is used. apiRef: RefObject; inputRef?: React.Ref; - focusElementRef?: React.Ref; + focusElementRef?: React.Ref; headerFilterMenu?: React.ReactNode; clearButton?: React.ReactNode | null; /** From bdd59779fea2f74f2a837745985796dcc2a0c290 Mon Sep 17 00:00:00 2001 From: Armin Mehinovic Date: Wed, 29 Jan 2025 16:28:10 +0100 Subject: [PATCH 5/5] Revert type update for focusElementRef --- .../headerFiltering/GridHeaderFilterCell.tsx | 10 +--------- .../headerFiltering/GridHeaderFilterMenu.tsx | 10 +--------- .../headerFiltering/GridHeaderFilterMenuContainer.tsx | 10 +--------- .../x-data-grid/src/models/gridFilterInputComponent.ts | 2 +- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx index d4fc11357c530..9543352491b0e 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterCell.tsx @@ -467,15 +467,7 @@ GridHeaderFilterCell.propTypes = { focusElementRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: (props, propName) => { - if (props[propName] == null) { - return null; - } - if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { - return new Error(`Expected prop '${propName}' to be of type Element`); - } - return null; - }, + current: PropTypes.any.isRequired, }), ]), headerFilterMenu: PropTypes.node, diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx index 9578244807943..ca42ac3df62b6 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenu.tsx @@ -141,15 +141,7 @@ GridHeaderFilterMenu.propTypes = { focusElementRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: (props, propName) => { - if (props[propName] == null) { - return null; - } - if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { - return new Error(`Expected prop '${propName}' to be of type Element`); - } - return null; - }, + current: PropTypes.any.isRequired, }), ]), headerFilterMenu: PropTypes.node, diff --git a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx index 7a7624862250b..cc7c1fd7490c5 100644 --- a/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx +++ b/packages/x-data-grid-pro/src/components/headerFiltering/GridHeaderFilterMenuContainer.tsx @@ -130,15 +130,7 @@ GridHeaderFilterMenuContainer.propTypes = { focusElementRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ - current: (props, propName) => { - if (props[propName] == null) { - return null; - } - if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) { - return new Error(`Expected prop '${propName}' to be of type Element`); - } - return null; - }, + current: PropTypes.any.isRequired, }), ]), headerFilterMenu: PropTypes.node, diff --git a/packages/x-data-grid/src/models/gridFilterInputComponent.ts b/packages/x-data-grid/src/models/gridFilterInputComponent.ts index e9db2b6b83745..442700a10035e 100644 --- a/packages/x-data-grid/src/models/gridFilterInputComponent.ts +++ b/packages/x-data-grid/src/models/gridFilterInputComponent.ts @@ -19,7 +19,7 @@ export type GridFilterInputValueProps< // Is any because if typed as GridApiRef a dep cycle occurs. Same happens if ApiContext is used. apiRef: RefObject; inputRef?: React.Ref; - focusElementRef?: React.Ref; + focusElementRef?: React.Ref; headerFilterMenu?: React.ReactNode; clearButton?: React.ReactNode | null; /**