UNPKG

@lifi/widget

Version:

LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.

98 lines 5.61 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { Typography } from '@mui/material'; import { useVirtualizer } from '@tanstack/react-virtual'; import { useCallback, useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { TokenDetailsSheet } from './TokenDetailsSheet.js'; import { List } from './TokenList.style.js'; import { TokenListItem, TokenListItemSkeleton } from './TokenListItem.js'; export const VirtualizedTokenList = ({ account, tokens, scrollElementRef, chainId, chain, selectedTokenAddress, isLoading, isBalanceLoading, showCategories, onClick, }) => { const { t } = useTranslation(); const tokenDetailsSheetRef = useRef(null); const onShowTokenDetails = useCallback((tokenAddress, noContractAddress) => { tokenDetailsSheetRef.current?.open(tokenAddress, noContractAddress); }, []); const getItemKey = useCallback((index) => { return `${tokens[index].address}-${index}`; }, [tokens]); const { getVirtualItems, getTotalSize, scrollToIndex } = useVirtualizer({ count: tokens.length, overscan: 5, paddingEnd: 12, getScrollElement: () => scrollElementRef.current, estimateSize: (index) => { // Base size for TokenListItem let size = 64; // Early return if categories are not shown if (!showCategories) { return size; } const currentToken = tokens[index]; const previousToken = tokens[index - 1]; // Adjust size for the first featured token if (currentToken.featured && index === 0) { size += 24; } // Adjust size based on changes between the current and previous tokens const isCategoryChanged = (previousToken?.amount && !currentToken.amount) || (previousToken?.featured && !currentToken.featured) || (previousToken?.popular && !currentToken.popular); if (isCategoryChanged) { size += 32; } return size; }, getItemKey, }); // biome-ignore lint/correctness/useExhaustiveDependencies: run only when chainId changes useEffect(() => { // Scroll to the top of the list when switching the chains if (getVirtualItems().length) { scrollToIndex(0, { align: 'start' }); } // Close the token details sheet when switching the chains tokenDetailsSheetRef.current?.close(); }, [scrollToIndex, chainId, getVirtualItems]); if (isLoading) { return (_jsx(List, { disablePadding: true, children: Array.from({ length: 3 }).map((_, index) => (_jsx(TokenListItemSkeleton, {}, index))) })); } return (_jsxs(_Fragment, { children: [_jsx(List, { className: "long-list", style: { height: getTotalSize() }, disablePadding: true, children: getVirtualItems().map((item) => { const currentToken = tokens[item.index]; const previousToken = tokens[item.index - 1]; const isFirstFeaturedToken = currentToken.featured && item.index === 0; const isTransitionFromFeaturedTokens = previousToken?.featured && !currentToken.featured; const isTransitionFromMyTokens = previousToken?.amount && !currentToken.amount; const isTransitionToMyTokens = isTransitionFromFeaturedTokens && currentToken.amount; const isTransitionToPopularTokens = (isTransitionFromFeaturedTokens || isTransitionFromMyTokens) && currentToken.popular; const shouldShowAllTokensCategory = isTransitionFromMyTokens || isTransitionFromFeaturedTokens || (previousToken?.popular && !currentToken.popular); const startAdornmentLabel = showCategories ? (() => { if (isFirstFeaturedToken) { return t('main.featuredTokens'); } if (isTransitionToMyTokens) { return t('main.myTokens'); } if (isTransitionToPopularTokens) { return t('main.popularTokens'); } if (shouldShowAllTokensCategory) { return t('main.allTokens'); } return null; })() : null; return (_jsx(TokenListItem, { onClick: onClick, size: item.size, start: item.start, token: currentToken, chain: chain, selected: currentToken.address === selectedTokenAddress, onShowTokenDetails: onShowTokenDetails, isBalanceLoading: isBalanceLoading, accountAddress: account.address, startAdornment: startAdornmentLabel ? (_jsx(Typography, { sx: { fontSize: 14, fontWeight: 600, lineHeight: '16px', px: 1.5, pt: isFirstFeaturedToken ? 0 : 1, pb: 1, }, children: startAdornmentLabel })) : null }, item.key)); }) }), _jsx(TokenDetailsSheet, { ref: tokenDetailsSheetRef, chainId: chainId })] })); }; //# sourceMappingURL=VirtualizedTokenList.js.map