mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-12 12:04:16 +00:00
improve Searcher
methods
This commit is contained in:
parent
3fad41fc14
commit
d5cd03ac37
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user