diff --git a/javascript/packages/linter/docs/rules/README.md b/javascript/packages/linter/docs/rules/README.md index 93f5541fd..4ac203b84 100644 --- a/javascript/packages/linter/docs/rules/README.md +++ b/javascript/packages/linter/docs/rules/README.md @@ -8,6 +8,7 @@ This page contains documentation for all Herb Linter rules. - [`a11y-avoid-generic-link-text`](./a11y-avoid-generic-link-text.md) - Avoid generic link text like "Click here" or "Read more" - [`a11y-disabled-attribute`](./a11y-disabled-attribute.md) - Prevent usage of the `disabled` attribute on unsupported elements +- [`a11y-nested-interactive-elements`](./a11y-nested-interactive-elements.md) - Disallow nesting interactive elements - [`a11y-no-accesskey-attribute`](./a11y-no-accesskey-attribute.md) - Prevent usage of the `accesskey` attribute - [`a11y-no-aria-label-misuse`](./a11y-no-aria-label-misuse.md) - Prevent `aria-label` and `aria-labelledby` on non-interactive elements - [`a11y-no-aria-unsupported-elements`](./a11y-no-aria-unsupported-elements.md) - Prevent usage of ARIA on unsupported elements diff --git a/javascript/packages/linter/docs/rules/a11y-nested-interactive-elements.md b/javascript/packages/linter/docs/rules/a11y-nested-interactive-elements.md new file mode 100644 index 000000000..6958b1967 --- /dev/null +++ b/javascript/packages/linter/docs/rules/a11y-nested-interactive-elements.md @@ -0,0 +1,65 @@ +# Linter Rule: No nested interactive elements + +**Rule:** `a11y-nested-interactive-elements` + +## Description + +Disallow nesting interactive elements inside other interactive elements. Interactive controls such as `') + }) + + test("fails for anchor deeply nested inside button", () => { + expectError('Found `` nested inside of `') + }) + + test("fails for input deeply nested inside anchor", () => { + expectError('Found `` nested inside of ``. Nesting interactive elements produces invalid HTML, and assistive technologies, such as screen readers, might ignore or respond unexpectedly to such nested controls.') + + assertOffenses('
') + }) + + test("fails for input with dynamic type inside button", () => { + expectError('Found `` nested inside of `') + }) + + test("passes for div with role=button containing anchor", () => { + expectNoOffenses('
Link
') + }) + + test("fails for tag.a nested inside tag.button", () => { + expectError('Found `` nested inside of `') + }) + + test("fails for link_to block with nested button", () => { + expectError('Found `<% end %>') + }) + + test("fails for link_to block with nested tag.button", () => { + expectError('Found `') + }) +})