diff --git a/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx b/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx index fb99c05478c..b60157c6647 100644 --- a/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx +++ b/app/javascript/mastodon/features/navigation_panel/redesign/index.tsx @@ -27,6 +27,7 @@ import { openNewComposer } from '@/mastodon/reducers/slices/composer'; import { getOrderedLists } from '@/mastodon/selectors/lists'; import { selectUnreadNotificationGroupsCount } from '@/mastodon/selectors/notifications'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; +import { invokeVirtualIosKeyboard } from '@/mastodon/utils/invoke_virtual_ios_keyboard'; import { NavigationAccountCardAndMenu } from './account_card_and_menu'; import { NavigationFooterLinks } from './footer_links'; @@ -151,6 +152,7 @@ export const RedesignNavigationPanel: React.FC<{ state: { focusTarget: FOCUS_TARGET.SEARCH }, }} iconComponent={MagnifyingGlassIcon} + onClick={invokeVirtualIosKeyboard} > { state: { focusTarget: FOCUS_TARGET.SEARCH }, }} iconComponent={MagnifyingGlassIcon} + onClick={invokeVirtualIosKeyboard} > diff --git a/app/javascript/mastodon/utils/invoke_virtual_ios_keyboard.module.css b/app/javascript/mastodon/utils/invoke_virtual_ios_keyboard.module.css new file mode 100644 index 00000000000..008937b5ecd --- /dev/null +++ b/app/javascript/mastodon/utils/invoke_virtual_ios_keyboard.module.css @@ -0,0 +1,9 @@ +.dummyInput { + position: absolute; + top: 0; + width: 1px; + height: 1px; + overflow: hidden; + font-size: 16px; + opacity: 0.01; +} diff --git a/app/javascript/mastodon/utils/invoke_virtual_ios_keyboard.ts b/app/javascript/mastodon/utils/invoke_virtual_ios_keyboard.ts new file mode 100644 index 00000000000..a97102c91fd --- /dev/null +++ b/app/javascript/mastodon/utils/invoke_virtual_ios_keyboard.ts @@ -0,0 +1,16 @@ +import classes from './invoke_virtual_ios_keyboard.module.css'; + +export function invokeVirtualIosKeyboard() { + // To ensure that a virtual keyboard is shown on iOS when + // auto-focusing an input, we create a dummy input that + // we briefly attach to the DOM to capture focus, then let + // our regular FocusNavigationTarget handling take over. + const dummyInput = document.createElement('input'); + dummyInput.className = classes.dummyInput ?? ''; + dummyInput.onblur = () => { + // Cleanup: Remove the dummy input after focus was moved away from it + dummyInput.remove(); + }; + document.body.appendChild(dummyInput); + dummyInput.focus(); +}