Browse Source
Improve docs options toggle accessibility and handler safety
- add a :focus-visible ring on the toggle button for keyboard users
- keep the info line visible in the popover
- namespace and unbind the toggle handlers to avoid stacking on re-init
pull/25748/head
maliming
3 months ago
No known key found for this signature in database
GPG Key ID: A646B9CB645ECEA4
3 changed files with
20 additions and
13 deletions
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css
modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss
@ -191,23 +191,28 @@
$btn . trigger ( 'focus' ) ;
}
}
$btn . on ( 'click' , function ( e ) {
// clear any previous bindings so a second init (e.g. partial reload) does not stack handlers
$btn . off ( '.docsOptions' ) ;
$criteria . off ( '.docsOptions' ) ;
$ ( document ) . off ( '.docsOptions' ) ;
$ ( window ) . off ( '.docsOptions' ) ;
$btn . on ( 'click.docsOptions' , function ( e ) {
e . preventDefault ( ) ;
e . stopPropagation ( ) ;
setOpen ( ! $criteria . hasClass ( 'is-open' ) ) ;
} ) ;
$criteria . on ( 'click' , function ( e ) {
$criteria . on ( 'click.docsOptions ' , function ( e ) {
e . stopPropagation ( ) ;
} ) ;
$ ( document ) . on ( 'click' , function ( ) {
$ ( document ) . on ( 'click.docsOptions ' , function ( ) {
setOpen ( false ) ;
} ) ;
$ ( document ) . on ( 'keydown' , function ( e ) {
$ ( document ) . on ( 'keydown.docsOptions ' , function ( e ) {
if ( e . key === 'Escape' ) {
setOpen ( false ) ;
}
} ) ;
$ ( window ) . on ( 'scroll' , function ( ) {
$ ( window ) . on ( 'scroll.docsOptions ' , function ( ) {
if ( ! $ ( 'body' ) . hasClass ( 'scrolledMore' ) ) {
setOpen ( false ) ;
}
@ -118,6 +118,10 @@ body.scrolledMore .alert-criteria .options-header .toggle-btn:hover {
transform : translateY ( -2px ) ;
box-shadow : 0 12px 28px rgba ( 111 , 66 , 193 , 0 . 28 ) ;
}
body . scrolledMore . alert-criteria . options-header . toggle-btn : focus-visible {
outline : 2px solid # 6f42c1 ;
outline-offset : 2px ;
}
body . scrolledMore . alert-criteria . is-open {
visibility : visible ! important ;
pointer-events : auto ;
@ -135,9 +139,6 @@ body.scrolledMore .alert-criteria.is-open .options-header .toggle-btn::before {
content : "\f00d" ;
font-size : 22px ;
}
body . scrolledMore . alert-criteria : has ( . options-header ) p . alert-p {
display : none ! important ;
}
body . scrolledMore . alert-criteria p . alert-p {
margin : 0 0 12px ! important ;
color : # 6f42c1 ! important ;
@ -149,6 +149,12 @@ body {
transform : translateY ( - 2 px ) ;
box-shadow : 0 12 px 28 px rgba ( 111 , 66 , 193 , 0 .28 ) ;
}
/ / the custom box-shadow hides the default focus ring ; restore a visible one for keyboard users
& : focus-visible {
outline : 2 px solid #6f42c1 ;
outline-offset : 2 px ;
}
}
}
@ -174,11 +180,6 @@ body {
}
}
/ / abp . io renders an . options-header title , so its info line is redundant ; module pages keep it
& : has ( . options-header ) p . alert-p {
display : none !important ;
}
p . alert-p {
margin : 0 0 12 px !important ;
color : #6f42c1 !important ;