Create new WarningBanner component (#242)
- Create new WarningBanner component - Add chainWalletWhitelists config - Add warning in form when chains require certain walletspull/246/head
parent
eb281570c1
commit
295dc2a949
@ -0,0 +1,13 @@ |
||||
import { ComponentProps } from 'react'; |
||||
|
||||
import { WarningBanner } from '../../components/banner/WarningBanner'; |
||||
|
||||
export function FormWarningBanner({ className, ...props }: ComponentProps<typeof WarningBanner>) { |
||||
return ( |
||||
<WarningBanner |
||||
// The margins here should be the inverse of those in Card.tsx
|
||||
className={`z-20 -m-1.5 mb-0 sm:-m-3 sm:mb-0 md:-m-3.5 md:mb-0 ${className}`} |
||||
{...props} |
||||
/> |
||||
); |
||||
} |
@ -0,0 +1,37 @@ |
||||
import Image from 'next/image'; |
||||
import { PropsWithChildren, ReactNode } from 'react'; |
||||
|
||||
import WarningIcon from '../../images/icons/warning.svg'; |
||||
|
||||
export function WarningBanner({ |
||||
isVisible, |
||||
cta, |
||||
onClick, |
||||
className, |
||||
children, |
||||
}: PropsWithChildren<{ |
||||
isVisible: boolean; |
||||
cta: ReactNode; |
||||
onClick: () => void; |
||||
className?: string; |
||||
}>) { |
||||
return ( |
||||
<div |
||||
className={`flex items-center justify-between gap-2 px-4 bg-amber-400 text-sm ${ |
||||
isVisible ? 'max-h-28 py-2 mb-2' : 'max-h-0 mb-0' |
||||
} overflow-hidden transition-all duration-500 ${className}`}
|
||||
> |
||||
<div className="flex items-center gap-2"> |
||||
<Image src={WarningIcon} width={20} height={20} alt="Warning:" /> |
||||
{children} |
||||
</div> |
||||
<button |
||||
type="button" |
||||
onClick={onClick} |
||||
className="bg-white/30 rounded-full px-2.5 py-1 text-center hover:bg-white/50 active:bg-white/60" |
||||
> |
||||
{cta} |
||||
</button> |
||||
</div> |
||||
); |
||||
} |
@ -0,0 +1,48 @@ |
||||
import { useMemo } from 'react'; |
||||
|
||||
import { toTitleCase } from '@hyperlane-xyz/utils'; |
||||
|
||||
import { FormWarningBanner } from '../../components/banner/FormWarningBanner'; |
||||
import { config } from '../../consts/config'; |
||||
import { logger } from '../../utils/logger'; |
||||
import { useConnectFns, useDisconnectFns, useWalletDetails } from '../wallet/hooks/multiProtocol'; |
||||
|
||||
import { getChainDisplayName, tryGetChainProtocol } from './utils'; |
||||
|
||||
export function ChainWalletWarning({ originChain }: { originChain: ChainName }) { |
||||
const wallets = useWalletDetails(); |
||||
const connectFns = useConnectFns(); |
||||
const disconnectFns = useDisconnectFns(); |
||||
|
||||
const { isVisible, chainDisplayName, walletWhitelist, connectFn, disconnectFn } = useMemo(() => { |
||||
const protocol = tryGetChainProtocol(originChain); |
||||
const walletWhitelist = config.chainWalletWhitelists[originChain]?.map((w) => |
||||
w.trim().toLowerCase(), |
||||
); |
||||
if (!protocol || !walletWhitelist?.length) |
||||
return { isVisible: false, chainDisplayName: '', walletWhitelist: [] }; |
||||
|
||||
const chainDisplayName = getChainDisplayName(originChain, true); |
||||
const walletName = wallets[protocol]?.name?.trim()?.toLowerCase(); |
||||
const connectFn = connectFns[protocol]; |
||||
const disconnectFn = disconnectFns[protocol]; |
||||
const isVisible = !!walletName && !walletWhitelist.includes(walletName); |
||||
|
||||
return { isVisible, chainDisplayName, walletWhitelist, connectFn, disconnectFn }; |
||||
}, [originChain, wallets, connectFns, disconnectFns]); |
||||
|
||||
const onClickChange = () => { |
||||
if (!connectFn || !disconnectFn) return; |
||||
disconnectFn() |
||||
.then(() => connectFn()) |
||||
.catch((err) => logger.error('Error changing wallet connection', err)); |
||||
}; |
||||
|
||||
return ( |
||||
<FormWarningBanner isVisible={isVisible} cta="Change" onClick={onClickChange}> |
||||
{`${chainDisplayName} requires one of the following wallets: ${walletWhitelist |
||||
.map((w) => toTitleCase(w)) |
||||
.join(', ')}`}
|
||||
</FormWarningBanner> |
||||
); |
||||
} |
After Width: | Height: | Size: 935 B |
Loading…
Reference in new issue