@@ -18,8 +18,54 @@ function closeClick(e) {
1818 closeModal ( ) ;
1919 }
2020}
21+ function trapTabKey ( e ) {
22+ const vanillaModal = document . querySelector ( ".vanilla-modal" ) ;
23+ const FOCUSABLE_ELEMENTS = [
24+ "a[href]" ,
25+ "area[href]" ,
26+ 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])' ,
27+ "select:not([disabled]):not([aria-hidden])" ,
28+ "textarea:not([disabled]):not([aria-hidden])" ,
29+ "button:not([disabled]):not([aria-hidden])" ,
30+ "iframe" ,
31+ "object" ,
32+ "embed" ,
33+ "[contenteditable]" ,
34+ '[tabindex]:not([tabindex^="-"])' ,
35+ ] ;
36+
37+ const nodes = vanillaModal . querySelectorAll ( FOCUSABLE_ELEMENTS ) ;
38+ let focusableNodes = Array ( ...nodes ) ;
39+
40+ if ( focusableNodes . length === 0 ) return ;
41+
42+ focusableNodes = focusableNodes . filter ( ( node ) => {
43+ return node . offsetParent !== null ;
44+ } ) ;
45+
46+ // if disableFocus is true
47+ if ( ! vanillaModal . contains ( document . activeElement ) ) {
48+ focusableNodes [ 0 ] . focus ( ) ;
49+ } else {
50+ const focusedItemIndex = focusableNodes . indexOf ( document . activeElement ) ;
51+
52+ if ( e . shiftKey && focusedItemIndex === 0 ) {
53+ focusableNodes [ focusableNodes . length - 1 ] . focus ( ) ;
54+ e . preventDefault ( ) ;
55+ }
2156
22- const closeModal = function ( ) {
57+ if (
58+ ! e . shiftKey &&
59+ focusableNodes . length > 0 &&
60+ focusedItemIndex === focusableNodes . length - 1
61+ ) {
62+ focusableNodes [ 0 ] . focus ( ) ;
63+ e . preventDefault ( ) ;
64+ }
65+ }
66+ }
67+
68+ function closeModal ( ) {
2369 const vanillaModal = document . querySelector ( ".vanilla-modal" ) ;
2470 if ( vanillaModal ) {
2571 vanillaModal . classList . remove ( "modal-visible" ) ;
@@ -30,7 +76,8 @@ const closeModal = function () {
3076 document . removeEventListener ( "keydown" , escKey ) ;
3177 document . removeEventListener ( "click" , outsideClick , true ) ;
3278 document . removeEventListener ( "click" , closeClick ) ;
33- } ;
79+ document . removeEventListener ( "keydown" , trapTabKey ) ;
80+ }
3481
3582const modal = {
3683 init : function ( ) {
@@ -66,6 +113,7 @@ const modal = {
66113 vanillaModal . classList . add ( "modal-visible" ) ;
67114 document . addEventListener ( "click" , outsideClick , true ) ;
68115 document . addEventListener ( "keydown" , escKey ) ;
116+ document . addEventListener ( "keydown" , trapTabKey ) ;
69117 document
70118 . getElementById ( "modal-content" )
71119 . addEventListener ( "click" , closeClick ) ;
0 commit comments