diff --git a/app/components/MobileNav.module.css b/app/components/MobileNav.module.css index dceb4d3b1..873433d75 100644 --- a/app/components/MobileNav.module.css +++ b/app/components/MobileNav.module.css @@ -11,11 +11,6 @@ background: none; color: inherit; z-index: 19; - - --mobile-nav-height: calc( - var(--layout-nav-height) + - env(safe-area-inset-bottom) - ); } @media screen and (min-width: 600px) { @@ -25,7 +20,7 @@ } .tabBar { - display: flex; + display: var(--mobile-tab-bar-display); justify-content: space-around; align-items: center; height: var(--mobile-nav-height); diff --git a/app/components/elements/Select.browser.test.tsx b/app/components/elements/Select.browser.test.tsx index 5efe7baf5..56ec98e73 100644 --- a/app/components/elements/Select.browser.test.tsx +++ b/app/components/elements/Select.browser.test.tsx @@ -69,6 +69,15 @@ describe("SendouSelect", () => { .not.toBeInTheDocument(); }); + test("focuses the search input within the opening click", async () => { + const screen = await render(); + const trigger = screen.getByRole("button").element() as HTMLButtonElement; + + trigger.click(); + + expect(document.activeElement).toBe(screen.getByRole("combobox").element()); + }); + test("shows the empty state when nothing matches the search", async () => { const screen = await render(); diff --git a/app/components/elements/Select.tsx b/app/components/elements/Select.tsx index b29fcaf18..2229a64db 100644 --- a/app/components/elements/Select.tsx +++ b/app/components/elements/Select.tsx @@ -1,6 +1,7 @@ import clsx from "clsx"; import { ChevronsUpDown, Search, X } from "lucide-react"; import * as React from "react"; +import { flushSync } from "react-dom"; import { useTranslation } from "react-i18next"; import { SendouBottomTexts } from "~/components/elements/BottomTexts"; import { SendouButton } from "~/components/elements/Button"; @@ -299,6 +300,14 @@ export function SendouSelect({ scrollIntoView(targetKey); }; + // iOS only brings up the keyboard for a focus inside the tap itself, but the native + // open is redone a frame later (useShowPopoverOnOpen), so a searchable select opens here + const onTriggerClick = (event: React.MouseEvent) => { + if (!search || open) return; + event.preventDefault(); + flushSync(() => setOpen(true)); + }; + const onTriggerKeyDown = (event: React.KeyboardEvent) => { if (event.key === "ArrowDown" || event.key === "ArrowUp") { event.preventDefault(); @@ -535,6 +544,7 @@ export function SendouSelect({ } data-required={isRequired || undefined} {...popoverTriggerProps} + onClick={onTriggerClick} onKeyDown={onTriggerKeyDown} >