no-access-key

Try in Playground
jsx-a11y

oscar143

Best PracticeInformational

0

No tags

No CWE or CVE

jsx-a11y/no-access-key

Enforce no accessKey prop on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screenreaders and keyboard-only users create accessibility complications so to avoid complications, access keys should not be used.

References

  • WebAIM

Resources

Ast Rule: html element


no-access-key

How to write a rule
const TYPES = {
  string: getPropStringValue,
  sequence: getPropSequenceValue,
  array: getPropArrayValue,
  object: getPropObjectValue,
  object_element: getPropObjectValue,
  functiondefinition: () => {},
};

function getTag(node) {
  if (node && node.tag) {
    return node.tag.value;
  }
}

function getProp(attributes = [], prop = "") {
  if (!prop) return;

  return attributes.find((attribute) => {
    if (attribute && attribute.name && attribute.name.value) {
      return attribute.name.value === prop;
    }
  });
}

function getPropStringValue(value) {
  if (value.value === "true") {
    return true;
  }

  if (value.value === "false") {
    return false;
  }

  return value.value.replace(/^\"/g, "").replace(/\"$/g, "");
}

function getPropArrayValue(value) {
  const array = [];
  const arrayElements = value.elements;

  if (arrayElements.length) {
    for (const element of arrayElements) {
      array.push(TYPES[element.astType](element));
    }
  }

  return array;
}

function getPropObjectValue(value) {
  const object = {};
  const objectElements = value.elements;

  if (objectElements.length) {
    for (const element of objectElements) {
      object[element.name.value] = TYPES[element.value.astType](element.value);
    }
  }

  return object;
}

function getPropSequenceValue(value) {
  if (value.elements.length) {
    const element = value.elements[0];

    if (element) {
      return TYPES[element.astType](element);
    }
  }
}

function extractValue(attribute, extractor) {
  if (attribute) {
    // Null valued attributes imply truthiness.
    // For example: <div aria-hidden />
    if (attribute.value === null) return true;

    return extractor(attribute.value);
  }
}

function getValue(value) {
  return TYPES[value.astType](value);
}

function getPropValue(attribute) {
  return extractValue(attribute, getValue);
}

function propHasValue(attribute) {
  const value = getPropValue(attribute);

  if (typeof value !== "boolean") {
    return !!value;
  }

  return false;
}

function visit(node, filename, code) {
  const accessKey = getProp(node.attributes, 'accessKey');
  const accessKeyValue = getPropValue(accessKey);
  console.log(accessKey, accessKeyValue)
  if (accessKey && accessKeyValue) {
    const error = buildError(
      node.start.line,
      node.start.col,
      node.end.line,
      node.end.col,
      'Enforce that the `accessKey` prop is not used on any element to avoid complications with keyboard commands used by a screenreader.',
      "INFO",
      "BEST_PRACTICES"
    );

    addError(error);
  }
}

bad.jsx

Expected test result: has error

<div accessKey="h" />

good.jsx

Expected test result: no error

<div />

good.jsx

Expected test result: no error

<div />

good.jsx

Expected test result: no error

good.jsx

Expected test result: no error

Add comment

Log in to add a comment


    Be the first one to leave a comment!

Codiga Logo
Codiga Hub
  • Rulesets
  • Playground
  • Snippets
  • Cookbooks
soc-2 icon

We are SOC-2 Compliance Certified

G2 high performer medal

Codiga – All rights reserved 2022.