0xtrails 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aave.d.ts +2 -0
- package/dist/aave.d.ts.map +1 -1
- package/dist/abortController.d.ts +8 -0
- package/dist/abortController.d.ts.map +1 -0
- package/dist/{ccip-CXlshvBY.js → ccip-BMB3uDZt.js} +1 -1
- package/dist/config.d.ts +0 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +4 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/error.d.ts +4 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/fees.d.ts +19 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/{index-_QuyGrjU.js → index-QXPUrZVv.js} +48719 -50852
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +811 -784
- package/dist/intentReceiptMonitor.d.ts +24 -0
- package/dist/intentReceiptMonitor.d.ts.map +1 -0
- package/dist/intentReceiptPoller.d.ts +69 -0
- package/dist/intentReceiptPoller.d.ts.map +1 -0
- package/dist/intents.d.ts +15 -11
- package/dist/intents.d.ts.map +1 -1
- package/dist/morpho.d.ts +6 -5
- package/dist/morpho.d.ts.map +1 -1
- package/dist/mutations.d.ts +16 -0
- package/dist/mutations.d.ts.map +1 -0
- package/dist/preconditions.d.ts +5 -4
- package/dist/preconditions.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +7 -258
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/prices.d.ts +9 -6
- package/dist/prices.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +3 -16
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts +17 -13
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/trails.d.ts +24 -40
- package/dist/trails.d.ts.map +1 -1
- package/dist/transactionIntent/constants.d.ts +7 -0
- package/dist/transactionIntent/constants.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +44 -0
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +30 -0
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/index.d.ts +4 -0
- package/dist/transactionIntent/deposits/index.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +30 -0
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -0
- package/dist/transactionIntent/execution/index.d.ts +2 -0
- package/dist/transactionIntent/execution/index.d.ts.map +1 -0
- package/dist/transactionIntent/execution/transactionState.d.ts +5 -0
- package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/crossChain.d.ts +82 -0
- package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/index.d.ts +4 -0
- package/dist/transactionIntent/handlers/index.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts +62 -0
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +72 -0
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -0
- package/dist/transactionIntent/index.d.ts +9 -0
- package/dist/transactionIntent/index.d.ts.map +1 -0
- package/dist/transactionIntent/quote/feeExtractors.d.ts +17 -0
- package/dist/transactionIntent/quote/feeExtractors.d.ts.map +1 -0
- package/dist/transactionIntent/quote/index.d.ts +4 -0
- package/dist/transactionIntent/quote/index.d.ts.map +1 -0
- package/dist/transactionIntent/quote/normalizeQuote.d.ts +34 -0
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -0
- package/dist/transactionIntent/quote/quoteHelpers.d.ts +5 -0
- package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/types.d.ts +131 -0
- package/dist/transactionIntent/types.d.ts.map +1 -0
- package/dist/transactionIntent/utils/balanceChecker.d.ts +18 -0
- package/dist/transactionIntent/utils/balanceChecker.d.ts.map +1 -0
- package/dist/transactionIntent/utils/index.d.ts +4 -0
- package/dist/transactionIntent/utils/index.d.ts.map +1 -0
- package/dist/transactionIntent/utils/lifiHelpers.d.ts +10 -0
- package/dist/transactionIntent/utils/lifiHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/utils/testnetHelpers.d.ts +3 -0
- package/dist/transactionIntent/utils/testnetHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/validators.d.ts +6 -0
- package/dist/transactionIntent/validators.d.ts.map +1 -0
- package/dist/transactions.d.ts +6 -3
- package/dist/transactions.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts +4 -0
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -0
- package/dist/widget/components/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +2 -3
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DynamicInputStyles.d.ts +18 -0
- package/dist/widget/components/DynamicInputStyles.d.ts.map +1 -0
- package/dist/widget/components/DynamicSizeInputField.d.ts +13 -0
- package/dist/widget/components/DynamicSizeInputField.d.ts.map +1 -0
- package/dist/widget/components/Earn.d.ts +2 -3
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/ErrorAnimationIcon.d.ts +2 -0
- package/dist/widget/components/ErrorAnimationIcon.d.ts.map +1 -0
- package/dist/widget/components/FeeBreakdown.d.ts +9 -0
- package/dist/widget/components/FeeBreakdown.d.ts.map +1 -0
- package/dist/widget/components/FeeOptions.d.ts +5 -13
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +2 -3
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/FundSwap.d.ts +2 -3
- package/dist/widget/components/FundSwap.d.ts.map +1 -1
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Identicon.d.ts.map +1 -1
- package/dist/widget/components/MeshConnectExchanges.d.ts +0 -3
- package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
- package/dist/widget/components/Modal.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts +2 -3
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts +3 -3
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/PoolWithdraw.d.ts +3 -20
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts +2 -0
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +2 -3
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts +11 -0
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts.map +1 -0
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Tooltip.d.ts +9 -0
- package/dist/widget/components/Tooltip.d.ts.map +1 -0
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts +1 -0
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +2 -2
- package/dist/widget/hooks/useCheckout.d.ts +17 -4
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +82 -0
- package/dist/widget/hooks/useQuote.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts +1 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +5 -6
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useWalletConnectionContext.d.ts +25 -0
- package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -0
- package/dist/widget/index.js +2 -2
- package/dist/widget/widget.d.ts +17 -7
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +19 -21
- package/src/aave.ts +54 -1
- package/src/abortController.ts +35 -0
- package/src/config.ts +57 -58
- package/src/constants.ts +11 -9
- package/src/error.ts +21 -3
- package/src/fees.ts +210 -0
- package/src/index.ts +35 -13
- package/src/intentReceiptMonitor.ts +102 -0
- package/src/intentReceiptPoller.ts +299 -0
- package/src/intents.ts +205 -171
- package/src/morpho.ts +58 -9
- package/src/mutations.ts +129 -0
- package/src/preconditions.ts +16 -21
- package/src/prepareSend.ts +92 -4699
- package/src/prices.ts +26 -22
- package/src/relaySdk.ts +2 -2
- package/src/sequenceWallet.ts +6 -73
- package/src/tokenBalances.ts +175 -69
- package/src/trails.ts +230 -722
- package/src/transactionIntent/constants.ts +11 -0
- package/src/transactionIntent/deposits/depositOrchestrator.ts +210 -0
- package/src/transactionIntent/deposits/gaslessDeposit.ts +588 -0
- package/src/transactionIntent/deposits/index.ts +3 -0
- package/src/transactionIntent/deposits/standardDeposit.ts +379 -0
- package/src/transactionIntent/execution/index.ts +1 -0
- package/src/transactionIntent/execution/transactionState.ts +35 -0
- package/src/transactionIntent/handlers/crossChain.ts +1707 -0
- package/src/transactionIntent/handlers/index.ts +3 -0
- package/src/transactionIntent/handlers/sameChainDifferentToken.ts +323 -0
- package/src/transactionIntent/handlers/sameChainSameToken.ts +712 -0
- package/src/transactionIntent/index.ts +9 -0
- package/src/transactionIntent/quote/feeExtractors.ts +81 -0
- package/src/transactionIntent/quote/index.ts +3 -0
- package/src/transactionIntent/quote/normalizeQuote.ts +367 -0
- package/src/transactionIntent/quote/quoteHelpers.ts +53 -0
- package/src/transactionIntent/types.ts +157 -0
- package/src/transactionIntent/utils/balanceChecker.ts +96 -0
- package/src/transactionIntent/utils/index.ts +3 -0
- package/src/transactionIntent/utils/lifiHelpers.ts +68 -0
- package/src/transactionIntent/utils/testnetHelpers.ts +10 -0
- package/src/transactionIntent/validators.ts +57 -0
- package/src/transactions.ts +98 -71
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountIntentTransactionHistory.tsx +36 -36
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
- package/src/widget/components/AccountSettings.tsx +70 -41
- package/src/widget/components/ChainFilterDropdown.tsx +24 -3
- package/src/widget/components/ClassicSwap.tsx +44 -107
- package/src/widget/components/ConfigDisplay.tsx +0 -11
- package/src/widget/components/ConnectWallet.tsx +4 -1
- package/src/widget/components/ConnectedWallets.tsx +51 -25
- package/src/widget/components/DynamicInputStyles.tsx +76 -0
- package/src/widget/components/DynamicSizeInputField.tsx +109 -0
- package/src/widget/components/Earn.tsx +34 -45
- package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
- package/src/widget/components/FeeBreakdown.tsx +155 -0
- package/src/widget/components/FeeOption.tsx +2 -2
- package/src/widget/components/FeeOptions.tsx +151 -112
- package/src/widget/components/Fund.tsx +10 -29
- package/src/widget/components/FundMethods.tsx +4 -3
- package/src/widget/components/FundSwap.tsx +2 -3
- package/src/widget/components/FundingMethodSelectorButton.tsx +24 -14
- package/src/widget/components/Identicon.tsx +164 -95
- package/src/widget/components/MeshConnectExchanges.tsx +2 -15
- package/src/widget/components/Modal.tsx +0 -12
- package/src/widget/components/Pay.tsx +72 -75
- package/src/widget/components/PoolDeposit.tsx +221 -242
- package/src/widget/components/PoolWithdraw.tsx +347 -469
- package/src/widget/components/PriceImpactWarning.tsx +1 -1
- package/src/widget/components/QuoteDetails.tsx +906 -484
- package/src/widget/components/Receipt.tsx +16 -2
- package/src/widget/components/RecipientSelectorButton.tsx +7 -5
- package/src/widget/components/Recipients.tsx +1 -1
- package/src/widget/components/ScreenHeader.tsx +60 -36
- package/src/widget/components/Swap.tsx +2 -3
- package/src/widget/components/ThemeProvider.tsx +2 -1
- package/src/widget/components/TokenDisplayNonSelectable.tsx +40 -0
- package/src/widget/components/TokenImage.tsx +1 -1
- package/src/widget/components/TokenSelector.tsx +62 -53
- package/src/widget/components/TokenSelectorButton.tsx +38 -15
- package/src/widget/components/Tooltip.tsx +51 -0
- package/src/widget/components/TransferPendingVertical.tsx +12 -8
- package/src/widget/components/WaasFeeOptions.tsx +139 -4
- package/src/widget/components/WalletConfirmation.tsx +23 -13
- package/src/widget/components/WalletConnect.tsx +93 -29
- package/src/widget/hooks/useAmountUsd.ts +9 -9
- package/src/widget/hooks/useCheckout.ts +97 -9
- package/src/widget/hooks/useDefaultTokenSelection.tsx +27 -21
- package/src/widget/hooks/useQuote.ts +466 -0
- package/src/widget/hooks/useSelectedFeeToken.tsx +32 -37
- package/src/widget/hooks/useSendForm.ts +45 -51
- package/src/widget/hooks/useTokenList.ts +34 -26
- package/src/widget/hooks/useWalletConnectionContext.tsx +128 -0
- package/src/widget/widget.tsx +365 -390
- package/dist/apiClient.d.ts +0 -9
- package/dist/apiClient.d.ts.map +0 -1
- package/dist/intentEntrypoint.d.ts +0 -114
- package/dist/intentEntrypoint.d.ts.map +0 -1
- package/dist/metaTxnMonitor.d.ts +0 -15
- package/dist/metaTxnMonitor.d.ts.map +0 -1
- package/dist/metaTxns.d.ts +0 -11
- package/dist/metaTxns.d.ts.map +0 -1
- package/dist/relayer.d.ts +0 -43
- package/dist/relayer.d.ts.map +0 -1
- package/src/apiClient.ts +0 -35
- package/src/intentEntrypoint.ts +0 -203
- package/src/metaTxnMonitor.ts +0 -171
- package/src/metaTxns.ts +0 -45
- package/src/relayer.ts +0 -289
|
@@ -13,6 +13,7 @@ import { truncateAddress } from "../../utils.js"
|
|
|
13
13
|
import { formatElapsed } from "../../utils.js"
|
|
14
14
|
import { ChainImage } from "./ChainImage.js"
|
|
15
15
|
import { getChainInfo } from "../../chains.js"
|
|
16
|
+
import { useMode } from "../hooks/useMode.js"
|
|
16
17
|
|
|
17
18
|
interface ReceiptProps {
|
|
18
19
|
onSendAnother: () => void
|
|
@@ -86,6 +87,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
86
87
|
quote,
|
|
87
88
|
showCloseButton,
|
|
88
89
|
}) => {
|
|
90
|
+
const { mode } = useMode()
|
|
89
91
|
const [showContent, setShowContent] = useState(false)
|
|
90
92
|
const [showRefundInfo, setShowRefundInfo] = useState(false)
|
|
91
93
|
const [refundMessage, setRefundMessage] = useState<string | ReactNode | null>(
|
|
@@ -111,6 +113,18 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
111
113
|
return transactionStates.some((tx) => hasMetaTxError(tx))
|
|
112
114
|
}, [transactionStates, hasMetaTxError])
|
|
113
115
|
|
|
116
|
+
const buttonText = useMemo(() => {
|
|
117
|
+
if (mode === "pay") {
|
|
118
|
+
return "Pay Again"
|
|
119
|
+
} else if (mode === "fund") {
|
|
120
|
+
return "Fund Again"
|
|
121
|
+
} else if (mode === "swap") {
|
|
122
|
+
return "Swap Again"
|
|
123
|
+
} else {
|
|
124
|
+
return "Send Again"
|
|
125
|
+
}
|
|
126
|
+
}, [mode])
|
|
127
|
+
|
|
114
128
|
const {
|
|
115
129
|
finalExplorerUrl,
|
|
116
130
|
finalChainId,
|
|
@@ -154,7 +168,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
154
168
|
// Extract QuoteDetails section to reuse in both success and failure states
|
|
155
169
|
const quoteDetailsSection = quote && (
|
|
156
170
|
<div className="mt-2">
|
|
157
|
-
<QuoteDetails quote={quote} showContent={true}>
|
|
171
|
+
<QuoteDetails quote={quote} showContent={true} compact={true}>
|
|
158
172
|
{transactionStates.length > 0 && (
|
|
159
173
|
<>
|
|
160
174
|
<div className="font-medium text-gray-700 dark:text-gray-300">
|
|
@@ -477,7 +491,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
477
491
|
onClick={onSendAnother}
|
|
478
492
|
className="inline-flex items-center gap-1 px-4 py-2 text-sm bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 trails-border-radius-button transition-colors duration-200 text-gray-600 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 cursor-pointer font-medium"
|
|
479
493
|
>
|
|
480
|
-
|
|
494
|
+
{buttonText}
|
|
481
495
|
<ChevronRight className="w-4 h-4" />
|
|
482
496
|
</button>
|
|
483
497
|
</div>
|
|
@@ -26,15 +26,17 @@ export const RecipientSelectorButton: React.FC = () => {
|
|
|
26
26
|
>
|
|
27
27
|
{selectedRecipient ? (
|
|
28
28
|
<>
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
<div className="flex items-center mr-1">
|
|
30
|
+
<Identicon value={selectedRecipient} size={16} />
|
|
31
|
+
</div>
|
|
32
|
+
<span className="text-sm font-medium m-0">
|
|
33
|
+
{truncateAddress(selectedRecipient, 4, 4)}
|
|
32
34
|
</span>
|
|
33
35
|
</>
|
|
34
36
|
) : (
|
|
35
|
-
<span className="text-sm font-medium">Select Recipient</span>
|
|
37
|
+
<span className="text-sm font-medium m-0">Select Recipient</span>
|
|
36
38
|
)}
|
|
37
|
-
<ChevronRight className="w-4 h-4" />
|
|
39
|
+
<ChevronRight className="w-4 h-4 m-0" />
|
|
38
40
|
</button>
|
|
39
41
|
)
|
|
40
42
|
}
|
|
@@ -233,7 +233,7 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
233
233
|
{/* Recent Recipients */}
|
|
234
234
|
{recentRecipients.length > 0 && (
|
|
235
235
|
<div className="space-y-2">
|
|
236
|
-
<div className="text-sm font-medium text-gray-
|
|
236
|
+
<div className="text-sm font-medium text-gray-900 dark:text-gray-100 text-left">
|
|
237
237
|
Recent wallets
|
|
238
238
|
</div>
|
|
239
239
|
<div className="trails-border-radius-container border trails-border-primary">
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { ChevronLeft } from "lucide-react"
|
|
1
|
+
import { ChevronLeft, X } from "lucide-react"
|
|
2
2
|
import type React from "react"
|
|
3
|
-
import {
|
|
3
|
+
import { useConnections } from "wagmi"
|
|
4
4
|
import AccountActionsDropdown from "./AccountActionsDropdown.js"
|
|
5
|
+
import AccountIntentTransactionHistoryButton from "./AccountIntentTransactionHistoryButton.js"
|
|
5
6
|
import { useWidgetProps } from "../hooks/useWidgetProps.js"
|
|
7
|
+
import { useModal } from "../widget.js"
|
|
6
8
|
|
|
7
9
|
interface ScreenHeaderProps {
|
|
8
10
|
onBack?: () => void
|
|
@@ -20,45 +22,67 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = ({
|
|
|
20
22
|
headerContentAlign = "left",
|
|
21
23
|
showAccountActions = false,
|
|
22
24
|
}) => {
|
|
23
|
-
const
|
|
25
|
+
const connections = useConnections()
|
|
24
26
|
const { renderInline } = useWidgetProps()
|
|
27
|
+
const { closeModal, isModalOpen } = useModal()
|
|
28
|
+
|
|
29
|
+
// Check if there are any connected accounts across all connectors
|
|
30
|
+
const isConnected = connections.length > 0
|
|
31
|
+
|
|
32
|
+
// Show close button when in modal mode (not renderInline) and modal is open
|
|
33
|
+
const showCloseButton = !renderInline && isModalOpen
|
|
25
34
|
return (
|
|
26
|
-
<div className="
|
|
27
|
-
{/* Left side - Back button
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
<div className="flex items-center justify-between w-full mb-4">
|
|
36
|
+
{/* Left side - Back button */}
|
|
37
|
+
<div className="flex items-center">
|
|
38
|
+
{onBack && (
|
|
39
|
+
<button
|
|
40
|
+
type="button"
|
|
41
|
+
onClick={onBack}
|
|
42
|
+
className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600 mr-2"
|
|
43
|
+
title="Back"
|
|
44
|
+
>
|
|
45
|
+
<ChevronLeft className="h-4 w-4" />
|
|
46
|
+
</button>
|
|
47
|
+
)}
|
|
48
|
+
|
|
49
|
+
{/* Header content */}
|
|
50
|
+
<h2
|
|
51
|
+
className={`text-lg font-semibold ${
|
|
52
|
+
headerContentAlign === "center" ? "text-center" : "text-left"
|
|
53
|
+
} text-gray-900 dark:text-white`}
|
|
33
54
|
>
|
|
34
|
-
|
|
35
|
-
</
|
|
36
|
-
|
|
55
|
+
{headerContent}
|
|
56
|
+
</h2>
|
|
57
|
+
</div>
|
|
37
58
|
|
|
38
|
-
{/*
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
{/* Right side - Content, Account Actions, and Close button */}
|
|
60
|
+
<div className="flex items-center gap-2">
|
|
61
|
+
{/* Right side content and Account Actions */}
|
|
62
|
+
{rightSideContent && (
|
|
63
|
+
<div className="text-right max-w-[280px]">{rightSideContent}</div>
|
|
64
|
+
)}
|
|
65
|
+
{isConnected && showAccountActions && (
|
|
66
|
+
<>
|
|
67
|
+
<div className="m-0">
|
|
68
|
+
<AccountIntentTransactionHistoryButton />
|
|
69
|
+
</div>
|
|
70
|
+
<AccountActionsDropdown />
|
|
71
|
+
</>
|
|
72
|
+
)}
|
|
50
73
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
{/* Close button (always rightmost) */}
|
|
75
|
+
{showCloseButton && (
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
onClick={closeModal}
|
|
79
|
+
className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
80
|
+
title="Close"
|
|
81
|
+
>
|
|
82
|
+
<X className="h-4 w-4" />
|
|
83
|
+
</button>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
62
86
|
</div>
|
|
63
87
|
)
|
|
64
88
|
}
|
|
@@ -13,18 +13,17 @@ interface SwapProps {
|
|
|
13
13
|
onBack?: () => void
|
|
14
14
|
onConfirm: () => void
|
|
15
15
|
onComplete: (result: OnCompleteProps) => void
|
|
16
|
-
account
|
|
16
|
+
account?: Account
|
|
17
17
|
toRecipient?: string
|
|
18
18
|
toAmount?: string
|
|
19
19
|
toChainId?: number
|
|
20
20
|
toToken?: string
|
|
21
21
|
toCalldata?: string
|
|
22
|
-
walletClient
|
|
22
|
+
walletClient?: WalletClient
|
|
23
23
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
24
24
|
onError: (error: Error | string | null) => void
|
|
25
25
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
26
26
|
paymasterUrls?: Array<{ chainId: number; url: string }>
|
|
27
|
-
gasless?: boolean
|
|
28
27
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
29
28
|
quoteProvider?: string
|
|
30
29
|
fundMethod?: string
|
|
@@ -3,6 +3,7 @@ import { createContext, useContext, useEffect, useState } from "react"
|
|
|
3
3
|
import type { Theme } from "../../theme.js"
|
|
4
4
|
import { ThemeProvider as DesignSystemThemeProvider } from "@0xsequence/design-system"
|
|
5
5
|
import { logger } from "../../logger.js"
|
|
6
|
+
import { DEFAULT_THEME } from "../../constants.js"
|
|
6
7
|
|
|
7
8
|
interface ThemeContextType {
|
|
8
9
|
theme: Theme
|
|
@@ -31,7 +32,7 @@ const getIsDark = (theme: Theme): boolean => {
|
|
|
31
32
|
|
|
32
33
|
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
33
34
|
children,
|
|
34
|
-
initialTheme =
|
|
35
|
+
initialTheme = DEFAULT_THEME,
|
|
35
36
|
}) => {
|
|
36
37
|
const [theme, setTheme] = useState<Theme>(initialTheme)
|
|
37
38
|
const [isDark, setIsDark] = useState(getIsDark(initialTheme))
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
import { TokenImage } from "./TokenImage.js"
|
|
3
|
+
|
|
4
|
+
interface TokenDisplayNonSelectableProps {
|
|
5
|
+
symbol: string
|
|
6
|
+
imageUrl?: string
|
|
7
|
+
chainId: number
|
|
8
|
+
contractAddress: string
|
|
9
|
+
chainName?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const TokenDisplayNonSelectable: React.FC<
|
|
13
|
+
TokenDisplayNonSelectableProps
|
|
14
|
+
> = ({ symbol, imageUrl, chainId, contractAddress, chainName }) => {
|
|
15
|
+
return (
|
|
16
|
+
<div className="relative max-w-[120px]">
|
|
17
|
+
<div className="flex items-center space-x-1.5 trails-bg-card trails-border-radius-input px-2.5 py-1.5 border trails-border-primary">
|
|
18
|
+
<div className="flex items-center flex-shrink-0">
|
|
19
|
+
<TokenImage
|
|
20
|
+
symbol={symbol}
|
|
21
|
+
imageUrl={imageUrl}
|
|
22
|
+
chainId={chainId}
|
|
23
|
+
contractAddress={contractAddress}
|
|
24
|
+
size={28}
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
27
|
+
<div className="flex flex-col items-start min-w-0 overflow-hidden">
|
|
28
|
+
<span className="font-bold trails-text-primary text-sm leading-tight truncate max-w-full text-left">
|
|
29
|
+
{symbol}
|
|
30
|
+
</span>
|
|
31
|
+
{chainName && (
|
|
32
|
+
<span className="text-xs trails-text-muted leading-tight truncate max-w-full text-left">
|
|
33
|
+
{chainName}
|
|
34
|
+
</span>
|
|
35
|
+
)}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -64,7 +64,7 @@ export const TokenImage: React.FC<TokenImageProps> = ({
|
|
|
64
64
|
|
|
65
65
|
return (
|
|
66
66
|
<div
|
|
67
|
-
className={`rounded-full flex items-center justify-center text-sm relative ${
|
|
67
|
+
className={`rounded-full flex items-center justify-center text-sm relative m-0 ${
|
|
68
68
|
symbol !== "ETH" ? "bg-gray-400 dark:bg-gray-900" : ""
|
|
69
69
|
}`}
|
|
70
70
|
style={{
|
|
@@ -2,6 +2,7 @@ import { ChevronLeft, Copy } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useState, useMemo } from "react"
|
|
4
4
|
import { AnimatePresence, motion } from "framer-motion"
|
|
5
|
+
import { zeroAddress } from "viem"
|
|
5
6
|
import type { Token, TokenFormatted } from "../hooks/useTokenList.js"
|
|
6
7
|
import { useTokenList } from "../hooks/useTokenList.js"
|
|
7
8
|
import { useChainFilter } from "../hooks/useChainFilter.js"
|
|
@@ -14,6 +15,7 @@ import { ChainFilterDropdown } from "./ChainFilterDropdown.js"
|
|
|
14
15
|
import { SearchInputField } from "./SearchInputField.js"
|
|
15
16
|
import { truncateAddress } from "../../utils.js"
|
|
16
17
|
import { logger } from "../../logger.js"
|
|
18
|
+
import { useAccount } from "wagmi"
|
|
17
19
|
|
|
18
20
|
interface TokenSelectorProps {
|
|
19
21
|
onTokenSelect: (selectedToken: Token) => void
|
|
@@ -55,6 +57,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
55
57
|
}) => {
|
|
56
58
|
const [copiedAddress, setCopiedAddress] = useState<string | null>(null)
|
|
57
59
|
const { isBalanceVisible } = useBalanceVisible()
|
|
60
|
+
const { address } = useAccount()
|
|
58
61
|
|
|
59
62
|
const {
|
|
60
63
|
searchQuery,
|
|
@@ -224,7 +227,9 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
224
227
|
? "No tokens found matching your search."
|
|
225
228
|
: fundMethod === "qr-code" || fundMethod === "exchange"
|
|
226
229
|
? ""
|
|
227
|
-
:
|
|
230
|
+
: address
|
|
231
|
+
? "No available tokens found"
|
|
232
|
+
: ""}
|
|
228
233
|
</p>
|
|
229
234
|
</div>
|
|
230
235
|
)}
|
|
@@ -330,7 +335,9 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
330
335
|
{/* Default state: show symbol */}
|
|
331
336
|
<div
|
|
332
337
|
className={`flex items-center transition-all duration-300 ease-in-out ${
|
|
333
|
-
contractAddress
|
|
338
|
+
contractAddress &&
|
|
339
|
+
contractAddress.toLowerCase() !==
|
|
340
|
+
zeroAddress.toLowerCase()
|
|
334
341
|
? "group-hover:opacity-0 group-hover:transform group-hover:-translate-x-2"
|
|
335
342
|
: ""
|
|
336
343
|
} ${
|
|
@@ -346,58 +353,60 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
346
353
|
</span>
|
|
347
354
|
</div>
|
|
348
355
|
|
|
349
|
-
{/* Hover state: show address with copy button */}
|
|
350
|
-
{contractAddress &&
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
{truncateAddress(contractAddress)}
|
|
362
|
-
</span>
|
|
363
|
-
<button
|
|
364
|
-
type="button"
|
|
365
|
-
onClick={(e) =>
|
|
366
|
-
handleCopyAddress(contractAddress, e)
|
|
367
|
-
}
|
|
368
|
-
className={`ml-1 p-0.5 rounded transition-all duration-200 cursor-pointer ${
|
|
369
|
-
copiedAddress === contractAddress
|
|
370
|
-
? "bg-green-100 dark:bg-green-900/30"
|
|
371
|
-
: "hover:bg-gray-200 dark:hover:bg-gray-600"
|
|
372
|
-
}`}
|
|
373
|
-
title={
|
|
374
|
-
copiedAddress === contractAddress
|
|
375
|
-
? "Copied!"
|
|
376
|
-
: "Copy full address"
|
|
377
|
-
}
|
|
356
|
+
{/* Hover state: show address with copy button (only for non-zero addresses) */}
|
|
357
|
+
{contractAddress &&
|
|
358
|
+
contractAddress.toLowerCase() !==
|
|
359
|
+
zeroAddress.toLowerCase() && (
|
|
360
|
+
<div
|
|
361
|
+
className={`absolute top-0 left-0 flex items-center transition-all duration-300 ease-in-out opacity-0 transform translate-x-2 ${
|
|
362
|
+
!isSufficientBalance &&
|
|
363
|
+
fundMethod !== "qr-code" &&
|
|
364
|
+
fundMethod !== "exchange"
|
|
365
|
+
? "group-hover:opacity-70"
|
|
366
|
+
: "group-hover:opacity-100"
|
|
367
|
+
} group-hover:translate-x-0`}
|
|
378
368
|
>
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
369
|
+
<span className="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
|
|
370
|
+
{truncateAddress(contractAddress)}
|
|
371
|
+
</span>
|
|
372
|
+
<button
|
|
373
|
+
type="button"
|
|
374
|
+
onClick={(e) =>
|
|
375
|
+
handleCopyAddress(contractAddress, e)
|
|
376
|
+
}
|
|
377
|
+
className={`ml-1 p-0.5 rounded transition-all duration-200 cursor-pointer ${
|
|
378
|
+
copiedAddress === contractAddress
|
|
379
|
+
? "bg-green-100 dark:bg-green-900/30"
|
|
380
|
+
: "hover:bg-gray-200 dark:hover:bg-gray-600"
|
|
381
|
+
}`}
|
|
382
|
+
title={
|
|
383
|
+
copiedAddress === contractAddress
|
|
384
|
+
? "Copied!"
|
|
385
|
+
: "Copy full address"
|
|
386
|
+
}
|
|
387
|
+
>
|
|
388
|
+
{copiedAddress === contractAddress ? (
|
|
389
|
+
<svg
|
|
390
|
+
className="w-3 h-3 text-green-600 dark:text-green-400"
|
|
391
|
+
fill="none"
|
|
392
|
+
viewBox="0 0 24 24"
|
|
393
|
+
stroke="currentColor"
|
|
394
|
+
aria-label="Copied"
|
|
395
|
+
>
|
|
396
|
+
<title>Copied</title>
|
|
397
|
+
<path
|
|
398
|
+
strokeLinecap="round"
|
|
399
|
+
strokeLinejoin="round"
|
|
400
|
+
strokeWidth={2}
|
|
401
|
+
d="M5 13l4 4L19 7"
|
|
402
|
+
/>
|
|
403
|
+
</svg>
|
|
404
|
+
) : (
|
|
405
|
+
<Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
|
|
406
|
+
)}
|
|
407
|
+
</button>
|
|
408
|
+
</div>
|
|
409
|
+
)}
|
|
401
410
|
</div>
|
|
402
411
|
</div>
|
|
403
412
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { ChevronRight } from "lucide-react"
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useMemo } from "react"
|
|
4
|
+
import { useConnections } from "wagmi"
|
|
4
5
|
import { TokenImage } from "./TokenImage.js"
|
|
5
6
|
import { getChainInfo } from "../../chains.js"
|
|
7
|
+
import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
|
|
8
|
+
import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
|
|
6
9
|
|
|
7
10
|
interface TokenSelectorButtonProps {
|
|
8
11
|
token?: {
|
|
@@ -21,47 +24,67 @@ export const TokenSelectorButton: React.FC<TokenSelectorButtonProps> = ({
|
|
|
21
24
|
token,
|
|
22
25
|
chainId,
|
|
23
26
|
onSelect,
|
|
24
|
-
className = "flex items-center space-x-
|
|
27
|
+
className = "flex items-center space-x-1.5 trails-border-radius-input px-2.5 py-1.5 border transition-all duration-200",
|
|
25
28
|
unselectable = false,
|
|
26
29
|
}) => {
|
|
30
|
+
const connections = useConnections()
|
|
31
|
+
const { setCurrentScreen } = useCurrentScreen()
|
|
32
|
+
const { selectedFundMethod } = useSelectedFundMethod()
|
|
27
33
|
const displayChainId = token?.chainId || chainId
|
|
28
34
|
|
|
35
|
+
// Check if there are any connected accounts across all connectors
|
|
36
|
+
const isConnected = connections.length > 0
|
|
37
|
+
|
|
29
38
|
const chainInfo = useMemo(() => {
|
|
30
39
|
return displayChainId ? getChainInfo(displayChainId) : null
|
|
31
40
|
}, [displayChainId])
|
|
32
41
|
|
|
42
|
+
const handleClick = () => {
|
|
43
|
+
if (unselectable) return
|
|
44
|
+
|
|
45
|
+
// If no wallet connected and fund method is "wallet", redirect to connect screen
|
|
46
|
+
if (!isConnected && selectedFundMethod === "wallet") {
|
|
47
|
+
setCurrentScreen("connect")
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
onSelect()
|
|
52
|
+
}
|
|
53
|
+
|
|
33
54
|
return (
|
|
34
55
|
<button
|
|
35
56
|
type="button"
|
|
36
|
-
onClick={
|
|
57
|
+
onClick={handleClick}
|
|
37
58
|
disabled={unselectable}
|
|
38
|
-
className={`${className} ${
|
|
59
|
+
className={`${className} ${token ? "max-w-[120px]" : ""} ${
|
|
39
60
|
token
|
|
40
|
-
? "
|
|
61
|
+
? "bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600"
|
|
41
62
|
: "bg-blue-500 hover:bg-blue-600 border-blue-500 text-white"
|
|
42
63
|
} ${unselectable ? "cursor-default" : "cursor-pointer"}`}
|
|
43
64
|
>
|
|
44
65
|
{token ? (
|
|
45
66
|
<>
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
67
|
+
<div className="flex items-center flex-shrink-0">
|
|
68
|
+
<TokenImage
|
|
69
|
+
symbol={token.symbol}
|
|
70
|
+
imageUrl={token.imageUrl}
|
|
71
|
+
chainId={displayChainId}
|
|
72
|
+
contractAddress={token.contractAddress}
|
|
73
|
+
size={28}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
<div className="flex flex-col items-start min-w-0 overflow-hidden">
|
|
77
|
+
<span className="font-bold trails-text-primary text-sm leading-tight truncate max-w-full text-left">
|
|
55
78
|
{token.symbol}
|
|
56
79
|
</span>
|
|
57
80
|
{chainInfo && (
|
|
58
|
-
<span className="text-xs trails-text-muted">
|
|
81
|
+
<span className="text-xs trails-text-muted leading-tight truncate max-w-full text-left">
|
|
59
82
|
{chainInfo.name}
|
|
60
83
|
</span>
|
|
61
84
|
)}
|
|
62
85
|
</div>
|
|
63
86
|
{!unselectable && (
|
|
64
|
-
<ChevronRight className="w-3.5 h-3.5 trails-text-muted" />
|
|
87
|
+
<ChevronRight className="w-3.5 h-3.5 trails-text-muted flex-shrink-0" />
|
|
65
88
|
)}
|
|
66
89
|
</>
|
|
67
90
|
) : (
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
import { TooltipPrimitive } from "@0xsequence/design-system"
|
|
3
|
+
import { useTheme } from "./ThemeProvider.js"
|
|
4
|
+
|
|
5
|
+
interface TooltipProps {
|
|
6
|
+
message: string
|
|
7
|
+
children: React.ReactNode
|
|
8
|
+
className?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Tooltip: React.FC<TooltipProps> = ({
|
|
12
|
+
message,
|
|
13
|
+
children,
|
|
14
|
+
className = "",
|
|
15
|
+
}) => {
|
|
16
|
+
const { isDark } = useTheme()
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<TooltipPrimitive.Provider>
|
|
20
|
+
<TooltipPrimitive.Root delayDuration={0}>
|
|
21
|
+
<TooltipPrimitive.Trigger asChild>
|
|
22
|
+
<div className={className}>{children}</div>
|
|
23
|
+
</TooltipPrimitive.Trigger>
|
|
24
|
+
<TooltipPrimitive.Portal>
|
|
25
|
+
<TooltipPrimitive.Content
|
|
26
|
+
className="trails-border-radius-container px-3 py-2 text-xs font-medium shadow-lg z-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
|
|
27
|
+
style={{
|
|
28
|
+
maxWidth: "400px",
|
|
29
|
+
wordWrap: "break-word",
|
|
30
|
+
whiteSpace: "normal",
|
|
31
|
+
overflowWrap: "break-word",
|
|
32
|
+
backgroundColor: isDark ? "#111827" : "#ffffff", // gray-900 or white
|
|
33
|
+
color: isDark ? "#ffffff" : "#000000", // white or black
|
|
34
|
+
}}
|
|
35
|
+
side="top"
|
|
36
|
+
align="center"
|
|
37
|
+
sideOffset={4}
|
|
38
|
+
alignOffset={0}
|
|
39
|
+
>
|
|
40
|
+
{message}
|
|
41
|
+
<TooltipPrimitive.Arrow
|
|
42
|
+
style={{ fill: isDark ? "#111827" : "#ffffff" }} // gray-900 or white
|
|
43
|
+
/>
|
|
44
|
+
</TooltipPrimitive.Content>
|
|
45
|
+
</TooltipPrimitive.Portal>
|
|
46
|
+
</TooltipPrimitive.Root>
|
|
47
|
+
</TooltipPrimitive.Provider>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default Tooltip
|
|
@@ -477,15 +477,19 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
|
|
|
477
477
|
)}
|
|
478
478
|
|
|
479
479
|
{/* Details Section */}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
480
|
+
{quote && (
|
|
481
|
+
<div
|
|
482
|
+
className={`w-full max-w-sm transition-all duration-500 ease-out delay-200 ${
|
|
483
|
+
showContent
|
|
484
|
+
? "opacity-100 translate-y-0"
|
|
485
|
+
: "opacity-0 translate-y-4"
|
|
486
|
+
}`}
|
|
487
|
+
>
|
|
488
|
+
<div className="mt-4">
|
|
489
|
+
<QuoteDetails quote={quote} showContent={true} compact={true} />
|
|
490
|
+
</div>
|
|
487
491
|
</div>
|
|
488
|
-
|
|
492
|
+
)}
|
|
489
493
|
|
|
490
494
|
{/* Timeout Warning */}
|
|
491
495
|
{showTimeoutWarning && !showContinueButton && (
|