react-spectrum icon indicating copy to clipboard operation
react-spectrum copied to clipboard

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

Open jeffijoe opened this issue 1 year ago โ€ข 6 comments

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

https://github.com/user-attachments/assets/77142acc-d21b-42a7-8b27-65e24d811bd4

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 avatar Oct 01 '24 18:10 jeffijoe

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

https://github.com/user-attachments/assets/93a61b42-45d9-492e-90b6-87b9241174ae

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

jeffijoe avatar Oct 02 '24 15:10 jeffijoe

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

snowystinger avatar Oct 02 '24 21:10 snowystinger

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.

ktabors avatar Oct 02 '24 21:10 ktabors

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 avatar Oct 02 '24 22:10 jeffijoe

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?

jeffijoe avatar Oct 03 '24 09:10 jeffijoe

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.

snowystinger avatar Oct 03 '24 10:10 snowystinger

Maybe due to https://github.com/adobe/react-spectrum/blob/7eae25e124a9d235ff30f12bd86383b894a1ea04/packages/%40react-aria/overlays/src/usePreventScroll.ts#L142-L154

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.

devongovett avatar Dec 05 '24 04:12 devongovett

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 ๐Ÿ˜‚

jeffijoe avatar Dec 05 '24 10:12 jeffijoe

@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.

ztsmith avatar Dec 09 '24 02:12 ztsmith

It's not released yet.

devongovett avatar Dec 09 '24 02:12 devongovett

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.

ztsmith avatar Dec 09 '24 02:12 ztsmith

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?

nataliawalasik avatar Feb 11 '25 07:02 nataliawalasik

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

snowystinger avatar Feb 11 '25 11:02 snowystinger

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.

nataliawalasik avatar Feb 11 '25 11:02 nataliawalasik

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.

snowystinger avatar Feb 11 '25 20:02 snowystinger

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.

jeffijoe avatar Feb 11 '25 21:02 jeffijoe