@@ -2,7 +2,11 @@ import {
2
2
computeAccessibleDescription ,
3
3
computeAccessibleName ,
4
4
} from 'dom-accessibility-api'
5
- import { roles as allRoles , roleElements } from 'aria-query'
5
+ import {
6
+ roles as allRoles ,
7
+ roleElements ,
8
+ ARIARoleDefinitionKey ,
9
+ } from 'aria-query'
6
10
import {
7
11
computeAriaSelected ,
8
12
computeAriaChecked ,
@@ -17,6 +21,17 @@ import {
17
21
} from '../role-helpers'
18
22
import { wrapAllByQueryWithSuggestion } from '../query-helpers'
19
23
import { checkContainerType } from '../helpers'
24
+ import {
25
+ AllByRole ,
26
+ ByRoleMatcher ,
27
+ ByRoleOptions ,
28
+ GetErrorFunction ,
29
+ Matcher ,
30
+ MatcherFunction ,
31
+ MatcherOptions ,
32
+ NormalizerFn ,
33
+ } from '../../types'
34
+
20
35
import {
21
36
buildQueries ,
22
37
fuzzyMatches ,
@@ -25,7 +40,7 @@ import {
25
40
matches ,
26
41
} from './all-utils'
27
42
28
- function queryAllByRole (
43
+ const queryAllByRole : AllByRole = (
29
44
container ,
30
45
role ,
31
46
{
@@ -44,28 +59,37 @@ function queryAllByRole(
44
59
level,
45
60
expanded,
46
61
} = { } ,
47
- ) {
62
+ ) => {
48
63
checkContainerType ( container )
49
64
const matcher = exact ? matches : fuzzyMatches
50
65
const matchNormalizer = makeNormalizer ( { collapseWhitespace, trim, normalizer} )
51
66
52
67
if ( selected !== undefined ) {
53
68
// guard against unknown roles
54
- if ( allRoles . get ( role ) ?. props [ 'aria-selected' ] === undefined ) {
69
+ if (
70
+ allRoles . get ( role as ARIARoleDefinitionKey ) ?. props [ 'aria-selected' ] ===
71
+ undefined
72
+ ) {
55
73
throw new Error ( `"aria-selected" is not supported on role "${ role } ".` )
56
74
}
57
75
}
58
76
59
77
if ( checked !== undefined ) {
60
78
// guard against unknown roles
61
- if ( allRoles . get ( role ) ?. props [ 'aria-checked' ] === undefined ) {
79
+ if (
80
+ allRoles . get ( role as ARIARoleDefinitionKey ) ?. props [ 'aria-checked' ] ===
81
+ undefined
82
+ ) {
62
83
throw new Error ( `"aria-checked" is not supported on role "${ role } ".` )
63
84
}
64
85
}
65
86
66
87
if ( pressed !== undefined ) {
67
88
// guard against unknown roles
68
- if ( allRoles . get ( role ) ?. props [ 'aria-pressed' ] === undefined ) {
89
+ if (
90
+ allRoles . get ( role as ARIARoleDefinitionKey ) ?. props [ 'aria-pressed' ] ===
91
+ undefined
92
+ ) {
69
93
throw new Error ( `"aria-pressed" is not supported on role "${ role } ".` )
70
94
}
71
95
}
@@ -75,7 +99,10 @@ function queryAllByRole(
75
99
// guard against unknown roles
76
100
// All currently released ARIA versions support `aria-current` on all roles.
77
101
// Leaving this for symetry and forward compatibility
78
- if ( allRoles . get ( role ) ?. props [ 'aria-current' ] === undefined ) {
102
+ if (
103
+ allRoles . get ( role as ARIARoleDefinitionKey ) ?. props [ 'aria-current' ] ===
104
+ undefined
105
+ ) {
79
106
throw new Error ( `"aria-current" is not supported on role "${ role } ".` )
80
107
}
81
108
}
@@ -89,22 +116,25 @@ function queryAllByRole(
89
116
90
117
if ( expanded !== undefined ) {
91
118
// guard against unknown roles
92
- if ( allRoles . get ( role ) ?. props [ 'aria-expanded' ] === undefined ) {
119
+ if (
120
+ allRoles . get ( role as ARIARoleDefinitionKey ) ?. props [ 'aria-expanded' ] ===
121
+ undefined
122
+ ) {
93
123
throw new Error ( `"aria-expanded" is not supported on role "${ role } ".` )
94
124
}
95
125
}
96
126
97
- const subtreeIsInaccessibleCache = new WeakMap ( )
98
- function cachedIsSubtreeInaccessible ( element ) {
127
+ const subtreeIsInaccessibleCache = new WeakMap < Element , Boolean > ( )
128
+ function cachedIsSubtreeInaccessible ( element : Element ) {
99
129
if ( ! subtreeIsInaccessibleCache . has ( element ) ) {
100
130
subtreeIsInaccessibleCache . set ( element , isSubtreeInaccessible ( element ) )
101
131
}
102
132
103
- return subtreeIsInaccessibleCache . get ( element )
133
+ return subtreeIsInaccessibleCache . get ( element ) as boolean
104
134
}
105
135
106
136
return Array . from (
107
- container . querySelectorAll (
137
+ container . querySelectorAll < HTMLElement > (
108
138
// Only query elements that can be matched by the following filters
109
139
makeRoleSelector ( role , exact , normalizer ? matchNormalizer : undefined ) ,
110
140
) ,
@@ -113,26 +143,26 @@ function queryAllByRole(
113
143
const isRoleSpecifiedExplicitly = node . hasAttribute ( 'role' )
114
144
115
145
if ( isRoleSpecifiedExplicitly ) {
116
- const roleValue = node . getAttribute ( 'role' )
146
+ const roleValue = node . getAttribute ( 'role' ) as string
117
147
if ( queryFallbacks ) {
118
148
return roleValue
119
149
. split ( ' ' )
120
150
. filter ( Boolean )
121
- . some ( text => matcher ( text , node , role , matchNormalizer ) )
151
+ . some ( text => matcher ( text , node , role as Matcher , matchNormalizer ) )
122
152
}
123
153
// if a custom normalizer is passed then let normalizer handle the role value
124
154
if ( normalizer ) {
125
- return matcher ( roleValue , node , role , matchNormalizer )
155
+ return matcher ( roleValue , node , role as Matcher , matchNormalizer )
126
156
}
127
157
// other wise only send the first word to match
128
158
const [ firstWord ] = roleValue . split ( ' ' )
129
- return matcher ( firstWord , node , role , matchNormalizer )
159
+ return matcher ( firstWord , node , role as Matcher , matchNormalizer )
130
160
}
131
161
132
- const implicitRoles = getImplicitAriaRoles ( node )
162
+ const implicitRoles = getImplicitAriaRoles ( node ) as string [ ]
133
163
134
164
return implicitRoles . some ( implicitRole =>
135
- matcher ( implicitRole , node , role , matchNormalizer ) ,
165
+ matcher ( implicitRole , node , role as Matcher , matchNormalizer ) ,
136
166
)
137
167
} )
138
168
. filter ( element => {
@@ -169,7 +199,7 @@ function queryAllByRole(
169
199
getConfig ( ) . computedStyleSupportsPseudoElements ,
170
200
} ) ,
171
201
element ,
172
- name ,
202
+ name as MatcherFunction ,
173
203
text => text ,
174
204
)
175
205
} )
@@ -185,7 +215,7 @@ function queryAllByRole(
185
215
getConfig ( ) . computedStyleSupportsPseudoElements ,
186
216
} ) ,
187
217
element ,
188
- description ,
218
+ description as Matcher ,
189
219
text => text ,
190
220
)
191
221
} )
@@ -198,7 +228,11 @@ function queryAllByRole(
198
228
} )
199
229
}
200
230
201
- function makeRoleSelector ( role , exact , customNormalizer ) {
231
+ function makeRoleSelector (
232
+ role : ByRoleMatcher ,
233
+ exact : boolean ,
234
+ customNormalizer ?: NormalizerFn ,
235
+ ) {
202
236
if ( typeof role !== 'string' ) {
203
237
// For non-string role parameters we can not determine the implicitRoleSelectors.
204
238
return '*'
@@ -207,7 +241,8 @@ function makeRoleSelector(role, exact, customNormalizer) {
207
241
const explicitRoleSelector =
208
242
exact && ! customNormalizer ? `*[role~="${ role } "]` : '*[role]'
209
243
210
- const roleRelations = roleElements . get ( role ) ?? new Set ( )
244
+ const roleRelations =
245
+ roleElements . get ( role as ARIARoleDefinitionKey ) ?? new Set ( )
211
246
const implicitRoleSelectors = new Set (
212
247
Array . from ( roleRelations ) . map ( ( { name} ) => name ) ,
213
248
)
@@ -220,7 +255,7 @@ function makeRoleSelector(role, exact, customNormalizer) {
220
255
. join ( ',' )
221
256
}
222
257
223
- const getNameHint = name => {
258
+ const getNameHint = ( name : ByRoleOptions [ 'name' ] ) : string => {
224
259
let nameHint = ''
225
260
if ( name === undefined ) {
226
261
nameHint = ''
@@ -233,11 +268,15 @@ const getNameHint = name => {
233
268
return nameHint
234
269
}
235
270
236
- const getMultipleError = ( c , role , { name} = { } ) => {
271
+ const getMultipleError : GetErrorFunction <
272
+ [ matcher : ByRoleMatcher , options : ByRoleOptions ]
273
+ > = ( c , role , { name} = { } ) => {
237
274
return `Found multiple elements with the role "${ role } "${ getNameHint ( name ) } `
238
275
}
239
276
240
- const getMissingError = (
277
+ const getMissingError : GetErrorFunction <
278
+ [ matcher : ByRoleMatcher , options : ByRoleOptions ]
279
+ > = (
241
280
container ,
242
281
role ,
243
282
{ hidden = getConfig ( ) . defaultHidden , name, description} = { } ,
@@ -247,7 +286,7 @@ const getMissingError = (
247
286
}
248
287
249
288
let roles = ''
250
- Array . from ( container . children ) . forEach ( childElement => {
289
+ Array . from ( ( container as Element ) . children ) . forEach ( childElement => {
251
290
roles += prettyRoles ( childElement , {
252
291
hidden,
253
292
includeDescription : description !== undefined ,
@@ -297,11 +336,10 @@ Unable to find an ${
297
336
298
337
${ roleMessage } `. trim ( )
299
338
}
300
- const queryAllByRoleWithSuggestions = wrapAllByQueryWithSuggestion (
301
- queryAllByRole ,
302
- queryAllByRole . name ,
303
- 'queryAll' ,
304
- )
339
+ const queryAllByRoleWithSuggestions = wrapAllByQueryWithSuggestion <
340
+ // @ts -expect-error -- See `wrapAllByQueryWithSuggestion` Argument constraint comment
341
+ [ labelText : Matcher , options ?: MatcherOptions ]
342
+ > ( queryAllByRole , queryAllByRole . name , 'queryAll' )
305
343
const [ queryByRole , getAllByRole , getByRole , findAllByRole , findByRole ] =
306
344
buildQueries ( queryAllByRole , getMultipleError , getMissingError )
307
345
0 commit comments