Skip to content

Fix inputs passing props removed in MUI v9 - #11388

Open
devserkan wants to merge 4 commits into
marmelab:masterfrom
devserkan:fix/mui9-removed-props
Open

devserkan wants to merge 4 commits into
marmelab:masterfrom
devserkan:fix/mui9-removed-props

Conversation

@devserkan

Copy link
Copy Markdown
Contributor

Description

Fix inputs passing props removed in MUI v9

Problem

Since #11248 added MUI v9 to the peer dependencies (#11241), several inputs still pass props that MUI v9 removed:

  • InputProps, inputProps and InputLabelProps on TextField (ResettableTextField, NumberInput, DateInput, DateTimeInput, TimeInput, AutocompleteInput)
  • inputProps on Checkbox (DatagridHeader, SelectPageCheckbox)
  • inputRef on Switch / Checkbox (BooleanInput, CheckboxGroupInput)

On MUI v9 these props reach the DOM and React logs unknown-prop warnings.

The inputRef one is also a functional bug: BooleanInput and CheckboxGroupInput forward the form ref through FormControlLabel's inputRef, so on MUI v9 the ref never reaches the <input> and setFocus() from react-hook-form does nothing (the use case fixed in #9202).

Solution

  • Only pass the legacy props on the MUI versions that still support them, using the existing muiMajor gating pattern. The slotProps equivalents were already passed on MUI v6+.
  • For BooleanInput and CheckboxGroupInput, forward the ref through slotProps.input.ref on MUI v7+, and keep inputRef on older versions. The gate is < 7 rather than < 6 because Switch/Checkbox only support slotProps.input since MUI v6.4.
  • Add type="button" to the SetFocus story buttons of BooleanInput, CheckboxGroupInput and NumberInput. Without it the button submitted the form, which crashed with the default dataProvider (create returns { data: null }).

AutocompleteInput only gets the minimal change here (not passing InputProps on v9). On MUI v9, renderInput receives params.slotProps instead of params.InputProps; I'll handle that in a separate PR to keep this one small.

How To Test

  1. Run the unit tests. The new specs reuse the existing SetFocus stories:
    yarn test-unit packages/ra-ui-materialui/src/input/BooleanInput.spec.tsx packages/ra-ui-materialui/src/input/CheckboxGroupInput.spec.tsx
  2. To see the bug, use an app with react-admin 5.15.4 and @mui/material 9.x, with a button calling setFocus('published') next to a <BooleanInput source="published" />:
    • Before: focus stays on the button, Space does not toggle the switch, and the console shows inputRef / InputProps / InputLabelProps warnings.
    • After (with this branch's ra-ui-materialui build): the switch gets focus, Space toggles it, and these warnings are gone for the changed inputs.

What I verified:

  • MUI v5 (the repo's version): the full ra-ui-materialui suite passes (1204 passed), along with lint, prettier and tsc.
  • MUI v9.4.0: the new ref specs fail on master and pass with this branch. The removed-prop warnings in the ra-ui-materialui suite drop from 728 to 4, and those 4 come from SelectInput.spec.tsx itself. MUI v9 also emits unrelated prop-type warnings (e.g. Invalid prop 'children' supplied to 'ThemeProvider'), which make many tests fail on master too, so I ran these with that noise ignored.
  • The browser check above was done with a local Vite app on MUI 9.4.0.
  • I didn't run MUI v6 or v7. The version gates come from the MUI source (TextField slotProps since v6.0, Switch/Checkbox slotProps.input since v6.4.6).

Additional Checks

  • The PR targets master for a bugfix or a documentation fix, or next for a feature
  • The PR includes unit tests (if not possible, describe why)
  • The PR includes one or several stories (if not possible, describe why) — reuses the existing SetFocus stories, fixed so they no longer submit the form
  • The documentation is up to date — no API change

MUI v9 removed InputProps, inputProps and InputLabelProps from TextField, and inputProps from Checkbox. react-admin still passed them alongside the slotProps equivalents, so on MUI v9 they reached the DOM and triggered React unknown-prop warnings. Only pass the legacy props on the MUI versions that still support them.
Both inputs forwarded the form ref through FormControlLabel's inputRef. MUI v9 removed inputRef from Switch and Checkbox, so the ref never reached the <input> and react-hook-form's setFocus() did nothing. Pass the ref through slotProps.input.ref on MUI v7+, and keep inputRef on older versions, where Switch/Checkbox slotProps.input may not exist.
The buttons had no type, so they defaulted to submit. Clicking them also submitted the form and called the default dataProvider's create, which returns { data: null } and crashed in validateResponseFormat.
// Checkbox slotProps were only added in MUI v6.4
{...(muiMajor < 7
? { inputProps: selectAllInputProps }
: {})}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can make this ternary operator muiMajor < 7 ? { inputProps: selectAllInputProps } : { slotProps: { input: selectAllInputProps } } maybe this will look slightly better?

Also if the old code says muiMajor >= 6 but in your comment Checkbox slotProps were only added in MUI v6.4 then there is a conflict. The peerDependency for @mui/material need to be bumped from "^5.16.12 || ^6.0.0 || ^7.0.0 || ^9.0.0" to "^5.16.12 || ^6.4.0 || ^7.0.0 || ^9.0.0"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw your question in discord https://discord.com/channels/830711057643208724/1552655977608908911 Thanks for pointing that out.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, thanks! Applied the ternary here and in SelectPageCheckbox, which had the same pattern.

About the peerDependency: that's actually why the gate is < 7 instead of < 6. slotProps.input is only used on MUI v7+, where it's always supported, while MUI v6.0–6.3 still get inputProps, which works there. So ^6.0.0 stays valid and we don't need to drop support for 6.0–6.3. I updated the comment to make the reasoning clearer. Happy to bump it if you prefer, though.

PS: I am trusting AI here since I am a bit confused :)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants