Skip to content
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

[material-ui][Autocomplete] Fix Passing slotProps to the TextField #43606

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

sai6855
Copy link
Contributor

@sai6855 sai6855 commented Sep 4, 2024

@sai6855 sai6855 added bug 🐛 Something doesn't work component: autocomplete This is the name of the generic UI component, not the React module! labels Sep 4, 2024
@mui-bot
Copy link

mui-bot commented Sep 4, 2024

Netlify deploy preview

https://deploy-preview-43606--material-ui.netlify.app/

Bundle size report

No bundle size changes (Toolpad)
No bundle size changes

Generated by 🚫 dangerJS against e130ed6

@sai6855 sai6855 marked this pull request as draft September 4, 2024 10:35
inputLabel: InputLabelPropsProp,
htmlInput: inputPropsProp,
formHelperText: FormHelperTextPropsProp,
select: SelectPropsProp,
...slotProps,
Copy link
Contributor Author

@sai6855 sai6855 Sep 4, 2024

Choose a reason for hiding this comment

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

Issue is props which are set by Autocomplete to input slot or other slots is getting overriden by slotProps object. Instead of overrding i tried to merge inputProps and slotProps.htmlInput and looks like it is working

Additionally we also need to migrate usage of InputProps, InputLabelProps to slotProps in Autocomplete, i think, it can be done in seperate PR

@sai6855 sai6855 marked this pull request as ready for review September 4, 2024 10:52
@ZeeshanTamboli ZeeshanTamboli changed the title [Autocomplete] Fix Passing slotProps to the TextField [material-ui][Autocomplete] Fix Passing slotProps to the TextField Sep 6, 2024
@ZeeshanTamboli ZeeshanTamboli added the package: material-ui Specific to @mui/material label Sep 6, 2024
Comment on lines +146 to +149
input:
typeof slotProps.input === 'function'
? slotProps.input
: { ...(InputPropsProp ?? {}), ...(slotProps.input ?? {}) },
Copy link
Member

Choose a reason for hiding this comment

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

Are we doing these checks in other components as well? Do we have some kind of helper for this?

Copy link
Contributor Author

@sai6855 sai6855 Sep 23, 2024

Choose a reason for hiding this comment

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

As far as I know, other components don't have these checks. (Also We don't have any issues reported yet on other components)

Instead of creating new helper, I'm thinking it's better to handle this in useSlotProps hook, so that all slots related logic will be in one place

Copy link
Member

Choose a reason for hiding this comment

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

Thoughts @DiegoAndai?

Copy link
Member

Choose a reason for hiding this comment

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

The useSlot hook already has merging strategies implemented, but I think the problem here is that the Autocomplete should handle the slot props better:

  • Refactor Autocomplete to use slotProps instead of InputProps and inputProps
  • Inside Autocomplete, merge slotProps.input and slotProps.htmlInput
const [HtmlInputSlot, htmlInputProps] = useSlot('htmlInput', {
    elementType: 'input',
    externalForwardedProps, // already defined above
    additionalProps: {
        disabled,
        readOnly,
        ...getInputProps(),
    },
    className: classes.input,
    ownerState,
  });

// ...

// line 730
    {renderInput(
     // ...
     // line 778
    slotProps: {
        htmlInput: htmlInputProps,
    },
},

I haven't tested this, but it should be something similar to the code above.

This will be a complex PR, but in the end, the result should be the slots pattern properly implemented in the Autocomplete component.

We're still discussing if the slots pattern needs changes, cc: @aarongarciah, so this PR might require changes in the future given that decision.

Does that make sense @sai6855?

Copy link
Contributor Author

@sai6855 sai6855 Oct 5, 2024

Choose a reason for hiding this comment

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

@DiegoAndai I'm bit confused with this approch. are you imagining renderInput would look something like this after refactoring?

  {renderInput({
          id,
          disabled,
          fullWidth: true,
          size: size === 'small' ? 'small' : undefined,
-          InputLabelProps: getInputLabelProps(),
-          InputProps: {
-          },
-         inputProps: {
-        }
+     slotProps:{
+     htmlInput: htmlInputProps // derived from useSLot
+    input: inputProps // derived from useSLot
+    inputLable: inputLabelProps // derived from useSlot
+ } 
)}

Assuming this is the approach you want to take, I'm not sure it is possible to merge slotProps from renderInput and slotProps defined in user land without doing any changes in userland.

This is how currently users use Autocomplete, after refactoring params will have slotProps key. If i understand your approch you want slotProps in params key and slotProps in highlighted line to be merged inside Autocomplete. As Autocomplete component don't have any control over slotProps in highlighted line, is it possible to merge without changes to be done in userland?

<Autocomplete
      value="one"
      open
      options={['one', 'two']}
      renderInput={(params) => (
+      <TextField {...params} autoFocus slotProps={{ htmlInput: { className: 'my-class' } }} />
      )}
    />

Copy link
Member

Choose a reason for hiding this comment

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

are you imagining renderInput would look something like this after refactoring?

Yes, exactly that

As Autocomplete component don't have any control over slotProps in highlighted line, is it possible to merge without changes to be done in userland?

I don't understand the issue. Is it that params has a slotProps key as well, so it's overridden?

Copy link
Member

Choose a reason for hiding this comment

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

Oh ok, I think I see the issue. The Autocomplete structure confused me. Yes, my suggestion is not correct, I was confusing Autocomplete slots with TextField slots.

Copy link
Member

Choose a reason for hiding this comment

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

@sai6855 I think these should be merged in userland, this was always required, see: #43573 (comment).

Let's wait and see if we can move forward with migrating the usage of InputProps, InputLabelProps to slotProps in Autocomplete

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, apart from migrating *Props to slotProps, i think we should also improve migration guide and if possible add codemod. If x team has made a mistake in migrating then we can expect many such users also done same mistake

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@DiegoAndai what do you think way forward to this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: autocomplete This is the name of the generic UI component, not the React module! package: material-ui Specific to @mui/material
Projects
None yet
5 participants