@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.
76 lines • 4.59 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useAccount } from '@lifi/wallet-management';
import { Box } from '@mui/material';
import { useEffect } from 'react';
import { useChain } from '../../hooks/useChain.js';
import { useDebouncedWatch } from '../../hooks/useDebouncedWatch.js';
import { useTokenBalances } from '../../hooks/useTokenBalances.js';
import { useTokenSearch } from '../../hooks/useTokenSearch.js';
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js';
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
import { FormKeyHelper } from '../../stores/form/types.js';
import { useFieldValues } from '../../stores/form/useFieldValues.js';
import { WidgetEvent } from '../../types/events.js';
import { getConfigItemSets, isFormItemAllowed } from '../../utils/item.js';
import { TokenNotFound } from './TokenNotFound.js';
import { useTokenSelect } from './useTokenSelect.js';
import { filteredTokensComparator } from './utils.js';
import { VirtualizedTokenList } from './VirtualizedTokenList.js';
export const TokenList = ({ formType, parentRef, height, onClick, }) => {
const emitter = useWidgetEvents();
const [selectedChainId, selectedTokenAddress] = useFieldValues(FormKeyHelper.getChainKey(formType), FormKeyHelper.getTokenKey(formType));
const [tokenSearchFilter] = useDebouncedWatch(320, 'tokenSearchFilter');
const { tokens: configTokens } = useWidgetConfig();
const { chain: selectedChain, isLoading: isSelectedChainLoading } = useChain(selectedChainId);
const { account } = useAccount({
chainType: selectedChain?.chainType,
});
const { tokens: chainTokens, tokensWithBalance, isLoading: isTokensLoading, isBalanceLoading, featuredTokens, popularTokens, } = useTokenBalances(selectedChainId);
let filteredTokens = (tokensWithBalance ?? chainTokens ?? []);
const normalizedSearchFilter = tokenSearchFilter?.replaceAll('$', '');
const searchFilter = normalizedSearchFilter?.toUpperCase() ?? '';
const filteredConfigTokens = getConfigItemSets(configTokens, (tokens) => new Set(tokens
.filter((t) => t.chainId === selectedChainId)
.map((t) => t.address)), formType);
// Get the appropriate allow/deny lists based on formType
filteredTokens = filteredTokens.filter((token) => token.chainId === selectedChainId &&
isFormItemAllowed(token, filteredConfigTokens, formType, (t) => t.address));
filteredTokens = tokenSearchFilter
? filteredTokens
.filter((token) => token.name?.toUpperCase().includes(searchFilter) ||
token.symbol
.toUpperCase()
// Replace ₮ with T for USD₮0
.replaceAll('₮', 'T')
.includes(searchFilter) ||
token.address.toUpperCase().includes(searchFilter))
.sort(filteredTokensComparator(searchFilter))
: filteredTokens;
const tokenSearchEnabled = !isTokensLoading &&
!filteredTokens.length &&
!!tokenSearchFilter &&
!!selectedChainId;
const { token: searchedToken, isLoading: isSearchedTokenLoading } = useTokenSearch(selectedChainId, normalizedSearchFilter, tokenSearchEnabled, formType);
const isLoading = isTokensLoading ||
isSelectedChainLoading ||
(tokenSearchEnabled && isSearchedTokenLoading);
const tokens = filteredTokens.length
? filteredTokens
: searchedToken
? [searchedToken]
: filteredTokens;
const handleTokenClick = useTokenSelect(formType, onClick);
const showCategories = Boolean(featuredTokens?.length || popularTokens?.length) &&
!tokenSearchFilter;
// biome-ignore lint/correctness/useExhaustiveDependencies: Should fire only when search filter changes
useEffect(() => {
if (normalizedSearchFilter) {
emitter.emit(WidgetEvent.TokenSearch, {
value: normalizedSearchFilter,
tokens,
});
}
}, [normalizedSearchFilter, emitter]);
return (_jsxs(Box, { ref: parentRef, style: { height, overflow: 'auto' }, children: [!tokens.length && !isLoading ? (_jsx(TokenNotFound, { formType: formType })) : null, _jsx(VirtualizedTokenList, { account: account, tokens: tokens, scrollElementRef: parentRef, chainId: selectedChainId, chain: selectedChain, isLoading: isLoading, isBalanceLoading: isBalanceLoading, showCategories: showCategories, onClick: handleTokenClick, selectedTokenAddress: selectedTokenAddress })] }));
};
//# sourceMappingURL=TokenList.js.map