fix(FN-1207): improve mobile header search behavior

- Replace delayed focus effect with native autoFocus on the mobile search input
- Constrain expanded mobile search positioning and width to prevent overflow on small viewports
- Add Header tests covering mobile search auto-focus and expanded container rendering
This commit is contained in:
gsxdsm
2026-04-08 15:41:18 -07:00
parent d66300c794
commit 0304a3df20
3 changed files with 42 additions and 10 deletions

View File

@@ -195,13 +195,6 @@ export function Header({
return () => document.removeEventListener("keydown", handleKeyDown);
}, []);
// Focus input when mobile search opens
useEffect(() => {
if (isMobileSearchOpen && mobileSearchInputRef.current) {
setTimeout(() => mobileSearchInputRef.current?.focus(), 0);
}
}, [isMobileSearchOpen]);
const handleMobileSearchToggle = useCallback(() => {
setIsMobileSearchOpen((prev) => !prev);
}, []);
@@ -335,6 +328,7 @@ export function Header({
<Search size={14} className="header-search-icon" />
<input
ref={mobileSearchInputRef}
autoFocus
type="text"
placeholder="Search tasks..."
value={searchQuery}

View File

@@ -459,6 +459,44 @@ describe("Header", () => {
expect(screen.getByPlaceholderText("Search tasks...")).toBeDefined();
});
it("focuses mobile search input when expanded", async () => {
const onSearchChange = vi.fn();
render(
<Header
view="board"
onChangeView={vi.fn()}
searchQuery=""
onSearchChange={onSearchChange}
/>
);
fireEvent.click(screen.getByTitle("Open search"));
const input = screen.getByPlaceholderText("Search tasks...") as HTMLInputElement;
await waitFor(() => {
expect(document.activeElement).toBe(input);
});
});
it("renders expanded mobile search container with expected class", () => {
const onSearchChange = vi.fn();
render(
<Header
view="board"
onChangeView={vi.fn()}
searchQuery=""
onSearchChange={onSearchChange}
/>
);
fireEvent.click(screen.getByTitle("Open search"));
const input = screen.getByPlaceholderText("Search tasks...");
const expandedContainer = input.closest(".mobile-search-expanded");
expect(expandedContainer).not.toBeNull();
expect(expandedContainer?.className).toContain("mobile-search-expanded");
});
it("mobile search stays expanded when searchQuery is non-empty", () => {
const onSearchChange = vi.fn();
render(

View File

@@ -5747,13 +5747,13 @@ body {
.mobile-search-expanded {
position: absolute;
right: 140px;
right: 0;
left: auto;
top: 50%;
transform: translateY(-50%);
width: 200px;
max-width: 200px;
min-width: 160px;
max-width: calc(100vw - 140px - var(--space-md) * 2);
min-width: 120px;
z-index: 10;
background: var(--surface);
box-shadow: var(--shadow-md);