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
Uh oh!
There was an error while loading. Please reload this page.
-
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