Skip to content
Snippets Groups Projects
Commit 513a8133 authored by David Sveningsson's avatar David Sveningsson
Browse files

fix(rules): allow custom elements to use `aria-label`

parent afc3f1e8
No related branches found
No related tags found
Loading
......@@ -21,6 +21,9 @@ The attribute can only be used on the following elements:
- `<summary>`
- `<table>`, `<td>` and `<th>`
Additionally, this rule ignores elements which explicitly declare an `aria-label` attribute.
See the section on [custom components](#custom-components) below.
## Rule details
Examples of **incorrect** code for this rule:
......@@ -34,3 +37,25 @@ Examples of **correct** code for this rule:
<validate name="correct" rules="aria-label-misuse">
<input type="text" aria-label="foobar">
</validate>
## Custom components
When using custom components and you expect consumers to set `aria-label` on your component you need to explicitly declare the `aria-label` attribute:
```ts
import { defineMetadata } from "html-validate";
export default defineMetadata({
"awesome-component": {
attributes: {
"aria-label": {},
},
},
});
```
The mere presence of `aria-label` declaration ensures this rule will allow `aria-label` to be specified.
## Version history
- %version% - Allow usage on custom elements.
......@@ -7,6 +7,19 @@ describe("rule aria-label-misuse", () => {
beforeAll(() => {
htmlvalidate = new HtmlValidate({
elements: [
"html5",
{
"custom-allowed": {
attributes: {
"aria-label": {},
},
},
"custom-disallowed": {
attributes: {},
},
},
],
rules: { "aria-label-misuse": ["error"] },
});
});
......@@ -71,6 +84,13 @@ describe("rule aria-label-misuse", () => {
});
});
it("should not report on custom element with explicit aria-label attribute", () => {
expect.assertions(1);
const markup = /* HTML */ ` <custom-allowed aria-label="foobar"></custom-allowed> `;
const report = htmlvalidate.validateString(markup);
expect(report).toBeValid();
});
it("should report error when aria-label is used on invalid element", () => {
expect.assertions(2);
const markup = '<p aria-label="foobar"></p>';
......@@ -87,6 +107,19 @@ describe("rule aria-label-misuse", () => {
expect(report).toHaveError("aria-label-misuse", '"aria-label" cannot be used on this element');
});
it("should report error on custom element with without explicit aria-label attribute", () => {
expect.assertions(2);
const markup = /* HTML */ ` <custom-disallowed aria-label="foobar"></custom-disallowed> `;
const report = htmlvalidate.validateString(markup);
expect(report).toBeInvalid();
expect(report).toMatchInlineCodeframe(`
"error: "aria-label" cannot be used on this element (aria-label-misuse) at inline:1:21:
> 1 | <custom-disallowed aria-label="foobar"></custom-disallowed>
| ^^^^^^^^^^
Selector: custom-disallowed"
`);
});
it("should handle dynamic attribute", () => {
expect.assertions(2);
const markup = '<p dynamic-aria-label="foobar"></p>';
......
......@@ -51,6 +51,7 @@ export default class AriaLabelMisuse extends Rule {
});
}
/* eslint-disable-next-line complexity -- technical debt */
private validateElement(target: HtmlElement): void {
const attr = target.getAttribute("aria-label");
if (!attr || !attr.value || attr.valueMatches("", false)) {
......@@ -63,6 +64,11 @@ export default class AriaLabelMisuse extends Rule {
return;
}
/* ignore elements with explicit aria-label attribute */
if (meta.attributes["aria-label"]) {
return;
}
/* ignore landmark and other whitelisted elements */
if (whitelisted.includes(target.tagName)) {
return;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment