2
0
Эх сурвалжийг харах

fix: `select` instead of `focus` search input (#8483)

David Luzar 1 жил өмнө
parent
commit
d107215564

+ 4 - 12
packages/excalidraw/components/SearchMenu.tsx

@@ -10,8 +10,6 @@ import type { ExcalidrawTextElement } from "../element/types";
 import { measureText } from "../element/textElement";
 import { measureText } from "../element/textElement";
 import { addEventListener, getFontString } from "../utils";
 import { addEventListener, getFontString } from "../utils";
 import { KEYS } from "../keys";
 import { KEYS } from "../keys";
-
-import "./SearchMenu.scss";
 import clsx from "clsx";
 import clsx from "clsx";
 import { atom, useAtom } from "jotai";
 import { atom, useAtom } from "jotai";
 import { jotaiScope } from "../jotai";
 import { jotaiScope } from "../jotai";
@@ -21,6 +19,8 @@ import { randomInteger } from "../random";
 import { CLASSES, EVENT } from "../constants";
 import { CLASSES, EVENT } from "../constants";
 import { useStable } from "../hooks/useStable";
 import { useStable } from "../hooks/useStable";
 
 
+import "./SearchMenu.scss";
+
 const searchKeywordAtom = atom<string>("");
 const searchKeywordAtom = atom<string>("");
 export const searchItemInFocusAtom = atom<number | null>(null);
 export const searchItemInFocusAtom = atom<number | null>(null);
 
 
@@ -229,6 +229,7 @@ export const SearchMenu = () => {
             });
             });
           }
           }
           searchInputRef.current?.focus();
           searchInputRef.current?.focus();
+          searchInputRef.current?.select();
         } else {
         } else {
           setAppState({
           setAppState({
             openSidebar: null,
             openSidebar: null,
@@ -264,16 +265,6 @@ export const SearchMenu = () => {
     });
     });
   }, [setAppState, stableState, app]);
   }, [setAppState, stableState, app]);
 
 
-  /**
-   * NOTE:
-   *
-   * for testing purposes, we're manually focusing instead of
-   * setting `selectOnRender` on <TextField>
-   */
-  useEffect(() => {
-    searchInputRef.current?.focus();
-  }, []);
-
   const matchCount = `${searchMatches.items.length} ${
   const matchCount = `${searchMatches.items.length} ${
     searchMatches.items.length === 1
     searchMatches.items.length === 1
       ? t("search.singleResult")
       ? t("search.singleResult")
@@ -292,6 +283,7 @@ export const SearchMenu = () => {
           onChange={(value) => {
           onChange={(value) => {
             setKeyword(value);
             setKeyword(value);
           }}
           }}
+          selectOnRender
         />
         />
       </div>
       </div>
 
 

+ 2 - 0
packages/excalidraw/components/TextField.tsx

@@ -51,6 +51,8 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
 
 
     useLayoutEffect(() => {
     useLayoutEffect(() => {
       if (selectOnRender) {
       if (selectOnRender) {
+        // focusing first is needed because vitest/jsdom
+        innerRef.current?.focus();
         innerRef.current?.select();
         innerRef.current?.select();
       }
       }
     }, [selectOnRender]);
     }, [selectOnRender]);

+ 4 - 3
packages/excalidraw/tests/helpers/api.ts

@@ -76,11 +76,12 @@ export class API {
     });
     });
   };
   };
 
 
-  static updateElement = (
-    ...[element, updates]: Parameters<typeof mutateElement>
+  // eslint-disable-next-line prettier/prettier
+  static updateElement = <T extends ExcalidrawElement>(
+    ...args: Parameters<typeof mutateElement<T>>
   ) => {
   ) => {
     act(() => {
     act(() => {
-      mutateElement(element, updates);
+      mutateElement<T>(...args);
     });
     });
   };
   };
 
 

+ 7 - 5
packages/excalidraw/tests/search.test.tsx

@@ -1,6 +1,6 @@
 import React from "react";
 import React from "react";
-import { render, waitFor } from "./test-utils";
-import { Excalidraw, mutateElement } from "../index";
+import { act, render, waitFor } from "./test-utils";
+import { Excalidraw } from "../index";
 import { CLASSES, SEARCH_SIDEBAR } from "../constants";
 import { CLASSES, SEARCH_SIDEBAR } from "../constants";
 import { Keyboard } from "./helpers/ui";
 import { Keyboard } from "./helpers/ui";
 import { KEYS } from "../keys";
 import { KEYS } from "../keys";
@@ -22,7 +22,7 @@ const querySearchInput = async () => {
 describe("search", () => {
 describe("search", () => {
   beforeEach(async () => {
   beforeEach(async () => {
     await render(<Excalidraw handleKeyboardGlobally />);
     await render(<Excalidraw handleKeyboardGlobally />);
-    h.setState({
+    API.setAppState({
       openSidebar: null,
       openSidebar: null,
     });
     });
   });
   });
@@ -50,7 +50,9 @@ describe("search", () => {
         `.${CLASSES.SEARCH_MENU_INPUT_WRAPPER} input`,
         `.${CLASSES.SEARCH_MENU_INPUT_WRAPPER} input`,
       );
       );
 
 
-    searchInput?.blur();
+    act(() => {
+      searchInput?.blur();
+    });
 
 
     expect(h.app.state.openSidebar).not.toBeNull();
     expect(h.app.state.openSidebar).not.toBeNull();
     expect(searchInput?.matches(":focus")).toBe(false);
     expect(searchInput?.matches(":focus")).toBe(false);
@@ -109,7 +111,7 @@ describe("search", () => {
       }),
       }),
     ]);
     ]);
 
 
-    mutateElement(h.elements[0] as ExcalidrawTextElement, {
+    API.updateElement(h.elements[0] as ExcalidrawTextElement, {
       text: "t\ne\ns\nt \nt\ne\nx\nt \ns\np\nli\nt \ni\nn\nt\no\nm\nu\nlt\ni\np\nl\ne \nli\nn\ne\ns",
       text: "t\ne\ns\nt \nt\ne\nx\nt \ns\np\nli\nt \ni\nn\nt\no\nm\nu\nlt\ni\np\nl\ne \nli\nn\ne\ns",
       originalText: "test text split into multiple lines",
       originalText: "test text split into multiple lines",
     });
     });