import CircularProgress from "@material-ui/core/CircularProgress"; import MenuItem from "@material-ui/core/MenuItem"; import Paper from "@material-ui/core/Paper"; import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import Downshift, { ControllerStateAndHelpers } from "downshift"; import * as React from "react"; import i18n from "../../i18n"; import ArrowDropdownIcon from "../../icons/ArrowDropdown"; import Debounce, { DebounceProps } from "../Debounce"; interface ChoiceType { label: string; value: string; } const styles = (theme: Theme) => createStyles({ chip: { margin: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 2}px` }, container: { flexGrow: 1, position: "relative" }, paper: { left: 0, marginTop: theme.spacing.unit, padding: theme.spacing.unit, position: "absolute", right: 0, zIndex: 2 } }); export interface MultiAutocompleteSelectFieldChildrenFunc { deleteItem: (item: ChoiceType) => void; items: ChoiceType[]; } export type MultiAutocompleteSelectFieldChildren = ( props: MultiAutocompleteSelectFieldChildrenFunc ) => React.ReactNode; export interface MultiAutocompleteSelectFieldProps extends WithStyles { name: string; children: MultiAutocompleteSelectFieldChildren; choices: ChoiceType[]; value?: ChoiceType[]; loading?: boolean; placeholder?: string; helperText?: string; label?: string; fetchChoices(value: string); onChange(event); } const DebounceAutocomplete: React.ComponentType< DebounceProps > = Debounce; export const MultiAutocompleteSelectField = withStyles(styles, { name: "MultiAutocompleteSelectField" })( ({ children, choices, classes, helperText, label, loading, name, placeholder, value, fetchChoices, onChange }: MultiAutocompleteSelectFieldProps) => { const handleSelect = ( item: ChoiceType, { reset }: ControllerStateAndHelpers ) => { reset({ inputValue: "" }); onChange({ target: { name, value: [...value, item] } }); }; const handleDelete = (item: ChoiceType) => { const newValue = value.slice(); newValue.splice( value.findIndex(listItem => listItem.value === item.value), 1 ); onChange({ target: { name, value: newValue } }); }; const filteredChoices = choices.filter( suggestion => value.map(v => v.value).indexOf(suggestion.value) === -1 ); return ( {debounce => ( (item ? item.label : "")} onSelect={handleSelect} onInputValueChange={value => debounce(value)} > {({ getInputProps, getItemProps, isOpen, selectedItem, toggleMenu, closeMenu, openMenu, highlightedIndex }) => { return (
{loading ? ( ) : ( )}
), id: undefined, onBlur: closeMenu, onFocus: openMenu }} helperText={helperText} label={label} fullWidth={true} /> {isOpen && ( {!loading && filteredChoices.length > 0 ? filteredChoices.map((suggestion, index) => ( {suggestion.label} )) : !loading && ( {i18n.t("No results found")} )} )} {children({ deleteItem: handleDelete, items: selectedItem })} ); }}
)}
); } ); MultiAutocompleteSelectField.displayName = "MultiAutocompleteSelectField"; export default MultiAutocompleteSelectField;