diff --git a/dist/lib/index.js b/dist/lib/index.js
index f2493d3..e1784d5 100644
--- a/dist/lib/index.js
+++ b/dist/lib/index.js
@@ -7,6 +7,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
console.log("Loading my-eslint-plugin");
const prefer_aria_over_title_attribute_1 = __importDefault(require("./rules/prefer-aria-over-title-attribute"));
+const checkbox_needs_labelling_1 = __importDefault(require("./rules/checkbox-needs-labelling"));
+const image_button_missing_aria_1 = __importDefault(require("./rules/buttons/image-button-missing-aria"));
+const link_missing_labelling_1 = __importDefault(require("./rules/link-missing-labelling"));
+const input_components_require_accessible_name_1 = __importDefault(require("./rules/input-components-require-accessible-name"));
+const menu_item_needs_labelling_1 = __importDefault(require("./rules/menu-item-needs-labelling"));
+const switch_needs_labelling_1 = __importDefault(require("./rules/switch-needs-labelling"));
+const toolbar_missing_aria_1 = __importDefault(require("./rules/toolbar-missing-aria"));
+const combobox_needs_labelling_1 = __importDefault(require("./rules/combobox-needs-labelling"));
+const no_empty_components_1 = __importDefault(require("./rules/no-empty-components"));
+const accordion_header_needs_labelling_1 = __importDefault(require("./rules/accordion-header-needs-labelling"));
+const accordion_item_needs_header_and_panel_1 = __importDefault(require("./rules/accordion-item-needs-header-and-panel"));
+const compound_button_needs_labelling_1 = __importDefault(require("./rules/buttons/compound-button-needs-labelling"));
+const no_empty_buttons_1 = __importDefault(require("./rules/buttons/no-empty-buttons"));
+const spin_button_needs_labelling_1 = __importDefault(require("./rules/spin-button-needs-labelling"));
+const spin_button_unrecommended_labelling_1 = __importDefault(require("./rules/spin-button-unrecommended-labelling"));
+const breadcrumb_needs_labelling_1 = __importDefault(require("./rules/breadcrumb-needs-labelling"));
+const dropdown_needs_labelling_1 = __importDefault(require("./rules/dropdown-needs-labelling"));
+const tooltip_not_recommended_1 = __importDefault(require("./rules/tooltip-not-recommended"));
+const avatar_needs_name_1 = __importDefault(require("./rules/avatar-needs-name"));
+const radio_button_missing_label_1 = __importDefault(require("./rules/radio-button-missing-label"));
+const radiogroup_missing_label_1 = __importDefault(require("./rules/radiogroup-missing-label"));
+const dialogbody_needs_title_content_and_actions_1 = __importDefault(require("./rules/dialogbody-needs-title-content-and-actions"));
+const dialogsurface_needs_aria_1 = __importDefault(require("./rules/dialogsurface-needs-aria"));
+const spinner_needs_labelling_1 = __importDefault(require("./rules/spinner-needs-labelling"));
+const badge_needs_accessible_name_1 = __importDefault(require("./rules/badge-needs-accessible-name"));
+const progressbar_needs_labelling_1 = __importDefault(require("./rules/progressbar-needs-labelling"));
const field_needs_labelling_1 = __importDefault(require("./rules/field-needs-labelling"));
//------------------------------------------------------------------------------
// Requirements
@@ -17,33 +43,33 @@ const field_needs_labelling_1 = __importDefault(require("./rules/field-needs-lab
// import all rules in lib/rules
module.exports = {
rules: {
- "checkbox-needs-labelling": require("./rules/checkbox-needs-labelling"),
- "image-button-missing-aria": require("./rules/buttons/image-button-missing-aria"),
- "link-missing-labelling": require("./rules/link-missing-labelling"),
- "input-components-require-accessible-name": require("./rules/input-components-require-accessible-name"),
- "menu-item-needs-labelling": require("./rules/menu-item-needs-labelling"),
- "switch-needs-labelling": require("./rules/switch-needs-labelling"),
- "toolbar-missing-aria": require("./rules/toolbar-missing-aria"),
- "combobox-needs-labelling": require("./rules/combobox-needs-labelling"),
- "no-empty-components": require("./rules/no-empty-components"),
- "accordion-header-needs-labelling": require("./rules/accordion-header-needs-labelling"),
- "accordion-item-needs-header-and-panel": require("./rules/accordion-item-needs-header-and-panel"),
- "compound-button-needs-labelling": require("./rules/buttons/compound-button-needs-labelling"),
- "no-empty-buttons": require("./rules/buttons/no-empty-buttons"),
- "spin-button-needs-labelling": require("./rules/spin-button-needs-labelling"),
- "spin-button-unrecommended-labelling": require("./rules/spin-button-unrecommended-labelling"),
- "breadcrumb-needs-labelling": require("./rules/breadcrumb-needs-labelling"),
- "dropdown-needs-labelling": require("./rules/dropdown-needs-labelling"),
- "tooltip-not-recommended": require("./rules/tooltip-not-recommended"),
- "avatar-needs-name": require("./rules/avatar-needs-name"),
- "radio-button-missing-label": require("./rules/radio-button-missing-label"),
- "radiogroup-missing-label": require("./rules/radiogroup-missing-label"),
+ "checkbox-needs-labelling": checkbox_needs_labelling_1.default,
+ "image-button-missing-aria": image_button_missing_aria_1.default,
+ "link-missing-labelling": link_missing_labelling_1.default,
+ "input-components-require-accessible-name": input_components_require_accessible_name_1.default,
+ "menu-item-needs-labelling": menu_item_needs_labelling_1.default,
+ "switch-needs-labelling": switch_needs_labelling_1.default,
+ "toolbar-missing-aria": toolbar_missing_aria_1.default,
+ "combobox-needs-labelling": combobox_needs_labelling_1.default,
+ "no-empty-components": no_empty_components_1.default,
+ "accordion-header-needs-labelling": accordion_header_needs_labelling_1.default,
+ "accordion-item-needs-header-and-panel": accordion_item_needs_header_and_panel_1.default,
+ "compound-button-needs-labelling": compound_button_needs_labelling_1.default,
+ "no-empty-buttons": no_empty_buttons_1.default,
+ "spin-button-needs-labelling": spin_button_needs_labelling_1.default,
+ "spin-button-unrecommended-labelling": spin_button_unrecommended_labelling_1.default,
+ "breadcrumb-needs-labelling": breadcrumb_needs_labelling_1.default,
+ "dropdown-needs-labelling": dropdown_needs_labelling_1.default,
+ "tooltip-not-recommended": tooltip_not_recommended_1.default,
+ "avatar-needs-name": avatar_needs_name_1.default,
+ "radio-button-missing-label": radio_button_missing_label_1.default,
+ "radiogroup-missing-label": radiogroup_missing_label_1.default,
"prefer-aria-over-title-attribute": prefer_aria_over_title_attribute_1.default,
- "dialogbody-needs-title-content-and-actions": require("./rules/dialogbody-needs-title-content-and-actions"),
- "dialogsurface-needs-aria": require("./rules/dialogsurface-needs-aria"),
- "spinner-needs-labelling": require("./rules/spinner-needs-labelling"),
- "badge-needs-accessible-name": require("./rules/badge-needs-accessible-name"),
- "progressbar-needs-labelling": require("./rules/progressbar-needs-labelling"),
+ "dialogbody-needs-title-content-and-actions": dialogbody_needs_title_content_and_actions_1.default,
+ "dialogsurface-needs-aria": dialogsurface_needs_aria_1.default,
+ "spinner-needs-labelling": spinner_needs_labelling_1.default,
+ "badge-needs-accessible-name": badge_needs_accessible_name_1.default,
+ "progressbar-needs-labelling": progressbar_needs_labelling_1.default,
"field-needs-labelling": field_needs_labelling_1.default
},
configs: {
diff --git a/dist/lib/rules/accordion-header-needs-labelling.d.ts b/dist/lib/rules/accordion-header-needs-labelling.d.ts
index de4c0ec..f2a0058 100644
--- a/dist/lib/rules/accordion-header-needs-labelling.d.ts
+++ b/dist/lib/rules/accordion-header-needs-labelling.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingAriaLabel", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/accordion-header-needs-labelling.js b/dist/lib/rules/accordion-header-needs-labelling.js
index f3b0a88..ccb655e 100644
--- a/dist/lib/rules/accordion-header-needs-labelling.js
+++ b/dist/lib/rules/accordion-header-needs-labelling.js
@@ -1,17 +1,18 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-var hasProp = require("jsx-ast-utils").hasProp;
-var elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const hasTooltipParent_1 = require("../util/hasTooltipParent");
+const hasTextContentChild_1 = require("../util/hasTextContentChild");
+const labelUtils_1 = require("../util/labelUtils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
messages: {
missingAriaLabel: "Accessibility: the accordion header must have an accessible name"
@@ -19,10 +20,8 @@ module.exports = {
type: "problem", // `problem`, `suggestion`, or `layout`
docs: {
description: "The accordion header is a button and it needs an accessibile name e.g. text content, aria-label, aria-labelledby.",
- recommended: false,
- url: null // URL to the documentation page for this rule
+ recommended: false
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
// create (function) returns an object with methods that ESLint calls to “visit” nodes while traversing the abstract syntax tree
@@ -32,26 +31,27 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it is not a AccordionHeader, return
- if (elementType(openingElement) !== "AccordionHeader") {
+ if ((0, jsx_ast_utils_1.elementType)(openingElement) !== "AccordionHeader") {
return;
}
// if it has text content, return
- if (hasTextContentChild(node)) {
+ if ((0, hasTextContentChild_1.hasTextContentChild)(node)) {
return;
}
// if it is not an icon button, return
- if (!hasProp(openingElement.attributes, "icon") && !hasProp(openingElement.attributes, "expandIcon")) {
+ if (!(0, jsx_ast_utils_1.hasProp)(openingElement.attributes, "icon") &&
+ !(0, jsx_ast_utils_1.hasProp)(openingElement.attributes, "expandIcon")) {
return;
}
// if it has a tooltip parent, return
- if (hasToolTipParent(context)) {
+ if ((0, hasTooltipParent_1.hasToolTipParent)(context)) {
return;
}
// the button has an associated label
- if (hasAssociatedLabelViaAriaLabelledBy(openingElement, context)) {
+ if ((0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(openingElement, context)) {
return;
}
- const hasAccessibleLabelling = hasNonEmptyProp(openingElement.attributes, "title") || hasNonEmptyProp(openingElement.attributes, "aria-label");
+ const hasAccessibleLabelling = (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "title") || (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "aria-label");
// if it has no accessible name, report error
if (!hasAccessibleLabelling) {
context.report({
@@ -62,4 +62,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/accordion-item-needs-header-and-panel.d.ts b/dist/lib/rules/accordion-item-needs-header-and-panel.d.ts
index de4c0ec..34313bb 100644
--- a/dist/lib/rules/accordion-item-needs-header-and-panel.d.ts
+++ b/dist/lib/rules/accordion-item-needs-header-and-panel.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"accordionItemOneHeaderOnePanel", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/accordion-item-needs-header-and-panel.js b/dist/lib/rules/accordion-item-needs-header-and-panel.js
index 6dc0f8d..d25ab92 100644
--- a/dist/lib/rules/accordion-item-needs-header-and-panel.js
+++ b/dist/lib/rules/accordion-item-needs-header-and-panel.js
@@ -1,11 +1,13 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
messages: {
accordionItemOneHeaderOnePanel: "ensure AccordionItem has exactly one header and one panel"
@@ -13,21 +15,25 @@ module.exports = {
type: "problem", // `problem`, `suggestion`, or `layout`
docs: {
description: "An AccordionItem needs exactly one header and one panel",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/ARIA/apg/patterns/accordion/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
JSXOpeningElement(node) {
- if (node.name.name !== "AccordionItem") {
+ if (node.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier && node.name.name !== "AccordionItem") {
+ return;
+ }
+ if (!(node.parent && node.parent.type === utils_1.AST_NODE_TYPES.JSXElement)) {
return;
}
const children = node.parent.children.filter(child => child.type === "JSXElement");
- const hasOneHeader = children.filter(child => child.openingElement.name.name === "AccordionHeader").length === 1;
- const hasOnePanel = children.filter(child => child.openingElement.name.name === "AccordionPanel").length === 1;
+ const hasOneHeader = children.filter(child => child.openingElement.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "AccordionHeader").length === 1;
+ const hasOnePanel = children.filter(child => child.openingElement.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "AccordionPanel").length === 1;
if (!hasOneHeader || !hasOnePanel || children.length !== 2) {
context.report({
node,
@@ -37,4 +43,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/avatar-needs-name.d.ts b/dist/lib/rules/avatar-needs-name.d.ts
index 1bb0b91..3ac584a 100644
--- a/dist/lib/rules/avatar-needs-name.d.ts
+++ b/dist/lib/rules/avatar-needs-name.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let missingAriaLabel: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingAriaLabel", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/avatar-needs-name.js b/dist/lib/rules/avatar-needs-name.js
index fc133e3..79adb20 100644
--- a/dist/lib/rules/avatar-needs-name.js
+++ b/dist/lib/rules/avatar-needs-name.js
@@ -1,13 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const labelUtils_1 = require("../util/labelUtils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -19,7 +22,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: Avatar must have an accessible labelling: name, aria-label, aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -30,13 +33,13 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not an Avatar, return
- if (elementType(node) !== "Avatar") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Avatar") {
return;
}
// if the Avatar has a name, aria-label or aria-labelledby, return
- if (hasNonEmptyProp(node.attributes, "name") ||
- hasNonEmptyProp(node.attributes, "aria-label") ||
- hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "name") ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
// no aria
@@ -47,4 +50,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.d.ts b/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.d.ts
index de4c0ec..ae2e6fb 100644
--- a/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.d.ts
+++ b/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noAriaDescribedbyAsLabel", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js b/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js
index 702d7e5..be3887a 100644
--- a/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js
+++ b/dist/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js
@@ -1,19 +1,21 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { applicableComponents: inputComponents } = require("../applicableComponents/inputBasedComponents");
-const { applicableComponents: buttonComponents } = require("../applicableComponents/buttonBasedComponents");
-const { elementType } = require("jsx-ast-utils");
-const { isInsideLabelTag, hasAssociatedLabelViaHtmlFor, hasAssociatedLabelViaAriaLabelledBy, hasAssociatedLabelViaAriaDescribedby } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const inputBasedComponents_1 = require("../applicableComponents/inputBasedComponents");
+const buttonBasedComponents_1 = require("../applicableComponents/buttonBasedComponents");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const hasTooltipParent_1 = require("../util/hasTooltipParent");
+const hasTextContentChild_1 = require("../util/hasTextContentChild");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
messages: {
noAriaDescribedbyAsLabel: "Accessibility: aria-describedby provides additional context and is not meant for primary labeling."
@@ -21,35 +23,33 @@ module.exports = {
type: "suggestion", // `problem`, `suggestion`, or `layout`
docs: {
description: "aria-describedby provides additional context and is not meant for primary labeling.",
- recommended: true,
- url: null // URL to the documentation page for this rule
+ recommended: "strict"
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
JSXElement(node) {
const openingElement = node.openingElement;
- if (buttonComponents.includes(elementType(openingElement)) && // It's a button-based component
- !hasToolTipParent(context) && // It doesn't have a tooltip parent
- !hasTextContentChild(node) && // It doesn't have text content
- !hasNonEmptyProp(openingElement.attributes, "title") && // Doesn't have a title
- !hasNonEmptyProp(openingElement.attributes, "aria-label") && // Doesn't have an aria-label
- !hasAssociatedLabelViaAriaLabelledBy(openingElement, context) && // Doesn't have aria-labelledby
- hasAssociatedLabelViaAriaDescribedby(openingElement, context) // But it does have aria-describedby
+ if (buttonBasedComponents_1.applicableComponents.includes((0, jsx_ast_utils_1.elementType)(openingElement)) && // It's a button-based component
+ !(0, hasTooltipParent_1.hasToolTipParent)(context) && // It doesn't have a tooltip parent
+ !(0, hasTextContentChild_1.hasTextContentChild)(node) && // It doesn't have text content
+ !(0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "title") && // Doesn't have a title
+ !(0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "aria-label") && // Doesn't have an aria-label
+ !(0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(openingElement, context) && // Doesn't have aria-labelledby
+ (0, labelUtils_1.hasAssociatedLabelViaAriaDescribedby)(openingElement, context) // But it does have aria-describedby
) {
context.report({
node,
messageId: "noAriaDescribedbyAsLabel"
});
}
- if (inputComponents.includes(elementType(openingElement)) && // It's an input component
- !hasFieldParent(context) && // It doesn't have a field parent
- !isInsideLabelTag(context) && // It's not inside a label tag
- !hasAssociatedLabelViaHtmlFor(openingElement, context) && // Doesn't have a label via htmlFor
- !hasAssociatedLabelViaAriaLabelledBy(openingElement, context) && // Doesn't have aria-labelledby
- hasAssociatedLabelViaAriaDescribedby(openingElement, context) // But it does have aria-describedby
+ if (inputBasedComponents_1.applicableComponents.includes((0, jsx_ast_utils_1.elementType)(openingElement)) && // It's an input component
+ !(0, hasFieldParent_1.hasFieldParent)(context) && // It doesn't have a field parent
+ !(0, labelUtils_1.isInsideLabelTag)(context) && // It's not inside a label tag
+ !(0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(openingElement, context) && // Doesn't have a label via htmlFor
+ !(0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(openingElement, context) && // Doesn't have aria-labelledby
+ (0, labelUtils_1.hasAssociatedLabelViaAriaDescribedby)(openingElement, context) // But it does have aria-describedby
) {
context.report({
node,
@@ -59,4 +59,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/badge-needs-accessible-name.d.ts b/dist/lib/rules/badge-needs-accessible-name.d.ts
index de4c0ec..50c63b5 100644
--- a/dist/lib/rules/badge-needs-accessible-name.d.ts
+++ b/dist/lib/rules/badge-needs-accessible-name.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"badgeNeedsAccessibleName" | "colourOnlyBadgesNeedAttributes" | "badgeIconNeedsLabelling", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/badge-needs-accessible-name.js b/dist/lib/rules/badge-needs-accessible-name.js
index 06b1dad..4ab3b3e 100644
--- a/dist/lib/rules/badge-needs-accessible-name.js
+++ b/dist/lib/rules/badge-needs-accessible-name.js
@@ -1,15 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-var elementType = require("jsx-ast-utils").elementType;
-const { getPropValue, getProp } = require("jsx-ast-utils");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-var hasProp = require("jsx-ast-utils").hasProp;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const jsx_ast_utils_2 = require("jsx-ast-utils");
+const hasTextContentChild_1 = require("../util/hasTextContentChild");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -32,22 +33,22 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// If it's not a Badge component, return early
- if (elementType(openingElement) !== "Badge") {
+ if ((0, jsx_ast_utils_1.elementType)(openingElement) !== "Badge") {
return;
}
- const hasTextContent = hasTextContentChild(node);
+ const hasTextContent = (0, hasTextContentChild_1.hasTextContentChild)(node);
// Check if Badge has text content and return early if it does
if (hasTextContent) {
return;
}
// Check if Badge has an icon
- const hasIconProp = hasProp(openingElement.attributes, "icon");
+ const hasIconProp = (0, jsx_ast_utils_1.hasProp)(openingElement.attributes, "icon");
if (hasIconProp) {
- const iconProp = getProp(openingElement.attributes, "icon");
- if (iconProp) {
+ const iconProp = (0, jsx_ast_utils_2.getProp)(openingElement.attributes, "icon");
+ if (iconProp && iconProp.value && iconProp.value.type === utils_1.AST_NODE_TYPES.JSXExpressionContainer) {
const iconElement = iconProp.value.expression;
// Check if the icon has an aria-label
- const ariaLabelAttr = hasProp(iconElement.openingElement.attributes, "aria-label");
+ const ariaLabelAttr = (0, jsx_ast_utils_1.hasProp)(iconElement.openingElement.attributes, "aria-label");
// Report an error if aria-label is missing
if (!ariaLabelAttr) {
context.report({
@@ -62,9 +63,10 @@ module.exports = {
}
}
// Simplified logic to check for a color-only Badge (no icon, no text)
- const hasColorProp = hasProp(openingElement.attributes, "color");
- const hasRole = getPropValue(getProp(openingElement.attributes, "role")) === "img";
- const hasAriaLabel = hasProp(openingElement.attributes, "aria-label");
+ const roleProp = (0, jsx_ast_utils_2.getProp)(openingElement.attributes, "role");
+ const hasColorProp = (0, jsx_ast_utils_1.hasProp)(openingElement.attributes, "color");
+ const hasRole = !!roleProp && (0, jsx_ast_utils_2.getPropValue)(roleProp) === "img";
+ const hasAriaLabel = (0, jsx_ast_utils_1.hasProp)(openingElement.attributes, "aria-label");
// If it's color-only, ensure it has role="img" and aria-label
if (!hasIconProp && !(hasRole && hasAriaLabel)) {
if (hasColorProp) {
@@ -95,4 +97,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/breadcrumb-needs-labelling.d.ts b/dist/lib/rules/breadcrumb-needs-labelling.d.ts
index de4c0ec..9376036 100644
--- a/dist/lib/rules/breadcrumb-needs-labelling.d.ts
+++ b/dist/lib/rules/breadcrumb-needs-labelling.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledBreadcrumb", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/breadcrumb-needs-labelling.js b/dist/lib/rules/breadcrumb-needs-labelling.js
index d3b50aa..ae5333d 100644
--- a/dist/lib/rules/breadcrumb-needs-labelling.js
+++ b/dist/lib/rules/breadcrumb-needs-labelling.js
@@ -1,14 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const labelUtils_1 = require("../util/labelUtils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -21,7 +23,6 @@ module.exports = {
recommended: false,
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
@@ -29,12 +30,12 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Breadcrumb, return
- if (elementType(node) !== "Breadcrumb") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Breadcrumb") {
return;
}
// if the Breadcrumb has a label, if the Breadcrumb has an associated label, return
- if (hasNonEmptyProp(node.attributes, "aria-label") || //aria-label
- hasAssociatedLabelViaAriaLabelledBy(node, context) // aria-labelledby
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") || //aria-label
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context) // aria-labelledby
) {
return;
}
@@ -46,4 +47,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/buttons/compound-button-needs-labelling.d.ts b/dist/lib/rules/buttons/compound-button-needs-labelling.d.ts
index 3f05421..f2a0058 100644
--- a/dist/lib/rules/buttons/compound-button-needs-labelling.d.ts
+++ b/dist/lib/rules/buttons/compound-button-needs-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let missingAriaLabel: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingAriaLabel", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/buttons/compound-button-needs-labelling.js b/dist/lib/rules/buttons/compound-button-needs-labelling.js
index 1706449..7d83385 100644
--- a/dist/lib/rules/buttons/compound-button-needs-labelling.js
+++ b/dist/lib/rules/buttons/compound-button-needs-labelling.js
@@ -1,15 +1,18 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../../util/hasTooltipParent");
-const { hasTextContentChild } = require("../../util/hasTextContentChild");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../../util/labelUtils");
-var elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../../util/hasNonEmptyProp");
+const hasTooltipParent_1 = require("../../util/hasTooltipParent");
+const hasTextContentChild_1 = require("../../util/hasTextContentChild");
+const labelUtils_1 = require("../../util/labelUtils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -20,7 +23,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Compound buttons must have accessible labelling: title, aria-label, aria-labelledby, aria-describedby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -32,17 +35,17 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it is not a Compound button, return
- if (elementType(openingElement) !== "CompoundButton") {
+ if ((0, jsx_ast_utils_1.elementType)(openingElement) !== "CompoundButton") {
return;
}
// if it has a tooltip parent Or has text content Or has an associated label or has secondaryContent, return
- if (hasToolTipParent(context) ||
- hasTextContentChild(node) ||
- hasAssociatedLabelViaAriaLabelledBy(openingElement, context) ||
- hasNonEmptyProp(openingElement.attributes, "secondaryContent")) {
+ if ((0, hasTooltipParent_1.hasToolTipParent)(context) ||
+ (0, hasTextContentChild_1.hasTextContentChild)(node) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(openingElement, context) ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "secondaryContent")) {
return;
}
- const hasAccessibleLabelling = hasNonEmptyProp(openingElement.attributes, "title") || hasNonEmptyProp(openingElement.attributes, "aria-label");
+ const hasAccessibleLabelling = (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "title") || (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "aria-label");
// if it has no accessible name, report error
if (!hasAccessibleLabelling) {
context.report({
@@ -53,4 +56,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/buttons/image-button-missing-aria.d.ts b/dist/lib/rules/buttons/image-button-missing-aria.d.ts
index 3f05421..f2a0058 100644
--- a/dist/lib/rules/buttons/image-button-missing-aria.d.ts
+++ b/dist/lib/rules/buttons/image-button-missing-aria.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let missingAriaLabel: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingAriaLabel", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/buttons/image-button-missing-aria.js b/dist/lib/rules/buttons/image-button-missing-aria.js
index 4cfac1a..aa8ac6f 100644
--- a/dist/lib/rules/buttons/image-button-missing-aria.js
+++ b/dist/lib/rules/buttons/image-button-missing-aria.js
@@ -1,17 +1,19 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../../util/hasTooltipParent");
-const { hasTextContentChild } = require("../../util/hasTextContentChild");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../../util/labelUtils");
-const { applicableComponents } = require("../../applicableComponents/buttonBasedComponents");
-var hasProp = require("jsx-ast-utils").hasProp;
-var elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../../util/hasNonEmptyProp");
+const hasTooltipParent_1 = require("../../util/hasTooltipParent");
+const hasTextContentChild_1 = require("../../util/hasTextContentChild");
+const labelUtils_1 = require("../../util/labelUtils");
+const buttonBasedComponents_1 = require("../../applicableComponents/buttonBasedComponents");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -22,7 +24,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Image buttons must have accessible labelling: title, aria-label, aria-labelledby, aria-describedby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -34,26 +36,26 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it is not a button, return
- if (!applicableComponents.includes(elementType(openingElement))) {
+ if (!buttonBasedComponents_1.applicableComponents.includes((0, jsx_ast_utils_1.elementType)(openingElement))) {
return;
}
// if it is not an icon button, return
- if (!hasProp(openingElement.attributes, "icon")) {
+ if (!(0, jsx_ast_utils_1.hasProp)(openingElement.attributes, "icon")) {
return;
}
// if it has a tooltip parent, return
- if (hasToolTipParent(context)) {
+ if ((0, hasTooltipParent_1.hasToolTipParent)(context)) {
return;
}
// if it has text content, return
- if (hasTextContentChild(node)) {
+ if ((0, hasTextContentChild_1.hasTextContentChild)(node)) {
return;
}
// the button has an associated label
- if (hasAssociatedLabelViaAriaLabelledBy(openingElement, context)) {
+ if ((0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(openingElement, context)) {
return;
}
- const hasAccessibleLabelling = hasNonEmptyProp(openingElement.attributes, "title") || hasNonEmptyProp(openingElement.attributes, "aria-label");
+ const hasAccessibleLabelling = (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "title") || (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "aria-label");
// if it has no accessible name, report error
if (!hasAccessibleLabelling) {
context.report({
@@ -64,4 +66,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/buttons/no-empty-buttons.d.ts b/dist/lib/rules/buttons/no-empty-buttons.d.ts
index da25e0f..4765267 100644
--- a/dist/lib/rules/buttons/no-empty-buttons.d.ts
+++ b/dist/lib/rules/buttons/no-empty-buttons.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noEmptyButtons: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXElement(node: any): any;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noEmptyButtons", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/buttons/no-empty-buttons.js b/dist/lib/rules/buttons/no-empty-buttons.js
index 78b0856..265fd97 100644
--- a/dist/lib/rules/buttons/no-empty-buttons.js
+++ b/dist/lib/rules/buttons/no-empty-buttons.js
@@ -1,15 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasTextContentChild } = require("../../util/hasTextContentChild");
-const { hasNonEmptyProp } = require("../../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-var hasProp = require("jsx-ast-utils").hasProp;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasTextContentChild_1 = require("../../util/hasTextContentChild");
+const hasNonEmptyProp_1 = require("../../util/hasNonEmptyProp");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
const allowedComponents = ["Button", "ToggleButton", "SplitButton", "MenuButton", "CompoundButton"];
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the lint rule
messages: {
@@ -20,7 +22,7 @@ module.exports = {
// docs for the rule
docs: {
description: `Accessibility: ${allowedComponents.join(", ")} must either text content or icon or child component`,
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: [] // no options
@@ -32,18 +34,19 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it is not a button, return
- if (!allowedComponents.includes(elementType(openingElement))) {
+ if (!allowedComponents.includes((0, jsx_ast_utils_1.elementType)(openingElement))) {
return;
}
// if it has text content, return
- if (hasTextContentChild(node))
+ if ((0, hasTextContentChild_1.hasTextContentChild)(node))
return;
// if there is icon prop, return
- if (hasProp(openingElement.attributes, "icon")) {
+ if ((0, jsx_ast_utils_1.hasProp)(openingElement.attributes, "icon")) {
return;
}
// if split button has secondary content, return
- if (elementType(openingElement) === "CompoundButton" && hasNonEmptyProp(openingElement.attribute, "secondaryContent")) {
+ if ((0, jsx_ast_utils_1.elementType)(openingElement) === "CompoundButton" &&
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "secondaryContent")) {
return;
}
const hasChildren = node.children.length > 0;
@@ -57,4 +60,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/checkbox-needs-labelling.d.ts b/dist/lib/rules/checkbox-needs-labelling.d.ts
index 72b437b..55b9e4a 100644
--- a/dist/lib/rules/checkbox-needs-labelling.d.ts
+++ b/dist/lib/rules/checkbox-needs-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noUnlabelledCheckbox: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledCheckbox", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/checkbox-needs-labelling.js b/dist/lib/rules/checkbox-needs-labelling.js
index 24e84d4..11344b2 100644
--- a/dist/lib/rules/checkbox-needs-labelling.js
+++ b/dist/lib/rules/checkbox-needs-labelling.js
@@ -1,14 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -20,7 +23,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: Checkbox without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -31,15 +34,15 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Checkbox, return
- if (elementType(node) !== "Checkbox") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Checkbox") {
return;
}
// if the Checkbox has a label, if the Switch has an associated label, return
- if (hasNonEmptyProp(node.attributes, "label") ||
- hasFieldParent(context) ||
- isInsideLabelTag(context) ||
- hasAssociatedLabelViaHtmlFor(node, context) ||
- hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "label") ||
+ (0, hasFieldParent_1.hasFieldParent)(context) ||
+ (0, labelUtils_1.isInsideLabelTag)(context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
// if it has no visual labelling, report error
@@ -50,4 +53,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/combobox-needs-labelling.d.ts b/dist/lib/rules/combobox-needs-labelling.d.ts
index de4c0ec..d855084 100644
--- a/dist/lib/rules/combobox-needs-labelling.d.ts
+++ b/dist/lib/rules/combobox-needs-labelling.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledCombobox", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/combobox-needs-labelling.js b/dist/lib/rules/combobox-needs-labelling.js
index ebd4427..1124820 100644
--- a/dist/lib/rules/combobox-needs-labelling.js
+++ b/dist/lib/rules/combobox-needs-labelling.js
@@ -1,15 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -22,7 +24,6 @@ module.exports = {
recommended: false,
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
@@ -30,15 +31,15 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Combobox, return
- if (elementType(node) !== "Combobox") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Combobox") {
return;
}
// if the Combobox has a label, if the Combobox has an associated label, return
- if (hasFieldParent(context) ||
- hasNonEmptyProp(node.attributes, "aria-label") || //aria-label, not recommended but will work for screen reader users
- isInsideLabelTag(context) || // wrapped in label
- hasAssociatedLabelViaHtmlFor(node, context) || // label with htmlFor
- hasAssociatedLabelViaAriaLabelledBy(node, context) // aria-labelledby
+ if ((0, hasFieldParent_1.hasFieldParent)(context) ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") || //aria-label, not recommended but will work for screen reader users
+ (0, labelUtils_1.isInsideLabelTag)(context) || // wrapped in label
+ (0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) || // label with htmlFor
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context) // aria-labelledby
) {
return;
}
@@ -50,4 +51,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/dialogbody-needs-title-content-and-actions.d.ts b/dist/lib/rules/dialogbody-needs-title-content-and-actions.d.ts
index de4c0ec..717e62d 100644
--- a/dist/lib/rules/dialogbody-needs-title-content-and-actions.d.ts
+++ b/dist/lib/rules/dialogbody-needs-title-content-and-actions.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"dialogBodyOneTitleOneContentOneFooter", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/dialogbody-needs-title-content-and-actions.js b/dist/lib/rules/dialogbody-needs-title-content-and-actions.js
index ef3deb6..003bf2c 100644
--- a/dist/lib/rules/dialogbody-needs-title-content-and-actions.js
+++ b/dist/lib/rules/dialogbody-needs-title-content-and-actions.js
@@ -1,11 +1,13 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
messages: {
dialogBodyOneTitleOneContentOneFooter: "ensure DialogBody has exactly one header,one content and one footer"
@@ -13,29 +15,36 @@ module.exports = {
type: "problem", // `problem`, `suggestion`, or `layout`
docs: {
description: "A DialogBody should have a header(DialogTitle), content(DialogContent), and footer(DialogActions)",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
JSXOpeningElement(node) {
- if (node.name.name !== "DialogBody") {
+ if (node.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier && node.name.name !== "DialogBody") {
return;
}
- const children = node.parent.children.filter(child => child.type === "JSXElement");
- const hasOneTitle = children.filter(child => child.openingElement.name.name === "DialogTitle").length === 1;
- const hasOneContnet = children.filter(child => child.openingElement.name.name === "DialogContent").length === 1;
- const hasOneAction = children.filter(child => child.openingElement.name.name === "DialogActions").length === 1;
- if (!hasOneTitle || !hasOneContnet || !hasOneAction || children.length !== 3) {
- context.report({
- node,
- messageId: "dialogBodyOneTitleOneContentOneFooter"
- });
+ const children = node.parent &&
+ node.parent.type === utils_1.AST_NODE_TYPES.JSXElement &&
+ node.parent.children.filter(child => child.type === "JSXElement");
+ if (children) {
+ const hasOneTitle = children.filter(child => child.openingElement.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogTitle").length === 1;
+ const hasOneContnet = children.filter(child => child.openingElement.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogContent").length === 1;
+ const hasOneAction = children.filter(child => child.openingElement.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogActions").length === 1;
+ if (!hasOneTitle || !hasOneContnet || !hasOneAction || children.length !== 3) {
+ context.report({
+ node,
+ messageId: "dialogBodyOneTitleOneContentOneFooter"
+ });
+ }
}
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/dialogsurface-needs-aria.d.ts b/dist/lib/rules/dialogsurface-needs-aria.d.ts
index de4c0ec..651b4c5 100644
--- a/dist/lib/rules/dialogsurface-needs-aria.d.ts
+++ b/dist/lib/rules/dialogsurface-needs-aria.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingAriaOnDialogSurface", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/dialogsurface-needs-aria.js b/dist/lib/rules/dialogsurface-needs-aria.js
index 3889df6..156b980 100644
--- a/dist/lib/rules/dialogsurface-needs-aria.js
+++ b/dist/lib/rules/dialogsurface-needs-aria.js
@@ -1,15 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasAssociatedAriaText } = require("../util/labelUtils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-var elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const labelUtils_1 = require("../util/labelUtils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const hasTextContentChild_1 = require("../util/hasTextContentChild");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -20,7 +22,7 @@ module.exports = {
// docs for the rule
docs: {
description: "DialogueSurface need accessible labelling: aria-describedby on DialogueSurface and aria-label or aria-labelledby(if DialogueTitle is missing)",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" // URL to the documentation page for this rule
},
schema: []
@@ -30,30 +32,40 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a DialogSurface, return
- if (elementType(node) !== "DialogSurface") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "DialogSurface") {
return;
}
// determine if DialogSurface as aria-describedby
- const hasAriaDescribedBy = hasAssociatedAriaText(node, context, "aria-describedby");
+ const hasAriaDescribedBy = (0, labelUtils_1.hasAssociatedAriaText)(node, context, "aria-describedby");
// find DialogBody Component
- const dialogueSurfaceChildren = node.parent.children.filter(child => child.type === "JSXElement");
- const DialogBodyNode = dialogueSurfaceChildren.find(child => child.openingElement.name.name === "DialogBody");
- // find DialogTitle inside DialogBody Component
- const dialogueBodyChildren = DialogBodyNode && DialogBodyNode.children.filter(child => child.type === "JSXElement");
- const DialogTitleNode = dialogueBodyChildren && dialogueBodyChildren.find(child => child.openingElement.name.name === "DialogTitle");
- // determine if DialogueText has any text content
- const hasDialogTitleText = DialogTitleNode && hasTextContentChild(DialogTitleNode);
- // determine if DialogueText or aria-label is present
- const hasTitleOrAriaLabelledBy = hasDialogTitleText || hasNonEmptyProp(node.attributes, "aria-label") || hasAssociatedAriaText(node, context, "aria-labelledby");
- // if the DialogSurface has aria labelling and description, return
- if (hasAriaDescribedBy && hasTitleOrAriaLabelledBy) {
- return;
+ const dialogueSurfaceChildren = node.parent &&
+ node.parent.type === utils_1.AST_NODE_TYPES.JSXElement &&
+ node.parent.children.filter(child => child.type === "JSXElement");
+ if (dialogueSurfaceChildren) {
+ const DialogBodyNode = dialogueSurfaceChildren.find(child => child.openingElement.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogBody");
+ // find DialogTitle inside DialogBody Component
+ const dialogueBodyChildren = DialogBodyNode && DialogBodyNode.children.filter(child => child.type === "JSXElement");
+ const DialogTitleNode = dialogueBodyChildren &&
+ dialogueBodyChildren.find(child => child.openingElement.name.type === utils_1.AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogTitle");
+ // determine if DialogueText has any text content
+ const hasDialogTitleText = DialogTitleNode && (0, hasTextContentChild_1.hasTextContentChild)(DialogTitleNode);
+ // determine if DialogueText or aria-label is present
+ const hasTitleOrAriaLabelledBy = hasDialogTitleText ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") ||
+ (0, labelUtils_1.hasAssociatedAriaText)(node, context, "aria-labelledby");
+ // if the DialogSurface has aria labelling and description, return
+ if (hasAriaDescribedBy && hasTitleOrAriaLabelledBy) {
+ return;
+ }
+ context.report({
+ node,
+ messageId: `missingAriaOnDialogSurface`
+ });
}
- context.report({
- node,
- messageId: `missingAriaOnDialogSurface`
- });
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/dropdown-needs-labelling.d.ts b/dist/lib/rules/dropdown-needs-labelling.d.ts
index e1e9aaf..dbdb20e 100644
--- a/dist/lib/rules/dropdown-needs-labelling.d.ts
+++ b/dist/lib/rules/dropdown-needs-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let missingLabelOrAriaLabeledByInDropdown: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: null;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingLabelOrAriaLabeledByInDropdown", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/dropdown-needs-labelling.js b/dist/lib/rules/dropdown-needs-labelling.js
index d4b19f8..ccdf2e6 100644
--- a/dist/lib/rules/dropdown-needs-labelling.js
+++ b/dist/lib/rules/dropdown-needs-labelling.js
@@ -1,13 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, hasAssociatedLabelViaHtmlFor, isInsideLabelTag } = require("../util/labelUtils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const labelUtils_1 = require("../util/labelUtils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -18,8 +21,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Dropdown menu must have an id and it needs to be linked via htmlFor of a Label",
- recommended: true,
- url: null
+ recommended: "strict"
},
schema: []
},
@@ -29,17 +31,17 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Dropdown, return
- if (elementType(node) !== "Dropdown") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Dropdown") {
return;
}
// if the dropdown has a aria-LabeledBy with same value present in id of Label, return (Most recommended)
// if the dropdown has an id and a label with htmlFor with sanme value as id, return
// if the dropdown has an associated label, return
// if the dropdown is inside Label tag, return
- if (hasAssociatedLabelViaHtmlFor(node, context) ||
- hasAssociatedLabelViaAriaLabelledBy(node, context) ||
- hasNonEmptyProp(node.attributes, "aria-label") ||
- isInsideLabelTag(context)) {
+ if ((0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context) ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") ||
+ (0, labelUtils_1.isInsideLabelTag)(context)) {
return;
}
// if it has no visual labelling, report error
@@ -50,4 +52,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/input-components-require-accessible-name.d.ts b/dist/lib/rules/input-components-require-accessible-name.d.ts
index 27bb3d1..00b3681 100644
--- a/dist/lib/rules/input-components-require-accessible-name.d.ts
+++ b/dist/lib/rules/input-components-require-accessible-name.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let missingLabelOnInput: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingLabelOnInput", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/input-components-require-accessible-name.js b/dist/lib/rules/input-components-require-accessible-name.js
index a63ee2f..6aa199b 100644
--- a/dist/lib/rules/input-components-require-accessible-name.js
+++ b/dist/lib/rules/input-components-require-accessible-name.js
@@ -1,25 +1,28 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { elementType } = require("jsx-ast-utils");
-const { isInsideLabelTag, hasAssociatedLabelViaHtmlFor, hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
-const { applicableComponents } = require("../applicableComponents/inputBasedComponents");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
+const inputBasedComponents_1 = require("../applicableComponents/inputBasedComponents");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
- missingLabelOnInput: `Accessibility - input fields must have a aria label associated with it: ${applicableComponents.join(", ")}`
+ missingLabelOnInput: `Accessibility - input fields must have a aria label associated with it: ${inputBasedComponents_1.applicableComponents.join(", ")}`
},
// "problem" means the rule is identifying code that either will cause an error or may cause a confusing behavior: https://eslint.org/docs/latest/developer-guide/working-with-rules
type: "problem",
// docs for the rule
docs: {
description: "Accessibility: Input fields must have accessible labelling: aria-label, aria-labelledby or an associated label",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/tutorials/forms/labels/" // URL to the documentation page for this rule
},
schema: []
@@ -29,14 +32,14 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a listed component, return
- if (!applicableComponents.includes(elementType(node))) {
+ if (!inputBasedComponents_1.applicableComponents.includes((0, jsx_ast_utils_1.elementType)(node))) {
return;
}
// wrapped in Label tag, labelled with htmlFor, labelled with aria-labelledby
- if (hasFieldParent(context) ||
- isInsideLabelTag(context) ||
- hasAssociatedLabelViaHtmlFor(node, context) ||
- hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasFieldParent_1.hasFieldParent)(context) ||
+ (0, labelUtils_1.isInsideLabelTag)(context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
context.report({
@@ -46,4 +49,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/link-missing-labelling.d.ts b/dist/lib/rules/link-missing-labelling.d.ts
index de4c0ec..8c36a14 100644
--- a/dist/lib/rules/link-missing-labelling.d.ts
+++ b/dist/lib/rules/link-missing-labelling.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingAriaLabel" | "missingHref", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/link-missing-labelling.js b/dist/lib/rules/link-missing-labelling.js
index 5268a79..e4ebc47 100644
--- a/dist/lib/rules/link-missing-labelling.js
+++ b/dist/lib/rules/link-missing-labelling.js
@@ -1,22 +1,24 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { elementType } = require("jsx-ast-utils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-const { hasLabelledChildImage } = require("../util/hasLabelledChildImage");
-const { linkBasedComponents } = require("../applicableComponents/linkBasedComponents");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const hasTextContentChild_1 = require("../util/hasTextContentChild");
+const hasLabelledChildImage_1 = require("../util/hasLabelledChildImage");
+const linkBasedComponents_1 = require("../applicableComponents/linkBasedComponents");
+const labelUtils_1 = require("../util/labelUtils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
type: "problem",
docs: {
description: "Accessibility: Image links must have an accessible name. Add either text content, labelling to the image or labelling to the link itself.",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/standards-guidelines/act/rules/c487ae/" // URL to the documentation page for this rule
},
messages: {
@@ -36,10 +38,10 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it's not a link based component, return
- if (!linkBasedComponents.includes(elementType(openingElement))) {
+ if (!linkBasedComponents_1.linkBasedComponents.includes((0, jsx_ast_utils_1.elementType)(openingElement))) {
return;
}
- const hasHref = hasNonEmptyProp(openingElement.attributes, "href");
+ const hasHref = (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "href");
// check if the link has an href
if (!hasHref) {
context.report({
@@ -48,18 +50,18 @@ module.exports = {
});
}
// if it has text content, return
- if (hasTextContentChild(node)) {
+ if ((0, hasTextContentChild_1.hasTextContentChild)(node)) {
return;
}
// if there is a containing image and it is labelled correctly, return
- const hasAccessibleImage = hasLabelledChildImage(node);
+ const hasAccessibleImage = (0, hasLabelledChildImage_1.hasLabelledChildImage)(node);
if (hasAccessibleImage) {
return;
}
// Check if there is an accessible link
- const linkHasAccessibleLabel = hasNonEmptyProp(openingElement.attributes, "title") ||
- hasNonEmptyProp(openingElement.attributes, "aria-label") ||
- hasAssociatedLabelViaAriaLabelledBy(openingElement, context);
+ const linkHasAccessibleLabel = (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "title") ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "aria-label") ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(openingElement, context);
if (linkHasAccessibleLabel) {
return;
}
@@ -73,4 +75,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/menu-item-needs-labelling.d.ts b/dist/lib/rules/menu-item-needs-labelling.d.ts
index de4c0ec..b830d80 100644
--- a/dist/lib/rules/menu-item-needs-labelling.d.ts
+++ b/dist/lib/rules/menu-item-needs-labelling.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledMenuItem", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/menu-item-needs-labelling.js b/dist/lib/rules/menu-item-needs-labelling.js
index 3e2e296..6b19020 100644
--- a/dist/lib/rules/menu-item-needs-labelling.js
+++ b/dist/lib/rules/menu-item-needs-labelling.js
@@ -1,16 +1,18 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const labelUtils_1 = require("../util/labelUtils");
+const hasTextContentChild_1 = require("../util/hasTextContentChild");
+const hasTooltipParent_1 = require("../util/hasTooltipParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -20,10 +22,9 @@ module.exports = {
type: "problem",
docs: {
description: "Accessibility: MenuItem without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
@@ -32,14 +33,14 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it is not a MenuItem, return
- if (elementType(openingElement) !== "MenuItem") {
+ if ((0, jsx_ast_utils_1.elementType)(openingElement) !== "MenuItem") {
return;
}
// if the MenuItem has a text, label or an associated label, return
- if (hasNonEmptyProp(openingElement.attributes, "aria-label") || //aria-label, not recommended but will work for screen reader users
- hasAssociatedLabelViaAriaLabelledBy(openingElement, context) || // aria-labelledby
- hasTextContentChild(node) || // has text content
- hasToolTipParent(context) // has tooltip parent, not recommended but will work for screen reader users
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(openingElement.attributes, "aria-label") || //aria-label, not recommended but will work for screen reader users
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(openingElement, context) || // aria-labelledby
+ (0, hasTextContentChild_1.hasTextContentChild)(node) || // has text content
+ (0, hasTooltipParent_1.hasToolTipParent)(context) // has tooltip parent, not recommended but will work for screen reader users
) {
return;
}
@@ -51,4 +52,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/no-empty-components.d.ts b/dist/lib/rules/no-empty-components.d.ts
index de4c0ec..5ebe065 100644
--- a/dist/lib/rules/no-empty-components.d.ts
+++ b/dist/lib/rules/no-empty-components.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noEmptyComponents", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/no-empty-components.js b/dist/lib/rules/no-empty-components.js
index daae293..0528eaa 100644
--- a/dist/lib/rules/no-empty-components.js
+++ b/dist/lib/rules/no-empty-components.js
@@ -1,14 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-var elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
// Define an array of allowed component names
const allowedComponents = ["Text", "Label", "Combobox", "Breadcrumb", "Dropdown", "Accordion", "AccordionItem", "AccordionPanel"];
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the lint rule
messages: {
@@ -17,10 +19,8 @@ module.exports = {
type: "problem", // `problem`, `suggestion`, or `layout`
docs: {
description: "FluentUI components should not be empty",
- recommended: true,
- url: null // URL to the documentation page for this rule
+ recommended: "strict"
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
// create (function) returns an object with methods that ESLint calls to “visit” nodes while traversing the abstract syntax tree
@@ -30,7 +30,7 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it is not a listed component, return
- if (!allowedComponents.includes(elementType(openingElement))) {
+ if (!allowedComponents.includes((0, jsx_ast_utils_1.elementType)(openingElement))) {
return;
}
const hasChildren = node.children.length > 0;
@@ -44,4 +44,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/progressbar-needs-labelling.d.ts b/dist/lib/rules/progressbar-needs-labelling.d.ts
index 180690f..85b4d29 100644
--- a/dist/lib/rules/progressbar-needs-labelling.d.ts
+++ b/dist/lib/rules/progressbar-needs-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noUnlabelledProgressbar: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledProgressbar", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/progressbar-needs-labelling.js b/dist/lib/rules/progressbar-needs-labelling.js
index 33edfbf..1b79719 100644
--- a/dist/lib/rules/progressbar-needs-labelling.js
+++ b/dist/lib/rules/progressbar-needs-labelling.js
@@ -1,13 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasFieldParent } = require("../util/hasFieldParent");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -18,7 +21,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Progressbar must have aria-valuemin, aria-valuemax, aria-valuenow, aria-describedby and either aria-label or aria-labelledby attributes",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -29,24 +32,24 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a ProgressBar, return
- if (elementType(node) !== "ProgressBar") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "ProgressBar") {
return;
}
// check if the ProgressBar has a Field parent
- const hasFieldParentCheck = hasFieldParent(context);
+ const hasFieldParentCheck = (0, hasFieldParent_1.hasFieldParent)(context);
// If no Field parent, ensure one of the aria-label or aria-labelledby is provided as well as aria-describedby
- const hasLabelling = (hasNonEmptyProp(node.attributes, "aria-label") || hasNonEmptyProp(node.attributes, "aria-labelledby")) &&
- hasNonEmptyProp(node.attributes, "aria-describedby");
+ const hasLabelling = ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") || (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-labelledby")) &&
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-describedby");
const mandatoryAttributes = [];
// Check if max is provided, if not, require aria-valuemax
- const hasMaxProp = hasNonEmptyProp(node.attributes, "max");
+ const hasMaxProp = (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "max");
if (!hasMaxProp) {
mandatoryAttributes.push("aria-valuemax");
mandatoryAttributes.push("aria-valuemin");
mandatoryAttributes.push("aria-valuenow");
}
// If all mandatory attributes (including optional aria-valuemax) are present, return
- if (mandatoryAttributes.every(attribute => hasNonEmptyProp(node.attributes, attribute)) &&
+ if (mandatoryAttributes.every(attribute => (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, attribute)) &&
(hasFieldParentCheck || hasLabelling)) {
return;
}
@@ -58,4 +61,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/radio-button-missing-label.d.ts b/dist/lib/rules/radio-button-missing-label.d.ts
index 7465799..23ca7db 100644
--- a/dist/lib/rules/radio-button-missing-label.d.ts
+++ b/dist/lib/rules/radio-button-missing-label.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noUnlabeledRadioButton: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabeledRadioButton", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/radio-button-missing-label.js b/dist/lib/rules/radio-button-missing-label.js
index 0335354..e6812ac 100644
--- a/dist/lib/rules/radio-button-missing-label.js
+++ b/dist/lib/rules/radio-button-missing-label.js
@@ -1,14 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -20,7 +23,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: Radio button without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -31,16 +34,16 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Checkbox, return
- if (elementType(node) !== "Radio") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Radio") {
return;
}
// if the Checkbox has a label, if the Switch has an associated label, return
- if (hasFieldParent(context) ||
- hasNonEmptyProp(node.attributes, "label") ||
- hasNonEmptyProp(node.attributes, "aria-label") ||
- isInsideLabelTag(context) ||
- hasAssociatedLabelViaHtmlFor(node, context) ||
- hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasFieldParent_1.hasFieldParent)(context) ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "label") ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") ||
+ (0, labelUtils_1.isInsideLabelTag)(context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
// if it has no visual labelling, report error
@@ -51,4 +54,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/radiogroup-missing-label.d.ts b/dist/lib/rules/radiogroup-missing-label.d.ts
index aab1b22..ba22572 100644
--- a/dist/lib/rules/radiogroup-missing-label.d.ts
+++ b/dist/lib/rules/radiogroup-missing-label.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noUnlabeledRadioGroup: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabeledRadioGroup", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/radiogroup-missing-label.js b/dist/lib/rules/radiogroup-missing-label.js
index 98b15b6..817099d 100644
--- a/dist/lib/rules/radiogroup-missing-label.js
+++ b/dist/lib/rules/radiogroup-missing-label.js
@@ -1,14 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -20,7 +23,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: RadioGroup without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -31,16 +34,16 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Checkbox, return
- if (elementType(node) !== "RadioGroup") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "RadioGroup") {
return;
}
// if the Checkbox has a label, if the Switch has an associated label, return
- if (hasFieldParent(context) ||
- hasNonEmptyProp(node.attributes, "label") ||
- hasNonEmptyProp(node.attributes, "aria-label") ||
- isInsideLabelTag(context) ||
- hasAssociatedLabelViaHtmlFor(node, context) ||
- hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasFieldParent_1.hasFieldParent)(context) ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "label") ||
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") ||
+ (0, labelUtils_1.isInsideLabelTag)(context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
// if it has no visual labelling, report error
@@ -51,4 +54,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/spin-button-needs-labelling.d.ts b/dist/lib/rules/spin-button-needs-labelling.d.ts
index c49d72a..df462b9 100644
--- a/dist/lib/rules/spin-button-needs-labelling.d.ts
+++ b/dist/lib/rules/spin-button-needs-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noUnlabelledSpinButton: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledSpinButton", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/spin-button-needs-labelling.js b/dist/lib/rules/spin-button-needs-labelling.js
index 27ccbbe..eec2150 100644
--- a/dist/lib/rules/spin-button-needs-labelling.js
+++ b/dist/lib/rules/spin-button-needs-labelling.js
@@ -1,13 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -18,7 +21,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: SpinButtons must have an accessible label",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -29,14 +32,14 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a SpinButton, return
- if (elementType(node) !== "SpinButton") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "SpinButton") {
return;
}
// if the SpinButton has an associated label, return
- if (hasFieldParent(context) ||
- isInsideLabelTag(context) ||
- hasAssociatedLabelViaHtmlFor(node, context) ||
- hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasFieldParent_1.hasFieldParent)(context) ||
+ (0, labelUtils_1.isInsideLabelTag)(context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
// if it has no visual labelling, report error
@@ -47,4 +50,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/spin-button-unrecommended-labelling.d.ts b/dist/lib/rules/spin-button-unrecommended-labelling.d.ts
index 7fcb4f0..5de3d41 100644
--- a/dist/lib/rules/spin-button-unrecommended-labelling.d.ts
+++ b/dist/lib/rules/spin-button-unrecommended-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let unRecommendedlabellingSpinButton: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"unRecommendedlabellingSpinButton", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/spin-button-unrecommended-labelling.js b/dist/lib/rules/spin-button-unrecommended-labelling.js
index 9dae79e..01cd595 100644
--- a/dist/lib/rules/spin-button-unrecommended-labelling.js
+++ b/dist/lib/rules/spin-button-unrecommended-labelling.js
@@ -1,13 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
-var elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const hasTooltipParent_1 = require("../util/hasTooltipParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible suggestion messages for the rule
messages: {
@@ -18,7 +21,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Unrecommended accessibility labelling - SpinButton",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -29,11 +32,11 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a SpinButton, return
- if (elementType(node) !== "SpinButton") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "SpinButton") {
return;
}
// if the SpinButton has an aria-label or is wrapped in a Tooltip, show warning
- if (hasNonEmptyProp(node.attributes, "aria-label") || hasToolTipParent(context)) {
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") || (0, hasTooltipParent_1.hasToolTipParent)(context)) {
context.report({
node,
messageId: `unRecommendedlabellingSpinButton`
@@ -42,4 +45,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/spinner-needs-labelling.d.ts b/dist/lib/rules/spinner-needs-labelling.d.ts
index 30b60ae..bc40b13 100644
--- a/dist/lib/rules/spinner-needs-labelling.d.ts
+++ b/dist/lib/rules/spinner-needs-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noUnlabelledSpinner: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledSpinner", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/spinner-needs-labelling.js b/dist/lib/rules/spinner-needs-labelling.js
index c4f8aa5..bc0b298 100644
--- a/dist/lib/rules/spinner-needs-labelling.js
+++ b/dist/lib/rules/spinner-needs-labelling.js
@@ -1,12 +1,15 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -17,7 +20,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Spinner must have either aria-label or label, aria-live and aria-busy attributes",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -28,12 +31,12 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Spinner, return
- if (elementType(node) !== "Spinner") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Spinner") {
return;
}
- if (hasNonEmptyProp(node.attributes, "aria-busy")
- && hasNonEmptyProp(node.attributes, "aria-live")
- && (hasNonEmptyProp(node.attributes, "label") || hasNonEmptyProp(node.attributes, "aria-label"))) {
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-busy") &&
+ (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-live") &&
+ ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "label") || (0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label"))) {
return;
}
// if it has no visual labelling, report error
@@ -44,4 +47,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/switch-needs-labelling.d.ts b/dist/lib/rules/switch-needs-labelling.d.ts
index 8e61b45..9a4895d 100644
--- a/dist/lib/rules/switch-needs-labelling.d.ts
+++ b/dist/lib/rules/switch-needs-labelling.d.ts
@@ -1,15 +1,5 @@
-export namespace meta {
- namespace messages {
- let noUnlabelledSwitch: string;
- }
- let type: string;
- namespace docs {
- let description: string;
- let recommended: boolean;
- let url: string;
- }
- let schema: never[];
-}
-export function create(context: any): {
- JSXOpeningElement(node: any): void;
-};
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"noUnlabelledSwitch", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/switch-needs-labelling.js b/dist/lib/rules/switch-needs-labelling.js
index 6013633..3f357b6 100644
--- a/dist/lib/rules/switch-needs-labelling.js
+++ b/dist/lib/rules/switch-needs-labelling.js
@@ -1,14 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
+const labelUtils_1 = require("../util/labelUtils");
+const hasFieldParent_1 = require("../util/hasFieldParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -19,7 +22,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Switch must have an accessible label",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -30,15 +33,15 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Switch, return
- if (elementType(node) !== "Switch") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Switch") {
return;
}
// if the Switch has a label, if the Switch has an associated label, return
- if (hasNonEmptyProp(node.attributes, "label") ||
- hasFieldParent(context) ||
- isInsideLabelTag(context) ||
- hasAssociatedLabelViaHtmlFor(node, context) ||
- hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "label") ||
+ (0, hasFieldParent_1.hasFieldParent)(context) ||
+ (0, labelUtils_1.isInsideLabelTag)(context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaHtmlFor)(node, context) ||
+ (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
// if it has no visual labelling, report error
@@ -49,4 +52,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/toolbar-missing-aria.d.ts b/dist/lib/rules/toolbar-missing-aria.d.ts
index de4c0ec..1af37a3 100644
--- a/dist/lib/rules/toolbar-missing-aria.d.ts
+++ b/dist/lib/rules/toolbar-missing-aria.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from "@typescript-eslint/utils";
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingLabelOnToolbar", [], {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/toolbar-missing-aria.js b/dist/lib/rules/toolbar-missing-aria.js
index 926fb8f..239fffd 100644
--- a/dist/lib/rules/toolbar-missing-aria.js
+++ b/dist/lib/rules/toolbar-missing-aria.js
@@ -1,14 +1,16 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const labelUtils_1 = require("../util/labelUtils");
+const hasNonEmptyProp_1 = require("../util/hasNonEmptyProp");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -19,7 +21,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Toolbars need accessible labelling: aria-label or aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/tutorials/forms/labels/" // URL to the documentation page for this rule
},
schema: []
@@ -29,11 +31,11 @@ module.exports = {
// visitor functions for different types of nodes
JSXOpeningElement(node) {
// if it is not a Toolbar, return
- if (elementType(node) !== "Toolbar") {
+ if ((0, jsx_ast_utils_1.elementType)(node) !== "Toolbar") {
return;
}
// if the Toolbar has aria labelling, return
- if (hasNonEmptyProp(node.attributes, "aria-label") || hasAssociatedLabelViaAriaLabelledBy(node, context)) {
+ if ((0, hasNonEmptyProp_1.hasNonEmptyProp)(node.attributes, "aria-label") || (0, labelUtils_1.hasAssociatedLabelViaAriaLabelledBy)(node, context)) {
return;
}
context.report({
@@ -43,4 +45,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/rules/tooltip-not-recommended.d.ts b/dist/lib/rules/tooltip-not-recommended.d.ts
index de4c0ec..c0f910b 100644
--- a/dist/lib/rules/tooltip-not-recommended.d.ts
+++ b/dist/lib/rules/tooltip-not-recommended.d.ts
@@ -1,2 +1,5 @@
-declare const _exports: import("eslint").Rule.RuleModule;
-export = _exports;
+import { TSESTree } from '@typescript-eslint/utils';
+declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"tooltipNotRecommended", [], {
+ JSXElement(node: TSESTree.JSXElement): void;
+}>;
+export default rule;
diff --git a/dist/lib/rules/tooltip-not-recommended.js b/dist/lib/rules/tooltip-not-recommended.js
index 55f893e..b8b545a 100644
--- a/dist/lib/rules/tooltip-not-recommended.js
+++ b/dist/lib/rules/tooltip-not-recommended.js
@@ -1,15 +1,17 @@
+"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-var elementType = require("jsx-ast-utils").elementType;
-const { hasToolTipParent } = require("../util/hasTooltipParent");
+Object.defineProperty(exports, "__esModule", { value: true });
+const utils_1 = require("@typescript-eslint/utils");
+const jsx_ast_utils_1 = require("jsx-ast-utils");
+const hasTooltipParent_1 = require("../util/hasTooltipParent");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
// Define an array of allowed component names
const allowedComponents = ["MenuItem", "SpinButton"];
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = utils_1.ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the lint rule
messages: {
@@ -18,10 +20,8 @@ module.exports = {
type: "suggestion", // `problem`, `suggestion`, or `layout`
docs: {
description: `Accessibility: Prefer text content or aria over a tooltip for these components ${allowedComponents.join(", ")}`,
- recommended: true,
- url: null // URL to the documentation page for this rule
+ recommended: 'strict',
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
// create (function) returns an object with methods that ESLint calls to “visit” nodes while traversing the abstract syntax tree
@@ -31,11 +31,11 @@ module.exports = {
JSXElement(node) {
const openingElement = node.openingElement;
// if it is not a listed component, return
- if (!allowedComponents.includes(elementType(openingElement))) {
+ if (!allowedComponents.includes((0, jsx_ast_utils_1.elementType)(openingElement))) {
return;
}
// if there are is tooltip, report
- if (hasToolTipParent(context)) {
+ if ((0, hasTooltipParent_1.hasToolTipParent)(context)) {
context.report({
node,
messageId: `tooltipNotRecommended`
@@ -44,4 +44,5 @@ module.exports = {
}
};
}
-};
+});
+exports.default = rule;
diff --git a/dist/lib/util/hasLabelledChildImage.js b/dist/lib/util/hasLabelledChildImage.js
index 3449825..2970c63 100644
--- a/dist/lib/util/hasLabelledChildImage.js
+++ b/dist/lib/util/hasLabelledChildImage.js
@@ -18,9 +18,7 @@ function hasLabelledChildImage(node) {
}
// Check if there is an accessible image
const hasAccessibleImage = flattenChildren(node).some(child => {
- console.log("mergedImageComponents.includes(child.openingElement.name.name)::: ", mergedImageComponents.includes(child.openingElement.name.name));
if (child.type === "JSXElement" && mergedImageComponents.includes(child.openingElement.name.name)) {
- console.log("here 3");
return hasProp(child.openingElement.attributes, "aria-hidden") || getPropValue(child.openingElement.attributes, "alt")
? false
: hasNonEmptyProp(child.openingElement.attributes, "title") ||
diff --git a/lib/index.ts b/lib/index.ts
index 6266604..3fcff30 100644
--- a/lib/index.ts
+++ b/lib/index.ts
@@ -3,6 +3,32 @@
console.log("Loading my-eslint-plugin");
import preferAriaOverTitleAttribute from "./rules/prefer-aria-over-title-attribute";
+import checkboxNeedsLabelling from "./rules/checkbox-needs-labelling";
+import imageButtonMissingAria from "./rules/buttons/image-button-missing-aria";
+import linkMissingLabelling from "./rules/link-missing-labelling";
+import inputComponentsRequireAccessibleName from "./rules/input-components-require-accessible-name";
+import menuItemNeedsLabelling from "./rules/menu-item-needs-labelling";
+import switchNeedsLabelling from "./rules/switch-needs-labelling";
+import toolbarMissingAria from "./rules/toolbar-missing-aria";
+import comboboxNeedsLabelling from "./rules/combobox-needs-labelling";
+import noEmptyComponents from "./rules/no-empty-components";
+import accordionHeaderNeedsLabelling from "./rules/accordion-header-needs-labelling";
+import accordionItemNeedsHeaderAndPanel from "./rules/accordion-item-needs-header-and-panel";
+import compoundButtonNeedsLabelling from "./rules/buttons/compound-button-needs-labelling";
+import noEmptyButtons from "./rules/buttons/no-empty-buttons";
+import spinButtonNeedsLabelling from "./rules/spin-button-needs-labelling";
+import spinButtonUnrecommendedLabelling from "./rules/spin-button-unrecommended-labelling";
+import breadcrumbNeedsLabelling from "./rules/breadcrumb-needs-labelling";
+import dropwdonNeedsLabelling from "./rules/dropdown-needs-labelling";
+import tooltipNotRecommended from "./rules/tooltip-not-recommended";
+import avatarNeedsName from "./rules/avatar-needs-name";
+import radioButtonMissingLabel from "./rules/radio-button-missing-label";
+import radiogroupMissingLabel from "./rules/radiogroup-missing-label";
+import dialogbodyNeedsTitleContentAndActions from "./rules/dialogbody-needs-title-content-and-actions";
+import dialogsurfaceNeedsAria from "./rules/dialogsurface-needs-aria";
+import spinnerNeedsLabelling from "./rules/spinner-needs-labelling";
+import badgeNeedsAccessibleName from "./rules/badge-needs-accessible-name";
+import progressbarNeedsLabelling from "./rules/progressbar-needs-labelling";
import fieldNeedsLabelling from "./rules/field-needs-labelling";
//------------------------------------------------------------------------------
// Requirements
@@ -15,33 +41,33 @@ import fieldNeedsLabelling from "./rules/field-needs-labelling";
// import all rules in lib/rules
module.exports = {
rules: {
- "checkbox-needs-labelling": require("./rules/checkbox-needs-labelling"),
- "image-button-missing-aria": require("./rules/buttons/image-button-missing-aria"),
- "link-missing-labelling": require("./rules/link-missing-labelling"),
- "input-components-require-accessible-name": require("./rules/input-components-require-accessible-name"),
- "menu-item-needs-labelling": require("./rules/menu-item-needs-labelling"),
- "switch-needs-labelling": require("./rules/switch-needs-labelling"),
- "toolbar-missing-aria": require("./rules/toolbar-missing-aria"),
- "combobox-needs-labelling": require("./rules/combobox-needs-labelling"),
- "no-empty-components": require("./rules/no-empty-components"),
- "accordion-header-needs-labelling": require("./rules/accordion-header-needs-labelling"),
- "accordion-item-needs-header-and-panel": require("./rules/accordion-item-needs-header-and-panel"),
- "compound-button-needs-labelling": require("./rules/buttons/compound-button-needs-labelling"),
- "no-empty-buttons": require("./rules/buttons/no-empty-buttons"),
- "spin-button-needs-labelling": require("./rules/spin-button-needs-labelling"),
- "spin-button-unrecommended-labelling": require("./rules/spin-button-unrecommended-labelling"),
- "breadcrumb-needs-labelling": require("./rules/breadcrumb-needs-labelling"),
- "dropdown-needs-labelling": require("./rules/dropdown-needs-labelling"),
- "tooltip-not-recommended": require("./rules/tooltip-not-recommended"),
- "avatar-needs-name": require("./rules/avatar-needs-name"),
- "radio-button-missing-label": require("./rules/radio-button-missing-label"),
- "radiogroup-missing-label": require("./rules/radiogroup-missing-label"),
+ "checkbox-needs-labelling": checkboxNeedsLabelling,
+ "image-button-missing-aria": imageButtonMissingAria,
+ "link-missing-labelling": linkMissingLabelling,
+ "input-components-require-accessible-name": inputComponentsRequireAccessibleName,
+ "menu-item-needs-labelling": menuItemNeedsLabelling,
+ "switch-needs-labelling": switchNeedsLabelling,
+ "toolbar-missing-aria": toolbarMissingAria,
+ "combobox-needs-labelling": comboboxNeedsLabelling,
+ "no-empty-components": noEmptyComponents,
+ "accordion-header-needs-labelling": accordionHeaderNeedsLabelling,
+ "accordion-item-needs-header-and-panel": accordionItemNeedsHeaderAndPanel,
+ "compound-button-needs-labelling": compoundButtonNeedsLabelling,
+ "no-empty-buttons": noEmptyButtons,
+ "spin-button-needs-labelling": spinButtonNeedsLabelling,
+ "spin-button-unrecommended-labelling": spinButtonUnrecommendedLabelling,
+ "breadcrumb-needs-labelling": breadcrumbNeedsLabelling,
+ "dropdown-needs-labelling": dropwdonNeedsLabelling,
+ "tooltip-not-recommended": tooltipNotRecommended,
+ "avatar-needs-name": avatarNeedsName,
+ "radio-button-missing-label": radioButtonMissingLabel,
+ "radiogroup-missing-label": radiogroupMissingLabel,
"prefer-aria-over-title-attribute": preferAriaOverTitleAttribute,
- "dialogbody-needs-title-content-and-actions": require("./rules/dialogbody-needs-title-content-and-actions"),
- "dialogsurface-needs-aria": require("./rules/dialogsurface-needs-aria"),
- "spinner-needs-labelling": require("./rules/spinner-needs-labelling"),
- "badge-needs-accessible-name": require("./rules/badge-needs-accessible-name"),
- "progressbar-needs-labelling": require("./rules/progressbar-needs-labelling"),
+ "dialogbody-needs-title-content-and-actions": dialogbodyNeedsTitleContentAndActions,
+ "dialogsurface-needs-aria": dialogsurfaceNeedsAria,
+ "spinner-needs-labelling": spinnerNeedsLabelling,
+ "badge-needs-accessible-name": badgeNeedsAccessibleName,
+ "progressbar-needs-labelling": progressbarNeedsLabelling,
"field-needs-labelling": fieldNeedsLabelling
},
configs: {
diff --git a/lib/rules/accordion-header-needs-labelling.js b/lib/rules/accordion-header-needs-labelling.ts
similarity index 70%
rename from lib/rules/accordion-header-needs-labelling.js
rename to lib/rules/accordion-header-needs-labelling.ts
index b5b4974..943308b 100644
--- a/lib/rules/accordion-header-needs-labelling.js
+++ b/lib/rules/accordion-header-needs-labelling.ts
@@ -1,21 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-var hasProp = require("jsx-ast-utils").hasProp;
-var elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType, hasProp } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasToolTipParent } from "../util/hasTooltipParent";
+import { hasTextContentChild } from "../util/hasTextContentChild";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../util/labelUtils";
+import { JSXAttribute, JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
messages: {
missingAriaLabel: "Accessibility: the accordion header must have an accessible name"
@@ -24,21 +23,19 @@ module.exports = {
docs: {
description:
"The accordion header is a button and it needs an accessibile name e.g. text content, aria-label, aria-labelledby.",
- recommended: false,
- url: null // URL to the documentation page for this rule
+ recommended: false
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
// create (function) returns an object with methods that ESLint calls to “visit” nodes while traversing the abstract syntax tree
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it is not a AccordionHeader, return
- if (elementType(openingElement) !== "AccordionHeader") {
+ if (elementType(openingElement as JSXOpeningElement) !== "AccordionHeader") {
return;
}
@@ -48,7 +45,10 @@ module.exports = {
}
// if it is not an icon button, return
- if (!hasProp(openingElement.attributes, "icon") && !hasProp(openingElement.attributes, "expandIcon")) {
+ if (
+ !hasProp(openingElement.attributes as JSXAttribute[], "icon") &&
+ !hasProp(openingElement.attributes as JSXAttribute[], "expandIcon")
+ ) {
return;
}
@@ -75,4 +75,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/accordion-item-needs-header-and-panel.js b/lib/rules/accordion-item-needs-header-and-panel.ts
similarity index 51%
rename from lib/rules/accordion-item-needs-header-and-panel.js
rename to lib/rules/accordion-item-needs-header-and-panel.ts
index b3e62c0..97611cf 100644
--- a/lib/rules/accordion-item-needs-header-and-panel.js
+++ b/lib/rules/accordion-item-needs-header-and-panel.ts
@@ -1,14 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
+import { AST_NODE_TYPES, ESLintUtils, TSESTree } from "@typescript-eslint/utils";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
messages: {
accordionItemOneHeaderOnePanel: "ensure AccordionItem has exactly one header and one panel"
@@ -16,25 +16,38 @@ module.exports = {
type: "problem", // `problem`, `suggestion`, or `layout`
docs: {
description: "An AccordionItem needs exactly one header and one panel",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/ARIA/apg/patterns/accordion/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
- JSXOpeningElement(node) {
- if (node.name.name !== "AccordionItem") {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
+ if (node.name.type === AST_NODE_TYPES.JSXIdentifier && node.name.name !== "AccordionItem") {
+ return;
+ }
+
+ if (!(node.parent && node.parent.type === AST_NODE_TYPES.JSXElement)) {
return;
}
const children = node.parent.children.filter(child => child.type === "JSXElement");
- const hasOneHeader = children.filter(child => child.openingElement.name.name === "AccordionHeader").length === 1;
+ const hasOneHeader =
+ children.filter(
+ child =>
+ child.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "AccordionHeader"
+ ).length === 1;
- const hasOnePanel = children.filter(child => child.openingElement.name.name === "AccordionPanel").length === 1;
+ const hasOnePanel =
+ children.filter(
+ child =>
+ child.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "AccordionPanel"
+ ).length === 1;
if (!hasOneHeader || !hasOnePanel || children.length !== 2) {
context.report({
@@ -45,5 +58,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/avatar-needs-name.js b/lib/rules/avatar-needs-name.ts
similarity index 76%
rename from lib/rules/avatar-needs-name.js
rename to lib/rules/avatar-needs-name.ts
index 4578b03..5db732e 100644
--- a/lib/rules/avatar-needs-name.js
+++ b/lib/rules/avatar-needs-name.ts
@@ -1,17 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { JSXOpeningElement } from "estree-jsx";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../util/labelUtils";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -23,7 +24,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: Avatar must have an accessible labelling: name, aria-label, aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -32,9 +33,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not an Avatar, return
- if (elementType(node) !== "Avatar") {
+ if (elementType(node as JSXOpeningElement) !== "Avatar") {
return;
}
@@ -55,4 +56,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js b/lib/rules/avoid-using-aria-describedby-for-primary-labelling.ts
similarity index 73%
rename from lib/rules/avoid-using-aria-describedby-for-primary-labelling.js
rename to lib/rules/avoid-using-aria-describedby-for-primary-labelling.ts
index 8878738..431e594 100644
--- a/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js
+++ b/lib/rules/avoid-using-aria-describedby-for-primary-labelling.ts
@@ -1,29 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { applicableComponents: inputComponents } = require("../applicableComponents/inputBasedComponents");
-const { applicableComponents: buttonComponents } = require("../applicableComponents/buttonBasedComponents");
-const { elementType } = require("jsx-ast-utils");
-const {
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { JSXOpeningElement } from "estree-jsx";
+import { elementType } from "jsx-ast-utils";
+import { applicableComponents as inputComponents } from "../applicableComponents/inputBasedComponents";
+import { applicableComponents as buttonComponents } from "../applicableComponents/buttonBasedComponents";
+import {
isInsideLabelTag,
hasAssociatedLabelViaHtmlFor,
hasAssociatedLabelViaAriaLabelledBy,
hasAssociatedLabelViaAriaDescribedby
-} = require("../util/labelUtils");
-
-const { hasFieldParent } = require("../util/hasFieldParent");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
+} from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasToolTipParent } from "../util/hasTooltipParent";
+import { hasTextContentChild } from "../util/hasTextContentChild";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
messages: {
noAriaDescribedbyAsLabel: "Accessibility: aria-describedby provides additional context and is not meant for primary labeling."
@@ -31,20 +30,18 @@ module.exports = {
type: "suggestion", // `problem`, `suggestion`, or `layout`
docs: {
description: "aria-describedby provides additional context and is not meant for primary labeling.",
- recommended: true,
- url: null // URL to the documentation page for this rule
+ recommended: "strict"
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
if (
- buttonComponents.includes(elementType(openingElement)) && // It's a button-based component
+ buttonComponents.includes(elementType(openingElement as JSXOpeningElement)) && // It's a button-based component
!hasToolTipParent(context) && // It doesn't have a tooltip parent
!hasTextContentChild(node) && // It doesn't have text content
!hasNonEmptyProp(openingElement.attributes, "title") && // Doesn't have a title
@@ -59,7 +56,7 @@ module.exports = {
}
if (
- inputComponents.includes(elementType(openingElement)) && // It's an input component
+ inputComponents.includes(elementType(openingElement as JSXOpeningElement)) && // It's an input component
!hasFieldParent(context) && // It doesn't have a field parent
!isInsideLabelTag(context) && // It's not inside a label tag
!hasAssociatedLabelViaHtmlFor(openingElement, context) && // Doesn't have a label via htmlFor
@@ -74,4 +71,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/badge-needs-accessible-name.js b/lib/rules/badge-needs-accessible-name.ts
similarity index 76%
rename from lib/rules/badge-needs-accessible-name.js
rename to lib/rules/badge-needs-accessible-name.ts
index cbc35ab..089f413 100644
--- a/lib/rules/badge-needs-accessible-name.js
+++ b/lib/rules/badge-needs-accessible-name.ts
@@ -1,19 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-var elementType = require("jsx-ast-utils").elementType;
-const { getPropValue, getProp } = require("jsx-ast-utils");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-var hasProp = require("jsx-ast-utils").hasProp;
+import { AST_NODE_TYPES, ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType, hasProp } from "jsx-ast-utils";
+import { getPropValue, getProp } from "jsx-ast-utils";
+import { hasTextContentChild } from "../util/hasTextContentChild";
+import { JSXAttribute, JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -34,8 +33,8 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
- const openingElement = node.openingElement;
+ JSXElement(node: TSESTree.JSXElement) {
+ const openingElement = node.openingElement as JSXOpeningElement;
// If it's not a Badge component, return early
if (elementType(openingElement) !== "Badge") {
@@ -53,13 +52,13 @@ module.exports = {
const hasIconProp = hasProp(openingElement.attributes, "icon");
if (hasIconProp) {
- const iconProp = getProp(openingElement.attributes, "icon");
+ const iconProp = getProp(openingElement.attributes, "icon") as TSESTree.JSXAttribute;
- if (iconProp) {
- const iconElement = iconProp.value.expression;
+ if (iconProp && iconProp.value && iconProp.value.type === AST_NODE_TYPES.JSXExpressionContainer) {
+ const iconElement = iconProp.value.expression as TSESTree.JSXElement;
// Check if the icon has an aria-label
- const ariaLabelAttr = hasProp(iconElement.openingElement.attributes, "aria-label");
+ const ariaLabelAttr = hasProp(iconElement.openingElement.attributes as JSXAttribute[], "aria-label");
// Report an error if aria-label is missing
if (!ariaLabelAttr) {
@@ -76,8 +75,9 @@ module.exports = {
}
// Simplified logic to check for a color-only Badge (no icon, no text)
+ const roleProp = getProp(openingElement.attributes, "role");
const hasColorProp = hasProp(openingElement.attributes, "color");
- const hasRole = getPropValue(getProp(openingElement.attributes, "role")) === "img";
+ const hasRole = !!roleProp && getPropValue(roleProp) === "img";
const hasAriaLabel = hasProp(openingElement.attributes, "aria-label");
// If it's color-only, ensure it has role="img" and aria-label
@@ -91,12 +91,14 @@ module.exports = {
// Fix role by adding role="img"
if (!hasRole) {
- fixes.push(fixer.insertTextAfter(openingElement.name, ' role="img"'));
+ fixes.push(fixer.insertTextAfter((openingElement as TSESTree.JSXOpeningElement).name, ' role="img"'));
}
// Fix aria-label by adding aria-label=""
if (!hasAriaLabel) {
- fixes.push(fixer.insertTextAfter(openingElement.name, ' aria-label=""'));
+ fixes.push(
+ fixer.insertTextAfter((openingElement as TSESTree.JSXOpeningElement).name, ' aria-label=""')
+ );
}
return fixes;
@@ -112,5 +114,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/breadcrumb-needs-labelling.js b/lib/rules/breadcrumb-needs-labelling.ts
similarity index 76%
rename from lib/rules/breadcrumb-needs-labelling.js
rename to lib/rules/breadcrumb-needs-labelling.ts
index c157e56..ee1f746 100644
--- a/lib/rules/breadcrumb-needs-labelling.js
+++ b/lib/rules/breadcrumb-needs-labelling.ts
@@ -1,18 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../util/labelUtils";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -25,16 +25,15 @@ module.exports = {
recommended: false,
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Breadcrumb, return
- if (elementType(node) !== "Breadcrumb") {
+ if (elementType(node as JSXOpeningElement) !== "Breadcrumb") {
return;
}
@@ -54,5 +53,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/buttons/compound-button-needs-labelling.js b/lib/rules/buttons/compound-button-needs-labelling.ts
similarity index 76%
rename from lib/rules/buttons/compound-button-needs-labelling.js
rename to lib/rules/buttons/compound-button-needs-labelling.ts
index 14db29f..e4cdd46 100644
--- a/lib/rules/buttons/compound-button-needs-labelling.js
+++ b/lib/rules/buttons/compound-button-needs-labelling.ts
@@ -1,19 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../../util/hasTooltipParent");
-const { hasTextContentChild } = require("../../util/hasTextContentChild");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../../util/labelUtils");
-var elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../../util/hasNonEmptyProp";
+import { hasToolTipParent } from "../../util/hasTooltipParent";
+import { hasTextContentChild } from "../../util/hasTextContentChild";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../../util/labelUtils";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -25,7 +26,7 @@ module.exports = {
docs: {
description:
"Accessibility: Compound buttons must have accessible labelling: title, aria-label, aria-labelledby, aria-describedby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -34,11 +35,11 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it is not a Compound button, return
- if (elementType(openingElement) !== "CompoundButton") {
+ if (elementType(openingElement as JSXOpeningElement) !== "CompoundButton") {
return;
}
@@ -65,4 +66,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/buttons/image-button-missing-aria.js b/lib/rules/buttons/image-button-missing-aria.ts
similarity index 74%
rename from lib/rules/buttons/image-button-missing-aria.js
rename to lib/rules/buttons/image-button-missing-aria.ts
index 06fad1c..9cd6ff5 100644
--- a/lib/rules/buttons/image-button-missing-aria.js
+++ b/lib/rules/buttons/image-button-missing-aria.ts
@@ -1,21 +1,21 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../../util/hasTooltipParent");
-const { hasTextContentChild } = require("../../util/hasTextContentChild");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../../util/labelUtils");
-const { applicableComponents } = require("../../applicableComponents/buttonBasedComponents");
-var hasProp = require("jsx-ast-utils").hasProp;
-var elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType, hasProp } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../../util/hasNonEmptyProp";
+import { hasToolTipParent } from "../../util/hasTooltipParent";
+import { hasTextContentChild } from "../../util/hasTextContentChild";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../../util/labelUtils";
+import { applicableComponents } from "../../applicableComponents/buttonBasedComponents";
+import { JSXAttribute, JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -27,7 +27,7 @@ module.exports = {
docs: {
description:
"Accessibility: Image buttons must have accessible labelling: title, aria-label, aria-labelledby, aria-describedby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -36,16 +36,16 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it is not a button, return
- if (!applicableComponents.includes(elementType(openingElement))) {
+ if (!applicableComponents.includes(elementType(openingElement as JSXOpeningElement))) {
return;
}
// if it is not an icon button, return
- if (!hasProp(openingElement.attributes, "icon")) {
+ if (!hasProp(openingElement.attributes as JSXAttribute[], "icon")) {
return;
}
@@ -77,4 +77,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/buttons/no-empty-buttons.js b/lib/rules/buttons/no-empty-buttons.ts
similarity index 72%
rename from lib/rules/buttons/no-empty-buttons.js
rename to lib/rules/buttons/no-empty-buttons.ts
index a48815d..ec2158f 100644
--- a/lib/rules/buttons/no-empty-buttons.js
+++ b/lib/rules/buttons/no-empty-buttons.ts
@@ -1,19 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasTextContentChild } = require("../../util/hasTextContentChild");
-const { hasNonEmptyProp } = require("../../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-var hasProp = require("jsx-ast-utils").hasProp;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType, hasProp } from "jsx-ast-utils";
+import { hasTextContentChild } from "../../util/hasTextContentChild";
+import { hasNonEmptyProp } from "../../util/hasNonEmptyProp";
+import { JSXAttribute, JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
const allowedComponents = ["Button", "ToggleButton", "SplitButton", "MenuButton", "CompoundButton"];
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the lint rule
messages: {
@@ -24,7 +24,7 @@ module.exports = {
// docs for the rule
docs: {
description: `Accessibility: ${allowedComponents.join(", ")} must either text content or icon or child component`,
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: [] // no options
@@ -33,11 +33,11 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it is not a button, return
- if (!allowedComponents.includes(elementType(openingElement))) {
+ if (!allowedComponents.includes(elementType(openingElement as JSXOpeningElement))) {
return;
}
@@ -45,12 +45,15 @@ module.exports = {
if (hasTextContentChild(node)) return;
// if there is icon prop, return
- if (hasProp(openingElement.attributes, "icon")) {
+ if (hasProp(openingElement.attributes as JSXAttribute[], "icon")) {
return;
}
// if split button has secondary content, return
- if (elementType(openingElement) === "CompoundButton" && hasNonEmptyProp(openingElement.attribute, "secondaryContent")) {
+ if (
+ elementType(openingElement as JSXOpeningElement) === "CompoundButton" &&
+ hasNonEmptyProp(openingElement.attributes, "secondaryContent")
+ ) {
return;
}
@@ -66,4 +69,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/checkbox-needs-labelling.js b/lib/rules/checkbox-needs-labelling.ts
similarity index 75%
rename from lib/rules/checkbox-needs-labelling.js
rename to lib/rules/checkbox-needs-labelling.ts
index 33f776c..e16eea9 100644
--- a/lib/rules/checkbox-needs-labelling.js
+++ b/lib/rules/checkbox-needs-labelling.ts
@@ -1,18 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { elementType } from "jsx-ast-utils";
+import { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -24,7 +25,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: Checkbox without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -33,9 +34,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Checkbox, return
- if (elementType(node) !== "Checkbox") {
+ if (elementType(node as JSXOpeningElement) !== "Checkbox") {
return;
}
@@ -58,4 +59,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/combobox-needs-labelling.js b/lib/rules/combobox-needs-labelling.ts
similarity index 75%
rename from lib/rules/combobox-needs-labelling.js
rename to lib/rules/combobox-needs-labelling.ts
index 919ac9a..a5d2387 100644
--- a/lib/rules/combobox-needs-labelling.js
+++ b/lib/rules/combobox-needs-labelling.ts
@@ -1,19 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -26,16 +26,15 @@ module.exports = {
recommended: false,
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Combobox, return
- if (elementType(node) !== "Combobox") {
+ if (elementType(node as JSXOpeningElement) !== "Combobox") {
return;
}
@@ -58,5 +57,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/dialogbody-needs-title-content-and-actions.js b/lib/rules/dialogbody-needs-title-content-and-actions.js
deleted file mode 100644
index 62f09b9..0000000
--- a/lib/rules/dialogbody-needs-title-content-and-actions.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Rule Definition
-//------------------------------------------------------------------------------
-
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
- meta: {
- messages: {
- dialogBodyOneTitleOneContentOneFooter: "ensure DialogBody has exactly one header,one content and one footer"
- },
- type: "problem", // `problem`, `suggestion`, or `layout`
- docs: {
- description: "A DialogBody should have a header(DialogTitle), content(DialogContent), and footer(DialogActions)",
- recommended: true,
- url: "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" // URL to the documentation page for this rule
- },
- fixable: null, // Or `code` or `whitespace`
- schema: [] // Add a schema if the rule has options
- },
-
- create(context) {
- return {
- JSXOpeningElement(node) {
- if (node.name.name !== "DialogBody") {
- return;
- }
-
- const children = node.parent.children.filter(child => child.type === "JSXElement");
-
- const hasOneTitle = children.filter(child => child.openingElement.name.name === "DialogTitle").length === 1;
-
- const hasOneContnet = children.filter(child => child.openingElement.name.name === "DialogContent").length === 1;
-
- const hasOneAction = children.filter(child => child.openingElement.name.name === "DialogActions").length === 1;
-
- if (!hasOneTitle || !hasOneContnet || !hasOneAction || children.length !== 3) {
- context.report({
- node,
- messageId: "dialogBodyOneTitleOneContentOneFooter"
- });
- }
- }
- };
- }
-};
diff --git a/lib/rules/dialogbody-needs-title-content-and-actions.ts b/lib/rules/dialogbody-needs-title-content-and-actions.ts
new file mode 100644
index 0000000..a9adaa1
--- /dev/null
+++ b/lib/rules/dialogbody-needs-title-content-and-actions.ts
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+import { AST_NODE_TYPES, ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
+ meta: {
+ messages: {
+ dialogBodyOneTitleOneContentOneFooter: "ensure DialogBody has exactly one header,one content and one footer"
+ },
+ type: "problem", // `problem`, `suggestion`, or `layout`
+ docs: {
+ description: "A DialogBody should have a header(DialogTitle), content(DialogContent), and footer(DialogActions)",
+ recommended: "strict",
+ url: "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" // URL to the documentation page for this rule
+ },
+ schema: [] // Add a schema if the rule has options
+ },
+
+ create(context) {
+ return {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
+ if (node.name.type === AST_NODE_TYPES.JSXIdentifier && node.name.name !== "DialogBody") {
+ return;
+ }
+
+ const children =
+ node.parent &&
+ node.parent.type === AST_NODE_TYPES.JSXElement &&
+ node.parent.children.filter(child => child.type === "JSXElement");
+
+ if (children) {
+ const hasOneTitle =
+ children.filter(
+ child =>
+ child.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogTitle"
+ ).length === 1;
+
+ const hasOneContnet =
+ children.filter(
+ child =>
+ child.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogContent"
+ ).length === 1;
+
+ const hasOneAction =
+ children.filter(
+ child =>
+ child.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogActions"
+ ).length === 1;
+
+ if (!hasOneTitle || !hasOneContnet || !hasOneAction || children.length !== 3) {
+ context.report({
+ node,
+ messageId: "dialogBodyOneTitleOneContentOneFooter"
+ });
+ }
+ }
+ }
+ };
+ }
+});
+
+export default rule;
diff --git a/lib/rules/dialogsurface-needs-aria.js b/lib/rules/dialogsurface-needs-aria.js
deleted file mode 100644
index b1a71da..0000000
--- a/lib/rules/dialogsurface-needs-aria.js
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-"use strict";
-
-const { hasAssociatedAriaText } = require("../util/labelUtils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-var elementType = require("jsx-ast-utils").elementType;
-
-//------------------------------------------------------------------------------
-// Rule Definition
-//------------------------------------------------------------------------------
-
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
- meta: {
- // possible error messages for the rule
- messages: {
- missingAriaOnDialogSurface: "DialogueSurface need accessible labelling: aria-describedby on DialogueSurface and aria-label or aria-labelledby(if DialogueTitle is missing)"
- },
- // "problem" means the rule is identifying code that either will cause an error or may cause a confusing behavior: https://eslint.org/docs/latest/developer-guide/working-with-rules
- type: "problem",
- // docs for the rule
- docs: {
- description: "DialogueSurface need accessible labelling: aria-describedby on DialogueSurface and aria-label or aria-labelledby(if DialogueTitle is missing)",
- recommended: true,
- url: "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" // URL to the documentation page for this rule
- },
- schema: []
- },
-
- create(context) {
- return {
- // visitor functions for different types of nodes
- JSXOpeningElement(node) {
-
- // if it is not a DialogSurface, return
- if (elementType(node) !== "DialogSurface") {
- return;
- }
-
- // determine if DialogSurface as aria-describedby
- const hasAriaDescribedBy = hasAssociatedAriaText(node, context, "aria-describedby");
-
- // find DialogBody Component
- const dialogueSurfaceChildren = node.parent.children.filter(child => child.type === "JSXElement");
-
- const DialogBodyNode = dialogueSurfaceChildren.find(child => child.openingElement.name.name === "DialogBody");
-
-
- // find DialogTitle inside DialogBody Component
- const dialogueBodyChildren = DialogBodyNode && DialogBodyNode.children.filter(child => child.type === "JSXElement");
-
- const DialogTitleNode = dialogueBodyChildren && dialogueBodyChildren.find(child => child.openingElement.name.name === "DialogTitle");
-
- // determine if DialogueText has any text content
- const hasDialogTitleText = DialogTitleNode && hasTextContentChild(DialogTitleNode);
-
- // determine if DialogueText or aria-label is present
- const hasTitleOrAriaLabelledBy = hasDialogTitleText || hasNonEmptyProp(node.attributes, "aria-label") || hasAssociatedAriaText(node, context, "aria-labelledby");
-
- // if the DialogSurface has aria labelling and description, return
- if (hasAriaDescribedBy && hasTitleOrAriaLabelledBy) {
- return;
- }
-
- context.report({
- node,
- messageId: `missingAriaOnDialogSurface`
- });
- }
- };
- }
-};
-
diff --git a/lib/rules/dialogsurface-needs-aria.ts b/lib/rules/dialogsurface-needs-aria.ts
new file mode 100644
index 0000000..dcb59ed
--- /dev/null
+++ b/lib/rules/dialogsurface-needs-aria.ts
@@ -0,0 +1,95 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+import { AST_NODE_TYPES, ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasAssociatedAriaText } from "../util/labelUtils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasTextContentChild } from "../util/hasTextContentChild";
+import { JSXOpeningElement } from "estree-jsx";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
+ meta: {
+ // possible error messages for the rule
+ messages: {
+ missingAriaOnDialogSurface:
+ "DialogueSurface need accessible labelling: aria-describedby on DialogueSurface and aria-label or aria-labelledby(if DialogueTitle is missing)"
+ },
+ // "problem" means the rule is identifying code that either will cause an error or may cause a confusing behavior: https://eslint.org/docs/latest/developer-guide/working-with-rules
+ type: "problem",
+ // docs for the rule
+ docs: {
+ description:
+ "DialogueSurface need accessible labelling: aria-describedby on DialogueSurface and aria-label or aria-labelledby(if DialogueTitle is missing)",
+ recommended: "strict",
+ url: "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" // URL to the documentation page for this rule
+ },
+ schema: []
+ },
+
+ create(context) {
+ return {
+ // visitor functions for different types of nodes
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
+ // if it is not a DialogSurface, return
+ if (elementType(node as JSXOpeningElement) !== "DialogSurface") {
+ return;
+ }
+
+ // determine if DialogSurface as aria-describedby
+ const hasAriaDescribedBy = hasAssociatedAriaText(node, context, "aria-describedby");
+
+ // find DialogBody Component
+ const dialogueSurfaceChildren =
+ node.parent &&
+ node.parent.type === AST_NODE_TYPES.JSXElement &&
+ node.parent.children.filter(child => child.type === "JSXElement");
+
+ if (dialogueSurfaceChildren) {
+ const DialogBodyNode = dialogueSurfaceChildren.find(
+ child =>
+ child.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogBody"
+ );
+
+ // find DialogTitle inside DialogBody Component
+ const dialogueBodyChildren = DialogBodyNode && DialogBodyNode.children.filter(child => child.type === "JSXElement");
+
+ const DialogTitleNode =
+ dialogueBodyChildren &&
+ dialogueBodyChildren.find(
+ child =>
+ child.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&
+ child.openingElement.name.name === "DialogTitle"
+ );
+
+ // determine if DialogueText has any text content
+ const hasDialogTitleText = DialogTitleNode && hasTextContentChild(DialogTitleNode);
+
+ // determine if DialogueText or aria-label is present
+ const hasTitleOrAriaLabelledBy =
+ hasDialogTitleText ||
+ hasNonEmptyProp(node.attributes, "aria-label") ||
+ hasAssociatedAriaText(node, context, "aria-labelledby");
+
+ // if the DialogSurface has aria labelling and description, return
+ if (hasAriaDescribedBy && hasTitleOrAriaLabelledBy) {
+ return;
+ }
+
+ context.report({
+ node,
+ messageId: `missingAriaOnDialogSurface`
+ });
+ }
+ }
+ };
+ }
+});
+
+export default rule;
diff --git a/lib/rules/dropdown-needs-labelling.js b/lib/rules/dropdown-needs-labelling.ts
similarity index 77%
rename from lib/rules/dropdown-needs-labelling.js
rename to lib/rules/dropdown-needs-labelling.ts
index f87e46b..8141c82 100644
--- a/lib/rules/dropdown-needs-labelling.js
+++ b/lib/rules/dropdown-needs-labelling.ts
@@ -1,17 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, hasAssociatedLabelViaHtmlFor, isInsideLabelTag } = require("../util/labelUtils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasAssociatedLabelViaAriaLabelledBy, hasAssociatedLabelViaHtmlFor, isInsideLabelTag } from "../util/labelUtils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -22,8 +23,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Dropdown menu must have an id and it needs to be linked via htmlFor of a Label",
- recommended: true,
- url: null
+ recommended: "strict"
},
schema: []
},
@@ -32,9 +32,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Dropdown, return
- if (elementType(node) !== "Dropdown") {
+ if (elementType(node as JSXOpeningElement) !== "Dropdown") {
return;
}
@@ -59,4 +59,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/input-components-require-accessible-name.js b/lib/rules/input-components-require-accessible-name.ts
similarity index 74%
rename from lib/rules/input-components-require-accessible-name.js
rename to lib/rules/input-components-require-accessible-name.ts
index 7068829..9fa0c88 100644
--- a/lib/rules/input-components-require-accessible-name.js
+++ b/lib/rules/input-components-require-accessible-name.ts
@@ -1,19 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { elementType } = require("jsx-ast-utils");
-
-const { isInsideLabelTag, hasAssociatedLabelViaHtmlFor, hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
-const { applicableComponents } = require("../applicableComponents/inputBasedComponents");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { isInsideLabelTag, hasAssociatedLabelViaHtmlFor, hasAssociatedLabelViaAriaLabelledBy } from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { applicableComponents } from "../applicableComponents/inputBasedComponents";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -26,7 +26,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Input fields must have accessible labelling: aria-label, aria-labelledby or an associated label",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/tutorials/forms/labels/" // URL to the documentation page for this rule
},
schema: []
@@ -35,9 +35,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a listed component, return
- if (!applicableComponents.includes(elementType(node))) {
+ if (!applicableComponents.includes(elementType(node as JSXOpeningElement))) {
return;
}
@@ -58,4 +58,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/link-missing-labelling.js b/lib/rules/link-missing-labelling.ts
similarity index 81%
rename from lib/rules/link-missing-labelling.js
rename to lib/rules/link-missing-labelling.ts
index 845e9ce..a086394 100644
--- a/lib/rules/link-missing-labelling.js
+++ b/lib/rules/link-missing-labelling.ts
@@ -1,27 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { elementType } = require("jsx-ast-utils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-const { hasLabelledChildImage } = require("../util/hasLabelledChildImage");
-const { linkBasedComponents } = require("../applicableComponents/linkBasedComponents");
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasTextContentChild } from "../util/hasTextContentChild";
+import { hasLabelledChildImage } from "../util/hasLabelledChildImage";
+import { linkBasedComponents } from "../applicableComponents/linkBasedComponents";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../util/labelUtils";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
type: "problem",
docs: {
description:
"Accessibility: Image links must have an accessible name. Add either text content, labelling to the image or labelling to the link itself.",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/standards-guidelines/act/rules/c487ae/" // URL to the documentation page for this rule
},
messages: {
@@ -40,11 +40,11 @@ module.exports = {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it's not a link based component, return
- if (!linkBasedComponents.includes(elementType(openingElement))) {
+ if (!linkBasedComponents.includes(elementType(openingElement as JSXOpeningElement))) {
return;
}
@@ -90,4 +90,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/menu-item-needs-labelling.js b/lib/rules/menu-item-needs-labelling.ts
similarity index 74%
rename from lib/rules/menu-item-needs-labelling.js
rename to lib/rules/menu-item-needs-labelling.ts
index 6bc4e2a..e1d2169 100644
--- a/lib/rules/menu-item-needs-labelling.js
+++ b/lib/rules/menu-item-needs-labelling.ts
@@ -1,20 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-const { hasTextContentChild } = require("../util/hasTextContentChild");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../util/labelUtils";
+import { hasTextContentChild } from "../util/hasTextContentChild";
+import { hasToolTipParent } from "../util/hasTooltipParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -24,20 +24,19 @@ module.exports = {
type: "problem",
docs: {
description: "Accessibility: MenuItem without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it is not a MenuItem, return
- if (elementType(openingElement) !== "MenuItem") {
+ if (elementType(openingElement as JSXOpeningElement) !== "MenuItem") {
return;
}
@@ -59,5 +58,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/no-empty-components.js b/lib/rules/no-empty-components.ts
similarity index 81%
rename from lib/rules/no-empty-components.js
rename to lib/rules/no-empty-components.ts
index b023967..6e4f61a 100644
--- a/lib/rules/no-empty-components.js
+++ b/lib/rules/no-empty-components.ts
@@ -1,9 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-var elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { JSXOpeningElement } from "estree-jsx";
+import { elementType } from "jsx-ast-utils";
//------------------------------------------------------------------------------
// Rule Definition
@@ -11,8 +11,8 @@ var elementType = require("jsx-ast-utils").elementType;
// Define an array of allowed component names
const allowedComponents = ["Text", "Label", "Combobox", "Breadcrumb", "Dropdown", "Accordion", "AccordionItem", "AccordionPanel"];
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the lint rule
messages: {
@@ -21,21 +21,19 @@ module.exports = {
type: "problem", // `problem`, `suggestion`, or `layout`
docs: {
description: "FluentUI components should not be empty",
- recommended: true,
- url: null // URL to the documentation page for this rule
+ recommended: "strict"
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
// create (function) returns an object with methods that ESLint calls to “visit” nodes while traversing the abstract syntax tree
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it is not a listed component, return
- if (!allowedComponents.includes(elementType(openingElement))) {
+ if (!allowedComponents.includes(elementType(openingElement as JSXOpeningElement))) {
return;
}
@@ -51,4 +49,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/progressbar-needs-labelling.js b/lib/rules/progressbar-needs-labelling.ts
similarity index 84%
rename from lib/rules/progressbar-needs-labelling.js
rename to lib/rules/progressbar-needs-labelling.ts
index a580aea..37ad191 100644
--- a/lib/rules/progressbar-needs-labelling.js
+++ b/lib/rules/progressbar-needs-labelling.ts
@@ -1,17 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasFieldParent } = require("../util/hasFieldParent");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -24,7 +25,7 @@ module.exports = {
docs: {
description:
"Accessibility: Progressbar must have aria-valuemin, aria-valuemax, aria-valuenow, aria-describedby and either aria-label or aria-labelledby attributes",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -33,9 +34,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a ProgressBar, return
- if (elementType(node) !== "ProgressBar") {
+ if (elementType(node as JSXOpeningElement) !== "ProgressBar") {
return;
}
@@ -73,5 +74,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/radio-button-missing-label.js b/lib/rules/radio-button-missing-label.ts
similarity index 76%
rename from lib/rules/radio-button-missing-label.js
rename to lib/rules/radio-button-missing-label.ts
index 9e76123..fa7c791 100644
--- a/lib/rules/radio-button-missing-label.js
+++ b/lib/rules/radio-button-missing-label.ts
@@ -1,18 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -24,7 +25,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: Radio button without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -33,9 +34,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Checkbox, return
- if (elementType(node) !== "Radio") {
+ if (elementType(node as JSXOpeningElement) !== "Radio") {
return;
}
@@ -59,4 +60,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/radiogroup-missing-label.js b/lib/rules/radiogroup-missing-label.ts
similarity index 75%
rename from lib/rules/radiogroup-missing-label.js
rename to lib/rules/radiogroup-missing-label.ts
index 9be7dc1..eb585f2 100644
--- a/lib/rules/radiogroup-missing-label.js
+++ b/lib/rules/radiogroup-missing-label.ts
@@ -1,18 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -24,7 +25,7 @@ module.exports = {
docs: {
// DONE
description: "Accessibility: RadioGroup without label must have an accessible and visual label: aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -33,9 +34,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Checkbox, return
- if (elementType(node) !== "RadioGroup") {
+ if (elementType(node as JSXOpeningElement) !== "RadioGroup") {
return;
}
@@ -59,4 +60,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/spin-button-needs-labelling.js b/lib/rules/spin-button-needs-labelling.ts
similarity index 75%
rename from lib/rules/spin-button-needs-labelling.js
rename to lib/rules/spin-button-needs-labelling.ts
index 181a57b..d6272f8 100644
--- a/lib/rules/spin-button-needs-labelling.js
+++ b/lib/rules/spin-button-needs-labelling.ts
@@ -1,17 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -22,7 +23,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: SpinButtons must have an accessible label",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -31,9 +32,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a SpinButton, return
- if (elementType(node) !== "SpinButton") {
+ if (elementType(node as JSXOpeningElement) !== "SpinButton") {
return;
}
@@ -55,4 +56,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/spin-button-unrecommended-labelling.js b/lib/rules/spin-button-unrecommended-labelling.ts
similarity index 75%
rename from lib/rules/spin-button-unrecommended-labelling.js
rename to lib/rules/spin-button-unrecommended-labelling.ts
index a713d83..e10b6c4 100644
--- a/lib/rules/spin-button-unrecommended-labelling.js
+++ b/lib/rules/spin-button-unrecommended-labelling.ts
@@ -1,17 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const { hasToolTipParent } = require("../util/hasTooltipParent");
-var elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasToolTipParent } from "../util/hasTooltipParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible suggestion messages for the rule
messages: {
@@ -22,7 +23,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Unrecommended accessibility labelling - SpinButton",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -31,9 +32,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a SpinButton, return
- if (elementType(node) !== "SpinButton") {
+ if (elementType(node as JSXOpeningElement) !== "SpinButton") {
return;
}
@@ -47,5 +48,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/spinner-needs-labelling.js b/lib/rules/spinner-needs-labelling.ts
similarity index 67%
rename from lib/rules/spinner-needs-labelling.js
rename to lib/rules/spinner-needs-labelling.ts
index cc1dc58..5005cc6 100644
--- a/lib/rules/spinner-needs-labelling.js
+++ b/lib/rules/spinner-needs-labelling.ts
@@ -1,16 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-const elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -21,7 +22,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Spinner must have either aria-label or label, aria-live and aria-busy attributes",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -30,15 +31,16 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Spinner, return
- if (elementType(node) !== "Spinner") {
+ if (elementType(node as JSXOpeningElement) !== "Spinner") {
return;
}
- if (hasNonEmptyProp(node.attributes, "aria-busy")
- && hasNonEmptyProp(node.attributes, "aria-live")
- && (hasNonEmptyProp(node.attributes, "label") || hasNonEmptyProp(node.attributes, "aria-label"))
+ if (
+ hasNonEmptyProp(node.attributes, "aria-busy") &&
+ hasNonEmptyProp(node.attributes, "aria-live") &&
+ (hasNonEmptyProp(node.attributes, "label") || hasNonEmptyProp(node.attributes, "aria-label"))
) {
return;
}
@@ -51,5 +53,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/switch-needs-labelling.js b/lib/rules/switch-needs-labelling.ts
similarity index 74%
rename from lib/rules/switch-needs-labelling.js
rename to lib/rules/switch-needs-labelling.ts
index f2e1d5b..648a6f3 100644
--- a/lib/rules/switch-needs-labelling.js
+++ b/lib/rules/switch-needs-labelling.ts
@@ -1,18 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
-const { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } = require("../util/labelUtils");
-const { hasFieldParent } = require("../util/hasFieldParent");
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { hasAssociatedLabelViaAriaLabelledBy, isInsideLabelTag, hasAssociatedLabelViaHtmlFor } from "../util/labelUtils";
+import { hasFieldParent } from "../util/hasFieldParent";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -23,7 +24,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Switch must have an accessible label",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/TR/html-aria/" // URL to the documentation page for this rule
},
schema: []
@@ -32,9 +33,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Switch, return
- if (elementType(node) !== "Switch") {
+ if (elementType(node as JSXOpeningElement) !== "Switch") {
return;
}
@@ -57,4 +58,6 @@ module.exports = {
}
};
}
-};
+});
+
+export default rule;
diff --git a/lib/rules/toolbar-missing-aria.js b/lib/rules/toolbar-missing-aria.ts
similarity index 73%
rename from lib/rules/toolbar-missing-aria.js
rename to lib/rules/toolbar-missing-aria.ts
index f7438db..f725458 100644
--- a/lib/rules/toolbar-missing-aria.js
+++ b/lib/rules/toolbar-missing-aria.ts
@@ -1,18 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { hasAssociatedLabelViaAriaLabelledBy } = require("../util/labelUtils");
-const { hasNonEmptyProp } = require("../util/hasNonEmptyProp");
-var elementType = require("jsx-ast-utils").elementType;
+import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
+import { elementType } from "jsx-ast-utils";
+import { hasAssociatedLabelViaAriaLabelledBy } from "../util/labelUtils";
+import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
+import { JSXOpeningElement } from "estree-jsx";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the rule
messages: {
@@ -23,7 +23,7 @@ module.exports = {
// docs for the rule
docs: {
description: "Accessibility: Toolbars need accessible labelling: aria-label or aria-labelledby",
- recommended: true,
+ recommended: "strict",
url: "https://www.w3.org/WAI/tutorials/forms/labels/" // URL to the documentation page for this rule
},
schema: []
@@ -32,9 +32,9 @@ module.exports = {
create(context) {
return {
// visitor functions for different types of nodes
- JSXOpeningElement(node) {
+ JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Toolbar, return
- if (elementType(node) !== "Toolbar") {
+ if (elementType(node as JSXOpeningElement) !== "Toolbar") {
return;
}
@@ -50,5 +50,6 @@ module.exports = {
}
};
}
-};
+});
+export default rule;
diff --git a/lib/rules/tooltip-not-recommended.js b/lib/rules/tooltip-not-recommended.ts
similarity index 78%
rename from lib/rules/tooltip-not-recommended.js
rename to lib/rules/tooltip-not-recommended.ts
index 6c12a06..b2111c9 100644
--- a/lib/rules/tooltip-not-recommended.js
+++ b/lib/rules/tooltip-not-recommended.ts
@@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-var elementType = require("jsx-ast-utils").elementType;
-const { hasToolTipParent } = require("../util/hasTooltipParent");
+import {ESLintUtils, TSESTree} from '@typescript-eslint/utils';
+import { elementType } from "jsx-ast-utils";
+import { hasToolTipParent } from "../util/hasTooltipParent";
+import { JSXOpeningElement } from 'estree-jsx';
//------------------------------------------------------------------------------
// Rule Definition
@@ -12,8 +12,8 @@ const { hasToolTipParent } = require("../util/hasTooltipParent");
// Define an array of allowed component names
const allowedComponents = ["MenuItem", "SpinButton"];
-/** @type {import('eslint').Rule.RuleModule} */
-module.exports = {
+const rule = ESLintUtils.RuleCreator.withoutDocs({
+ defaultOptions: [],
meta: {
// possible error messages for the lint rule
messages: {
@@ -22,21 +22,19 @@ module.exports = {
type: "suggestion", // `problem`, `suggestion`, or `layout`
docs: {
description: `Accessibility: Prefer text content or aria over a tooltip for these components ${allowedComponents.join(", ")}`,
- recommended: true,
- url: null // URL to the documentation page for this rule
+ recommended: 'strict',
},
- fixable: null, // Or `code` or `whitespace`
schema: [] // Add a schema if the rule has options
},
// create (function) returns an object with methods that ESLint calls to “visit” nodes while traversing the abstract syntax tree
create(context) {
return {
// visitor functions for different types of nodes
- JSXElement(node) {
+ JSXElement(node: TSESTree.JSXElement) {
const openingElement = node.openingElement;
// if it is not a listed component, return
- if (!allowedComponents.includes(elementType(openingElement))) {
+ if (!allowedComponents.includes(elementType(openingElement as JSXOpeningElement))) {
return;
}
@@ -50,5 +48,8 @@ module.exports = {
}
};
}
-};
+});
+
+
+export default rule;
\ No newline at end of file
diff --git a/lib/util/hasLabelledChildImage.js b/lib/util/hasLabelledChildImage.js
index b15cdeb..9b5684d 100644
--- a/lib/util/hasLabelledChildImage.js
+++ b/lib/util/hasLabelledChildImage.js
@@ -21,12 +21,7 @@ function hasLabelledChildImage(node) {
// Check if there is an accessible image
const hasAccessibleImage = flattenChildren(node).some(child => {
- console.log(
- "mergedImageComponents.includes(child.openingElement.name.name)::: ",
- mergedImageComponents.includes(child.openingElement.name.name)
- );
if (child.type === "JSXElement" && mergedImageComponents.includes(child.openingElement.name.name)) {
- console.log("here 3");
return hasProp(child.openingElement.attributes, "aria-hidden") || getPropValue(child.openingElement.attributes, "alt")
? false
: hasNonEmptyProp(child.openingElement.attributes, "title") ||
diff --git a/package-lock.json b/package-lock.json
index 481f21d..55b858a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,9 +14,11 @@
"requireindex": "^1.2.0"
},
"devDependencies": {
+ "@types/chai": "^4.3.19",
"@types/eslint": "=7.2.10",
"@types/estree": "^1.0.5",
"@types/estree-jsx": "^1.0.5",
+ "@types/jest": "^29.5.13",
"@types/jsx-ast-utils": "^3.3.1",
"@types/node": "^22.5.5",
"@typescript-eslint/eslint-plugin": "^8.6.0",
@@ -31,7 +33,6 @@
"jest": "^29.7.0",
"markdownlint": "^0.28.1",
"markdownlint-cli": "^0.33.0",
- "mocha": "^10.0.0",
"npm-run-all": "^4.1.5",
"prettier": "2.8.4",
"ts-jest": "^29.2.5",
@@ -1233,6 +1234,12 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/chai": {
+ "version": "4.3.19",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.19.tgz",
+ "integrity": "sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==",
+ "dev": true
+ },
"node_modules/@types/eslint": {
"version": "7.2.10",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz",
@@ -1291,6 +1298,16 @@
"@types/istanbul-lib-report": "*"
}
},
+ "node_modules/@types/jest": {
+ "version": "29.5.13",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.13.tgz",
+ "integrity": "sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg==",
+ "dev": true,
+ "dependencies": {
+ "expect": "^29.0.0",
+ "pretty-format": "^29.0.0"
+ }
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -2009,15 +2026,6 @@
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
- "node_modules/ansi-colors": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
- "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
@@ -2263,15 +2271,6 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
- "node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/boolean": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
@@ -2312,12 +2311,6 @@
"node": ">=8"
}
},
- "node_modules/browser-stdout": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
- "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
- "dev": true
- },
"node_modules/browserslist": {
"version": "4.23.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
@@ -2536,33 +2529,6 @@
"node": "*"
}
},
- "node_modules/chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- ],
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
"node_modules/ci-info": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
@@ -2584,17 +2550,6 @@
"integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==",
"dev": true
},
- "node_modules/cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
"node_modules/co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -2733,18 +2688,6 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
- "node_modules/decamelize": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
- "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/dedent": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
@@ -2819,15 +2762,6 @@
"node": ">=8"
}
},
- "node_modules/diff": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
- "dev": true,
- "engines": {
- "node": ">=0.3.1"
- }
- },
"node_modules/diff-sequences": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
@@ -3673,15 +3607,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/flat": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
- "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
- "dev": true,
- "bin": {
- "flat": "cli.js"
- }
- },
"node_modules/flat-cache": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
@@ -4039,15 +3964,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/he": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
- "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "dev": true,
- "bin": {
- "he": "bin/he"
- }
- },
"node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@@ -4206,18 +4122,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-boolean-object": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
@@ -4352,15 +4256,6 @@
"node": ">=8"
}
},
- "node_modules/is-plain-obj": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
- "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -4445,18 +4340,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-unicode-supported": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
- "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-weakref": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
@@ -5366,22 +5249,6 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
- "node_modules/log-symbols": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
- "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.1.0",
- "is-unicode-supported": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/loupe": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
@@ -5664,85 +5531,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/mocha": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
- "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
- "dev": true,
- "dependencies": {
- "ansi-colors": "4.1.1",
- "browser-stdout": "1.3.1",
- "chokidar": "3.5.3",
- "debug": "4.3.4",
- "diff": "5.0.0",
- "escape-string-regexp": "4.0.0",
- "find-up": "5.0.0",
- "glob": "7.2.0",
- "he": "1.2.0",
- "js-yaml": "4.1.0",
- "log-symbols": "4.1.0",
- "minimatch": "5.0.1",
- "ms": "2.1.3",
- "nanoid": "3.3.3",
- "serialize-javascript": "6.0.0",
- "strip-json-comments": "3.1.1",
- "supports-color": "8.1.1",
- "workerpool": "6.2.1",
- "yargs": "16.2.0",
- "yargs-parser": "20.2.4",
- "yargs-unparser": "2.0.0"
- },
- "bin": {
- "_mocha": "bin/_mocha",
- "mocha": "bin/mocha.js"
- },
- "engines": {
- "node": ">= 14.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/mochajs"
- }
- },
- "node_modules/mocha/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/mocha/node_modules/minimatch": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
- "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true
- },
- "node_modules/nanoid": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
- "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
- "dev": true,
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -6299,15 +6087,6 @@
}
]
},
- "node_modules/randombytes": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
- "dependencies": {
- "safe-buffer": "^5.1.0"
- }
- },
"node_modules/react-is": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
@@ -6340,18 +6119,6 @@
"node": ">=4"
}
},
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
"node_modules/regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
@@ -6526,26 +6293,6 @@
"queue-microtask": "^1.2.2"
}
},
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@@ -6568,15 +6315,6 @@
"semver": "bin/semver"
}
},
- "node_modules/serialize-javascript": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
- "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
- "dev": true,
- "dependencies": {
- "randombytes": "^2.1.0"
- }
- },
"node_modules/shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -7228,12 +6966,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/workerpool": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
- "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
- "dev": true
- },
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
@@ -7318,48 +7050,6 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true
},
- "node_modules/yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "dev": true,
- "dependencies": {
- "cliui": "^7.0.2",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.0",
- "y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yargs-parser": {
- "version": "20.2.4",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
- "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yargs-unparser": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
- "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
- "dev": true,
- "dependencies": {
- "camelcase": "^6.0.0",
- "decamelize": "^4.0.0",
- "flat": "^5.0.2",
- "is-plain-obj": "^2.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 3c64585..85f2f91 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
"lint": "npm-run-all \"lint:*\"",
"lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
"lint:js": "eslint .",
- "test": "mocha tests --recursive && jest",
+ "test": "jest",
"lint:docs": "markdownlint **/*.md",
"update:eslint-docs": "eslint-doc-generator",
"fix:md": "npm run lint:docs -- --fix",
@@ -52,9 +52,11 @@
"requireindex": "^1.2.0"
},
"devDependencies": {
+ "@types/chai": "^4.3.19",
"@types/eslint": "=7.2.10",
"@types/estree": "^1.0.5",
"@types/estree-jsx": "^1.0.5",
+ "@types/jest": "^29.5.13",
"@types/jsx-ast-utils": "^3.3.1",
"@types/node": "^22.5.5",
"@typescript-eslint/eslint-plugin": "^8.6.0",
@@ -69,7 +71,6 @@
"jest": "^29.7.0",
"markdownlint": "^0.28.1",
"markdownlint-cli": "^0.33.0",
- "mocha": "^10.0.0",
"npm-run-all": "^4.1.5",
"prettier": "2.8.4",
"ts-jest": "^29.2.5",
diff --git a/tests/lib/rules/accordion-header-needs-labelling.js b/tests/lib/rules/accordion-header-needs-labelling.test.ts
similarity index 86%
rename from tests/lib/rules/accordion-header-needs-labelling.js
rename to tests/lib/rules/accordion-header-needs-labelling.test.ts
index bb2310d..93e4304 100644
--- a/tests/lib/rules/accordion-header-needs-labelling.js
+++ b/tests/lib/rules/accordion-header-needs-labelling.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/accordion-header-needs-labelling");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/accordion-header-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("accordion-header-needs-labelling", rule, {
+ruleTester.run("accordion-header-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
"Accordion Header 1",
"}>Accordion Header 1",
diff --git a/tests/lib/rules/accordion-item-needs-header-and-panel.js b/tests/lib/rules/accordion-item-needs-header-and-panel.test.ts
similarity index 81%
rename from tests/lib/rules/accordion-item-needs-header-and-panel.js
rename to tests/lib/rules/accordion-item-needs-header-and-panel.test.ts
index 7037402..2392eda 100644
--- a/tests/lib/rules/accordion-item-needs-header-and-panel.js
+++ b/tests/lib/rules/accordion-item-needs-header-and-panel.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/accordion-item-needs-header-and-panel"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/accordion-item-needs-header-and-panel";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("accordion-item-needs-header-and-panel", rule, {
+ruleTester.run("accordion-item-needs-header-and-panel", rule as unknown as Rule.RuleModule, {
valid: [
`Accordion Header 1Accordion Panel 1
`
],
diff --git a/tests/lib/rules/avatar-needs-name.js b/tests/lib/rules/avatar-needs-name.test.ts
similarity index 82%
rename from tests/lib/rules/avatar-needs-name.js
rename to tests/lib/rules/avatar-needs-name.test.ts
index 1769a78..f307c82 100644
--- a/tests/lib/rules/avatar-needs-name.js
+++ b/tests/lib/rules/avatar-needs-name.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/avatar-needs-name");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/avatar-needs-name";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("avatar-needs-name", rule, {
+ruleTester.run("avatar-needs-name", rule as unknown as Rule.RuleModule, {
valid: [
// give me some code that won't trigger a warning
'',
diff --git a/tests/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js b/tests/lib/rules/avoid-using-aria-describedby-for-primary-labelling.test.ts
similarity index 83%
rename from tests/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js
rename to tests/lib/rules/avoid-using-aria-describedby-for-primary-labelling.test.ts
index 3812535..57c26d0 100644
--- a/tests/lib/rules/avoid-using-aria-describedby-for-primary-labelling.js
+++ b/tests/lib/rules/avoid-using-aria-describedby-for-primary-labelling.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/avoid-using-aria-describedby-for-primary-labelling"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/avoid-using-aria-describedby-for-primary-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("avoid-using-aria-describedby-for-primary-labelling", rule, {
+ruleTester.run("avoid-using-aria-describedby-for-primary-labelling", rule as unknown as Rule.RuleModule, {
valid: [
'<>} />>',
'<>>',
diff --git a/tests/lib/rules/badge-needs-accessible-name.js b/tests/lib/rules/badge-needs-accessible-name.test.ts
similarity index 85%
rename from tests/lib/rules/badge-needs-accessible-name.js
rename to tests/lib/rules/badge-needs-accessible-name.test.ts
index b47c1ae..fa7db40 100644
--- a/tests/lib/rules/badge-needs-accessible-name.js
+++ b/tests/lib/rules/badge-needs-accessible-name.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/badge-needs-accessible-name"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/badge-needs-accessible-name";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("badge-needs-accessible-name", rule, {
+ruleTester.run("badge-needs-accessible-name", rule as unknown as Rule.RuleModule, {
valid: [
``,
`} />`,
@@ -69,4 +58,3 @@ ruleTester.run("badge-needs-accessible-name", rule, {
}
]
});
-
diff --git a/tests/lib/rules/breadcrumb-needs-labelling.js b/tests/lib/rules/breadcrumb-needs-labelling.test.ts
similarity index 78%
rename from tests/lib/rules/breadcrumb-needs-labelling.js
rename to tests/lib/rules/breadcrumb-needs-labelling.test.ts
index 5d48c81..802981e 100644
--- a/tests/lib/rules/breadcrumb-needs-labelling.js
+++ b/tests/lib/rules/breadcrumb-needs-labelling.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/breadcrumb-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/breadcrumb-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("breadcrumb-needs-labelling", rule, {
+ruleTester.run("breadcrumb-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
// give me some code that won't trigger a warning
'',
diff --git a/tests/lib/rules/buttons/compound-button-needs-labelling.js b/tests/lib/rules/buttons/compound-button-needs-labelling.test.ts
similarity index 88%
rename from tests/lib/rules/buttons/compound-button-needs-labelling.js
rename to tests/lib/rules/buttons/compound-button-needs-labelling.test.ts
index 022f88a..6c00dca 100644
--- a/tests/lib/rules/buttons/compound-button-needs-labelling.js
+++ b/tests/lib/rules/buttons/compound-button-needs-labelling.test.ts
@@ -1,21 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-
-const rule = require("../../../../lib/rules/buttons/compound-button-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "../helper/ruleTester";
+import rule from "../../../../lib/rules/buttons/compound-button-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("compound-button-needs-labelling", rule, {
+ruleTester.run("compound-button-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
'}>',
"Example",
diff --git a/tests/lib/rules/buttons/image-button-missing-aria.js b/tests/lib/rules/buttons/image-button-missing-aria.test.ts
similarity index 91%
rename from tests/lib/rules/buttons/image-button-missing-aria.js
rename to tests/lib/rules/buttons/image-button-missing-aria.test.ts
index fa46ffa..eedca93 100644
--- a/tests/lib/rules/buttons/image-button-missing-aria.js
+++ b/tests/lib/rules/buttons/image-button-missing-aria.test.ts
@@ -1,21 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../../lib/rules/buttons/image-button-missing-aria"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "../helper/ruleTester";
+import rule from "../../../../lib/rules/buttons/image-button-missing-aria";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("image-button-missing-aria", rule, {
+ruleTester.run("image-button-missing-aria", rule as unknown as Rule.RuleModule, {
valid: [
// give me some code that won't trigger a warning
'} aria-label="Close" />',
diff --git a/tests/lib/rules/buttons/no-empty-buttons.js b/tests/lib/rules/buttons/no-empty-buttons.test.ts
similarity index 91%
rename from tests/lib/rules/buttons/no-empty-buttons.js
rename to tests/lib/rules/buttons/no-empty-buttons.test.ts
index a68e6b8..c1384fa 100644
--- a/tests/lib/rules/buttons/no-empty-buttons.js
+++ b/tests/lib/rules/buttons/no-empty-buttons.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../../lib/rules/buttons/no-empty-buttons");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "../helper/ruleTester";
+import rule from "../../../../lib/rules/buttons/no-empty-buttons";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("no-empty-buttons", rule, {
+ruleTester.run("no-empty-buttons", rule as unknown as Rule.RuleModule, {
valid: [
// sample code that won't trigger a warning
"",
diff --git a/tests/lib/rules/checkbox-needs-labelling.js b/tests/lib/rules/checkbox-needs-labelling.test.ts
similarity index 86%
rename from tests/lib/rules/checkbox-needs-labelling.js
rename to tests/lib/rules/checkbox-needs-labelling.test.ts
index 1af8ed6..90bb791 100644
--- a/tests/lib/rules/checkbox-needs-labelling.js
+++ b/tests/lib/rules/checkbox-needs-labelling.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/checkbox-needs-labelling");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/checkbox-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("checkbox-needs-labelling", rule, {
+ruleTester.run("checkbox-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
"<>>",
`<>>`,
diff --git a/tests/lib/rules/combobox-needs-labelling.js b/tests/lib/rules/combobox-needs-labelling.test.ts
similarity index 87%
rename from tests/lib/rules/combobox-needs-labelling.js
rename to tests/lib/rules/combobox-needs-labelling.test.ts
index 09aa639..cc64590 100644
--- a/tests/lib/rules/combobox-needs-labelling.js
+++ b/tests/lib/rules/combobox-needs-labelling.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/combobox-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/combobox-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("combobox-needs-labelling", rule, {
+ruleTester.run("combobox-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
// give me some code that won't trigger a warning
'',
diff --git a/tests/lib/rules/dialogbody-needs-title-content-and-actions.js b/tests/lib/rules/dialogbody-needs-title-content-and-actions.test.ts
similarity index 78%
rename from tests/lib/rules/dialogbody-needs-title-content-and-actions.js
rename to tests/lib/rules/dialogbody-needs-title-content-and-actions.test.ts
index e430c57..aaf71e3 100644
--- a/tests/lib/rules/dialogbody-needs-title-content-and-actions.js
+++ b/tests/lib/rules/dialogbody-needs-title-content-and-actions.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/dialogbody-needs-title-content-and-actions");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/dialogbody-needs-title-content-and-actions";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("dialogbody-needs-title-content-and-actions", rule, {
+ruleTester.run("dialogbody-needs-title-content-and-actions", rule as any as Rule.RuleModule, {
valid: [
`
Dialog title
@@ -39,8 +27,7 @@ ruleTester.run("dialogbody-needs-title-content-and-actions", rule, {
invalid: [
{
- code:
- `
+ code: `
Test
@@ -50,8 +37,7 @@ ruleTester.run("dialogbody-needs-title-content-and-actions", rule, {
errors: [{ messageId: "dialogBodyOneTitleOneContentOneFooter" }]
},
{
- code:
- `
+ code: `
Dialog title
@@ -61,12 +47,11 @@ ruleTester.run("dialogbody-needs-title-content-and-actions", rule, {
errors: [{ messageId: "dialogBodyOneTitleOneContentOneFooter" }]
},
{
- code:
- `
+ code: `
Dialog title
Test
`,
errors: [{ messageId: "dialogBodyOneTitleOneContentOneFooter" }]
- },
+ }
]
});
diff --git a/tests/lib/rules/dialogsurface-needs-aria.js b/tests/lib/rules/dialogsurface-needs-aria.test.ts
similarity index 88%
rename from tests/lib/rules/dialogsurface-needs-aria.js
rename to tests/lib/rules/dialogsurface-needs-aria.test.ts
index ea211e4..902e538 100644
--- a/tests/lib/rules/dialogsurface-needs-aria.js
+++ b/tests/lib/rules/dialogsurface-needs-aria.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/dialogsurface-needs-aria")
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/dialogsurface-needs-aria";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("dialogsurface-needs-aria", rule, {
+ruleTester.run("dialogsurface-needs-aria", rule as any as Rule.RuleModule, {
valid: [
`<>
My Label
@@ -71,8 +59,7 @@ ruleTester.run("dialogsurface-needs-aria", rule, {
invalid: [
{
- code:
- `<>
+ code: `<>
Dialog title
@@ -87,8 +74,7 @@ ruleTester.run("dialogsurface-needs-aria", rule, {
errors: [{ messageId: "missingAriaOnDialogSurface" }]
},
{
- code:
- `<>
+ code: `<>
diff --git a/tests/lib/rules/dropdown-needs-labelling.js b/tests/lib/rules/dropdown-needs-labelling.test.ts
similarity index 89%
rename from tests/lib/rules/dropdown-needs-labelling.js
rename to tests/lib/rules/dropdown-needs-labelling.test.ts
index bf76f54..46a9c7e 100644
--- a/tests/lib/rules/dropdown-needs-labelling.js
+++ b/tests/lib/rules/dropdown-needs-labelling.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/dropdown-needs-labelling");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/dropdown-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("dropdown-needs-labelling", rule, {
+ruleTester.run("dropdown-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
`<> {options.map((option) => ( ))}>`,
`<>>`,
diff --git a/tests/lib/rules/helper/ruleTester.ts b/tests/lib/rules/helper/ruleTester.ts
new file mode 100644
index 0000000..cff3317
--- /dev/null
+++ b/tests/lib/rules/helper/ruleTester.ts
@@ -0,0 +1,7 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+import { RuleTester } from "eslint";
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } });
+
+export default ruleTester;
diff --git a/tests/lib/rules/input-components-require-accessible-name.js b/tests/lib/rules/input-components-require-accessible-name.test.ts
similarity index 82%
rename from tests/lib/rules/input-components-require-accessible-name.js
rename to tests/lib/rules/input-components-require-accessible-name.test.ts
index c74edc5..f29bacb 100644
--- a/tests/lib/rules/input-components-require-accessible-name.js
+++ b/tests/lib/rules/input-components-require-accessible-name.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { applicableComponents } = require("../../../lib/applicableComponents/inputBasedComponents");
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/input-components-require-accessible-name");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/input-components-require-accessible-name";
+import { applicableComponents } from "../../../lib/applicableComponents/inputBasedComponents";
//------------------------------------------------------------------------------
// Helper function to generate test cases
//------------------------------------------------------------------------------
-function generateTestCases(componentName) {
+function generateTestCases(componentName: string) {
return {
valid: [
`<><${componentName} id="some-id"/>>`,
@@ -71,8 +59,7 @@ const allTestCases = applicableComponents.flatMap(component => generateTestCases
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("input-missing-label", rule, {
+ruleTester.run("input-missing-label", rule as unknown as Rule.RuleModule, {
valid: allTestCases.flatMap(test => test.valid),
invalid: allTestCases.flatMap(test => test.invalid)
});
diff --git a/tests/lib/rules/label-utils.test.js b/tests/lib/rules/label-utils.test.ts
similarity index 91%
rename from tests/lib/rules/label-utils.test.js
rename to tests/lib/rules/label-utils.test.ts
index 4aadcff..8c2017b 100644
--- a/tests/lib/rules/label-utils.test.js
+++ b/tests/lib/rules/label-utils.test.ts
@@ -1,9 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-const chai = require("chai");
-const assert = chai.assert;
-const { isInsideLabelTag } = require("../../../lib/util/labelUtils");
+import chai from "chai";
+import { isInsideLabelTag } from "../../../lib/util/labelUtils";
+
+const assert: Chai.AssertStatic = chai.assert;
console.log(assert);
describe("isInsideLabelTag", function () {
diff --git a/tests/lib/rules/link-missing-labelling.js b/tests/lib/rules/link-missing-labelling.test.ts
similarity index 87%
rename from tests/lib/rules/link-missing-labelling.js
rename to tests/lib/rules/link-missing-labelling.test.ts
index 0bc6a94..f094522 100644
--- a/tests/lib/rules/link-missing-labelling.js
+++ b/tests/lib/rules/link-missing-labelling.test.ts
@@ -1,26 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
-const { linkBasedComponents } = require("../../../lib/applicableComponents/linkBasedComponents");
-const RuleTester = require("eslint").RuleTester;
-const rule = require("../../../lib/rules/link-missing-labelling");
-const { fluentImageComponents, imageDomNodes } = require("../../../lib/applicableComponents/imageBasedComponents");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import { linkBasedComponents } from "../../../lib/applicableComponents/linkBasedComponents";
+import rule from "../../../lib/rules/link-missing-labelling";
+import { fluentImageComponents, imageDomNodes } from "../../../lib/applicableComponents/imageBasedComponents";
//------------------------------------------------------------------------------
// Helper function to generate test cases with abstracted Link and Image components
//------------------------------------------------------------------------------
-function generateTestCases(componentName, imageName) {
+function generateTestCases(componentName: string, imageName: string) {
return {
valid: [
// Valid cases
@@ -69,7 +59,7 @@ function generateTestCases(componentName, imageName) {
//------------------------------------------------------------------------------
// Collect all test cases for link components and image components
function generateAllTestCases() {
- const testSets = [];
+ const testSets: any[] = [];
// For each link-based component, generate test cases for each fluent image component
linkBasedComponents.forEach(linkComponent => {
@@ -91,10 +81,9 @@ const allTestCases = generateAllTestCases();
//------------------------------------------------------------------------------
// Run tests for each test set
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
allTestCases.forEach((testCaseSet, index) => {
- ruleTester.run(`link-missing-labelling test set ${index + 1}`, rule, {
+ ruleTester.run(`link-missing-labelling test set ${index + 1}`, rule as unknown as Rule.RuleModule, {
valid: testCaseSet.valid,
invalid: testCaseSet.invalid
});
diff --git a/tests/lib/rules/menu-item-needs-labelling.js b/tests/lib/rules/menu-item-needs-labelling.test.ts
similarity index 82%
rename from tests/lib/rules/menu-item-needs-labelling.js
rename to tests/lib/rules/menu-item-needs-labelling.test.ts
index a34e76f..c0ea50d 100644
--- a/tests/lib/rules/menu-item-needs-labelling.js
+++ b/tests/lib/rules/menu-item-needs-labelling.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/menu-item-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/menu-item-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("menuitem-needs-labelling", rule, {
+ruleTester.run("menuitem-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
// Valid cases
'} onClick={handleClick}>',
diff --git a/tests/lib/rules/no-empty-components.js b/tests/lib/rules/no-empty-components.test.ts
similarity index 90%
rename from tests/lib/rules/no-empty-components.js
rename to tests/lib/rules/no-empty-components.test.ts
index 87864df..e3d7667 100644
--- a/tests/lib/rules/no-empty-components.js
+++ b/tests/lib/rules/no-empty-components.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/no-empty-components"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/no-empty-components";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("no-empty-components", rule, {
+ruleTester.run("no-empty-components", rule as unknown as Rule.RuleModule, {
valid: [
"Hello",
"",
diff --git a/tests/lib/rules/prefer-aria-over-title-attribute.test.ts b/tests/lib/rules/prefer-aria-over-title-attribute.test.ts
index e1c8dbc..7513074 100644
--- a/tests/lib/rules/prefer-aria-over-title-attribute.test.ts
+++ b/tests/lib/rules/prefer-aria-over-title-attribute.test.ts
@@ -5,15 +5,15 @@
// Requirements
//------------------------------------------------------------------------------
-import { RuleTester } from "eslint";
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
import rule from "../../../lib/rules/prefer-aria-over-title-attribute";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } });
-ruleTester.run("prefer-aria-over-title-attribute", rule as any, {
+ruleTester.run("prefer-aria-over-title-attribute", rule as unknown as Rule.RuleModule, {
valid: [
// give me some code that won't trigger a warning
'} aria-label="Close" />',
diff --git a/tests/lib/rules/progressbar-needs-labelling.js b/tests/lib/rules/progressbar-needs-labelling.test.ts
similarity index 94%
rename from tests/lib/rules/progressbar-needs-labelling.js
rename to tests/lib/rules/progressbar-needs-labelling.test.ts
index fbcef8b..a46e26c 100644
--- a/tests/lib/rules/progressbar-needs-labelling.js
+++ b/tests/lib/rules/progressbar-needs-labelling.test.ts
@@ -1,21 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/progressbar-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/progressbar-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("progressbar-needs-labelling", rule, {
+ruleTester.run("progressbar-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
`>",
`<>>`,
diff --git a/tests/lib/rules/radioGroup-missing-label.js b/tests/lib/rules/radioGroup-missing-label.test.ts
similarity index 86%
rename from tests/lib/rules/radioGroup-missing-label.js
rename to tests/lib/rules/radioGroup-missing-label.test.ts
index 0e325f0..59cddae 100644
--- a/tests/lib/rules/radioGroup-missing-label.js
+++ b/tests/lib/rules/radioGroup-missing-label.test.ts
@@ -1,31 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const RuleTester = require("eslint").RuleTester;
-
-const rule = require("../../../lib/rules/radiogroup-missing-label");
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/radiogroup-missing-label";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("radioGroup-missing-label", rule, {
+ruleTester.run("radioGroup-missing-label", rule as unknown as Rule.RuleModule, {
valid: [
"<>>",
`<>>`,
diff --git a/tests/lib/rules/spin-button-needs-labelling.js b/tests/lib/rules/spin-button-needs-labelling.test.ts
similarity index 91%
rename from tests/lib/rules/spin-button-needs-labelling.js
rename to tests/lib/rules/spin-button-needs-labelling.test.ts
index df55155..60cc726 100644
--- a/tests/lib/rules/spin-button-needs-labelling.js
+++ b/tests/lib/rules/spin-button-needs-labelling.test.ts
@@ -1,21 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/spin-button-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/spin-button-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("spin-button-needs-labelling", rule, {
+ruleTester.run("spin-button-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
"<>>",
`<>>`,
diff --git a/tests/lib/rules/spin-button-unrecommended-labelling.js b/tests/lib/rules/spin-button-unrecommended-labelling.test.ts
similarity index 78%
rename from tests/lib/rules/spin-button-unrecommended-labelling.js
rename to tests/lib/rules/spin-button-unrecommended-labelling.test.ts
index b01691e..bacf5b2 100644
--- a/tests/lib/rules/spin-button-unrecommended-labelling.js
+++ b/tests/lib/rules/spin-button-unrecommended-labelling.test.ts
@@ -1,21 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/spin-button-unrecommended-labelling"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/spin-button-unrecommended-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("spin-button-unrecommended-labelling", rule, {
+ruleTester.run("spin-button-unrecommended-labelling", rule as unknown as Rule.RuleModule, {
valid: [],
invalid: [
{
diff --git a/tests/lib/rules/spinner-needs-labelling.js b/tests/lib/rules/spinner-needs-labelling.test.ts
similarity index 82%
rename from tests/lib/rules/spinner-needs-labelling.js
rename to tests/lib/rules/spinner-needs-labelling.test.ts
index c6a55e9..2eeb622 100644
--- a/tests/lib/rules/spinner-needs-labelling.js
+++ b/tests/lib/rules/spinner-needs-labelling.test.ts
@@ -1,26 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/spinner-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/spinner-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("spinner-needs-labelling", rule, {
+ruleTester.run("spinner-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
``,
``,
``,
- ``,
+ ``
],
invalid: [
{
@@ -44,9 +42,8 @@ ruleTester.run("spinner-needs-labelling", rule, {
errors: [{ messageId: "noUnlabelledSpinner" }]
},
{
- code : ``,
+ code: ``,
errors: [{ messageId: "noUnlabelledSpinner" }]
}
]
});
-
diff --git a/tests/lib/rules/switch-needs-labelling.js b/tests/lib/rules/switch-needs-labelling.test.ts
similarity index 90%
rename from tests/lib/rules/switch-needs-labelling.js
rename to tests/lib/rules/switch-needs-labelling.test.ts
index 303d5c5..4ff1440 100644
--- a/tests/lib/rules/switch-needs-labelling.js
+++ b/tests/lib/rules/switch-needs-labelling.test.ts
@@ -1,21 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/switch-needs-labelling"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/switch-needs-labelling";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("switch-needs-labelling", rule, {
+ruleTester.run("switch-needs-labelling", rule as unknown as Rule.RuleModule, {
valid: [
"<>>",
``,
diff --git a/tests/lib/rules/toolbar-missing-aria.js b/tests/lib/rules/toolbar-missing-aria.test.ts
similarity index 89%
rename from tests/lib/rules/toolbar-missing-aria.js
rename to tests/lib/rules/toolbar-missing-aria.test.ts
index 06b8b12..8967f62 100644
--- a/tests/lib/rules/toolbar-missing-aria.js
+++ b/tests/lib/rules/toolbar-missing-aria.test.ts
@@ -1,21 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/toolbar-missing-aria"),
- RuleTester = require("eslint").RuleTester;
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/toolbar-missing-aria";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("toolbar-missing-aria", rule, {
+ruleTester.run("toolbar-missing-aria", rule as unknown as Rule.RuleModule, {
valid: [
'',
'',
diff --git a/tests/lib/rules/tooltip-not-recommended.js b/tests/lib/rules/tooltip-not-recommended.test.ts
similarity index 74%
rename from tests/lib/rules/tooltip-not-recommended.js
rename to tests/lib/rules/tooltip-not-recommended.test.ts
index 4f485bf..5b73db9 100644
--- a/tests/lib/rules/tooltip-not-recommended.js
+++ b/tests/lib/rules/tooltip-not-recommended.test.ts
@@ -1,30 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-"use strict";
-
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
-const rule = require("../../../lib/rules/tooltip-not-recommended"),
- RuleTester = require("eslint").RuleTester;
-
-RuleTester.setDefaultConfig({
- parserOptions: {
- ecmaVersion: 6,
- ecmaFeatures: {
- jsx: true
- }
- }
-});
+import { Rule } from "eslint";
+import ruleTester from "./helper/ruleTester";
+import rule from "../../../lib/rules/tooltip-not-recommended";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
-const ruleTester = new RuleTester();
-ruleTester.run("tooltip-not-recommended", rule, {
+ruleTester.run("tooltip-not-recommended", rule as unknown as Rule.RuleModule, {
valid: [
// Valid cases
'
',