+
setSearch(val)}
value={props.value.searchQuery}
- className="placeholder-denim-700 w-full flex-1 bg-transparent text-white focus:outline-none"
+ className="w-full flex-1 bg-transparent text-white placeholder-denim-700 focus:outline-none"
placeholder={props.placeholder}
/>
diff --git a/src/components/text-inputs/TextInputControl.tsx b/src/components/text-inputs/TextInputControl.tsx
index 65830fc8..a6d18994 100644
--- a/src/components/text-inputs/TextInputControl.tsx
+++ b/src/components/text-inputs/TextInputControl.tsx
@@ -1,5 +1,6 @@
export interface TextInputControlPropsNoLabel {
onChange?: (data: string) => void;
+ onUnFocus?: () => void;
value?: string;
placeholder?: string;
className?: string;
@@ -11,6 +12,7 @@ export interface TextInputControlProps extends TextInputControlPropsNoLabel {
export function TextInputControl({
onChange,
+ onUnFocus,
value,
label,
className,
@@ -23,6 +25,7 @@ export function TextInputControl({
placeholder={placeholder}
onChange={(e) => onChange && onChange(e.target.value)}
value={value}
+ onBlur={() => onUnFocus && onUnFocus()}
/>
);
diff --git a/src/hooks/useSearchQuery.ts b/src/hooks/useSearchQuery.ts
index f83e7715..f03d4668 100644
--- a/src/hooks/useSearchQuery.ts
+++ b/src/hooks/useSearchQuery.ts
@@ -1,19 +1,25 @@
import { MWMediaType, MWQuery } from "providers";
-import React, { useState } from "react";
+import React, { useRef, useState } from "react";
import { generatePath, useHistory, useRouteMatch } from "react-router-dom";
-export function useSearchQuery(): [MWQuery, (inp: Partial) => void] {
+export function useSearchQuery(): [
+ MWQuery,
+ (inp: Partial, force: boolean) => void,
+ () => void
+] {
const history = useHistory();
+ const isFirstRender = useRef(false);
const { path, params } = useRouteMatch<{ type: string; query: string }>();
const [search, setSearch] = useState({
searchQuery: "",
type: MWMediaType.MOVIE,
});
- const updateParams = (inp: Partial) => {
+ const updateParams = (inp: Partial, force: boolean) => {
const copySearch: MWQuery = { ...search };
Object.assign(copySearch, inp);
setSearch(copySearch);
+ if (!force) return;
history.replace(
generatePath(path, {
query:
@@ -23,13 +29,28 @@ export function useSearchQuery(): [MWQuery, (inp: Partial) => void] {
);
};
+ const onUnFocus = () => {
+ history.replace(
+ generatePath(path, {
+ query: search.searchQuery.length === 0 ? undefined : search.searchQuery,
+ type: search.type,
+ })
+ );
+ };
+
+ // only run on first load of the page
React.useEffect(() => {
+ if (isFirstRender.current === true) {
+ isFirstRender.current = false;
+ return;
+ }
+ isFirstRender.current = true;
const type =
Object.values(MWMediaType).find((v) => params.type === v) ||
MWMediaType.MOVIE;
const searchQuery = params.query || "";
setSearch({ type, searchQuery });
- }, [params, setSearch]);
+ }, [setSearch, params, isFirstRender]);
- return [search, updateParams];
+ return [search, updateParams, onUnFocus];
}
diff --git a/src/views/SearchView.tsx b/src/views/SearchView.tsx
index 3054a8f9..871ba69a 100644
--- a/src/views/SearchView.tsx
+++ b/src/views/SearchView.tsx
@@ -165,7 +165,7 @@ function ExtraItems() {
export function SearchView() {
const [searching, setSearching] = useState(false);
const [loading, setLoading] = useState(false);
- const [search, setSearch] = useSearchQuery();
+ const [search, setSearch, setSearchUnFocus] = useSearchQuery();
const debouncedSearch = useDebounce(search, 2000);
useEffect(() => {
@@ -182,7 +182,7 @@ export function SearchView() {
return (
setSearch({ searchQuery: "" })}
+ clear={() => setSearch({ searchQuery: "" }, true)}
/>
);
return ;
@@ -201,6 +201,7 @@ export function SearchView() {