@lifi/widget 4.0.0-beta.18 → 4.0.0-beta.20
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/esm/App.js.map +1 -1
- package/dist/esm/AppDefault.js.map +1 -1
- package/dist/esm/AppDrawer.js.map +1 -1
- package/dist/esm/AppLayout.js.map +1 -1
- package/dist/esm/AppProvider.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputStartAdornment.js.map +1 -1
- package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
- package/dist/esm/components/AppContainer.js.map +1 -1
- package/dist/esm/components/Avatar/AccountAvatar.js.map +1 -1
- package/dist/esm/components/Avatar/Avatar.js.map +1 -1
- package/dist/esm/components/Avatar/Avatar.style.js.map +1 -1
- package/dist/esm/components/Avatar/ChainBadgeContent.js.map +1 -1
- package/dist/esm/components/Avatar/SmallAvatar.js.map +1 -1
- package/dist/esm/components/Avatar/TokenAvatar.js.map +1 -1
- package/dist/esm/components/Avatar/utils.js.map +1 -1
- package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js.map +1 -1
- package/dist/esm/components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/esm/components/Card/Card.js.map +1 -1
- package/dist/esm/components/Card/CardIconButton.js.map +1 -1
- package/dist/esm/components/ChainSelect/ChainSelect.js.map +1 -1
- package/dist/esm/components/ChainSelect/ChainSelect.style.js.map +1 -1
- package/dist/esm/components/ChainSelect/useChainSelect.js.map +1 -1
- package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
- package/dist/esm/components/Chains/ChainList.js.map +1 -1
- package/dist/esm/components/Chains/ChainList.style.js.map +1 -1
- package/dist/esm/components/Chains/ChainListItem.js.map +1 -1
- package/dist/esm/components/Chains/ChainSearchInput.js.map +1 -1
- package/dist/esm/components/Chains/ChainsExpanded.js.map +1 -1
- package/dist/esm/components/Chains/PinChainButton.js.map +1 -1
- package/dist/esm/components/Chains/SelectChainContent.js.map +1 -1
- package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
- package/dist/esm/components/ContextMenu.js.map +1 -1
- package/dist/esm/components/ContractComponent/ContractComponent.js.map +1 -1
- package/dist/esm/components/ContractComponent/ItemPrice.js.map +1 -1
- package/dist/esm/components/ContractComponent/NFT/NFT.js.map +1 -1
- package/dist/esm/components/ContractComponent/NFT/NFTBase.js.map +1 -1
- package/dist/esm/components/Dialog/Dialog.js.map +1 -1
- package/dist/esm/components/Expansion/Expansion.js.map +1 -1
- package/dist/esm/components/Expansion/ExpansionTransition.js.map +1 -1
- package/dist/esm/components/FeeBreakdownTooltip.js.map +1 -1
- package/dist/esm/components/Header/ActivitiesButton.js.map +1 -1
- package/dist/esm/components/Header/BackButton.js.map +1 -1
- package/dist/esm/components/Header/CloseDrawerButton.js.map +1 -1
- package/dist/esm/components/Header/DisconnectIconButton.js.map +1 -1
- package/dist/esm/components/Header/Header.js.map +1 -1
- package/dist/esm/components/Header/Header.style.js.map +1 -1
- package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
- package/dist/esm/components/Header/SettingsButton.js.map +1 -1
- package/dist/esm/components/Header/SettingsButton.style.js.map +1 -1
- package/dist/esm/components/Header/SplitNavigationTabs.js.map +1 -1
- package/dist/esm/components/Header/WalletHeader.js.map +1 -1
- package/dist/esm/components/Header/WalletMenu.js.map +1 -1
- package/dist/esm/components/IconCircle/IconCircle.js.map +1 -1
- package/dist/esm/components/IconCircle/IconCircle.style.js.map +1 -1
- package/dist/esm/components/Initializer.js.map +1 -1
- package/dist/esm/components/ListItemButton.js.map +1 -1
- package/dist/esm/components/Messages/AccountDeployedMessage.js.map +1 -1
- package/dist/esm/components/Messages/AccountNotDeployedMessage.js.map +1 -1
- package/dist/esm/components/Messages/FundsSufficiencyMessage.js.map +1 -1
- package/dist/esm/components/Messages/GasRefuelMessage.js.map +1 -1
- package/dist/esm/components/Messages/GasSufficiencyMessage.js.map +1 -1
- package/dist/esm/components/Messages/MinFromAmountUSDMessage.js.map +1 -1
- package/dist/esm/components/Messages/MissingRouteRequiredAccountMessage.js.map +1 -1
- package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
- package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
- package/dist/esm/components/NotFound.js.map +1 -1
- package/dist/esm/components/PageEntered.js.map +1 -1
- package/dist/esm/components/PoweredBy/PoweredBy.js.map +1 -1
- package/dist/esm/components/ProgressToNextUpdate.js.map +1 -1
- package/dist/esm/components/ReverseTokensButton/ReverseTokensButton.js.map +1 -1
- package/dist/esm/components/ReverseTokensButton/ReverseTokensButton.style.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteCard.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteCardSkeleton.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteDetails.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteNotFoundCard.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteToken.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteTokens.js.map +1 -1
- package/dist/esm/components/RouteCard/getMatchingLabels.js +1 -0
- package/dist/esm/components/RouteCard/getMatchingLabels.js.map +1 -1
- package/dist/esm/components/Routes/Routes.js.map +1 -1
- package/dist/esm/components/Routes/RoutesContent.js.map +1 -1
- package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
- package/dist/esm/components/Routes/RoutesExpanded.style.js.map +1 -1
- package/dist/esm/components/Search/SearchInput.js.map +1 -1
- package/dist/esm/components/SelectChainAndToken.js.map +1 -1
- package/dist/esm/components/SelectTokenButton/SelectTokenButton.js.map +1 -1
- package/dist/esm/components/SelectTokenButton/SelectTokenButton.style.js.map +1 -1
- package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
- package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
- package/dist/esm/components/Skeleton/WidgetSkeleton.js.map +1 -1
- package/dist/esm/components/Skeleton/WidgetSkeleton.style.js.map +1 -1
- package/dist/esm/components/Step/CircularProgress.js.map +1 -1
- package/dist/esm/components/Step/CircularProgress.style.js.map +1 -1
- package/dist/esm/components/Step/DestinationWalletAddress.js.map +1 -1
- package/dist/esm/components/Step/Step.js.map +1 -1
- package/dist/esm/components/Step/StepAction.js.map +1 -1
- package/dist/esm/components/Step/StepActions.js.map +1 -1
- package/dist/esm/components/Step/StepList.js.map +1 -1
- package/dist/esm/components/StepActions/StepActions.js.map +1 -1
- package/dist/esm/components/StepDivider/StepDivider.js.map +1 -1
- package/dist/esm/components/TextFitter/TextFitter.js.map +1 -1
- package/dist/esm/components/Timer/StepTimer.js.map +1 -1
- package/dist/esm/components/Timer/TimerContent.js.map +1 -1
- package/dist/esm/components/Token/Token.js.map +1 -1
- package/dist/esm/components/TokenList/PinTokenButton.js.map +1 -1
- package/dist/esm/components/TokenList/TokenDetailsSheet.js.map +1 -1
- package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
- package/dist/esm/components/TokenList/TokenList.js.map +1 -1
- package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
- package/dist/esm/components/TokenList/TokenNotFound.js.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
- package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
- package/dist/esm/components/TokenRate/TokenRate.js.map +1 -1
- package/dist/esm/components/Tools/ToolItem.js.map +1 -1
- package/dist/esm/components/Tools/Tools.js.map +1 -1
- package/dist/esm/components/TransactionCard/ActiveTransactionCard.js.map +1 -1
- package/dist/esm/components/TransactionCard/TransactionCard.js.map +1 -1
- package/dist/esm/components/TransactionCard/TransactionCardSkeleton.js.map +1 -1
- package/dist/esm/components/TransactionDetails.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/timer/time.js.map +1 -1
- package/dist/esm/hooks/timer/useExecutionTimer.js.map +1 -1
- package/dist/esm/hooks/timer/useInterval.js.map +1 -1
- package/dist/esm/hooks/timer/useTimer.js.map +1 -1
- package/dist/esm/hooks/timer/validate.js.map +1 -1
- package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
- package/dist/esm/hooks/useActionMessage.js.map +1 -1
- package/dist/esm/hooks/useAddressActivity.js.map +1 -1
- package/dist/esm/hooks/useAddressValidation.js.map +1 -1
- package/dist/esm/hooks/useAvailableChains.js.map +1 -1
- package/dist/esm/hooks/useChain.js.map +1 -1
- package/dist/esm/hooks/useChains.js.map +1 -1
- package/dist/esm/hooks/useContactSupport.js.map +1 -1
- package/dist/esm/hooks/useDebouncedWatch.js.map +1 -1
- package/dist/esm/hooks/useDefaultElementId.js.map +1 -1
- package/dist/esm/hooks/useExplorer.js.map +1 -1
- package/dist/esm/hooks/useFilteredByTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useFromAmountThreshold.js.map +1 -1
- package/dist/esm/hooks/useFromTokenSufficiency.js.map +1 -1
- package/dist/esm/hooks/useGasRecommendation.js.map +1 -1
- package/dist/esm/hooks/useGasRefuel.js.map +1 -1
- package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
- package/dist/esm/hooks/useHasChainExpansion.js.map +1 -1
- package/dist/esm/hooks/useHeader.js.map +1 -1
- package/dist/esm/hooks/useInitializeSDKProviders.js.map +1 -1
- package/dist/esm/hooks/useInitializer.js.map +1 -1
- package/dist/esm/hooks/useIsBatchingSupported.js.map +1 -1
- package/dist/esm/hooks/useIsContractAddress.js.map +1 -1
- package/dist/esm/hooks/useLanguages.js.map +1 -1
- package/dist/esm/hooks/useListHeight.js.map +1 -1
- package/dist/esm/hooks/useLongPress.js.map +1 -1
- package/dist/esm/hooks/useNavigateBack.js.map +1 -1
- package/dist/esm/hooks/useRouteExecution.js.map +1 -1
- package/dist/esm/hooks/useRouteRequiredAccountConnection.js.map +1 -1
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useScrollableContainer.js.map +1 -1
- package/dist/esm/hooks/useSetContentHeight.js.map +1 -1
- package/dist/esm/hooks/useSettingMonitor.js.map +1 -1
- package/dist/esm/hooks/useSwapOnly.js.map +1 -1
- package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
- package/dist/esm/hooks/useToAddressReset.js.map +1 -1
- package/dist/esm/hooks/useToken.js.map +1 -1
- package/dist/esm/hooks/useTokenAddressBalance.js.map +1 -1
- package/dist/esm/hooks/useTokenBalance.js.map +1 -1
- package/dist/esm/hooks/useTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
- package/dist/esm/hooks/useTokenRateText.js.map +1 -1
- package/dist/esm/hooks/useTokenSearch.js.map +1 -1
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/hooks/useTools.js.map +1 -1
- package/dist/esm/hooks/useTransactionDetails.js.map +1 -1
- package/dist/esm/hooks/useTransactionHistory.js.map +1 -1
- package/dist/esm/hooks/useTransactionList.js.map +1 -1
- package/dist/esm/hooks/useWideVariant.js.map +1 -1
- package/dist/esm/hooks/useWidgetChains.js.map +1 -1
- package/dist/esm/hooks/useWidgetEvents.js.map +1 -1
- package/dist/esm/pages/ActivitiesPage/ActiveTransactionItem.js.map +1 -1
- package/dist/esm/pages/ActivitiesPage/ActivitiesPage.js.map +1 -1
- package/dist/esm/pages/ActivitiesPage/ActivitiesPageMenuButton.js.map +1 -1
- package/dist/esm/pages/ActivitiesPage/TransactionHistoryEmpty.js.map +1 -1
- package/dist/esm/pages/ActivitiesPage/TransactionHistoryItem.js.map +1 -1
- package/dist/esm/pages/LanguagesPage.js.map +1 -1
- package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
- package/dist/esm/pages/MainPage/MainWarningMessages.js.map +1 -1
- package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
- package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
- package/dist/esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
- package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
- package/dist/esm/pages/SelectTokenPage/SearchTokenInput.js.map +1 -1
- package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js.map +1 -1
- package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/ConfirmAddressSheet.js.map +1 -1
- package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
- package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/GasPriceSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/LanguageSetting.js.map +1 -1
- package/dist/esm/pages/SettingsPage/ResetSettingsButton.js.map +1 -1
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SettingsCard/SettingCardExpandable.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SettingsCard/SettingsAccordian.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/ActionRow.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/ReceiptsCard.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/SentToWalletRow.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/StepActionRow.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/StepActionsList.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsSkeleton.js.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/TransferIdCard.js.map +1 -1
- package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/RouteTracker.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TransactionPage.js.map +1 -1
- package/dist/esm/pages/TransactionPage/utils.js.map +1 -1
- package/dist/esm/providers/I18nProvider/I18nProvider.js.map +1 -1
- package/dist/esm/providers/I18nProvider/i18n.js.map +1 -1
- package/dist/esm/providers/QueryClientProvider.js.map +1 -1
- package/dist/esm/providers/SDKClientProvider.js.map +1 -1
- package/dist/esm/providers/ThemeProvider/ThemeProvider.js.map +1 -1
- package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
- package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/stores/StoreProvider.js.map +1 -1
- package/dist/esm/stores/bookmarks/BookmarkStore.js.map +1 -1
- package/dist/esm/stores/bookmarks/createBookmarkStore.js.map +1 -1
- package/dist/esm/stores/bookmarks/useBookmarkActions.js.map +1 -1
- package/dist/esm/stores/bookmarks/useBookmarks.js.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
- package/dist/esm/stores/chains/createChainOrderStore.js.map +1 -1
- package/dist/esm/stores/chains/useChainOrder.js.map +1 -1
- package/dist/esm/stores/form/FormStore.js.map +1 -1
- package/dist/esm/stores/form/FormUpdater.js.map +1 -1
- package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
- package/dist/esm/stores/form/createFormStore.js.map +1 -1
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
- package/dist/esm/stores/form/useFieldActions.js.map +1 -1
- package/dist/esm/stores/form/useFieldValues.js.map +1 -1
- package/dist/esm/stores/form/useFormRef.js.map +1 -1
- package/dist/esm/stores/form/useFormStore.js.map +1 -1
- package/dist/esm/stores/form/useTouchedFields.js.map +1 -1
- package/dist/esm/stores/header/useHeaderStore.js.map +1 -1
- package/dist/esm/stores/inputMode/useInputModeStore.js.map +1 -1
- package/dist/esm/stores/pinnedTokens/PinnedTokensStore.js.map +1 -1
- package/dist/esm/stores/pinnedTokens/createPinnedTokensStore.js.map +1 -1
- package/dist/esm/stores/routes/RouteExecutionStore.js.map +1 -1
- package/dist/esm/stores/routes/createRouteExecutionStore.js.map +1 -1
- package/dist/esm/stores/routes/useIntermediateRoutesStore.js.map +1 -1
- package/dist/esm/stores/routes/useRouteExecutionIndicator.js.map +1 -1
- package/dist/esm/stores/routes/useSetExecutableRoute.js.map +1 -1
- package/dist/esm/stores/routes/utils.js.map +1 -1
- package/dist/esm/stores/settings/SettingsStore.js.map +1 -1
- package/dist/esm/stores/settings/createSettingsStore.js.map +1 -1
- package/dist/esm/stores/settings/useSettings.js.map +1 -1
- package/dist/esm/stores/settings/useSettingsActions.js.map +1 -1
- package/dist/esm/stores/settings/useSplitSubvariantStore.js.map +1 -1
- package/dist/esm/themes/createTheme.js.map +1 -1
- package/dist/esm/themes/utils.js.map +1 -1
- package/dist/esm/types/events.js.map +1 -1
- package/dist/esm/types/widget.d.ts +9 -1
- package/dist/esm/types/widget.d.ts.map +1 -1
- package/dist/esm/types/widget.js.map +1 -1
- package/dist/esm/utils/compactNumberFormatter.js.map +1 -1
- package/dist/esm/utils/converters.js.map +1 -1
- package/dist/esm/utils/currencyExtendedFormatter.js.map +1 -1
- package/dist/esm/utils/deepEqual.js.map +1 -1
- package/dist/esm/utils/deepMerge.js.map +1 -1
- package/dist/esm/utils/fees.js.map +1 -1
- package/dist/esm/utils/format.js.map +1 -1
- package/dist/esm/utils/getActionMessage.js.map +1 -1
- package/dist/esm/utils/getErrorMessage.js.map +1 -1
- package/dist/esm/utils/getPriceImpact.js.map +1 -1
- package/dist/esm/utils/input.js.map +1 -1
- package/dist/esm/utils/item.js.map +1 -1
- package/dist/esm/utils/percentFormatter.js.map +1 -1
- package/dist/esm/utils/prepareActions.js.map +1 -1
- package/dist/esm/utils/timer.js.map +1 -1
- package/dist/esm/utils/token.js.map +1 -1
- package/dist/esm/utils/tokenList.js.map +1 -1
- package/dist/esm/utils/variant.js.map +1 -1
- package/dist/esm/utils/widgetSize.js.map +1 -1
- package/package.json +11 -11
- package/src/components/RouteCard/getMatchingLabels.ts +5 -0
- package/src/config/version.ts +1 -1
- package/src/types/widget.ts +9 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepActions.js","names":["StepConnector","MuiStep","StepLabel"],"sources":["../../../../src/components/StepActions/StepActions.tsx"],"sourcesContent":["import type { LiFiStep, StepExtended } from '@lifi/sdk'\nimport { useEthereumContext } from '@lifi/widget-provider'\nimport ArrowForward from '@mui/icons-material/ArrowForward'\nimport ExpandLess from '@mui/icons-material/ExpandLess'\nimport ExpandMore from '@mui/icons-material/ExpandMore'\nimport type { StepIconProps } from '@mui/material'\nimport {\n Badge,\n Box,\n Collapse,\n Step as MuiStep,\n Stepper,\n Typography,\n} from '@mui/material'\nimport type { MouseEventHandler } from 'react'\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { lifiLogoUrl } from '../../icons/lifi.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { HiddenUI } from '../../types/widget.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { SmallAvatar } from '../Avatar/SmallAvatar.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport {\n StepAvatar,\n StepConnector,\n StepContent,\n StepLabel,\n StepLabelTypography,\n} from './StepActions.style.js'\nimport type {\n IncludedStepsProps,\n StepActionsProps,\n StepDetailsLabelProps,\n} from './types.js'\n\nexport const StepActions: React.FC<StepActionsProps> = ({\n step,\n dense,\n ...other\n}) => {\n const { t } = useTranslation()\n const { subvariant } = useWidgetConfig()\n const [cardExpanded, setCardExpanded] = useState(false)\n\n const handleExpand: MouseEventHandler<HTMLButtonElement> = (e) => {\n e.stopPropagation()\n setCardExpanded((expanded) => !expanded)\n }\n\n // FIXME: step transaction request overrides step tool details, but not included step tool details\n const toolDetails =\n subvariant === 'custom'\n ? step.includedSteps.find(\n (step) => step.tool === 'custom' && step.toolDetails.key !== 'custom'\n )?.toolDetails || step.toolDetails\n : step.toolDetails\n\n return (\n <Box {...other}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n }}\n >\n <Badge\n overlap=\"circular\"\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n badgeContent={<SmallAvatar src={lifiLogoUrl} />}\n >\n <StepAvatar\n variant=\"circular\"\n src={toolDetails.logoURI ?? lifiLogoUrl}\n alt={toolDetails.name}\n >\n {toolDetails.name[0]}\n </StepAvatar>\n </Badge>\n <Box\n sx={{\n flex: 1,\n }}\n >\n <Typography\n sx={{\n fontSize: 18,\n fontWeight: 600,\n lineHeight: 1.3334,\n ml: 2,\n }}\n >\n {toolDetails.name?.includes('LI.FI')\n ? toolDetails.name\n : t('main.stepDetails', {\n tool: toolDetails.name,\n })}\n </Typography>\n {/* <StepFees ml={2} step={step} /> */}\n </Box>\n {dense ? (\n <CardIconButton onClick={handleExpand} size=\"small\">\n {cardExpanded ? (\n <ExpandLess fontSize=\"inherit\" />\n ) : (\n <ExpandMore fontSize=\"inherit\" />\n )}\n </CardIconButton>\n ) : null}\n </Box>\n {dense ? (\n <Collapse timeout={225} in={cardExpanded} mountOnEnter unmountOnExit>\n <IncludedSteps step={step} />\n </Collapse>\n ) : (\n <IncludedSteps step={step} />\n )}\n </Box>\n )\n}\n\nconst IncludedSteps: React.FC<IncludedStepsProps> = ({ step }) => {\n const { subvariant, subvariantOptions, feeConfig, hiddenUI } =\n useWidgetConfig()\n const { isGaslessStep } = useEthereumContext()\n\n let includedSteps = step.includedSteps\n if (hiddenUI?.includes(HiddenUI.IntegratorStepDetails)) {\n const feeCollectionStep = includedSteps.find(\n (step) => step.tool === 'feeCollection'\n )\n if (feeCollectionStep) {\n includedSteps = structuredClone(\n includedSteps.filter((step) => step.tool !== 'feeCollection')\n )\n includedSteps[0].estimate.fromAmount =\n feeCollectionStep.estimate.fromAmount\n }\n }\n\n // biome-ignore lint/correctness/noNestedComponentDefinitions: part of the flow\n const StepIconComponent = ({ icon }: StepIconProps) => {\n const includedStep = includedSteps?.[Number(icon) - 1]\n const feeCollectionStep =\n includedStep?.type === 'protocol' &&\n includedStep?.tool === 'feeCollection'\n const toolName =\n feeCollectionStep && feeConfig?.name\n ? feeConfig?.name\n : includedStep?.toolDetails.name\n const toolLogoURI =\n feeCollectionStep && feeConfig?.logoURI\n ? feeConfig?.logoURI\n : includedStep?.toolDetails.logoURI\n return toolLogoURI ? (\n <SmallAvatar\n src={toolLogoURI}\n alt={toolName}\n sx={{ width: 20, height: 20 }}\n >\n {toolName?.[0]}\n </SmallAvatar>\n ) : null\n }\n\n const hasGaslessSupport = !!isGaslessStep?.(step)\n\n return (\n <Box\n sx={{\n mt: 1,\n }}\n >\n <Stepper\n orientation=\"vertical\"\n connector={<StepConnector />}\n activeStep={-1}\n >\n {includedSteps.map((step, i, includedSteps) => (\n <MuiStep key={step.id} expanded>\n <StepLabel\n slots={{\n stepIcon: StepIconComponent,\n }}\n >\n {step.type === 'custom' && subvariant === 'custom' ? (\n <CustomStepDetailsLabel\n step={step}\n subvariant={subvariant}\n subvariantOptions={subvariantOptions}\n />\n ) : step.type === 'cross' ? (\n <BridgeStepDetailsLabel step={step} />\n ) : step.type === 'protocol' ? (\n <ProtocolStepDetailsLabel\n step={step}\n feeConfig={feeConfig}\n relayerSupport={hasGaslessSupport}\n />\n ) : (\n <SwapStepDetailsLabel step={step} />\n )}\n </StepLabel>\n <StepContent last={i === includedSteps.length - 1}>\n <StepDetailsContent step={step} />\n </StepContent>\n </MuiStep>\n ))}\n </Stepper>\n </Box>\n )\n}\n\nconst StepDetailsContent: React.FC<{\n step: StepExtended\n}> = ({ step }) => {\n const { t } = useTranslation()\n\n const sameTokenProtocolStep =\n step.action.fromToken.chainId === step.action.toToken.chainId &&\n step.action.fromToken.address === step.action.toToken.address\n\n let fromAmount: string | undefined\n if (sameTokenProtocolStep) {\n const estimatedFromAmount =\n BigInt(step.estimate.fromAmount) - BigInt(step.estimate.toAmount)\n\n fromAmount =\n estimatedFromAmount > 0n\n ? formatTokenAmount(estimatedFromAmount, step.action.fromToken.decimals)\n : formatTokenAmount(\n BigInt(step.estimate.fromAmount),\n step.action.fromToken.decimals\n )\n } else {\n fromAmount = formatTokenAmount(\n BigInt(step.estimate.fromAmount),\n step.action.fromToken.decimals\n )\n }\n\n const showToAmount =\n step.type !== 'custom' && step.tool !== 'custom' && !sameTokenProtocolStep\n\n return (\n <Typography\n sx={{\n fontSize: 12,\n lineHeight: 1,\n fontWeight: '500',\n color: 'text.secondary',\n alignItems: 'center',\n display: 'flex',\n }}\n >\n {!showToAmount ? (\n <>\n {t('format.tokenAmount', {\n value: formatTokenAmount(\n BigInt(step.estimate.fromAmount),\n step.action.fromToken.decimals\n ),\n })}{' '}\n {step.action.fromToken.symbol}\n {' - '}\n </>\n ) : null}\n {t('format.tokenAmount', {\n value: fromAmount,\n })}{' '}\n {step.action.fromToken.symbol}\n {showToAmount ? (\n <>\n <ArrowForward sx={{ fontSize: 18, paddingX: 0.5, height: 12 }} />\n {t('format.tokenAmount', {\n value: formatTokenAmount(\n BigInt(step.execution?.toAmount ?? step.estimate.toAmount),\n step.execution?.toToken?.decimals ?? step.action.toToken.decimals\n ),\n })}{' '}\n {step.execution?.toToken?.symbol ?? step.action.toToken.symbol}\n </>\n ) : (\n ` (${t('format.currency', {\n value: formatTokenPrice(\n fromAmount,\n step.action.fromToken.priceUSD,\n step.action.fromToken.decimals\n ),\n })})`\n )}\n </Typography>\n )\n}\n\nconst CustomStepDetailsLabel: React.FC<StepDetailsLabelProps> = ({\n step,\n subvariant,\n subvariantOptions,\n}) => {\n const { t } = useTranslation()\n\n if (!subvariant) {\n return null\n }\n\n // FIXME: step transaction request overrides step tool details, but not included step tool details\n const toolDetails =\n subvariant === 'custom' &&\n (step as unknown as LiFiStep).includedSteps?.length > 0\n ? (step as unknown as LiFiStep).includedSteps.find(\n (step) => step.tool === 'custom' && step.toolDetails.key !== 'custom'\n )?.toolDetails || step.toolDetails\n : step.toolDetails\n\n const stepDetailsKey =\n (subvariant === 'custom' && subvariantOptions?.custom) || 'checkout'\n\n return (\n <StepLabelTypography>\n {t(`main.${stepDetailsKey}StepDetails`, {\n tool: toolDetails.name,\n })}\n </StepLabelTypography>\n )\n}\n\nconst BridgeStepDetailsLabel: React.FC<\n Omit<StepDetailsLabelProps, 'variant'>\n> = ({ step }) => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n return (\n <StepLabelTypography>\n {t('main.bridgeStepDetails', {\n from: getChainById(step.action.fromChainId)?.name,\n to: getChainById(step.action.toChainId)?.name,\n tool: step.toolDetails.name,\n })}\n </StepLabelTypography>\n )\n}\n\nconst SwapStepDetailsLabel: React.FC<\n Omit<StepDetailsLabelProps, 'variant'>\n> = ({ step }) => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n return (\n <StepLabelTypography>\n {t('main.swapStepDetails', {\n chain: getChainById(step.action.fromChainId)?.name,\n tool: step.toolDetails.name,\n })}\n </StepLabelTypography>\n )\n}\n\nconst ProtocolStepDetailsLabel: React.FC<\n Omit<StepDetailsLabelProps, 'variant'>\n> = ({ step, feeConfig, relayerSupport }) => {\n const { t } = useTranslation()\n return (\n <StepLabelTypography>\n {step.toolDetails.key === 'feeCollection'\n ? feeConfig?.name ||\n (relayerSupport\n ? t('main.fees.relayerService')\n : t('main.fees.defaultIntegrator'))\n : step.toolDetails.key === 'gasZip'\n ? t('main.refuelStepDetails', {\n tool: step.toolDetails.name,\n })\n : step.toolDetails.name}\n </StepLabelTypography>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StepActions.js","names":["StepConnector","MuiStep","StepLabel"],"sources":["../../../../src/components/StepActions/StepActions.tsx"],"sourcesContent":["import type { LiFiStep, StepExtended } from '@lifi/sdk'\nimport { useEthereumContext } from '@lifi/widget-provider'\nimport ArrowForward from '@mui/icons-material/ArrowForward'\nimport ExpandLess from '@mui/icons-material/ExpandLess'\nimport ExpandMore from '@mui/icons-material/ExpandMore'\nimport type { StepIconProps } from '@mui/material'\nimport {\n Badge,\n Box,\n Collapse,\n Step as MuiStep,\n Stepper,\n Typography,\n} from '@mui/material'\nimport type { MouseEventHandler } from 'react'\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { lifiLogoUrl } from '../../icons/lifi.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { HiddenUI } from '../../types/widget.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { SmallAvatar } from '../Avatar/SmallAvatar.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport {\n StepAvatar,\n StepConnector,\n StepContent,\n StepLabel,\n StepLabelTypography,\n} from './StepActions.style.js'\nimport type {\n IncludedStepsProps,\n StepActionsProps,\n StepDetailsLabelProps,\n} from './types.js'\n\nexport const StepActions: React.FC<StepActionsProps> = ({\n step,\n dense,\n ...other\n}) => {\n const { t } = useTranslation()\n const { subvariant } = useWidgetConfig()\n const [cardExpanded, setCardExpanded] = useState(false)\n\n const handleExpand: MouseEventHandler<HTMLButtonElement> = (e) => {\n e.stopPropagation()\n setCardExpanded((expanded) => !expanded)\n }\n\n // FIXME: step transaction request overrides step tool details, but not included step tool details\n const toolDetails =\n subvariant === 'custom'\n ? step.includedSteps.find(\n (step) => step.tool === 'custom' && step.toolDetails.key !== 'custom'\n )?.toolDetails || step.toolDetails\n : step.toolDetails\n\n return (\n <Box {...other}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n }}\n >\n <Badge\n overlap=\"circular\"\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n badgeContent={<SmallAvatar src={lifiLogoUrl} />}\n >\n <StepAvatar\n variant=\"circular\"\n src={toolDetails.logoURI ?? lifiLogoUrl}\n alt={toolDetails.name}\n >\n {toolDetails.name[0]}\n </StepAvatar>\n </Badge>\n <Box\n sx={{\n flex: 1,\n }}\n >\n <Typography\n sx={{\n fontSize: 18,\n fontWeight: 600,\n lineHeight: 1.3334,\n ml: 2,\n }}\n >\n {toolDetails.name?.includes('LI.FI')\n ? toolDetails.name\n : t('main.stepDetails', {\n tool: toolDetails.name,\n })}\n </Typography>\n {/* <StepFees ml={2} step={step} /> */}\n </Box>\n {dense ? (\n <CardIconButton onClick={handleExpand} size=\"small\">\n {cardExpanded ? (\n <ExpandLess fontSize=\"inherit\" />\n ) : (\n <ExpandMore fontSize=\"inherit\" />\n )}\n </CardIconButton>\n ) : null}\n </Box>\n {dense ? (\n <Collapse timeout={225} in={cardExpanded} mountOnEnter unmountOnExit>\n <IncludedSteps step={step} />\n </Collapse>\n ) : (\n <IncludedSteps step={step} />\n )}\n </Box>\n )\n}\n\nconst IncludedSteps: React.FC<IncludedStepsProps> = ({ step }) => {\n const { subvariant, subvariantOptions, feeConfig, hiddenUI } =\n useWidgetConfig()\n const { isGaslessStep } = useEthereumContext()\n\n let includedSteps = step.includedSteps\n if (hiddenUI?.includes(HiddenUI.IntegratorStepDetails)) {\n const feeCollectionStep = includedSteps.find(\n (step) => step.tool === 'feeCollection'\n )\n if (feeCollectionStep) {\n includedSteps = structuredClone(\n includedSteps.filter((step) => step.tool !== 'feeCollection')\n )\n includedSteps[0].estimate.fromAmount =\n feeCollectionStep.estimate.fromAmount\n }\n }\n\n // biome-ignore lint/correctness/noNestedComponentDefinitions: part of the flow\n const StepIconComponent = ({ icon }: StepIconProps) => {\n const includedStep = includedSteps?.[Number(icon) - 1]\n const feeCollectionStep =\n includedStep?.type === 'protocol' &&\n includedStep?.tool === 'feeCollection'\n const toolName =\n feeCollectionStep && feeConfig?.name\n ? feeConfig?.name\n : includedStep?.toolDetails.name\n const toolLogoURI =\n feeCollectionStep && feeConfig?.logoURI\n ? feeConfig?.logoURI\n : includedStep?.toolDetails.logoURI\n return toolLogoURI ? (\n <SmallAvatar\n src={toolLogoURI}\n alt={toolName}\n sx={{ width: 20, height: 20 }}\n >\n {toolName?.[0]}\n </SmallAvatar>\n ) : null\n }\n\n const hasGaslessSupport = !!isGaslessStep?.(step)\n\n return (\n <Box\n sx={{\n mt: 1,\n }}\n >\n <Stepper\n orientation=\"vertical\"\n connector={<StepConnector />}\n activeStep={-1}\n >\n {includedSteps.map((step, i, includedSteps) => (\n <MuiStep key={step.id} expanded>\n <StepLabel\n slots={{\n stepIcon: StepIconComponent,\n }}\n >\n {step.type === 'custom' && subvariant === 'custom' ? (\n <CustomStepDetailsLabel\n step={step}\n subvariant={subvariant}\n subvariantOptions={subvariantOptions}\n />\n ) : step.type === 'cross' ? (\n <BridgeStepDetailsLabel step={step} />\n ) : step.type === 'protocol' ? (\n <ProtocolStepDetailsLabel\n step={step}\n feeConfig={feeConfig}\n relayerSupport={hasGaslessSupport}\n />\n ) : (\n <SwapStepDetailsLabel step={step} />\n )}\n </StepLabel>\n <StepContent last={i === includedSteps.length - 1}>\n <StepDetailsContent step={step} />\n </StepContent>\n </MuiStep>\n ))}\n </Stepper>\n </Box>\n )\n}\n\nconst StepDetailsContent: React.FC<{\n step: StepExtended\n}> = ({ step }) => {\n const { t } = useTranslation()\n\n const sameTokenProtocolStep =\n step.action.fromToken.chainId === step.action.toToken.chainId &&\n step.action.fromToken.address === step.action.toToken.address\n\n let fromAmount: string | undefined\n if (sameTokenProtocolStep) {\n const estimatedFromAmount =\n BigInt(step.estimate.fromAmount) - BigInt(step.estimate.toAmount)\n\n fromAmount =\n estimatedFromAmount > 0n\n ? formatTokenAmount(estimatedFromAmount, step.action.fromToken.decimals)\n : formatTokenAmount(\n BigInt(step.estimate.fromAmount),\n step.action.fromToken.decimals\n )\n } else {\n fromAmount = formatTokenAmount(\n BigInt(step.estimate.fromAmount),\n step.action.fromToken.decimals\n )\n }\n\n const showToAmount =\n step.type !== 'custom' && step.tool !== 'custom' && !sameTokenProtocolStep\n\n return (\n <Typography\n sx={{\n fontSize: 12,\n lineHeight: 1,\n fontWeight: '500',\n color: 'text.secondary',\n alignItems: 'center',\n display: 'flex',\n }}\n >\n {!showToAmount ? (\n <>\n {t('format.tokenAmount', {\n value: formatTokenAmount(\n BigInt(step.estimate.fromAmount),\n step.action.fromToken.decimals\n ),\n })}{' '}\n {step.action.fromToken.symbol}\n {' - '}\n </>\n ) : null}\n {t('format.tokenAmount', {\n value: fromAmount,\n })}{' '}\n {step.action.fromToken.symbol}\n {showToAmount ? (\n <>\n <ArrowForward sx={{ fontSize: 18, paddingX: 0.5, height: 12 }} />\n {t('format.tokenAmount', {\n value: formatTokenAmount(\n BigInt(step.execution?.toAmount ?? step.estimate.toAmount),\n step.execution?.toToken?.decimals ?? step.action.toToken.decimals\n ),\n })}{' '}\n {step.execution?.toToken?.symbol ?? step.action.toToken.symbol}\n </>\n ) : (\n ` (${t('format.currency', {\n value: formatTokenPrice(\n fromAmount,\n step.action.fromToken.priceUSD,\n step.action.fromToken.decimals\n ),\n })})`\n )}\n </Typography>\n )\n}\n\nconst CustomStepDetailsLabel: React.FC<StepDetailsLabelProps> = ({\n step,\n subvariant,\n subvariantOptions,\n}) => {\n const { t } = useTranslation()\n\n if (!subvariant) {\n return null\n }\n\n // FIXME: step transaction request overrides step tool details, but not included step tool details\n const toolDetails =\n subvariant === 'custom' &&\n (step as unknown as LiFiStep).includedSteps?.length > 0\n ? (step as unknown as LiFiStep).includedSteps.find(\n (step) => step.tool === 'custom' && step.toolDetails.key !== 'custom'\n )?.toolDetails || step.toolDetails\n : step.toolDetails\n\n const stepDetailsKey =\n (subvariant === 'custom' && subvariantOptions?.custom) || 'checkout'\n\n return (\n <StepLabelTypography>\n {t(`main.${stepDetailsKey}StepDetails`, {\n tool: toolDetails.name,\n })}\n </StepLabelTypography>\n )\n}\n\nconst BridgeStepDetailsLabel: React.FC<\n Omit<StepDetailsLabelProps, 'variant'>\n> = ({ step }) => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n return (\n <StepLabelTypography>\n {t('main.bridgeStepDetails', {\n from: getChainById(step.action.fromChainId)?.name,\n to: getChainById(step.action.toChainId)?.name,\n tool: step.toolDetails.name,\n })}\n </StepLabelTypography>\n )\n}\n\nconst SwapStepDetailsLabel: React.FC<\n Omit<StepDetailsLabelProps, 'variant'>\n> = ({ step }) => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n return (\n <StepLabelTypography>\n {t('main.swapStepDetails', {\n chain: getChainById(step.action.fromChainId)?.name,\n tool: step.toolDetails.name,\n })}\n </StepLabelTypography>\n )\n}\n\nconst ProtocolStepDetailsLabel: React.FC<\n Omit<StepDetailsLabelProps, 'variant'>\n> = ({ step, feeConfig, relayerSupport }) => {\n const { t } = useTranslation()\n return (\n <StepLabelTypography>\n {step.toolDetails.key === 'feeCollection'\n ? feeConfig?.name ||\n (relayerSupport\n ? t('main.fees.relayerService')\n : t('main.fees.defaultIntegrator'))\n : step.toolDetails.key === 'gasZip'\n ? t('main.refuelStepDetails', {\n tool: step.toolDetails.name,\n })\n : step.toolDetails.name}\n </StepLabelTypography>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqCA,MAAa,eAA2C,EACtD,MACA,OACA,GAAG,YACC;CACJ,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,eAAe,iBAAiB;CACxC,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;CAEvD,MAAM,gBAAsD,MAAM;EAChE,EAAE,iBAAiB;EACnB,iBAAiB,aAAa,CAAC,SAAS;;CAI1C,MAAM,cACJ,eAAe,WACX,KAAK,cAAc,MAChB,SAAS,KAAK,SAAS,YAAY,KAAK,YAAY,QAAQ,SAC9D,EAAE,eAAe,KAAK,cACvB,KAAK;CAEX,OACE,qBAAC,KAAD;EAAK,GAAI;YAAT,CACE,qBAAC,KAAD;GACE,IAAI;IACF,SAAS;IACT,YAAY;IACb;aAJH;IAME,oBAAC,OAAD;KACE,SAAQ;KACR,cAAc;MAAE,UAAU;MAAU,YAAY;MAAS;KACzD,cAAc,oBAAC,aAAD,EAAa,KAAK,aAAe,CAAA;eAE/C,oBAAC,YAAD;MACE,SAAQ;MACR,KAAK,YAAY,WAAA;MACjB,KAAK,YAAY;gBAEhB,YAAY,KAAK;MACP,CAAA;KACP,CAAA;IACR,oBAAC,KAAD;KACE,IAAI,EACF,MAAM,GACP;eAED,oBAAC,YAAD;MACE,IAAI;OACF,UAAU;OACV,YAAY;OACZ,YAAY;OACZ,IAAI;OACL;gBAEA,YAAY,MAAM,SAAS,QAAQ,GAChC,YAAY,OACZ,EAAE,oBAAoB,EACpB,MAAM,YAAY,MACnB,CAAC;MACK,CAAA;KAET,CAAA;IACL,QACC,oBAAC,gBAAD;KAAgB,SAAS;KAAc,MAAK;eACzC,eACC,oBAAC,YAAD,EAAY,UAAS,WAAY,CAAA,GAEjC,oBAAC,YAAD,EAAY,UAAS,WAAY,CAAA;KAEpB,CAAA,GACf;IACA;MACL,QACC,oBAAC,UAAD;GAAU,SAAS;GAAK,IAAI;GAAc,cAAA;GAAa,eAAA;aACrD,oBAAC,eAAD,EAAqB,MAAQ,CAAA;GACpB,CAAA,GAEX,oBAAC,eAAD,EAAqB,MAAQ,CAAA,CAE3B;;;AAIV,MAAM,iBAA+C,EAAE,WAAW;CAChE,MAAM,EAAE,YAAY,mBAAmB,WAAW,aAChD,iBAAiB;CACnB,MAAM,EAAE,kBAAkB,oBAAoB;CAE9C,IAAI,gBAAgB,KAAK;CACzB,IAAI,UAAU,SAAA,wBAAwC,EAAE;EACtD,MAAM,oBAAoB,cAAc,MACrC,SAAS,KAAK,SAAS,gBACzB;EACD,IAAI,mBAAmB;GACrB,gBAAgB,gBACd,cAAc,QAAQ,SAAS,KAAK,SAAS,gBAAgB,CAC9D;GACD,cAAc,GAAG,SAAS,aACxB,kBAAkB,SAAS;;;CAKjC,MAAM,qBAAqB,EAAE,WAA0B;EACrD,MAAM,eAAe,gBAAgB,OAAO,KAAK,GAAG;EACpD,MAAM,oBACJ,cAAc,SAAS,cACvB,cAAc,SAAS;EACzB,MAAM,WACJ,qBAAqB,WAAW,OAC5B,WAAW,OACX,cAAc,YAAY;EAChC,MAAM,cACJ,qBAAqB,WAAW,UAC5B,WAAW,UACX,cAAc,YAAY;EAChC,OAAO,cACL,oBAAC,aAAD;GACE,KAAK;GACL,KAAK;GACL,IAAI;IAAE,OAAO;IAAI,QAAQ;IAAI;aAE5B,WAAW;GACA,CAAA,GACZ;;CAGN,MAAM,oBAAoB,CAAC,CAAC,gBAAgB,KAAK;CAEjD,OACE,oBAAC,KAAD;EACE,IAAI,EACF,IAAI,GACL;YAED,oBAAC,SAAD;GACE,aAAY;GACZ,WAAW,oBAACA,iBAAD,EAAiB,CAAA;GAC5B,YAAY;aAEX,cAAc,KAAK,MAAM,GAAG,kBAC3B,qBAACC,MAAD;IAAuB,UAAA;cAAvB,CACE,oBAACC,aAAD;KACE,OAAO,EACL,UAAU,mBACX;eAEA,KAAK,SAAS,YAAY,eAAe,WACxC,oBAAC,wBAAD;MACQ;MACM;MACO;MACnB,CAAA,GACA,KAAK,SAAS,UAChB,oBAAC,wBAAD,EAA8B,MAAQ,CAAA,GACpC,KAAK,SAAS,aAChB,oBAAC,0BAAD;MACQ;MACK;MACX,gBAAgB;MAChB,CAAA,GAEF,oBAAC,sBAAD,EAA4B,MAAQ,CAAA;KAE5B,CAAA,EACZ,oBAAC,aAAD;KAAa,MAAM,MAAM,cAAc,SAAS;eAC9C,oBAAC,oBAAD,EAA0B,MAAQ,CAAA;KACtB,CAAA,CACN;MA3BI,KAAK,GA2BT,CACV;GACM,CAAA;EACN,CAAA;;AAIV,MAAM,sBAEA,EAAE,WAAW;CACjB,MAAM,EAAE,MAAM,gBAAgB;CAE9B,MAAM,wBACJ,KAAK,OAAO,UAAU,YAAY,KAAK,OAAO,QAAQ,WACtD,KAAK,OAAO,UAAU,YAAY,KAAK,OAAO,QAAQ;CAExD,IAAI;CACJ,IAAI,uBAAuB;EACzB,MAAM,sBACJ,OAAO,KAAK,SAAS,WAAW,GAAG,OAAO,KAAK,SAAS,SAAS;EAEnE,aACE,sBAAsB,KAClB,kBAAkB,qBAAqB,KAAK,OAAO,UAAU,SAAS,GACtE,kBACE,OAAO,KAAK,SAAS,WAAW,EAChC,KAAK,OAAO,UAAU,SACvB;QAEP,aAAa,kBACX,OAAO,KAAK,SAAS,WAAW,EAChC,KAAK,OAAO,UAAU,SACvB;CAGH,MAAM,eACJ,KAAK,SAAS,YAAY,KAAK,SAAS,YAAY,CAAC;CAEvD,OACE,qBAAC,YAAD;EACE,IAAI;GACF,UAAU;GACV,YAAY;GACZ,YAAY;GACZ,OAAO;GACP,YAAY;GACZ,SAAS;GACV;YARH;GAUG,CAAC,eACA,qBAAA,YAAA,EAAA,UAAA;IACG,EAAE,sBAAsB,EACvB,OAAO,kBACL,OAAO,KAAK,SAAS,WAAW,EAChC,KAAK,OAAO,UAAU,SACvB,EACF,CAAC;IAAE;IACH,KAAK,OAAO,UAAU;IACtB;IACA,EAAA,CAAA,GACD;GACH,EAAE,sBAAsB,EACvB,OAAO,YACR,CAAC;GAAE;GACH,KAAK,OAAO,UAAU;GACtB,eACC,qBAAA,YAAA,EAAA,UAAA;IACE,oBAAC,cAAD,EAAc,IAAI;KAAE,UAAU;KAAI,UAAU;KAAK,QAAQ;KAAI,EAAI,CAAA;IAChE,EAAE,sBAAsB,EACvB,OAAO,kBACL,OAAO,KAAK,WAAW,YAAY,KAAK,SAAS,SAAS,EAC1D,KAAK,WAAW,SAAS,YAAY,KAAK,OAAO,QAAQ,SAC1D,EACF,CAAC;IAAE;IACH,KAAK,WAAW,SAAS,UAAU,KAAK,OAAO,QAAQ;IACvD,EAAA,CAAA,GAEH,KAAK,EAAE,mBAAmB,EACxB,OAAO,iBACL,YACA,KAAK,OAAO,UAAU,UACtB,KAAK,OAAO,UAAU,SACvB,EACF,CAAC,CAAC;GAEM;;;AAIjB,MAAM,0BAA2D,EAC/D,MACA,YACA,wBACI;CACJ,MAAM,EAAE,MAAM,gBAAgB;CAE9B,IAAI,CAAC,YACH,OAAO;CAIT,MAAM,cACJ,eAAe,YACd,KAA6B,eAAe,SAAS,IACjD,KAA6B,cAAc,MACzC,SAAS,KAAK,SAAS,YAAY,KAAK,YAAY,QAAQ,SAC9D,EAAE,eAAe,KAAK,cACvB,KAAK;CAKX,OACE,oBAAC,qBAAD,EAAA,UACG,EAAE,QAJJ,eAAe,YAAY,mBAAmB,UAAW,WAI9B,cAAc,EACtC,MAAM,YAAY,MACnB,CAAC,EACkB,CAAA;;AAI1B,MAAM,0BAED,EAAE,WAAW;CAChB,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,iBAAiB,oBAAoB;CAC7C,OACE,oBAAC,qBAAD,EAAA,UACG,EAAE,0BAA0B;EAC3B,MAAM,aAAa,KAAK,OAAO,YAAY,EAAE;EAC7C,IAAI,aAAa,KAAK,OAAO,UAAU,EAAE;EACzC,MAAM,KAAK,YAAY;EACxB,CAAC,EACkB,CAAA;;AAI1B,MAAM,wBAED,EAAE,WAAW;CAChB,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,iBAAiB,oBAAoB;CAC7C,OACE,oBAAC,qBAAD,EAAA,UACG,EAAE,wBAAwB;EACzB,OAAO,aAAa,KAAK,OAAO,YAAY,EAAE;EAC9C,MAAM,KAAK,YAAY;EACxB,CAAC,EACkB,CAAA;;AAI1B,MAAM,4BAED,EAAE,MAAM,WAAW,qBAAqB;CAC3C,MAAM,EAAE,MAAM,gBAAgB;CAC9B,OACE,oBAAC,qBAAD,EAAA,UACG,KAAK,YAAY,QAAQ,kBACtB,WAAW,SACV,iBACG,EAAE,2BAA2B,GAC7B,EAAE,8BAA8B,IACpC,KAAK,YAAY,QAAQ,WACvB,EAAE,0BAA0B,EAC1B,MAAM,KAAK,YAAY,MACxB,CAAC,GACF,KAAK,YAAY,MACH,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepDivider.js","names":["Container"],"sources":["../../../../src/components/StepDivider/StepDivider.tsx"],"sourcesContent":["import { Divider } from '@mui/material'\nimport { Container } from './StepDivider.style.js'\n\nexport const StepDivider: React.FC = () => {\n return (\n <Container>\n <Divider orientation=\"vertical\" flexItem />\n </Container>\n )\n}\n"],"mappings":";;;;AAGA,MAAa,oBAA8B;
|
|
1
|
+
{"version":3,"file":"StepDivider.js","names":["Container"],"sources":["../../../../src/components/StepDivider/StepDivider.tsx"],"sourcesContent":["import { Divider } from '@mui/material'\nimport { Container } from './StepDivider.style.js'\n\nexport const StepDivider: React.FC = () => {\n return (\n <Container>\n <Divider orientation=\"vertical\" flexItem />\n </Container>\n )\n}\n"],"mappings":";;;;AAGA,MAAa,oBAA8B;CACzC,OACE,oBAACA,aAAD,EAAA,UACE,oBAAC,SAAD;EAAS,aAAY;EAAW,UAAA;EAAW,CAAA,EACjC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextFitter.js","names":[],"sources":["../../../../src/components/TextFitter/TextFitter.tsx"],"sourcesContent":["import { useTheme } from '@mui/material'\nimport type { PropsWithChildren } from 'react'\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react'\nimport { useInView } from 'react-intersection-observer'\nimport type { TextFitterProps } from './types.js'\n\nconst initialState = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n}\n\nexport const TextFitter: React.FC<PropsWithChildren<TextFitterProps>> = ({\n children,\n width = '100%',\n height,\n preserveAspectRatio = 'xMinYMid meet',\n textStyle,\n svgStyle,\n cropTop,\n cropBottom,\n onFit,\n}) => {\n const theme = useTheme()\n const textRef = useRef<SVGTextElement>(null)\n const [viewBox, setViewBox] = useState<Partial<DOMRect>>(initialState)\n\n const [ref] = useInView({\n onChange(inView) {\n if (inView) {\n calculateBox()\n }\n },\n })\n\n const calculateBox = useCallback(() => {\n if (!textRef.current) {\n return\n }\n const box = textRef.current.getBBox()\n if (cropTop) {\n box.y += box.height * cropTop\n box.height -= box.height * cropTop\n }\n if (cropBottom) {\n box.height -= box.height * cropBottom\n }\n setViewBox(box)\n onFit?.()\n }, [cropBottom, cropTop, onFit])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when children changes\n useLayoutEffect(() => {\n calculateBox()\n }, [calculateBox, children])\n\n useLayoutEffect(() => {\n if (document.fonts) {\n document.fonts.ready.then(() => {\n calculateBox()\n })\n }\n }, [calculateBox])\n\n return (\n <svg\n style={svgStyle}\n viewBox={`${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`}\n width={width}\n height={height}\n // height={\n // textRect.height && maxHeight && textRect.height >= maxHeight\n // ? maxHeight\n // : height\n // }\n preserveAspectRatio={preserveAspectRatio}\n fill={theme.vars.palette.text.primary}\n ref={ref}\n >\n <title>{children}</title>\n <text x={0} y={0} style={textStyle} ref={textRef}>\n {children}\n </text>\n </svg>\n )\n}\n"],"mappings":";;;;;AAMA,MAAM,eAAe;CACnB,GAAG;CACH,GAAG;CACH,OAAO;CACP,QAAQ;CACT;AAED,MAAa,cAA4D,EACvE,UACA,QAAQ,QACR,QACA,sBAAsB,iBACtB,WACA,UACA,SACA,YACA,YACI;CACJ,MAAM,QAAQ,UAAU;CACxB,MAAM,UAAU,OAAuB,KAAK;CAC5C,MAAM,CAAC,SAAS,cAAc,SAA2B,aAAa;CAEtE,MAAM,CAAC,OAAO,UAAU,EACtB,SAAS,QAAQ;
|
|
1
|
+
{"version":3,"file":"TextFitter.js","names":[],"sources":["../../../../src/components/TextFitter/TextFitter.tsx"],"sourcesContent":["import { useTheme } from '@mui/material'\nimport type { PropsWithChildren } from 'react'\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react'\nimport { useInView } from 'react-intersection-observer'\nimport type { TextFitterProps } from './types.js'\n\nconst initialState = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n}\n\nexport const TextFitter: React.FC<PropsWithChildren<TextFitterProps>> = ({\n children,\n width = '100%',\n height,\n preserveAspectRatio = 'xMinYMid meet',\n textStyle,\n svgStyle,\n cropTop,\n cropBottom,\n onFit,\n}) => {\n const theme = useTheme()\n const textRef = useRef<SVGTextElement>(null)\n const [viewBox, setViewBox] = useState<Partial<DOMRect>>(initialState)\n\n const [ref] = useInView({\n onChange(inView) {\n if (inView) {\n calculateBox()\n }\n },\n })\n\n const calculateBox = useCallback(() => {\n if (!textRef.current) {\n return\n }\n const box = textRef.current.getBBox()\n if (cropTop) {\n box.y += box.height * cropTop\n box.height -= box.height * cropTop\n }\n if (cropBottom) {\n box.height -= box.height * cropBottom\n }\n setViewBox(box)\n onFit?.()\n }, [cropBottom, cropTop, onFit])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when children changes\n useLayoutEffect(() => {\n calculateBox()\n }, [calculateBox, children])\n\n useLayoutEffect(() => {\n if (document.fonts) {\n document.fonts.ready.then(() => {\n calculateBox()\n })\n }\n }, [calculateBox])\n\n return (\n <svg\n style={svgStyle}\n viewBox={`${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`}\n width={width}\n height={height}\n // height={\n // textRect.height && maxHeight && textRect.height >= maxHeight\n // ? maxHeight\n // : height\n // }\n preserveAspectRatio={preserveAspectRatio}\n fill={theme.vars.palette.text.primary}\n ref={ref}\n >\n <title>{children}</title>\n <text x={0} y={0} style={textStyle} ref={textRef}>\n {children}\n </text>\n </svg>\n )\n}\n"],"mappings":";;;;;AAMA,MAAM,eAAe;CACnB,GAAG;CACH,GAAG;CACH,OAAO;CACP,QAAQ;CACT;AAED,MAAa,cAA4D,EACvE,UACA,QAAQ,QACR,QACA,sBAAsB,iBACtB,WACA,UACA,SACA,YACA,YACI;CACJ,MAAM,QAAQ,UAAU;CACxB,MAAM,UAAU,OAAuB,KAAK;CAC5C,MAAM,CAAC,SAAS,cAAc,SAA2B,aAAa;CAEtE,MAAM,CAAC,OAAO,UAAU,EACtB,SAAS,QAAQ;EACf,IAAI,QACF,cAAc;IAGnB,CAAC;CAEF,MAAM,eAAe,kBAAkB;EACrC,IAAI,CAAC,QAAQ,SACX;EAEF,MAAM,MAAM,QAAQ,QAAQ,SAAS;EACrC,IAAI,SAAS;GACX,IAAI,KAAK,IAAI,SAAS;GACtB,IAAI,UAAU,IAAI,SAAS;;EAE7B,IAAI,YACF,IAAI,UAAU,IAAI,SAAS;EAE7B,WAAW,IAAI;EACf,SAAS;IACR;EAAC;EAAY;EAAS;EAAM,CAAC;CAGhC,sBAAsB;EACpB,cAAc;IACb,CAAC,cAAc,SAAS,CAAC;CAE5B,sBAAsB;EACpB,IAAI,SAAS,OACX,SAAS,MAAM,MAAM,WAAW;GAC9B,cAAc;IACd;IAEH,CAAC,aAAa,CAAC;CAElB,OACE,qBAAC,OAAD;EACE,OAAO;EACP,SAAS,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,MAAM,GAAG,QAAQ;EACxD;EACC;EAMa;EACrB,MAAM,MAAM,KAAK,QAAQ,KAAK;EACzB;YAZP,CAcE,oBAAC,SAAD,EAAQ,UAAiB,CAAA,EACzB,oBAAC,QAAD;GAAM,GAAG;GAAG,GAAG;GAAG,OAAO;GAAW,KAAK;GACtC;GACI,CAAA,CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepTimer.js","names":[],"sources":["../../../../src/components/Timer/StepTimer.tsx"],"sourcesContent":["import type { LiFiStepExtended } from '@lifi/sdk'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useExecutionTimer } from '../../hooks/timer/useExecutionTimer.js'\nimport { TimerContent } from './TimerContent.js'\n\nexport const getExpiryTimestamp = (step: LiFiStepExtended): Date => {\n const execution = step?.execution\n if (!execution) {\n return new Date()\n }\n const expiry = new Date(\n (execution.signedAt ?? Date.now()) + step.estimate.executionDuration * 1000\n )\n return expiry\n}\n\nexport const StepTimer: React.FC<{\n step: LiFiStepExtended\n hideInProgress?: boolean\n}> = ({ step, hideInProgress }) => {\n const { i18n } = useTranslation()\n\n if (\n step.execution?.status === 'DONE' ||\n step.execution?.status === 'FAILED'\n ) {\n return null\n }\n\n if (!step.execution?.signedAt) {\n const showSeconds = step.estimate.executionDuration < 60\n const duration = showSeconds\n ? Math.floor(step.estimate.executionDuration)\n : Math.floor(step.estimate.executionDuration / 60)\n return (\n <TimerContent>\n {duration.toLocaleString(i18n.language, {\n style: 'unit',\n unit: showSeconds ? 'second' : 'minute',\n unitDisplay: 'narrow',\n })}\n </TimerContent>\n )\n }\n\n return (\n <ExecutionTimer\n expiryTimestamp={getExpiryTimestamp(step)}\n hideInProgress={hideInProgress}\n />\n )\n}\n\nexport const ExecutionTimerText = ({\n expiryTimestamp,\n}: {\n expiryTimestamp: Date\n}): string | null => {\n const { formatted } = useExecutionTimer(expiryTimestamp)\n return formatted\n}\n\nexport const ExecutionTimer = ({\n expiryTimestamp,\n hideInProgress,\n}: {\n expiryTimestamp: Date\n hideInProgress?: boolean\n}): JSX.Element | string | null => {\n const { t } = useTranslation()\n const { formatted, isTimerExpired } = useExecutionTimer(expiryTimestamp)\n\n if (isTimerExpired) {\n if (hideInProgress) {\n return null\n }\n return t('main.inProgress')\n }\n\n return <TimerContent>{formatted}</TimerContent>\n}\n"],"mappings":";;;;;AAMA,MAAa,sBAAsB,SAAiC;CAClE,MAAM,YAAY,MAAM;
|
|
1
|
+
{"version":3,"file":"StepTimer.js","names":[],"sources":["../../../../src/components/Timer/StepTimer.tsx"],"sourcesContent":["import type { LiFiStepExtended } from '@lifi/sdk'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useExecutionTimer } from '../../hooks/timer/useExecutionTimer.js'\nimport { TimerContent } from './TimerContent.js'\n\nexport const getExpiryTimestamp = (step: LiFiStepExtended): Date => {\n const execution = step?.execution\n if (!execution) {\n return new Date()\n }\n const expiry = new Date(\n (execution.signedAt ?? Date.now()) + step.estimate.executionDuration * 1000\n )\n return expiry\n}\n\nexport const StepTimer: React.FC<{\n step: LiFiStepExtended\n hideInProgress?: boolean\n}> = ({ step, hideInProgress }) => {\n const { i18n } = useTranslation()\n\n if (\n step.execution?.status === 'DONE' ||\n step.execution?.status === 'FAILED'\n ) {\n return null\n }\n\n if (!step.execution?.signedAt) {\n const showSeconds = step.estimate.executionDuration < 60\n const duration = showSeconds\n ? Math.floor(step.estimate.executionDuration)\n : Math.floor(step.estimate.executionDuration / 60)\n return (\n <TimerContent>\n {duration.toLocaleString(i18n.language, {\n style: 'unit',\n unit: showSeconds ? 'second' : 'minute',\n unitDisplay: 'narrow',\n })}\n </TimerContent>\n )\n }\n\n return (\n <ExecutionTimer\n expiryTimestamp={getExpiryTimestamp(step)}\n hideInProgress={hideInProgress}\n />\n )\n}\n\nexport const ExecutionTimerText = ({\n expiryTimestamp,\n}: {\n expiryTimestamp: Date\n}): string | null => {\n const { formatted } = useExecutionTimer(expiryTimestamp)\n return formatted\n}\n\nexport const ExecutionTimer = ({\n expiryTimestamp,\n hideInProgress,\n}: {\n expiryTimestamp: Date\n hideInProgress?: boolean\n}): JSX.Element | string | null => {\n const { t } = useTranslation()\n const { formatted, isTimerExpired } = useExecutionTimer(expiryTimestamp)\n\n if (isTimerExpired) {\n if (hideInProgress) {\n return null\n }\n return t('main.inProgress')\n }\n\n return <TimerContent>{formatted}</TimerContent>\n}\n"],"mappings":";;;;;AAMA,MAAa,sBAAsB,SAAiC;CAClE,MAAM,YAAY,MAAM;CACxB,IAAI,CAAC,WACH,uBAAO,IAAI,MAAM;CAKnB,OAAO,IAHY,MAChB,UAAU,YAAY,KAAK,KAAK,IAAI,KAAK,SAAS,oBAAoB,IAE5D;;AAGf,MAAa,aAGP,EAAE,MAAM,qBAAqB;CACjC,MAAM,EAAE,SAAS,gBAAgB;CAEjC,IACE,KAAK,WAAW,WAAW,UAC3B,KAAK,WAAW,WAAW,UAE3B,OAAO;CAGT,IAAI,CAAC,KAAK,WAAW,UAAU;EAC7B,MAAM,cAAc,KAAK,SAAS,oBAAoB;EAItD,OACE,oBAAC,cAAD,EAAA,WAJe,cACb,KAAK,MAAM,KAAK,SAAS,kBAAkB,GAC3C,KAAK,MAAM,KAAK,SAAS,oBAAoB,GAAG,EAGtC,eAAe,KAAK,UAAU;GACtC,OAAO;GACP,MAAM,cAAc,WAAW;GAC/B,aAAa;GACd,CAAC,EACW,CAAA;;CAInB,OACE,oBAAC,gBAAD;EACE,iBAAiB,mBAAmB,KAAK;EACzB;EAChB,CAAA;;AAIN,MAAa,sBAAsB,EACjC,sBAGmB;CACnB,MAAM,EAAE,cAAc,kBAAkB,gBAAgB;CACxD,OAAO;;AAGT,MAAa,kBAAkB,EAC7B,iBACA,qBAIiC;CACjC,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,WAAW,mBAAmB,kBAAkB,gBAAgB;CAExE,IAAI,gBAAgB;EAClB,IAAI,gBACF,OAAO;EAET,OAAO,EAAE,kBAAkB;;CAG7B,OAAO,oBAAC,cAAD,EAAA,UAAe,WAAyB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimerContent.js","names":[],"sources":["../../../../src/components/Timer/TimerContent.tsx"],"sourcesContent":["import AccessTimeFilled from '@mui/icons-material/AccessTimeFilled'\nimport { Box, Tooltip } from '@mui/material'\nimport type { FC, PropsWithChildren } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { IconTypography } from '../IconTypography.js'\n\nexport const TimerContent: FC<PropsWithChildren> = ({ children }) => {\n const { t } = useTranslation()\n return (\n <Tooltip title={t('tooltip.estimatedTime')} sx={{ cursor: 'help' }}>\n <Box\n component=\"span\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n height: 14,\n }}\n >\n <IconTypography\n component=\"span\"\n sx={{ marginRight: 0.5, fontSize: 16, display: 'inline-flex' }}\n >\n <AccessTimeFilled fontSize=\"inherit\" />\n </IconTypography>\n <Box\n component=\"span\"\n sx={{\n fontVariantNumeric: 'tabular-nums',\n cursor: 'help',\n }}\n >\n {children}\n </Box>\n </Box>\n </Tooltip>\n )\n}\n"],"mappings":";;;;;;AAMA,MAAa,gBAAuC,EAAE,eAAe;CACnE,MAAM,EAAE,MAAM,gBAAgB;
|
|
1
|
+
{"version":3,"file":"TimerContent.js","names":[],"sources":["../../../../src/components/Timer/TimerContent.tsx"],"sourcesContent":["import AccessTimeFilled from '@mui/icons-material/AccessTimeFilled'\nimport { Box, Tooltip } from '@mui/material'\nimport type { FC, PropsWithChildren } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { IconTypography } from '../IconTypography.js'\n\nexport const TimerContent: FC<PropsWithChildren> = ({ children }) => {\n const { t } = useTranslation()\n return (\n <Tooltip title={t('tooltip.estimatedTime')} sx={{ cursor: 'help' }}>\n <Box\n component=\"span\"\n sx={{\n display: 'flex',\n alignItems: 'center',\n height: 14,\n }}\n >\n <IconTypography\n component=\"span\"\n sx={{ marginRight: 0.5, fontSize: 16, display: 'inline-flex' }}\n >\n <AccessTimeFilled fontSize=\"inherit\" />\n </IconTypography>\n <Box\n component=\"span\"\n sx={{\n fontVariantNumeric: 'tabular-nums',\n cursor: 'help',\n }}\n >\n {children}\n </Box>\n </Box>\n </Tooltip>\n )\n}\n"],"mappings":";;;;;;AAMA,MAAa,gBAAuC,EAAE,eAAe;CACnE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,OACE,oBAAC,SAAD;EAAS,OAAO,EAAE,wBAAwB;EAAE,IAAI,EAAE,QAAQ,QAAQ;YAChE,qBAAC,KAAD;GACE,WAAU;GACV,IAAI;IACF,SAAS;IACT,YAAY;IACZ,QAAQ;IACT;aANH,CAQE,oBAAC,gBAAD;IACE,WAAU;IACV,IAAI;KAAE,aAAa;KAAK,UAAU;KAAI,SAAS;KAAe;cAE9D,oBAAC,kBAAD,EAAkB,UAAS,WAAY,CAAA;IACxB,CAAA,EACjB,oBAAC,KAAD;IACE,WAAU;IACV,IAAI;KACF,oBAAoB;KACpB,QAAQ;KACT;IAEA;IACG,CAAA,CACF;;EACE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Token.js","names":[],"sources":["../../../../src/components/Token/Token.tsx"],"sourcesContent":["import type { LiFiStep, TokenAmount } from '@lifi/sdk'\nimport type { BoxProps } from '@mui/material'\nimport { Box, Grow, Skeleton, Tooltip } from '@mui/material'\nimport type { FC, PropsWithChildren, ReactElement } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useChain } from '../../hooks/useChain.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { getPriceImpact } from '../../utils/getPriceImpact.js'\nimport { AvatarBadgedSkeleton } from '../Avatar/Avatar.js'\nimport { SmallAvatar } from '../Avatar/SmallAvatar.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { TextFitter } from '../TextFitter/TextFitter.js'\nimport { TextSecondary, TextSecondaryContainer } from './Token.style.js'\n\ninterface TokenProps {\n token: TokenAmount\n impactToken?: TokenAmount\n enableImpactTokenTooltip?: boolean\n step?: LiFiStep\n stepVisible?: boolean\n disableDescription?: boolean\n isLoading?: boolean\n}\n\nexport const Token: FC<TokenProps & BoxProps> = ({ token, ...other }) => {\n if (!token.priceUSD || !token.logoURI) {\n return <TokenFallback token={token} {...other} />\n }\n return <TokenBase token={token} {...other} />\n}\n\nconst TokenFallback: FC<TokenProps & BoxProps> = ({\n token,\n isLoading,\n ...other\n}) => {\n const { token: chainToken, isLoading: isLoadingToken } = useToken(\n token.chainId,\n token.address\n )\n\n return (\n <TokenBase\n token={{ ...token, ...chainToken } as TokenAmount}\n isLoading={isLoading || isLoadingToken}\n {...other}\n />\n )\n}\n\nconst TokenBase: FC<TokenProps & BoxProps> = ({\n token,\n impactToken,\n enableImpactTokenTooltip,\n step,\n stepVisible,\n disableDescription,\n isLoading,\n ...other\n}) => {\n const { t, i18n } = useTranslation()\n const { chain } = useChain(token?.chainId)\n\n if (isLoading) {\n return (\n <TokenSkeleton\n token={token}\n step={step}\n disableDescription={disableDescription}\n {...other}\n />\n )\n }\n\n const tokenAmount = formatTokenAmount(token.amount, token.decimals)\n const tokenPrice = formatTokenPrice(\n token.amount,\n token.priceUSD,\n token.decimals\n )\n\n let priceImpact: number | undefined\n let priceImpactPercent: number | undefined\n if (impactToken) {\n priceImpact = getPriceImpact({\n fromToken: impactToken,\n fromAmount: impactToken.amount,\n toToken: token,\n toAmount: token.amount,\n })\n priceImpactPercent = priceImpact * 100\n }\n\n const tokenOnChain = !disableDescription ? (\n <TextSecondary>\n {t('main.tokenOnChain', {\n tokenSymbol: token.symbol,\n chainName: chain?.name,\n })}\n </TextSecondary>\n ) : null\n\n return (\n <Box\n {...other}\n sx={[\n {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n },\n ...(Array.isArray(other.sx) ? other.sx : [other.sx]),\n ]}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n isLoading={isLoading}\n sx={{ marginRight: 2 }}\n />\n <Box\n sx={{\n flex: 1,\n }}\n >\n <Box\n sx={{\n mb: 0.5,\n height: 24,\n display: 'flex',\n alignItems: 'center',\n }}\n title={tokenAmount}\n >\n <TextFitter\n height={30}\n textStyle={{\n fontWeight: 700,\n }}\n >\n {t('format.tokenAmount', {\n value: tokenAmount,\n })}\n </TextFitter>\n </Box>\n <TextSecondaryContainer>\n <TextSecondary>\n {t('format.currency', {\n value: tokenPrice,\n })}\n </TextSecondary>\n {impactToken ? (\n <TextSecondary sx={{ px: 0.5 }} dot>\n •\n </TextSecondary>\n ) : null}\n {impactToken ? (\n enableImpactTokenTooltip ? (\n <Tooltip title={t('tooltip.priceImpact')} sx={{ cursor: 'help' }}>\n <TextSecondary>\n {t('format.percent', {\n value: priceImpact,\n usePlusSign: true,\n })}\n </TextSecondary>\n </Tooltip>\n ) : (\n <TextSecondary\n title={priceImpactPercent?.toLocaleString(i18n.language, {\n maximumFractionDigits: 9,\n })}\n >\n {t('format.percent', { value: priceImpact, usePlusSign: true })}\n </TextSecondary>\n )\n ) : null}\n {!disableDescription ? (\n <TextSecondary sx={{ px: 0.5 }} dot>\n •\n </TextSecondary>\n ) : null}\n {!disableDescription && step ? (\n <TokenStep\n step={step}\n stepVisible={stepVisible}\n disableDescription={disableDescription}\n >\n {tokenOnChain}\n </TokenStep>\n ) : (\n tokenOnChain\n )}\n </TextSecondaryContainer>\n </Box>\n </Box>\n )\n}\n\nconst TokenStep: FC<PropsWithChildren<Partial<TokenProps>>> = ({\n step,\n stepVisible,\n disableDescription,\n children,\n}) => {\n return (\n <Box\n sx={{\n flex: 1,\n position: 'relative',\n overflow: 'hidden',\n height: 16,\n }}\n >\n <Grow\n in={!stepVisible && !disableDescription}\n style={{\n position: 'absolute',\n }}\n appear={false}\n timeout={225}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n height: 16,\n }}\n >\n {children as ReactElement}\n </Box>\n </Grow>\n <Grow\n in={stepVisible}\n style={{\n position: 'absolute',\n }}\n appear={false}\n timeout={225}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n height: 16,\n }}\n >\n <Box\n sx={{\n mr: 0.75,\n height: 16,\n }}\n >\n <SmallAvatar\n src={step?.toolDetails.logoURI}\n alt={step?.toolDetails.name}\n >\n {step?.toolDetails.name[0]}\n </SmallAvatar>\n </Box>\n <TextSecondary>{step?.toolDetails.name}</TextSecondary>\n </Box>\n </Grow>\n </Box>\n )\n}\n\nexport const TokenSkeleton: FC<Partial<TokenProps> & BoxProps> = ({\n step,\n disableDescription,\n ...other\n}) => {\n return (\n <Box\n {...other}\n sx={[\n {\n flex: 1,\n },\n ...(Array.isArray(other.sx) ? other.sx : [other.sx]),\n ]}\n >\n <Box\n sx={{\n display: 'flex',\n flex: 1,\n alignItems: 'center',\n }}\n >\n <AvatarBadgedSkeleton sx={{ marginRight: 2 }} />\n <Box\n sx={{\n flex: 1,\n }}\n >\n <Skeleton width={112} height={28} variant=\"text\" />\n <TextSecondaryContainer>\n <Skeleton\n width={48}\n height={12}\n variant=\"rounded\"\n sx={{ marginTop: 0.5 }}\n />\n {!step && !disableDescription ? (\n <Skeleton\n width={96}\n height={12}\n variant=\"rounded\"\n sx={{ marginTop: 0.5, marginLeft: 1.5 }}\n />\n ) : null}\n </TextSecondaryContainer>\n </Box>\n </Box>\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Token.js","names":[],"sources":["../../../../src/components/Token/Token.tsx"],"sourcesContent":["import type { LiFiStep, TokenAmount } from '@lifi/sdk'\nimport type { BoxProps } from '@mui/material'\nimport { Box, Grow, Skeleton, Tooltip } from '@mui/material'\nimport type { FC, PropsWithChildren, ReactElement } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useChain } from '../../hooks/useChain.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { getPriceImpact } from '../../utils/getPriceImpact.js'\nimport { AvatarBadgedSkeleton } from '../Avatar/Avatar.js'\nimport { SmallAvatar } from '../Avatar/SmallAvatar.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { TextFitter } from '../TextFitter/TextFitter.js'\nimport { TextSecondary, TextSecondaryContainer } from './Token.style.js'\n\ninterface TokenProps {\n token: TokenAmount\n impactToken?: TokenAmount\n enableImpactTokenTooltip?: boolean\n step?: LiFiStep\n stepVisible?: boolean\n disableDescription?: boolean\n isLoading?: boolean\n}\n\nexport const Token: FC<TokenProps & BoxProps> = ({ token, ...other }) => {\n if (!token.priceUSD || !token.logoURI) {\n return <TokenFallback token={token} {...other} />\n }\n return <TokenBase token={token} {...other} />\n}\n\nconst TokenFallback: FC<TokenProps & BoxProps> = ({\n token,\n isLoading,\n ...other\n}) => {\n const { token: chainToken, isLoading: isLoadingToken } = useToken(\n token.chainId,\n token.address\n )\n\n return (\n <TokenBase\n token={{ ...token, ...chainToken } as TokenAmount}\n isLoading={isLoading || isLoadingToken}\n {...other}\n />\n )\n}\n\nconst TokenBase: FC<TokenProps & BoxProps> = ({\n token,\n impactToken,\n enableImpactTokenTooltip,\n step,\n stepVisible,\n disableDescription,\n isLoading,\n ...other\n}) => {\n const { t, i18n } = useTranslation()\n const { chain } = useChain(token?.chainId)\n\n if (isLoading) {\n return (\n <TokenSkeleton\n token={token}\n step={step}\n disableDescription={disableDescription}\n {...other}\n />\n )\n }\n\n const tokenAmount = formatTokenAmount(token.amount, token.decimals)\n const tokenPrice = formatTokenPrice(\n token.amount,\n token.priceUSD,\n token.decimals\n )\n\n let priceImpact: number | undefined\n let priceImpactPercent: number | undefined\n if (impactToken) {\n priceImpact = getPriceImpact({\n fromToken: impactToken,\n fromAmount: impactToken.amount,\n toToken: token,\n toAmount: token.amount,\n })\n priceImpactPercent = priceImpact * 100\n }\n\n const tokenOnChain = !disableDescription ? (\n <TextSecondary>\n {t('main.tokenOnChain', {\n tokenSymbol: token.symbol,\n chainName: chain?.name,\n })}\n </TextSecondary>\n ) : null\n\n return (\n <Box\n {...other}\n sx={[\n {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n },\n ...(Array.isArray(other.sx) ? other.sx : [other.sx]),\n ]}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n isLoading={isLoading}\n sx={{ marginRight: 2 }}\n />\n <Box\n sx={{\n flex: 1,\n }}\n >\n <Box\n sx={{\n mb: 0.5,\n height: 24,\n display: 'flex',\n alignItems: 'center',\n }}\n title={tokenAmount}\n >\n <TextFitter\n height={30}\n textStyle={{\n fontWeight: 700,\n }}\n >\n {t('format.tokenAmount', {\n value: tokenAmount,\n })}\n </TextFitter>\n </Box>\n <TextSecondaryContainer>\n <TextSecondary>\n {t('format.currency', {\n value: tokenPrice,\n })}\n </TextSecondary>\n {impactToken ? (\n <TextSecondary sx={{ px: 0.5 }} dot>\n •\n </TextSecondary>\n ) : null}\n {impactToken ? (\n enableImpactTokenTooltip ? (\n <Tooltip title={t('tooltip.priceImpact')} sx={{ cursor: 'help' }}>\n <TextSecondary>\n {t('format.percent', {\n value: priceImpact,\n usePlusSign: true,\n })}\n </TextSecondary>\n </Tooltip>\n ) : (\n <TextSecondary\n title={priceImpactPercent?.toLocaleString(i18n.language, {\n maximumFractionDigits: 9,\n })}\n >\n {t('format.percent', { value: priceImpact, usePlusSign: true })}\n </TextSecondary>\n )\n ) : null}\n {!disableDescription ? (\n <TextSecondary sx={{ px: 0.5 }} dot>\n •\n </TextSecondary>\n ) : null}\n {!disableDescription && step ? (\n <TokenStep\n step={step}\n stepVisible={stepVisible}\n disableDescription={disableDescription}\n >\n {tokenOnChain}\n </TokenStep>\n ) : (\n tokenOnChain\n )}\n </TextSecondaryContainer>\n </Box>\n </Box>\n )\n}\n\nconst TokenStep: FC<PropsWithChildren<Partial<TokenProps>>> = ({\n step,\n stepVisible,\n disableDescription,\n children,\n}) => {\n return (\n <Box\n sx={{\n flex: 1,\n position: 'relative',\n overflow: 'hidden',\n height: 16,\n }}\n >\n <Grow\n in={!stepVisible && !disableDescription}\n style={{\n position: 'absolute',\n }}\n appear={false}\n timeout={225}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n height: 16,\n }}\n >\n {children as ReactElement}\n </Box>\n </Grow>\n <Grow\n in={stepVisible}\n style={{\n position: 'absolute',\n }}\n appear={false}\n timeout={225}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n height: 16,\n }}\n >\n <Box\n sx={{\n mr: 0.75,\n height: 16,\n }}\n >\n <SmallAvatar\n src={step?.toolDetails.logoURI}\n alt={step?.toolDetails.name}\n >\n {step?.toolDetails.name[0]}\n </SmallAvatar>\n </Box>\n <TextSecondary>{step?.toolDetails.name}</TextSecondary>\n </Box>\n </Grow>\n </Box>\n )\n}\n\nexport const TokenSkeleton: FC<Partial<TokenProps> & BoxProps> = ({\n step,\n disableDescription,\n ...other\n}) => {\n return (\n <Box\n {...other}\n sx={[\n {\n flex: 1,\n },\n ...(Array.isArray(other.sx) ? other.sx : [other.sx]),\n ]}\n >\n <Box\n sx={{\n display: 'flex',\n flex: 1,\n alignItems: 'center',\n }}\n >\n <AvatarBadgedSkeleton sx={{ marginRight: 2 }} />\n <Box\n sx={{\n flex: 1,\n }}\n >\n <Skeleton width={112} height={28} variant=\"text\" />\n <TextSecondaryContainer>\n <Skeleton\n width={48}\n height={12}\n variant=\"rounded\"\n sx={{ marginTop: 0.5 }}\n />\n {!step && !disableDescription ? (\n <Skeleton\n width={96}\n height={12}\n variant=\"rounded\"\n sx={{ marginTop: 0.5, marginLeft: 1.5 }}\n />\n ) : null}\n </TextSecondaryContainer>\n </Box>\n </Box>\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinTokenButton.js","names":[],"sources":["../../../../src/components/TokenList/PinTokenButton.tsx"],"sourcesContent":["import PushPinIcon from '@mui/icons-material/PushPin'\nimport PushPinOutlinedIcon from '@mui/icons-material/PushPinOutlined'\nimport { IconButton } from '@mui/material'\nimport type { JSX } from 'react'\nimport { usePinnedTokensStore } from '../../stores/pinnedTokens/PinnedTokensStore.js'\n\ninterface PinTokenButtonProps {\n chainId: number\n tokenAddress: string\n}\n\nexport const PinTokenButton = ({\n chainId,\n tokenAddress,\n}: PinTokenButtonProps): JSX.Element => {\n const [pinnedTokens, pinToken, unpinToken] = usePinnedTokensStore((state) => [\n state.pinnedTokens,\n state.pinToken,\n state.unpinToken,\n ])\n\n const isPinned =\n pinnedTokens[chainId]?.includes(tokenAddress.toLowerCase()) ?? false\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n ;(e.currentTarget as HTMLElement).blur()\n if (isPinned) {\n unpinToken(chainId, tokenAddress)\n } else {\n pinToken(chainId, tokenAddress)\n }\n }\n\n const PinIcon = isPinned ? PushPinIcon : PushPinOutlinedIcon\n\n return (\n <IconButton\n sx={{ width: 20, height: 20 }}\n size=\"small\"\n onClick={handleClick}\n >\n <PinIcon\n sx={{\n fontSize: 12,\n color: isPinned ? 'text.primary' : 'text.secondary',\n }}\n />\n </IconButton>\n )\n}\n"],"mappings":";;;;;;AAWA,MAAa,kBAAkB,EAC7B,SACA,mBACsC;CACtC,MAAM,CAAC,cAAc,UAAU,cAAc,sBAAsB,UAAU;EAC3E,MAAM;EACN,MAAM;EACN,MAAM;EACP,CAAC;CAEF,MAAM,WACJ,aAAa,UAAU,SAAS,aAAa,aAAa,CAAC,IAAI;CAEjE,MAAM,eAAe,MAAwB;
|
|
1
|
+
{"version":3,"file":"PinTokenButton.js","names":[],"sources":["../../../../src/components/TokenList/PinTokenButton.tsx"],"sourcesContent":["import PushPinIcon from '@mui/icons-material/PushPin'\nimport PushPinOutlinedIcon from '@mui/icons-material/PushPinOutlined'\nimport { IconButton } from '@mui/material'\nimport type { JSX } from 'react'\nimport { usePinnedTokensStore } from '../../stores/pinnedTokens/PinnedTokensStore.js'\n\ninterface PinTokenButtonProps {\n chainId: number\n tokenAddress: string\n}\n\nexport const PinTokenButton = ({\n chainId,\n tokenAddress,\n}: PinTokenButtonProps): JSX.Element => {\n const [pinnedTokens, pinToken, unpinToken] = usePinnedTokensStore((state) => [\n state.pinnedTokens,\n state.pinToken,\n state.unpinToken,\n ])\n\n const isPinned =\n pinnedTokens[chainId]?.includes(tokenAddress.toLowerCase()) ?? false\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n ;(e.currentTarget as HTMLElement).blur()\n if (isPinned) {\n unpinToken(chainId, tokenAddress)\n } else {\n pinToken(chainId, tokenAddress)\n }\n }\n\n const PinIcon = isPinned ? PushPinIcon : PushPinOutlinedIcon\n\n return (\n <IconButton\n sx={{ width: 20, height: 20 }}\n size=\"small\"\n onClick={handleClick}\n >\n <PinIcon\n sx={{\n fontSize: 12,\n color: isPinned ? 'text.primary' : 'text.secondary',\n }}\n />\n </IconButton>\n )\n}\n"],"mappings":";;;;;;AAWA,MAAa,kBAAkB,EAC7B,SACA,mBACsC;CACtC,MAAM,CAAC,cAAc,UAAU,cAAc,sBAAsB,UAAU;EAC3E,MAAM;EACN,MAAM;EACN,MAAM;EACP,CAAC;CAEF,MAAM,WACJ,aAAa,UAAU,SAAS,aAAa,aAAa,CAAC,IAAI;CAEjE,MAAM,eAAe,MAAwB;EAC3C,EAAE,iBAAiB;EAClB,EAAG,cAA8B,MAAM;EACxC,IAAI,UACF,WAAW,SAAS,aAAa;OAEjC,SAAS,SAAS,aAAa;;CAMnC,OACE,oBAAC,YAAD;EACE,IAAI;GAAE,OAAO;GAAI,QAAQ;GAAI;EAC7B,MAAK;EACL,SAAS;YAET,oBARY,WAAW,cAAc,qBAQrC,EACE,IAAI;GACF,UAAU;GACV,OAAO,WAAW,iBAAiB;GACpC,EACD,CAAA;EACS,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenDetailsSheet.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheet.tsx"],"sourcesContent":["import type React from 'react'\nimport { forwardRef, useImperativeHandle, useRef, useState } from 'react'\nimport { BottomSheet } from '../BottomSheet/BottomSheet.js'\nimport type { BottomSheetBase } from '../BottomSheet/types.js'\nimport { TokenDetailsSheetContent } from './TokenDetailsSheetContent.js'\nimport type { TokenDetailsSheetBase } from './types.js'\n\nexport const TokenDetailsSheet: React.ForwardRefExoticComponent<\n React.RefAttributes<TokenDetailsSheetBase>\n> = forwardRef<TokenDetailsSheetBase>((_, ref) => {\n const bottomSheetRef = useRef<BottomSheetBase>(null)\n const [tokenAddress, setTokenAddress] = useState<string | undefined>(\n undefined\n )\n const [chainId, setChainId] = useState<number | undefined>(undefined)\n const [withoutContractAddress, setWithoutContractAddress] = useState(false)\n\n useImperativeHandle(\n ref,\n () => ({\n isOpen: () => bottomSheetRef.current?.isOpen(),\n open: (address: string, noContractAddress: boolean, chainId: number) => {\n setTokenAddress(address)\n setWithoutContractAddress(noContractAddress)\n setChainId(chainId)\n bottomSheetRef.current?.open()\n },\n close: () => {\n bottomSheetRef.current?.close()\n },\n }),\n []\n )\n\n return (\n <BottomSheet ref={bottomSheetRef} keepMounted>\n <TokenDetailsSheetContent\n ref={ref}\n tokenAddress={tokenAddress}\n withoutContractAddress={withoutContractAddress}\n chainId={chainId}\n />\n </BottomSheet>\n )\n})\n"],"mappings":";;;;;AAOA,MAAa,oBAET,YAAmC,GAAG,QAAQ;CAChD,MAAM,iBAAiB,OAAwB,KAAK;CACpD,MAAM,CAAC,cAAc,mBAAmB,SACtC,KAAA,EACD;CACD,MAAM,CAAC,SAAS,cAAc,SAA6B,KAAA,EAAU;CACrE,MAAM,CAAC,wBAAwB,6BAA6B,SAAS,MAAM;
|
|
1
|
+
{"version":3,"file":"TokenDetailsSheet.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheet.tsx"],"sourcesContent":["import type React from 'react'\nimport { forwardRef, useImperativeHandle, useRef, useState } from 'react'\nimport { BottomSheet } from '../BottomSheet/BottomSheet.js'\nimport type { BottomSheetBase } from '../BottomSheet/types.js'\nimport { TokenDetailsSheetContent } from './TokenDetailsSheetContent.js'\nimport type { TokenDetailsSheetBase } from './types.js'\n\nexport const TokenDetailsSheet: React.ForwardRefExoticComponent<\n React.RefAttributes<TokenDetailsSheetBase>\n> = forwardRef<TokenDetailsSheetBase>((_, ref) => {\n const bottomSheetRef = useRef<BottomSheetBase>(null)\n const [tokenAddress, setTokenAddress] = useState<string | undefined>(\n undefined\n )\n const [chainId, setChainId] = useState<number | undefined>(undefined)\n const [withoutContractAddress, setWithoutContractAddress] = useState(false)\n\n useImperativeHandle(\n ref,\n () => ({\n isOpen: () => bottomSheetRef.current?.isOpen(),\n open: (address: string, noContractAddress: boolean, chainId: number) => {\n setTokenAddress(address)\n setWithoutContractAddress(noContractAddress)\n setChainId(chainId)\n bottomSheetRef.current?.open()\n },\n close: () => {\n bottomSheetRef.current?.close()\n },\n }),\n []\n )\n\n return (\n <BottomSheet ref={bottomSheetRef} keepMounted>\n <TokenDetailsSheetContent\n ref={ref}\n tokenAddress={tokenAddress}\n withoutContractAddress={withoutContractAddress}\n chainId={chainId}\n />\n </BottomSheet>\n )\n})\n"],"mappings":";;;;;AAOA,MAAa,oBAET,YAAmC,GAAG,QAAQ;CAChD,MAAM,iBAAiB,OAAwB,KAAK;CACpD,MAAM,CAAC,cAAc,mBAAmB,SACtC,KAAA,EACD;CACD,MAAM,CAAC,SAAS,cAAc,SAA6B,KAAA,EAAU;CACrE,MAAM,CAAC,wBAAwB,6BAA6B,SAAS,MAAM;CAE3E,oBACE,YACO;EACL,cAAc,eAAe,SAAS,QAAQ;EAC9C,OAAO,SAAiB,mBAA4B,YAAoB;GACtE,gBAAgB,QAAQ;GACxB,0BAA0B,kBAAkB;GAC5C,WAAW,QAAQ;GACnB,eAAe,SAAS,MAAM;;EAEhC,aAAa;GACX,eAAe,SAAS,OAAO;;EAElC,GACD,EAAE,CACH;CAED,OACE,oBAAC,aAAD;EAAa,KAAK;EAAgB,aAAA;YAChC,oBAAC,0BAAD;GACO;GACS;GACU;GACf;GACT,CAAA;EACU,CAAA;EAEhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenDetailsSheetContent.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheetContent.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close'\nimport ContentCopyRounded from '@mui/icons-material/ContentCopyRounded'\nimport OpenInNewRounded from '@mui/icons-material/OpenInNewRounded'\nimport { Box, IconButton, Link, Skeleton, Typography } from '@mui/material'\nimport type React from 'react'\nimport { forwardRef, type PropsWithChildren, useMemo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useExplorer } from '../../hooks/useExplorer.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport {\n Label,\n MetricContainer,\n TokenDetailsSheetContainer,\n TokenDetailsSheetHeader,\n} from './TokenDetailsSheetContent.style.js'\nimport type { TokenDetailsSheetBase } from './types.js'\n\ninterface TokenDetailsSheetContentProps {\n tokenAddress: string | undefined\n chainId: number | undefined\n withoutContractAddress: boolean\n}\n\nconst noDataLabel = '-'\n\nexport const TokenDetailsSheetContent: React.ForwardRefExoticComponent<\n TokenDetailsSheetContentProps & React.RefAttributes<TokenDetailsSheetBase>\n> = forwardRef<TokenDetailsSheetBase, TokenDetailsSheetContentProps>(\n ({ tokenAddress, chainId, withoutContractAddress }, ref) => {\n const { t } = useTranslation()\n const { getAddressLink } = useExplorer()\n const { getChainById } = useAvailableChains()\n\n const { token, isLoading } = useToken(chainId, tokenAddress, true)\n const chain = useMemo(() => getChainById(chainId), [chainId, getChainById])\n\n const copyContractAddress = async (e: React.MouseEvent) => {\n e.stopPropagation()\n try {\n // Clipboard API may throw if access is denied (e.g., in insecure contexts or older browsers)\n await navigator.clipboard.writeText(tokenAddress || '')\n } catch {\n // Silently fail to avoid crashing the UI if clipboard write fails\n }\n }\n\n return (\n <TokenDetailsSheetContainer>\n <TokenDetailsSheetHeader>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 3,\n }}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n tokenAvatarSize={72}\n chainAvatarSize={28}\n isLoading={isLoading}\n />\n <MetricContainer>\n {isLoading ? (\n <>\n <Skeleton variant=\"rounded\" width={80} height={24} />\n <Skeleton variant=\"rounded\" width={80} height={16} />\n </>\n ) : (\n <>\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '24px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.symbol || noDataLabel}\n </Typography>\n <Label>{token?.name || noDataLabel}</Label>\n </>\n )}\n </MetricContainer>\n </Box>\n <IconButton\n onClick={(e) => {\n e.stopPropagation()\n if (ref && typeof ref !== 'function') {\n ref.current?.close()\n }\n }}\n sx={{ mt: '-8px', mr: '-8px' }}\n >\n <Close />\n </IconButton>\n </TokenDetailsSheetHeader>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.currentPrice')}\n width={200}\n height={40}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '32px',\n lineHeight: '40px',\n color: 'text.primary',\n }}\n >\n {token?.priceUSD\n ? t('format.currency', {\n value: token.priceUSD,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n {!withoutContractAddress && (\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.contractAddress')}\n width={200}\n height={24}\n >\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 1,\n }}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {shortenAddress(tokenAddress)}\n </Typography>\n {tokenAddress && (\n <CardIconButton size=\"small\" onClick={copyContractAddress}>\n <ContentCopyRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n {tokenAddress && (\n <CardIconButton\n size=\"small\"\n LinkComponent={Link}\n href={getAddressLink(tokenAddress, chainId)}\n target=\"_blank\"\n rel=\"nofollow noreferrer\"\n onClick={(e) => e.stopPropagation()}\n >\n <OpenInNewRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n </Box>\n </MetricWithSkeleton>\n )}\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.marketCap')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.marketCapUSD\n ? t('format.currency', {\n value: token.marketCapUSD,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.volume24h')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.volumeUSD24H\n ? t('format.currency', {\n value: token.volumeUSD24H,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n </TokenDetailsSheetContainer>\n )\n }\n)\n\ninterface MetricWithSkeletonProps {\n label: string\n isLoading: boolean\n width: number\n height: number\n}\n\nconst MetricWithSkeleton = ({\n label,\n width,\n height,\n isLoading,\n children,\n}: PropsWithChildren<MetricWithSkeletonProps>) => {\n return (\n <MetricContainer>\n <Label>{label}</Label>\n {isLoading ? (\n <Skeleton variant=\"rounded\" width={width} height={height} />\n ) : (\n children\n )}\n </MetricContainer>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TokenDetailsSheetContent.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheetContent.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close'\nimport ContentCopyRounded from '@mui/icons-material/ContentCopyRounded'\nimport OpenInNewRounded from '@mui/icons-material/OpenInNewRounded'\nimport { Box, IconButton, Link, Skeleton, Typography } from '@mui/material'\nimport type React from 'react'\nimport { forwardRef, type PropsWithChildren, useMemo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useExplorer } from '../../hooks/useExplorer.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport {\n Label,\n MetricContainer,\n TokenDetailsSheetContainer,\n TokenDetailsSheetHeader,\n} from './TokenDetailsSheetContent.style.js'\nimport type { TokenDetailsSheetBase } from './types.js'\n\ninterface TokenDetailsSheetContentProps {\n tokenAddress: string | undefined\n chainId: number | undefined\n withoutContractAddress: boolean\n}\n\nconst noDataLabel = '-'\n\nexport const TokenDetailsSheetContent: React.ForwardRefExoticComponent<\n TokenDetailsSheetContentProps & React.RefAttributes<TokenDetailsSheetBase>\n> = forwardRef<TokenDetailsSheetBase, TokenDetailsSheetContentProps>(\n ({ tokenAddress, chainId, withoutContractAddress }, ref) => {\n const { t } = useTranslation()\n const { getAddressLink } = useExplorer()\n const { getChainById } = useAvailableChains()\n\n const { token, isLoading } = useToken(chainId, tokenAddress, true)\n const chain = useMemo(() => getChainById(chainId), [chainId, getChainById])\n\n const copyContractAddress = async (e: React.MouseEvent) => {\n e.stopPropagation()\n try {\n // Clipboard API may throw if access is denied (e.g., in insecure contexts or older browsers)\n await navigator.clipboard.writeText(tokenAddress || '')\n } catch {\n // Silently fail to avoid crashing the UI if clipboard write fails\n }\n }\n\n return (\n <TokenDetailsSheetContainer>\n <TokenDetailsSheetHeader>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 3,\n }}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n tokenAvatarSize={72}\n chainAvatarSize={28}\n isLoading={isLoading}\n />\n <MetricContainer>\n {isLoading ? (\n <>\n <Skeleton variant=\"rounded\" width={80} height={24} />\n <Skeleton variant=\"rounded\" width={80} height={16} />\n </>\n ) : (\n <>\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '24px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.symbol || noDataLabel}\n </Typography>\n <Label>{token?.name || noDataLabel}</Label>\n </>\n )}\n </MetricContainer>\n </Box>\n <IconButton\n onClick={(e) => {\n e.stopPropagation()\n if (ref && typeof ref !== 'function') {\n ref.current?.close()\n }\n }}\n sx={{ mt: '-8px', mr: '-8px' }}\n >\n <Close />\n </IconButton>\n </TokenDetailsSheetHeader>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.currentPrice')}\n width={200}\n height={40}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '32px',\n lineHeight: '40px',\n color: 'text.primary',\n }}\n >\n {token?.priceUSD\n ? t('format.currency', {\n value: token.priceUSD,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n {!withoutContractAddress && (\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.contractAddress')}\n width={200}\n height={24}\n >\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 1,\n }}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {shortenAddress(tokenAddress)}\n </Typography>\n {tokenAddress && (\n <CardIconButton size=\"small\" onClick={copyContractAddress}>\n <ContentCopyRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n {tokenAddress && (\n <CardIconButton\n size=\"small\"\n LinkComponent={Link}\n href={getAddressLink(tokenAddress, chainId)}\n target=\"_blank\"\n rel=\"nofollow noreferrer\"\n onClick={(e) => e.stopPropagation()}\n >\n <OpenInNewRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n </Box>\n </MetricWithSkeleton>\n )}\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.marketCap')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.marketCapUSD\n ? t('format.currency', {\n value: token.marketCapUSD,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.volume24h')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.volumeUSD24H\n ? t('format.currency', {\n value: token.volumeUSD24H,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n </TokenDetailsSheetContainer>\n )\n }\n)\n\ninterface MetricWithSkeletonProps {\n label: string\n isLoading: boolean\n width: number\n height: number\n}\n\nconst MetricWithSkeleton = ({\n label,\n width,\n height,\n isLoading,\n children,\n}: PropsWithChildren<MetricWithSkeletonProps>) => {\n return (\n <MetricContainer>\n <Label>{label}</Label>\n {isLoading ? (\n <Skeleton variant=\"rounded\" width={width} height={height} />\n ) : (\n children\n )}\n </MetricContainer>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenList.js","names":[],"sources":["../../../../src/components/TokenList/TokenList.tsx"],"sourcesContent":["import { Box } from '@mui/material'\nimport { type FC, memo, useEffect, useRef } from 'react'\nimport { useDebouncedWatch } from '../../hooks/useDebouncedWatch.js'\nimport { useListHeight } from '../../hooks/useListHeight.js'\nimport { useNavigateBack } from '../../hooks/useNavigateBack.js'\nimport { useTokenBalances } from '../../hooks/useTokenBalances.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport { TokenNotFound } from './TokenNotFound.js'\nimport type { TokenListProps } from './types.js'\nimport { useTokenSelect } from './useTokenSelect.js'\nimport { VirtualizedTokenList } from './VirtualizedTokenList.js'\n\nexport const TokenList: FC<TokenListProps> = memo(({ formType, headerRef }) => {\n const navigateBack = useNavigateBack()\n const listParentRef = useRef<HTMLUListElement | null>(null)\n const { listHeight } = useListHeight({\n listParentRef,\n headerRef,\n })\n\n const emitter = useWidgetEvents()\n\n const [selectedChainId, selectedTokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const isAllNetworks = useChainOrderStore(\n (state) => state[`${formType}IsAllNetworks`]\n )\n\n const [tokenSearchFilter]: string[] = useDebouncedWatch(\n 320,\n 'tokenSearchFilter'\n )\n\n const {\n tokens,\n withCategories,\n withPinnedTokens,\n isTokensLoading,\n isBalanceLoading,\n isSearchLoading,\n } = useTokenBalances(\n selectedChainId,\n formType,\n isAllNetworks,\n tokenSearchFilter\n )\n\n const handleTokenClick = useTokenSelect(formType, navigateBack)\n\n const showCategories = withCategories && !tokenSearchFilter && !isAllNetworks\n\n useEffect(() => {\n const normalizedSearchFilter = tokenSearchFilter?.replaceAll('$', '')\n if (normalizedSearchFilter) {\n emitter.emit(WidgetEvent.TokenSearch, {\n value: normalizedSearchFilter,\n tokens,\n })\n }\n }, [tokenSearchFilter, tokens, emitter])\n\n return (\n <Box ref={listParentRef} style={{ height: listHeight, overflow: 'auto' }}>\n {!tokens.length && !isTokensLoading && !isSearchLoading ? (\n <TokenNotFound formType={formType} />\n ) : null}\n <VirtualizedTokenList\n tokens={tokens}\n scrollElementRef={listParentRef}\n chainId={selectedChainId}\n isLoading={isTokensLoading || isSearchLoading}\n isBalanceLoading={isBalanceLoading}\n showCategories={showCategories}\n showPinnedTokens={withPinnedTokens}\n onClick={handleTokenClick}\n selectedTokenAddress={selectedTokenAddress}\n isAllNetworks={isAllNetworks}\n />\n </Box>\n )\n})\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAa,YAAgC,MAAM,EAAE,UAAU,gBAAgB;CAC7E,MAAM,eAAe,iBAAiB;CACtC,MAAM,gBAAgB,OAAgC,KAAK;CAC3D,MAAM,EAAE,eAAe,cAAc;EACnC;EACA;EACD,CAAC;CAEF,MAAM,UAAU,iBAAiB;CAEjC,MAAM,CAAC,iBAAiB,wBAAwB,eAC9C,cAAc,YAAY,SAAS,EACnC,cAAc,YAAY,SAAS,CACpC;CAED,MAAM,gBAAgB,oBACnB,UAAU,MAAM,GAAG,SAAS,gBAC9B;CAED,MAAM,CAAC,qBAA+B,kBACpC,KACA,oBACD;CAED,MAAM,EACJ,QACA,gBACA,kBACA,iBACA,kBACA,oBACE,iBACF,iBACA,UACA,eACA,kBACD;CAED,MAAM,mBAAmB,eAAe,UAAU,aAAa;CAE/D,MAAM,iBAAiB,kBAAkB,CAAC,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"TokenList.js","names":[],"sources":["../../../../src/components/TokenList/TokenList.tsx"],"sourcesContent":["import { Box } from '@mui/material'\nimport { type FC, memo, useEffect, useRef } from 'react'\nimport { useDebouncedWatch } from '../../hooks/useDebouncedWatch.js'\nimport { useListHeight } from '../../hooks/useListHeight.js'\nimport { useNavigateBack } from '../../hooks/useNavigateBack.js'\nimport { useTokenBalances } from '../../hooks/useTokenBalances.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport { TokenNotFound } from './TokenNotFound.js'\nimport type { TokenListProps } from './types.js'\nimport { useTokenSelect } from './useTokenSelect.js'\nimport { VirtualizedTokenList } from './VirtualizedTokenList.js'\n\nexport const TokenList: FC<TokenListProps> = memo(({ formType, headerRef }) => {\n const navigateBack = useNavigateBack()\n const listParentRef = useRef<HTMLUListElement | null>(null)\n const { listHeight } = useListHeight({\n listParentRef,\n headerRef,\n })\n\n const emitter = useWidgetEvents()\n\n const [selectedChainId, selectedTokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const isAllNetworks = useChainOrderStore(\n (state) => state[`${formType}IsAllNetworks`]\n )\n\n const [tokenSearchFilter]: string[] = useDebouncedWatch(\n 320,\n 'tokenSearchFilter'\n )\n\n const {\n tokens,\n withCategories,\n withPinnedTokens,\n isTokensLoading,\n isBalanceLoading,\n isSearchLoading,\n } = useTokenBalances(\n selectedChainId,\n formType,\n isAllNetworks,\n tokenSearchFilter\n )\n\n const handleTokenClick = useTokenSelect(formType, navigateBack)\n\n const showCategories = withCategories && !tokenSearchFilter && !isAllNetworks\n\n useEffect(() => {\n const normalizedSearchFilter = tokenSearchFilter?.replaceAll('$', '')\n if (normalizedSearchFilter) {\n emitter.emit(WidgetEvent.TokenSearch, {\n value: normalizedSearchFilter,\n tokens,\n })\n }\n }, [tokenSearchFilter, tokens, emitter])\n\n return (\n <Box ref={listParentRef} style={{ height: listHeight, overflow: 'auto' }}>\n {!tokens.length && !isTokensLoading && !isSearchLoading ? (\n <TokenNotFound formType={formType} />\n ) : null}\n <VirtualizedTokenList\n tokens={tokens}\n scrollElementRef={listParentRef}\n chainId={selectedChainId}\n isLoading={isTokensLoading || isSearchLoading}\n isBalanceLoading={isBalanceLoading}\n showCategories={showCategories}\n showPinnedTokens={withPinnedTokens}\n onClick={handleTokenClick}\n selectedTokenAddress={selectedTokenAddress}\n isAllNetworks={isAllNetworks}\n />\n </Box>\n )\n})\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAa,YAAgC,MAAM,EAAE,UAAU,gBAAgB;CAC7E,MAAM,eAAe,iBAAiB;CACtC,MAAM,gBAAgB,OAAgC,KAAK;CAC3D,MAAM,EAAE,eAAe,cAAc;EACnC;EACA;EACD,CAAC;CAEF,MAAM,UAAU,iBAAiB;CAEjC,MAAM,CAAC,iBAAiB,wBAAwB,eAC9C,cAAc,YAAY,SAAS,EACnC,cAAc,YAAY,SAAS,CACpC;CAED,MAAM,gBAAgB,oBACnB,UAAU,MAAM,GAAG,SAAS,gBAC9B;CAED,MAAM,CAAC,qBAA+B,kBACpC,KACA,oBACD;CAED,MAAM,EACJ,QACA,gBACA,kBACA,iBACA,kBACA,oBACE,iBACF,iBACA,UACA,eACA,kBACD;CAED,MAAM,mBAAmB,eAAe,UAAU,aAAa;CAE/D,MAAM,iBAAiB,kBAAkB,CAAC,qBAAqB,CAAC;CAEhE,gBAAgB;EACd,MAAM,yBAAyB,mBAAmB,WAAW,KAAK,GAAG;EACrE,IAAI,wBACF,QAAQ,KAAA,eAA8B;GACpC,OAAO;GACP;GACD,CAAC;IAEH;EAAC;EAAmB;EAAQ;EAAQ,CAAC;CAExC,OACE,qBAAC,KAAD;EAAK,KAAK;EAAe,OAAO;GAAE,QAAQ;GAAY,UAAU;GAAQ;YAAxE,CACG,CAAC,OAAO,UAAU,CAAC,mBAAmB,CAAC,kBACtC,oBAAC,eAAD,EAAyB,UAAY,CAAA,GACnC,MACJ,oBAAC,sBAAD;GACU;GACR,kBAAkB;GAClB,SAAS;GACT,WAAW,mBAAmB;GACZ;GACF;GAChB,kBAAkB;GAClB,SAAS;GACa;GACP;GACf,CAAA,CACE;;EAER"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenListItem.js","names":["ListItem","IconButton","ListItemButton"],"sources":["../../../../src/components/TokenList/TokenListItem.tsx"],"sourcesContent":["import type { StaticToken } from '@lifi/sdk'\nimport { ChainType } from '@lifi/sdk'\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'\nimport WarningRounded from '@mui/icons-material/WarningRounded'\nimport {\n Avatar,\n Box,\n ListItemAvatar,\n ListItemText,\n listItemSecondaryActionClasses,\n Skeleton,\n Slide,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport type { JSX, MouseEventHandler } from 'react'\nimport { memo, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useLongPress } from '../../hooks/useLongPress.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { ListItemButton } from '../ListItem/ListItemButton.js'\nimport { PinTokenButton } from './PinTokenButton.js'\nimport { IconButton, ListItem } from './TokenList.style.js'\nimport type {\n TokenListItemAvatarProps,\n TokenListItemButtonProps,\n TokenListItemProps,\n} from './types.js'\n\nexport const TokenListItem: React.FC<TokenListItemProps> = memo(\n ({\n onClick,\n size,\n start,\n token,\n chain,\n isBalanceLoading,\n startAdornment,\n endAdornment,\n selected,\n onShowTokenDetails,\n }) => {\n return (\n <ListItem\n style={{\n height: `${size}px`,\n transform: `translateY(${start}px)`,\n padding: 0,\n }}\n >\n {startAdornment}\n <TokenListItemButton\n token={token}\n isBalanceLoading={isBalanceLoading}\n onClick={onClick}\n chain={chain}\n selected={selected}\n onShowTokenDetails={onShowTokenDetails}\n />\n {endAdornment}\n </ListItem>\n )\n }\n)\n\nconst TokenListItemAvatar = memo(({ token }: TokenListItemAvatarProps) => {\n const [isImageLoading, setIsImageLoading] = useState(true)\n\n return (\n <Avatar\n src={token.logoURI}\n alt={token.symbol}\n sx={(theme) =>\n isImageLoading ? { bgcolor: theme.vars.palette.grey[300] } : null\n }\n onLoad={() => setIsImageLoading(false)}\n >\n {token.symbol?.[0]}\n </Avatar>\n )\n})\n\ninterface OpenTokenDetailsButtonProps {\n tokenAddress: string | undefined\n withoutContractAddress: boolean\n chainId: number\n onClick: (\n tokenAddress: string,\n withoutContractAddress: boolean,\n chainId: number\n ) => void\n}\n\nconst OpenTokenDetailsButton = ({\n tokenAddress,\n withoutContractAddress,\n chainId,\n onClick,\n}: OpenTokenDetailsButtonProps) => {\n if (!tokenAddress) {\n return null\n }\n return (\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation()\n e.currentTarget.blur() // Remove focus to prevent accessibility issues when opening drawer\n onClick(tokenAddress, withoutContractAddress, chainId)\n }}\n >\n <InfoOutlinedIcon />\n </IconButton>\n )\n}\n\nconst TokenListItemButton: React.FC<TokenListItemButtonProps> = memo(\n ({\n onClick,\n token,\n chain,\n isBalanceLoading,\n selected,\n onShowTokenDetails,\n }) => {\n const { t } = useTranslation()\n const container = useRef(null)\n const timeoutId = useRef<ReturnType<typeof setTimeout>>(undefined)\n const [showAddress, setShowAddress] = useState(false)\n\n const withoutContractAddress = chain?.chainType === ChainType.UTXO\n\n const onMouseEnter = () => {\n timeoutId.current = setTimeout(() => {\n if (token.address) {\n setShowAddress(true)\n }\n }, 350)\n }\n\n const onMouseLeave = () => {\n clearTimeout(timeoutId.current)\n if (showAddress) {\n setShowAddress(false)\n }\n }\n\n const handleClick: MouseEventHandler<HTMLDivElement> = (e) => {\n e.stopPropagation()\n onClick?.(token.address, token.chainId)\n }\n\n const tokenAmount = useMemo(\n () => formatTokenAmount(token.amount, token.decimals),\n [token.amount, token.decimals]\n )\n\n const tokenPrice = useMemo(\n () => formatTokenPrice(token.amount, token.priceUSD, token.decimals),\n [token.amount, token.priceUSD, token.decimals]\n )\n\n const longPressEvents = useLongPress(() =>\n onShowTokenDetails(token.address, withoutContractAddress, token.chainId)\n )\n\n return (\n <ListItemButton\n onClick={handleClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n {...longPressEvents}\n dense\n selected={selected}\n sx={{\n height: 60,\n marginBottom: '4px',\n }}\n >\n <ListItemAvatar>\n {chain ? (\n <TokenAvatar\n token={token as StaticToken}\n chain={chain}\n tokenAvatarSize={40}\n chainAvatarSize={16}\n />\n ) : (\n <TokenListItemAvatar token={token} />\n )}\n </ListItemAvatar>\n <ListItemText\n primary={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n {token.symbol}\n {!token.verified && (\n <Tooltip\n title={t('warning.message.unverifiedToken')}\n placement=\"top\"\n arrow\n >\n <WarningRounded\n sx={{\n display: 'flex',\n fontSize: 16,\n color: 'warning.main',\n cursor: 'help',\n }}\n />\n </Tooltip>\n )}\n </Box>\n }\n slotProps={{\n secondary: {\n component: 'div',\n },\n }}\n secondary={\n withoutContractAddress ? (\n <Box\n ref={container}\n sx={{\n height: 20,\n display: 'flex',\n }}\n >\n <Box\n sx={{\n pt: 0.25,\n }}\n >\n {token.name}\n </Box>\n <Box\n sx={{\n position: 'relative',\n }}\n >\n <Slide\n direction=\"up\"\n in={showAddress}\n container={container.current}\n style={{\n position: 'absolute',\n }}\n appear={false}\n mountOnEnter\n >\n <Box>\n <OpenTokenDetailsButton\n tokenAddress={token.address}\n withoutContractAddress={withoutContractAddress}\n chainId={token.chainId}\n onClick={onShowTokenDetails}\n />\n <PinTokenButton\n chainId={token.chainId}\n tokenAddress={token.address}\n />\n </Box>\n </Slide>\n </Box>\n </Box>\n ) : (\n <Box\n ref={container}\n sx={{\n position: 'relative',\n height: 20,\n }}\n >\n <Slide\n direction=\"down\"\n in={!showAddress}\n container={container.current}\n style={{\n position: 'absolute',\n }}\n appear={false}\n >\n <Box\n sx={{\n pt: 0.25,\n }}\n >\n {token.name}\n </Box>\n </Slide>\n <Slide\n direction=\"up\"\n in={showAddress}\n container={container.current}\n style={{\n position: 'absolute',\n }}\n appear={false}\n mountOnEnter\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 0.5,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n pt: 0.125,\n }}\n >\n {shortenAddress(token.address)}\n </Box>\n <Box>\n <OpenTokenDetailsButton\n tokenAddress={token.address}\n withoutContractAddress={withoutContractAddress}\n chainId={token.chainId}\n onClick={onShowTokenDetails}\n />\n <PinTokenButton\n chainId={token.chainId}\n tokenAddress={token.address}\n />\n </Box>\n </Box>\n </Slide>\n </Box>\n )\n }\n />\n {isBalanceLoading ? (\n <TokenAmountSkeleton />\n ) : (\n <Box sx={{ textAlign: 'right' }}>\n {token.amount ? (\n <Typography\n noWrap\n sx={{\n fontWeight: 600,\n }}\n title={tokenAmount}\n >\n {t('format.tokenAmount', {\n value: tokenAmount,\n })}\n </Typography>\n ) : null}\n {token.amount && token.priceUSD ? (\n <Typography\n data-price={token.priceUSD}\n sx={{\n fontWeight: 500,\n fontSize: 12,\n color: 'text.secondary',\n }}\n >\n {t('format.currency', {\n value: tokenPrice,\n })}\n </Typography>\n ) : null}\n </Box>\n )}\n </ListItemButton>\n )\n }\n)\n\nexport const TokenListItemSkeleton = (): JSX.Element => {\n return (\n <ListItem\n secondaryAction={<TokenAmountSkeleton />}\n disablePadding\n sx={(theme) => ({\n position: 'relative',\n flexDirection: 'row',\n alignItems: 'center',\n padding: 0,\n [`& .${listItemSecondaryActionClasses.root}`]: {\n right: theme.spacing(1.5),\n },\n })}\n >\n <ListItemAvatar>\n <Skeleton\n variant=\"circular\"\n width={40}\n height={40}\n sx={{ marginLeft: 1.5, marginRight: 2 }}\n />\n </ListItemAvatar>\n <ListItemText\n primary={<Skeleton variant=\"text\" width={56} height={24} />}\n secondary={<Skeleton variant=\"text\" width={96} height={16} />}\n />\n </ListItem>\n )\n}\n\nconst TokenAmountSkeleton: React.FC = () => {\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n }}\n >\n <Skeleton variant=\"text\" width={56} height={24} />\n <Skeleton variant=\"text\" width={48} height={16} />\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TokenListItem.js","names":["ListItem","IconButton","ListItemButton"],"sources":["../../../../src/components/TokenList/TokenListItem.tsx"],"sourcesContent":["import type { StaticToken } from '@lifi/sdk'\nimport { ChainType } from '@lifi/sdk'\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'\nimport WarningRounded from '@mui/icons-material/WarningRounded'\nimport {\n Avatar,\n Box,\n ListItemAvatar,\n ListItemText,\n listItemSecondaryActionClasses,\n Skeleton,\n Slide,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport type { JSX, MouseEventHandler } from 'react'\nimport { memo, useMemo, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useLongPress } from '../../hooks/useLongPress.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { ListItemButton } from '../ListItem/ListItemButton.js'\nimport { PinTokenButton } from './PinTokenButton.js'\nimport { IconButton, ListItem } from './TokenList.style.js'\nimport type {\n TokenListItemAvatarProps,\n TokenListItemButtonProps,\n TokenListItemProps,\n} from './types.js'\n\nexport const TokenListItem: React.FC<TokenListItemProps> = memo(\n ({\n onClick,\n size,\n start,\n token,\n chain,\n isBalanceLoading,\n startAdornment,\n endAdornment,\n selected,\n onShowTokenDetails,\n }) => {\n return (\n <ListItem\n style={{\n height: `${size}px`,\n transform: `translateY(${start}px)`,\n padding: 0,\n }}\n >\n {startAdornment}\n <TokenListItemButton\n token={token}\n isBalanceLoading={isBalanceLoading}\n onClick={onClick}\n chain={chain}\n selected={selected}\n onShowTokenDetails={onShowTokenDetails}\n />\n {endAdornment}\n </ListItem>\n )\n }\n)\n\nconst TokenListItemAvatar = memo(({ token }: TokenListItemAvatarProps) => {\n const [isImageLoading, setIsImageLoading] = useState(true)\n\n return (\n <Avatar\n src={token.logoURI}\n alt={token.symbol}\n sx={(theme) =>\n isImageLoading ? { bgcolor: theme.vars.palette.grey[300] } : null\n }\n onLoad={() => setIsImageLoading(false)}\n >\n {token.symbol?.[0]}\n </Avatar>\n )\n})\n\ninterface OpenTokenDetailsButtonProps {\n tokenAddress: string | undefined\n withoutContractAddress: boolean\n chainId: number\n onClick: (\n tokenAddress: string,\n withoutContractAddress: boolean,\n chainId: number\n ) => void\n}\n\nconst OpenTokenDetailsButton = ({\n tokenAddress,\n withoutContractAddress,\n chainId,\n onClick,\n}: OpenTokenDetailsButtonProps) => {\n if (!tokenAddress) {\n return null\n }\n return (\n <IconButton\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation()\n e.currentTarget.blur() // Remove focus to prevent accessibility issues when opening drawer\n onClick(tokenAddress, withoutContractAddress, chainId)\n }}\n >\n <InfoOutlinedIcon />\n </IconButton>\n )\n}\n\nconst TokenListItemButton: React.FC<TokenListItemButtonProps> = memo(\n ({\n onClick,\n token,\n chain,\n isBalanceLoading,\n selected,\n onShowTokenDetails,\n }) => {\n const { t } = useTranslation()\n const container = useRef(null)\n const timeoutId = useRef<ReturnType<typeof setTimeout>>(undefined)\n const [showAddress, setShowAddress] = useState(false)\n\n const withoutContractAddress = chain?.chainType === ChainType.UTXO\n\n const onMouseEnter = () => {\n timeoutId.current = setTimeout(() => {\n if (token.address) {\n setShowAddress(true)\n }\n }, 350)\n }\n\n const onMouseLeave = () => {\n clearTimeout(timeoutId.current)\n if (showAddress) {\n setShowAddress(false)\n }\n }\n\n const handleClick: MouseEventHandler<HTMLDivElement> = (e) => {\n e.stopPropagation()\n onClick?.(token.address, token.chainId)\n }\n\n const tokenAmount = useMemo(\n () => formatTokenAmount(token.amount, token.decimals),\n [token.amount, token.decimals]\n )\n\n const tokenPrice = useMemo(\n () => formatTokenPrice(token.amount, token.priceUSD, token.decimals),\n [token.amount, token.priceUSD, token.decimals]\n )\n\n const longPressEvents = useLongPress(() =>\n onShowTokenDetails(token.address, withoutContractAddress, token.chainId)\n )\n\n return (\n <ListItemButton\n onClick={handleClick}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n {...longPressEvents}\n dense\n selected={selected}\n sx={{\n height: 60,\n marginBottom: '4px',\n }}\n >\n <ListItemAvatar>\n {chain ? (\n <TokenAvatar\n token={token as StaticToken}\n chain={chain}\n tokenAvatarSize={40}\n chainAvatarSize={16}\n />\n ) : (\n <TokenListItemAvatar token={token} />\n )}\n </ListItemAvatar>\n <ListItemText\n primary={\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n {token.symbol}\n {!token.verified && (\n <Tooltip\n title={t('warning.message.unverifiedToken')}\n placement=\"top\"\n arrow\n >\n <WarningRounded\n sx={{\n display: 'flex',\n fontSize: 16,\n color: 'warning.main',\n cursor: 'help',\n }}\n />\n </Tooltip>\n )}\n </Box>\n }\n slotProps={{\n secondary: {\n component: 'div',\n },\n }}\n secondary={\n withoutContractAddress ? (\n <Box\n ref={container}\n sx={{\n height: 20,\n display: 'flex',\n }}\n >\n <Box\n sx={{\n pt: 0.25,\n }}\n >\n {token.name}\n </Box>\n <Box\n sx={{\n position: 'relative',\n }}\n >\n <Slide\n direction=\"up\"\n in={showAddress}\n container={container.current}\n style={{\n position: 'absolute',\n }}\n appear={false}\n mountOnEnter\n >\n <Box>\n <OpenTokenDetailsButton\n tokenAddress={token.address}\n withoutContractAddress={withoutContractAddress}\n chainId={token.chainId}\n onClick={onShowTokenDetails}\n />\n <PinTokenButton\n chainId={token.chainId}\n tokenAddress={token.address}\n />\n </Box>\n </Slide>\n </Box>\n </Box>\n ) : (\n <Box\n ref={container}\n sx={{\n position: 'relative',\n height: 20,\n }}\n >\n <Slide\n direction=\"down\"\n in={!showAddress}\n container={container.current}\n style={{\n position: 'absolute',\n }}\n appear={false}\n >\n <Box\n sx={{\n pt: 0.25,\n }}\n >\n {token.name}\n </Box>\n </Slide>\n <Slide\n direction=\"up\"\n in={showAddress}\n container={container.current}\n style={{\n position: 'absolute',\n }}\n appear={false}\n mountOnEnter\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 0.5,\n }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n pt: 0.125,\n }}\n >\n {shortenAddress(token.address)}\n </Box>\n <Box>\n <OpenTokenDetailsButton\n tokenAddress={token.address}\n withoutContractAddress={withoutContractAddress}\n chainId={token.chainId}\n onClick={onShowTokenDetails}\n />\n <PinTokenButton\n chainId={token.chainId}\n tokenAddress={token.address}\n />\n </Box>\n </Box>\n </Slide>\n </Box>\n )\n }\n />\n {isBalanceLoading ? (\n <TokenAmountSkeleton />\n ) : (\n <Box sx={{ textAlign: 'right' }}>\n {token.amount ? (\n <Typography\n noWrap\n sx={{\n fontWeight: 600,\n }}\n title={tokenAmount}\n >\n {t('format.tokenAmount', {\n value: tokenAmount,\n })}\n </Typography>\n ) : null}\n {token.amount && token.priceUSD ? (\n <Typography\n data-price={token.priceUSD}\n sx={{\n fontWeight: 500,\n fontSize: 12,\n color: 'text.secondary',\n }}\n >\n {t('format.currency', {\n value: tokenPrice,\n })}\n </Typography>\n ) : null}\n </Box>\n )}\n </ListItemButton>\n )\n }\n)\n\nexport const TokenListItemSkeleton = (): JSX.Element => {\n return (\n <ListItem\n secondaryAction={<TokenAmountSkeleton />}\n disablePadding\n sx={(theme) => ({\n position: 'relative',\n flexDirection: 'row',\n alignItems: 'center',\n padding: 0,\n [`& .${listItemSecondaryActionClasses.root}`]: {\n right: theme.spacing(1.5),\n },\n })}\n >\n <ListItemAvatar>\n <Skeleton\n variant=\"circular\"\n width={40}\n height={40}\n sx={{ marginLeft: 1.5, marginRight: 2 }}\n />\n </ListItemAvatar>\n <ListItemText\n primary={<Skeleton variant=\"text\" width={56} height={24} />}\n secondary={<Skeleton variant=\"text\" width={96} height={16} />}\n />\n </ListItem>\n )\n}\n\nconst TokenAmountSkeleton: React.FC = () => {\n return (\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n }}\n >\n <Skeleton variant=\"text\" width={56} height={24} />\n <Skeleton variant=\"text\" width={48} height={16} />\n </Box>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenNotFound.js","names":[],"sources":["../../../../src/components/TokenList/TokenNotFound.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { SearchNotFound } from '../Search/SearchNotFound.js'\n\nexport const TokenNotFound: React.FC<FormTypeProps> = () => {\n const { t } = useTranslation()\n\n return (\n <SearchNotFound message={t('info.message.emptyTokenListAllNetworks')} />\n )\n}\n"],"mappings":";;;;AAIA,MAAa,sBAA+C;CAC1D,MAAM,EAAE,MAAM,gBAAgB;
|
|
1
|
+
{"version":3,"file":"TokenNotFound.js","names":[],"sources":["../../../../src/components/TokenList/TokenNotFound.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { SearchNotFound } from '../Search/SearchNotFound.js'\n\nexport const TokenNotFound: React.FC<FormTypeProps> = () => {\n const { t } = useTranslation()\n\n return (\n <SearchNotFound message={t('info.message.emptyTokenListAllNetworks')} />\n )\n}\n"],"mappings":";;;;AAIA,MAAa,sBAA+C;CAC1D,MAAM,EAAE,MAAM,gBAAgB;CAE9B,OACE,oBAAC,gBAAD,EAAgB,SAAS,EAAE,yCAAyC,EAAI,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualizedTokenList.js","names":["List"],"sources":["../../../../src/components/TokenList/VirtualizedTokenList.tsx"],"sourcesContent":["import { Typography } from '@mui/material'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport type { FC } from 'react'\nimport { useCallback, useEffect, useMemo, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport type { TokenAmount } from '../../types/token.js'\nimport { TokenDetailsSheet } from './TokenDetailsSheet.js'\nimport { List } from './TokenList.style.js'\nimport { TokenListItem, TokenListItemSkeleton } from './TokenListItem.js'\nimport type {\n TokenDetailsSheetBase,\n VirtualizedTokenListProps,\n} from './types.js'\n\nconst tokenItemHeight = 64 // 60 + 4px margin-bottom\n\nexport const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({\n tokens,\n scrollElementRef,\n chainId,\n selectedTokenAddress,\n isLoading,\n isBalanceLoading,\n showCategories,\n showPinnedTokens,\n onClick,\n isAllNetworks,\n}) => {\n const { t } = useTranslation()\n\n const { chains } = useAvailableChains()\n\n // Create Set for O(1) chain lookup instead of O(n) find\n const chainsSet = useMemo(() => {\n if (!chains) {\n return undefined\n }\n return new Map(chains.map((chain) => [chain.id, chain]))\n }, [chains])\n\n const tokenDetailsSheetRef = useRef<TokenDetailsSheetBase>(null)\n\n const onShowTokenDetails = useCallback(\n (tokenAddress: string, noContractAddress: boolean, chainId: number) => {\n tokenDetailsSheetRef.current?.open(\n tokenAddress,\n noContractAddress,\n chainId\n )\n },\n []\n )\n\n const getItemKey = useCallback(\n (index: number) => {\n const token = tokens[index]\n return `${token.chainId}-${token.address}-${index}`\n },\n [tokens]\n )\n\n const estimateSize = useCallback(\n (index: number) => {\n const currentToken = tokens[index]\n const previousToken = tokens[index - 1]\n let size = tokenItemHeight\n\n // Pinned tokens (always shown, even in all networks mode)\n if (currentToken.pinned && index === 0) {\n size += 24\n }\n if (previousToken?.pinned && !currentToken.pinned) {\n size += 32\n }\n\n if (!showCategories) {\n return size\n }\n\n if (currentToken.featured && !currentToken.pinned && index === 0) {\n size += 24\n }\n\n // Category transition (excluding pinned tokens)\n const isNotPinned = !currentToken.pinned && !previousToken?.pinned\n if (\n isNotPinned &&\n ((previousToken?.amount && !currentToken.amount) ||\n (previousToken?.featured && !currentToken.featured) ||\n (previousToken?.popular && !currentToken.popular))\n ) {\n size += 32\n }\n\n return size\n },\n [tokens, showCategories]\n )\n\n const virtualizerConfig = useMemo(\n () => ({\n count: tokens.length,\n overscan: 5,\n getScrollElement: () => scrollElementRef.current,\n estimateSize,\n getItemKey,\n }),\n [tokens.length, estimateSize, getItemKey, scrollElementRef]\n )\n\n const { getVirtualItems, getTotalSize, scrollToIndex, measure } =\n useVirtualizer(virtualizerConfig)\n\n // Address the issue of disappearing tokens on rerender\n useEffect(() => {\n if (scrollElementRef.current) {\n measure()\n }\n }, [measure, scrollElementRef.current])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when chainId changes\n useEffect(() => {\n // Scroll to the top of the list when switching the chains\n if (getVirtualItems().length) {\n scrollToIndex(0, { align: 'start' })\n }\n // Close the token details sheet when switching the chains\n tokenDetailsSheetRef.current?.close()\n }, [scrollToIndex, isAllNetworks, chainId, getVirtualItems])\n\n return (\n <>\n <List\n className=\"long-list\"\n style={{ height: getTotalSize() }}\n disablePadding\n >\n {getVirtualItems().map((item) => {\n const currentToken = tokens[item.index]\n const previousToken: TokenAmount | undefined = tokens[item.index - 1]\n const chain = chainsSet?.get(currentToken.chainId)\n\n const isNotPinned = !currentToken.pinned\n const isFirstPinnedToken = currentToken.pinned && item.index === 0\n const isTransitionFromPinned = previousToken?.pinned && isNotPinned\n\n // Category transitions (excluding pinned)\n const isTransitionFromFeatured =\n previousToken?.featured && !currentToken.featured && isNotPinned\n const isTransitionFromMyTokens =\n previousToken?.amount && !currentToken.amount && isNotPinned\n const isTransitionFromPopular =\n previousToken?.popular && !currentToken.popular && isNotPinned\n\n // Determine which category label to show\n const startAdornmentLabel = (() => {\n if (showPinnedTokens && isFirstPinnedToken) {\n return t('main.pinnedTokens')\n }\n if (showPinnedTokens && !showCategories && isTransitionFromPinned) {\n return t('main.allTokens')\n }\n if (!showCategories) {\n return null\n }\n\n if (\n (isTransitionFromPinned && currentToken.featured) ||\n (currentToken.featured && isNotPinned && item.index === 0)\n ) {\n return t('main.featuredTokens')\n }\n if (\n (isTransitionFromFeatured || isTransitionFromPinned) &&\n currentToken.amount &&\n isNotPinned\n ) {\n return t('main.myTokens')\n }\n if (\n (isTransitionFromFeatured ||\n isTransitionFromMyTokens ||\n isTransitionFromPinned) &&\n currentToken.popular &&\n isNotPinned\n ) {\n return t('main.popularTokens')\n }\n if (\n isTransitionFromMyTokens ||\n isTransitionFromFeatured ||\n isTransitionFromPinned ||\n isTransitionFromPopular\n ) {\n return t('main.allTokens')\n }\n return null\n })()\n\n const isSelected =\n selectedTokenAddress === currentToken.address &&\n chainId === currentToken.chainId\n\n return (\n <TokenListItem\n key={item.key}\n onClick={onClick}\n size={item.size}\n start={item.start}\n token={currentToken}\n chain={isAllNetworks ? chain : undefined}\n selected={isSelected}\n onShowTokenDetails={onShowTokenDetails}\n isBalanceLoading={isBalanceLoading}\n startAdornment={\n startAdornmentLabel ? (\n <Typography\n sx={{\n fontSize: 14,\n fontWeight: 600,\n lineHeight: '16px',\n px: 1.5,\n pt:\n isFirstPinnedToken ||\n (currentToken.featured &&\n isNotPinned &&\n item.index === 0)\n ? 0\n : 1,\n pb: 1,\n }}\n >\n {startAdornmentLabel}\n </Typography>\n ) : null\n }\n />\n )\n })}\n </List>\n <TokenDetailsSheet ref={tokenDetailsSheetRef} />\n {isLoading && (\n <List disablePadding sx={{ cursor: 'default' }}>\n {Array.from({ length: 3 }).map((_, index) => (\n <TokenListItemSkeleton key={index} />\n ))}\n </List>\n )}\n </>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualizedTokenList.js","names":["List"],"sources":["../../../../src/components/TokenList/VirtualizedTokenList.tsx"],"sourcesContent":["import { Typography } from '@mui/material'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport type { FC } from 'react'\nimport { useCallback, useEffect, useMemo, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport type { TokenAmount } from '../../types/token.js'\nimport { TokenDetailsSheet } from './TokenDetailsSheet.js'\nimport { List } from './TokenList.style.js'\nimport { TokenListItem, TokenListItemSkeleton } from './TokenListItem.js'\nimport type {\n TokenDetailsSheetBase,\n VirtualizedTokenListProps,\n} from './types.js'\n\nconst tokenItemHeight = 64 // 60 + 4px margin-bottom\n\nexport const VirtualizedTokenList: FC<VirtualizedTokenListProps> = ({\n tokens,\n scrollElementRef,\n chainId,\n selectedTokenAddress,\n isLoading,\n isBalanceLoading,\n showCategories,\n showPinnedTokens,\n onClick,\n isAllNetworks,\n}) => {\n const { t } = useTranslation()\n\n const { chains } = useAvailableChains()\n\n // Create Set for O(1) chain lookup instead of O(n) find\n const chainsSet = useMemo(() => {\n if (!chains) {\n return undefined\n }\n return new Map(chains.map((chain) => [chain.id, chain]))\n }, [chains])\n\n const tokenDetailsSheetRef = useRef<TokenDetailsSheetBase>(null)\n\n const onShowTokenDetails = useCallback(\n (tokenAddress: string, noContractAddress: boolean, chainId: number) => {\n tokenDetailsSheetRef.current?.open(\n tokenAddress,\n noContractAddress,\n chainId\n )\n },\n []\n )\n\n const getItemKey = useCallback(\n (index: number) => {\n const token = tokens[index]\n return `${token.chainId}-${token.address}-${index}`\n },\n [tokens]\n )\n\n const estimateSize = useCallback(\n (index: number) => {\n const currentToken = tokens[index]\n const previousToken = tokens[index - 1]\n let size = tokenItemHeight\n\n // Pinned tokens (always shown, even in all networks mode)\n if (currentToken.pinned && index === 0) {\n size += 24\n }\n if (previousToken?.pinned && !currentToken.pinned) {\n size += 32\n }\n\n if (!showCategories) {\n return size\n }\n\n if (currentToken.featured && !currentToken.pinned && index === 0) {\n size += 24\n }\n\n // Category transition (excluding pinned tokens)\n const isNotPinned = !currentToken.pinned && !previousToken?.pinned\n if (\n isNotPinned &&\n ((previousToken?.amount && !currentToken.amount) ||\n (previousToken?.featured && !currentToken.featured) ||\n (previousToken?.popular && !currentToken.popular))\n ) {\n size += 32\n }\n\n return size\n },\n [tokens, showCategories]\n )\n\n const virtualizerConfig = useMemo(\n () => ({\n count: tokens.length,\n overscan: 5,\n getScrollElement: () => scrollElementRef.current,\n estimateSize,\n getItemKey,\n }),\n [tokens.length, estimateSize, getItemKey, scrollElementRef]\n )\n\n const { getVirtualItems, getTotalSize, scrollToIndex, measure } =\n useVirtualizer(virtualizerConfig)\n\n // Address the issue of disappearing tokens on rerender\n useEffect(() => {\n if (scrollElementRef.current) {\n measure()\n }\n }, [measure, scrollElementRef.current])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when chainId changes\n useEffect(() => {\n // Scroll to the top of the list when switching the chains\n if (getVirtualItems().length) {\n scrollToIndex(0, { align: 'start' })\n }\n // Close the token details sheet when switching the chains\n tokenDetailsSheetRef.current?.close()\n }, [scrollToIndex, isAllNetworks, chainId, getVirtualItems])\n\n return (\n <>\n <List\n className=\"long-list\"\n style={{ height: getTotalSize() }}\n disablePadding\n >\n {getVirtualItems().map((item) => {\n const currentToken = tokens[item.index]\n const previousToken: TokenAmount | undefined = tokens[item.index - 1]\n const chain = chainsSet?.get(currentToken.chainId)\n\n const isNotPinned = !currentToken.pinned\n const isFirstPinnedToken = currentToken.pinned && item.index === 0\n const isTransitionFromPinned = previousToken?.pinned && isNotPinned\n\n // Category transitions (excluding pinned)\n const isTransitionFromFeatured =\n previousToken?.featured && !currentToken.featured && isNotPinned\n const isTransitionFromMyTokens =\n previousToken?.amount && !currentToken.amount && isNotPinned\n const isTransitionFromPopular =\n previousToken?.popular && !currentToken.popular && isNotPinned\n\n // Determine which category label to show\n const startAdornmentLabel = (() => {\n if (showPinnedTokens && isFirstPinnedToken) {\n return t('main.pinnedTokens')\n }\n if (showPinnedTokens && !showCategories && isTransitionFromPinned) {\n return t('main.allTokens')\n }\n if (!showCategories) {\n return null\n }\n\n if (\n (isTransitionFromPinned && currentToken.featured) ||\n (currentToken.featured && isNotPinned && item.index === 0)\n ) {\n return t('main.featuredTokens')\n }\n if (\n (isTransitionFromFeatured || isTransitionFromPinned) &&\n currentToken.amount &&\n isNotPinned\n ) {\n return t('main.myTokens')\n }\n if (\n (isTransitionFromFeatured ||\n isTransitionFromMyTokens ||\n isTransitionFromPinned) &&\n currentToken.popular &&\n isNotPinned\n ) {\n return t('main.popularTokens')\n }\n if (\n isTransitionFromMyTokens ||\n isTransitionFromFeatured ||\n isTransitionFromPinned ||\n isTransitionFromPopular\n ) {\n return t('main.allTokens')\n }\n return null\n })()\n\n const isSelected =\n selectedTokenAddress === currentToken.address &&\n chainId === currentToken.chainId\n\n return (\n <TokenListItem\n key={item.key}\n onClick={onClick}\n size={item.size}\n start={item.start}\n token={currentToken}\n chain={isAllNetworks ? chain : undefined}\n selected={isSelected}\n onShowTokenDetails={onShowTokenDetails}\n isBalanceLoading={isBalanceLoading}\n startAdornment={\n startAdornmentLabel ? (\n <Typography\n sx={{\n fontSize: 14,\n fontWeight: 600,\n lineHeight: '16px',\n px: 1.5,\n pt:\n isFirstPinnedToken ||\n (currentToken.featured &&\n isNotPinned &&\n item.index === 0)\n ? 0\n : 1,\n pb: 1,\n }}\n >\n {startAdornmentLabel}\n </Typography>\n ) : null\n }\n />\n )\n })}\n </List>\n <TokenDetailsSheet ref={tokenDetailsSheetRef} />\n {isLoading && (\n <List disablePadding sx={{ cursor: 'default' }}>\n {Array.from({ length: 3 }).map((_, index) => (\n <TokenListItemSkeleton key={index} />\n ))}\n </List>\n )}\n </>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenSelect.js","names":[],"sources":["../../../../src/components/TokenList/useTokenSelect.ts"],"sourcesContent":["import { useCallback } from 'react'\nimport { useToAddressAutoPopulate } from '../../hooks/useToAddressAutoPopulate.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'\nimport type { FormType } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useSplitSubvariantStore } from '../../stores/settings/useSplitSubvariantStore.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport type { DisabledUI } from '../../types/widget.js'\nimport { isItemAllowed } from '../../utils/item.js'\n\nexport const useTokenSelect = (\n formType: FormType,\n onClick?: () => void\n): ((tokenAddress: string, chainId?: number) => void) => {\n const { subvariant, disabledUI, chains: chainsConfig } = useWidgetConfig()\n const splitSubvariant = useSplitSubvariantStore((store) => store.state)\n const emitter = useWidgetEvents()\n const { setFieldValue, getFieldValues } = useFieldActions()\n const autoPopulateToAddress = useToAddressAutoPopulate()\n const [setChain, setIsAllNetworks] = useChainOrderStore((state) => [\n state.setChain,\n state.setIsAllNetworks,\n ])\n\n const tokenKey = FormKeyHelper.getTokenKey(formType)\n\n return useCallback(\n (tokenAddress: string, chainId?: number) => {\n setFieldValue(tokenKey, tokenAddress, { isDirty: true, isTouched: true })\n const selectedChainId =\n chainId ?? getFieldValues(FormKeyHelper.getChainKey(formType))[0]\n // Set chain again to trigger URL builder update\n setFieldValue(FormKeyHelper.getChainKey(formType), selectedChainId, {\n isDirty: true,\n isTouched: true,\n })\n const amountKey = FormKeyHelper.getAmountKey(formType)\n if (!disabledUI?.includes(amountKey as DisabledUI)) {\n setFieldValue(amountKey, '')\n }\n const oppositeFormType = formType === 'from' ? 'to' : 'from'\n const [\n selectedOppositeTokenAddress,\n selectedOppositeChainId,\n selectedToAddress,\n ] = getFieldValues(\n FormKeyHelper.getTokenKey(oppositeFormType),\n FormKeyHelper.getChainKey(oppositeFormType),\n 'toAddress'\n )\n\n // TODO: remove when we enable same chain/token transfers\n const isSameTokenTransfer =\n selectedOppositeTokenAddress === tokenAddress &&\n selectedOppositeChainId === selectedChainId\n\n const isBridgeToSameChain =\n subvariant === 'split' &&\n splitSubvariant === 'bridge' &&\n selectedOppositeChainId === selectedChainId\n\n if (\n (isSameTokenTransfer || isBridgeToSameChain) &&\n subvariant !== 'custom'\n ) {\n setFieldValue(FormKeyHelper.getTokenKey(oppositeFormType), '', {\n isDirty: true,\n isTouched: true,\n })\n }\n\n // If no opposite token is selected, synchronize the opposite chain\n // to match the currently selected chain (if allowed).\n // In default exchange mode, also collapse \"All Networks\" on the opposite\n // side - same-chain swap is the most common action.\n if (\n !selectedOppositeTokenAddress &&\n selectedChainId &&\n isItemAllowed(selectedChainId, chainsConfig?.[oppositeFormType])\n ) {\n const isDefaultExchange = !subvariant || subvariant === 'default'\n if (isDefaultExchange) {\n setIsAllNetworks(false, oppositeFormType)\n }\n setFieldValue(\n FormKeyHelper.getChainKey(oppositeFormType),\n selectedChainId,\n {\n isDirty: true,\n isTouched: true,\n }\n )\n setChain(selectedChainId, oppositeFormType)\n }\n\n // Automatically populate toAddress field if bridging across ecosystems and compatible wallet is connected\n autoPopulateToAddress({\n formType,\n selectedToAddress,\n selectedChainId,\n selectedOppositeChainId,\n selectedOppositeTokenAddress,\n })\n\n const eventToEmit =\n formType === 'from'\n ? WidgetEvent.SourceChainTokenSelected\n : WidgetEvent.DestinationChainTokenSelected\n\n if (selectedChainId) {\n emitter.emit(eventToEmit, {\n chainId: selectedChainId,\n tokenAddress,\n })\n }\n\n onClick?.()\n },\n [\n autoPopulateToAddress,\n disabledUI,\n emitter,\n formType,\n getFieldValues,\n onClick,\n setChain,\n setIsAllNetworks,\n setFieldValue,\n subvariant,\n splitSubvariant,\n tokenKey,\n chainsConfig,\n ]\n )\n}\n"],"mappings":";;;;;;;;;;;AAaA,MAAa,kBACX,UACA,YACuD;CACvD,MAAM,EAAE,YAAY,YAAY,QAAQ,iBAAiB,iBAAiB;CAC1E,MAAM,kBAAkB,yBAAyB,UAAU,MAAM,MAAM;CACvE,MAAM,UAAU,iBAAiB;CACjC,MAAM,EAAE,eAAe,mBAAmB,iBAAiB;CAC3D,MAAM,wBAAwB,0BAA0B;CACxD,MAAM,CAAC,UAAU,oBAAoB,oBAAoB,UAAU,CACjE,MAAM,UACN,MAAM,iBACP,CAAC;CAEF,MAAM,WAAW,cAAc,YAAY,SAAS;
|
|
1
|
+
{"version":3,"file":"useTokenSelect.js","names":[],"sources":["../../../../src/components/TokenList/useTokenSelect.ts"],"sourcesContent":["import { useCallback } from 'react'\nimport { useToAddressAutoPopulate } from '../../hooks/useToAddressAutoPopulate.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'\nimport type { FormType } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useSplitSubvariantStore } from '../../stores/settings/useSplitSubvariantStore.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport type { DisabledUI } from '../../types/widget.js'\nimport { isItemAllowed } from '../../utils/item.js'\n\nexport const useTokenSelect = (\n formType: FormType,\n onClick?: () => void\n): ((tokenAddress: string, chainId?: number) => void) => {\n const { subvariant, disabledUI, chains: chainsConfig } = useWidgetConfig()\n const splitSubvariant = useSplitSubvariantStore((store) => store.state)\n const emitter = useWidgetEvents()\n const { setFieldValue, getFieldValues } = useFieldActions()\n const autoPopulateToAddress = useToAddressAutoPopulate()\n const [setChain, setIsAllNetworks] = useChainOrderStore((state) => [\n state.setChain,\n state.setIsAllNetworks,\n ])\n\n const tokenKey = FormKeyHelper.getTokenKey(formType)\n\n return useCallback(\n (tokenAddress: string, chainId?: number) => {\n setFieldValue(tokenKey, tokenAddress, { isDirty: true, isTouched: true })\n const selectedChainId =\n chainId ?? getFieldValues(FormKeyHelper.getChainKey(formType))[0]\n // Set chain again to trigger URL builder update\n setFieldValue(FormKeyHelper.getChainKey(formType), selectedChainId, {\n isDirty: true,\n isTouched: true,\n })\n const amountKey = FormKeyHelper.getAmountKey(formType)\n if (!disabledUI?.includes(amountKey as DisabledUI)) {\n setFieldValue(amountKey, '')\n }\n const oppositeFormType = formType === 'from' ? 'to' : 'from'\n const [\n selectedOppositeTokenAddress,\n selectedOppositeChainId,\n selectedToAddress,\n ] = getFieldValues(\n FormKeyHelper.getTokenKey(oppositeFormType),\n FormKeyHelper.getChainKey(oppositeFormType),\n 'toAddress'\n )\n\n // TODO: remove when we enable same chain/token transfers\n const isSameTokenTransfer =\n selectedOppositeTokenAddress === tokenAddress &&\n selectedOppositeChainId === selectedChainId\n\n const isBridgeToSameChain =\n subvariant === 'split' &&\n splitSubvariant === 'bridge' &&\n selectedOppositeChainId === selectedChainId\n\n if (\n (isSameTokenTransfer || isBridgeToSameChain) &&\n subvariant !== 'custom'\n ) {\n setFieldValue(FormKeyHelper.getTokenKey(oppositeFormType), '', {\n isDirty: true,\n isTouched: true,\n })\n }\n\n // If no opposite token is selected, synchronize the opposite chain\n // to match the currently selected chain (if allowed).\n // In default exchange mode, also collapse \"All Networks\" on the opposite\n // side - same-chain swap is the most common action.\n if (\n !selectedOppositeTokenAddress &&\n selectedChainId &&\n isItemAllowed(selectedChainId, chainsConfig?.[oppositeFormType])\n ) {\n const isDefaultExchange = !subvariant || subvariant === 'default'\n if (isDefaultExchange) {\n setIsAllNetworks(false, oppositeFormType)\n }\n setFieldValue(\n FormKeyHelper.getChainKey(oppositeFormType),\n selectedChainId,\n {\n isDirty: true,\n isTouched: true,\n }\n )\n setChain(selectedChainId, oppositeFormType)\n }\n\n // Automatically populate toAddress field if bridging across ecosystems and compatible wallet is connected\n autoPopulateToAddress({\n formType,\n selectedToAddress,\n selectedChainId,\n selectedOppositeChainId,\n selectedOppositeTokenAddress,\n })\n\n const eventToEmit =\n formType === 'from'\n ? WidgetEvent.SourceChainTokenSelected\n : WidgetEvent.DestinationChainTokenSelected\n\n if (selectedChainId) {\n emitter.emit(eventToEmit, {\n chainId: selectedChainId,\n tokenAddress,\n })\n }\n\n onClick?.()\n },\n [\n autoPopulateToAddress,\n disabledUI,\n emitter,\n formType,\n getFieldValues,\n onClick,\n setChain,\n setIsAllNetworks,\n setFieldValue,\n subvariant,\n splitSubvariant,\n tokenKey,\n chainsConfig,\n ]\n )\n}\n"],"mappings":";;;;;;;;;;;AAaA,MAAa,kBACX,UACA,YACuD;CACvD,MAAM,EAAE,YAAY,YAAY,QAAQ,iBAAiB,iBAAiB;CAC1E,MAAM,kBAAkB,yBAAyB,UAAU,MAAM,MAAM;CACvE,MAAM,UAAU,iBAAiB;CACjC,MAAM,EAAE,eAAe,mBAAmB,iBAAiB;CAC3D,MAAM,wBAAwB,0BAA0B;CACxD,MAAM,CAAC,UAAU,oBAAoB,oBAAoB,UAAU,CACjE,MAAM,UACN,MAAM,iBACP,CAAC;CAEF,MAAM,WAAW,cAAc,YAAY,SAAS;CAEpD,OAAO,aACJ,cAAsB,YAAqB;EAC1C,cAAc,UAAU,cAAc;GAAE,SAAS;GAAM,WAAW;GAAM,CAAC;EACzE,MAAM,kBACJ,WAAW,eAAe,cAAc,YAAY,SAAS,CAAC,CAAC;EAEjE,cAAc,cAAc,YAAY,SAAS,EAAE,iBAAiB;GAClE,SAAS;GACT,WAAW;GACZ,CAAC;EACF,MAAM,YAAY,cAAc,aAAa,SAAS;EACtD,IAAI,CAAC,YAAY,SAAS,UAAwB,EAChD,cAAc,WAAW,GAAG;EAE9B,MAAM,mBAAmB,aAAa,SAAS,OAAO;EACtD,MAAM,CACJ,8BACA,yBACA,qBACE,eACF,cAAc,YAAY,iBAAiB,EAC3C,cAAc,YAAY,iBAAiB,EAC3C,YACD;EAYD,KARE,iCAAiC,gBACjC,4BAA4B,mBAG5B,eAAe,WACf,oBAAoB,YACpB,4BAA4B,oBAI5B,eAAe,UAEf,cAAc,cAAc,YAAY,iBAAiB,EAAE,IAAI;GAC7D,SAAS;GACT,WAAW;GACZ,CAAC;EAOJ,IACE,CAAC,gCACD,mBACA,cAAc,iBAAiB,eAAe,kBAAkB,EAChE;GAEA,IAD0B,CAAC,cAAc,eAAe,WAEtD,iBAAiB,OAAO,iBAAiB;GAE3C,cACE,cAAc,YAAY,iBAAiB,EAC3C,iBACA;IACE,SAAS;IACT,WAAW;IACZ,CACF;GACD,SAAS,iBAAiB,iBAAiB;;EAI7C,sBAAsB;GACpB;GACA;GACA;GACA;GACA;GACD,CAAC;EAEF,MAAM,cACJ,aAAa,SAAA,6BAAA;EAIf,IAAI,iBACF,QAAQ,KAAK,aAAa;GACxB,SAAS;GACT;GACD,CAAC;EAGJ,WAAW;IAEb;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenRate.js","names":[],"sources":["../../../../src/components/TokenRate/TokenRate.tsx"],"sourcesContent":["import { formatUnits, type RouteExtended } from '@lifi/sdk'\nimport type { TypographyProps } from '@mui/material'\nimport type { MouseEventHandler } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { create } from 'zustand'\nimport { TokenRateTypography } from './TokenRate.style.js'\n\ninterface TokenRateProps extends TypographyProps {\n route: RouteExtended\n}\n\ninterface TokenRateState {\n isForward: boolean\n toggleIsForward(): void\n}\n\nconst useTokenRate = create<TokenRateState>((set) => ({\n isForward: true,\n toggleIsForward: () => set((state) => ({ isForward: !state.isForward })),\n}))\n\nexport const TokenRate: React.FC<TokenRateProps> = ({ route }) => {\n const { t } = useTranslation()\n const { isForward, toggleIsForward } = useTokenRate()\n\n const toggleRate: MouseEventHandler<HTMLSpanElement> = (e) => {\n e.stopPropagation()\n toggleIsForward()\n }\n\n const lastStep = route.steps.at(-1)\n\n const fromToken = {\n ...route.fromToken,\n amount: BigInt(route.fromAmount),\n }\n const toToken = {\n ...(lastStep?.execution?.toToken ??\n lastStep?.action.toToken ??\n route.toToken),\n amount: lastStep?.execution?.toAmount\n ? BigInt(lastStep.execution.toAmount)\n : BigInt(route.toAmount),\n }\n\n const fromToRate =\n Number.parseFloat(formatUnits(toToken.amount!, toToken.decimals)) /\n Number.parseFloat(formatUnits(fromToken.amount!, fromToken.decimals))\n const toFromRate =\n Number.parseFloat(formatUnits(fromToken.amount!, fromToken.decimals)) /\n Number.parseFloat(formatUnits(toToken.amount!, toToken.decimals))\n\n const rateText = isForward\n ? `1 ${fromToken.symbol} ≈ ${t('format.tokenAmount', { value: fromToRate })} ${toToken.symbol}`\n : `1 ${toToken.symbol} ≈ ${t('format.tokenAmount', { value: toFromRate })} ${fromToken.symbol}`\n\n return (\n <TokenRateTypography onClick={toggleRate} role=\"button\">\n {rateText}\n </TokenRateTypography>\n )\n}\n"],"mappings":";;;;;;AAgBA,MAAM,eAAe,QAAwB,SAAS;CACpD,WAAW;CACX,uBAAuB,KAAK,WAAW,EAAE,WAAW,CAAC,MAAM,WAAW,EAAE;CACzE,EAAE;AAEH,MAAa,aAAuC,EAAE,YAAY;CAChE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,WAAW,oBAAoB,cAAc;CAErD,MAAM,cAAkD,MAAM;
|
|
1
|
+
{"version":3,"file":"TokenRate.js","names":[],"sources":["../../../../src/components/TokenRate/TokenRate.tsx"],"sourcesContent":["import { formatUnits, type RouteExtended } from '@lifi/sdk'\nimport type { TypographyProps } from '@mui/material'\nimport type { MouseEventHandler } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { create } from 'zustand'\nimport { TokenRateTypography } from './TokenRate.style.js'\n\ninterface TokenRateProps extends TypographyProps {\n route: RouteExtended\n}\n\ninterface TokenRateState {\n isForward: boolean\n toggleIsForward(): void\n}\n\nconst useTokenRate = create<TokenRateState>((set) => ({\n isForward: true,\n toggleIsForward: () => set((state) => ({ isForward: !state.isForward })),\n}))\n\nexport const TokenRate: React.FC<TokenRateProps> = ({ route }) => {\n const { t } = useTranslation()\n const { isForward, toggleIsForward } = useTokenRate()\n\n const toggleRate: MouseEventHandler<HTMLSpanElement> = (e) => {\n e.stopPropagation()\n toggleIsForward()\n }\n\n const lastStep = route.steps.at(-1)\n\n const fromToken = {\n ...route.fromToken,\n amount: BigInt(route.fromAmount),\n }\n const toToken = {\n ...(lastStep?.execution?.toToken ??\n lastStep?.action.toToken ??\n route.toToken),\n amount: lastStep?.execution?.toAmount\n ? BigInt(lastStep.execution.toAmount)\n : BigInt(route.toAmount),\n }\n\n const fromToRate =\n Number.parseFloat(formatUnits(toToken.amount!, toToken.decimals)) /\n Number.parseFloat(formatUnits(fromToken.amount!, fromToken.decimals))\n const toFromRate =\n Number.parseFloat(formatUnits(fromToken.amount!, fromToken.decimals)) /\n Number.parseFloat(formatUnits(toToken.amount!, toToken.decimals))\n\n const rateText = isForward\n ? `1 ${fromToken.symbol} ≈ ${t('format.tokenAmount', { value: fromToRate })} ${toToken.symbol}`\n : `1 ${toToken.symbol} ≈ ${t('format.tokenAmount', { value: toFromRate })} ${fromToken.symbol}`\n\n return (\n <TokenRateTypography onClick={toggleRate} role=\"button\">\n {rateText}\n </TokenRateTypography>\n )\n}\n"],"mappings":";;;;;;AAgBA,MAAM,eAAe,QAAwB,SAAS;CACpD,WAAW;CACX,uBAAuB,KAAK,WAAW,EAAE,WAAW,CAAC,MAAM,WAAW,EAAE;CACzE,EAAE;AAEH,MAAa,aAAuC,EAAE,YAAY;CAChE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,WAAW,oBAAoB,cAAc;CAErD,MAAM,cAAkD,MAAM;EAC5D,EAAE,iBAAiB;EACnB,iBAAiB;;CAGnB,MAAM,WAAW,MAAM,MAAM,GAAG,GAAG;CAEnC,MAAM,YAAY;EAChB,GAAG,MAAM;EACT,QAAQ,OAAO,MAAM,WAAW;EACjC;CACD,MAAM,UAAU;EACd,GAAI,UAAU,WAAW,WACvB,UAAU,OAAO,WACjB,MAAM;EACR,QAAQ,UAAU,WAAW,WACzB,OAAO,SAAS,UAAU,SAAS,GACnC,OAAO,MAAM,SAAS;EAC3B;CAED,MAAM,aACJ,OAAO,WAAW,YAAY,QAAQ,QAAS,QAAQ,SAAS,CAAC,GACjE,OAAO,WAAW,YAAY,UAAU,QAAS,UAAU,SAAS,CAAC;CACvE,MAAM,aACJ,OAAO,WAAW,YAAY,UAAU,QAAS,UAAU,SAAS,CAAC,GACrE,OAAO,WAAW,YAAY,QAAQ,QAAS,QAAQ,SAAS,CAAC;CAMnE,OACE,oBAAC,qBAAD;EAAqB,SAAS;EAAY,MAAK;YALhC,YACb,KAAK,UAAU,OAAO,KAAK,EAAE,sBAAsB,EAAE,OAAO,YAAY,CAAC,CAAC,GAAG,QAAQ,WACrF,KAAK,QAAQ,OAAO,KAAK,EAAE,sBAAsB,EAAE,OAAO,YAAY,CAAC,CAAC,GAAG,UAAU;EAKjE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolItem.js","names":["ListItemText"],"sources":["../../../../src/components/Tools/ToolItem.tsx"],"sourcesContent":["import { Avatar, Checkbox, ListItemAvatar } from '@mui/material'\nimport { memo, type NamedExoticComponent } from 'react'\nimport { ListItemText } from '../ListItemText.js'\nimport { SettingsListItemButton } from '../SettingsListItemButton.js'\n\ninterface ToolItemProps {\n tool: any\n typeKey: string\n isEnabled: boolean\n onToggle: (key: string) => void\n}\n\nexport const ToolItem: NamedExoticComponent<ToolItemProps> =\n memo<ToolItemProps>(({ tool, typeKey, isEnabled, onToggle }) => {\n const handleClick = () => {\n onToggle(tool.key)\n }\n\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n onToggle(tool.key)\n }\n\n return (\n <SettingsListItemButton onClick={handleClick}>\n <ListItemAvatar>\n <Avatar src={tool.logoURI} alt={tool.name}>\n {tool.name[0]}\n </Avatar>\n </ListItemAvatar>\n <ListItemText primary={tool.name} />\n <Checkbox\n id={`${typeKey}-${tool.key}-checkbox`}\n checked={isEnabled}\n onChange={handleClick}\n onClick={handleCheckboxClick}\n sx={{ mr: -1 }}\n />\n </SettingsListItemButton>\n )\n })\n"],"mappings":";;;;;;AAYA,MAAa,WACX,MAAqB,EAAE,MAAM,SAAS,WAAW,eAAe;CAC9D,MAAM,oBAAoB;
|
|
1
|
+
{"version":3,"file":"ToolItem.js","names":["ListItemText"],"sources":["../../../../src/components/Tools/ToolItem.tsx"],"sourcesContent":["import { Avatar, Checkbox, ListItemAvatar } from '@mui/material'\nimport { memo, type NamedExoticComponent } from 'react'\nimport { ListItemText } from '../ListItemText.js'\nimport { SettingsListItemButton } from '../SettingsListItemButton.js'\n\ninterface ToolItemProps {\n tool: any\n typeKey: string\n isEnabled: boolean\n onToggle: (key: string) => void\n}\n\nexport const ToolItem: NamedExoticComponent<ToolItemProps> =\n memo<ToolItemProps>(({ tool, typeKey, isEnabled, onToggle }) => {\n const handleClick = () => {\n onToggle(tool.key)\n }\n\n const handleCheckboxClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n onToggle(tool.key)\n }\n\n return (\n <SettingsListItemButton onClick={handleClick}>\n <ListItemAvatar>\n <Avatar src={tool.logoURI} alt={tool.name}>\n {tool.name[0]}\n </Avatar>\n </ListItemAvatar>\n <ListItemText primary={tool.name} />\n <Checkbox\n id={`${typeKey}-${tool.key}-checkbox`}\n checked={isEnabled}\n onChange={handleClick}\n onClick={handleCheckboxClick}\n sx={{ mr: -1 }}\n />\n </SettingsListItemButton>\n )\n })\n"],"mappings":";;;;;;AAYA,MAAa,WACX,MAAqB,EAAE,MAAM,SAAS,WAAW,eAAe;CAC9D,MAAM,oBAAoB;EACxB,SAAS,KAAK,IAAI;;CAGpB,MAAM,uBAAuB,MAAwB;EACnD,EAAE,iBAAiB;EACnB,SAAS,KAAK,IAAI;;CAGpB,OACE,qBAAC,wBAAD;EAAwB,SAAS;YAAjC;GACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,QAAD;IAAQ,KAAK,KAAK;IAAS,KAAK,KAAK;cAClC,KAAK,KAAK;IACJ,CAAA,EACM,CAAA;GACjB,oBAACA,gBAAD,EAAc,SAAS,KAAK,MAAQ,CAAA;GACpC,oBAAC,UAAD;IACE,IAAI,GAAG,QAAQ,GAAG,KAAK,IAAI;IAC3B,SAAS;IACT,UAAU;IACV,SAAS;IACT,IAAI,EAAE,IAAI,IAAI;IACd,CAAA;GACqB;;EAE3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tools.js","names":[],"sources":["../../../../src/components/Tools/Tools.tsx"],"sourcesContent":["import type { ToolsResponse } from '@lifi/sdk'\nimport { type JSX, useMemo, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useSettingsStore } from '../../stores/settings/SettingsStore.js'\nimport { useSettingsActions } from '../../stores/settings/useSettingsActions.js'\nimport { SearchList } from '../Search/SearchInput.style.js'\nimport { SearchNotFound } from '../Search/SearchNotFound.js'\nimport { ToolItem } from './ToolItem.js'\n\nexport type ToolCollectionTypes =\n | ToolsResponse['exchanges']\n | ToolsResponse['bridges']\n\ninterface ToolsProps {\n filteredTools: ToolCollectionTypes\n type: 'Bridges' | 'Exchanges'\n}\n\nexport const Tools = ({ filteredTools, type }: ToolsProps): JSX.Element => {\n const { t } = useTranslation()\n const typeKey = type.toLowerCase() as 'bridges' | 'exchanges'\n const enabledTools = useSettingsStore((state) => state[`_enabled${type}`])\n const { setToolValue } = useSettingsActions()\n\n // Use ref to access current enabledTools without causing re-renders\n const enabledToolsRef = useRef(enabledTools)\n enabledToolsRef.current = enabledTools\n const toggleCallbacks = useMemo(() => {\n const callbacks: Record<string, () => void> = {}\n filteredTools.forEach((tool) => {\n callbacks[tool.key] = () => {\n // Access current state via ref to avoid dependency on enabledTools\n setToolValue(type, tool.key, !enabledToolsRef.current[tool.key])\n }\n })\n return callbacks\n }, [filteredTools, setToolValue, type])\n\n if (!filteredTools.length) {\n return (\n <SearchNotFound\n message={t(`info.message.empty${type}List`)}\n adjustForStickySearchInput\n />\n )\n }\n\n return (\n <SearchList className=\"long-list\" data-testid={`${typeKey}-list`}>\n {filteredTools.map((tool) => (\n <ToolItem\n key={tool.key}\n tool={tool}\n typeKey={typeKey}\n isEnabled={enabledTools[tool.key]}\n onToggle={toggleCallbacks[tool.key]}\n />\n ))}\n </SearchList>\n )\n}\n"],"mappings":";;;;;;;;;AAkBA,MAAa,SAAS,EAAE,eAAe,WAAoC;CACzE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,UAAU,KAAK,aAAa;CAClC,MAAM,eAAe,kBAAkB,UAAU,MAAM,WAAW,QAAQ;CAC1E,MAAM,EAAE,iBAAiB,oBAAoB;CAG7C,MAAM,kBAAkB,OAAO,aAAa;
|
|
1
|
+
{"version":3,"file":"Tools.js","names":[],"sources":["../../../../src/components/Tools/Tools.tsx"],"sourcesContent":["import type { ToolsResponse } from '@lifi/sdk'\nimport { type JSX, useMemo, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useSettingsStore } from '../../stores/settings/SettingsStore.js'\nimport { useSettingsActions } from '../../stores/settings/useSettingsActions.js'\nimport { SearchList } from '../Search/SearchInput.style.js'\nimport { SearchNotFound } from '../Search/SearchNotFound.js'\nimport { ToolItem } from './ToolItem.js'\n\nexport type ToolCollectionTypes =\n | ToolsResponse['exchanges']\n | ToolsResponse['bridges']\n\ninterface ToolsProps {\n filteredTools: ToolCollectionTypes\n type: 'Bridges' | 'Exchanges'\n}\n\nexport const Tools = ({ filteredTools, type }: ToolsProps): JSX.Element => {\n const { t } = useTranslation()\n const typeKey = type.toLowerCase() as 'bridges' | 'exchanges'\n const enabledTools = useSettingsStore((state) => state[`_enabled${type}`])\n const { setToolValue } = useSettingsActions()\n\n // Use ref to access current enabledTools without causing re-renders\n const enabledToolsRef = useRef(enabledTools)\n enabledToolsRef.current = enabledTools\n const toggleCallbacks = useMemo(() => {\n const callbacks: Record<string, () => void> = {}\n filteredTools.forEach((tool) => {\n callbacks[tool.key] = () => {\n // Access current state via ref to avoid dependency on enabledTools\n setToolValue(type, tool.key, !enabledToolsRef.current[tool.key])\n }\n })\n return callbacks\n }, [filteredTools, setToolValue, type])\n\n if (!filteredTools.length) {\n return (\n <SearchNotFound\n message={t(`info.message.empty${type}List`)}\n adjustForStickySearchInput\n />\n )\n }\n\n return (\n <SearchList className=\"long-list\" data-testid={`${typeKey}-list`}>\n {filteredTools.map((tool) => (\n <ToolItem\n key={tool.key}\n tool={tool}\n typeKey={typeKey}\n isEnabled={enabledTools[tool.key]}\n onToggle={toggleCallbacks[tool.key]}\n />\n ))}\n </SearchList>\n )\n}\n"],"mappings":";;;;;;;;;AAkBA,MAAa,SAAS,EAAE,eAAe,WAAoC;CACzE,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,UAAU,KAAK,aAAa;CAClC,MAAM,eAAe,kBAAkB,UAAU,MAAM,WAAW,QAAQ;CAC1E,MAAM,EAAE,iBAAiB,oBAAoB;CAG7C,MAAM,kBAAkB,OAAO,aAAa;CAC5C,gBAAgB,UAAU;CAC1B,MAAM,kBAAkB,cAAc;EACpC,MAAM,YAAwC,EAAE;EAChD,cAAc,SAAS,SAAS;GAC9B,UAAU,KAAK,aAAa;IAE1B,aAAa,MAAM,KAAK,KAAK,CAAC,gBAAgB,QAAQ,KAAK,KAAK;;IAElE;EACF,OAAO;IACN;EAAC;EAAe;EAAc;EAAK,CAAC;CAEvC,IAAI,CAAC,cAAc,QACjB,OACE,oBAAC,gBAAD;EACE,SAAS,EAAE,qBAAqB,KAAK,MAAM;EAC3C,4BAAA;EACA,CAAA;CAIN,OACE,oBAAC,YAAD;EAAY,WAAU;EAAY,eAAa,GAAG,QAAQ;YACvD,cAAc,KAAK,SAClB,oBAAC,UAAD;GAEQ;GACG;GACT,WAAW,aAAa,KAAK;GAC7B,UAAU,gBAAgB,KAAK;GAC/B,EALK,KAAK,IAKV,CACF;EACS,CAAA"}
|