diff --git a/src/__tests__/ariaAttributes.js b/src/__tests__/ariaAttributes.js
index 1ceb210d..498f21b3 100644
--- a/src/__tests__/ariaAttributes.js
+++ b/src/__tests__/ariaAttributes.js
@@ -36,6 +36,28 @@ test('`expanded` throws on unsupported roles', () => {
)
})
+test('`busy` throws on unsupported roles', () => {
+ const {getByRole} = render(
+ `
Hello, Dave!
`,
+ )
+ expect(() =>
+ getByRole('none', {busy: true}),
+ ).toThrowErrorMatchingInlineSnapshot(
+ `"aria-busy" is not supported on role "none".`,
+ )
+})
+
+test('`busy: true|false` matches `busy` regions', () => {
+ const {getByRole} = renderIntoDocument(
+ ``,
+ )
+ expect(getByRole('log', {busy: true})).toBeInTheDocument()
+ expect(getByRole('log', {busy: false})).toBeInTheDocument()
+})
+
test('`checked: true|false` matches `checked` checkboxes', () => {
const {getByRole} = renderIntoDocument(
`
diff --git a/src/queries/role.ts b/src/queries/role.ts
index f8e976a4..5655e2ba 100644
--- a/src/queries/role.ts
+++ b/src/queries/role.ts
@@ -9,6 +9,7 @@ import {
} from 'aria-query'
import {
computeAriaSelected,
+ computeAriaBusy,
computeAriaChecked,
computeAriaPressed,
computeAriaCurrent,
@@ -42,6 +43,7 @@ const queryAllByRole: AllByRole = (
description,
queryFallbacks = false,
selected,
+ busy,
checked,
pressed,
current,
@@ -61,6 +63,16 @@ const queryAllByRole: AllByRole = (
}
}
+ if (busy !== undefined) {
+ // guard against unknown roles
+ if (
+ allRoles.get(role as ARIARoleDefinitionKey)?.props['aria-busy'] ===
+ undefined
+ ) {
+ throw new Error(`"aria-busy" is not supported on role "${role}".`)
+ }
+ }
+
if (checked !== undefined) {
// guard against unknown roles
if (
@@ -152,6 +164,9 @@ const queryAllByRole: AllByRole = (
if (selected !== undefined) {
return selected === computeAriaSelected(element)
}
+ if (busy !== undefined) {
+ return busy === computeAriaBusy(element)
+ }
if (checked !== undefined) {
return checked === computeAriaChecked(element)
}
diff --git a/src/role-helpers.js b/src/role-helpers.js
index 500bcdd2..7a8f3c82 100644
--- a/src/role-helpers.js
+++ b/src/role-helpers.js
@@ -240,6 +240,15 @@ function computeAriaSelected(element) {
return checkBooleanAttribute(element, 'aria-selected')
}
+/**
+ * @param {Element} element -
+ * @returns {boolean} -
+ */
+function computeAriaBusy(element) {
+ // https://www.w3.org/TR/wai-aria-1.1/#aria-busy
+ return element.getAttribute('aria-busy') === 'true'
+}
+
/**
* @param {Element} element -
* @returns {boolean | undefined} - false/true if (not)checked, undefined if not checked-able
@@ -333,6 +342,7 @@ export {
prettyRoles,
isInaccessible,
computeAriaSelected,
+ computeAriaBusy,
computeAriaChecked,
computeAriaPressed,
computeAriaCurrent,
diff --git a/types/queries.d.ts b/types/queries.d.ts
index cea02365..c6568abf 100644
--- a/types/queries.d.ts
+++ b/types/queries.d.ts
@@ -80,6 +80,11 @@ export interface ByRoleOptions {
* selected in the accessibility tree, i.e., `aria-selected="true"`
*/
selected?: boolean
+ /**
+ * If true only includes elements in the query set that are marked as
+ * busy in the accessibility tree, i.e., `aria-busy="true"`
+ */
+ busy?: boolean
/**
* If true only includes elements in the query set that are marked as
* checked in the accessibility tree, i.e., `aria-checked="true"`