[Code Demo] Focus Trapping in Modal System | JSer - Front-End Interview questions

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys how's everything going this is jay sir in the previous video uh we've made a model system in react with the context api and yeah here's the code you can search in my channel for the previous video uh let's review our demo one more time so when we push a model and we could push a new model uh above it and we could do another one and close this one close this one close the uh bottom one so all the models are stored in the array here react element array and then just be rendered one by one okay each model is wrapped in this model component which has the common close button so when we push a new model we just need to define the content like this and no need to worry about the close button so this is a bruised demo and also i've mentioned that there is a big problem of this approach not not this approach but there's one problem left unsolved which is the access accessibility issue you see that yeah this is a demo right okay when i use the tab key to navigate the button okay this one is okay when i uh press the return key now this model is popped it's fine and then when i tap again you see that we go to the uh shoe model too well this because of the cursor problem okay let's uh do it one more one more time okay now we get so close well it looks fine and then tab again show model 2 pretty good and then when i tab it is gone right this is not good uh why because we suppose that a model is a component that attracts users into interaction so no other action should be allowed unless you dismiss this model when i show another model and tab close show model 3 and the tab and the focus is gone so this is not good what is good let's uh actually there is a way aria authorizing authoring practices 1.1 there are a lot of guidelines about each con a component that showing the best practices let's take a look at the dialog which is the model okay here is it a dialog is a window overlaid in either the primary window or another dialog window blah blah blah like non-model dialogues model dialogues contain their tab sequence that is tab and shift tabs do not move yet you see do not move focus outside the dialog however unlike most diamonds do not provide means to move keyboard focus outside the dialog without closing the dialog yeah okay so here is an example let's take take a look at the example here okay when i click this button this model popped out right and the first input is focused okay when i tab and we can use the shift tab to move it along the input and go to this button and this cancel right okay when i hear when i tap again it goes to the first input so these are uh this focus you the focus is trapped in this dialog we cannot get over it unless we cancel it okay and then we can add this is another dialog right this is another dialog and then tab you can see that it navigates about the link and about the button and then tab you're still trapped and then clap click okay it's gone but you'll see that the button here is actually uh being focused right it's focused it's already focused so when i click uh tap click the return the model pops up okay here's another model the first one is this is focus but it's a paragraph without a button because this content is too long we need to scroll scroll and should be shift space space yeah space and then navigate these three buttons so this video is not about the whole picture but only focus on two things about the uh about the accessibility issue okay uh let's continue this part on the best practices okay keyboard interaction when the dialog opens focus moves to an element inside the dialog okay it means focus placement depends on the nature of the size of the cotton in all circumstances focus moves to an element containing dialogue of course unless a condition we're doing otherwise is advisable focus is initially set on the first focusable element well it's button links or with tab index right if con is not g not large enough that focusing the first interact element could cause the beginning of a content scroll it is advisable to add tab index negative one to a static element just like the paragraph we have seen before at the top of the dialog such as the diagonal title or first paragraph initially focus that element yes prevent it from scrolling okay and then if a dialogue contains a final step in a process that is not easily reversible such as the deletion data blah blah blah it may be advisable to set focus on the least destructive action least destructive action so not like you want to delete something you might be focused on focus on the close or cancel right if a dialogue is limited interactions blah blah blah okay it might be advisable to set focus on the element that is likely to be most frequently used provide additional information or continuing process and the convert continue could be focused yeah so this is the first one when the dialogue opens we need to focus something focus the first first one let's write down the requirements we need to do today okay this should be in the model right okay one a new requirement one opens and focus let's make it simple here focus the first uh the first focusable faux casable uh elements but we already wrapped up within the close button here right so we could avoid it by adding a div wrapping the children here and just starting to iterate iterate uh the uh the focusable element here or we could just focus on the close button well it's uh it just it doesn't make that difference let's just say for this problem for these for now the first focusable is fine okay the error is too small okay this is the first requirement like let's take a look at the second one tab will focus to the next habitable elements this is default behavior it focuses on the last type of animating side dialogue moves focus to the first typical element inside the dialogue so this is uh the most important feature we want wanted today it's a trap the focus unable to focus outside when popup is displayed yeah and the shift tab is moving backward right so you focus on the first type of element then moving before would lead to last type of element well this is not hard and escape close the dialog escape well this is uh okay anyway let's escape to close the dialogue for okay and there's another requirement here say when a dialogue closes focus returns to the element of the invoked dialogue unless either it means that say i want to push about model this is the trigger right i click this button and click pop this model and then i close the focus should be on this model the shift tab shift tab yeah and no it's not right right so this is the full fourth requirement um refocus the trigger when model is dismissed is closed i would say okay now this is four requirements let's solve it today first one opens and focus the first focus of the element because we already wrapped all the models here uh we could just uh get the rest of this div when this model is mounted and we would be able to find the first okay we would be store able to store the ref to first and last uh focusable element right yeah let's do it so as we have said in this particular demo we don't care about the close button should be the first one or not we just search for the uh first um uh focusable element to say focusable element we should link right anchor tag that button their checkbox a lot so i would say that we add the tab index to default to zero and then we query that tab index number or okay this is two number fine yeah okay so uh ref first focusable react create ref it should be an html element no or um what great ah i'm sorry ah i forgot that we are in hooks so this should be react use ref i'm sorry html element or no default to nor all right and then we said next one ref our last focusable we will initialize these two variables in the use effect hook when the dom is mounted by we need to first get the ref of this div copy paste ref outer elements just html def element outer here great and then we would uh query the selectors right so the uh focusables elements would be um ref outer current query selector all with the uh it should be a tab index right i'm not sure should be yeah it should be small case here okay issue might be a elements array or undefined so if it is okay it's not undefined we wrap first okay this should be oh it should be array oh no no no we transform into array okay should default an array and we could spread it make it an array the never noteless of is not array type ah i see okay so we could use array from yeah default is this then it must be array we don't need this anymore we set the current to focusable elements first one this should be okay let's say html element uh ref last focus current pool be last one so now we get the reference to the first and the last one right now we would what do we need to do we need to uh we need to listen to these uh the key down event to check if the tab key is pressed right so we on key down why do we use on key down because the tab key if we press down without kia without without leaving the tab queue will go all all along right so it won't stop so we use um key down here so const on key down use callback uh we don't want this to function to read to be regenerated every in every render so okay okay down this event should be mouse event i would say not mouse event uh event keyboard ah yeah so you should be keyboard event keyboard event uh-huh so um then if tab key is tapped on the last focus on the first yeah so um here's a problem if the if there is a con within the button like a span the on key down actually uh will be bubbled to this div but with the target set to that inner inner one right so technically we need to check that uh what that the e event is um a child of the last focusable here need to check e current if a child of last focusable but here for for make it simpler uh we ignore it so warning this is just for demonstration there is no element in the button so we could safely say if e uh the target right equals to last focusable oh yeah it's current oh ref last focusable if it is then what we do we focus on the we focus on on kid on e in target is it we can we get the target actually i'm not sure let's console log the e target okay let's try push model and then tab button shoe model ah i remember so actually we could have a uh reference call document dot active element yeah this could be true it's just currently the the elements are being focused currently if it is then what we do we first focus the first one right so current focus yeah focus the first one yeah so this is it let's take a look we push model and then tap tap not okay okay wait a minute because document should we prove it should we prevent the default wait a minute tab tab tab tap oh yeah actually it works it is our last one right let's uh e prevent default proven default okay how is it now huh we have some problem here it says we actually we were being trapped into the clothes first one okay um let's console log the focusable element okay one button ah oh my bad we forgot to add the tab index here so the first model the button here let's say tab index zero tapping next zero zero yeah so now actually we have two buttons what can why can't we reload it waiting it seems that network is down okay we push the model yeah this should be okay here go to the model which model tab tab tab yeah you see that okay the tab is perfectly focused the same goes for the ship tab we just need to check i'll remove the console here i think the proven default is not necessary maybe let's take a take a look oh it's it is need this default great so now we trap it and uh to do we could do the same actually for um for the shift tab right so if the fir if it is focused on oh i forgot to check the key if e key equals tab yeah and also this should be the same for the first so ref first focusable and the key tab and also the shift key is shift key is used then we go to the last focus mode right okay and it should not be uh ift key shift key yeah oh it should be not shift key okay shift key is okay now tab key is okay now um and also we need to focus on this is first oh this first is not yet we've done the second one right the first one is when we focused it and then focusable first one uh should be refocus focus it let's see so first one the second uh requirements are satisfied now let's take a look push tab tap tap good and then show model two close is focused and then tap tap tap focus focus focus shimada 3 close focus and then close okay first and two are uh mid now now we need to do the escape to close the dialog right um this is um this is pretty simple let's just add add one um but if it is not focused on key down i'm not sure whether um the on key down here would trap the focus uh it should be because when the model is uh is displayed it will actually uh trap the focus right so the key will be bubbled up okay so if key is esc we just dismiss right we need to call the dismiss which is the close so we just close it let's see push yes you see close is not focus shift okay okay you see close so it's not esc then what it is uh console.log e key let's see what it is console here push model uh you see escape oh sorry escape okay great push hmm they didn't focus commander 2 focused him on the three focus close yeah because it's not focused now okay put if we do like this focus esc okay it's working the one problem is that actually if we don't press the tab button it won't the focus is not there tap is it right i already co i've already uh focused focused it let's log it okay console log focus the first one let's see what it is okay push button with focus to close but it's not focused actually right it is focused but just uh uh yeah it's focused but actually the outline is not there you see when i close we can actually close it and also escape it yeah it's focused just not outline okay one and two are okay three is okay now the fourth one refocus the problem is that and i showed the model two that's your model three when i press uh tap the escape it's gone now i should i should be the shoot model three button should be focused right when i press the return again it should pop the three number three and also i can continuously press escape key to close all the bot models so how should we do it well it's pretty simple uh when we trigger of a focus uh when we pop a model we'll pass in not only the model component but also the trigger right which means in screen one when that we show a model here shoe model one shoe model two click show model 2 we say and even we pass in the uh okay not not this one yet we show model one we needed to know who showed model one right so the we get the event which should be mouse event it should be html button right button element start generate generic react oh import okay okay so we push we push them this is the model and we could put the second parameter should be the trigger right so we get e and the target again this should be uh the button we want there might be some other elements within the button we need to handle that but in this problem we would ignore it um push here when i say push this one right okay we need to first modify the model context and note here but also we need the trigger which should be html element [Music] and so in app here we will say this is the trigger this is html elements okay so we get the elements and then close model when we show this model okay close so in this when the model the model is could be only closed by this close function right so in this close we actually could uh restore the focus for for the trigger yeah so we just call trigger and focus so this is it and in the screen one we could just uh okay here we push it e target e target is not assignable to xml elements the target target is base synthetic event target is event target [Music] e synthetic it's hmo target uh origin some target there's synthetic target huh what is synthetic target event target is not assignable to perimeter shoe model on click react html button element cost target equals e the target to type event target this should not be okay oh oh it's not it should be current target i'm sorry yeah it's it's okay we will just to copy the code here and then we show model 2 we yeah we push and then here should be e current target because we don't use the event delegation here we use the current target okay e current target okay there should be no error let's see how it goes push model your model 2 tap close fine okay yeah the previous one is focus you see the model want to hear okay tab on the three close all uh we haven't implemented close all yet okay go back shift tab shift by shift tab close and then close and then we show model 2 show mother 3 and then we press escape escape escape voila perfect right yeah so ok that's all for this video we've managed to implement sys4 requirement and pretty interesting and not that difficult and it's not perfect yet there must be some detailed problems we haven't covered but it's a demo so it's good enough to be a prototype i would say anyway this so this is the idea of handling the focus trapping a model system hope it helps don't forget to subscribe my channel i will bring more videos to it and see you next time bye
Info
Channel: JSer
Views: 347
Rating: 5 out of 5
Keywords: algorithm, JavaScript, Front-End
Id: hUlSgA8yrew
Channel Id: undefined
Length: 35min 17sec (2117 seconds)
Published: Fri Mar 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.