mirror of
https://github.com/zhigang1992/react.git
synced 2026-02-07 22:41:59 +08:00
feat(auto-complete): add control for free solo
This commit is contained in:
@@ -28,9 +28,10 @@ const AutoCompleteItem: React.FC<React.PropsWithChildren<AutoCompleteItemProps>>
|
||||
children,
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const { value, updateValue, size } = useAutoCompleteContext()
|
||||
const { value, updateValue, size, updateVisible } = useAutoCompleteContext()
|
||||
const selectHandler = () => {
|
||||
updateValue && updateValue(identValue)
|
||||
updateVisible && updateVisible(false)
|
||||
}
|
||||
|
||||
const isActive = useMemo(() => value === identValue, [identValue, value])
|
||||
|
||||
@@ -8,6 +8,7 @@ import { AutoCompleteContext, AutoCompleteConfig } from './auto-complete-context
|
||||
import { NormalSizes, NormalTypes } from '../utils/prop-types'
|
||||
import Loading from '../loading'
|
||||
import { pickChild } from '../utils/collections'
|
||||
import useCurrentState from '../utils/use-current-state'
|
||||
|
||||
export type AutoCompleteOption = {
|
||||
label: string
|
||||
@@ -31,6 +32,7 @@ interface Props {
|
||||
dropdownClassName?: string
|
||||
dropdownStyle?: object
|
||||
disableMatchWidth?: boolean
|
||||
disableFreeSolo?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
@@ -41,6 +43,7 @@ const defaultProps = {
|
||||
clearable: false,
|
||||
size: 'medium' as NormalSizes,
|
||||
disableMatchWidth: false,
|
||||
disableFreeSolo: false,
|
||||
className: '',
|
||||
}
|
||||
|
||||
@@ -83,11 +86,14 @@ const AutoComplete: React.FC<React.PropsWithChildren<AutoCompleteProps>> = ({
|
||||
dropdownClassName,
|
||||
dropdownStyle,
|
||||
disableMatchWidth,
|
||||
disableFreeSolo,
|
||||
...props
|
||||
}) => {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const [state, setState] = useState<string>(customInitialValue)
|
||||
const resetTimer = useRef<number>()
|
||||
const [state, setState, stateRef] = useCurrentState<string>(customInitialValue)
|
||||
const [selectVal, setSelectVal] = useState<string>(customInitialValue)
|
||||
const [visible, setVisible] = useState<boolean>(false)
|
||||
|
||||
const [, searchChild] = pickChild(children, AutoCompleteSearching)
|
||||
@@ -112,18 +118,24 @@ const AutoComplete: React.FC<React.PropsWithChildren<AutoCompleteProps>> = ({
|
||||
|
||||
const updateValue = (val: string) => {
|
||||
if (disabled) return
|
||||
setSelectVal(val)
|
||||
onSelect && onSelect(val)
|
||||
setState(val)
|
||||
if (inputRef.current) {
|
||||
inputRef.current.focus()
|
||||
setVisible(false)
|
||||
}
|
||||
inputRef.current && inputRef.current.focus()
|
||||
}
|
||||
const updateVisible = (next: boolean) => setVisible(next)
|
||||
const onInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setVisible(true)
|
||||
onSearch && onSearch(event.target.value)
|
||||
setState(event.target.value)
|
||||
}
|
||||
const resetInputValue = () => {
|
||||
if (!disableFreeSolo) return
|
||||
if (!state || state === '') return
|
||||
if (state !== selectVal) {
|
||||
setState(selectVal)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
onChange && onChange(state)
|
||||
@@ -146,9 +158,15 @@ const AutoComplete: React.FC<React.PropsWithChildren<AutoCompleteProps>> = ({
|
||||
)
|
||||
|
||||
const toggleFocusHandler = (next: boolean) => {
|
||||
clearTimeout(resetTimer.current)
|
||||
setVisible(next)
|
||||
if (next) {
|
||||
onSearch && onSearch(state)
|
||||
onSearch && onSearch(stateRef.current)
|
||||
} else {
|
||||
resetTimer.current = window.setTimeout(() => {
|
||||
resetInputValue()
|
||||
clearTimeout(resetTimer.current)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user