8
8
Managing preferences dialog
9
9
*/
10
10
11
- import { Component } from 'react'
11
+ import { Component , createRef } from 'react'
12
12
import getIntegrations from '../util/integrations'
13
13
import Button from '@hashicorp/react-button'
14
14
import Toggle from '@hashicorp/react-toggle'
@@ -33,6 +33,7 @@ export default class ConsentPreferences extends Component {
33
33
34
34
this . handleFold = this . handleFold . bind ( this )
35
35
this . getCategoryToggle = this . getCategoryToggle . bind ( this )
36
+ this . dialogRef = createRef ( )
36
37
}
37
38
38
39
componentDidMount ( ) {
@@ -44,6 +45,12 @@ export default class ConsentPreferences extends Component {
44
45
) . then ( ( groupedIntegrations ) => {
45
46
this . setState ( { groupedIntegrations } )
46
47
} )
48
+
49
+ this . dialogRef . current ?. showModal ( )
50
+ }
51
+
52
+ componentWillUnmount ( ) {
53
+ this . dialogRef . current ?. close ( )
47
54
}
48
55
49
56
// Handler for when user toggles a category or individual integration
@@ -106,11 +113,16 @@ export default class ConsentPreferences extends Component {
106
113
// Build each individual category and integration row
107
114
buildCategory ( items , name ) {
108
115
const categoryItems = items . map ( ( item ) => {
116
+ const categoryItemTitleID = `consent-manager-categoryItemTitle-${ item . name } `
117
+
109
118
return (
110
119
< div className = { s . categoryItem } key = { item . name } >
111
- < header className = { s . categoryItemHeader } >
112
- < h4 className = { s . categoryItemTitle } > { item . name } </ h4 >
120
+ < div className = { s . categoryItemHeader } >
121
+ < h4 id = { categoryItemTitleID } className = { s . categoryItemTitle } >
122
+ { item . name }
123
+ </ h4 >
113
124
< Toggle
125
+ ariaLabelledBy = { categoryItemTitleID }
114
126
onChange = { this . handleToggle . bind ( this , item . name , item . origin ) }
115
127
enabled = { Boolean (
116
128
this . state . consent . loadAll ||
@@ -119,18 +131,24 @@ export default class ConsentPreferences extends Component {
119
131
this . state . consent [ item . origin ] [ item . name ] )
120
132
) }
121
133
/>
122
- </ header >
134
+ </ div >
123
135
< p className = { s . categoryItemDescription } > { item . description } </ p >
124
136
</ div >
125
137
)
126
138
} )
127
139
140
+ const categoryHeaderTitleID = `consent-manager-categoryHeaderTitle-${ name } `
141
+ const categoryListID = `consent-manager-categoryHeaderTitle-${ name } -list`
142
+
128
143
return (
129
144
< div className = { s . category } key = { name } >
130
- < header className = { s . categoryHeader } >
131
- < h3 className = { s . categoryHeaderTitle } > { name } </ h3 >
145
+ < div className = { s . categoryHeader } >
146
+ < h3 id = { categoryHeaderTitleID } className = { s . categoryHeaderTitle } >
147
+ { name }
148
+ </ h3 >
132
149
{ ! this . state . showCategories [ name ] && (
133
150
< Toggle
151
+ ariaLabelledBy = { categoryHeaderTitleID }
134
152
onChange = { this . handleToggle . bind ( this , name , 'categories' ) }
135
153
enabled = {
136
154
this . state . consent . loadAll || this . getCategoryToggle ( name )
@@ -145,14 +163,20 @@ export default class ConsentPreferences extends Component {
145
163
this . handleFold ( name )
146
164
} }
147
165
aria-label = {
148
- this . state . showCategories [ name ] ? 'See less' : 'See more'
166
+ this . state . showCategories [ name ]
167
+ ? `See less in ${ name } `
168
+ : `See more in ${ name } `
169
+ }
170
+ aria-expanded = { this . state . showCategories [ name ] ? `true` : `false` }
171
+ aria-controls = {
172
+ this . state . showCategories [ name ] ? categoryListID : null
149
173
}
150
174
>
151
175
< IconArrowDown24 />
152
176
</ button >
153
- </ header >
177
+ </ div >
154
178
{ this . state . showCategories [ name ] && (
155
- < div className = { s . categoryFold } >
179
+ < div className = { s . categoryFold } id = { categoryListID } >
156
180
< p className = { s . categoryFoldDescription } >
157
181
{ this . state . categories [ name ] }
158
182
</ p >
@@ -173,12 +197,19 @@ export default class ConsentPreferences extends Component {
173
197
} )
174
198
175
199
return (
176
- < div className = { s . root } data-testid = "consent-mgr-dialog" >
200
+ < dialog
201
+ aria-labelledby = "consent-mgr-dialog-title"
202
+ className = { s . root }
203
+ data-testid = "consent-mgr-dialog"
204
+ ref = { this . dialogRef }
205
+ >
177
206
{ /* Manage preferences dialog */ }
178
207
< div className = { s . visibleDialog } >
179
- < header className = { s . dialogHeader } >
180
- < h2 className = { s . dialogHeaderTitle } > Manage cookies</ h2 >
181
- </ header >
208
+ < div className = { s . dialogHeader } >
209
+ < h2 id = "consent-mgr-dialog-title" className = { s . dialogHeaderTitle } >
210
+ Manage cookies
211
+ </ h2 >
212
+ </ div >
182
213
< div className = { s . dialogBody } >
183
214
< p className = { s . dialogBodyIntro } >
184
215
HashiCorp uses data collected by cookies and JavaScript libraries
@@ -224,6 +255,7 @@ export default class ConsentPreferences extends Component {
224
255
} }
225
256
/>
226
257
< Button
258
+ autoFocus
227
259
className = { s . saveButton }
228
260
title = "Accept all"
229
261
onClick = { ( ) => {
@@ -232,7 +264,7 @@ export default class ConsentPreferences extends Component {
232
264
/>
233
265
</ div >
234
266
</ div >
235
- </ div >
267
+ </ dialog >
236
268
)
237
269
}
238
270
}
0 commit comments