label-has-associated-control Rule is Triggered Even when Associated Control is Present
Closed this issue · 9 comments
Integrating this plugin to our code base there was one occasion where the a11y/label-has-associated-control
rule is triggered even when an associated control was present just below the label. We couldn't understand exactly why this is the case? 🤔 Maybe this plugin couldn't understand the underlying react.input
as a proper input
control?
Associated PR Discussion: opencollective/opencollective-frontend#5961 (comment)
Interesting. The code looks normal. I'll try and take a look soon. Thanks for pointing it out
Interesting. The code looks normal. I'll try and take a look soon. Thanks for pointing it out
You are welcome; let us know if there's anything you need from our end. 👍🏽
@SudharakaP It looks like your eslintconfig extends styled-components-a11y which extends eslint-config-airbnb which force both id & nesting rules to be followed. However in your code you only associated them by id. You can override the rule to check for only one of them with this:
'jsx-a11y/label-has-associated-control': [
'error',
{
required: {
some: ['nesting', 'id'],
},
},
],
Or you can change your code to something like this:
<label for="id">
My label
<input id="id">
</label>
@42tte : Thanks much for looking into this issue. 🥇 I've opened a PR which fixes this in our repos, but my understanding is that this is still an issue with this plugin as ideally it should be handled automatically without the user doing manual configurations for this rule. 🤔
cc: @brendanmorrell
I'm running into this now myself: I have a simple set of a styled label
wrapping a styled input
, and this rule is triggered.
The specific code triggering the error (some parts elided):
import styled from 'styled-components';
const ProfilePictureLabel = styled.label`
display: block;
& > img {
cursor: pointer;
height: 160px;
position: relative;
transition: opacity 50ms ease-in-out;
width: 160px;
&.round {
border-radius: 50%;
}
&:hover {
opacity: 0.3;
}
}
`;
const ProfilePictureInput = styled.input`
display: none;
`;
export function ProfileSummary({
[...]
}: Props): JSX.Element {
[...]
return (
[...]
<ProfilePictureLabel>
<img
alt={displayName}
className={accountType === 'BUSINESS' ? undefined : 'round'}
src={profileImageUrl}
/>
<ProfilePictureInput
accept="image/*"
disabled={actionState == 'loading'}
onChange={event => setActionInput(event.target?.files?.[0])}
type="file"
/>
</ProfilePictureLabel>
[...]
);
}
Is it because it is a file input? And/or because it is set to display: none
?
This rule does seem to be imperfect at the moment. I am traveling the next couple months, but when I get back I can take a closer look and see if I can find anything
Since you state this plugin is meant to be the equivalent to eslint-plugin-jsx-a11y you should probably not extend eslint-config-airbnb/rules/react-a11y since the latter apparently have at least one different rule.