From 1636786af89426ca545ed4baf873190b68bb06df Mon Sep 17 00:00:00 2001 From: Charles Bachmeier Date: Wed, 17 Aug 2022 11:24:56 -0700 Subject: [PATCH] feat: add the phase0 chain switcher (#4376) * feat: add phase0 chain switcher * update styles * add chain switcher files * remove unneeded eslint disable * add Celo and remove unneeded null check * remove old comment * fix mobile routing Co-authored-by: Charles Bachmeier --- src/components/NavBar/ChainSwitcher.css.ts | 49 ++++++++++ src/components/NavBar/ChainSwitcher.tsx | 108 +++++++++++++++++++++ src/components/NavBar/MobileSidebar.tsx | 2 +- src/components/NavBar/Navbar.tsx | 5 +- 4 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 src/components/NavBar/ChainSwitcher.css.ts create mode 100644 src/components/NavBar/ChainSwitcher.tsx diff --git a/src/components/NavBar/ChainSwitcher.css.ts b/src/components/NavBar/ChainSwitcher.css.ts new file mode 100644 index 0000000000..0deb2c5da9 --- /dev/null +++ b/src/components/NavBar/ChainSwitcher.css.ts @@ -0,0 +1,49 @@ +import { style } from '@vanilla-extract/css' + +import { sprinkles } from '../../nft/css/sprinkles.css' + +export const ChainSwitcher = style([ + sprinkles({ + background: 'lightGrayContainer', + borderRadius: '8', + paddingY: '8', + paddingX: '12', + cursor: 'pointer', + border: 'none', + }), +]) + +export const ChainSwitcherRow = style([ + sprinkles({ + border: 'none', + color: 'blackBlue', + justifyContent: 'space-between', + paddingX: '16', + paddingY: '12', + cursor: 'pointer', + }), + { + lineHeight: '24px', + width: '308px', + }, +]) + +export const Image = style([ + sprinkles({ + width: '28', + height: '28', + }), +]) + +export const Icon = style([ + Image, + sprinkles({ + marginRight: '12', + }), +]) + +export const Indicator = style([ + sprinkles({ + marginLeft: '8', + }), +]) diff --git a/src/components/NavBar/ChainSwitcher.tsx b/src/components/NavBar/ChainSwitcher.tsx new file mode 100644 index 0000000000..487e0413a1 --- /dev/null +++ b/src/components/NavBar/ChainSwitcher.tsx @@ -0,0 +1,108 @@ +import { useWeb3React } from '@web3-react/core' +import { getChainInfo } from 'constants/chainInfo' +import { SupportedChainId } from 'constants/chains' +import { useOnClickOutside } from 'hooks/useOnClickOutside' +import useSelectChain from 'hooks/useSelectChain' +import useSyncChainQuery from 'hooks/useSyncChainQuery' +import { Box } from 'nft/components/Box' +import { Column, Row } from 'nft/components/Flex' +import { NewChevronDownIcon, NewChevronUpIcon } from 'nft/components/icons' +import { CheckMarkIcon } from 'nft/components/icons' +import { subhead } from 'nft/css/common.css' +import { ReactNode, useReducer, useRef } from 'react' +import { isChainAllowed } from 'utils/switchChain' + +import * as styles from './ChainSwitcher.css' +import { NavDropdown } from './NavDropdown' + +const ChainRow = ({ + targetChain, + onSelectChain, +}: { + targetChain: SupportedChainId + onSelectChain: (targetChain: number) => void +}) => { + const { chainId } = useWeb3React() + const active = chainId === targetChain + const { label, logoUrl } = getChainInfo(targetChain) + + return ( + onSelectChain(targetChain)} + > + + {label} + {label} + + {active && } + + ) +} + +const ChainDetails = ({ children }: { children: ReactNode }) => {children} + +const NETWORK_SELECTOR_CHAINS = [ + SupportedChainId.MAINNET, + SupportedChainId.POLYGON, + SupportedChainId.OPTIMISM, + SupportedChainId.ARBITRUM_ONE, + SupportedChainId.CELO, +] + +interface ChainSwitcherProps { + isMobile?: boolean +} + +export const ChainSwitcher = ({ isMobile }: ChainSwitcherProps) => { + const { chainId, connector } = useWeb3React() + const [isOpen, toggleOpen] = useReducer((s) => !s, false) + + const ref = useRef(null) + useOnClickOutside(ref, isOpen ? toggleOpen : undefined) + + const info = chainId ? getChainInfo(chainId) : undefined + + const selectChain = useSelectChain() + useSyncChainQuery() + + if (!chainId || !info) { + return null + } + + return ( + + + {info.label} + + {info.label} + + {isOpen ? ( + + ) : ( + + )} + + {isOpen && ( + + + {NETWORK_SELECTOR_CHAINS.map((chainId: SupportedChainId) => + isChainAllowed(connector, chainId) ? ( + { + await selectChain(targetChainId) + toggleOpen() + }} + targetChain={chainId} + key={chainId} + /> + ) : null + )} + + + )} + + ) +} diff --git a/src/components/NavBar/MobileSidebar.tsx b/src/components/NavBar/MobileSidebar.tsx index 79ec4ac6d5..3f91df8b9e 100644 --- a/src/components/NavBar/MobileSidebar.tsx +++ b/src/components/NavBar/MobileSidebar.tsx @@ -159,7 +159,7 @@ export const MobileSideBar = () => { Swap - + Tokens diff --git a/src/components/NavBar/Navbar.tsx b/src/components/NavBar/Navbar.tsx index 45755bbf3e..e4ddcd02e2 100644 --- a/src/components/NavBar/Navbar.tsx +++ b/src/components/NavBar/Navbar.tsx @@ -7,6 +7,7 @@ import { Box } from '../../nft/components/Box' import { Row } from '../../nft/components/Flex' import { UniIcon, UniIconMobile } from '../../nft/components/icons' import { breakpoints } from '../../nft/css/sprinkles.css' +import { ChainSwitcher } from './ChainSwitcher' import { MenuDropdown } from './MenuDropdown' import { MobileSideBar } from './MobileSidebar' import * as styles from './Navbar.css' @@ -40,7 +41,7 @@ const MobileNavbar = () => { - {/* TODO add ChainSwitcher */} + @@ -95,7 +96,7 @@ const Navbar = () => { - {/* TODO add ChainSwitcher */} +