diff --git a/.changeset/rare-cycles-nail.md b/.changeset/rare-cycles-nail.md new file mode 100644 index 00000000..09c8e778 --- /dev/null +++ b/.changeset/rare-cycles-nail.md @@ -0,0 +1,5 @@ +--- +"dom-accessibility-api": minor +--- + +add an `isDisabled` function to check if elements are disabled or not diff --git a/sources/__tests__/is-disabled.js b/sources/__tests__/is-disabled.js new file mode 100644 index 00000000..9c6f88be --- /dev/null +++ b/sources/__tests__/is-disabled.js @@ -0,0 +1,20 @@ +import { isDisabled } from "../is-disabled"; +import { cleanup, renderIntoDocument } from "./helpers/test-utils"; + +describe("isDisabled", () => { + afterEach(cleanup); + test.each([ + ["", false], + ['', true], + ['', true], + ["", true], + ['', false], + ["
", false], + ])("markup #%#", (markup, expectedIsDisabled) => { + const container = renderIntoDocument(markup); + expect(container).not.toBe(null); + + const testNode = container.querySelector("[data-test]"); + expect(isDisabled(testNode)).toBe(expectedIsDisabled); + }); +}); diff --git a/sources/index.ts b/sources/index.ts index e26d4f40..6b0711ab 100644 --- a/sources/index.ts +++ b/sources/index.ts @@ -2,3 +2,4 @@ export { computeAccessibleDescription } from "./accessible-description"; export { computeAccessibleName } from "./accessible-name"; export { default as getRole } from "./getRole"; export * from "./is-inaccessible"; +export { isDisabled } from "./is-disabled"; diff --git a/sources/is-disabled.ts b/sources/is-disabled.ts new file mode 100644 index 00000000..a201f2aa --- /dev/null +++ b/sources/is-disabled.ts @@ -0,0 +1,27 @@ +import { getLocalName } from "./getRole"; + +const elementsSupportingDisabledAttribute = new Set([ + "button", + "fieldset", + "input", + "optgroup", + "option", + "select", + "textarea", +]); + +/** + * Check if an element is disabled + * https://www.w3.org/TR/html-aam-1.0/#html-attribute-state-and-property-mappings + * https://www.w3.org/TR/wai-aria-1.1/#aria-disabled + * + * @param element + * @returns {boolean} true if disabled, otherwise false + */ +export function isDisabled(element: Element): boolean { + const localName = getLocalName(element); + return elementsSupportingDisabledAttribute.has(localName) && + element.hasAttribute("disabled") + ? true + : element.getAttribute("aria-disabled") === "true"; +}