diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts
index e351a02499..119e187954 100644
--- a/src/compiler/compile/nodes/Element.ts
+++ b/src/compiler/compile/nodes/Element.ts
@@ -626,8 +626,24 @@ export default class Element extends Node {
}
if (this.name === 'label') {
- const has_input_child = this.children.some(i => (i instanceof Element && a11y_labelable.has(i.name) ));
- if (!attribute_map.has('for') && !has_input_child) {
+ const has_input_child = (children: INode[]) => {
+ if (children.some(child => (child instanceof Element && (a11y_labelable.has(child.name) || child.name === 'slot')))) {
+ return true;
+ }
+
+ for (const child of children) {
+ if (!('children' in child) || child.children.length === 0) {
+ continue;
+ }
+ if (has_input_child(child.children)) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ if (!attribute_map.has('for') && !has_input_child(this.children)) {
component.warn(this, compiler_warnings.a11y_label_has_associated_control);
}
}
diff --git a/test/validator/samples/a11y-label-has-associated-control-2/input.svelte b/test/validator/samples/a11y-label-has-associated-control-2/input.svelte
new file mode 100644
index 0000000000..de26d50782
--- /dev/null
+++ b/test/validator/samples/a11y-label-has-associated-control-2/input.svelte
@@ -0,0 +1,3 @@
+
diff --git a/test/validator/samples/a11y-label-has-associated-control-2/warnings.json b/test/validator/samples/a11y-label-has-associated-control-2/warnings.json
new file mode 100644
index 0000000000..fe51488c70
--- /dev/null
+++ b/test/validator/samples/a11y-label-has-associated-control-2/warnings.json
@@ -0,0 +1 @@
+[]
diff --git a/test/validator/samples/a11y-label-has-associated-control/input.svelte b/test/validator/samples/a11y-label-has-associated-control/input.svelte
index 43304689dc..124888c089 100644
--- a/test/validator/samples/a11y-label-has-associated-control/input.svelte
+++ b/test/validator/samples/a11y-label-has-associated-control/input.svelte
@@ -1,6 +1,12 @@
+
+
+
+G
diff --git a/test/validator/samples/a11y-label-has-associated-control/warnings.json b/test/validator/samples/a11y-label-has-associated-control/warnings.json
index b70a1a47de..f618e16973 100644
--- a/test/validator/samples/a11y-label-has-associated-control/warnings.json
+++ b/test/validator/samples/a11y-label-has-associated-control/warnings.json
@@ -1,32 +1,32 @@
[
- {
- "code": "a11y-label-has-associated-control",
- "end": {
- "character": 16,
- "column": 16,
- "line": 1
- },
- "message": "A11y: A form label must be associated with a control.",
- "pos": 0,
- "start": {
- "character": 0,
- "column": 0,
- "line": 1
- }
- },
- {
- "code": "a11y-label-has-associated-control",
- "end": {
- "character": 149,
- "column": 30,
- "line": 6
- },
- "message": "A11y: A form label must be associated with a control.",
- "pos": 119,
- "start": {
- "character": 119,
- "column": 0,
- "line": 6
- }
- }
+ {
+ "code": "a11y-label-has-associated-control",
+ "end": {
+ "character": 82,
+ "column": 16,
+ "line": 5
+ },
+ "message": "A11y: A form label must be associated with a control.",
+ "pos": 66,
+ "start": {
+ "character": 66,
+ "column": 0,
+ "line": 5
+ }
+ },
+ {
+ "code": "a11y-label-has-associated-control",
+ "end": {
+ "character": 215,
+ "column": 30,
+ "line": 10
+ },
+ "message": "A11y: A form label must be associated with a control.",
+ "pos": 185,
+ "start": {
+ "character": 185,
+ "column": 0,
+ "line": 10
+ }
+ }
]