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:
@@ -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}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user