diff --git a/src/app/components/account-total-balance.tsx b/src/app/components/account-total-balance.tsx
index 4dfb1a5622f..efb430ded57 100644
--- a/src/app/components/account-total-balance.tsx
+++ b/src/app/components/account-total-balance.tsx
@@ -13,5 +13,9 @@ export const AccountTotalBalance = memo(({ btcAddress, stxAddress }: AccountTota
if (!totalBalance) return null;
- return {totalBalance.totalUsdBalance};
+ return (
+
+ {totalBalance.totalUsdBalance}
+
+ );
});
diff --git a/src/app/components/account/account-addresses.tsx b/src/app/components/account/account-addresses.tsx
new file mode 100644
index 00000000000..f9c3c66b64e
--- /dev/null
+++ b/src/app/components/account/account-addresses.tsx
@@ -0,0 +1,29 @@
+import { HStack } from 'leather-styles/jsx';
+
+import { useViewportMinWidth } from '@app/common/hooks/use-media-query';
+import { BulletSeparator } from '@app/ui/components/bullet-separator/bullet-separator';
+import { Caption } from '@app/ui/components/typography/caption';
+import { truncateMiddle } from '@app/ui/utils/truncate-middle';
+
+import { StacksAccountLoader } from '../loaders/stacks-account-loader';
+import { BitcoinNativeSegwitAccountLoader } from './bitcoin-account-loader';
+
+interface AccountAddressesProps {
+ index: number;
+}
+export function AcccountAddresses({ index }: AccountAddressesProps) {
+ const isBreakpointSm = useViewportMinWidth('sm');
+
+ return (
+
+
+
+ {account => {truncateMiddle(account.address, isBreakpointSm ? 4 : 3)}}
+
+
+ {signer => {truncateMiddle(signer.address, 5)}}
+
+
+
+ );
+}
diff --git a/src/app/components/account/account-list-item-layout.tsx b/src/app/components/account/account-list-item-layout.tsx
deleted file mode 100644
index c639cc12969..00000000000
--- a/src/app/components/account/account-list-item-layout.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { SettingsSelectors } from '@tests/selectors/settings.selectors';
-import { Flex, HStack, Stack, StackProps, styled } from 'leather-styles/jsx';
-
-import { useViewportMinWidth } from '@app/common/hooks/use-media-query';
-import { BulletSeparator } from '@app/ui/components/bullet-separator/bullet-separator';
-import { Flag } from '@app/ui/components/flag/flag';
-import { CheckmarkIcon } from '@app/ui/components/icons/checkmark-icon';
-import { Spinner } from '@app/ui/components/spinner';
-import { truncateMiddle } from '@app/ui/utils/truncate-middle';
-
-import { StacksAccountLoader } from '../loaders/stacks-account-loader';
-import { BitcoinNativeSegwitAccountLoader } from './bitcoin-account-loader';
-
-interface AccountListItemLayoutProps extends StackProps {
- isLoading: boolean;
- isActive: boolean;
- index: number;
- accountName: React.ReactNode;
- avatar: React.JSX.Element;
- balanceLabel: React.ReactNode;
- onSelectAccount(): void;
-}
-export function AccountListItemLayout(props: AccountListItemLayoutProps) {
- const {
- index,
- isLoading,
- isActive,
- accountName,
- avatar,
- balanceLabel,
- onSelectAccount,
- children = null,
- ...rest
- } = props;
-
- const isBreakpointSm = useViewportMinWidth('sm');
-
- return (
-
-
-
-
-
- {accountName}
- {isActive && }
-
- {isLoading ? (
-
- ) : (
- balanceLabel
- )}
-
-
-
-
- {account => (
-
- {truncateMiddle(account.address, isBreakpointSm ? 4 : 3)}
-
- )}
-
-
-
- {signer => (
-
- {truncateMiddle(signer.address, 5)}
-
- )}
-
-
-
-
-
- {children}
-
- );
-}
diff --git a/src/app/components/account/account-list-item.layout.tsx b/src/app/components/account/account-list-item.layout.tsx
new file mode 100644
index 00000000000..f353437b7ec
--- /dev/null
+++ b/src/app/components/account/account-list-item.layout.tsx
@@ -0,0 +1,58 @@
+import { ReactNode } from 'react';
+
+import { SettingsSelectors } from '@tests/selectors/settings.selectors';
+
+import { ItemInteractive } from '@app/ui/components/item/item-interactive';
+import { ItemLayout } from '@app/ui/components/item/item.layout';
+import { Spinner } from '@app/ui/components/spinner';
+
+interface AccountListItemLayoutProps {
+ accountAddresses: ReactNode;
+ accountName: ReactNode;
+ avatar: ReactNode;
+ balanceLabel: ReactNode;
+ index: number;
+ isLoading: boolean;
+ isSelected: boolean;
+ onSelectAccount(): void;
+}
+export function AccountListItemLayout(props: AccountListItemLayoutProps) {
+ const {
+ accountAddresses,
+ accountName,
+ avatar,
+ balanceLabel,
+ index,
+ isLoading,
+ isSelected,
+ onSelectAccount,
+ } = props;
+
+ return (
+
+
+ ) : (
+ balanceLabel
+ )
+ }
+ captionLeft={accountAddresses}
+ />
+
+ );
+}
diff --git a/src/app/components/account/account-name.tsx b/src/app/components/account/account-name.tsx
index 67a07d4fdbf..7101f5d76d5 100644
--- a/src/app/components/account/account-name.tsx
+++ b/src/app/components/account/account-name.tsx
@@ -6,5 +6,7 @@ interface AccountNameLayoutProps {
children: React.ReactNode;
}
export const AccountNameLayout = memo(({ children }: AccountNameLayoutProps) => (
- {children}
+
+ {children}
+
));
diff --git a/src/app/components/bitcoin-transaction-item/bitcoin-transaction-item.tsx b/src/app/components/bitcoin-transaction-item/bitcoin-transaction-item.tsx
index 227990cc93f..3838cd0a656 100644
--- a/src/app/components/bitcoin-transaction-item/bitcoin-transaction-item.tsx
+++ b/src/app/components/bitcoin-transaction-item/bitcoin-transaction-item.tsx
@@ -1,8 +1,6 @@
import { useMemo } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
-import { BoxProps } from 'leather-styles/jsx';
-
import { BitcoinTx } from '@shared/models/transactions/bitcoin-transaction.model';
import { RouteUrls } from '@shared/route-urls';
@@ -15,7 +13,6 @@ import {
isBitcoinTxInbound,
} from '@app/common/transactions/bitcoin/utils';
import { openInNewTab } from '@app/common/utils/open-in-new-tab';
-import { usePressable } from '@app/components/item-hover';
import { IncreaseFeeButton } from '@app/components/stacks-transaction-item/increase-fee-button';
import { TransactionTitle } from '@app/components/transaction/transaction-title';
import {
@@ -34,11 +31,10 @@ import { InscriptionIcon } from './bitcoin-transaction-inscription-icon';
import { BitcoinTransactionStatus } from './bitcoin-transaction-status';
import { BitcoinTransactionValue } from './bitcoin-transaction-value';
-interface BitcoinTransactionItemProps extends BoxProps {
+interface BitcoinTransactionItemProps {
transaction: BitcoinTx;
}
-export function BitcoinTransactionItem({ transaction, ...rest }: BitcoinTransactionItemProps) {
- const [component, bind, { isHovered }] = usePressable(true);
+export function BitcoinTransactionItem({ transaction }: BitcoinTransactionItemProps) {
const { pathname } = useLocation();
const navigate = useNavigate();
@@ -92,7 +88,6 @@ export function BitcoinTransactionItem({ transaction, ...rest }: BitcoinTransact
const increaseFeeButton = (
@@ -101,6 +96,7 @@ export function BitcoinTransactionItem({ transaction, ...rest }: BitcoinTransact
return (
}
txTitle={}
txValue={txValue}
- belowCaptionEl={increaseFeeButton}
- {...bind}
- {...rest}
- >
- {component}
-
+ />
);
}
diff --git a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx
index 5bd77800863..80e06aa8328 100644
--- a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx
+++ b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list.tsx
@@ -3,11 +3,13 @@ import { useNavigate } from 'react-router-dom';
import { RouteUrls } from '@shared/route-urls';
import { noop } from '@shared/utils';
-import { Brc20TokenAssetItem } from '@app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item';
import { useNativeSegwitBalance } from '@app/query/bitcoin/balance/btc-native-segwit-balance.hooks';
import { Brc20Token } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.query';
import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
+import { Brc20TokenAssetItemLayout } from './components/brc20-token-asset-item.layout';
+import { Brc20AssetListLayout } from './components/brc20-token-asset-list.layout';
+
export function Brc20TokenAssetList(props: { brc20Tokens?: Brc20Token[] }) {
const navigate = useNavigate();
const currentAccountBtcAddress = useCurrentAccountNativeSegwitAddressIndexZero();
@@ -24,13 +26,17 @@ export function Brc20TokenAssetList(props: { brc20Tokens?: Brc20Token[] }) {
}
if (!props.brc20Tokens?.length) return null;
- return props.brc20Tokens.map(token => (
- navigateToBrc20SendForm(token) : noop}
- displayNotEnoughBalance={!hasPositiveBtcBalanceForFees}
- key={token.tick}
- />
- ));
+
+ return (
+
+ {props.brc20Tokens?.map(token => (
+ navigateToBrc20SendForm(token) : noop}
+ />
+ ))}
+
+ );
}
diff --git a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.layout.tsx b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.layout.tsx
index 027deed6f74..6232995762b 100644
--- a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.layout.tsx
+++ b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.layout.tsx
@@ -1,69 +1,52 @@
-import { BoxProps, Flex, HStack, styled } from 'leather-styles/jsx';
+import { styled } from 'leather-styles/jsx';
-import type { Money } from '@shared/models/money.model';
+import { createMoney } from '@shared/models/money.model';
import { formatBalance } from '@app/common/format-balance';
-import { AssetCaption } from '@app/components/crypto-assets/components/asset-caption';
-import { usePressable } from '@app/components/item-hover';
-import { Flag } from '@app/ui/components/flag/flag';
+import { Brc20Token } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.query';
import { Brc20TokenIcon } from '@app/ui/components/icons/brc20-token-icon';
+import { ItemInteractive } from '@app/ui/components/item/item-interactive';
+import { ItemLayout } from '@app/ui/components/item/item.layout';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
-interface Brc20TokenAssetItemLayoutProps extends BoxProps {
- balance: Money;
- caption: string;
- isPressable?: boolean;
+interface Brc20TokenAssetItemLayoutProps {
+ token: Brc20Token;
onClick?(): void;
- title: string;
displayNotEnoughBalance?: boolean;
}
export function Brc20TokenAssetItemLayout({
- balance,
- caption,
- isPressable,
onClick,
- title,
displayNotEnoughBalance,
+ token,
}: Brc20TokenAssetItemLayoutProps) {
- const [component, bind] = usePressable(isPressable);
-
+ const balance = createMoney(Number(token.overall_balance), token.tick, 0);
const formattedBalance = formatBalance(balance.amount.toString());
return (
-
- } spacing="space.04" width="100%">
-
-
- {title}
-
+
+ }
+ titleLeft={token.tick}
+ captionLeft="BRC-20"
+ titleRight={
-
+
{formattedBalance.value}
-
-
-
-
- {component}
-
-
+ }
+ />
+
);
}
diff --git a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.tsx b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.tsx
deleted file mode 100644
index 29820b11099..00000000000
--- a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { createMoney } from '@shared/models/money.model';
-
-import { Brc20Token } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.query';
-
-import { Brc20TokenAssetItemLayout } from './brc20-token-asset-item.layout';
-
-interface Brc20TokenAssetItemProps {
- token: Brc20Token;
- isPressable?: boolean;
- onClick?(): void;
- displayNotEnoughBalance?: boolean;
-}
-export function Brc20TokenAssetItem({
- token,
- isPressable,
- onClick,
- displayNotEnoughBalance,
-}: Brc20TokenAssetItemProps) {
- return (
-
- );
-}
diff --git a/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-list.layout.tsx b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-list.layout.tsx
new file mode 100644
index 00000000000..41ea4db9c38
--- /dev/null
+++ b/src/app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-list.layout.tsx
@@ -0,0 +1,10 @@
+import { CryptoAssetSelectors } from '@tests/selectors/crypto-asset.selectors';
+import { Stack, StackProps } from 'leather-styles/jsx';
+
+export function Brc20AssetListLayout({ children }: StackProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list-item.tsx b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list-item.tsx
index e98f899f166..4e790a4e35f 100644
--- a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list-item.tsx
+++ b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list-item.tsx
@@ -1,7 +1,6 @@
import type { AllTransferableCryptoAssetBalances } from '@shared/models/crypto-asset-balance.model';
-import { CryptoCurrencyAssetItem } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item';
-
+import { CryptoCurrencyAssetItemLayout } from '../crypto-currency-asset/crypto-currency-asset-item.layout';
import { CryptoCurrencyAssetIcon } from './crypto-currency-asset-icon';
import { FungibleTokenAssetItem } from './fungible-token-asset-item';
@@ -16,10 +15,9 @@ export function CryptoAssetListItem(props: CryptoAssetListItemProps) {
switch (type) {
case 'crypto-currency':
return (
- }
- isPressable
onClick={onClick}
/>
);
diff --git a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx
index e1803d73421..c5c9418347b 100644
--- a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx
+++ b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.layout.tsx
@@ -3,12 +3,7 @@ import { Stack, StackProps } from 'leather-styles/jsx';
export function CryptoAssetListLayout({ children }: StackProps) {
return (
-
+
{children}
);
diff --git a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx
index fd1fb2f0e0f..0605e67c3bf 100644
--- a/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx
+++ b/src/app/components/crypto-assets/choose-crypto-asset/crypto-asset-list.tsx
@@ -8,7 +8,7 @@ import { Brc20TokensLoader } from '@app/components/brc20-tokens-loader';
import { Brc20TokenAssetList } from '@app/components/crypto-assets/bitcoin/brc20-token-asset-list/brc20-token-asset-list';
import { BtcIcon } from '@app/ui/components/icons/btc-icon';
-import { CryptoCurrencyAssetItem } from '../crypto-currency-asset/crypto-currency-asset-item';
+import { CryptoCurrencyAssetItemLayout } from '../crypto-currency-asset/crypto-currency-asset-item.layout';
import { CryptoAssetListItem } from './crypto-asset-list-item';
import { CryptoAssetListLayout } from './crypto-asset-list.layout';
@@ -25,11 +25,10 @@ export function CryptoAssetList({ cryptoAssetBalances, onItemClick }: CryptoAsse
{signer => (
{balance => (
- }
onClick={() => onItemClick(balance)}
- isPressable
/>
)}
diff --git a/src/app/components/crypto-assets/choose-crypto-asset/fungible-token-asset-item.tsx b/src/app/components/crypto-assets/choose-crypto-asset/fungible-token-asset-item.tsx
index 0ce6b98c4ff..7be8034c33e 100644
--- a/src/app/components/crypto-assets/choose-crypto-asset/fungible-token-asset-item.tsx
+++ b/src/app/components/crypto-assets/choose-crypto-asset/fungible-token-asset-item.tsx
@@ -2,7 +2,7 @@ import { FlexProps } from 'leather-styles/jsx';
import type { StacksFungibleTokenAssetBalance } from '@shared/models/crypto-asset-balance.model';
-import { StacksFungibleTokenAssetItem } from '@app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item';
+import { StacksFungibleTokenAssetItemLayout } from '../stacks/fungible-token-asset/stacks-fungible-token-asset-item.layout';
interface FungibleTokenAssetItemProps extends FlexProps {
assetBalance: StacksFungibleTokenAssetBalance;
@@ -13,9 +13,7 @@ export function FungibleTokenAssetItem({ assetBalance, onClick }: FungibleTokenA
switch (blockchain) {
case 'stacks':
- return (
-
- );
+ return ;
default:
return null;
}
diff --git a/src/app/components/crypto-assets/components/asset-caption.tsx b/src/app/components/crypto-assets/components/asset-caption.tsx
deleted file mode 100644
index 36dd07d71d4..00000000000
--- a/src/app/components/crypto-assets/components/asset-caption.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Flex, styled } from 'leather-styles/jsx';
-
-interface AssetCaptionProps {
- caption: string;
-}
-export function AssetCaption({ caption }: AssetCaptionProps) {
- return (
-
- {caption}{' '}
-
- );
-}
diff --git a/src/app/components/crypto-assets/components/asset-row-grid.tsx b/src/app/components/crypto-assets/components/asset-row-grid.tsx
deleted file mode 100644
index 3508934ab32..00000000000
--- a/src/app/components/crypto-assets/components/asset-row-grid.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Grid, GridItem } from 'leather-styles/jsx';
-
-interface AssetRowGridProps {
- title: React.ReactNode;
- balance: React.ReactNode;
- caption: React.ReactNode;
- usdBalance?: React.ReactNode;
- rightElement?: React.ReactNode;
-}
-export function AssetRowGrid({
- title,
- balance,
- caption,
- usdBalance,
- rightElement,
-}: AssetRowGridProps) {
- const balanceItem = rightElement ? (
-
- {rightElement}
-
- ) : (
- {balance}
- );
- return (
-
-
- {title}
-
- {balanceItem}
- {caption}
- {usdBalance && {usdBalance}}
-
- );
-}
diff --git a/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout.tsx b/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout.tsx
index 5dc6cfadb58..0efb73b7727 100644
--- a/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout.tsx
+++ b/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout.tsx
@@ -1,98 +1,69 @@
-import { CryptoAssetSelectors } from '@tests/selectors/crypto-asset.selectors';
-import { Flex, styled } from 'leather-styles/jsx';
+import { ReactNode } from 'react';
-import { CryptoCurrencies } from '@shared/models/currencies.model';
-import { Money } from '@shared/models/money.model';
+import { styled } from 'leather-styles/jsx';
-import { formatBalance } from '@app/common/format-balance';
-import { ftDecimals } from '@app/common/stacks-utils';
-import { usePressable } from '@app/components/item-hover';
-import { Flag } from '@app/ui/components/flag/flag';
+import { AllCryptoCurrencyAssetBalances } from '@shared/models/crypto-asset-balance.model';
+
+import { ItemInteractive } from '@app/ui/components/item/item-interactive';
+import { ItemLayout } from '@app/ui/components/item/item.layout';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
-import { truncateMiddle } from '@app/ui/utils/truncate-middle';
+import { Caption } from '@app/ui/components/typography/caption';
-import { AssetRowGrid } from '../components/asset-row-grid';
+import { parseCryptoCurrencyAssetBalance } from './crypto-currency-asset.utils';
interface CryptoCurrencyAssetItemLayoutProps {
- balance: Money;
- caption: string;
- icon: React.ReactNode;
- copyIcon?: React.ReactNode;
- isPressable?: boolean;
- title: string;
- usdBalance?: string;
+ additionalBalanceInfo?: ReactNode;
+ additionalUsdBalanceInfo?: ReactNode;
address?: string;
- isHovered?: boolean;
- currency?: CryptoCurrencies;
- additionalBalanceInfo?: React.ReactNode;
- additionalUsdBalanceInfo?: React.ReactNode;
- rightElement?: React.ReactNode;
+ assetBalance: AllCryptoCurrencyAssetBalances;
+ icon: React.ReactNode;
onClick?(): void;
+ rightElement?: React.ReactNode;
+ usdBalance?: string;
}
export function CryptoCurrencyAssetItemLayout({
- balance,
- caption,
- icon,
- copyIcon,
- isPressable,
- title,
- usdBalance,
- address = '',
- isHovered = false,
additionalBalanceInfo,
additionalUsdBalanceInfo,
- rightElement,
+ address = '',
+ assetBalance,
+ icon,
onClick,
+ rightElement,
+ usdBalance,
}: CryptoCurrencyAssetItemLayoutProps) {
- const [component, bind] = usePressable(isPressable);
-
- const amount = balance.decimals
- ? ftDecimals(balance.amount, balance.decimals)
- : balance.amount.toString();
- const dataTestId = CryptoAssetSelectors.CryptoAssetListItem.replace(
- '{symbol}',
- balance.symbol.toLowerCase()
- );
- const formattedBalance = formatBalance(amount);
+ const { balance, dataTestId, formattedBalance, title } =
+ parseCryptoCurrencyAssetBalance(assetBalance);
return (
-
-
-
- {isHovered ? truncateMiddle(address, 6) : title}
-
- }
- balance={
+
+
-
+
{formattedBalance.value} {additionalBalanceInfo}
- }
- caption={
-
- {caption}
-
- }
- usdBalance={
-
- {balance.amount.toNumber() > 0 && address ? (
-
- {usdBalance}
-
- ) : null}
+ )
+ }
+ captionRight={
+ !rightElement && (
+ <>
+ {balance.amount.toNumber() > 0 && address ? usdBalance : null}
{additionalUsdBalanceInfo}
-
- }
- rightElement={rightElement}
- />
-
- {component}
-
+ >
+ )
+ }
+ />
+
);
}
diff --git a/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.tsx b/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.tsx
deleted file mode 100644
index bddbae243ac..00000000000
--- a/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import type { AllCryptoCurrencyAssetBalances } from '@shared/models/crypto-asset-balance.model';
-
-import { spamFilter } from '@app/common/utils/spam-filter';
-
-import { CryptoCurrencyAssetItemLayout } from './crypto-currency-asset-item.layout';
-
-interface CryptoCurrencyAssetItemProps {
- assetBalance: AllCryptoCurrencyAssetBalances;
- icon: React.ReactNode;
- usdBalance?: string;
- address?: string;
- isPressable?: boolean;
- additionalBalanceInfo?: React.ReactNode;
- additionalUsdBalanceInfo?: React.ReactNode;
- rightElement?: React.ReactNode;
- onClick?(): void;
-}
-export function CryptoCurrencyAssetItem({
- additionalBalanceInfo,
- additionalUsdBalanceInfo,
- address,
- assetBalance,
- icon,
- isPressable,
- onClick,
- rightElement,
- usdBalance,
-}: CryptoCurrencyAssetItemProps) {
- const { balance, asset } = assetBalance;
-
- return (
-
- );
-}
diff --git a/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset.utils.ts b/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset.utils.ts
new file mode 100644
index 00000000000..041ca288ea5
--- /dev/null
+++ b/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset.utils.ts
@@ -0,0 +1,28 @@
+import { CryptoAssetSelectors } from '@tests/selectors/crypto-asset.selectors';
+
+import { AllCryptoCurrencyAssetBalances } from '@shared/models/crypto-asset-balance.model';
+
+import { formatBalance } from '@app/common/format-balance';
+import { ftDecimals } from '@app/common/stacks-utils';
+import { spamFilter } from '@app/common/utils/spam-filter';
+
+export function parseCryptoCurrencyAssetBalance(assetBalance: AllCryptoCurrencyAssetBalances) {
+ const { asset, balance } = assetBalance;
+
+ const amount = balance.decimals
+ ? ftDecimals(balance.amount, balance.decimals)
+ : balance.amount.toString();
+ const dataTestId = CryptoAssetSelectors.CryptoAssetListItem.replace(
+ '{symbol}',
+ balance.symbol.toLowerCase()
+ );
+ const formattedBalance = formatBalance(amount);
+ const title = spamFilter(asset.name);
+
+ return {
+ balance,
+ dataTestId,
+ formattedBalance,
+ title,
+ };
+}
diff --git a/src/app/components/crypto-assets/stacks/components/stacks-asset-avatar.tsx b/src/app/components/crypto-assets/stacks/components/stacks-asset-avatar.tsx
index f731aea9a1f..08d771dd2d1 100644
--- a/src/app/components/crypto-assets/stacks/components/stacks-asset-avatar.tsx
+++ b/src/app/components/crypto-assets/stacks/components/stacks-asset-avatar.tsx
@@ -15,7 +15,7 @@ export function StacksAssetAvatar({
gradientString,
imageCanonicalUri,
isStx,
- size = '36',
+ size = '40',
...props
}: StacksAssetAvatarProps) {
if (isStx) return ;
diff --git a/src/app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item.tsx b/src/app/components/crypto-assets/stacks/fungible-token-asset/fungible-token-asset.utils.ts
similarity index 58%
rename from src/app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item.tsx
rename to src/app/components/crypto-assets/stacks/fungible-token-asset/fungible-token-asset.utils.ts
index 62c76e02d1c..06336273364 100644
--- a/src/app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item.tsx
+++ b/src/app/components/crypto-assets/stacks/fungible-token-asset/fungible-token-asset.utils.ts
@@ -1,46 +1,41 @@
import { CryptoAssetSelectors } from '@tests/selectors/crypto-asset.selectors';
-import { FlexProps } from 'leather-styles/jsx';
import type { StacksFungibleTokenAssetBalance } from '@shared/models/crypto-asset-balance.model';
import { getImageCanonicalUri } from '@app/common/crypto-assets/stacks-crypto-asset.utils';
+import { formatBalance } from '@app/common/format-balance';
+import { ftDecimals } from '@app/common/stacks-utils';
import { formatContractId, getTicker } from '@app/common/utils';
import { spamFilter } from '@app/common/utils/spam-filter';
import { getAssetName } from '@app/ui/utils/get-asset-name';
-import { StacksFungibleTokenAssetItemLayout } from './stacks-fungible-token-asset-item.layout';
-
-interface StacksFungibleTokenAssetItemProps extends FlexProps {
- assetBalance: StacksFungibleTokenAssetBalance;
- isPressable?: boolean;
- onClick?(): void;
-}
-export function StacksFungibleTokenAssetItem({
- assetBalance,
- isPressable,
- onClick,
-}: StacksFungibleTokenAssetItemProps) {
+export function parseStacksFungibleTokenAssetBalance(
+ assetBalance: StacksFungibleTokenAssetBalance
+) {
const { asset, balance } = assetBalance;
const { contractAddress, contractAssetName, contractName, name, symbol } = asset;
+ const amount = balance.decimals
+ ? ftDecimals(balance.amount, balance.decimals || 0)
+ : balance.amount.toString();
const avatar = `${formatContractId(contractAddress, contractName)}::${contractAssetName}`;
const dataTestId =
symbol && CryptoAssetSelectors.CryptoAssetListItem.replace('{symbol}', symbol.toLowerCase());
+ const formattedBalance = formatBalance(amount);
const friendlyName =
name ||
(contractAssetName.includes('::') ? getAssetName(contractAssetName) : contractAssetName);
const imageCanonicalUri = getImageCanonicalUri(asset.imageCanonicalUri, asset.name);
const caption = symbol || getTicker(friendlyName);
- return (
-
- );
+ const title = spamFilter(friendlyName);
+
+ return {
+ amount,
+ avatar,
+ caption,
+ dataTestId,
+ formattedBalance,
+ imageCanonicalUri,
+ title,
+ };
}
diff --git a/src/app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item.layout.tsx b/src/app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item.layout.tsx
index d476b4db70c..79b0f6fc747 100644
--- a/src/app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item.layout.tsx
+++ b/src/app/components/crypto-assets/stacks/fungible-token-asset/stacks-fungible-token-asset-item.layout.tsx
@@ -1,46 +1,29 @@
-import { Flex, FlexProps, styled } from 'leather-styles/jsx';
+import { styled } from 'leather-styles/jsx';
-import type { Money } from '@shared/models/money.model';
+import { StacksFungibleTokenAssetBalance } from '@shared/models/crypto-asset-balance.model';
-import { formatBalance } from '@app/common/format-balance';
-import { ftDecimals } from '@app/common/stacks-utils';
import { StacksAssetAvatar } from '@app/components/crypto-assets/stacks/components/stacks-asset-avatar';
-import { usePressable } from '@app/components/item-hover';
-import { Flag } from '@app/ui/components/flag/flag';
+import { ItemInteractive } from '@app/ui/components/item/item-interactive';
+import { ItemLayout } from '@app/ui/components/item/item.layout';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
-import { AssetCaption } from '../../components/asset-caption';
-import { AssetRowGrid } from '../../components/asset-row-grid';
+import { parseStacksFungibleTokenAssetBalance } from './fungible-token-asset.utils';
-interface StacksFungibleTokenAssetItemLayoutProps extends FlexProps {
- avatar: string;
- balance: Money;
- caption: string;
- imageCanonicalUri?: string;
- isPressable?: boolean;
- title: string;
+interface StacksFungibleTokenAssetItemLayoutProps {
+ assetBalance: StacksFungibleTokenAssetBalance;
onClick?(): void;
}
export function StacksFungibleTokenAssetItemLayout({
- avatar,
- balance,
- caption,
- imageCanonicalUri,
- isPressable,
- title,
+ assetBalance,
onClick,
}: StacksFungibleTokenAssetItemLayoutProps) {
- const [component, bind] = usePressable(isPressable);
-
- const amount = balance.decimals
- ? ftDecimals(balance.amount, balance.decimals || 0)
- : balance.amount.toString();
- const formattedBalance = formatBalance(amount);
+ const { amount, avatar, caption, dataTestId, formattedBalance, imageCanonicalUri, title } =
+ parseStacksFungibleTokenAssetBalance(assetBalance);
return (
-
-
+
}
- spacing="space.04"
- width="100%"
- >
- {title}}
- balance={
-
-
- {formattedBalance.value}
-
-
- }
- caption={}
- />
- {component}
-
-
+ titleLeft={title}
+ captionLeft={caption}
+ titleRight={
+
+
+ {formattedBalance.value}
+
+
+ }
+ />
+
);
}
diff --git a/src/app/components/stacks-transaction-item/increase-fee-button.tsx b/src/app/components/stacks-transaction-item/increase-fee-button.tsx
index 7cb383c8fef..cf924f4e988 100644
--- a/src/app/components/stacks-transaction-item/increase-fee-button.tsx
+++ b/src/app/components/stacks-transaction-item/increase-fee-button.tsx
@@ -4,13 +4,12 @@ import { ChevronsRightIcon } from '@app/ui/components/icons/chevrons-right-icon'
interface IncreaseFeeButtonProps {
isEnabled?: boolean;
- isHovered: boolean;
isSelected: boolean;
onIncreaseFee(): void;
}
export function IncreaseFeeButton(props: IncreaseFeeButtonProps) {
- const { isEnabled, isHovered, isSelected, onIncreaseFee } = props;
- const isActive = isEnabled && isHovered && !isSelected;
+ const { isEnabled, isSelected, onIncreaseFee } = props;
+ const isActive = isEnabled && !isSelected;
return (
@@ -99,16 +95,12 @@ export function StacksTransactionItem({
return (
}
txValue={txValue}
- belowCaptionEl={increaseFeeButton}
- {...bind}
- {...rest}
- >
- {component}
-
+ />
);
}
diff --git a/src/app/components/transaction-item/transaction-item.layout.tsx b/src/app/components/transaction-item/transaction-item.layout.tsx
index bb961b93108..e778cf9591d 100644
--- a/src/app/components/transaction-item/transaction-item.layout.tsx
+++ b/src/app/components/transaction-item/transaction-item.layout.tsx
@@ -1,49 +1,53 @@
import { ReactNode } from 'react';
-import { Box, Flex, HStack } from 'leather-styles/jsx';
+import { styled } from 'leather-styles/jsx';
+
+import { ItemInteractive } from '@app/ui/components/item/item-interactive';
+import { ItemLayout } from '@app/ui/components/item/item.layout';
interface TransactionItemLayoutProps {
openTxLink(): void;
+ rightElement?: ReactNode;
txCaption: ReactNode;
txTitle: ReactNode;
txValue: ReactNode;
txIcon?: ReactNode;
txStatus?: ReactNode;
- belowCaptionEl?: ReactNode;
children?: ReactNode;
}
export function TransactionItemLayout({
openTxLink,
+ rightElement,
txCaption,
txIcon,
txStatus,
txTitle,
txValue,
- belowCaptionEl,
- children,
- ...rest
}: TransactionItemLayoutProps) {
return (
-
-
- {txIcon && txIcon}
-
-
- {txTitle} {txValue}
-
-
- {txCaption} {txStatus && txStatus}
- {belowCaptionEl ? belowCaptionEl : null}
-
-
-
- {children}
-
+ // TODO: Revisit if needed styles position="relative" zIndex={99}
+
+
+
+ {txCaption}
+
+ {txStatus && txStatus}
+ >
+ }
+ titleRight={
+ rightElement ? (
+ rightElement
+ ) : (
+
+ {txValue}
+
+ )
+ }
+ />
+
);
}
diff --git a/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.layout.tsx b/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.layout.tsx
index 3d2fb787563..44acfa0e297 100644
--- a/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.layout.tsx
+++ b/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.layout.tsx
@@ -11,7 +11,7 @@ export function PendingTransactionListLayout({ children }: PendingTransactionLis
Pending
-
+
{children}
>
diff --git a/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.tsx b/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.tsx
index 6fa22d355a1..2fe58970c23 100644
--- a/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.tsx
+++ b/src/app/features/activity-list/components/pending-transaction-list/pending-transaction-list.tsx
@@ -2,9 +2,9 @@ import { MempoolTransaction } from '@stacks/stacks-blockchain-api-types';
import { BitcoinTx } from '@shared/models/transactions/bitcoin-transaction.model';
+import { BitcoinTransactionItem } from '@app/components/bitcoin-transaction-item/bitcoin-transaction-item';
import { StacksTransactionItem } from '@app/components/stacks-transaction-item/stacks-transaction-item';
-import { BitcoinTransactionItem } from '../../../../components/bitcoin-transaction-item/bitcoin-transaction-item';
import { PendingTransactionListLayout } from './pending-transaction-list.layout';
interface PendingTransactionListProps {
diff --git a/src/app/features/activity-list/components/transaction-list/transaction-list.layout.tsx b/src/app/features/activity-list/components/transaction-list/transaction-list.layout.tsx
index eed16bebc44..7d3f7c2e50a 100644
--- a/src/app/features/activity-list/components/transaction-list/transaction-list.layout.tsx
+++ b/src/app/features/activity-list/components/transaction-list/transaction-list.layout.tsx
@@ -6,9 +6,5 @@ interface TransactionListLayoutProps {
children: ReactNode;
}
export function TransactionListLayout({ children }: TransactionListLayoutProps) {
- return (
-
- {children}
-
- );
+ return {children};
}
diff --git a/src/app/features/activity-list/components/transaction-list/transactions-by-date.layout.tsx b/src/app/features/activity-list/components/transaction-list/transactions-by-date.layout.tsx
index 117d795d447..f9b3bde1d8d 100644
--- a/src/app/features/activity-list/components/transaction-list/transactions-by-date.layout.tsx
+++ b/src/app/features/activity-list/components/transaction-list/transactions-by-date.layout.tsx
@@ -17,9 +17,7 @@ export function TransactionsByDateLayout({
{displayDate}
-
- {children}
-
+ {children}
);
}
diff --git a/src/app/features/asset-list/asset-list.tsx b/src/app/features/asset-list/asset-list.tsx
index d6703e2c534..096f86f20b0 100644
--- a/src/app/features/asset-list/asset-list.tsx
+++ b/src/app/features/asset-list/asset-list.tsx
@@ -7,7 +7,7 @@ import { useBtcAssetBalance } from '@app/common/hooks/balance/btc/use-btc-balanc
import { useWalletType } from '@app/common/use-wallet-type';
import { BitcoinContractEntryPoint } from '@app/components/bitcoin-contract-entry-point/bitcoin-contract-entry-point';
import { Brc20TokensLoader } from '@app/components/brc20-tokens-loader';
-import { CryptoCurrencyAssetItem } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item';
+import { CryptoCurrencyAssetItemLayout } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout';
import { CurrentStacksAccountLoader } from '@app/components/loaders/stacks-account-loader';
import { useHasBitcoinLedgerKeychain } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger';
import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
@@ -31,10 +31,10 @@ export function AssetsList() {
const { whenWallet } = useWalletType();
return (
-
+
{whenWallet({
software: (
- }
@@ -42,7 +42,7 @@ export function AssetsList() {
/>
),
ledger: (
- }
diff --git a/src/app/features/asset-list/components/add-stacks-ledger-keys-item.tsx b/src/app/features/asset-list/components/add-stacks-ledger-keys-item.tsx
index a09c669a03f..ff0f0ed281a 100644
--- a/src/app/features/asset-list/components/add-stacks-ledger-keys-item.tsx
+++ b/src/app/features/asset-list/components/add-stacks-ledger-keys-item.tsx
@@ -1,6 +1,6 @@
import BigNumber from 'bignumber.js';
-import { CryptoCurrencyAssetItem } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item';
+import { CryptoCurrencyAssetItemLayout } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout';
import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar';
import { createStacksCryptoCurrencyAssetTypeWrapper } from '@app/query/stacks/balance/stacks-ft-balances.utils';
@@ -8,7 +8,7 @@ import { ConnectLedgerAssetBtn } from './connect-ledger-asset-button';
export function AddStacksLedgerKeysItem() {
return (
- }
rightElement={}
diff --git a/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx b/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx
index c8ce70ef4b9..e71915b3ee3 100644
--- a/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx
+++ b/src/app/features/asset-list/components/bitcoin-fungible-tokens-asset-list.tsx
@@ -1,6 +1,6 @@
import { Stack } from 'leather-styles/jsx';
-import { Brc20TokenAssetItem } from '@app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item';
+import { Brc20TokenAssetItemLayout } from '@app/components/crypto-assets/bitcoin/brc20-token-asset-list/components/brc20-token-asset-item.layout';
import { Brc20Token } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.query';
interface BitcoinFungibleTokenAssetListProps {
@@ -12,7 +12,7 @@ export function BitcoinFungibleTokenAssetList({ brc20Tokens }: BitcoinFungibleTo
return (
{brc20Tokens.map(token => (
-
+
))}
);
diff --git a/src/app/features/asset-list/components/stacks-asset-list.tsx b/src/app/features/asset-list/components/stacks-asset-list.tsx
index 13019d672e4..a58c3a82834 100644
--- a/src/app/features/asset-list/components/stacks-asset-list.tsx
+++ b/src/app/features/asset-list/components/stacks-asset-list.tsx
@@ -2,7 +2,7 @@ import { styled } from 'leather-styles/jsx';
import { useStxBalance } from '@app/common/hooks/balance/stx/use-stx-balance';
import { ftDecimals } from '@app/common/stacks-utils';
-import { CryptoCurrencyAssetItem } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item';
+import { CryptoCurrencyAssetItemLayout } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout';
import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar';
import { useStacksFungibleTokenAssetBalancesWithMetadata } from '@app/query/stacks/balance/stacks-ft-balances.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
@@ -36,7 +36,7 @@ export function StacksAssetList({ account }: StacksAssetListProps) {
return (
<>
-
+
{assetBalances.map(assetBalance => (
-
diff --git a/src/app/features/collectibles/components/collectibes.layout.tsx b/src/app/features/collectibles/components/collectibes.layout.tsx
index ccdae07f19e..091fa5196c5 100644
--- a/src/app/features/collectibles/components/collectibes.layout.tsx
+++ b/src/app/features/collectibles/components/collectibes.layout.tsx
@@ -23,7 +23,7 @@ export function CollectiblesLayout({
}: CollectiblesLayoutProps) {
return (
<>
-
+
{title}
{isLoading ? (
diff --git a/src/app/features/increase-fee-drawer/components/increase-btc-fee-form.tsx b/src/app/features/increase-fee-drawer/components/increase-btc-fee-form.tsx
index c9520a69f7b..bb6bff62f2a 100644
--- a/src/app/features/increase-fee-drawer/components/increase-btc-fee-form.tsx
+++ b/src/app/features/increase-fee-drawer/components/increase-btc-fee-form.tsx
@@ -50,7 +50,7 @@ export function IncreaseBtcFeeForm({ btcTx }: IncreaseBtcFeeFormProps) {
validationSchema={validationSchema}
>
- {btcTx && }
+ {btcTx && }
diff --git a/src/app/features/increase-fee-drawer/components/increase-stx-fee-form.tsx b/src/app/features/increase-fee-drawer/components/increase-stx-fee-form.tsx
index bd9a3ce5512..3d010093475 100644
--- a/src/app/features/increase-fee-drawer/components/increase-stx-fee-form.tsx
+++ b/src/app/features/increase-fee-drawer/components/increase-stx-fee-form.tsx
@@ -74,7 +74,7 @@ export function IncreaseStxFeeForm() {
>
{props => (
- {tx && }
+ {tx && }
{balances?.stx.unlockedStx.amount && (
diff --git a/src/app/features/leather-intro-dialog/leather-intro-steps.tsx b/src/app/features/leather-intro-dialog/leather-intro-steps.tsx
index 29b62738bfc..48d8f80131a 100644
--- a/src/app/features/leather-intro-dialog/leather-intro-steps.tsx
+++ b/src/app/features/leather-intro-dialog/leather-intro-steps.tsx
@@ -16,7 +16,7 @@ export function LeatherIntroDialog({ children }: HasChildren) {
return (
e.preventDefault()}
onInteractOutside={e => e.preventDefault()}
className={css({ maxWidth: '500px', backgroundColor: 'accent.background-primary' })}
diff --git a/src/app/features/switch-account-drawer/components/switch-account-list-item.tsx b/src/app/features/switch-account-drawer/components/switch-account-list-item.tsx
index 761823e7bc1..384fb50567c 100644
--- a/src/app/features/switch-account-drawer/components/switch-account-list-item.tsx
+++ b/src/app/features/switch-account-drawer/components/switch-account-list-item.tsx
@@ -4,13 +4,13 @@ import { useAccountDisplayName } from '@app/common/hooks/account/use-account-nam
import { useSwitchAccount } from '@app/common/hooks/account/use-switch-account';
import { useLoading } from '@app/common/hooks/use-loading';
import { AccountTotalBalance } from '@app/components/account-total-balance';
-import { AccountListItemLayout } from '@app/components/account/account-list-item-layout';
-import { usePressable } from '@app/components/item-hover';
+import { AcccountAddresses } from '@app/components/account/account-addresses';
+import { AccountListItemLayout } from '@app/components/account/account-list-item.layout';
+import { AccountNameLayout } from '@app/components/account/account-name';
import { useNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { AccountAvatarItem } from '../../../components/account/account-avatar-item';
-import { AccountNameLayout } from '../../../components/account/account-name';
interface SwitchAccountListItemProps {
handleClose(): void;
@@ -20,16 +20,15 @@ interface SwitchAccountListItemProps {
export const SwitchAccountListItem = memo(
({ handleClose, currentAccountIndex, index }: SwitchAccountListItemProps) => {
const stacksAccounts = useStacksAccounts();
- const stacksAddress = stacksAccounts[index]?.address || '';
+ const stxAddress = stacksAccounts[index]?.address || '';
const bitcoinSigner = useNativeSegwitSigner(index);
- const bitcoinAddress = bitcoinSigner?.(0).address || '';
+ const btcAddress = bitcoinSigner?.(0).address || '';
const { isLoading, setIsLoading, setIsIdle } = useLoading(
- 'SWITCH_ACCOUNTS' + stacksAddress || bitcoinAddress
+ 'SWITCH_ACCOUNTS' + stxAddress || btcAddress
);
const { handleSwitchAccount } = useSwitchAccount(handleClose);
- const [component, bind] = usePressable(true);
- const name = useAccountDisplayName({ address: stacksAddress, index });
+ const name = useAccountDisplayName({ address: stxAddress, index });
const handleClick = async () => {
setIsLoading();
@@ -41,9 +40,8 @@ export const SwitchAccountListItem = memo(
return (
}
+ accountName={{name}}
avatar={
}
+ balanceLabel={}
+ index={index}
+ isLoading={isLoading}
+ isSelected={currentAccountIndex === index}
onSelectAccount={handleClick}
- accountName={{name}}
- balanceLabel={
-
- }
- mt="space.05"
- {...bind}
- >
- {component}
-
+ />
);
}
);
diff --git a/src/app/features/switch-account-drawer/components/switch-account-list.tsx b/src/app/features/switch-account-drawer/components/switch-account-list.tsx
index 809dccd3804..0cafce7570f 100644
--- a/src/app/features/switch-account-drawer/components/switch-account-list.tsx
+++ b/src/app/features/switch-account-drawer/components/switch-account-list.tsx
@@ -23,7 +23,7 @@ export const SwitchAccountList = memo(
style={{ paddingTop: '24px', height: '70vh' }}
totalCount={addressesNum}
itemContent={index => (
-
+
{
- const [component, bind] = usePressable(true);
const name = useAccountDisplayName(account);
const btcAddress = useNativeSegwitAccountIndexAddressIndexZero(account.index);
const accountSlug = useMemo(() => slugify(`Account ${account?.index + 1}`), [account?.index]);
return (
- // Padding required on outer element to prevent jumpy list behaviours in
- // virtualised list library
+ // Padding required on outer element to prevent jumpy virtualized list
}
accountName={
}>
{name}
@@ -65,13 +63,12 @@ const ChooseAccountItem = memo(
balanceLabel={
}
+ data-testid={`account-${accountSlug}-${account.index}`}
+ index={account.index}
isLoading={isLoading}
+ isSelected={false}
onSelectAccount={() => onSelectAccount(account.index)}
- data-testid={`account-${accountSlug}-${account.index}`}
- {...bind}
- >
- {component}
-
+ />
);
}
diff --git a/src/app/pages/receive/components/receive-item.tsx b/src/app/pages/receive/components/receive-item.tsx
index 043c75214a7..d4b79796505 100644
--- a/src/app/pages/receive/components/receive-item.tsx
+++ b/src/app/pages/receive/components/receive-item.tsx
@@ -1,9 +1,8 @@
-import { Flex, HStack, Stack, styled } from 'leather-styles/jsx';
-
import { Button } from '@app/ui/components/button/button';
-import { Flag } from '@app/ui/components/flag/flag';
import { CopyIcon } from '@app/ui/components/icons/copy-icon';
import { QrCodeIcon } from '@app/ui/components/icons/qr-code-icon';
+import { ItemInteractive } from '@app/ui/components/item/item-interactive';
+import { ItemWithButtonsLayout } from '@app/ui/components/item/item-with-buttons.layout';
import { truncateMiddle } from '@app/ui/utils/truncate-middle';
interface ReceiveItemProps {
@@ -24,23 +23,29 @@ export function ReceiveItem({
}: ReceiveItemProps) {
if (!address) return null;
return (
-
-
-
- {title}
- {truncateMiddle(address, 6)}
-
-
-
- {onClickQrCode && (
-
-
-
+ {onClickQrCode && (
+
+
+
+ )}
+ >
+ }
+ />
+
);
}
diff --git a/src/app/pages/receive/components/receive-items.tsx b/src/app/pages/receive/components/receive-items.tsx
index d1c2d674ae9..4f89ecee966 100644
--- a/src/app/pages/receive/components/receive-items.tsx
+++ b/src/app/pages/receive/components/receive-items.tsx
@@ -13,7 +13,7 @@ export function ReceiveItemList({ children, title }: ReceiveItemListProps) {
)}
-
+
{children}
>
diff --git a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/account-list-item.tsx b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/account-list-item.tsx
index 971e0aa5bb5..d59114ed9d0 100644
--- a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/account-list-item.tsx
+++ b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-drawer/account-list-item.tsx
@@ -6,10 +6,10 @@ import { BitcoinSendFormValues, StacksSendFormValues } from '@shared/models/form
import { useAccountDisplayName } from '@app/common/hooks/account/use-account-names';
import { AccountTotalBalance } from '@app/components/account-total-balance';
+import { AcccountAddresses } from '@app/components/account/account-addresses';
import { AccountAvatarItem } from '@app/components/account/account-avatar-item';
-import { AccountListItemLayout } from '@app/components/account/account-list-item-layout';
+import { AccountListItemLayout } from '@app/components/account/account-list-item.layout';
import { AccountNameLayout } from '@app/components/account/account-name';
-import { usePressable } from '@app/components/item-hover';
import { useNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
@@ -22,7 +22,6 @@ export const AccountListItem = memo(({ index, stacksAccount, onClose }: AccountL
const { setFieldValue, values, setFieldTouched } = useFormikContext<
BitcoinSendFormValues | StacksSendFormValues
>();
- const [component, bind] = usePressable(true);
const stacksAddress = stacksAccount?.address || '';
const name = useAccountDisplayName({ address: stacksAddress, index });
@@ -38,6 +37,7 @@ export const AccountListItem = memo(({ index, stacksAccount, onClose }: AccountL
return (
}
accountName={{name}}
avatar={
}
index={index}
- isActive={false}
+ isSelected={false}
isLoading={false}
- mt="space.05"
onSelectAccount={onSelectAccount}
- {...bind}
- >
- {component}
-
+ />
);
});
diff --git a/src/app/pages/swap/swap-choose-asset/components/swap-asset-item.layout.tsx b/src/app/pages/swap/swap-choose-asset/components/swap-asset-item.layout.tsx
deleted file mode 100644
index 075868fc2d8..00000000000
--- a/src/app/pages/swap/swap-choose-asset/components/swap-asset-item.layout.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Stack } from 'leather-styles/jsx';
-
-import { HasChildren } from '@app/common/has-children';
-import { Flag } from '@app/ui/components/flag/flag';
-
-export function SwapAssetItemLayout({
- children,
- icon,
- ...rest
-}: HasChildren & { icon: React.JSX.Element }) {
- return (
-
- {children}
-
- );
-}
diff --git a/src/app/pages/swap/swap-choose-asset/components/swap-asset-item.tsx b/src/app/pages/swap/swap-choose-asset/components/swap-asset-item.tsx
index 06b608c7194..f0f9e632948 100644
--- a/src/app/pages/swap/swap-choose-asset/components/swap-asset-item.tsx
+++ b/src/app/pages/swap/swap-choose-asset/components/swap-asset-item.tsx
@@ -1,19 +1,20 @@
-import { HStack, styled } from 'leather-styles/jsx';
+import { SwapSelectors } from '@tests/selectors/swap.selectors';
+import { styled } from 'leather-styles/jsx';
import { formatMoneyWithoutSymbol } from '@app/common/money/format-money';
-import { usePressable } from '@app/components/item-hover';
import { useGetFungibleTokenMetadataQuery } from '@app/query/stacks/tokens/fungible-tokens/fungible-token-metadata.query';
import { isFtAsset } from '@app/query/stacks/tokens/token-metadata.utils';
+import { ItemInteractive } from '@app/ui/components/item/item-interactive';
+import { ItemLayout } from '@app/ui/components/item/item.layout';
import { useAlexSdkBalanceAsFiat } from '../../hooks/use-alex-sdk-fiat-price';
import { SwapAsset } from '../../hooks/use-swap-form';
-import { SwapAssetItemLayout } from './swap-asset-item.layout';
interface SwapAssetItemProps {
asset: SwapAsset;
+ onClick(): void;
}
-export function SwapAssetItem({ asset }: SwapAssetItemProps) {
- const [component, bind] = usePressable(true);
+export function SwapAssetItem({ asset, onClick }: SwapAssetItemProps) {
const balanceAsFiat = useAlexSdkBalanceAsFiat(asset.balance, asset.price);
const { data: ftMetadata } = useGetFungibleTokenMetadataQuery(asset.principal);
@@ -21,21 +22,14 @@ export function SwapAssetItem({ asset }: SwapAssetItemProps) {
const displayName = asset.displayName ?? ftMetadataName;
return (
- }
- {...bind}
- >
-
- {displayName}
- {formatMoneyWithoutSymbol(asset.balance)}
-
-
- {asset.name}
-
- {balanceAsFiat}
-
-
- {component}
-
+
+ }
+ titleLeft={displayName}
+ captionLeft={asset.name}
+ titleRight={formatMoneyWithoutSymbol(asset.balance)}
+ captionRight={balanceAsFiat}
+ />
+
);
}
diff --git a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx b/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx
index e7feee61700..eb40bfdcbf4 100644
--- a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx
+++ b/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.layout.tsx
@@ -2,7 +2,7 @@ import { Stack, StackProps } from 'leather-styles/jsx';
export function SwapAssetListLayout({ children }: StackProps) {
return (
-
+
{children}
);
diff --git a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx b/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx
index bc2875175ff..32c2028fd89 100644
--- a/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx
+++ b/src/app/pages/swap/swap-choose-asset/components/swap-asset-list.tsx
@@ -1,9 +1,7 @@
import { useNavigate } from 'react-router-dom';
-import { SwapSelectors } from '@tests/selectors/swap.selectors';
import BigNumber from 'bignumber.js';
import { useFormikContext } from 'formik';
-import { styled } from 'leather-styles/jsx';
import { createMoney } from '@shared/models/money.model';
import { isUndefined } from '@shared/utils';
@@ -68,15 +66,11 @@ export function SwapAssetList({ assets }: SwapAssetList) {
return (
{selectableAssets.map(asset => (
- onChooseAsset(asset)}
- textAlign="left"
- type="button"
- >
-
-
+ />
))}
);
diff --git a/src/app/ui/components/dowpdown-menu/dropdown-menu.tsx b/src/app/ui/components/dowpdown-menu/dropdown-menu.tsx
index 169d56ed1c7..38d0bbf67ea 100644
--- a/src/app/ui/components/dowpdown-menu/dropdown-menu.tsx
+++ b/src/app/ui/components/dowpdown-menu/dropdown-menu.tsx
@@ -3,6 +3,8 @@ import { ReactNode, forwardRef } from 'react';
import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';
import { css } from 'leather-styles/css';
+import { itemBaseStyles, itemInteractiveStyles } from '../item/item-interactive';
+
export interface DropdownMenuItem {
iconLeft?: ReactNode;
iconRight?: ReactNode;
@@ -67,20 +69,12 @@ const Label: typeof RadixDropdownMenu.Label = forwardRef((props, ref) => (
));
-const dropdownMenuItemStyles = css({
- bg: 'accent.background-primary',
- color: 'accent.text-primary',
- height: 'auto',
- outline: 'none',
- userSelect: 'none',
- p: 'space.03',
-
- '&[data-highlighted]': {
- bg: 'accent.component-background-hover',
- },
-});
const Item: typeof RadixDropdownMenu.Item = forwardRef((props, ref) => (
-
+
));
const dropdownMenuSeparatorStyles = css({
diff --git a/src/app/ui/components/dynamic-color-circle.tsx b/src/app/ui/components/dynamic-color-circle.tsx
index e0d62e71db4..2b4d0f0e495 100644
--- a/src/app/ui/components/dynamic-color-circle.tsx
+++ b/src/app/ui/components/dynamic-color-circle.tsx
@@ -6,7 +6,7 @@ interface DynamicColorCircleProps extends CircleProps {
}
export function DynamicColorCircle({
children,
- sizeParam = '36',
+ sizeParam = '40',
value,
...props
}: DynamicColorCircleProps) {
diff --git a/src/app/ui/components/item/item-interactive.stories.tsx b/src/app/ui/components/item/item-interactive.stories.tsx
new file mode 100644
index 00000000000..6bcc9274e00
--- /dev/null
+++ b/src/app/ui/components/item/item-interactive.stories.tsx
@@ -0,0 +1,72 @@
+import { Meta, StoryObj } from '@storybook/react';
+
+import { Button } from '../button/button';
+import { BtcIcon } from '../icons/btc-icon';
+import { CopyIcon } from '../icons/copy-icon';
+import { QrCodeIcon } from '../icons/qr-code-icon';
+import { ItemInteractive as Component } from './item-interactive';
+import { ItemWithButtonsLayout } from './item-with-buttons.layout';
+import { ItemLayout } from './item.layout';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Item Interactive',
+ parameters: {
+ controls: { include: [] },
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const ItemInteractive: Story = {
+ args: {
+ onClick: () => {},
+ children: (
+ }
+ titleLeft="Label"
+ captionLeft="Caption"
+ titleRight="1,000.00 ABC"
+ captionRight="$1,000.00"
+ />
+ ),
+ },
+};
+
+export const Disabled: Story = {
+ args: {
+ disabled: true,
+ onClick: () => {},
+ children: (
+ }
+ titleLeft="Label"
+ captionLeft="Caption"
+ titleRight="1,000.00 ABC"
+ captionRight="$1,000.00"
+ />
+ ),
+ },
+};
+
+export const WithButtons: Story = {
+ args: {
+ children: (
+ }
+ title="Label"
+ caption="Caption"
+ buttons={
+ <>
+ {}
+ {}
+ >
+ }
+ />
+ ),
+ },
+};
diff --git a/src/app/ui/components/item/item-interactive.tsx b/src/app/ui/components/item/item-interactive.tsx
new file mode 100644
index 00000000000..9a4667b681d
--- /dev/null
+++ b/src/app/ui/components/item/item-interactive.tsx
@@ -0,0 +1,100 @@
+import { forwardRef } from 'react';
+
+import { type RecipeVariantProps, css, cva } from 'leather-styles/css';
+import { Box, BoxProps } from 'leather-styles/jsx';
+
+import { isDefined } from '@shared/utils';
+
+const basePseudoOutlineProps = {
+ content: '""',
+ rounded: 'xs',
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ bottom: 0,
+ right: 0,
+};
+
+const focusVisibleStyles = {
+ _before: {
+ ...basePseudoOutlineProps,
+ border: '2px solid',
+ borderColor: 'lightModeBlue.500',
+ },
+ _focusWithin: { outline: 'none' },
+};
+
+export const itemBaseStyles = css.raw({
+ bg: 'accent.background-primary',
+ color: 'accent.text-primary',
+ cursor: 'default',
+ display: 'flex',
+ height: 'auto',
+ outline: 'none',
+ p: 'space.03',
+ position: 'relative',
+ rounded: 'xs',
+ userSelect: 'none',
+ width: '100%',
+});
+
+export const itemInteractiveStyles = css.raw({
+ cursor: 'pointer',
+
+ '&:is(:active)': {
+ bg: 'accent.component-background-pressed',
+ },
+ '&:is(:focus-visible)': {
+ ...focusVisibleStyles,
+ },
+ '&:is(:disabled, [data-disabled])': {
+ _active: { bg: 'unset' },
+ _focus: { border: 'unset' },
+ _hover: { bg: 'unset' },
+ color: 'accent.non-interactive',
+ cursor: 'not-allowed',
+ },
+ '&:is(:hover, [data-highlighted])': {
+ _before: { borderColor: 'transparent' },
+ bg: 'accent.component-background-hover',
+ },
+});
+
+const itemRecipe = cva({
+ base: itemBaseStyles,
+ variants: {
+ disabled: { true: {} },
+ interactive: {
+ true: itemInteractiveStyles,
+ },
+ },
+});
+
+export const itemCaptionStyles = css({
+ _groupDisabled: { color: 'accent.non-interactive' },
+ color: 'accent.text-subdued',
+});
+
+export const itemChevronStyles = css({
+ _groupDisabled: { color: 'accent.non-interactive' },
+ color: 'accent.action-primary-default',
+});
+
+type ItemVariantProps = RecipeVariantProps;
+
+export const ItemInteractive = forwardRef(
+ (props, ref) => {
+ const { disabled, onClick, ...rest } = props;
+ const isInteractive = isDefined(onClick);
+ return (
+
+ );
+ }
+);
diff --git a/src/app/ui/components/item/item-with-buttons.layout.tsx b/src/app/ui/components/item/item-with-buttons.layout.tsx
new file mode 100644
index 00000000000..af00349f3f8
--- /dev/null
+++ b/src/app/ui/components/item/item-with-buttons.layout.tsx
@@ -0,0 +1,44 @@
+import { ReactNode } from 'react';
+
+import { Flex, HStack, Stack, styled } from 'leather-styles/jsx';
+
+import { Flag } from '../flag/flag';
+import { itemCaptionStyles } from './item-interactive';
+
+interface ItemWithButtonsLayoutProps {
+ buttons: ReactNode;
+ caption: string;
+ flagImg: ReactNode;
+ title: string;
+}
+export function ItemWithButtonsLayout({
+ buttons,
+ caption,
+ flagImg,
+ title,
+}: ItemWithButtonsLayoutProps) {
+ return (
+
+
+
+
+ {title}
+
+
+ {caption}
+
+
+
+ {buttons}
+
+
+
+ );
+}
diff --git a/src/app/ui/components/item/item.layout.tsx b/src/app/ui/components/item/item.layout.tsx
new file mode 100644
index 00000000000..da1dae0d8e2
--- /dev/null
+++ b/src/app/ui/components/item/item.layout.tsx
@@ -0,0 +1,80 @@
+import { ReactNode, isValidElement } from 'react';
+
+import { Flex, HStack, Stack, styled } from 'leather-styles/jsx';
+
+import { Flag } from '../flag/flag';
+import { CheckmarkIcon } from '../icons/checkmark-icon';
+import { ChevronUpIcon } from '../icons/chevron-up-icon';
+import { itemCaptionStyles, itemChevronStyles } from './item-interactive';
+
+interface ItemLayoutProps {
+ captionLeft: ReactNode;
+ captionRight?: ReactNode;
+ flagImg: ReactNode;
+ isDisabled?: boolean;
+ isSelected?: boolean;
+ showChevron?: boolean;
+ titleLeft: ReactNode;
+ titleRight: ReactNode;
+}
+export function ItemLayout({
+ captionLeft,
+ captionRight,
+ flagImg,
+ isSelected,
+ showChevron,
+ titleLeft,
+ titleRight,
+}: ItemLayoutProps) {
+ return (
+
+
+
+
+ {isValidElement(titleLeft) ? (
+ titleLeft
+ ) : (
+
+ {titleLeft}
+
+ )}
+ {isSelected && }
+
+ {isValidElement(captionLeft) ? (
+ captionLeft
+ ) : (
+
+ {captionLeft}
+
+ )}
+
+
+
+ {isValidElement(titleRight) ? (
+ titleRight
+ ) : (
+
+ {titleRight}
+
+ )}
+ {isValidElement(captionRight) ? (
+ captionRight
+ ) : (
+
+ {captionRight}
+
+ )}
+
+ {showChevron && }
+
+
+
+ );
+}
diff --git a/src/app/ui/components/item/item.stories.tsx b/src/app/ui/components/item/item.stories.tsx
new file mode 100644
index 00000000000..7a118342b18
--- /dev/null
+++ b/src/app/ui/components/item/item.stories.tsx
@@ -0,0 +1,25 @@
+import { Meta, StoryObj } from '@storybook/react';
+import { Box, Circle } from 'leather-styles/jsx';
+
+import { ItemLayout as Component } from './item.layout';
+
+const meta: Meta = {
+ component: Component,
+ tags: ['autodocs'],
+ title: 'Layout/Item',
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Item: Story = {
+ render: () => (
+ }
+ titleLeft={}
+ captionLeft={}
+ titleRight={}
+ captionRight={}
+ />
+ ),
+};
diff --git a/src/app/ui/components/select/select.tsx b/src/app/ui/components/select/select.tsx
index 9953bdce076..166fd0b70e0 100644
--- a/src/app/ui/components/select/select.tsx
+++ b/src/app/ui/components/select/select.tsx
@@ -3,6 +3,8 @@ import { ReactNode, forwardRef } from 'react';
import * as RadixSelect from '@radix-ui/react-select';
import { css } from 'leather-styles/css';
+import { itemBaseStyles, itemInteractiveStyles } from '../item/item-interactive';
+
export interface SelectItem {
iconLeft?: ReactNode;
iconRight?: ReactNode;
@@ -79,20 +81,8 @@ const Label: typeof RadixSelect.Label = forwardRef((props, ref) => (
));
-const selectItemStyles = css({
- bg: 'accent.background-primary',
- color: 'accent.text-primary',
- height: 'auto',
- outline: 'none',
- userSelect: 'none',
- p: 'space.03',
-
- '&[data-highlighted]': {
- bg: 'accent.component-background-hover',
- },
-});
const Item: typeof RadixSelect.Item = forwardRef((props, ref) => (
-
+
));
const ItemText = RadixSelect.ItemText;
diff --git a/src/app/ui/components/tooltip/basic-tooltip.tsx b/src/app/ui/components/tooltip/basic-tooltip.tsx
index e10e2d61616..56fcead792f 100644
--- a/src/app/ui/components/tooltip/basic-tooltip.tsx
+++ b/src/app/ui/components/tooltip/basic-tooltip.tsx
@@ -11,7 +11,6 @@ interface BasicTooltipProps {
side?: RadixTooltip.TooltipContentProps['side'];
asChild?: boolean;
}
-
export function BasicTooltip({ children, label, disabled, side, asChild }: BasicTooltipProps) {
const isDisabled = !label || disabled;
return (
diff --git a/src/app/ui/components/typography/caption.tsx b/src/app/ui/components/typography/caption.tsx
index 96eb6c55b1b..d87df4d218e 100644
--- a/src/app/ui/components/typography/caption.tsx
+++ b/src/app/ui/components/typography/caption.tsx
@@ -1,9 +1,17 @@
import { forwardRef } from 'react';
-import { BoxProps, styled } from 'leather-styles/jsx';
+import { HTMLStyledProps, styled } from 'leather-styles/jsx';
-export const Caption = forwardRef(({ children, ...props }, ref) => (
-
- {children}
-
-));
+export const Caption = forwardRef>(
+ ({ children, ...props }, ref) => (
+
+ {children}
+
+ )
+);
diff --git a/src/app/ui/components/typography/title.tsx b/src/app/ui/components/typography/title.tsx
index 0129f184d97..c8eaac73eec 100644
--- a/src/app/ui/components/typography/title.tsx
+++ b/src/app/ui/components/typography/title.tsx
@@ -1,15 +1,18 @@
import { forwardRef } from 'react';
-import { BoxProps, styled } from 'leather-styles/jsx';
+import { HTMLStyledProps, styled } from 'leather-styles/jsx';
-export const Title = forwardRef(({ children, ...props }, ref) => (
-
- {children}
-
-));
+export const Title = forwardRef>(
+ ({ children, ...props }, ref) => (
+
+ {children}
+
+ )
+);