Skip to content

Commit 47633fb

Browse files
committed
[Fix] label-has-for: textareas are inputs too
Fixes #470.
1 parent c1bf3c1 commit 47633fb

File tree

3 files changed

+7
-1
lines changed

3 files changed

+7
-1
lines changed

__tests__/src/rules/label-has-associated-control-test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const htmlForValid = [
3838
];
3939
const nestingValid = [
4040
{ code: '<label>A label<input /></label>' },
41+
{ code: '<label>A label<textarea /></label>' },
4142
{ code: '<label><img alt="A label" /><input /></label>' },
4243
{ code: '<label><img aria-label="A label" /><input /></label>' },
4344
{ code: '<label><span>A label<input /></span></label>' },
@@ -56,6 +57,7 @@ const bothValid = [
5657
{ code: '<label htmlFor="js_id"><span><span><span>A label<input /></span></span></span></label>', options: [{ depth: 4 }] },
5758
{ code: '<label htmlFor="js_id" aria-label="A label"><input /></label>' },
5859
{ code: '<label htmlFor="js_id" aria-labelledby="A label"><input /></label>' },
60+
{ code: '<label htmlFor="js_id" aria-labelledby="A label"><textarea /></label>' },
5961
// Custom label component.
6062
{ code: '<CustomLabel htmlFor="js_id" aria-label="A label"><input /></CustomLabel>', options: [{ labelComponents: ['CustomLabel'] }] },
6163
{ code: '<CustomLabel htmlFor="js_id" label="A label"><input /></CustomLabel>', options: [{ labelAttributes: ['label'], labelComponents: ['CustomLabel'] }] },
@@ -80,6 +82,7 @@ const htmlForInvalid = [
8082
];
8183
const nestingInvalid = [
8284
{ code: '<label>A label<input /></label>', errors: [expectedError] },
85+
{ code: '<label>A label<textarea /></label>', errors: [expectedError] },
8386
{ code: '<label><img alt="A label" /><input /></label>', errors: [expectedError] },
8487
{ code: '<label><img aria-label="A label" /><input /></label>', errors: [expectedError] },
8588
{ code: '<label><span>A label<input /></span></label>', errors: [expectedError] },
@@ -97,6 +100,7 @@ const nestingInvalid = [
97100
const neverValid = [
98101
{ code: '<label htmlFor="js_id" />', errors: [expectedError] },
99102
{ code: '<label htmlFor="js_id"><input /></label>', errors: [expectedError] },
103+
{ code: '<label htmlFor="js_id"><textarea /></label>', errors: [expectedError] },
100104
{ code: '<label></label>', errors: [expectedError] },
101105
{ code: '<label>A label</label>', errors: [expectedError] },
102106
{ code: '<div><label /><input /></div>', errors: [expectedError] },

__tests__/src/rules/label-has-for-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ ruleTester.run('label-has-for', rule, {
5656
// DEFAULT ELEMENT 'label' TESTS
5757
{ code: '<div />' },
5858
{ code: '<label htmlFor="foo"><input /></label>' },
59+
{ code: '<label htmlFor="foo"><textarea /></label>' },
5960
{ code: '<Label />' }, // lower-case convention refers to real HTML elements.
6061
{ code: '<Label htmlFor="foo" />' },
6162
{ code: '<Descriptor />' },
@@ -100,6 +101,7 @@ ruleTester.run('label-has-for', rule, {
100101
{ code: '<label>First Name</label>', errors: [expectedEveryError], options: optionsRequiredEvery },
101102
{ code: '<label {...props}>Foo</label>', errors: [expectedEveryError], options: optionsRequiredEvery },
102103
{ code: '<label><input /></label>', errors: [expectedEveryError], options: optionsRequiredEvery },
104+
{ code: '<label><textarea /></label>', errors: [expectedEveryError], options: optionsRequiredEvery },
103105
{ code: '<label>{children}</label>', errors: [expectedEveryError], options: optionsRequiredEvery },
104106
{ code: '<label htmlFor="foo" />', errors: [expectedEveryError], options: optionsRequiredEvery },
105107
{ code: '<label htmlFor={"foo"} />', errors: [expectedEveryError], options: optionsRequiredEvery },

src/rules/label-has-for.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function validateNesting(node) {
3434
while (queue.length) {
3535
child = queue.shift();
3636
opener = child.openingElement;
37-
if (child.type === 'JSXElement' && opener && opener.name.name === 'input') {
37+
if (child.type === 'JSXElement' && opener && (opener.name.name === 'input' || opener.name.name === 'textarea')) {
3838
return true;
3939
}
4040
if (child.children) {

0 commit comments

Comments
 (0)