-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Try to refactor the logic regarding refocusing when the modal is closed #29199
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
Conversation
|
Hey! I see that you made changes to our Form component. Make sure to update the docs in FORMS.md accordingly. Cheers! |
1130e78 to
d5694f6
Compare
ec72ddf to
05c51f6
Compare
|
Hi @0xmiroslav, when you get a chance, could you take a quick look at the implementation of this PR? It has successfully passed tests in many scenarios. I'm eager to get your initial impressions on this PR, such as whether this implementation approach is acceptable and if there are any serious blockers I might have overlooked. :) |
| > | ||
| {props.children} | ||
| </View> | ||
| <ModalContent onDismiss={handleDismissContent}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
App/src/components/PopoverWithoutOverlay/index.js
Lines 84 to 88 in e1fcb42
| } else { | |
| props.onModalHide(); | |
| close(props.anchorRef); | |
| Modal.onModalDidClose(); | |
| } |
It's somewhat similar to the above condition code, but has the following advantages:
- it's only called when the modal disappears (the code above is called even on the initial load),
- it's beneficial for extracting common logic in the future.
src/pages/iou/WaypointEditor.js
Outdated
| }; | ||
|
|
||
| const deleteStopAndHideModal = () => { | ||
| setRestoreFocusType(CONST.MODAL.RESTORE_TYPE.DELETE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the focus type have to change dynamically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this case, when we remove a waypoint, the navigation will return to the distance page, the input is unmounted after refocusing is called, which can cause keyboard flickering. So setting the type to DELETE can avoid this issue. When clicking Cancel, we can set it back to DEFAULT to allow refocusing to continue working.
demo.mp4
|
I will take a deeper dive into this PR starting tomorrow. |
|
Hey both, just checking the progress here. It looks like there have been a decent amount of updates since the last review, but I see lint errors. @ntdiary is this ready for a second C+ review? |
@Julesssss, so far, the current implementation has fixed many cases. My updates are more aimed at resolving conflicts. |
|
Just updated the test cases, so far, the count is 23. :) |
Julesssss
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ntdiary, I didn't realise this would require so many test cases. Lets talk in the issue about increasing the bounty 👍
|
Yeah, I think the bounty should be increased for sure. Meanwhile, we should create a project and put other focus-related issues on hold so that we don't create new challenges for this PR. May be inform this on the C+ channel so that C+ can prevent that from happening. |
|
Hey @parasharrajat, bumping the review here now your back |
|
I thought we are breaking this PR into parts. @ntdiary Could you please confirm? |
|
@ntdiary can you provide an update on where we're at here? |
@mallenexpensify, yesterday, @getusha reported two bugs in the first small PR #35572, and I'm still investigating them. :) |
|
Hey @ntdiary, just checking in here for the next steps as the linked PRs were merged. |
@Julesssss, sorry for the delayed update. While I have reassigned all other new issues in the past few weeks, there are still two long-standing and relatively challenging issues that require my attention (#26239, #37596). Now that progress has been made on the other two issues, so expect to be able to raise a second small PR for this issue this week. 😂 |
|
Ah another new problem introduced by the new architecture 😅 |
|
Hey @ntdiary. Can we close this outdated PR? |
@Julesssss, sure! BTW, I noticed that some issues have been put on hold because of this PR, so I plan to look into them this week to see if I can offer any suggestions, just like issue #31224. :) |

So far, the
Modalcomponents under our control can be categorized into three types:BaseModal,PopoverWithoutOverlay, andRHP(Right Hand Panel).This PR will simulate the iOS native Modal refocusing behavior: If there is a focused input field before opening the
Modal, our app will attempt to restore that focus after theModalis dismissed. If there is no focus before opening, no restore after theModalis dismissed.Additionally, this PR will introduce a
restoreFocusTypeprop, here are possible values:default, this will follow the default behavior mentioned above.preserve, this will leave the focus in the manager and no longer restore focus, applicable for consecutive modal scenarios.delete, this will delete the focus and no longer restore focus, the caller can decide in its own business logic whether to focus a specific element.The specific business Modals that have been tested:
deleteactions will show this modal)Once the POC is approved by most people, we'll refine the code, clean things up, and then repush it.
Details
Fixed Issues
$ #29011
$ #24452
PROPOSAL: #24452 (comment)
Tests
context menu modal
case 1 (cancel action)
case 2 (add reaction + cancel action)
Add reactionto open the emoji modal.case 3 (edit coment)
Edit comment.case 4 (delete comment)
Delete commentto open theConfirmmodal.Deletebutton /Cancelbutton to close theConfirmmodal.emoji modal
case 1 (cancel action)
case 2 (cancel action)
case 3 (cancel action)
ios nativemain focus didn't show
Right Hand Panel
case 1 (test by mouse)
case 2 (test by keyboard shortcuts)
CMD + Jto open the keyboard shortcuts page.attachment modal
case 1 (cancel action)
case 2 (first attachment modal + RHP)
Request money/Send money/Assign task.it seems that the viewport api is not stable.
case 3 (all mobile platforms: cancel action for the second modal)
Add attachment.webdesktopcase 4 (cancel file selection)
Add attachment.Choose from gallery/Choose document.Cancelto cancel the file selection.case 5 (send an attachment)
Add attachment.Choose from gallery.Sendbutton.case 6 (send an invalid attachment, e.g. file size < 240B)
Add attachment.Choose document.Closebutton.case 7 (attachment preview modal)
case 8 (receipt preview modal + ThreeDotsMenu modal)
case 9 (receipt preview modal + ThreeDotsMenu modal + RHP)
Replaceoption.controlled by
useKeyboardManagercontrolled by
useKeyboardManagerThreeDotsMenu modal
case 1 (cancel action)
case 2 (delete action)
IOUreport.Delete requestto open theConfirmmodal.Cancelbutton to close theConfirmmodal.case 3 (waypoint editor, cancel action)
case 4 (waypoint editor, delete option + cancel action)
Deleteoption.Cancelbutton to close theConfirmmodal.case 5 (waypoint editor, delete option + confirm action)
Deleteoption.Deletebutton.Offline tests
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)myBool && <MyComponent />.src/languages/*files and using the translation methodWaiting for Copylabel for a copy review on the original GH to get the correct copy.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG))Avataris modified, I verified thatAvataris working as expected in all cases)ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop