-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
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
[Select][material-ui] Add name to hidden input element #39414
Conversation
Netlify deploy previewhttps://deploy-preview-39414--material-ui.netlify.app/ Bundle size reportDetails of bundle changes (Toolpad) |
@@ -213,7 +213,7 @@ describe('<TextField />', () => { | |||
); | |||
|
|||
const input = container.querySelector('input[aria-hidden]'); | |||
expect(input).not.to.have.attribute('id'); | |||
expect(input).to.have.attribute('id'); | |||
expect(input).not.to.have.attribute('aria-describedby'); |
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 we're changing the logic to include the id, perhaps we should also add the label-id to the aria-describedby as well?
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.
Nevermind, I just re-read and realised you used the htmlFor attribute on the label instead
Though this may actually cause an accessibility issue when the screenreader finds the label but can't find the associated input (because it's aria-hidden)
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.
So what do you suggest I do? Also, I just realised that this might still be happening because current htmlFor addresses the div.
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 not sure, unfortunately I'm not super well versed in improving accessibility. At the very least you could check out the chrome issues tab with your changes in place, to see what (if any) issues will occur around the Textfield with the select prop set to true.
I still have a suspicion that it will cause users of screenreaders to get confused from the label pointing to a hidden input though
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.
@Owenleo778 I completely understand your point. I'm not very experienced with accessibility either. I did check the Chrome issues tab, and it seems that there are no reported issues related to the changes made. If you have any specific recommendations or resources on accessibility best practices, I'd be more than happy to learn and implement them.
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 thinking about it more, I do feel like it would be best to change how the label connection is defined. Rather than setting the label's htmlFor attribute, I feel like it would be better to set the input's aria-labelledby attribute to the label id instead. This way, screenreaders wont see the for attribute leading to an invisible input from their perspective.
Hopefully, it resolves the chrome issues without causing any additional accessibility problems
(Though honestly, it does feel redundant to set up the id / htmlFor / aria-labeledby etc attributes when they're going to be hidden from the common usages anyway. But at least we can quieten the chrome issues. This is most likely the reason it wasn't set to something else when removed initially)
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.
As far as I can tell, this at minimum maintains the same level of accessibility as before and (presumably) removes the related chrome flagged issues.
You'll still have to wait for someone else to review first though
@Owenleo778 After some more testing I noticed that the accessibility issue is only shown in Chrome (still), I am unable to reproduce the issue in Safari and Firefox. I believe this might actually be an issue with Chrome DevTools as suggested in the original issue. Here, setting There were other accessibility issue for this |
The chrome throws an error: Incorrect use of <label for=FORM_ELEMENT>
The label's for attribute doesn't match any element id. This might prevent the browser from correctly autofilling the form and accessibility tools from working correctly.
To fix this issue, make sure the label's for attribute references the correct id of a form field. It seems that there's an issue with MUI's current practice of setting the label's htmlFor to a div and the div's aria-labelledby to the label's id. Upon further research into accessibility practices, I've found that setting a label's for attribute to a non-form field is generally considered a bad practice in terms of accessibility. Which leads to unexpected behavior in autofill and accessibility tools. That is why, there are multiple similar issues regarding this in the devtools. Now, I'm leaning towards the idea that the label's for attribute should not point to the div. However, I'm not entirely certain if this issue can be easily resolved without changing the overall accessibility practices within the components. I'd really appreciate your thoughts on this matter. |
The only accessibility issue would be the label without a linked input field I believe (since the input is hidden to screenreaders). I agree, due to the implementation of the component I don't see any easy solutions. Unfortunately, without the knowledge of the history of the component / reasoning behind certain decisions, I can't really comment much further on where to take this. We could potentially swap the input label for a different text component, but i'm not sure of the ramifications of that change on accessibility, and could just make the situation worse. |
@Owenleo778 How should I proceed now? Should I contact member signed in the implementation commit? |
@DarhkVoyd I'm not sure on the etiquette of reaching out directly, but potentially simply just leaving this issue until they view this PR and respond could be the best path of action for now |
Sorry for not getting back to this sooner, I will review this PR this week 🙏 |
@DarhkVoyd I don't think adding
But to get rid of the diff --git a/packages/mui-material/src/Select/SelectInput.js b/packages/mui-material/src/Select/SelectInput.js
index 9c36c98f14..75cd39dd11 100644
--- a/packages/mui-material/src/Select/SelectInput.js
+++ b/packages/mui-material/src/Select/SelectInput.js
@@ -489,6 +489,8 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
const listboxId = useId();
+ const hiddenInputId = useId();
+
return (
<React.Fragment>
<SelectSelect
@@ -523,7 +525,7 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
<SelectNativeInput
aria-invalid={error}
value={Array.isArray(value) ? value.join(',') : value}
- name={name}
+ name={name ?? hiddenInputId}
ref={inputRef}
aria-hidden
onChange={handleChange}
|
@Owenleo778 I think this is fine and doesn't harm a11y, see my comment here: #38869 (comment) |
@mj12albert Thank you, adding generated Id to name does resolve the |
@mj12albert Hey, I have made the necessary changes, fixing it from the users perspective which lead to a small styling error which I also have solved. Kindly review the PR. |
Thanks @DarhkVoyd for working through this and @Owenleo778 for assisting with the review 🙏 I've made a note to port the fix and the breaking change to v6 which we are ramping up! |
Nice one! |
Co-authored-by: Albert Yu <albert@albertyu.co>
Co-authored-by: Albert Yu <albert@albertyu.co>
Co-authored-by: Albert Yu <albert@albertyu.co>
Co-authored-by: Albert Yu <albert@albertyu.co>
Co-authored-by: Albert Yu <albert@albertyu.co>
Co-authored-by: Albert Yu <albert@albertyu.co>
I believe this change has unintended side effects; see #40128. |
This reverts commit b81119c.
Changes Made:
TextField.js
to have a conditionalhtmlFor
which generatesid
for the input based onselect
prop.id
is assigned to theSelectInput
throughSelectDisplayProps.id
inSelectInput.js
.id
on the input.Testing:
I have added tests to the
TextField.test.js
file to ensure that the changes work as expected. The tests include matching the id of the input with the label's htmlFor.Edit: The above discussed changes were discarded after further assessment instead a
name
was added to the hidden input element withuseId()
method. Theincorrect use of label for
error that could be resolved by passingspan
ascomponent
would also bring some styling issues. Since, settingspan
as the default component in this case would be a breaking change, it was noted for Port to v6 and just the style fix was added for now.Closes #38869