Skip to content

Commit

Permalink
feat: set new Account Picker
Browse files Browse the repository at this point in the history
  • Loading branch information
gmolki committed Aug 5, 2024
1 parent 5d5bfed commit 58bb0d6
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 182 deletions.
133 changes: 41 additions & 92 deletions src/components/common/Header/cmp.tsx
Original file line number Diff line number Diff line change
@@ -1,96 +1,12 @@
import { memo } from 'react'
import { createPortal } from 'react-dom'
import Link from 'next/link'
import { Button, RenderLinkProps } from '@aleph-front/core'
import {
StyledNavbarDesktop,
StyledWalletPicker,
StyledNavbarMobile,
StyledHeader,
StyledIcon,
} from './styles'
import { ellipseAddress } from '@/helpers/utils'
import {
UseAccountButtonProps,
useAccountButton,
useHeader,
} from '@/hooks/pages/useHeader'
import { AccountPicker, RenderLinkProps } from '@aleph-front/core'
import { StyledNavbarDesktop, StyledNavbarMobile, StyledHeader } from './styles'
import { useHeader } from '@/hooks/pages/useHeader'
import AutoBreadcrumb from '@/components/common/AutoBreadcrumb'
import { BlockchainId, blockchains } from '@/domain/connect/base'
import { blockchains } from '@/domain/connect/base'
import { useEnsNameLookup } from '@/hooks/common/useENSLookup'

export type AccountButtonProps = UseAccountButtonProps & {
isMobile?: boolean
}

export const AccountButton = ({ isMobile, ...rest }: AccountButtonProps) => {
const {
account,
accountBalance,
displayWalletPicker,
walletPickerOpen,
walletPickerRef,
walletPickerTriggerRef,
walletPosition,
rewards,
selectedNetwork,
networks,
handleSwitchNetwork,
handleConnect,
handleDisconnect,
handleDisplayWalletPicker,
} = useAccountButton(rest)

const ensName = useEnsNameLookup(account?.address)

return (
<>
<Button
ref={walletPickerTriggerRef}
as="button"
variant={account ? 'secondary' : 'tertiary'}
color={account ? 'main1' : 'main0'}
kind="neon"
size="md"
onClick={handleDisplayWalletPicker}
>
<div tw="flex items-center gap-3">
{!isMobile &&
(account ? ensName || ellipseAddress(account.address) : 'Connect')}
{(isMobile || account) && (
<StyledIcon
$network={selectedNetwork}
$isConnected={!!account}
$isMobile={isMobile}
/>
)}
</div>
</Button>
{displayWalletPicker &&
createPortal(
<StyledWalletPicker
ref={walletPickerRef}
networks={networks}
rewards={rewards}
selectedNetwork={selectedNetwork}
onSwitchNetwork={handleSwitchNetwork}
onConnect={handleConnect}
onDisconnect={handleDisconnect}
address={account?.address}
addressHref={`${blockchains[(selectedNetwork?.id || 'ETH') as BlockchainId].explorerUrl}address/${account?.address}`}
balance={accountBalance}
$isOpen={walletPickerOpen}
$position={walletPosition}
/>,
document.body,
)}
</>
)
}
AccountButton.displayName = 'AccountButton'

// ----------------------------

const CustomLink = (props: RenderLinkProps) => {
return props.route.children ? <span {...props} /> : <Link {...props} />
}
Expand All @@ -104,10 +20,19 @@ export const Header = () => {
breadcrumbNames,
isOpen,
breakpoint,
networks,
accountAddress,
accountBalance,
rewards,
selectedNetwork,
handleToggle,
...accountProps
handleConnect,
handleDisconnect,
handleSwitchNetwork,
} = useHeader()

const ensName = useEnsNameLookup(accountAddress)

