diff --git a/frontend/app/components/shared/Filters/FilterAutoComplete/FilterAutoComplete.tsx b/frontend/app/components/shared/Filters/FilterAutoComplete/FilterAutoComplete.tsx index e472574b1..5cc5f4280 100644 --- a/frontend/app/components/shared/Filters/FilterAutoComplete/FilterAutoComplete.tsx +++ b/frontend/app/components/shared/Filters/FilterAutoComplete/FilterAutoComplete.tsx @@ -4,8 +4,9 @@ import APIClient from 'App/api_client'; import { debounce } from 'App/utils'; import stl from './FilterAutoComplete.module.css'; import { components, DropdownIndicatorProps } from 'react-select'; -import AsyncCreatableSelect from 'react-select/async-creatable'; import colors from 'App/theme/colors'; +import Select from 'react-select'; +import cn from 'classnames'; const dropdownStyles = { option: (provided: any, state: any) => ({ @@ -22,7 +23,7 @@ const dropdownStyles = { '&:focus': { transition: 'all 0.2s', backgroundColor: colors['active-blue'], - } + }, }), control: (provided: any) => { const obj = { @@ -45,9 +46,6 @@ const dropdownStyles = { height: '26px', padding: '0 3px', }), - // placeholder: (provided: any) => ({ - // ...provided, - // }), indicatorsContainer: (provided: any) => ({ ...provided, padding: '0px', @@ -55,14 +53,29 @@ const dropdownStyles = { }), menu: (provided: any, state: any) => ({ ...provided, - top: 20, - left: 0, + top: 0, + borderRadius: '3px', + border: `1px solid ${colors['gray-light']}`, + backgroundColor: '#fff', + boxShadow: '1px 1px 1px rgba(0, 0, 0, 0.1)', + position: 'absolute', minWidth: 'fit-content', overflow: 'hidden', + zIndex: 100, + }), + menuList: (provided: any, state: any) => ({ + ...provided, + padding: 0, + }), + noOptionsMessage: (provided: any) => ({ + ...provided, + whiteSpace: 'nowrap !important', + // minWidth: 'fit-content', }), container: (provided: any) => ({ ...provided, - width: '100%', + top: '18px', + position: 'absolute', }), input: (provided: any) => ({ ...provided, @@ -113,12 +126,17 @@ function FilterAutoComplete(props: Props) { params = {}, value = '', } = props; - const [options, setOptions] = useState(value ? [{ label: value, value }] : []); + const [loading, setLoading] = useState(false); + const [options, setOptions] = useState([]); const [query, setQuery] = useState(value); + const [menuIsOpen, setMenuIsOpen] = useState(false); + const [initialFocus, setInitialFocus] = useState(false); + let selectRef: any = null; + let inputRef: any = null; useEffect(() => { setQuery(value); - }, [value, options]) + }, [value]) const loadOptions = (inputValue: string, callback: (options: []) => void) => { new APIClient() @@ -133,32 +151,71 @@ function FilterAutoComplete(props: Props) { const _options = data.map((i: any) => ({ value: i.value, label: i.value })) || []; setOptions(_options); callback(_options); - }) + setLoading(false); + }); }; const debouncedLoadOptions = React.useCallback(debounce(loadOptions, 1000), [params]); const handleInputChange = (newValue: string) => { - const inputValue = newValue.replace(/\W/g, ''); - setQuery(inputValue); - return inputValue; + // const inputValue = newValue.replace(/\W/g, ''); + setLoading(true); + setInitialFocus(true); + setQuery(newValue); + debouncedLoadOptions(newValue, (opt: any) => { + selectRef?.focus(); + }); }; + const onChange = (item: any) => { + setMenuIsOpen(false); + setQuery(item); + props.onSelect(null, item); + // inputRef?.blur(); + }; + + const onFocus = () => { + setMenuIsOpen(true); + }; + + const onBlur = () => { + setMenuIsOpen(false); + props.onSelect(null, query); + }; + + const selected = value ? options.find((i: any) => i.value === query) : null; + return (
-
- props.onSelect(null, obj)} - styles={dropdownStyles} +
+ (inputRef = ref)} + className="w-full rounded px-2 no-focus" + value={query} + onChange={({ target: { value } }: any) => handleInputChange(value)} + onClick={onFocus} + onFocus={onFocus} + onBlur={onBlur} placeholder={placeholder} - value={value ? options.find((i: any) => i.value === query) : null} + /> + {loading && ( +
+ +
+ )} +