From a2ad5347fa6f6029390b08a3fbed8b46f5b0d661 Mon Sep 17 00:00:00 2001 From: nikitasingla Date: Wed, 13 Mar 2024 09:33:29 +0530 Subject: [PATCH] added labelling for breadcrumb v9 --- COVERAGE.md | 1 + README.md | 1 + docs/rules/breadcrumb-needs-labelling-v9.md | 35 +++++++++++ lib/rules/breadcrumb-needs-labelling-v9.js | 59 +++++++++++++++++++ lib/rules/index.js | 4 +- .../rules/breadcrumb-needs-labelling-v9.js | 46 +++++++++++++++ 6 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 docs/rules/breadcrumb-needs-labelling-v9.md create mode 100644 lib/rules/breadcrumb-needs-labelling-v9.js create mode 100644 tests/lib/rules/breadcrumb-needs-labelling-v9.js diff --git a/COVERAGE.md b/COVERAGE.md index 4fd4c56..298447b 100644 --- a/COVERAGE.md +++ b/COVERAGE.md @@ -42,3 +42,4 @@ We currently cover the following components: - [x] TextArea - [x] Toolbar - [] Tooltip + - [x] Breadcrumb diff --git a/README.md b/README.md index e43f21d..34a9f5c 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ Any use of third-party trademarks or logos are subject to those third-party's po | Name                                          | Description | 🔧 | | :----------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :- | +| [breadcrumb-needs-labelling-v9](docs/rules/breadcrumb-needs-labelling-v9.md) | All interactive elements must have an accessible name | | | [checkbox-needs-labelling-v9](docs/rules/checkbox-needs-labelling-v9.md) | Accessibility: Checkbox without label must have an accessible and visual label: aria-labelledby | | | [combobox-needs-labelling-v9](docs/rules/combobox-needs-labelling-v9.md) | All interactive elements must have an accessible name | | | [icon-text-content-button-does-not-need-aria](docs/rules/icon-text-content-button-does-not-need-aria.md) | Accessibility: an image button with text content does not need aria labelling. The button already has an accessible name and the aria-label or aria-labelledby will override the text content for screen reader users. | | diff --git a/docs/rules/breadcrumb-needs-labelling-v9.md b/docs/rules/breadcrumb-needs-labelling-v9.md new file mode 100644 index 0000000..934a75a --- /dev/null +++ b/docs/rules/breadcrumb-needs-labelling-v9.md @@ -0,0 +1,35 @@ +# All interactive elements must have an accessible name (`@microsoft/fluentui-jsx-a11y/breadcrumb-needs-labelling-v9`) + + + +Provide labels to identify all form controls, including text fields, checkboxes, radio buttons, and drop-down menus. In most cases, this is done by using the label element. + + + +All interactive elements must have an accessible name. + +## Rule Details + +This rule aims to... + +Examples of **incorrect** code for this rule: + +```jsx +
+
+ +``` + +Examples of **correct** code for this rule: + +```jsx + +
+
+ +``` + diff --git a/lib/rules/breadcrumb-needs-labelling-v9.js b/lib/rules/breadcrumb-needs-labelling-v9.js new file mode 100644 index 0000000..d817bb7 --- /dev/null +++ b/lib/rules/breadcrumb-needs-labelling-v9.js @@ -0,0 +1,59 @@ +// 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 } = require("../util/labelUtils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + // possible error messages for the rule + messages: { + noUnlabelledBreadcrumb: "Accessibility: Breadcrumb must have an accessible label" + }, + // "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: { + description: "All interactive elements must have an accessible name", + 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) { + // if it is not a Breadcrumb, return + if (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 + isInsideLabelTag(context) || // wrapped in label + hasAssociatedLabelViaAriaLabelledBy(node, context) // aria-labelledby + ) { + return; + } + + // if it has no visual labelling, report error + context.report({ + node, + messageId: `noUnlabelledBreadcrumb` + }); + } + }; + } +}; + diff --git a/lib/rules/index.js b/lib/rules/index.js index a46ba7c..e963802 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -16,5 +16,7 @@ module.exports = { "image-button-missing-aria-v9": require("./image-button-missing-aria-v9"), "toolbar-missing-aria-v9": require("./toolbar-missing-aria-v9"), "combobox-needs-labelling-v9": require("./combobox-needs-labelling-v9"), - "no-empty-components-v9": require("./no-empty-components-v9") + "no-empty-components-v9": require("./no-empty-components-v9"), + "breadcrumb-needs-labelling-v9": require("./breadcrumb-needs-labelling-v9") }; + diff --git a/tests/lib/rules/breadcrumb-needs-labelling-v9.js b/tests/lib/rules/breadcrumb-needs-labelling-v9.js new file mode 100644 index 0000000..d37cdbd --- /dev/null +++ b/tests/lib/rules/breadcrumb-needs-labelling-v9.js @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require("../../../lib/rules/breadcrumb-needs-labelling-v9"), + RuleTester = require("eslint").RuleTester; + +RuleTester.setDefaultConfig({ + parserOptions: { + ecmaVersion: 6, + ecmaFeatures: { + jsx: true + } + } +}); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester(); +ruleTester.run("breadcrumb-needs-labelling-v9", rule, { + valid: [ + // give me some code that won't trigger a warning + '', + "", + '
', + '
' + ], + invalid: [ + { + code: '
', + errors: [{ messageId: "noUnlabelledBreadcrumb" }] + }, + { + code: "", + errors: [{ messageId: "noUnlabelledBreadcrumb" }] + } + ] +}); +