Replies: 3 comments
-
Did you ever get this working? |
Beta Was this translation helpful? Give feedback.
0 replies
-
I hope this helps: VirtualizedList component:import { Children, type HTMLAttributes, type ReactElement } from 'react'
const ListboxComponent = forwardRef<
HTMLDivElement,
HTMLAttributes<HTMLElement>
>((props, ref) => {
const { children, role, ...other } = props
const items = Children.toArray(children) as ReactElement[]
const itemCount = items.length
const scrollRef = useRef<HTMLDivElement>(null)
const virtualizer = useVirtualizer({
count: itemCount,
estimateSize: () => 55, //* NOTE: You may have to play around with this value.
getScrollElement: () => scrollRef.current,
})
return (
<div ref={ref}>
<List
{...other}
role={role}
ref={scrollRef}
component="div"
sx={{
position: 'relative',
height: virtualizer.getTotalSize(),
}}
>
{virtualizer.getVirtualItems().map(item => (
<Box
key={item.key}
sx={{
py: 0.5,
width: '100%',
position: 'absolute',
transform: `translateY(${item.start}px)`,
}}
>
{items[item.index]}
</Box>
))}
</List>
</div>
)
}) Autocomplete component with your virtualized list:<Autocomplete
ListboxComponent={ListboxComponent} // <-- Your component goes here.
// You can even use custom components for your options!
renderOption={(props, option, { selected }) => (
<ListItem {...props} disablePadding>
<ListItemIcon>
<Checkbox edge="start" checked={selected} />
</ListItemIcon>
<ListItemText primary={option.label} />
</ListItem>
)}
/> |
Beta Was this translation helpful? Give feedback.
0 replies
-
import {
Children,
type FC,
type HTMLAttributes,
type ReactElement,
cloneElement,
forwardRef,
useRef,
} from 'react';
import {
Autocomplete,
Avatar,
Checkbox,
List,
ListItem,
ListItemAvatar,
ListItemButton,
type ListItemProps,
ListItemText,
TextField,
} from '@mui/material';
import { matchSorter } from 'match-sorter';
import { useVirtualizer } from '@tanstack/react-virtual';
const TanStackVirtualAutocomplete: FC<{
options: Array<{
alt: string;
label: string;
src: string;
}>;
}> = ({ options }) => {
return (
<Autocomplete
ListboxComponent={forwardRef<
HTMLDivElement,
HTMLAttributes<HTMLDivElement>
>(
(
{
children,
...props
},
ref,
) => {
const items = Children.toArray(children);
const parentRef = useRef<HTMLDivElement>(null);
const rowVirtualizer = useVirtualizer({
count: items.length,
estimateSize: () => 68,
getScrollElement: () => parentRef.current,
});
return (
<div
ref={ref}
{...props}
style={{ padding: 0 }}
>
<div
ref={parentRef}
style={{
height: parentRef
.current
?.parentElement
?.getBoundingClientRect()
.height,
overflowY: 'auto',
}}
>
<List
sx={{
height: `${rowVirtualizer.getTotalSize()}px`,
position: 'relative',
}}
>
{rowVirtualizer
.getVirtualItems()
.map(
(virtualItem) => {
const item = items[virtualItem.index] as ReactElement<ListItemProps>;
return cloneElement(
item,
{
sx: {
...item.props.sx,
height: `${virtualItem.size}px`,
left: 0,
position: 'absolute',
top: 0,
transform: `translateY(${virtualItem.start}px)`,
},
},
);
},
)}
</List>
</div>
</div>
);
},
)}
disablePortal
filterOptions={(
options,
{ inputValue },
) => inputValue
? matchSorter(
options,
inputValue,
)
: options
}
getOptionLabel={({ label }) => label}
options={options}
renderInput={(params) => (
<TextField
{...params}
label="TanStack Virtual Autocomplete"
/>
)}
renderOption={(
{
key,
...props
},
option,
{ selected },
_ownerState,
) => (
<ListItem
key={key}
{...props}
>
<ListItemButton>
<ListItemAvatar>
<Avatar
alt={option.alt}
src={option.src}
sx={{
height: 56,
marginRight: 1,
width: 56,
}}
/>
</ListItemAvatar>
<ListItemText primary={option.label} />
<Checkbox checked={selected} />
</ListItemButton>
</ListItem>
)}
slotProps={{ popper: { keepMounted: true } }}
/>
);
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi - trying to integrate with Material UI's Autocomplete component, but having issues with virtualization (i.e. all options are being rendered) or with keyboard navigation not working.
Here is a WIP demo, which is mostly broken. How can I get this to work?
FWIW, MUI has a working demo with a different library, might be useful as a reference
Beta Was this translation helpful? Give feedback.
All reactions