import IconButton from "@material-ui/core/IconButton"; import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import Typography from "@material-ui/core/Typography"; import CloseIcon from "@material-ui/icons/Close"; import Downshift, { ControllerStateAndHelpers } from "downshift"; import React from "react"; import { compareTwoStrings } from "string-similarity"; import { fade } from "@material-ui/core/styles/colorManipulator"; import Debounce, { DebounceProps } from "@saleor/components/Debounce"; import ArrowDropdownIcon from "@saleor/icons/ArrowDropdown"; import { FetchMoreProps } from "@saleor/types"; import MultiAutocompleteSelectFieldContent, { MultiAutocompleteChoiceType } from "./MultiAutocompleteSelectFieldContent"; const styles = (theme: Theme) => createStyles({ chip: { width: "100%" }, chipClose: { height: 32, padding: 0, width: 32 }, chipContainer: { display: "flex", flexDirection: "column", marginTop: theme.spacing.unit }, chipInner: { "& svg": { color: theme.palette.primary.contrastText }, alignItems: "center", background: fade(theme.palette.primary.main, 0.8), borderRadius: 18, color: theme.palette.primary.contrastText, display: "flex", justifyContent: "space-between", margin: `${theme.spacing.unit}px 0`, paddingLeft: theme.spacing.unit * 2, paddingRight: theme.spacing.unit }, chipLabel: { color: theme.palette.primary.contrastText }, container: { flexGrow: 1, position: "relative" } }); export interface MultiAutocompleteSelectFieldProps extends Partial { allowCustomValues?: boolean; displayValues: MultiAutocompleteChoiceType[]; name: string; choices: MultiAutocompleteChoiceType[]; value: string[]; loading?: boolean; placeholder?: string; helperText?: string; label?: string; fetchChoices?: (value: string) => void; onChange: (event: React.ChangeEvent) => void; } const DebounceAutocomplete: React.ComponentType< DebounceProps > = Debounce; export const MultiAutocompleteSelectFieldComponent = withStyles(styles, { name: "MultiAutocompleteSelectField" })( ({ allowCustomValues, choices, classes, displayValues, hasMore, helperText, label, loading, name, placeholder, value, fetchChoices, onChange, onFetchMore, ...props }: MultiAutocompleteSelectFieldProps & WithStyles) => { const handleSelect = ( item: string, downshiftOpts?: ControllerStateAndHelpers ) => { if (downshiftOpts) { downshiftOpts.reset({ inputValue: "" }); } onChange({ target: { name, value: item } } as any); }; return ( <> ""} > {({ getInputProps, getItemProps, isOpen, toggleMenu, highlightedIndex, inputValue }) => { const displayCustomValue = inputValue && inputValue.length > 0 && allowCustomValues && !choices.find( choice => choice.label.toLowerCase() === inputValue.toLowerCase() ); return (
), id: undefined, onClick: toggleMenu }} helperText={helperText} label={label} fullWidth={true} /> {isOpen && (!!inputValue || !!choices.length) && ( !value.includes(choice.value) )} displayCustomValue={displayCustomValue} displayValues={displayValues} getItemProps={getItemProps} hasMore={hasMore} highlightedIndex={highlightedIndex} loading={loading} inputValue={inputValue} onFetchMore={onFetchMore} /> )} ); }}
{displayValues.map(value => (
{value.label} handleSelect(value.value)} >
))}
); } ); const MultiAutocompleteSelectField: React.FC< MultiAutocompleteSelectFieldProps > = ({ choices, fetchChoices, ...props }) => { const [query, setQuery] = React.useState(""); if (fetchChoices) { return ( {debounceFn => ( )} ); } const sortedChoices = choices.sort((a, b) => { const ratingA = compareTwoStrings(query, a.label); const ratingB = compareTwoStrings(query, b.label); if (ratingA > ratingB) { return -1; } if (ratingA < ratingB) { return 1; } return 0; }); return ( setQuery(q || "")} choices={sortedChoices} {...props} /> ); }; MultiAutocompleteSelectField.displayName = "MultiAutocompleteSelectField"; export default MultiAutocompleteSelectField;