import { InputProps } from "@material-ui/core/Input"; import { makeStyles } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import Downshift from "downshift"; import { filter } from "fuzzaldrin"; import React from "react"; import useStateFromProps from "@saleor/hooks/useStateFromProps"; import { FetchMoreProps } from "@saleor/types"; import ArrowDropdownIcon from "../../icons/ArrowDropdown"; import Debounce, { DebounceProps } from "../Debounce"; import SingleAutocompleteSelectFieldContent, { SingleAutocompleteChoiceType, SingleAutocompleteActionType } from "./SingleAutocompleteSelectFieldContent"; const useStyles = makeStyles( { container: { flexGrow: 1, position: "relative" } }, { name: "SingleAutocompleteSelectField" } ); export interface SingleAutocompleteSelectFieldProps extends Partial { add?: SingleAutocompleteActionType; error?: boolean; name: string; displayValue: string; emptyOption?: boolean; choices: SingleAutocompleteChoiceType[]; value: string; disabled?: boolean; placeholder?: string; allowCustomValues?: boolean; helperText?: string; label?: string; InputProps?: InputProps; fetchChoices?: (value: string) => void; onChange: (event: React.ChangeEvent) => void; } const DebounceAutocomplete: React.ComponentType> = Debounce; const SingleAutocompleteSelectFieldComponent: React.FC = props => { const { add, allowCustomValues, choices, disabled, displayValue, emptyOption, error, hasMore, helperText, label, loading, name, placeholder, value, InputProps, fetchChoices, onChange, onFetchMore, ...rest } = props; const classes = useStyles(props); const [prevDisplayValue] = useStateFromProps(displayValue); const handleChange = item => onChange({ target: { name, value: item } } as any); return ( {debounceFn => ( displayValue} onInputValueChange={value => debounceFn(value)} onSelect={handleChange} selectedItem={value} > {({ getInputProps, getItemProps, isOpen, inputValue, selectedItem, toggleMenu, closeMenu, highlightedIndex, reset }) => { const isCustomValueSelected = choices && selectedItem ? choices.filter(c => c.value === selectedItem).length === 0 : false; const hasInputValueChanged = prevDisplayValue !== displayValue; if (hasInputValueChanged) { reset({ inputValue: displayValue }); } const displayCustomValue = inputValue && inputValue.length > 0 && allowCustomValues && !choices.find( choice => choice.label.toLowerCase() === inputValue.toLowerCase() ); return (
), error, id: undefined, onBlur: closeMenu, onClick: toggleMenu }} error={error} disabled={disabled} helperText={helperText} label={label} fullWidth={true} /> {isOpen && (!!inputValue || !!choices.length) && ( { add.onClick(); closeMenu(); } } } choices={choices} displayCustomValue={displayCustomValue} emptyOption={emptyOption} getItemProps={getItemProps} hasMore={hasMore} highlightedIndex={highlightedIndex} loading={loading} inputValue={inputValue} isCustomValueSelected={isCustomValueSelected} selectedItem={selectedItem} onFetchMore={onFetchMore} /> )} ); }}
)}
); }; const SingleAutocompleteSelectField: React.FC = ({ choices, fetchChoices, ...rest }) => { const [query, setQuery] = React.useState(""); if (fetchChoices) { return ( {debounceFn => ( )} ); } return ( setQuery(q || "")} choices={filter(choices, query, { key: "label" })} {...rest} /> ); }; export default SingleAutocompleteSelectField;