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 Typography from "@material-ui/core/Typography"; import { makeStyles } from "@material-ui/styles"; import classNames from "classnames"; import { GetItemPropsOptions } from "downshift"; import React from "react"; import { FormattedMessage } from "react-intl"; import useElementScroll from "@saleor/hooks/useElementScroll"; import { FetchMoreProps } from "@saleor/types"; import Hr from "../Hr"; const menuItemHeight = 46; const maxMenuItems = 5; const offset = 24; export interface SingleAutocompleteChoiceType { label: string; value: any; } export interface SingleAutocompleteSelectFieldContentProps extends Partial { choices: SingleAutocompleteChoiceType[]; displayCustomValue: boolean; emptyOption: boolean; getItemProps: (options: GetItemPropsOptions) => void; highlightedIndex: number; inputValue: string; isCustomValueSelected: boolean; selectedItem: any; } const useStyles = makeStyles( (theme: Theme) => ({ content: { maxHeight: menuItemHeight * maxMenuItems + theme.spacing.unit * 2, overflow: "scroll", padding: 8 }, hr: { margin: `${theme.spacing.unit}px 0` }, menuItem: { height: "auto", whiteSpace: "normal" }, progress: {}, progressContainer: { display: "flex", justifyContent: "center" }, root: { borderRadius: 4, left: 0, marginTop: theme.spacing.unit, position: "absolute", right: 0, zIndex: 22 }, shadow: { "&$shadowLine": { boxShadow: `0px -5px 10px 0px ${theme.palette.grey[800]}` } }, shadowLine: { boxShadow: `0px 0px 0px 0px ${theme.palette.grey[50]}`, height: 1, transition: theme.transitions.duration.short + "ms" } }), { name: "SingleAutocompleteSelectFieldContent" } ); function getChoiceIndex( index: number, emptyValue: boolean, customValue: boolean ) { let choiceIndex = index; if (emptyValue) { choiceIndex += 1; } if (customValue) { choiceIndex += 2; } return choiceIndex; } const SingleAutocompleteSelectFieldContent: React.FC< SingleAutocompleteSelectFieldContentProps > = props => { const { choices, displayCustomValue, emptyOption, getItemProps, hasMore, highlightedIndex, loading, inputValue, isCustomValueSelected, selectedItem, onFetchMore } = props; const classes = useStyles(props); const anchor = React.useRef(); const scrollPosition = useElementScroll(anchor); const [calledForMore, setCalledForMore] = React.useState(false); const scrolledToBottom = anchor.current ? scrollPosition.y + anchor.current.clientHeight + offset >= anchor.current.scrollHeight : false; React.useEffect(() => { if (!calledForMore && onFetchMore && scrolledToBottom) { onFetchMore(); setCalledForMore(true); } }, [scrolledToBottom]); React.useEffect(() => { if (calledForMore && !loading) { setCalledForMore(false); } }, [loading]); return (
{choices.length > 0 || displayCustomValue ? ( <> {emptyOption && ( )} {displayCustomValue && ( )} {choices.length > 0 && displayCustomValue && (
)} {choices.map((suggestion, index) => { const choiceIndex = getChoiceIndex( index, emptyOption, displayCustomValue ); return ( {suggestion.label} ); })} {hasMore && ( <>
)} ) : ( )}
); }; SingleAutocompleteSelectFieldContent.displayName = "SingleAutocompleteSelectFieldContent"; export default SingleAutocompleteSelectFieldContent;