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

Support for attribute #977

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -157,7 +157,7 @@ will be evaluated as an `h3`. If no `polymorphicPropName` is set, then the compo
| [img-redundant-alt](docs/rules/img-redundant-alt.md) | Enforce `<img>` alt prop does not contain the word "image", "picture", or "photo". | ☑️ 🔒 | | |
| [interactive-supports-focus](docs/rules/interactive-supports-focus.md) | Enforce that elements with interactive handlers like `onClick` must be focusable. | ☑️ 🔒 | | |
| [label-has-associated-control](docs/rules/label-has-associated-control.md) | Enforce that a `label` tag has a text label and an associated control. | ☑️ 🔒 | | |
| [label-has-for](docs/rules/label-has-for.md) | Enforce that `<label>` elements have the `htmlFor` prop. | | ☑️ 🔒 | ❌ |
| [label-has-for](docs/rules/label-has-for.md) | Enforce that `<label>` elements have the `htmlFor` (or `for`) prop. | | ☑️ 🔒 | ❌ |
| [lang](docs/rules/lang.md) | Enforce lang attribute has a valid value. | | | |
| [media-has-caption](docs/rules/media-has-caption.md) | Enforces that `<audio>` and `<video>` elements must have a `<track>` for captions. | ☑️ 🔒 | | |
| [mouse-events-have-key-events](docs/rules/mouse-events-have-key-events.md) | Enforce that `onMouseOver`/`onMouseOut` are accompanied by `onFocus`/`onBlur` for keyboard-only users. | ☑️ 🔒 | | |
Expand Down
4 changes: 4 additions & 0 deletions __tests__/src/rules/label-has-associated-control-test.js
Expand Up @@ -40,6 +40,10 @@ const htmlForValid = [
{ code: '<label htmlFor="js_id" aria-label="A label" />' },
{ code: '<label htmlFor="js_id" aria-labelledby="A label" />' },
{ code: '<div><label htmlFor="js_id">A label</label><input id="js_id" /></div>' },
{ code: '<label for="js_id"><span><span><span>A label</span></span></span></label>', options: [{ depth: 4 }] },
{ code: '<label for="js_id" aria-label="A label" />' },
{ code: '<label for="js_id" aria-labelledby="A label" />' },
{ code: '<div><label for="js_id">A label</label><input id="js_id" /></div>' },
// Custom label component.
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label" />', options: [{ labelComponents: ['CustomLabel'] }] },
{ code: '<CustomLabel htmlFor="js_id" label="A label" />', options: [{ labelAttributes: ['label'], labelComponents: ['CustomLabel'] }] },
Expand Down
4 changes: 4 additions & 0 deletions __tests__/src/rules/label-has-for-test.js
Expand Up @@ -56,10 +56,14 @@ ruleTester.run('label-has-for', rule, {
{ code: '<div />' },
{ code: '<label htmlFor="foo"><input /></label>' },
{ code: '<label htmlFor="foo"><textarea /></label>' },
{ code: '<label for="foo"><input /></label>' },
{ code: '<label for="foo"><textarea /></label>' },
{ code: '<Label />' }, // lower-case convention refers to real HTML elements.
{ code: '<Label htmlFor="foo" />' },
{ code: '<Label for="foo" />' },
{ code: '<Descriptor />' },
{ code: '<Descriptor htmlFor="foo">Test!</Descriptor>' },
{ code: '<Descriptor for="foo">Test!</Descriptor>' },
{ code: '<UX.Layout>test</UX.Layout>' },

// CUSTOM ELEMENT ARRAY OPTION TESTS
Expand Down
4 changes: 2 additions & 2 deletions docs/rules/label-has-associated-control.md
Expand Up @@ -9,9 +9,9 @@ Enforce that a label tag has a text label and an associated control.
There are two supported ways to associate a label with a control:

- Wrapping a control in a label tag.
- Adding `htmlFor` to a label and assigning it a DOM ID string that indicates an input on the page.
- Adding `htmlFor` (or `for`) to a label and assigning it a DOM ID string that indicates an input on the page.

This rule checks that any `label` tag (or an indicated custom component that will output a `label` tag) either (1) wraps an `input` element (or an indicated custom component that will output an `input` tag) or (2) has an `htmlFor` attribute and that the `label` tag has text content.
This rule checks that any `label` tag (or an indicated custom component that will output a `label` tag) either (1) wraps an `input` element (or an indicated custom component that will output an `input` tag) or (2) has an `htmlFor` (or `for`) attribute and that the `label` tag has text content.

## How do I resolve this error?

Expand Down
4 changes: 2 additions & 2 deletions docs/rules/label-has-for.md
Expand Up @@ -13,7 +13,7 @@ Enforce label tags have associated control.
There are two supported ways to associate a label with a control:

- nesting: by wrapping a control in a label tag
- id: by using the prop `htmlFor` as in `htmlFor=[ID of control]`
- id: by using the prop `htmlFor` (or `for`) as in `htmlFor=[ID of control]`

To fully cover 100% of assistive devices, you're encouraged to validate for both nesting and id.

Expand All @@ -35,7 +35,7 @@ This rule takes one optional object argument of type object:
}
```

For the `components` option, these strings determine which JSX elements (**always including** `<label>`) should be checked for having `htmlFor` prop. This is a good use case when you have a wrapper component that simply renders a `label` element (like in React):
For the `components` option, these strings determine which JSX elements (**always including** `<label>`) should be checked for having `htmlFor` (or `for`) prop. This is a good use case when you have a wrapper component that simply renders a `label` element (like in React):

```js
// Label.js
Expand Down
2 changes: 1 addition & 1 deletion src/rules/label-has-associated-control.js
Expand Up @@ -36,7 +36,7 @@ const schema = generateObjSchema({
});

const validateId = (node) => {
const htmlForAttr = getProp(node.attributes, 'htmlFor');
const htmlForAttr = getProp(node.attributes, 'for') || getProp(node.attributes, 'htmlFor');
const htmlForValue = getPropValue(htmlForAttr);

return htmlForAttr !== false && !!htmlForValue;
Expand Down
4 changes: 2 additions & 2 deletions src/rules/label-has-for.js
Expand Up @@ -46,7 +46,7 @@ function validateNesting(node) {
}

const validateId = (node) => {
const htmlForAttr = getProp(node.attributes, 'htmlFor');
const htmlForAttr = getProp(node.attributes, 'for') || getProp(node.attributes, 'htmlFor');
const htmlForValue = getPropValue(htmlForAttr);

return htmlForAttr !== false && !!htmlForValue;
Expand Down Expand Up @@ -90,7 +90,7 @@ export default {
deprecated: true,
replacedBy: ['label-has-associated-control'],
docs: {
description: 'Enforce that `<label>` elements have the `htmlFor` prop.',
description: 'Enforce that `<label>` elements have the `htmlFor` (or `for`) prop.',
url: 'https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/label-has-for.md',
},
schema: [schema],
Expand Down