Skip to content

Instantly share code, notes, and snippets.

@keon
Last active July 28, 2023 09:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keon/02d73c6e3b0b1efa46f37ec50e974535 to your computer and use it in GitHub Desktop.
Save keon/02d73c6e3b0b1efa46f37ec50e974535 to your computer and use it in GitHub Desktop.
custom connect button
import { ChevronDown, Loader2 } from "lucide-react";
import { useEffect, useState } from "react";
import { useConnectionStatus } from "../../hooks/use-connection-status";
import { useEmojiAvatar } from "../../utils/avatars";
import { AsyncImage } from "../common/async-image";
import { PassComponent } from "../common/pass-component";
import { Button } from "../primitives/button";
import { useChains } from "../providers/chain-context";
import { ConnectButtonRenderer } from "./renderer";
const defaultProps = {
label: "Connect Wallet",
chainStatus: "icon",
} as const;
type AccountStatus = "full" | "avatar" | "address";
type ChainStatus = "icon" | "none";
export interface ConnectButtonProps {
// accountStatus?: AccountStatus;
// showBalance?: boolean;
chainStatus?: ChainStatus;
label?: string;
}
export const ConnectButton = ({
label = defaultProps.label,
chainStatus = defaultProps.chainStatus,
}: ConnectButtonProps) => {
const chains = useChains();
const connectionStatus = useConnectionStatus();
const [buttonText, setButtonText] = useState<string>(label);
useEffect(() => {
if (connectionStatus === "unauthenticated") {
setButtonText("✍️ Sign In");
} else if (connectionStatus === "loading") {
setButtonText("Loading");
} else {
setButtonText("Connect Wallet");
}
}, [connectionStatus]);
return (
<ConnectButtonRenderer>
{({
account,
chain,
openAccountModal,
openChainModal,
openConnectModal,
mounted,
}) => {
const ready = mounted && connectionStatus !== "loading";
const unsupportedChain = chain?.unsupported ?? false;
const avatar = useEmojiAvatar(account?.address);
const showNetworkModal = true;
return (
<PassComponent className="tw-flex tw-gap-2 tw-font-sf-round">
{ready && account && connectionStatus === "connected" ? (
<>
{chainStatus == "icon" &&
chain &&
(chains.length > 1 || unsupportedChain) &&
showNetworkModal && (
<>
{unsupportedChain ? (
<Button
variant={"rainbowError"}
className="tw-flex tw-items-center tw-p-3"
onClick={openChainModal}
>
<span>Wrong network</span>
</Button>
) : (
<Button
onClick={openChainModal}
variant={"rainbow"}
className="tw-p-2"
>
<div className="tw-flex tw-items-center tw-gap-1">
{chain.hasIcon ? (
<AsyncImage
alt={chain.name ?? "Chain icon"}
className={`tw-rounded-full tw-h-[24px] tw-w-[24px] tw-bg-[${chain.iconBackground}]`}
src={chain.iconUrl}
/>
) : null}
<ChevronDown className="tw-w-5 tw-h-5" />
</div>
</Button>
)}
</>
)}
{!unsupportedChain && (
<Button
variant="rainbow"
onClick={openAccountModal}
className="tw-flex tw-space-x-1 tw-p-2 tw-bg-white"
type="button"
>
<span
style={{
background: avatar.color,
}}
className="tw-inline-flex tw-w-6 tw-h-6 tw-items-center tw-justify-center tw-rounded-full tw-mr-1"
>
{avatar.emoji}
</span>
<span className="tw-hidden md:tw-flex">
{account.displayName}
</span>
<ChevronDown className="tw-w-5 tw-h-5" />
</Button>
)}
</>
) : (
<Button variant="rainbowAction" onClick={openConnectModal}>
{buttonText === "Loading" ? (
<Loader2 className="tw-w-4 tw-h-4 tw-animate-spin" />
) : (
buttonText
)}
</Button>
)}
</PassComponent>
);
}}
</ConnectButtonRenderer>
);
};
ConnectButton.__defaultProps = defaultProps;
ConnectButton.Custom = ConnectButtonRenderer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment