@@ -223,6 +223,7 @@ const TokenWidget: FC<TokenWidgetProps> = ({
223223 buy : { fromToken ?: Token ; toToken ?: Token }
224224 sell : { fromToken ?: Token ; toToken ?: Token }
225225 } > ( { buy : { } , sell : { } } )
226+ const prevActiveTabRef = useRef < 'buy' | 'sell' > ( activeTab )
226227 const autoSelectedFromTokenRef = useRef ( false )
227228 const tabRecipientRef = useRef < {
228229 buy : { override ?: string ; custom ?: string }
@@ -398,6 +399,9 @@ const TokenWidget: FC<TokenWidgetProps> = ({
398399 tradeTypeRef . current = tradeType
399400
400401 useEffect ( ( ) => {
402+ if ( prevActiveTabRef . current !== activeTab ) {
403+ return
404+ }
401405 tabTokenStateRef . current [ activeTab ] = {
402406 fromToken,
403407 toToken
@@ -970,6 +974,153 @@ const TokenWidget: FC<TokenWidgetProps> = ({
970974 walletsLoading
971975 ] )
972976
977+ const handleTabChange = useCallback (
978+ ( nextTab : 'buy' | 'sell' , updateActiveTab : boolean ) => {
979+ const prevTab = prevActiveTabRef . current ?? activeTab
980+
981+ if ( nextTab === prevTab && ! updateActiveTab ) {
982+ return
983+ }
984+
985+ setAllowUnsupportedOrigin ( nextTab === 'buy' )
986+ setAllowUnsupportedRecipient ( nextTab === 'sell' )
987+
988+ if ( nextTab !== prevTab ) {
989+ const storedNextState = tabTokenStateRef . current [ nextTab ] ?? { }
990+ const storedNextRecipient = tabRecipientRef . current [ nextTab ] ?? { }
991+
992+ const prevFromToken = fromToken
993+ const prevToToken = toToken
994+
995+ tabTokenStateRef . current [ prevTab ] = {
996+ fromToken : prevFromToken ,
997+ toToken : prevToToken
998+ }
999+ tabRecipientRef . current [ prevTab ] = {
1000+ override :
1001+ typeof destinationAddressOverride === 'string'
1002+ ? destinationAddressOverride
1003+ : undefined ,
1004+ custom :
1005+ typeof customToAddress === 'string'
1006+ ? customToAddress
1007+ : undefined
1008+ }
1009+
1010+ let nextFromToken : Token | undefined
1011+ let nextToToken : Token | undefined
1012+
1013+ if ( nextTab === 'sell' ) {
1014+ // Selling the page token: default to previously viewed token (prevToToken)
1015+ nextFromToken =
1016+ storedNextState . fromToken ??
1017+ prevToToken ??
1018+ prevFromToken ??
1019+ undefined
1020+ // Payout token should remain empty unless user explicitly selected it on sell
1021+ nextToToken = storedNextState . toToken ?? undefined
1022+ } else {
1023+ // Buying the page token: default output token is prev page token
1024+ nextToToken =
1025+ storedNextState . toToken ??
1026+ prevFromToken ??
1027+ prevToToken ??
1028+ undefined
1029+ // Payment method stays empty unless explicitly chosen on buy
1030+ nextFromToken = storedNextState . fromToken ?? undefined
1031+ }
1032+
1033+ handleSetFromToken ( nextFromToken )
1034+ handleSetToToken ( nextToToken )
1035+ setDestinationAddressOverride ( storedNextRecipient . override )
1036+ setCustomToAddress ( storedNextRecipient . custom )
1037+
1038+ // Auto-select first compatible wallet in buy tab if no destination is set
1039+ if (
1040+ nextTab === 'buy' &&
1041+ multiWalletSupportEnabled &&
1042+ linkedWallets &&
1043+ linkedWallets . length > 0 &&
1044+ ! storedNextRecipient . override &&
1045+ ! storedNextRecipient . custom
1046+ ) {
1047+ const toChainForRecipient = relayClient ?. chains ?. find (
1048+ ( c ) => c . id === nextToToken ?. chainId
1049+ )
1050+
1051+ if ( toChainForRecipient ) {
1052+ const compatibleWallets = linkedWallets . filter (
1053+ ( wallet ) => wallet . vmType === toChainForRecipient . vmType
1054+ )
1055+
1056+ if ( compatibleWallets . length > 0 ) {
1057+ setDestinationAddressOverride ( compatibleWallets [ 0 ] . address )
1058+ }
1059+ }
1060+ }
1061+
1062+ setAmountInputValue ( '' )
1063+ setAmountOutputValue ( '' )
1064+ setUsdInputValue ( '' )
1065+ setUsdOutputValue ( '' )
1066+ setTokenInputCache ( '' )
1067+ setIsUsdInputMode ( nextTab === 'buy' )
1068+ debouncedAmountInputControls . cancel ( )
1069+ debouncedAmountOutputControls . cancel ( )
1070+ setOriginAddressOverride ( undefined )
1071+ }
1072+
1073+ if ( updateActiveTab ) {
1074+ setActiveTab ( nextTab )
1075+ }
1076+
1077+ const desiredTradeType : TradeType =
1078+ nextTab === 'buy' ? 'EXPECTED_OUTPUT' : 'EXACT_INPUT'
1079+
1080+ if ( tradeType !== desiredTradeType ) {
1081+ setTradeType ( desiredTradeType )
1082+ }
1083+
1084+ prevActiveTabRef . current = nextTab
1085+ } ,
1086+ [
1087+ activeTab ,
1088+ customToAddress ,
1089+ debouncedAmountInputControls ,
1090+ debouncedAmountOutputControls ,
1091+ destinationAddressOverride ,
1092+ fromToken ,
1093+ handleSetFromToken ,
1094+ handleSetToToken ,
1095+ linkedWallets ,
1096+ multiWalletSupportEnabled ,
1097+ relayClient ?. chains ,
1098+ setActiveTab ,
1099+ setAllowUnsupportedOrigin ,
1100+ setAllowUnsupportedRecipient ,
1101+ setAmountInputValue ,
1102+ setAmountOutputValue ,
1103+ setCustomToAddress ,
1104+ setDestinationAddressOverride ,
1105+ setIsUsdInputMode ,
1106+ setOriginAddressOverride ,
1107+ setTokenInputCache ,
1108+ setTradeType ,
1109+ setUsdInputValue ,
1110+ setUsdOutputValue ,
1111+ toToken ,
1112+ tradeType
1113+ ]
1114+ )
1115+
1116+ useEffect ( ( ) => {
1117+ if ( prevActiveTabRef . current === activeTab ) {
1118+ return
1119+ }
1120+
1121+ handleTabChange ( activeTab , false )
1122+ } , [ activeTab , handleTabChange ] )
1123+
9731124 return (
9741125 < >
9751126 < WidgetContainer
@@ -1054,126 +1205,7 @@ const TokenWidget: FC<TokenWidgetProps> = ({
10541205 value = { activeTab }
10551206 onValueChange = { ( value ) => {
10561207 const nextTab = value as 'buy' | 'sell'
1057-
1058- setAllowUnsupportedOrigin ( nextTab === 'buy' )
1059- setAllowUnsupportedRecipient ( nextTab === 'sell' )
1060-
1061- if ( nextTab !== activeTab ) {
1062- tabTokenStateRef . current [ activeTab ] = {
1063- fromToken,
1064- toToken
1065- }
1066- tabRecipientRef . current [ activeTab ] = {
1067- override :
1068- typeof destinationAddressOverride === 'string'
1069- ? destinationAddressOverride
1070- : undefined ,
1071- custom :
1072- typeof customToAddress === 'string'
1073- ? customToAddress
1074- : undefined
1075- }
1076-
1077- const currentState =
1078- tabTokenStateRef . current [ activeTab ] ?? { }
1079- const storedNextState =
1080- tabTokenStateRef . current [ nextTab ] ?? { }
1081- const storedNextRecipient =
1082- tabRecipientRef . current [ nextTab ] ?? { }
1083-
1084- const hasStoredNextFromToken =
1085- 'fromToken' in storedNextState
1086- const hasStoredNextToToken =
1087- 'toToken' in storedNextState
1088-
1089- let nextFromToken : Token | undefined
1090- let nextToToken : Token | undefined
1091-
1092- if ( nextTab === 'sell' ) {
1093- const sellToken = hasStoredNextFromToken
1094- ? storedNextState . fromToken
1095- : ( currentState . toToken ?? toToken ?? fromToken )
1096- const receiveToken = hasStoredNextToToken
1097- ? storedNextState . toToken
1098- : ( currentState . fromToken ?? fromToken )
1099-
1100- nextFromToken = sellToken ?? undefined
1101- nextToToken = receiveToken ?? undefined
1102- } else {
1103- const buyToken = hasStoredNextToToken
1104- ? storedNextState . toToken
1105- : ( currentState . toToken ?? toToken ?? fromToken )
1106- const payToken = hasStoredNextFromToken
1107- ? storedNextState . fromToken
1108- : ( currentState . fromToken ?? fromToken )
1109-
1110- nextFromToken = payToken ?? undefined
1111- nextToToken = buyToken ?? undefined
1112- }
1113-
1114- tabTokenStateRef . current [ nextTab ] = {
1115- fromToken : nextFromToken ,
1116- toToken : nextToToken
1117- }
1118- tabRecipientRef . current [ nextTab ] = storedNextRecipient
1119-
1120- handleSetFromToken ( nextFromToken )
1121- handleSetToToken ( nextToToken )
1122- setDestinationAddressOverride (
1123- storedNextRecipient . override
1124- )
1125- setCustomToAddress ( storedNextRecipient . custom )
1126-
1127- // Auto-select first compatible wallet in buy tab if no destination is set
1128- if (
1129- nextTab === 'buy' &&
1130- multiWalletSupportEnabled &&
1131- linkedWallets &&
1132- linkedWallets . length > 0 &&
1133- ! storedNextRecipient . override &&
1134- ! storedNextRecipient . custom
1135- ) {
1136- // Find the destination chain for filtering compatible wallets
1137- const toChain = relayClient ?. chains ?. find (
1138- ( c ) => c . id === nextToToken ?. chainId
1139- )
1140-
1141- if ( toChain ) {
1142- // Filter wallets compatible with the destination chain VM type
1143- const compatibleWallets = linkedWallets . filter (
1144- ( wallet ) => {
1145- return wallet . vmType === toChain . vmType
1146- }
1147- )
1148-
1149- // Auto-select the first compatible wallet
1150- if ( compatibleWallets . length > 0 ) {
1151- setDestinationAddressOverride (
1152- compatibleWallets [ 0 ] . address
1153- )
1154- }
1155- }
1156- }
1157-
1158- setAmountInputValue ( '' )
1159- setAmountOutputValue ( '' )
1160- setUsdInputValue ( '' )
1161- setUsdOutputValue ( '' )
1162- setTokenInputCache ( '' )
1163- setIsUsdInputMode ( nextTab === 'buy' )
1164- debouncedAmountInputControls . cancel ( )
1165- debouncedAmountOutputControls . cancel ( )
1166- setOriginAddressOverride ( undefined )
1167- }
1168-
1169- setActiveTab ( nextTab )
1170-
1171- const desiredTradeType : TradeType =
1172- nextTab === 'buy' ? 'EXPECTED_OUTPUT' : 'EXACT_INPUT'
1173-
1174- if ( tradeType !== desiredTradeType ) {
1175- setTradeType ( desiredTradeType )
1176- }
1208+ handleTabChange ( nextTab , true )
11771209
11781210 onAnalyticEvent ?.( 'TAB_SWITCHED' , {
11791211 tab : value
0 commit comments