import { List, Typography } from '@mui/material'; import { useVirtualizer } from '@tanstack/react-virtual'; import type { FC } from 'react'; import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useAccount } from '../../hooks'; import { TokenListItem, TokenListItemSkeleton } from './TokenListItem'; import type { VirtualizedTokenListProps } from './types'; export const VirtualizedTokenList: FC = ({ tokens, featuredTokensLength, scrollElementRef, chainId, chain, isLoading, isBalanceLoading, showFeatured, onClick, }) => { const { isConnected } = useAccount(); const { t } = useTranslation(); const hasFeaturedTokens = !!featuredTokensLength && showFeatured; const featuredTokensLastIndex = (featuredTokensLength ?? 0) - 1; const tokensLastIndex = tokens.length - 1; const { getVirtualItems, getTotalSize, scrollToIndex } = useVirtualizer({ count: tokens.length, overscan: 10, paddingEnd: 12, getScrollElement: () => scrollElementRef.current, estimateSize: (index) => { // heigth of TokenListItem let size = 64; if (!hasFeaturedTokens) { return size; } if (index === 0 && tokens[index]?.featured) { // height of startAdornment size += 24; } if ( index === featuredTokensLastIndex && index !== tokensLastIndex && tokens[index]?.featured ) { // height of endAdornment size += 32; } return size; }, getItemKey: (index) => `${tokens[index].address}-${index}`, }); useEffect(() => { // Scroll to the top of the list when switching the chains if (getVirtualItems().length) { scrollToIndex(0, { align: 'start' }); } }, [scrollToIndex, chainId, getVirtualItems]); if (isLoading) { return ( {Array.from({ length: 3 }).map((_, index) => ( // eslint-disable-next-line react/no-array-index-key ))} ); } return ( {getVirtualItems().map((item) => { const token = tokens[item.index]; return ( {t('main.featuredTokens')} ) : null } endAdornment={ hasFeaturedTokens && token.featured && item.index === featuredTokensLastIndex && item.index !== tokensLastIndex ? ( {t('main.otherTokens')} ) : null } /> ); })} ); };