|
1 | 1 | import { FloatingOverlay } from "@floating-ui/react"; |
2 | 2 | import type { SuggestionProps } from "@tiptap/suggestion"; |
3 | | -import { |
4 | | - forwardRef, |
5 | | - useCallback, |
6 | | - useEffect, |
7 | | - useImperativeHandle, |
8 | | - useLayoutEffect, |
9 | | - useMemo, |
10 | | - useRef, |
11 | | - useState, |
12 | | -} from "react"; |
| 3 | +import { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react"; |
13 | 4 | import { v4 as uuidv4 } from "uuid"; |
14 | 5 | import { debounce } from "lodash-es"; |
15 | 6 | // plane utils |
@@ -85,34 +76,38 @@ export const MentionsListDropdown = forwardRef(function MentionsListDropdown(pro |
85 | 76 | }); |
86 | 77 | }, [sections]); |
87 | 78 |
|
88 | | - // create debounced search callback |
89 | | - const debouncedSearchCallback = useMemo( |
90 | | - () => |
91 | | - debounce(async (searchQuery: string) => { |
92 | | - setIsLoading(true); |
93 | | - try { |
94 | | - const sectionsResponse = await searchCallback?.(searchQuery); |
95 | | - if (sectionsResponse) { |
96 | | - setSections(sectionsResponse); |
97 | | - } |
98 | | - } catch (error) { |
99 | | - console.error("Failed to fetch suggestions:", error); |
100 | | - } finally { |
101 | | - setIsLoading(false); |
| 79 | + // debounced search callback |
| 80 | + const debouncedSearchCallback = useCallback( |
| 81 | + debounce(async (searchQuery: string) => { |
| 82 | + setIsLoading(true); |
| 83 | + try { |
| 84 | + const sectionsResponse = await searchCallback?.(searchQuery); |
| 85 | + if (sectionsResponse) { |
| 86 | + setSections(sectionsResponse); |
102 | 87 | } |
103 | | - }, 300), |
| 88 | + } catch (error) { |
| 89 | + console.error("Failed to fetch suggestions:", error); |
| 90 | + } finally { |
| 91 | + setIsLoading(false); |
| 92 | + } |
| 93 | + }, 300), |
104 | 94 | [searchCallback] |
105 | 95 | ); |
106 | 96 |
|
| 97 | + // trigger debounced search when query changes |
107 | 98 | useEffect(() => { |
108 | 99 | if (query) { |
109 | 100 | void debouncedSearchCallback(query); |
110 | 101 | } |
| 102 | + }, [query, debouncedSearchCallback]); |
111 | 103 |
|
112 | | - return () => { |
| 104 | + // cancel pending debounced calls on unmount |
| 105 | + useEffect( |
| 106 | + () => () => { |
113 | 107 | debouncedSearchCallback.cancel(); |
114 | | - }; |
115 | | - }, [query, debouncedSearchCallback]); |
| 108 | + }, |
| 109 | + [debouncedSearchCallback] |
| 110 | + ); |
116 | 111 |
|
117 | 112 | // scroll to the dropdown item when navigating via keyboard |
118 | 113 | useLayoutEffect(() => { |
|
0 commit comments