@@ -103,7 +103,7 @@ export default class ApiResponse extends LitElement {
103103 render ( ) {
104104 return html `
105105 < div class ="col regular-font response-panel ${ this . renderStyle } -mode ">
106- < div class =" ${ this . callback === 'true' ? 'tiny-title' : 'req-res-title' } " role ="heading " aria-level ="${ this . renderStyle === 'focused' ? 3 : 4 } ">
106+ < div class =" ${ this . callback === 'true' ? 'tiny-title' : 'req-res-title' } " role ="heading " aria-level ="${ this . renderStyle === 'focused' ? 3 : 4 } " id =" response-title " >
107107 ${ this . callback === 'true' ? getI18nText ( 'operations.callback-response' ) : getI18nText ( 'operations.response' ) }
108108 </ div >
109109 < div >
@@ -159,8 +159,8 @@ export default class ApiResponse extends LitElement {
159159 this . headersForEachRespStatus [ statusCode ] = tempHeaders ;
160160 this . mimeResponsesForEachStatus [ statusCode ] = allMimeResp ;
161161 }
162- return html `< div class ='row ' style ='flex-wrap:wrap ' role ="group ">
163- ${ Object . keys ( this . responses ) . map ( ( respStatus ) => html `
162+ return html `< div class ='row ' style ='flex-wrap:wrap ' role ="tablist " aria-labelledby =" response-title ">
163+ ${ Object . keys ( this . responses ) . map ( ( respStatus , i ) => html `
164164 ${ respStatus === '$$ref' // Swagger-Client parser creates '$$ref' object if JSON references are used to create responses - this should be ignored
165165 ? ''
166166 : html `
@@ -173,7 +173,32 @@ export default class ApiResponse extends LitElement {
173173 this . selectedMimeType = undefined ;
174174 }
175175 } } "
176- aria-current ="${ this . selectedStatus === respStatus } "
176+ @keydown ="${ ( e ) => {
177+ const keys = Object . keys ( this . responses ) ;
178+ let newIndex = 0 ;
179+ switch ( e . key ) {
180+ case 'ArrowRight' :
181+ newIndex = ( i + 1 ) % keys . length ;
182+ break ;
183+ case 'ArrowLeft' :
184+ newIndex = ( i - 1 + keys . length ) % keys . length ;
185+ break ;
186+ case 'Home' :
187+ newIndex = 0 ;
188+ break ;
189+ case 'End' :
190+ newIndex = keys . length - 1 ;
191+ break ;
192+ default :
193+ return ;
194+ }
195+ this . shadowRoot . getElementById ( `button${ keys [ newIndex ] } ` ) . focus ( ) ;
196+ } } "
197+ role ="tab "
198+ aria-selected ="${ this . selectedStatus === respStatus } "
199+ aria-controls ="status ${ respStatus } "
200+ tabindex ="${ this . selectedStatus === respStatus ? '0' : '-1' } "
201+ id ="button ${ respStatus } "
177202 class ='m-btn small ${ this . selectedStatus === respStatus ? 'primary' : '' } '
178203 part ="btn--resp ${ this . selectedStatus === respStatus ? 'btn-fill--resp' : 'btn-outline--resp' } btn-response-status "
179204 style ='margin: 8px 4px 0 0; text-transform: capitalize '>
@@ -184,7 +209,7 @@ export default class ApiResponse extends LitElement {
184209 </ div >
185210
186211 ${ Object . keys ( this . responses ) . map ( ( status ) => html `
187- < div style = ' display: ${ status === this . selectedStatus ? 'block' : 'none' } ' >
212+ < div id =" status ${ status } " role =" tabpanel " aria-labelledby =" button ${ status } " tabindex =" 0 " style =" display: ${ status === this . selectedStatus ? 'block' : 'none' } " >
188213 < div class ="top-gap ">
189214 < span class ="resp-descr m-markdown "> ${ unsafeHTML ( toMarkdown ( this . responses [ status ] && this . responses [ status ] . description || '' ) ) } </ span >
190215 ${ ( this . headersForEachRespStatus [ status ] && this . headersForEachRespStatus [ status ] . length > 0 )
@@ -196,23 +221,43 @@ export default class ApiResponse extends LitElement {
196221 ? ''
197222 : html `
198223 < div class ="tab-panel col ">
199- < div class ="tab-buttons row " role ="group " @click ="${ ( e ) => { if ( e . target . tagName . toLowerCase ( ) === 'button' ) { this . activeSchemaTab = e . target . dataset . tab ; } } } " >
200- < button class ="tab-btn ${ this . activeSchemaTab === 'model' ? 'active' : '' } " aria-current ="${ this . activeSchemaTab === 'model' } " data-tab ='model '> ${ getI18nText ( 'operations.model' ) } </ button >
201- < button class ="tab-btn ${ this . activeSchemaTab !== 'model' ? 'active' : '' } " aria-current ="${ this . activeSchemaTab !== 'model' } " data-tab ='body '> ${ getI18nText ( 'operations.example' ) } </ button >
224+ < div class ="tab-buttons row " role ="ta " @click ="${ ( e ) => { if ( e . target . tagName . toLowerCase ( ) === 'button' ) { this . activeSchemaTab = e . target . dataset . tab ; } } } " @keydown ="${ ( e ) => {
225+ const b = e . target ;
226+ if ( b . tagName . toLowerCase ( ) !== 'button' ) { return ; }
227+ const i = Array . from ( b . parentNode . children ) . indexOf ( b ) ;
228+ let newIndex = 0 ;
229+ switch ( e . key ) {
230+ case 'ArrowRight' :
231+ newIndex = ( i + 1 ) % 2 ;
232+ break ;
233+ case 'ArrowLeft' :
234+ newIndex = ( i - 1 + 2 ) % 2 ;
235+ break ;
236+ case 'Home' :
237+ newIndex = 0 ;
238+ break ;
239+ case 'End' :
240+ newIndex = 1 ;
241+ break ;
242+ default :
243+ return ;
244+ }
245+ e . target . parentElement . children [ newIndex ] . focus ( ) ;
246+ } } ">
247+ < button class ="tab-btn ${ this . activeSchemaTab === 'model' ? 'active' : '' } " id ="resp-model-button " aria-controls ="resp-model-body " aria-selected ="${ this . activeSchemaTab === 'model' } " tabindex ="${ this . activeSchemaTab === 'model' ? 0 : '-1' } " data-tab ='model '> ${ getI18nText ( 'operations.model' ) } </ button >
248+ < button class ="tab-btn ${ this . activeSchemaTab !== 'model' ? 'active' : '' } " id ="resp-body-button " aria-controls ="resp-body-body " aria-selected ="${ this . activeSchemaTab !== 'model' } " tabindex ="${ this . activeSchemaTab !== 'model' ? 0 : '-1' } " data-tab ='body '> ${ getI18nText ( 'operations.example' ) } </ button >
202249 < div style ="flex:1 "> </ div >
203250 ${ Object . keys ( this . mimeResponsesForEachStatus [ status ] ) . length === 1
204251 ? html `< span class ='small-font-size gray-text ' style ='align-self:center; margin-top:8px; '> ${ Object . keys ( this . mimeResponsesForEachStatus [ status ] ) [ 0 ] } </ span > `
205252 : html `${ this . mimeTypeDropdownTemplate ( Object . keys ( this . mimeResponsesForEachStatus [ status ] ) ) } `
206253 }
207254 </ div >
208- ${ this . activeSchemaTab === 'body'
209- ? html `< div class ='tab-content col ' style ='flex:1; '>
210- ${ this . mimeExampleTemplate ( this . mimeResponsesForEachStatus [ status ] [ this . selectedMimeType ] ) }
211- </ div > `
212- : html `< div class ='tab-content col ' style ='flex:1; '>
213- ${ this . mimeSchemaTemplate ( this . mimeResponsesForEachStatus [ status ] [ this . selectedMimeType ] ) }
214- </ div > `
215- }
255+ ${ html `< div class ='tab-content col ' role ="tabpanel " tabindex ="0 " id ='resp-body-body ' aria-labelledby ='resp-body-button ' style ='flex:1; display: ${ this . activeSchemaTab === 'body' ? 'block' : 'none' } '>
256+ ${ this . mimeExampleTemplate ( this . mimeResponsesForEachStatus [ status ] [ this . selectedMimeType ] ) } }
257+ </ div > ` }
258+ ${ html `< div class ='tab-content col ' role ="tabpanel " tabindex ="0 " id ='resp-model-body ' style ='flex:1; display: ${ this . activeSchemaTab === 'body' ? 'none' : 'block' } '>
259+ ${ this . mimeSchemaTemplate ( this . mimeResponsesForEachStatus [ status ] [ this . selectedMimeType ] ) }
260+ </ div > ` }
216261 </ div >
217262 `
218263 } `)
0 commit comments