Skip to content

Commit 8c40a21

Browse files
authored
feat(ByRole): Allow filter by busy state (#1222)
1 parent fb069c9 commit 8c40a21

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

src/__tests__/ariaAttributes.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,28 @@ test('`expanded` throws on unsupported roles', () => {
3636
)
3737
})
3838

39+
test('`busy` throws on unsupported roles', () => {
40+
const {getByRole} = render(
41+
`<div aria-busy="true" role="none">Hello, Dave!</div>`,
42+
)
43+
expect(() =>
44+
getByRole('none', {busy: true}),
45+
).toThrowErrorMatchingInlineSnapshot(
46+
`"aria-busy" is not supported on role "none".`,
47+
)
48+
})
49+
50+
test('`busy: true|false` matches `busy` regions', () => {
51+
const {getByRole} = renderIntoDocument(
52+
`<div>
53+
<div role="log" aria-busy="true" />
54+
<div role="log" aria-busy="false" />
55+
</div>`,
56+
)
57+
expect(getByRole('log', {busy: true})).toBeInTheDocument()
58+
expect(getByRole('log', {busy: false})).toBeInTheDocument()
59+
})
60+
3961
test('`checked: true|false` matches `checked` checkboxes', () => {
4062
const {getByRole} = renderIntoDocument(
4163
`<div>

src/queries/role.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from 'aria-query'
1010
import {
1111
computeAriaSelected,
12+
computeAriaBusy,
1213
computeAriaChecked,
1314
computeAriaPressed,
1415
computeAriaCurrent,
@@ -42,6 +43,7 @@ const queryAllByRole: AllByRole = (
4243
description,
4344
queryFallbacks = false,
4445
selected,
46+
busy,
4547
checked,
4648
pressed,
4749
current,
@@ -61,6 +63,16 @@ const queryAllByRole: AllByRole = (
6163
}
6264
}
6365

66+
if (busy !== undefined) {
67+
// guard against unknown roles
68+
if (
69+
allRoles.get(role as ARIARoleDefinitionKey)?.props['aria-busy'] ===
70+
undefined
71+
) {
72+
throw new Error(`"aria-busy" is not supported on role "${role}".`)
73+
}
74+
}
75+
6476
if (checked !== undefined) {
6577
// guard against unknown roles
6678
if (
@@ -152,6 +164,9 @@ const queryAllByRole: AllByRole = (
152164
if (selected !== undefined) {
153165
return selected === computeAriaSelected(element)
154166
}
167+
if (busy !== undefined) {
168+
return busy === computeAriaBusy(element)
169+
}
155170
if (checked !== undefined) {
156171
return checked === computeAriaChecked(element)
157172
}

src/role-helpers.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,15 @@ function computeAriaSelected(element) {
240240
return checkBooleanAttribute(element, 'aria-selected')
241241
}
242242

243+
/**
244+
* @param {Element} element -
245+
* @returns {boolean} -
246+
*/
247+
function computeAriaBusy(element) {
248+
// https://www.w3.org/TR/wai-aria-1.1/#aria-busy
249+
return element.getAttribute('aria-busy') === 'true'
250+
}
251+
243252
/**
244253
* @param {Element} element -
245254
* @returns {boolean | undefined} - false/true if (not)checked, undefined if not checked-able
@@ -333,6 +342,7 @@ export {
333342
prettyRoles,
334343
isInaccessible,
335344
computeAriaSelected,
345+
computeAriaBusy,
336346
computeAriaChecked,
337347
computeAriaPressed,
338348
computeAriaCurrent,

types/queries.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ export interface ByRoleOptions {
8080
* selected in the accessibility tree, i.e., `aria-selected="true"`
8181
*/
8282
selected?: boolean
83+
/**
84+
* If true only includes elements in the query set that are marked as
85+
* busy in the accessibility tree, i.e., `aria-busy="true"`
86+
*/
87+
busy?: boolean
8388
/**
8489
* If true only includes elements in the query set that are marked as
8590
* checked in the accessibility tree, i.e., `aria-checked="true"`

0 commit comments

Comments
 (0)