From b982eb85af346bcddc082daab1acc2dda6c7addc Mon Sep 17 00:00:00 2001 From: unix Date: Wed, 3 Jun 2020 03:35:07 +0800 Subject: [PATCH] feat(auto-complete): add control for free solo --- .../auto-complete/auto-complete-item.tsx | 3 +- components/auto-complete/auto-complete.tsx | 30 +++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/components/auto-complete/auto-complete-item.tsx b/components/auto-complete/auto-complete-item.tsx index 63b102b..6d6fb08 100644 --- a/components/auto-complete/auto-complete-item.tsx +++ b/components/auto-complete/auto-complete-item.tsx @@ -28,9 +28,10 @@ const AutoCompleteItem: React.FC> 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]) diff --git a/components/auto-complete/auto-complete.tsx b/components/auto-complete/auto-complete.tsx index 1703403..0e51a45 100644 --- a/components/auto-complete/auto-complete.tsx +++ b/components/auto-complete/auto-complete.tsx @@ -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> = ({ dropdownClassName, dropdownStyle, disableMatchWidth, + disableFreeSolo, ...props }) => { const ref = useRef(null) const inputRef = useRef(null) - const [state, setState] = useState(customInitialValue) + const resetTimer = useRef() + const [state, setState, stateRef] = useCurrentState(customInitialValue) + const [selectVal, setSelectVal] = useState(customInitialValue) const [visible, setVisible] = useState(false) const [, searchChild] = pickChild(children, AutoCompleteSearching) @@ -112,18 +118,24 @@ const AutoComplete: React.FC> = ({ 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) => { + 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> = ({ ) 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) } }