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][Select] Select not propagating readonly attribute to input #42256

Closed
Yuwan opened this issue May 16, 2024 · 4 comments
Closed

[material-ui][Select] Select not propagating readonly attribute to input #42256

Yuwan opened this issue May 16, 2024 · 4 comments
Assignees
Labels
component: select This is the name of the generic UI component, not the React module! component: text field This is the name of the generic UI component, not the React module! package: material-ui Specific to @mui/material

Comments

@Yuwan
Copy link

Yuwan commented May 16, 2024

Steps to reproduce

Link to live example: (required)
https://stackblitz.com/edit/react-n9koip-itsgyz?file=index.html,Demo.tsx

Steps:

  1. create a TextField and a SelectTextField and set the attribute to readOnly
  2. add the css with input[readonly] = { color: 'lightgray' }
  3. TextField works well with the correct color
  4. SelectTextField without dropdown list as expected but the css style didn't work.

Current behavior

Ref SelectInput
https://github.com/mui/material-ui/blob/dc922eeec5c1870affd9dfa3c6a351786a2ba451/packages/mui-material/src/Select/SelectInput.js

  • SelectTextField without dropdown list as the logic on line 506
    onMouseDown={disabled || readOnly ? null : handleMouseDown}
    but the Input element without "readonly" attribute
    (please check the imaged below, you cannot find readonly from input element of selectTextfield)
    so in live demo page, the dropdown list didn't show color:lightgray

image

Expected behavior

the behavior should be aligned with the attribute "disabled" or the "readonly" attribute in TextField
Ref SelectInput
https://github.com/mui/material-ui/blob/dc922eeec5c1870affd9dfa3c6a351786a2ba451/packages/mui-material/src/Select/SelectInput.js (line.523-536)

<SelectNativeInput
        aria-invalid={error}
        value={Array.isArray(value) ? value.join(',') : value}
        name={name}
        ref={inputRef}
        aria-hidden
        onChange={handleChange}
        tabIndex={-1}
        disabled={disabled}
        className={classes.nativeInput}
        autoFocus={autoFocus}
        ownerState={ownerState}
        {...other}
      />

I expected there to be an attribute "readonly={readonly}" like disabled={disabled}, so the readonly can apply to the Input element in the end.

Context

Your environment

Browsers:
Chrome: 124.0.6367.201

Search keywords: TextField

Search keywords:

@Yuwan Yuwan added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label May 16, 2024
@LukasTy LukasTy transferred this issue from mui/mui-x May 16, 2024
@zannager zannager added the component: text field This is the name of the generic UI component, not the React module! label May 16, 2024
@ZeeshanTamboli
Copy link
Member

I confirm it's a bug. The readOnly attribute is not passed to the hidden input. Would you like to create a PR? We would also need to add a test.

@ZeeshanTamboli ZeeshanTamboli added bug 🐛 Something doesn't work good first issue Great for first contributions. Enable to learn the contribution process. component: select This is the name of the generic UI component, not the React module! package: material-ui Specific to @mui/material and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels May 27, 2024
@ZeeshanTamboli ZeeshanTamboli changed the title SelectTextField not support readonly attruibute [material-ui] Select not propagating readonly attribute to input May 27, 2024
@ZeeshanTamboli ZeeshanTamboli changed the title [material-ui] Select not propagating readonly attribute to input [material-ui][Select] Select not propagating readonly attribute to input May 27, 2024
qiweiii added a commit to qiweiii/material-ui that referenced this issue May 28, 2024
qiweiii added a commit to qiweiii/material-ui that referenced this issue May 28, 2024
@aarongarciah
Copy link
Member

aarongarciah commented May 28, 2024

Note that even when we fix the issue and readOnly is propagated to the underlying input element, applying styles such as input[readonly] { color: lightgray } won't work because in the case of Select the input is visually hidden.

Also, although we support readOnly in Select, native select elements don't support readonly attributes (see HTML spec). It has no effect and even HTML validators will point it as an error. For example, readOnly in NativeSelect (which renders a plain select) end up in the DOM but has no effect.


Side note: we're not doing a good job of signaling states to assistive tech. When focusing the inputs in this demo https://mui.com/material-ui/react-select/#other-props the error, read-only, and required "states" are not announced.

@aarongarciah
Copy link
Member

aarongarciah commented Jun 4, 2024

Important context: the readOnly HTML is only supported on input (only with some types like text, password, etc.) and textarea elements. Read more in MDN. readOnly is not supported on select elements.

I've been digging deeper into this problem and it's more complex than it seems. I've created these two demos to showcase the issues.

  1. Using v5 (currently 5.15.19): CodeSandbox
  2. Using the PR version: CodeSandbox

You can see the differences between when the .Mui-readOnly class is applied and when the readonly attribute ends up in the DOM between the two versions. We should rely on the .Mui-readOnly class name being present to style read-only inputs and not in the readonly attribute is present.

To get the .Mui-readOnly present, this is the way to do it as of today:

  • <TextField select>: pass InputProps={{ readOnly: true }} (or using slotProps.input once InputProps gets deprecated in v6).
  • <Select>: pass readOnly. inputProps.readOnly doesn't work, neither in the PR version.
  • <NativeSelect>: pass readOnly. This gets the .Mui-readOnly class applied but the field is not read-only in practice.

Conclusions:

  • Developers should rely on .Mui-readOnly class names to style read-only inputs and not in the readonly attribute being present or not.
  • In the future, I think we should consider removing the support for read-only Select as it deviates from the native HTML element. Or at least make it accessible since it's no the case at the moment.
  • Components that accept a read-only state like TextField should have a dedicated prop for it and developers shouldn't rely on passing InputProps={{ readOnly: true }} and the like.
  • I think we should close the PR since it's not really solving anything if my analysis is correct.

cc @DiegoAndai

@DiegoAndai
Copy link
Member

I agree with your analysis @aarongarciah 👌🏼 as well as with closing the PR

I'm adding this issue to the Base UI milestone so we can revisit it when the Select component is refactored on top of Base UI. When that happens, we can revisit the following:

  • In the future, I think we should consider removing the support for read-only Select as it deviates from the native HTML element. Or at least make it accessible since it's no the case at the moment.
  • Components that accept a read-only state like TextField should have a dedicated prop for it and developers shouldn't rely on passing InputProps={{ readOnly: true }} and the like.

@DiegoAndai DiegoAndai added this to the Material UI with Base UI milestone Jun 4, 2024
@aarongarciah aarongarciah closed this as not planned Won't fix, can't repro, duplicate, stale Jun 4, 2024
@aarongarciah aarongarciah removed good first issue Great for first contributions. Enable to learn the contribution process. bug 🐛 Something doesn't work labels Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: select This is the name of the generic UI component, not the React module! component: text field This is the name of the generic UI component, not the React module! package: material-ui Specific to @mui/material
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants