improve Searcher methods

This commit is contained in:
SrGooglo 2023-05-30 00:58:28 +00:00
parent 3fad41fc14
commit d5cd03ac37
2 changed files with 81 additions and 21 deletions

View File

@ -1,6 +1,8 @@
import React from "react" import React from "react"
import * as antd from "antd" import * as antd from "antd"
import classnames from "classnames" import classnames from "classnames"
import useUrlQueryActiveKey from "hooks/useUrlQueryActiveKey"
import lodash from "lodash"
import { UserPreview } from "components" import { UserPreview } from "components"
import { Icons, createIconRender } from "components/Icons" import { Icons, createIconRender } from "components/Icons"
@ -83,21 +85,47 @@ const Results = (props) => {
}) })
} }
export default (props) => { export default (props) => {
const [loading, setLoading] = React.useState(false) const [loading, setLoading] = React.useState(false)
const [searchResult, setSearchResult] = React.useState(null) const [searchResult, setSearchResult] = React.useState(null)
const [searchValue, setSearchValue] = React.useState("") const [searchValue, setSearchValue] = React.useState("")
const [query, setQuery] = useUrlQueryActiveKey({
queryKey: "search",
defaultKey: null
})
const makeSearch = async (value) => { const makeSearch = async (value) => {
if (value === "") { if (value === "") {
return setSearchResult(null) return setSearchResult(null)
} }
const result = await SearchModel.search(value) setLoading(true)
if (props.useUrlQuery) {
setQuery(value)
}
let result = null
if (typeof props.model === "function") {
result = await props.model(value)
} else {
result = await SearchModel.search(value)
}
if (typeof props.onSearchResult === "function") {
await props.onSearchResult(result)
}
setLoading(false)
return setSearchResult(result) return setSearchResult(result)
} }
const debounceSearch = React.useCallback(lodash.debounce(makeSearch, 500), [])
const handleOnSearch = (e) => { const handleOnSearch = (e) => {
// not allow to input space as first character // not allow to input space as first character
if (e.target.value[0] === " ") { if (e.target.value[0] === " ") {
@ -105,6 +133,22 @@ export default (props) => {
} }
setSearchValue(e.target.value) setSearchValue(e.target.value)
if (e.target.value === "") {
if (props.useUrlQuery) {
setQuery(null)
}
if (typeof props.onEmpty === "function") {
props.onEmpty()
}
} else {
if (typeof props.onFilled === "function") {
props.onFilled()
}
debounceSearch(e.target.value)
}
} }
const handleResultClick = (type, value) => { const handleResultClick = (type, value) => {
@ -130,29 +174,22 @@ export default (props) => {
} }
React.useEffect(() => { React.useEffect(() => {
const timer = setTimeout(async () => { if (props.useUrlQuery) {
setLoading(true) if (typeof query === "string") {
makeSearch(query)
await makeSearch(searchValue) setSearchValue(query)
setLoading(false)
}, 400)
if (searchValue === "") {
if (typeof props.onEmpty === "function") {
props.onEmpty()
}
} else {
if (typeof props.onFilled === "function") {
props.onFilled()
} }
} }
}, [])
return () => clearTimeout(timer)
}, [searchValue])
return <div return <div
className={classnames("searcher", { ["open"]: searchValue })} className={classnames(
"searcher",
{
["open"]: searchValue,
["small"]: props.small,
}
)}
> >
<antd.Input <antd.Input
placeholder="Start typing to search..." placeholder="Start typing to search..."
@ -164,7 +201,7 @@ export default (props) => {
onBlur={props.onUnfocus} onBlur={props.onUnfocus}
/> />
{searchResult && <div className="results"> {searchResult && props.renderResults && <div className="results">
{loading && <antd.Skeleton active />} {loading && <antd.Skeleton active />}
{ {
!loading && <Results !loading && <Results

View File

@ -11,7 +11,28 @@
gap: 20px; gap: 20px;
&.small {
.ant-input-affix-wrapper {
padding: 7px;
height: fit-content;
.ant-input-prefix {
font-size: 1rem;
}
.ant-input {
font-size: 0.8rem;
}
}
}
.ant-input-affix-wrapper { .ant-input-affix-wrapper {
display: inline-flex;
flex-direction: row;
align-items: center;
border: 0; border: 0;
padding: 0; padding: 0;
margin: 0; margin: 0;
@ -34,6 +55,8 @@
color: var(--text-color); color: var(--text-color);
font-size: 1rem; font-size: 1rem;
margin: 0;
} }
} }