import React from 'react'; import TextField from '@material-ui/core/TextField'; import Autocomplete, { AutocompleteRenderGroupParams } from '@material-ui/lab/Autocomplete'; import useMediaQuery from '@material-ui/core/useMediaQuery'; import ListSubheader from '@material-ui/core/ListSubheader'; import { useTheme, makeStyles } from '@material-ui/core/styles'; import { VariableSizeList, ListChildComponentProps } from 'react-window'; import { Typography } from '@material-ui/core'; 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}
); }); function random(length: number) { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < length; i += 1) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } return result; } const useStyles = makeStyles({ listbox: { boxSizing: 'border-box', '& ul': { padding: 0, margin: 0, }, }, }); const OPTIONS = Array.from(new Array(10000)) .map(() => random(10 + Math.ceil(Math.random() * 20))) .sort((a: string, b: string) => a.toUpperCase().localeCompare(b.toUpperCase())); const renderGroup = (params: AutocompleteRenderGroupParams) => [ {params.group} , params.children, ]; export default function Virtualize() { const classes = useStyles(); return ( >} renderGroup={renderGroup} options={OPTIONS} groupBy={(option) => option[0].toUpperCase()} renderInput={(params) => } renderOption={(option) => {option}} /> ); }