Skip to content

Commit

Permalink
Merge pull request #170 from Cyriuz/search-clear-button
Browse files Browse the repository at this point in the history
feat: added a clear button to the search bar
  • Loading branch information
Cyriuz committed May 24, 2022
1 parent 3128d8d commit f516123
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,17 @@ html[data-theme="dark"] .noResultsIcon {
top: 6px;
}

.searchBarContainer .searchClearButton {
position: absolute;
right: 0.8rem;
top: 50%;
transform: translate(0, -50%);
padding: 0;
background: none;
border: none;
line-height: 1rem;
}

:global(.navbar__search) {
position: relative;
}
Expand Down
49 changes: 38 additions & 11 deletions docusaurus-search-local/src/client/theme/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export default function SearchBar({
const focusAfterIndexLoaded = useRef(false);
const [loading, setLoading] = useState(false);
const [inputChanged, setInputChanged] = useState(false);
const [inputValue, setInputValue] = useState("");
const search = useRef<any>(null);

const loadIndex = useCallback(async () => {
if (indexState.current !== "empty") {
Expand All @@ -69,7 +71,7 @@ export default function SearchBar({
fetchAutoCompleteJS(),
]);

const search = autoComplete(
search.current = autoComplete(
searchBarRef.current,
{
hint: false,
Expand Down Expand Up @@ -112,7 +114,7 @@ export default function SearchBar({
a.addEventListener("click", (e) => {
if (!e.ctrlKey && !e.metaKey) {
e.preventDefault();
search.autocomplete.close();
search.current.autocomplete.close();
history.push(url);
}
});
Expand Down Expand Up @@ -154,7 +156,7 @@ export default function SearchBar({
if (focusAfterIndexLoaded.current) {
const input = searchBarRef.current as HTMLInputElement;
if (input.value) {
search.autocomplete.open();
search.current.autocomplete.open();
}
input.focus();
}
Expand All @@ -167,9 +169,6 @@ export default function SearchBar({
const keywords = ExecutionEnvironment.canUseDOM
? new URLSearchParams(location.search).getAll(SEARCH_PARAM_HIGHLIGHT)
: [];
if (keywords.length === 0) {
return;
}
// A workaround to fix an issue of highlighting in code blocks.
// See https://github.com/easyops-cn/docusaurus-search-local/issues/92
// Code blocks will be re-rendered after this `useEffect` ran.
Expand All @@ -181,7 +180,13 @@ export default function SearchBar({
}
const mark = new Mark(root);
mark.unmark();
mark.mark(keywords);
if (keywords.length !== 0) {
mark.mark(keywords);
}

// Apply any keywords to the search input so that we can clear marks in case we loaded a page with a highlight in the url
setInputValue(keywords.join(" "));
search.current?.autocomplete.setVal(keywords.join(" "));
});
}, [location.search, location.pathname]);

Expand All @@ -201,6 +206,7 @@ export default function SearchBar({

const onInputChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
if (event.target.value) {
setInputChanged(true);
}
Expand Down Expand Up @@ -231,6 +237,20 @@ export default function SearchBar({
};
}, [isMac, onInputFocus]);

const onClearSearch = useCallback(() => {
const params = new URLSearchParams(location.search);
params.delete(SEARCH_PARAM_HIGHLIGHT);
let paramsStr = params.toString();
let searchUrl = location.pathname + (paramsStr != "" ? `?${paramsStr}` : "") + location.hash;
if (searchUrl != location.pathname + location.search + location.hash) {
history.push(searchUrl);
}

// We always clear these here because in case no match was selected the above history push wont happen
setInputValue("");
search.current?.autocomplete.setVal("");
}, [location.pathname, location.search, location.hash]);

return (
<div
className={clsx("navbar__search", styles.searchBarContainer, {
Expand All @@ -250,12 +270,19 @@ export default function SearchBar({
onBlur={onInputBlur}
onChange={onInputChange}
ref={searchBarRef}
value={inputValue}
/>
<LoadingRing className={styles.searchBarLoadingRing} />
<div className={styles.searchHintContainer}>
<kbd className={styles.searchHint}>{isMac ? "⌘" : "ctrl"}</kbd>
<kbd className={styles.searchHint}>K</kbd>
</div>
{inputValue !== "" ? (
<button className={styles.searchClearButton} onClick={onClearSearch}>
</button>
) : (
<div className={styles.searchHintContainer}>
<kbd className={styles.searchHint}>{isMac ? "⌘" : "ctrl"}</kbd>
<kbd className={styles.searchHint}>K</kbd>
</div>
)}
</div>
);
}

0 comments on commit f516123

Please sign in to comment.