import CircularProgress from "@material-ui/core/CircularProgress"; import MenuItem from "@material-ui/core/MenuItem"; import Paper from "@material-ui/core/Paper"; import { Theme } from "@material-ui/core/styles"; import AddIcon from "@material-ui/icons/Add"; import { makeStyles } from "@material-ui/styles"; import classNames from "classnames"; import { GetItemPropsOptions } from "downshift"; import React from "react"; import SVG from "react-inlinesvg"; import { FormattedMessage } from "react-intl"; import chevronDown from "@assets/images/ChevronDown.svg"; import Checkbox from "@saleor/components/Checkbox"; import useElementScroll, { isScrolledToBottom } from "@saleor/hooks/useElementScroll"; import { FetchMoreProps } from "@saleor/types"; import Hr from "../Hr"; const menuItemHeight = 46; const maxMenuItems = 5; const offset = 24; export interface MultiAutocompleteChoiceType { label: string; value: any; } export interface MultiAutocompleteSelectFieldContentProps extends Partial { choices: MultiAutocompleteChoiceType[]; displayCustomValue: boolean; displayValues: MultiAutocompleteChoiceType[]; getItemProps: (options: GetItemPropsOptions) => void; highlightedIndex: number; inputValue: string; } const useStyles = makeStyles( (theme: Theme) => ({ addIcon: { height: 24, margin: 9, width: 20 }, arrowContainer: { position: "relative" }, arrowInnerContainer: { alignItems: "center", background: theme.palette.grey[50], bottom: 0, display: "flex", height: 30, justifyContent: "center", opacity: 1, position: "absolute", transition: theme.transitions.duration.short + "ms", width: "100%" }, checkbox: { height: 24, width: 20 }, content: { maxHeight: menuItemHeight * maxMenuItems + theme.spacing.unit * 2, overflow: "scroll", padding: 8 }, hide: { opacity: 0 }, hr: { margin: `${theme.spacing.unit}px 0` }, menuItem: { "&:focus": { backgroundColor: [ theme.palette.background.default, "!important" ] as any, color: theme.palette.primary.main, fontWeight: 400 }, "&:hover": { backgroundColor: [ theme.palette.background.default, "!important" ] as any, color: theme.palette.primary.main, fontWeight: 700 }, borderRadius: 4, display: "grid", gridColumnGap: theme.spacing.unit + "px", gridTemplateColumns: "30px 1fr", height: "auto", padding: 0, whiteSpace: "normal" }, menuItemLabel: { overflowWrap: "break-word" }, progress: {}, progressContainer: { display: "flex", justifyContent: "center" }, root: { borderBottomLeftRadius: 8, borderBottomRightRadius: 8, left: 0, marginTop: theme.spacing.unit, overflow: "hidden", position: "absolute", right: 0, zIndex: 22 } }), { name: "MultiAutocompleteSelectFieldContent" } ); function getChoiceIndex( index: number, displayValues: MultiAutocompleteChoiceType[], displayCustomValue: boolean ) { let choiceIndex = index; if (displayCustomValue) { choiceIndex += 2; } if (displayValues.length > 0) { choiceIndex += 1 + displayValues.length; } return choiceIndex; } const MultiAutocompleteSelectFieldContent: React.FC< MultiAutocompleteSelectFieldContentProps > = props => { const { choices, displayCustomValue, displayValues, getItemProps, hasMore, highlightedIndex, loading, inputValue, onFetchMore } = props; const classes = useStyles(props); const anchor = React.useRef(); const scrollPosition = useElementScroll(anchor); const [calledForMore, setCalledForMore] = React.useState(false); const scrolledToBottom = isScrolledToBottom(anchor, scrollPosition, offset); React.useEffect(() => { if (!calledForMore && onFetchMore && scrolledToBottom) { onFetchMore(); setCalledForMore(true); } }, [scrolledToBottom]); React.useEffect(() => { if (calledForMore && !loading) { setCalledForMore(false); } }, [loading]); return (
{choices.length > 0 || displayValues.length > 0 || displayCustomValue ? ( <> {displayCustomValue && ( )} {(choices.length > 0 || displayValues.length > 0) && displayCustomValue &&
} {displayValues.map(value => ( {value.label} ))} {displayValues.length > 0 && choices.length > 0 && (
)} {choices.map((suggestion, index) => { const choiceIndex = getChoiceIndex( index, displayValues, displayCustomValue ); return ( {suggestion.label} ); })} {hasMore && ( <>
)} ) : ( )}
); }; MultiAutocompleteSelectFieldContent.displayName = "MultiAutocompleteSelectFieldContent"; export default MultiAutocompleteSelectFieldContent;