diff --git a/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js b/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js index 77ad537c3dc3c69b9f95ff4a0166bcc5bfd1867e..3f103e40a3c16e222ed7bfe9d922e0dd82042c0a 100644 --- a/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js +++ b/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js @@ -100,6 +100,38 @@ const Svg = styled.svg.attrs(() => ({ width: 24px; `; +const useDebounce = (value, delay) => { + // State and setters for debounced value + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect( + () => { + // Set debouncedValue to value (passed in) after the specified delay + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + // Return a cleanup function that will be called every time ... + // ... useEffect is re-called. useEffect will only be re-called ... + // ... if value changes (see the inputs array below). + // This is how we prevent debouncedValue from changing if value is ... + // ... changed within the delay period. Timeout gets cleared and restarted. + // To put it in context, if the user is typing within our app's ... + // ... search box, we don't want the debouncedValue to update until ... + // ... they've stopped typing for more than 500ms. + return () => { + clearTimeout(handler); + }; + }, + // Only re-call effect if value changes + // You could also add the "delay" var to inputs array if you ... + // ... need to be able to change that dynamically. + [value], + ); + + return debouncedValue; +}; + const FindComponent = ({ close, expand, @@ -119,32 +151,29 @@ const FindComponent = ({ const allStates = []; + const debouncedSearchTerm = useDebounce(searchValue, 300); + each(view, (singleView, viewId) => { allStates.push(singleView.state); }); - const delayedSearch = useCallback( - debounce(() => searchDocument(), 300), - [searchValue, matchCaseSearch, activeViewId], - ); + // const delayedSearch = useCallback(searchDocument(), [ + // (debouncedSearchTerm, matchCaseSearch, activeViewId), + // ]); const onChange = () => { setSearchValue(searchRef.current.value); }; useEffect(() => { - delayedSearch(); - let counter = 0; - counter = helpers.getMatchesByView(view, searchValue, matchCaseSearch); - - setCounterSearches(counter); + searchDocument(); if (isFirstRun) { setTimeout(() => { searchRef.current.focus(); setFirstRun(false); }); } - }, [searchValue, delayedSearch, matchCaseSearch, JSON.stringify(allStates)]); + }, [debouncedSearchTerm, matchCaseSearch, JSON.stringify(allStates)]); const setCounterSearches = counter => { if (counter === 0) return setCounterText('0 of 0'); @@ -195,11 +224,16 @@ const FindComponent = ({ }; const searchDocument = () => { - findAndReplacePlugin.props.setSearchText(searchValue); + let counter = 0; + if (searchValue === '') { + findAndReplacePlugin.props.setSearchText(''); + } else { + findAndReplacePlugin.props.setSearchText(searchValue); + } findAndReplacePlugin.props.setSearchMatchCase(matchCaseSearch); - // let counter = 0; - // counter = helpers.getMatchesByView(view, searchValue, matchCaseSearch); - // setCounterSearches(counter); + counter = helpers.getMatchesByView(view, searchValue, matchCaseSearch); + + setCounterSearches(counter); if (searchRef.current === document.activeElement) { eachRight(view, (singleView, viewId) => {