Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User/aubreyquinn/bug fix #135

Merged
merged 3 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/applicableComponents/dropdownBasedComponents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

const dropdownBasedComponents = ["Dropdown"];

export { dropdownBasedComponents };
3 changes: 2 additions & 1 deletion lib/rules/dropdown-needs-labelling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { elementType } from "jsx-ast-utils";
import { hasAssociatedLabelViaAriaLabelledBy, hasAssociatedLabelViaHtmlFor, isInsideLabelTag } from "../util/labelUtils";
import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
import { JSXOpeningElement } from "estree-jsx";
import { dropdownBasedComponents } from "../applicableComponents/dropdownBasedComponents";

//------------------------------------------------------------------------------
// Rule Definition
Expand Down Expand Up @@ -34,7 +35,7 @@ const rule = ESLintUtils.RuleCreator.withoutDocs({
// visitor functions for different types of nodes
JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a Dropdown, return
if (elementType(node as JSXOpeningElement) !== "Dropdown") {
if (!dropdownBasedComponents.includes(elementType(node as unknown as JSXOpeningElement))) {
return;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/rules/visual-label-better-than-aria-suggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { hasNonEmptyProp } from "../util/hasNonEmptyProp";
import { applicableComponents } from "../applicableComponents/inputBasedComponents";
import { dropdownBasedComponents } from "../applicableComponents/dropdownBasedComponents";
import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
import { elementType } from "jsx-ast-utils";
import { JSXOpeningElement } from "estree-jsx";
Expand Down Expand Up @@ -34,7 +35,7 @@ const rule = ESLintUtils.RuleCreator.withoutDocs({
// visitor functions for different types of nodes
JSXOpeningElement(node: TSESTree.JSXOpeningElement) {
// if it is not a listed component, return
if (!applicableComponents.includes(elementType(node as unknown as JSXOpeningElement))) {
if (![dropdownBasedComponents, ...applicableComponents].includes(elementType(node as unknown as JSXOpeningElement))) {
return;
}

Expand Down
18 changes: 11 additions & 7 deletions lib/util/hasLabelledChildImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,13 @@ const isJSXIdentifierWithName = (name: TSESTree.JSXTagNameExpression, validNames
* @returns boolean
*/
const hasLabelledChildImage = (node: TSESTree.JSXElement): boolean => {
console.log("node::", node);
if (!node.children || node.children.length === 0) {
return false;
}

return flattenChildren(node).some(child => {
if (child.type === "JSXElement" && isJSXIdentifierWithName(child.openingElement.name, mergedImageComponents)) {
const attributes = child.openingElement.attributes;
console.log("attributes::", attributes);
console.log("hasAccessibilityAttributes(attributes)", hasAccessibilityAttributes(attributes));
console.log("!isImageHidden(attributes)", !isImageHidden(attributes));

return !isImageHidden(attributes) && hasAccessibilityAttributes(attributes);
}
return false;
Expand Down Expand Up @@ -68,23 +63,32 @@ const isImageHidden = (attributes: TSESTree.JSXOpeningElement["attributes"]): bo
return true;
}

// Check if the image has an `aria-label` attribute with a non-empty value
// Check if the image has an `aria-label` or `aria-labelledby` attribute with a non-empty value
const ariaLabelProp = getProp(attributes as unknown as JSXOpeningElement["attributes"], "aria-label");
const ariaLabelledbyProp = getProp(attributes as unknown as JSXOpeningElement["attributes"], "aria-labelledby");

if (ariaLabelProp) {
const ariaLabelValue = getPropValue(ariaLabelProp);
if (ariaLabelValue) {
return false; // If `aria-label` is present and has a value, the image is not hidden
}
}

if (ariaLabelledbyProp) {
const ariaLabelledbyValue = getPropValue(ariaLabelledbyProp);
if (ariaLabelledbyValue) {
return false; // If `aria-labelledby` is present and has a value, the image is not hidden
}
}

// Check if the image has an `alt` attribute and return true if the `alt` value is falsy
const altProp = getProp(attributes as unknown as JSXOpeningElement["attributes"], "alt");
if (altProp) {
const altValue = getPropValue(altProp);
return !altValue; // Returns true if `altValue` is falsy (e.g., empty string, null, or undefined)
}

return true; // If neither `alt` nor `aria-label` is present, consider the image hidden
return true; // If neither `alt`, `aria-label`, nor `aria-labelledby` is present, consider the image hidden
};

export { hasLabelledChildImage, isImageHidden, hasAccessibilityAttributes, isJSXIdentifierWithName };
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/eslint-plugin-fluentui-jsx-a11y",
"version": "3.0.0-alpha.1",
"version": "3.0.0-alpha.2",
"description": "Static AST checker for accessibility rules on FluentUI JSX elements.",
"keywords": [
"eslint",
Expand Down
Loading