Skip to content

Unable to dismiss iOS keyboard when input has focus in modal dialog #7131

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

Closed
jeffijoe opened this issue Oct 1, 2024 · 16 comments · Fixed by #7479
Closed

Unable to dismiss iOS keyboard when input has focus in modal dialog #7131

jeffijoe opened this issue Oct 1, 2024 · 16 comments · Fixed by #7479

Comments

@jeffijoe
Copy link
Contributor

jeffijoe commented Oct 1, 2024

Provide a general summary of the issue here

When an input field is focused in a dialog on Mobile Safari, the user is unable to dismiss the keyboard using the Done button.

🤔 Expected Behavior?

The user should be able to dismiss the keyboard.

😯 Current Behavior

The user is unable to dismiss the keyboard.

💁 Possible Solution

No response

🔦 Context

Not being able to dismiss the keyboard makes it hard to escape the dialog.

🖥️ Steps to Reproduce

This reproduces in the official Spectrum sample for dialog

focus-trap-bug-encoded.mp4

Version

Version live on Spectrum docs site

What browsers are you seeing the problem on?

Safari

If other, please specify.

No response

What operating system are you using?

iOS

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

@jeffijoe
Copy link
Contributor Author

jeffijoe commented Oct 2, 2024

Not sure if this caused by the same underlying issue, but when scrolling by dragging, if the scroll is initiated by touching an input or label element, on release, that element receives focus, resulting in unwanted jumping.

EDIT: Here's a video, I had to remove the footer elements to provide enough space to demo this

scroll-issue-encoded.mp4

EDIT 2: This issue also reproduces on Chrome for iOS, but not when using the device toolbar on Chrome for macOS.

@snowystinger
Copy link
Member

snowystinger commented Oct 2, 2024

In iOS Safari 18 I cannot close the Dialog in our first RAC example if I hit "done"

@ktabors
Copy link
Member

ktabors commented Oct 2, 2024

In iOS Safari 17 I can't reproduce this with the RSP Dialog "Register" example. Clicking "done" closes the keyboard. The form input navigation via the carrots does not work. In RAC modals both the "done" button and carrots work.

@jeffijoe
Copy link
Contributor Author

jeffijoe commented Oct 2, 2024

Just want to note that while the recordings were done on the simulator to show pointer path, I was also able to reproduce on an actual device at the time of recording the video I posted.

@jeffijoe
Copy link
Contributor Author

jeffijoe commented Oct 3, 2024

I tried again this morning and the original issue seems to no longer reproduce on the official sample, nor in my project which is on the previous version of RA and RAC. How odd 🤔

However, the focus jumping is still a problem since it makes it incredibly difficult for the user to scroll a form in a modal. Should I open a new issue for that?

@snowystinger
Copy link
Member

snowystinger commented Oct 3, 2024

You can leave this one open. We need to do some investigating into all the things mentioned here so far and they are likely related. I think once someone has identified some paths forward we can consider breaking it apart.

@devongovett
Copy link
Member

Maybe due to

let onTouchEnd = (e: TouchEvent) => {
let target = e.target as HTMLElement;
// Apply this change if we're not already focused on the target element
if (willOpenKeyboard(target) && target !== document.activeElement) {
e.preventDefault();
setupStyles();
// Apply a transform to trick Safari into thinking the input is at the top of the page
// so it doesn't try to scroll it into view. When tapping on an input, this needs to
// be done before the "focus" event, so we have to focus the element ourselves.
target.style.transform = 'translateY(-2000px)';
target.focus();

Looks like touchend is fired on the original target of the touchstart event even if your finger isn't over it anymore. Unfortunately touchcancel isn't fired on scroll like pointercancel is, and pointerup's preventDefault also doesn't prevent the default browser focus.

In my brief testing it looks like we may be able to remove this touchend handler entirely now, and rely on the onFocus handler instead. I don't see the original issue mentioned in the comments anymore so it may have been fixed in newer versions of iOS.

@jeffijoe
Copy link
Contributor Author

jeffijoe commented Dec 5, 2024

Thank you for looking into this, I really appreciate it @devongovett ! 🙏

Yes it's very odd about the original issue is that 2 days later I couldn't reproduce it on either the simulator or a real device, I hadn't updated anything - I tried both on the Spectrum site and my local app. If I hadn't caught it on video I would have thought I'd gone insane 😂

@ztsmith
Copy link

ztsmith commented Dec 9, 2024

@devongovett tested this on IPhone 15 (iOS 17.2), using the first modal example from the rac docs and still unable to dismiss the iOS keyboard. Clicking done has no affect.

@devongovett
Copy link
Member

It's not released yet.

@ztsmith
Copy link

ztsmith commented Dec 9, 2024

sorry I should have specified - I did test with the fixed source code.

It feels like the issue is in the focus scoping. When I apply disableFocusManagement to the Overlay component it works.

@nataliawalasik
Copy link

Hey @devongovett ,
The issue still exists in iOS and Android devices.
Steps to reproduce are the same, open an example from the official site https://react-spectrum.adobe.com/react-spectrum/Dialog.html . Removing the dialog component helps a bit, but it has some weird behavior.

Could you take a look?

@snowystinger
Copy link
Member

What version of iOS are you on? I'm unable to reproduce on 18.3

@nataliawalasik
Copy link

What version of iOS are you on? I'm unable to reproduce on 18.3

I'm using iOS 18.1 on iPhone 13 Pro. It can also be reproduced on ios simulator 18.2

On Android 15 (Pixel 6a) switching between fields causes Dialog bumping when a keyboard is opened.

@snowystinger
Copy link
Member

I am not sure how reliable the ios simulator is. I'm unable to get the keyboard to fully display at all anywhere on the 18.2 one? Did you run into an issue where only the very top of the keyboard would appear?

On Android 11, Galaxy A10e, I cannot reproduce either. This is a pretty old phone and os though, so maybe not most representative.

@jeffijoe
Copy link
Contributor Author

Did you run into an issue where only the very top of the keyboard would appear?

While I was testing, I did run into this as well. I figured that was some hiccup due to the Simulator likely thinking there's a hardware keyboard connected? Not entirely sure about that one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants