diff --git a/packages/components/src/components/Collapsible/Collapsible.tsx b/packages/components/src/components/Collapsible/Collapsible.tsx
index 55848b3aa7..54beec551d 100644
--- a/packages/components/src/components/Collapsible/Collapsible.tsx
+++ b/packages/components/src/components/Collapsible/Collapsible.tsx
@@ -38,7 +38,9 @@ export const Collapsible = ({
gap,
}}
>
- {children}
+
+ {children}
+
);
};
diff --git a/packages/components/src/components/Collapsible/CollapsibleContent.tsx b/packages/components/src/components/Collapsible/CollapsibleContent.tsx
index a0cca332ab..e0ead87c20 100644
--- a/packages/components/src/components/Collapsible/CollapsibleContent.tsx
+++ b/packages/components/src/components/Collapsible/CollapsibleContent.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from 'react';
+import { HTMLProps, ReactNode } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import styled, { CSSProperties } from 'styled-components';
@@ -13,7 +13,7 @@ const Container = styled(motion.div)<{ $overflow?: CSSProperties['overflow'] }>`
overflow: ${({ $overflow = 'hidden' }) => $overflow};
`;
-type CollapsibleContentProps = {
+type CollapsibleContentProps = Pick, 'onClick'> & {
children: ReactNode;
'data-testid'?: string;
onAnimationComplete?: (isOpen: boolean) => void;
@@ -25,6 +25,7 @@ export const CollapsibleContent = ({
onAnimationComplete,
'data-testid': dataTestId,
overflow,
+ onClick,
}: CollapsibleContentProps) => {
const { isOpen, contentId, gap } = useCollapsible();
@@ -47,6 +48,7 @@ export const CollapsibleContent = ({
aria-expanded={isOpen}
id={contentId}
$overflow={overflow}
+ onClick={onClick}
>
{children}
diff --git a/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFees.tsx b/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFees.tsx
index b9ad96cc6d..bcc2ca2932 100644
--- a/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFees.tsx
+++ b/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFees.tsx
@@ -19,8 +19,9 @@ export type CollapsibleFeesProps = {
networkSymbol: NetworkSymbol;
networkType: NetworkType;
rbfForm?: boolean;
+ isOpen?: boolean;
} & Pick &
- Omit;
+ Omit;
export function CollapsibleFees({
label,
@@ -31,7 +32,7 @@ export function CollapsibleFees({
changeFeeLevel,
rbfForm,
headerTypographyStyle = 'body',
- isHeaderRowLayout,
+ isOpen,
}: CollapsibleFeesProps) {
const selectedFee = useWatch({
name: 'selectedFee',
@@ -68,17 +69,17 @@ export function CollapsibleFees({
composedLevels,
}}
>
-
+
{supportsAdjustableFees && (
-
+ ev.stopPropagation()}>
{!isCustomFee && }
diff --git a/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFeesHeader.tsx b/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFeesHeader.tsx
index 64078401e0..b2ef6e9310 100644
--- a/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFeesHeader.tsx
+++ b/packages/suite/src/components/wallet/Fees/CollapsibleFees/CollapsibleFeesHeader.tsx
@@ -4,7 +4,7 @@ import { useTheme } from 'styled-components';
import { Translation, TranslationKey } from '@suite/intl';
import { Icon, Link, Row, Text, Tooltip } from '@trezor/components';
-import { TypographyStyle, spacings } from '@trezor/theme';
+import { TypographyStyle } from '@trezor/theme';
import { HELP_CENTER_TRANSACTION_FEES_URL } from '@trezor/urls';
import { useFeesContext } from '../context/FeesContext';
@@ -43,7 +43,7 @@ export function CollapsibleFeesHeader({ label, typographyStyle }: CollapsibleFee
}, [networkType]);
return (
-
+
;
+ isOpen?: boolean;
};
export const CollapsibleFeesHeaderContent = ({
label,
headerTypographyStyle = 'body',
supportsAdjustableFees,
- isHeaderRowLayout,
txMaxFee,
+ isOpen,
}: CollapsibleFeesHeaderContentProps) => {
const content = (
-
+
@@ -35,20 +39,5 @@ export const CollapsibleFeesHeaderContent = ({
);
- return (
-
- {isHeaderRowLayout ? (
-
- {content}
-
- ) : (
- content
- )}
-
- );
+ return isOpen !== undefined ? content : {content};
};
diff --git a/packages/suite/src/components/wallet/Fees/Fees.tsx b/packages/suite/src/components/wallet/Fees/Fees.tsx
index 108baf6193..ad55941b31 100644
--- a/packages/suite/src/components/wallet/Fees/Fees.tsx
+++ b/packages/suite/src/components/wallet/Fees/Fees.tsx
@@ -9,10 +9,15 @@ import { FieldErrorBanner } from './FieldErrorBanner';
export type FeesProps = {
account: Pick;
- isHeaderRowLayout?: boolean;
} & Pick<
CollapsibleFeesProps,
- 'label' | 'rbfForm' | 'feeInfo' | 'changeFeeLevel' | 'composedLevels' | 'headerTypographyStyle'
+ | 'label'
+ | 'rbfForm'
+ | 'feeInfo'
+ | 'changeFeeLevel'
+ | 'composedLevels'
+ | 'headerTypographyStyle'
+ | 'isOpen'
>;
export const Fees = ({
@@ -23,7 +28,7 @@ export const Fees = ({
label,
rbfForm,
headerTypographyStyle,
- isHeaderRowLayout,
+ isOpen,
}: FeesProps) => {
useFetchFees({ networkSymbol });
@@ -38,7 +43,7 @@ export const Fees = ({
changeFeeLevel={changeFeeLevel}
rbfForm={rbfForm}
headerTypographyStyle={headerTypographyStyle}
- isHeaderRowLayout={isHeaderRowLayout}
+ isOpen={isOpen}
/>
diff --git a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingBuyFormInputs.tsx b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingBuyFormInputs.tsx
index 3c345592a9..4a96fcc50c 100644
--- a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingBuyFormInputs.tsx
+++ b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingBuyFormInputs.tsx
@@ -10,10 +10,9 @@ import {
tradingActions,
} from '@suite-common/trading';
import { TokenAddress } from '@suite-common/wallet-types';
-import { Card, Column, Divider, Row } from '@trezor/components';
+import { Column, Row } from '@trezor/components';
import { hasBitcoinOnlyFirmware } from '@trezor/device-utils/src/firmwareUtils';
import { useCurrentRef } from '@trezor/react-utils';
-import { spacings } from '@trezor/theme';
import { useDispatch, useSelector } from 'src/hooks/suite';
import { useTradingFormContext } from 'src/hooks/wallet/trading/form/useTradingCommonForm';
@@ -22,13 +21,15 @@ import { TradingFormInputCountry } from 'src/views/wallet/trading/common/Trading
import { TradingFormInputFiatCrypto } from 'src/views/wallet/trading/common/TradingForm/TradingFormInput/TradingFormInputFiatCrypto/TradingFormInputFiatCrypto';
import { TradingFormInputPaymentMethod } from 'src/views/wallet/trading/common/TradingForm/TradingFormInput/TradingFormInputPaymentMethod';
+import { TradingFormCard } from './TradingFormCard';
import { TradingFormFeesDisclamer } from './TradingFormFeeDisclamer';
-import { TradingReceiveAddress } from '../TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress';
+import { TradingFormSection } from './TradingFormSection';
import { TradingSelectedOfferProvider } from '../TradingSelectedOffer/TradingSelectedOfferProvider';
import {
TradingFormInputBuyAsset,
TradingFormInputBuyAssetProps,
} from './TradingFormInput/TradingFormInputBuyAsset/TradingFormInputBuyAsset';
+import { TradingReceiveAddress } from '../TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress';
export const TradingBuyFormInputs = () => {
const context = useTradingFormContext();
@@ -61,76 +62,56 @@ export const TradingBuyFormInputs = () => {
const buySupportedCryptoIds = useSelector(selectTradingBuySupportedCryptoIds);
return (
-
-
-
-
-
-
-
- {amountInCrypto && (
-
-
-
- )}
-
-
-
+
+
+
+
+
+ {amountInCrypto && (
+
+
+
+ )}
- {cryptoSelect && !isLoading && }
-
-
+
+
+ {cryptoSelect && !isLoading && }
+
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
-
-
+
+
);
};
diff --git a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingExchangeFormInputs.tsx b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingExchangeFormInputs.tsx
index 1ca2344f16..768cd1325f 100644
--- a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingExchangeFormInputs.tsx
+++ b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingExchangeFormInputs.tsx
@@ -15,31 +15,32 @@ import {
} from '@suite-common/trading';
import { TokenAddress } from '@suite-common/wallet-types';
import { convertAmountSubunitsToUnits } from '@suite-common/wallet-utils';
-import { Card, Column, Divider, FractionButton, Row } from '@trezor/components';
+import { Column, FractionButton, Row } from '@trezor/components';
import { useCurrentRef } from '@trezor/react-utils';
-import { spacings } from '@trezor/theme';
-import { Fees } from 'src/components/wallet/Fees/Fees';
import { useDispatch, useSelector } from 'src/hooks/suite';
import { useTradingAssetDecimals } from 'src/hooks/wallet/trading/form/common/useTradingAssetDecimals';
import { useTradingFormContext } from 'src/hooks/wallet/trading/form/useTradingCommonForm';
import { TradingBalance } from 'src/views/wallet/trading/common/TradingBalance';
import { TradingFormInputFiatCrypto } from 'src/views/wallet/trading/common/TradingForm/TradingFormInput/TradingFormInputFiatCrypto/TradingFormInputFiatCrypto';
+import { TradingFormCard } from './TradingFormCard';
import { TradingFormFeesDisclamer } from './TradingFormFeeDisclamer';
+import { TradingFormFees } from './TradingFormFees';
import { AssetPickerInputBalance } from './TradingFormInput/TradingFormInputAssetPicker';
import {
TradingFormInputBuyAsset,
TradingFormInputBuyAssetProps,
} from './TradingFormInput/TradingFormInputBuyAsset/TradingFormInputBuyAsset';
-import { TradingNetworkReserveBanner } from './TradingNetworkReserveBanner';
-import { generateFractionButtons } from './tradingFormInputsUtils';
-import { TradingReceiveAddress } from '../TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress';
-import { TradingSelectedOfferProvider } from '../TradingSelectedOffer/TradingSelectedOfferProvider';
import {
TradingFormInputSellAsset,
TradingFormInputSellAssetProps,
} from './TradingFormInput/TradingFormInputSellAsset/TradingFormInputSellAsset';
+import { TradingFormSection } from './TradingFormSection';
+import { TradingNetworkReserveBanner } from './TradingNetworkReserveBanner';
+import { generateFractionButtons } from './tradingFormInputsUtils';
+import { TradingReceiveAddress } from '../TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress';
+import { TradingSelectedOfferProvider } from '../TradingSelectedOffer/TradingSelectedOfferProvider';
export const TradingExchangeFormInputs = () => {
const context = useTradingFormContext();
@@ -115,8 +116,8 @@ export const TradingExchangeFormInputs = () => {
const exchangeSellSupportedCryptoIds = useSelector(selectTradingExchangeSellCryptoIds);
return (
-
-
+
+
{
dataTestId="@trading/form/select-crypto-for-sell"
onAssetSelect={handleSellAssetSelect}
/>
-
+
{
/>
{amountInCrypto && (
-
+
{generateFractionButtons(helpers).map(button => (
{
onAssetSelect={handleReceiveAssetSelect}
dataTestId="@trading/form/select-crypto-for-buy"
/>
-
+
{receiveCryptoSelect && !isLoading && }
-
-
-
-
-
-
+
-
-
+
+
);
};
diff --git a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormCard.tsx b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormCard.tsx
new file mode 100644
index 0000000000..feff6a762f
--- /dev/null
+++ b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormCard.tsx
@@ -0,0 +1,7 @@
+import { Card, Column } from '@trezor/components';
+
+export const TradingFormCard = ({ children }: { children: React.ReactNode }) => (
+
+ {children}
+
+);
diff --git a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormFees.tsx b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormFees.tsx
new file mode 100644
index 0000000000..1b4bb7f7fe
--- /dev/null
+++ b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormFees.tsx
@@ -0,0 +1,42 @@
+import { useState } from 'react';
+
+import { GhostContainer } from '@trezor/components';
+
+import { Fees, FeesProps } from 'src/components/wallet/Fees/Fees';
+
+export type TradingFormFeesProps = Pick<
+ FeesProps,
+ 'feeInfo' | 'account' | 'composedLevels' | 'changeFeeLevel'
+>;
+
+export const TradingFormFees = ({
+ feeInfo,
+ account,
+ composedLevels,
+ changeFeeLevel,
+}: TradingFormFeesProps) => {
+ const [isOpen, setIsOpen] = useState(false);
+
+ return (
+ {
+ setIsOpen(!isOpen);
+ if (document.activeElement instanceof HTMLElement) {
+ document.activeElement.blur();
+ }
+ }}
+ cursor="pointer"
+ isActive={isOpen}
+ >
+
+
+ );
+};
diff --git a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormSection.tsx b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormSection.tsx
new file mode 100644
index 0000000000..a3f8c7571d
--- /dev/null
+++ b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingFormSection.tsx
@@ -0,0 +1,7 @@
+import { Column } from '@trezor/components';
+
+export const TradingFormSection = ({ children }: { children: React.ReactNode }) => (
+
+ {children}
+
+);
diff --git a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingSellFormInputs.tsx b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingSellFormInputs.tsx
index a6576fc8b2..fee5e0c34d 100644
--- a/packages/suite/src/views/wallet/trading/common/TradingForm/TradingSellFormInputs.tsx
+++ b/packages/suite/src/views/wallet/trading/common/TradingForm/TradingSellFormInputs.tsx
@@ -11,11 +11,9 @@ import {
} from '@suite-common/trading';
import { TokenAddress } from '@suite-common/wallet-types';
import { convertAmountSubunitsToUnits } from '@suite-common/wallet-utils';
-import { Card, Column, Divider, FractionButton, Row } from '@trezor/components';
+import { Column, FractionButton, Row } from '@trezor/components';
import { useCurrentRef } from '@trezor/react-utils';
-import { spacings } from '@trezor/theme';
-import { Fees } from 'src/components/wallet/Fees/Fees';
import { useSelector } from 'src/hooks/suite';
import { useTradingAssetDecimals } from 'src/hooks/wallet/trading/form/common/useTradingAssetDecimals';
import { useTradingFormContext } from 'src/hooks/wallet/trading/form/useTradingCommonForm';
@@ -24,15 +22,18 @@ import { TradingFormInputCountry } from 'src/views/wallet/trading/common/Trading
import { TradingFormInputFiatCrypto } from 'src/views/wallet/trading/common/TradingForm/TradingFormInput/TradingFormInputFiatCrypto/TradingFormInputFiatCrypto';
import { TradingFormInputPaymentMethod } from 'src/views/wallet/trading/common/TradingForm/TradingFormInput/TradingFormInputPaymentMethod';
+import { TradingFormCard } from './TradingFormCard';
import { TradingFormFeesDisclamer } from './TradingFormFeeDisclamer';
+import { TradingFormFees } from './TradingFormFees';
import { AssetPickerInputBalance } from './TradingFormInput/TradingFormInputAssetPicker';
-import { TradingNetworkReserveBanner } from './TradingNetworkReserveBanner';
-import { generateFractionButtons } from './tradingFormInputsUtils';
-import { TradingSelectedOfferProvider } from '../TradingSelectedOffer/TradingSelectedOfferProvider';
import {
TradingFormInputSellAsset,
TradingFormInputSellAssetProps,
} from './TradingFormInput/TradingFormInputSellAsset/TradingFormInputSellAsset';
+import { TradingFormSection } from './TradingFormSection';
+import { TradingNetworkReserveBanner } from './TradingNetworkReserveBanner';
+import { generateFractionButtons } from './tradingFormInputsUtils';
+import { TradingSelectedOfferProvider } from '../TradingSelectedOffer/TradingSelectedOfferProvider';
export const TradingSellFormInputs = () => {
const context = useTradingFormContext();
@@ -78,8 +79,8 @@ export const TradingSellFormInputs = () => {
const sellSupportedCryptoIds = useSelector(selectTradingSellSupportedCryptoIds);
return (
-
-
+
+
{
dataTestId="@trading/form/select-crypto-for-sell"
onAssetSelect={handleSellAssetSelect}
/>
-
+
{
/>
{amountInCrypto && (
-
+
{generateFractionButtons(helpers).map(button => (
))}
@@ -117,32 +118,27 @@ export const TradingSellFormInputs = () => {
)}
-
{showReserveBanner && (
)}
-
-
-
+
-
-
+
-
+
-
-
+
-
-
+
+
);
};
diff --git a/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress.tsx b/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress.tsx
index b5374eb414..649bd460ed 100644
--- a/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress.tsx
+++ b/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingReceiveAddress/TradingReceiveAddress.tsx
@@ -1,8 +1,7 @@
import { ReactNode } from 'react';
import { Translation } from '@suite/intl';
-import { Box, Column, Divider, Icon, Row, Text } from '@trezor/components';
-import { spacings } from '@trezor/theme';
+import { Column, GhostContainer, Icon, Row, Text } from '@trezor/components';
import { AccountLabeling, Address } from 'src/components/suite';
@@ -15,7 +14,7 @@ interface TradingReceiveAddressEmptyProps {
}
export const TradingReceiveAddressEmpty = ({ title, text }: TradingReceiveAddressEmptyProps) => (
-
+
{title}
{text}
@@ -34,17 +33,18 @@ export const TradingReceiveAddress = () => {
};
return (
-
-
-
+
@@ -60,12 +60,17 @@ export const TradingReceiveAddress = () => {
{selectedAccountOption?.account && receiveAddress ? (
<>
-
+
+
+
{
{receiveAddress ? (
) : (
@@ -94,6 +99,6 @@ export const TradingReceiveAddress = () => {
-
+
);
};
diff --git a/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingSelectedOfferProvider.tsx b/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingSelectedOfferProvider.tsx
index 0a937935e3..c1474b499d 100644
--- a/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingSelectedOfferProvider.tsx
+++ b/packages/suite/src/views/wallet/trading/common/TradingSelectedOffer/TradingSelectedOfferProvider.tsx
@@ -1,8 +1,7 @@
import { ReactNode } from 'react';
import { Translation } from '@suite/intl';
-import { Column, Divider, Icon, Row, SkeletonRectangle, Text } from '@trezor/components';
-import { spacings } from '@trezor/theme';
+import { Column, GhostContainer, Icon, Row, SkeletonRectangle, Text } from '@trezor/components';
import { useTradingFormContext } from 'src/hooks/wallet/trading/form/useTradingCommonForm';
import {
@@ -20,7 +19,7 @@ interface TradingReceiveAddressEmptyProps {
}
export const TradingReceiveAddressEmpty = ({ title, text }: TradingReceiveAddressEmptyProps) => (
-
+
{title}
{text}
@@ -49,15 +48,13 @@ export const TradingSelectedOfferProvider = () => {
}
return (
-
-
-
+
+
@@ -66,17 +63,17 @@ export const TradingSelectedOfferProvider = () => {
) : (
<>
-
+
-
+
>
)}
-
+
);
};
diff --git a/suite/e2e/support/pageObjects/feeSection.ts b/suite/e2e/support/pageObjects/feeSection.ts
index d8f2b5c171..e6b33dd8c4 100644
--- a/suite/e2e/support/pageObjects/feeSection.ts
+++ b/suite/e2e/support/pageObjects/feeSection.ts
@@ -17,6 +17,7 @@ export class FeeSection {
this.page.getByTestId(`@fee-card/${feeType}-fiat-amount`);
readonly rateOnCard = (feeType: FeeTypes) => this.page.getByTestId(`@fee-card/${feeType}-rate`);
readonly collapsibleFeesToggle: Locator;
+ readonly collapsibleFees: Locator;
readonly maxFeeLoading: Locator;
readonly customInput: Locator;
readonly maxFee: Locator;
@@ -31,6 +32,7 @@ export class FeeSection {
constructor(private readonly page: Page) {
this.collapsibleFeesToggle = this.page.getByTestId('@wallet/fees/collapsible-fees-toggle');
+ this.collapsibleFees = this.page.getByTestId('@wallet/fees/collapsible-fees');
this.maxFeeLoading = this.page.getByTestId('@trading/quote/maximum-fee-amount-loading');
this.customInput = this.page.getByTestId('feePerUnit');
this.maxFee = this.page.getByTestId('@trading/quote/maximum-fee-amount');
@@ -74,7 +76,7 @@ export class FeeSection {
@step()
async openCollapsibleFees() {
- const isExpanded = await this.collapsibleFeesToggle.getAttribute('aria-expanded');
+ const isExpanded = await this.collapsibleFees.getAttribute('aria-expanded');
if (isExpanded === 'true') {
return;
@@ -93,9 +95,9 @@ export class FeeSection {
);
}
- await expect(this.collapsibleFeesToggle).toHaveAttribute('aria-expanded', 'false');
+ await expect(this.collapsibleFees).toHaveAttribute('aria-expanded', 'false');
await this.collapsibleFeesToggle.click();
- await expect(this.collapsibleFeesToggle).toHaveAttribute('aria-expanded', 'true');
+ await expect(this.collapsibleFees).toHaveAttribute('aria-expanded', 'true');
}
@step()