mirror of
https://github.com/zhigang1992/xverse-web-extension.git
synced 2026-04-30 13:42:52 +08:00
Improve token tile and btc balance breakdown tile handle large amount / many decimals (#779)
* change structure by row * fixes * touchup * change structure * fix forgot hide fiat balance
This commit is contained in:
@@ -7,6 +7,7 @@ import useStxWalletData from '@hooks/queries/useStxWalletData';
|
||||
import useSupportedCoinRates from '@hooks/queries/useSupportedCoinRates';
|
||||
import useWalletSelector from '@hooks/useWalletSelector';
|
||||
import { getFiatEquivalent, type FungibleToken } from '@secretkeylabs/xverse-core';
|
||||
import { StyledP } from '@ui-library/common.styled';
|
||||
import type { CurrencyTypes } from '@utils/constants';
|
||||
import { HIDDEN_BALANCE_LABEL } from '@utils/constants';
|
||||
import { getBalanceAmount, getFtTicker } from '@utils/tokens';
|
||||
@@ -21,52 +22,49 @@ const TileContainer = styled.button((props) => ({
|
||||
width: '100%',
|
||||
padding: `${props.theme.space.m} 0`,
|
||||
borderRadius: props.theme.radius(2),
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
const TokenImageContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
marginRight: props.theme.space.m,
|
||||
}));
|
||||
|
||||
const RowContainers = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const RowContainer = styled.div((props) => ({
|
||||
flex: '1 0 auto',
|
||||
display: 'flex',
|
||||
columnGap: props.theme.space.m,
|
||||
}));
|
||||
|
||||
const TextContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-start',
|
||||
rowGap: props.theme.space.xxxs,
|
||||
}));
|
||||
const CoinBalanceContainer = styled.div`
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
${(props) => props.theme.typography.body_medium_m};
|
||||
color: ${(props) => props.theme.colors.white_0};
|
||||
`;
|
||||
|
||||
const AmountContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginLeft: props.theme.space.xxs,
|
||||
overflow: 'hidden',
|
||||
alignItems: 'flex-end',
|
||||
rowGap: props.theme.space.xxxs,
|
||||
}));
|
||||
|
||||
const LoaderMainContainer = styled.div({
|
||||
flex: '1 1 auto',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-end',
|
||||
});
|
||||
const AmountContainer = styled.div`
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
`;
|
||||
|
||||
const CoinTickerText = styled.p((props) => ({
|
||||
...props.theme.typography.body_bold_m,
|
||||
color: props.theme.colors.white_0,
|
||||
lineHeight: '140%',
|
||||
minHeight: 20,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}));
|
||||
|
||||
const SubText = styled.p<{ $fullWidth: boolean }>((props) => ({
|
||||
const CoinSubtitleText = styled.p((props) => ({
|
||||
...props.theme.typography.body_medium_m,
|
||||
color: props.theme.colors.white_200,
|
||||
minHeight: 20,
|
||||
lineHeight: '140%',
|
||||
textAlign: 'left',
|
||||
maxWidth: props.$fullWidth ? 'unset' : 120,
|
||||
whiteSpace: props.$fullWidth ? 'normal' : 'nowrap',
|
||||
minHeight: 20,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}));
|
||||
@@ -81,12 +79,14 @@ const CoinBalanceText = styled.p((props) => ({
|
||||
maxWidth: '100%',
|
||||
}));
|
||||
|
||||
const TokenTitleContainer = styled.div({
|
||||
const TokenTitleContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
});
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
marginBottom: props.theme.space.xxxs,
|
||||
}));
|
||||
|
||||
const StyledBarLoader = styled(BestBarLoader)<{
|
||||
$withMarginBottom?: boolean;
|
||||
@@ -98,6 +98,7 @@ const FiatCurrencyRow = styled.div({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
});
|
||||
|
||||
const StyledFiatAmountText = styled(FiatAmountText)`
|
||||
${(props) => props.theme.typography.body_medium_m}
|
||||
color: ${(props) => props.theme.colors.white_200};
|
||||
@@ -105,25 +106,6 @@ const StyledFiatAmountText = styled(FiatAmountText)`
|
||||
min-height: 20px;
|
||||
`;
|
||||
|
||||
const CoinBalanceContainer = styled.div`
|
||||
${(props) => props.theme.typography.body_medium_m}
|
||||
color: ${(props) => props.theme.colors.white_0};
|
||||
`;
|
||||
|
||||
const FiatAmountContainer = styled.div`
|
||||
${(props) => props.theme.typography.body_medium_s}
|
||||
color: ${(props) => props.theme.colors.white_400};
|
||||
`;
|
||||
|
||||
function TokenLoader() {
|
||||
return (
|
||||
<LoaderMainContainer>
|
||||
<StyledBarLoader width={53} height={20} $withMarginBottom />
|
||||
<StyledBarLoader width={151} height={20} />
|
||||
</LoaderMainContainer>
|
||||
);
|
||||
}
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
loading?: boolean;
|
||||
@@ -174,8 +156,8 @@ function TokenTile({
|
||||
};
|
||||
|
||||
return (
|
||||
<TileContainer onClick={handleTokenPressed} className={className}>
|
||||
<RowContainer aria-label="Token Row">
|
||||
<TileContainer onClick={handleTokenPressed} className={className} aria-label="Token Row">
|
||||
<TokenImageContainer>
|
||||
<TokenImage
|
||||
currency={currency}
|
||||
loading={loading}
|
||||
@@ -183,35 +165,48 @@ function TokenTile({
|
||||
size={enlargeTicker ? 40 : 32}
|
||||
showProtocolIcon={showProtocolIcon}
|
||||
/>
|
||||
<TextContainer>
|
||||
<CoinTickerText>{getTickerTitle()}</CoinTickerText>
|
||||
</TokenImageContainer>
|
||||
<RowContainers>
|
||||
<RowContainer>
|
||||
<TokenTitleContainer>
|
||||
<SubText aria-label="Token SubTitle" $fullWidth={hideSwapBalance}>
|
||||
{title}
|
||||
</SubText>
|
||||
<CoinTickerText>{getTickerTitle()}</CoinTickerText>
|
||||
</TokenTitleContainer>
|
||||
</TextContainer>
|
||||
</RowContainer>
|
||||
{loading && <TokenLoader />}
|
||||
{!loading && !hideSwapBalance && (
|
||||
<AmountContainer aria-label="CoinBalance Container">
|
||||
<CoinBalanceContainer>
|
||||
{balanceHidden && HIDDEN_BALANCE_LABEL}
|
||||
{!balanceHidden && (
|
||||
<NumericFormat
|
||||
value={getBalanceAmount(currency, fungibleToken, stxData, btcBalance)}
|
||||
displayType="text"
|
||||
thousandSeparator
|
||||
renderText={(value: string) => <CoinBalanceText>{value}</CoinBalanceText>}
|
||||
/>
|
||||
)}
|
||||
</CoinBalanceContainer>
|
||||
<FiatCurrencyRow>
|
||||
<PercentageChange ftCurrencyPairs={[[fungibleToken, currency]]} />
|
||||
<StyledFiatAmountText fiatAmount={getFiatAmount()} fiatCurrency={fiatCurrency} />
|
||||
</FiatCurrencyRow>
|
||||
</AmountContainer>
|
||||
)}
|
||||
{loading && <StyledBarLoader width="10%" height={20} $withMarginBottom />}
|
||||
{!loading && !hideSwapBalance && (
|
||||
<CoinBalanceContainer aria-label="CoinBalance Container">
|
||||
{balanceHidden && HIDDEN_BALANCE_LABEL}
|
||||
{!balanceHidden && (
|
||||
<NumericFormat
|
||||
value={getBalanceAmount(currency, fungibleToken, stxData, btcBalance)}
|
||||
displayType="text"
|
||||
thousandSeparator
|
||||
renderText={(value: string) => <CoinBalanceText>{value}</CoinBalanceText>}
|
||||
/>
|
||||
)}
|
||||
</CoinBalanceContainer>
|
||||
)}
|
||||
</RowContainer>
|
||||
<RowContainer>
|
||||
<TokenTitleContainer>
|
||||
<CoinSubtitleText aria-label="Token SubTitle">{title}</CoinSubtitleText>
|
||||
</TokenTitleContainer>
|
||||
{loading && <StyledBarLoader width="20%" height={20} />}
|
||||
{!loading && !hideSwapBalance && (
|
||||
<AmountContainer aria-label="CurrencyBalance Container">
|
||||
{balanceHidden ? (
|
||||
<StyledP typography="body_medium_m" color="white_200">
|
||||
{HIDDEN_BALANCE_LABEL}
|
||||
</StyledP>
|
||||
) : (
|
||||
<FiatCurrencyRow>
|
||||
<PercentageChange ftCurrencyPairs={[[fungibleToken, currency]]} />
|
||||
<StyledFiatAmountText fiatAmount={getFiatAmount()} fiatCurrency={fiatCurrency} />
|
||||
</FiatCurrencyRow>
|
||||
)}
|
||||
</AmountContainer>
|
||||
)}
|
||||
</RowContainer>
|
||||
</RowContainers>
|
||||
</TileContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,40 +15,18 @@ const Container = styled.div((props) => ({
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
marginBottom: props.theme.space.m,
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
const IconOuterContainer = styled.div((_) => ({
|
||||
const IconOuterContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: props.theme.space.m,
|
||||
}));
|
||||
|
||||
const IconContainer = styled.div((_) => ({
|
||||
position: 'relative',
|
||||
}));
|
||||
|
||||
const TitleContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
margin: `${props.theme.space.s} ${props.theme.space.m}`,
|
||||
}));
|
||||
|
||||
const AddressTypeContainer = styled.div((_) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: '4px',
|
||||
}));
|
||||
|
||||
const BalanceContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'flex-end',
|
||||
margin: `${props.theme.space.s} ${props.theme.space.m}`,
|
||||
flexGrow: 1,
|
||||
}));
|
||||
|
||||
const StarIconContainer = styled.div((props) => ({
|
||||
position: 'absolute',
|
||||
right: '-8px',
|
||||
@@ -57,9 +35,48 @@ const StarIconContainer = styled.div((props) => ({
|
||||
borderRadius: '50%',
|
||||
padding: '2.2px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
const RowContainers = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const RowContainer = styled.div((props) => ({
|
||||
display: 'flex',
|
||||
columnGap: props.theme.space.m,
|
||||
justifyContent: 'center',
|
||||
}));
|
||||
|
||||
const AddressTypeContainer = styled.div((_) => ({
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
justifyContent: 'flex-start',
|
||||
gap: '4px',
|
||||
}));
|
||||
|
||||
const BalanceContainer = styled.div`
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
${(props) => props.theme.typography.body_bold_m};
|
||||
`;
|
||||
|
||||
const BalancePercentageContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-start;
|
||||
${(props) => props.theme.typography.body_m};
|
||||
color: ${(props) => props.theme.colors.white_200};
|
||||
`;
|
||||
|
||||
const CurrencyBalanceContainer = styled.div`
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
${(props) => props.theme.typography.body_m};
|
||||
color: ${(props) => props.theme.colors.white_200};
|
||||
`;
|
||||
|
||||
type AddressBalanceProps = {
|
||||
balance: number | undefined;
|
||||
addressType: BtcAddressType | undefined;
|
||||
@@ -97,30 +114,32 @@ export default function AddressBalance({
|
||||
)}
|
||||
</IconContainer>
|
||||
</IconOuterContainer>
|
||||
<TitleContainer>
|
||||
<AddressTypeContainer>
|
||||
<StyledP typography="body_bold_m">BTC</StyledP>
|
||||
{addressType && <BtcAddressTypeLabel addressType={addressType} />}
|
||||
</AddressTypeContainer>
|
||||
<StyledP typography="body_m" color="white_200">
|
||||
{totalBalance !== undefined ? `${balancePercentage}%` : ''}
|
||||
</StyledP>
|
||||
</TitleContainer>
|
||||
<BalanceContainer>
|
||||
<StyledP typography="body_bold_m">
|
||||
{balanceHidden ? HIDDEN_BALANCE_LABEL : satsToBtc(BigNumber(balance)).toString()}
|
||||
</StyledP>
|
||||
<StyledP typography="body_m" color="white_200">
|
||||
{balanceHidden ? (
|
||||
HIDDEN_BALANCE_LABEL
|
||||
) : (
|
||||
<FiatAmountText
|
||||
fiatAmount={getBtcFiatEquivalent(BigNumber(balance), BigNumber(btcFiatRate))}
|
||||
fiatCurrency={fiatCurrency}
|
||||
/>
|
||||
)}
|
||||
</StyledP>
|
||||
</BalanceContainer>
|
||||
<RowContainers>
|
||||
<RowContainer>
|
||||
<AddressTypeContainer>
|
||||
<StyledP typography="body_bold_m">BTC</StyledP>
|
||||
{addressType && <BtcAddressTypeLabel addressType={addressType} />}
|
||||
</AddressTypeContainer>
|
||||
<BalanceContainer>
|
||||
{balanceHidden ? HIDDEN_BALANCE_LABEL : satsToBtc(BigNumber(balance)).toString()}
|
||||
</BalanceContainer>
|
||||
</RowContainer>
|
||||
<RowContainer>
|
||||
<BalancePercentageContainer>
|
||||
{totalBalance !== undefined ? `${balancePercentage}%` : ''}
|
||||
</BalancePercentageContainer>
|
||||
<CurrencyBalanceContainer>
|
||||
{balanceHidden ? (
|
||||
HIDDEN_BALANCE_LABEL
|
||||
) : (
|
||||
<FiatAmountText
|
||||
fiatAmount={getBtcFiatEquivalent(BigNumber(balance), BigNumber(btcFiatRate))}
|
||||
fiatCurrency={fiatCurrency}
|
||||
/>
|
||||
)}
|
||||
</CurrencyBalanceContainer>
|
||||
</RowContainer>
|
||||
</RowContainers>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -442,9 +442,10 @@ export default class Wallet {
|
||||
this.buttonBRC20 = page.getByRole('button', { name: 'BRC-20' });
|
||||
this.buttonRunes = page.getByRole('button', { name: 'RUNES' });
|
||||
this.headingTokens = page.getByRole('heading', { name: 'Manage tokens' });
|
||||
|
||||
this.divTokenRow = page.getByLabel('Token Row');
|
||||
this.labelTokenSubtitle = page.getByLabel('Token SubTitle');
|
||||
this.labelCoinBalanceCurrency = page.getByLabel('CoinBalance Container').locator('span');
|
||||
this.labelCoinBalanceCurrency = page.getByLabel('CurrencyBalance Container').locator('span');
|
||||
this.labelCoinBalanceCrypto = page.getByLabel('CoinBalance Container').locator('p');
|
||||
|
||||
// Coin details
|
||||
|
||||
Reference in New Issue
Block a user