-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pattern Explorer category selection causes the modal to close unexpectedly #55110
Comments
@richtabor There's a similar report here - #55043. Though in a different part of the UI. I can't reproduce any issues with it closing (though I just spotted an issue that makes it crash completely). Is it happening for every category or just some? Are there patterns you've created in the affected categories? |
@richtabor, is this a Browser/Safari-specific issue? What version are you using? I can't reproduce the bug on Chrome. |
Ah yes, it's Safari. |
Seems like any category switch, regardless of pattern. |
@richtabor, can you share the version? I can't reproduce it with Safari Version 16.4. |
I couldn't replicate this in Safari 16.2 either. |
I can replicate this issue with Safari Version 17.1 |
I had a look into this and I think I know the reason. It happens only in Safari under two separate but interwound conditions:
I'm still not sure how to fix it though. I feel like making the scrollable wrapper always focusable ( |
@kevin940726 thank you for looking into this and for the ping.
No because setting the 'focusability' of that wrapper dynamically is the main point of that implementation. We want to make that div focusable only when there is an actual content overflow that triggers its 'scrollability'. Instead, we don't want it to be focusable when there is no actual content overflow. This point is well explained in the original PR. Native browser behavior with scrollable divs is inconsisntent and we want to standardize it. Please have a look at the original PR and also the codepen linked there, test with Chrome and Firefox. That said, there's a few issues here. In general, I don't think we should fix browser bugs. Certainly we should not do that by removing important accessible features. We can try to workaround them, when possible. I spent a few time debugging this issue and turns out there's a lot to say. First, it is important to highlight that anything that triggers a focus loss within the modal dialog is going to make it close. Category buttonsI was wondering why the Preferences modal dialog works correctly with Safari while this Patterns modal dialog does not. Comparing the behavior in the below animated GIF. I'm using a thick red outline to highlight where focus is: In the Preferences modal dialog:
In the Patterns explorer modal dialog:
Turns out in the Preferences modal dialog the buttons do have a Pagination buttonsThese buttons get a
To reproduce:
Animated GIF to illustrate the issue with Chrome: This needs to be fixed as well. I'd argue that making the modal dialog content populate dynamically by fetching content and even using pagination within the modal dialog content seems to be less than ideal in the first place. I'm not sure it's the best user experience. Also, this implementation exposes to potential further bugs. Anyways, as pointed out several times in the history of this project, using the Important Elements that are focused must not get disabled on the fly, or get hidden, or be removed from the DOM. That triggers a focus loss. Unless focus is managed and the focus loss is prevented programmatically. These pagination buttons need to be changed. We should also check if there are other interactive elements in this modal dialog that get disabled/hidden/removed. This principle applies to any focusable element: they should never be disabled/hidden/removed while they are focused. |
Important: I also suspect that re-populating the content area makes |
I created #56162 to explore a possible fix. |
Noticed one more thing: I'm not sure I understand this change: It comes from the PR that refactored the modal initial focus behavior. To my understanding it's getting as |
From what I recall, if you opt into the API that that PR provided, it will attempt to focus an element within the contents of the Modal rather than the entire Modal. If the Modal contents does not contain a focusable element then it might have undesired behaviour. However, it's an optional API and thus when you opt into it it's your responsibility (as noted in the accompanying docs) as a developer to ensure a focusable element is available. Maybe I'm misunderstanding something though...? |
I just found another case where a button within the Modal component gets a In the install Font modal dialog, the 'Install' button gets disabled after it is activated with the keyboard. As such, a focus loss occurs. At that point, pressing the Tab key restarts the tab sequence fron the document root outside of the modal dialog. It should never, ever, happen that focus lands outside of a modal dialog. I'm not sure educating developers to avoid these focus losses is sufficient. I think there should be a strict rule, enforced via code, to not allow the Screenshot of the inatall fonts modal dialog with the focus loss: see focus is on the 'Open navigation' button behind the modal dialog: |
I've tested a little more in depth the 'Fonts' modal dialog and it's literally full of cases where focusable elements are dynamically added / removed / hidden / disabled. Each of those cases has an impact on:
I'm not sure a modal dialog should ever used this way, for highly dynamic UIs, but, regardless, we should make sure no focus lossess ever occur. |
I agree, but as we can see in some parts of the code base it's not trivial to fix them all at once. The closing of the modal is the most unexpected, and in some cases it leaves users no choices to recover from it. I wonder if we should detect if a focus loss happens, and don't close the modal in that case. We can instead put the focus back in the modal again if needed. It's obviously sub-optimal, but I think the focus misplacement is still better than completely destroying users' intent of opening a modal. We can even put some console logs when they happen so that they're more obvious to the developers working on these issues. In const focusOutsideProps = useFocusOutside( ( event ) => {
+ if (document.activeElement === document.body) {
+ console.warn('Focus lost. Please check the code of the modal.');
+ return;
+ }
// This unstable prop is here only to manage backward compatibility
// for the Popover component otherwise, the onClose should be enough.
if ( currentOptions.current?.__unstableOnClose ) {
currentOptions.current.__unstableOnClose( 'focus-outside', event );
} else if ( currentOptions.current?.onClose ) {
currentOptions.current.onClose();
}
} ); What do you think of this temporary approach before we go on to fix the root cause? |
@kevin940726 that could be an option. However, I'd would like to first understand what is really happening here. For the Safari bug:
gutenberg/packages/compose/src/hooks/use-focus-outside/index.ts Lines 102 to 123 in 6e532f4
seems it is not working as intended though? For buttons that are dynamically added / removed / hidden / disabledThat's just a bad pattern that developers should never use within the modal dialog. Also, I'm not sure such highly dynamic user interfaces like the content of the Fonts modal dialog should ever be placed within a modal dialog. Consider the font 'Install' button. When it appears and users Tab to it, useConstrainedTabbing sets it to the 'next tabbable' element. But then the button is removed before users Tab again, so To me, we should just make clear that we must not make buttons added / removed / hidden / disabled dynamically. |
I believe the first point raised in this issue—Pattern Explorer unexpectedly closing—is no longer reproducible. I tried a bit and couldn't. I didn't try very hard but the following should help explain why.
Since 0816b4c this should no longer be true. That commit removed It happens that the aforementioned commit was merged less than an hour before this issue was created. So I believe it was technically solved before it was made. However, it did seem to help Andrea discover other issues. |
That explains why so many of us couldn't reproduce it. |
When running 6.4 beta 2, or Gutenberg trunk, I cannot select alternate categories within the Pattern Explorer. The modal closes unexpectedly. Chrome seems fine though.
CleanShot.2023-10-05.at.17.25.37.mp4
The text was updated successfully, but these errors were encountered: