Safari's approach to focus
is that it will only work within the same event loop. Therefore, if it's inside a Promise
or a timeout, it will not open the keyboard.
By today, it's impossible to open the keyboard after the timeout.
The only workaround you have is to use this hack:
/**
* iOS keyboard can only be opened by user interaction + focus event.
* There are situations in which we need to open keyboard programmatically
* before other elements are rendered, like when opening an overlay. this function can be used
* to open the keyboard before the overlay is rendered, and once the overlay is
* rendered, it's needed to focus to the desired input element, and the keyboard
* will stay open.
*
* This function needs to be called from native events attached to HTML elements. It will
* not work if called from a "passive" event, or after any event not coming from
* user interaction (onLoad, onFocus, etc).
*
* It's recommended to use it on MouseEvents or TouchEvents.
*/
export function openIosKeyboard() {
const input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("style", "position: fixed; top: -100px; left: -100px;");
document.body.appendChild(input);
input.focus();
// it's safe to remove the fake input after a 30s timeout
setTimeout(() => {
document.body.removeChild(input);
}, 30 * 1000);
}