import React from "react"; import { makeStyles, useTheme } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import Autocomplete from "@material-ui/lab/Autocomplete"; import useMediaQuery from "@material-ui/core/useMediaQuery"; import ListSubheader from "@material-ui/core/ListSubheader"; import { VariableSizeList, ListChildComponentProps } from "react-window"; import { GroupInfo } from "../api"; import { isDarkTheme } from "../theme"; const useStyles = makeStyles((theme) => ({ groupSelectOption: { display: "flex", justifyContent: "space-between", width: "100%", }, groupSize: { fontSize: "12px", color: theme.palette.text.secondary, background: isDarkTheme(theme) ? "#303030" : theme.palette.background.default, textAlign: "center", padding: "3px 6px", borderRadius: "10px", marginRight: "2px", }, })); interface Props { groups: GroupInfo[]; error: string; } export default function GroupSelect(props: Props) { const classes = useStyles(); return ( > } options={props.groups} getOptionLabel={(option: GroupInfo) => option.group} style={{ width: 300 }} renderOption={(option: GroupInfo) => (
{option.group} {option.size}
)} renderInput={(params) => ( )} /> ); } // Virtualized list. // Reference: https://v4.mui.com/components/autocomplete/#virtualization const LISTBOX_PADDING = 8; // px function renderRow(props: ListChildComponentProps) { const { data, index, style } = props; return React.cloneElement(data[index], { style: { ...style, top: (style.top as number) + LISTBOX_PADDING, }, }); } const OuterElementContext = React.createContext({}); const OuterElementType = React.forwardRef((props, ref) => { const outerProps = React.useContext(OuterElementContext); return
; }); function useResetCache(data: any) { const ref = React.useRef(null); React.useEffect(() => { if (ref.current != null) { ref.current.resetAfterIndex(0, true); } }, [data]); return ref; } // Adapter for react-window const ListboxComponent = React.forwardRef( function ListboxComponent(props, ref) { const { children, ...other } = props; const itemData = React.Children.toArray(children); const theme = useTheme(); const smUp = useMediaQuery(theme.breakpoints.up("sm"), { noSsr: true }); const itemCount = itemData.length; const itemSize = smUp ? 36 : 48; const getChildSize = (child: React.ReactNode) => { if (React.isValidElement(child) && child.type === ListSubheader) { return 48; } return itemSize; }; const getHeight = () => { if (itemCount > 8) { return 8 * itemSize; } return itemData.map(getChildSize).reduce((a, b) => a + b, 0); }; const gridRef = useResetCache(itemCount); return (
getChildSize(itemData[index])} overscanCount={5} itemCount={itemCount} > {renderRow}
); } );