import { Omit } from "@material-ui/core"; import { InputProps } from "@material-ui/core/Input"; import { createStyles, withStyles, WithStyles } 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 SingleAutocompleteSelectFieldContent, { SingleAutocompleteChoiceType } from "./SingleAutocompleteSelectFieldContent"; import useStateFromProps from "@saleor/hooks/useStateFromProps"; import { FetchMoreProps } from "@saleor/types"; import ArrowDropdownIcon from "../../icons/ArrowDropdown"; import Debounce, { DebounceProps } from "../Debounce"; const styles = createStyles({ container: { flexGrow: 1, position: "relative" } }); export interface SingleAutocompleteSelectFieldProps extends Partial { 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; } interface SingleAutocompleteSelectFieldState { choices: Array<{ label: string; value: string; }>; } const DebounceAutocomplete: React.ComponentType< DebounceProps > = Debounce; const SingleAutocompleteSelectFieldComponent = withStyles(styles, { name: "SingleAutocompleteSelectField" })( ({ choices, classes, allowCustomValues, disabled, displayValue, emptyOption, error, hasMore, helperText, label, loading, name, placeholder, value, InputProps, fetchChoices, onChange, onFetchMore, ...props }: SingleAutocompleteSelectFieldProps & WithStyles) => { 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, openMenu, 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, onFocus: openMenu }} error={error} disabled={disabled} helperText={helperText} label={label} fullWidth={true} /> {isOpen && (!!inputValue || !!choices.length) && ( )} ); }}
)}
); } ); const SingleAutocompleteSelectField: React.FC< SingleAutocompleteSelectFieldProps > = ({ choices, fetchChoices, ...props }) => { const [query, setQuery] = React.useState(""); if (fetchChoices) { return ( {debounceFn => ( )} ); } return ( setQuery(q || "")} choices={filter(choices, query, { key: "label" })} {...props} /> ); }; export default SingleAutocompleteSelectField;