From 808221a1a64a8515d976b87ede1a289d18513ca1 Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Tue, 17 Dec 2024 15:30:57 -0500 Subject: [PATCH 1/4] start work on converting existing chain selection dropdowns to Zeego --- .../components/TokenList/ChainSelection.tsx | 52 +++++-------------- src/components/DropdownMenu.tsx | 37 ++++++++++--- src/state/backendNetworks/backendNetworks.ts | 11 ++++ 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx b/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx index 6e803ae4904..814902dd8e4 100644 --- a/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx +++ b/src/__swaps__/screens/Swap/components/TokenList/ChainSelection.tsx @@ -10,15 +10,13 @@ import { ChainId } from '@/state/backendNetworks/types'; import { opacity } from '@/__swaps__/utils/swaps'; import { analyticsV2 } from '@/analytics'; import { ChainImage } from '@/components/coin-icon/ChainImage'; -import { ContextMenuButton } from '@/components/context-menu'; import { AnimatedText, Bleed, Box, Inline, Text, TextIcon, globalColors, useColorMode } from '@/design-system'; import { useAccountAccentColor } from '@/hooks'; import { useSharedValueState } from '@/hooks/reanimated/useSharedValueState'; import { userAssetsStore, useUserAssetsStore } from '@/state/assets/userAssets'; import { swapsStore } from '@/state/swaps/swapsStore'; -import { showActionSheetWithOptions } from '@/utils'; -import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; -import { getChainsLabelWorklet, getChainsNameWorklet, useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks'; +import { getChainsBadgeWorklet, getChainsLabelWorklet, useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks'; +import { DropdownMenu, MenuItem } from '@/components/DropdownMenu'; type ChainSelectionProps = { allText?: string; @@ -58,7 +56,7 @@ export const ChainSelection = memo(function ChainSelection({ allText, output }: }); const handleSelectChain = useCallback( - ({ nativeEvent: { actionKey } }: Omit) => { + (actionKey: string) => { analyticsV2.track(analyticsV2.event.swapsChangedChainId, { inputAsset: swapsStore.getState().inputAsset, type: output ? 'output' : 'input', @@ -78,14 +76,16 @@ export const ChainSelection = memo(function ChainSelection({ allText, output }: ); const menuConfig = useMemo(() => { - const supportedChains = balanceSortedChainList.map(chainId => { + let supportedChains: MenuItem[] = []; + supportedChains = balanceSortedChainList.map(chainId => { return { actionKey: `${chainId}`, actionTitle: getChainsLabelWorklet(backendNetworks)[chainId], icon: { - iconType: 'ASSET', - // NOTE: chainsName[chainId] for mainnet is 'mainnet' and we need it to be 'ethereum' - iconValue: chainId === ChainId.mainnet ? 'ethereumBadge' : `${getChainsNameWorklet(backendNetworks)[chainId]}BadgeNoShadow`, + iconType: 'REMOTE', + iconValue: { + uri: getChainsBadgeWorklet(backendNetworks)[chainId], + }, }, }; }); @@ -95,8 +95,8 @@ export const ChainSelection = memo(function ChainSelection({ allText, output }: actionKey: 'all', actionTitle: i18n.t(i18n.l.exchange.all_networks), icon: { - iconType: 'icon', - iconValue: '􀆪', + iconType: 'SYSTEM', + iconValue: 'globe', }, }); } @@ -106,24 +106,6 @@ export const ChainSelection = memo(function ChainSelection({ allText, output }: }; }, [backendNetworks, balanceSortedChainList, output]); - const onShowActionSheet = useCallback(() => { - const chainTitles = menuConfig.menuItems.map(chain => chain.actionTitle); - - showActionSheetWithOptions( - { - options: chainTitles, - showSeparators: true, - }, - (index: number | undefined) => { - // NOTE: When they click away from the menu, the index is undefined - if (typeof index === 'undefined') return; - handleSelectChain({ - nativeEvent: { actionKey: menuConfig.menuItems[index].actionKey, actionTitle: '' }, - }); - } - ); - }, [handleSelectChain, menuConfig.menuItems]); - return ( @@ -166,16 +148,8 @@ export const ChainSelection = memo(function ChainSelection({ allText, output }: )} - + - {/* TODO: We need to add some ethereum utils to handle worklet functions */} {chainName} @@ -184,7 +158,7 @@ export const ChainSelection = memo(function ChainSelection({ allText, output }: 􀆏 - + ); diff --git a/src/components/DropdownMenu.tsx b/src/components/DropdownMenu.tsx index 8d2c6572e7c..0acc50f9627 100644 --- a/src/components/DropdownMenu.tsx +++ b/src/components/DropdownMenu.tsx @@ -1,14 +1,19 @@ -import React, { useCallback } from 'react'; +import React, { ComponentProps, useCallback } from 'react'; import * as DropdownMenuPrimitive from 'zeego/dropdown-menu'; import styled from 'styled-components'; import { IconConfig, MenuActionConfig, MenuConfig as _MenuConfig } from 'react-native-ios-context-menu'; import { ImageSystemSymbolConfiguration } from 'react-native-ios-context-menu/lib/typescript/types/ImageItemConfig'; -import { ImageSourcePropType } from 'react-native'; +import { ImageSourcePropType, ImageURISource } from 'react-native'; import type { SFSymbols5_0 } from 'sf-symbols-typescript'; import type { DropdownMenuContentProps } from '@radix-ui/react-dropdown-menu'; +import { ButtonPressAnimation } from './animations'; + +type ExtendedDropdownMenuTriggerProps = ComponentProps & { + testID?: string; +}; export const DropdownMenuRoot = DropdownMenuPrimitive.Root; -export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; +export const DropdownMenuTrigger = DropdownMenuPrimitive.create(DropdownMenuPrimitive.Trigger, 'Trigger'); export const DropdownMenuContent = DropdownMenuPrimitive.Content; export const DropdownMenuItem = DropdownMenuPrimitive.create( styled(DropdownMenuPrimitive.CheckboxItem)({ @@ -30,12 +35,18 @@ export type MenuItemAssetImage = { iconValue: ImageSourcePropType; }; -export type MenuItemIcon = Omit & (MenuItemSystemImage | MenuItemAssetImage); +export type MenuItemRemoteAssetImage = { + iconType: 'REMOTE'; + iconValue: ImageURISource; +}; + +export type MenuItemIcon = Omit & + (MenuItemSystemImage | MenuItemAssetImage | MenuItemRemoteAssetImage); export type MenuItem = Omit & { actionKey: T; actionTitle: string; - icon?: MenuItemIcon | { iconType: string; iconValue: string }; + icon?: MenuItemIcon; }; export type MenuConfig = Omit<_MenuConfig, 'menuItems' | 'menuTitle'> & { @@ -47,18 +58,24 @@ type DropDownMenuProps = { children: React.ReactElement; menuConfig: MenuConfig; onPressMenuItem: (actionKey: T) => void; + hitSlop?: number; + testID?: string; } & DropdownMenuContentProps; const buildIconConfig = (icon?: MenuItemIcon) => { if (!icon) return null; - if (icon.iconType === 'SYSTEM' && typeof icon.iconValue === 'string') { + if (icon.iconType === 'SYSTEM') { const ios = { name: icon.iconValue }; return ; } - if (icon.iconType === 'ASSET' && typeof icon.iconValue === 'object') { + if (icon.iconType === 'ASSET') { + return ; + } + + if (icon.iconType === 'REMOTE') { return ; } @@ -75,6 +92,8 @@ export function DropdownMenu({ side = 'right', alignOffset = 5, avoidCollisions = true, + hitSlop = 12, // TODO: Figure out how to make the trigger hit slop work + testID, }: DropDownMenuProps) { const handleSelectItem = useCallback( (actionKey: T) => { @@ -85,7 +104,9 @@ export function DropdownMenu({ return ( - {children} + + {children} + ) => { + 'worklet'; + return backendNetworks.value.networks.reduce( + (acc, backendNetwork: BackendNetwork) => { + acc[parseInt(backendNetwork.id, 10)] = backendNetwork.icons.badgeURL; + return acc; + }, + {} as Record + ); +}; + export const getChainsNameWorklet = (backendNetworks: SharedValue) => { 'worklet'; return backendNetworks.value.networks.reduce( From bbf98f9323dee70e93499b2ed088f6fa89d03c4b Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Tue, 17 Dec 2024 16:33:30 -0500 Subject: [PATCH 2/4] available networks v2 convert --- .../expanded-state/AvailableNetworksv2.tsx | 180 +++++++++--------- .../{DropdownMenu.tsx => ClaimableMenu.tsx} | 31 +-- .../components/ClaimCustomization.tsx | 91 +++------ src/state/backendNetworks/backendNetworks.ts | 12 ++ 4 files changed, 140 insertions(+), 174 deletions(-) rename src/screens/claimables/shared/components/{DropdownMenu.tsx => ClaimableMenu.tsx} (61%) diff --git a/src/components/expanded-state/AvailableNetworksv2.tsx b/src/components/expanded-state/AvailableNetworksv2.tsx index b597edf481a..df5f1bab17a 100644 --- a/src/components/expanded-state/AvailableNetworksv2.tsx +++ b/src/components/expanded-state/AvailableNetworksv2.tsx @@ -6,13 +6,13 @@ import ChainBadge from '../coin-icon/ChainBadge'; import { Box, Inline, Text } from '@/design-system'; import { useNavigation } from '@/navigation'; import Routes from '@/navigation/routesNames'; -import { position } from '@/styles'; +import { colors, position } from '@/styles'; import { watchingAlert } from '@/utils'; import { useWallets } from '@/hooks'; import { RainbowToken } from '@/entities'; import { useTheme } from '@/theme'; import { ButtonPressAnimation } from '../animations'; -import ContextMenuButton from '@/components/native-context-menu/contextMenu'; +import { DropdownMenu, MenuItem } from '@/components/DropdownMenu'; import { implementation } from '@/entities/dispersion'; import { EthCoinIcon } from '../coin-icon/EthCoinIcon'; import { enableActionsOnReadOnlyWallet } from '@/config'; @@ -26,6 +26,16 @@ import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks const NOOP = () => null; +const radialGradientProps = { + center: [0, 1], + colors: colors.gradients.lightGreyWhite, + pointerEvents: 'none', + style: { + ...position.coverAsObject, + overflow: 'hidden', + }, +}; + const AvailableNetworksv2 = ({ asset, networks, @@ -41,16 +51,6 @@ const AvailableNetworksv2 = ({ const { goBack, navigate } = useNavigation(); const { isReadOnlyWallet } = useWallets(); - const radialGradientProps = { - center: [0, 1], - colors: colors.gradients.lightGreyWhite, - pointerEvents: 'none', - style: { - ...position.coverAsObject, - overflow: 'hidden', - }, - }; - const convertAssetAndNavigate = useCallback( (chainId: ChainId) => { if (isReadOnlyWallet && !enableActionsOnReadOnlyWallet) { @@ -116,13 +116,7 @@ const AvailableNetworksv2 = ({ [asset, goBack, isReadOnlyWallet, navigate, networks] ); - const handlePressContextMenu = useCallback( - // @ts-expect-error ContextMenu is an untyped JS component and can't type its onPress handler properly - ({ nativeEvent: { actionKey: chainId } }) => { - convertAssetAndNavigate(chainId); - }, - [convertAssetAndNavigate] - ); + const handlePressContextMenu = useCallback((chainId: string) => convertAssetAndNavigate(+chainId), [convertAssetAndNavigate]); const availableChainIds = useMemo(() => { // we dont want to show mainnet @@ -135,7 +129,7 @@ const AvailableNetworksv2 = ({ convertAssetAndNavigate(availableChainIds[0]); }, [availableChainIds, convertAssetAndNavigate]); - const networkMenuItems = useBackendNetworksStore + const networkMenuItems: MenuItem[] = useBackendNetworksStore .getState() .getSupportedChainIds() .filter(chainId => chainId !== ChainId.mainnet) @@ -144,81 +138,91 @@ const AvailableNetworksv2 = ({ actionKey: `${chain.id}`, actionTitle: useBackendNetworksStore.getState().getChainsLabel()[chain.id], icon: { - iconType: 'ASSET', - iconValue: `${useBackendNetworksStore.getState().getChainsName()[chain.id]}Badge${chain.id === ChainId.mainnet ? '' : 'NoShadow'}`, + iconType: 'REMOTE', + iconValue: { + uri: useBackendNetworksStore.getState().getChainsBadge()[chain.id], + }, }, })); - const MenuWrapper = availableChainIds.length > 1 ? ContextMenuButton : Box; + const Children = useMemo(() => { + return ( + + + + + + + {availableChainIds?.map((chainId, index) => { + return ( + + {chainId !== ChainId.mainnet ? ( + + ) : ( + + )} + + ); + })} + + + + + {availableChainIds?.length > 1 + ? lang.t('expanded_state.asset.available_networks', { + availableNetworks: availableChainIds?.length, + }) + : lang.t('expanded_state.asset.available_networkv2', { + availableNetwork: useBackendNetworksStore.getState().getChainsName()[availableChainIds[0]], + })} + + + + + {availableChainIds?.length > 1 ? '􀁱' : '􀯻'} + + + + + ); + }, [availableChainIds, colors.transparent, handlePressButton, marginHorizontal]); if (availableChainIds.length === 0) return null; + + if (availableChainIds.length === 1) { + return ( + <> + {Children} + {hideDivider ? null : } + + ); + } + return ( <> - - - - - - - - {availableChainIds?.map((chainId, index) => { - return ( - - {chainId !== ChainId.mainnet ? ( - - ) : ( - - )} - - ); - })} - - - - - {availableChainIds?.length > 1 - ? lang.t('expanded_state.asset.available_networks', { - availableNetworks: availableChainIds?.length, - }) - : lang.t('expanded_state.asset.available_networkv2', { - availableNetwork: useBackendNetworksStore.getState().getChainsName()[availableChainIds[0]], - })} - - - - - {availableChainIds?.length > 1 ? '􀁱' : '􀯻'} - - - - - + + {Children} + {hideDivider ? null : } ); diff --git a/src/screens/claimables/shared/components/DropdownMenu.tsx b/src/screens/claimables/shared/components/ClaimableMenu.tsx similarity index 61% rename from src/screens/claimables/shared/components/DropdownMenu.tsx rename to src/screens/claimables/shared/components/ClaimableMenu.tsx index 43dcac5ebb4..8f2a0c15ee5 100644 --- a/src/screens/claimables/shared/components/DropdownMenu.tsx +++ b/src/screens/claimables/shared/components/ClaimableMenu.tsx @@ -1,32 +1,20 @@ import { Bleed, Box, Text, useColorMode } from '@/design-system'; import React from 'react'; import { View } from 'react-native'; -import { ContextMenuButton } from '@/components/context-menu'; -import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; +import { DropdownMenu, MenuConfig } from '@/components/DropdownMenu'; -export function DropdownMenu({ +export function ClaimableMenu({ disabled, menuConfig, muted, onPressMenuItem, - onShowActionSheet, text, icon, }: { disabled: boolean; - menuConfig: { - menuItems: { - actionKey: string; - actionTitle: string; - icon?: { - iconType: string; - iconValue: string; - }; - }[]; - }; + menuConfig: MenuConfig; muted: boolean; - onPressMenuItem: ({ nativeEvent: { actionKey } }: Omit) => void; - onShowActionSheet: () => void; + onPressMenuItem: (actionKey: string) => void; text: string; icon?: React.ReactNode; // must have size: 16 }) { @@ -34,14 +22,7 @@ export function DropdownMenu({ return ( - + - + ); } diff --git a/src/screens/claimables/transaction/components/ClaimCustomization.tsx b/src/screens/claimables/transaction/components/ClaimCustomization.tsx index 6a43623e0d2..3192b99eb8e 100644 --- a/src/screens/claimables/transaction/components/ClaimCustomization.tsx +++ b/src/screens/claimables/transaction/components/ClaimCustomization.tsx @@ -1,19 +1,19 @@ import { Box, Text } from '@/design-system'; -import { haptics, showActionSheetWithOptions } from '@/utils'; +import { haptics } from '@/utils'; import React, { useCallback, useMemo, useState } from 'react'; import { ChainId } from '@/state/backendNetworks/types'; import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks'; import { useUserAssetsStore } from '@/state/assets/userAssets'; import { ETH_SYMBOL, USDC_ADDRESS } from '@/references'; -import { DropdownMenu } from '../../shared/components/DropdownMenu'; +import { ClaimableMenu } from '../../shared/components/ClaimableMenu'; import { TokenToReceive } from '../types'; import { useTransactionClaimableContext } from '../context/TransactionClaimableContext'; import { useTokenSearch } from '@/__swaps__/screens/Swap/resources/search'; import { SearchAsset } from '@/__swaps__/types/search'; import * as i18n from '@/languages'; import { ChainImage } from '@/components/coin-icon/ChainImage'; -import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; import { IS_ANDROID } from '@/env'; +import { MenuConfig, MenuItem } from '@/components/DropdownMenu'; type TokenMap = Record; @@ -32,6 +32,7 @@ export function ClaimCustomization() { const chainsLabel = useBackendNetworksStore.getState().getChainsLabel(); const chainsName = useBackendNetworksStore.getState().getChainsName(); + const backendNetworks = useBackendNetworksStore(state => state.backendNetworksSharedValue); const { data: usdcSearchData } = useTokenSearch( { @@ -131,7 +132,8 @@ export function ClaimCustomization() { ]); const tokenMenuConfig = useMemo(() => { - const availableTokens = Object.values(tokens) + let availableTokens: MenuItem[] = []; + availableTokens = Object.values(tokens) .filter(token => { // exclude if token is already selected if (token.symbol === outputToken?.symbol) { @@ -166,7 +168,7 @@ export function ClaimCustomization() { })) .sort((a, b) => (a.actionTitle < b.actionTitle ? 1 : -1)); - let menuItems = [ + availableTokens = [ { actionKey: 'reset', actionTitle: 'Reset', @@ -176,28 +178,37 @@ export function ClaimCustomization() { ]; if (IS_ANDROID) { - menuItems = menuItems.reverse(); + availableTokens = availableTokens.reverse(); } return { - menuItems, + menuItems: availableTokens, }; }, [tokens, outputToken?.symbol, isInitialState, outputChainId]); const networkMenuConfig = useMemo(() => { - const supportedChains = balanceSortedChainList + const chainsBadge = useBackendNetworksStore.getState().getChainsBadge(); + + let supportedChains: MenuItem[] = []; + + supportedChains = balanceSortedChainList .filter(chainId => isInitialState || (chainId !== outputChainId && (!outputToken || chainId in outputToken.networks))) .map(chainId => ({ actionKey: `${chainId}`, actionTitle: chainsLabel[chainId], icon: { - iconType: 'ASSET', - iconValue: chainId === ChainId.mainnet ? 'ethereumBadge' : `${chainsName[chainId]}BadgeNoShadow`, + iconType: 'REMOTE', + iconValue: { + uri: chainsBadge[chainId], + }, }, - })) - .reverse(); + })); + + if (!IS_ANDROID) { + supportedChains.reverse(); + } - let menuItems = [ + supportedChains = [ { actionKey: 'reset', actionTitle: 'Reset', @@ -206,17 +217,13 @@ export function ClaimCustomization() { ...supportedChains, ]; - if (IS_ANDROID) { - menuItems = menuItems.reverse(); - } - return { - menuItems, + menuItems: supportedChains, }; - }, [balanceSortedChainList, chainsLabel, chainsName, isInitialState, outputChainId, outputToken]); + }, [balanceSortedChainList, chainsLabel, isInitialState, outputChainId, outputToken]); const handleTokenSelection = useCallback( - ({ nativeEvent: { actionKey } }: Omit) => { + (actionKey: string) => { haptics.selection(); if (actionKey === 'reset') { resetState(); @@ -238,7 +245,7 @@ export function ClaimCustomization() { ); const handleNetworkSelection = useCallback( - ({ nativeEvent: { actionKey } }: Omit) => { + (actionKey: string) => { haptics.selection(); if (actionKey === 'reset') { resetState(); @@ -259,42 +266,6 @@ export function ClaimCustomization() { [resetState, setOutputConfig, setQuoteState, setGasState] ); - const onShowTokenActionSheet = useCallback(() => { - const tokenTitles = tokenMenuConfig.menuItems.map(token => token.actionTitle); - - showActionSheetWithOptions( - { - options: tokenTitles, - showSeparators: true, - }, - (index: number | undefined) => { - // NOTE: When they click away from the menu, the index is undefined - if (typeof index === 'undefined') return; - handleTokenSelection({ - nativeEvent: { actionKey: tokenMenuConfig.menuItems[index].actionKey, actionTitle: '' }, - }); - } - ); - }, [handleTokenSelection, tokenMenuConfig.menuItems]); - - const onShowNetworkActionSheet = useCallback(() => { - const networkTitles = networkMenuConfig.menuItems.map(network => network.actionTitle); - - showActionSheetWithOptions( - { - options: networkTitles, - showSeparators: true, - }, - (index: number | undefined) => { - // NOTE: When they click away from the menu, the index is undefined - if (typeof index === 'undefined') return; - handleNetworkSelection({ - nativeEvent: { actionKey: networkMenuConfig.menuItems[index].actionKey, actionTitle: '' }, - }); - } - ); - }, [handleNetworkSelection, networkMenuConfig.menuItems]); - const isDisabled = claimStatus === 'success' || claimStatus === 'pending' || claimStatus === 'claiming' || claimStatus === 'unrecoverableError'; @@ -303,22 +274,20 @@ export function ClaimCustomization() { {i18n.t(i18n.l.claimables.panel.receive)} - {i18n.t(i18n.l.claimables.panel.on)} - } diff --git a/src/state/backendNetworks/backendNetworks.ts b/src/state/backendNetworks/backendNetworks.ts index 20503bb9662..274688889a7 100644 --- a/src/state/backendNetworks/backendNetworks.ts +++ b/src/state/backendNetworks/backendNetworks.ts @@ -29,6 +29,7 @@ export interface BackendNetworksState { getChainsLabel: () => Record; getChainsPrivateMempoolTimeout: () => Record; getChainsName: () => Record; + getChainsBadge: () => Record; getChainsIdByName: () => Record; defaultGasSpeeds: (chainId: ChainId) => GasSpeed[]; @@ -152,6 +153,17 @@ export const useBackendNetworksStore = createRainbowStore( ); }, + getChainsBadge: () => { + const backendNetworks = get().backendNetworks; + return backendNetworks.networks.reduce( + (acc, backendNetwork) => { + acc[parseInt(backendNetwork.id, 10)] = backendNetwork.icons.badgeURL; + return acc; + }, + {} as Record + ); + }, + getChainsIdByName: () => { const backendNetworks = get().backendNetworks; return backendNetworks.networks.reduce( From 49f59969e6140672aa9e8bbca5b63180f9d37464 Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Tue, 17 Dec 2024 16:47:15 -0500 Subject: [PATCH 3/4] add token icons to claim dropdown and fix but with AvailableNetworks not showing ever --- .../expanded-state/asset/ChartExpandedState.js | 2 +- .../transaction/components/ClaimCustomization.tsx | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/components/expanded-state/asset/ChartExpandedState.js b/src/components/expanded-state/asset/ChartExpandedState.js index 3bf7aff28ff..d53e0308b0c 100644 --- a/src/components/expanded-state/asset/ChartExpandedState.js +++ b/src/components/expanded-state/asset/ChartExpandedState.js @@ -336,7 +336,7 @@ export default function ChartExpandedState({ asset }) { {!data?.networks && isL2 && ( )} - {data?.networks && !hasBalance && ( + {data?.networks && assetWithPrice && ( diff --git a/src/screens/claimables/transaction/components/ClaimCustomization.tsx b/src/screens/claimables/transaction/components/ClaimCustomization.tsx index 3192b99eb8e..397efc457e3 100644 --- a/src/screens/claimables/transaction/components/ClaimCustomization.tsx +++ b/src/screens/claimables/transaction/components/ClaimCustomization.tsx @@ -1,7 +1,6 @@ import { Box, Text } from '@/design-system'; import { haptics } from '@/utils'; import React, { useCallback, useMemo, useState } from 'react'; -import { ChainId } from '@/state/backendNetworks/types'; import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks'; import { useUserAssetsStore } from '@/state/assets/userAssets'; import { ETH_SYMBOL, USDC_ADDRESS } from '@/references'; @@ -13,7 +12,7 @@ import { SearchAsset } from '@/__swaps__/types/search'; import * as i18n from '@/languages'; import { ChainImage } from '@/components/coin-icon/ChainImage'; import { IS_ANDROID } from '@/env'; -import { MenuConfig, MenuItem } from '@/components/DropdownMenu'; +import { MenuItem } from '@/components/DropdownMenu'; type TokenMap = Record; @@ -165,8 +164,15 @@ export function ClaimCustomization() { .map(token => ({ actionKey: token.symbol, actionTitle: token.name, - })) - .sort((a, b) => (a.actionTitle < b.actionTitle ? 1 : -1)); + icon: { + iconType: 'REMOTE', + iconValue: { + uri: token.iconUrl, + }, + }, + })); + + availableTokens = availableTokens.sort((a, b) => (a.actionTitle < b.actionTitle ? 1 : -1)); availableTokens = [ { From 3a94dd2ef869c59897d5e04b0150b1669a85ba8a Mon Sep 17 00:00:00 2001 From: Matthew Wall Date: Wed, 18 Dec 2024 13:16:49 -0500 Subject: [PATCH 4/4] latest changes to try to get hitslop to work --- src/components/DropdownMenu.tsx | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/components/DropdownMenu.tsx b/src/components/DropdownMenu.tsx index 0acc50f9627..5d2c49a4eab 100644 --- a/src/components/DropdownMenu.tsx +++ b/src/components/DropdownMenu.tsx @@ -7,13 +7,29 @@ import { ImageSourcePropType, ImageURISource } from 'react-native'; import type { SFSymbols5_0 } from 'sf-symbols-typescript'; import type { DropdownMenuContentProps } from '@radix-ui/react-dropdown-menu'; import { ButtonPressAnimation } from './animations'; +import { DebugLayout, HitSlop } from '@/design-system'; type ExtendedDropdownMenuTriggerProps = ComponentProps & { + hitSlop?: number; testID?: string; }; export const DropdownMenuRoot = DropdownMenuPrimitive.Root; -export const DropdownMenuTrigger = DropdownMenuPrimitive.create(DropdownMenuPrimitive.Trigger, 'Trigger'); +export const DropdownMenuTrigger = DropdownMenuPrimitive.create( + (props: ExtendedDropdownMenuTriggerProps) => { + // TODO: This hitslop isn't working properly... + return ( + + + + {props.children} + + + + ); + }, + 'Trigger' +); export const DropdownMenuContent = DropdownMenuPrimitive.Content; export const DropdownMenuItem = DropdownMenuPrimitive.create( styled(DropdownMenuPrimitive.CheckboxItem)({ @@ -92,7 +108,7 @@ export function DropdownMenu({ side = 'right', alignOffset = 5, avoidCollisions = true, - hitSlop = 12, // TODO: Figure out how to make the trigger hit slop work + hitSlop = 20, testID, }: DropDownMenuProps) { const handleSelectItem = useCallback( @@ -104,8 +120,8 @@ export function DropdownMenu({ return ( - - {children} + + {children}