return (
<>
<StyledHeader $breakpoint={breakpoint}>
Expand All @@ -120,12 +45,37 @@ export const Header = () => {
Link: CustomLinkMemo,
height: '6.5rem',
breakpoint: 'lg',
mobileTopContent: <AccountButtonMemo {...accountProps} isMobile />,
mobileTopContent: (
<AccountPicker
isMobile
accountAddress={accountAddress}
accountBalance={accountBalance}
blockchains={blockchains}
networks={networks}
selectedNetwork={selectedNetwork}
rewards={rewards}
ensName={ensName}
handleConnect={handleConnect}
handleDisconnect={handleDisconnect}
handleSwitchNetwork={handleSwitchNetwork}
/>
),
}}
/>
<StyledNavbarDesktop $breakpoint={breakpoint}>
<AutoBreadcrumb names={breadcrumbNames} />
<AccountButtonMemo {...accountProps} />
<AccountPicker
accountAddress={accountAddress}
accountBalance={accountBalance}
blockchains={blockchains}
networks={networks}
selectedNetwork={selectedNetwork}
rewards={rewards}
ensName={ensName}
handleConnect={handleConnect}
handleDisconnect={handleDisconnect}
handleSwitchNetwork={handleSwitchNetwork}
/>
</StyledNavbarDesktop>
</StyledHeader>
<div tw="block flex-auto grow-0 shrink-0 h-[6.5rem] lg:hidden"></div>
Expand All @@ -138,5 +88,4 @@ export const Header = () => {
Header.displayName = 'Header'

export const CustomLinkMemo = memo(CustomLink)
export const AccountButtonMemo = memo(AccountButton)
export default memo(Header)
6 changes: 1 addition & 5 deletions src/components/common/Header/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
export {
default,
default as Header,
AccountButtonMemo as AccountButton,
} from './cmp'
export { default, default as Header } from './cmp'
74 changes: 1 addition & 73 deletions src/components/common/Header/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,8 @@
import {
BreakpointId,
Button,
FloatPosition,
Icon,
IconName,
IconProps,
RouterNavbar,
WalletPicker,
getResponsiveCss,
} from '@aleph-front/core'
import { BreakpointId, RouterNavbar, getResponsiveCss } from '@aleph-front/core'
import { ReactNode } from 'react'
import styled, { css } from 'styled-components'
import tw from 'twin.macro'

export const StyledButton = styled(Button).attrs((props) => {
return {
...props,
color: 'main0',
kind: 'neon',
size: 'md',
variant: 'tertiary',
}
})`
display: block;
&:last-child {
margin-bottom: 0;
}
`

export const StyledWalletPicker = styled(WalletPicker)<{
$position: FloatPosition
$isOpen: boolean
}>`
${({ $position: { x, y }, $isOpen }) => {
return css`
${tw`fixed z-20 mt-4 top-0 left-0`}
transform: ${`translate3d(${x}px, ${y}px, 0)`};
opacity: ${$isOpen ? 1 : 0};
will-change: opacity transform;
transition: opacity ease-in-out 250ms 0s;
`
}}
`

// --------------------------------------------

export type StyledNavbarDesktopProps = {
$breakpoint?: BreakpointId
children?: ReactNode
Expand Down Expand Up @@ -111,32 +68,3 @@ export const StyledHeader = styled.header<StyledHeaderProps>`
)};
`}
`

export type StyledIconProps = {
$isConnected: boolean
$network?: { icon: IconName }
$isMobile?: boolean
}

export const StyledIcon = styled(Icon).attrs<StyledIconProps, IconProps>(
(props) => {
return {
...props,
size: props.$isMobile ? 'lg' : 'md',
name: props.$network?.icon || 'link',
}
},
)<StyledIconProps>`
${({ theme, $isConnected, $isMobile }) => css`
height: 1em !important;
width: 1em !important;
${!$isMobile &&
css`
padding: 0.35rem;
border-radius: 50%;
background-color: ${theme.color.background};
border: 1px solid ${$isConnected ? theme.color.main1 : theme.color.main0};
`}
`}
`
33 changes: 21 additions & 12 deletions src/hooks/pages/useHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
useTransition,
useWindowScroll,
useWindowSize,
WalletPickerProps,
Wallet,
AccountPickerProps,
} from '@aleph-front/core'
import {
UseBreadcrumbNamesReturn,
Expand Down Expand Up @@ -117,22 +117,29 @@ export function useAccountButton({
// -----------------------------

export type UseHeaderReturn = UseRoutesReturn & {
accountAddress?: string
accountBalance?: number
networks: Network[]
pathname: string
breadcrumbNames: UseBreadcrumbNamesReturn['names']
breakpoint: BreakpointId
isOpen: boolean
rewards?: WalletPickerProps['rewards']
selectedNetwork: WalletPickerProps['selectedNetwork']
handleSwitchNetwork: WalletPickerProps['onSwitchNetwork']
rewards?: AccountPickerProps['rewards']
selectedNetwork: AccountPickerProps['selectedNetwork']
handleToggle: (isOpen: boolean) => void
handleConnect: (wallet: Wallet, network: Network) => void
handleDisconnect: () => void
handleSwitchNetwork: AccountPickerProps['handleSwitchNetwork']
handleConnect: AccountPickerProps['handleConnect']
handleDisconnect: AccountPickerProps['handleDisconnect']
}

export function useHeader(): UseHeaderReturn {
const [state] = useAppState()
const { account, provider, blockchain } = state.connection
const {
account,
balance: accountBalance,
provider,
blockchain,
} = state.connection

const { handleConnect: connect, handleDisconnect: disconnect } =
useConnection({ triggerOnMount: true })
Expand Down Expand Up @@ -197,16 +204,16 @@ export function useHeader(): UseHeaderReturn {

const handleConnect = useCallback(
async (wallet: Wallet, network: Network) => {
const provider = (wallet as any).id as ProviderId
const blockchain = (network as any).id as BlockchainId
const provider = (wallet as Wallet).id as ProviderId
const blockchain = (network as Network).id as BlockchainId
connect({ provider, blockchain })
},
[connect],
)

const handleSwitchNetwork = useCallback(
(network: Network) => {
const blockchain = (network as any).id as BlockchainId
const blockchain = (network as Network).id as BlockchainId
connect({ provider, blockchain })
},
[connect, provider],
Expand All @@ -220,7 +227,7 @@ export function useHeader(): UseHeaderReturn {
if (!blockchain) return

const id = blockchains[blockchain].id
return networks.find((network) => (network as any).id === id)
return networks.find((network) => (network as Network).id === id)
}, [networks, blockchain])

// -----------------------
Expand Down Expand Up @@ -261,14 +268,16 @@ export function useHeader(): UseHeaderReturn {
}, [pendingDays, userRewards])

return {
accountAddress: account?.address,
accountBalance,
networks,
pathname,
routes,
breadcrumbNames,
breakpoint,
isOpen,
rewards,
selectedNetwork,
selectedNetwork: selectedNetwork || networks[0],
handleSwitchNetwork,
handleToggle,
handleConnect,
Expand Down

0 comments on commit 58bb0d6

Please sign in to comment.