diff --git a/README.md b/README.md index 82827cd..779010c 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ npm i @buildship/web3-login Use it in your code: ```javascript -import { Web3Provider, ConnectWeb3Modal, useWeb3 } from "@buildship/web3-login"; +import { Web3Provider, ConnectWallet, AddressView } from "@buildship/web3-login"; // Wallets that you want to support const connectors = { @@ -43,19 +43,20 @@ const connectors = { const App = () => { const { address } = useWeb3() - const [isOpen, setIsOpen] = useState(false) - + return - Connected address: {address} - - + )} + /> + } diff --git a/package.json b/package.json index c6200af..3eac842 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@buildship/web3-login", "type": "module", - "version": "0.3.1", + "version": "0.3.2-beta4", "description": "UX-focused web3 auth for your React app", "author": "Buildship", "keywords": [ @@ -30,6 +30,7 @@ "@3rdweb/hooks": "1.9.0", "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", + "@mui/icons-material": "^5.8.4", "@mui/material": "^5.8.3" }, "peerDependencies": { diff --git a/src/App.tsx b/src/App.tsx index 1e2ac54..ea8480d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,29 +1,32 @@ -import React, { useState } from 'react'; -import './App.css'; -import { useWeb3, ConnectWeb3Modal, Web3Provider } from "./package"; +import React from 'react'; +import { Web3Provider, ProfileView, AddressView } from "./package"; import { defaultConnectors } from "./package/connectors"; import { defaultTheme } from "./package/styles/theme"; -const AddressView = () => { - const { address } = useWeb3(); +import './App.css'; - return
{address ? `Connected to ${address}` : 'Not connected'}
; -} function App() { - const [open, setOpen] = useState(true); - return ( -
- + + {/* autoOpen will pop the modal on page load */} + +
+ +
+ + {/* AddressView should be used inside Web3Provider so that it picks up address */} + Connected address: + +
); diff --git a/src/package/components/AddressView.tsx b/src/package/components/AddressView.tsx new file mode 100644 index 0000000..79f5854 --- /dev/null +++ b/src/package/components/AddressView.tsx @@ -0,0 +1,27 @@ +import React from "react" +import { useWeb3 } from "../" + +type Props = { + isShort?: boolean +} + +/** + * AddressView is used to display the current address. + * It should be used inside Web3Provider so that it picks up address + * @param isShort - If true, the address is displayed in short format: 0xff...abcd + * @returns {JSX.Element} + */ +export const AddressView = ({ isShort = true }: Props): JSX.Element => { + const { address } = useWeb3() + + if (!address) return null + + // TODO: parse ENS here + + return <> + {isShort ? `${address.slice(0, 4)}...${address.slice(-4)}` : address} + + +} + +export default AddressView diff --git a/src/package/components/ConnectWeb3Modal.tsx b/src/package/components/ConnectWeb3Modal.tsx index ce54d65..10ea6b7 100644 --- a/src/package/components/ConnectWeb3Modal.tsx +++ b/src/package/components/ConnectWeb3Modal.tsx @@ -1,11 +1,13 @@ -import React, { useState } from "react"; -import { Modal } from "./Modal"; -import { Typography } from "@mui/material"; -import styles from "./Modal/Modal.module.css" -import { ConnectButton } from "./ConnectButton"; +import React, { useState } from "react" +import { Typography } from "@mui/material" import { useWeb3 } from "@3rdweb/hooks" -import { MagicEmailModal } from "./MagicEmailModal"; -import { connectorsMetadata } from "../connectors"; + +import { MagicEmailModal } from "./MagicEmailModal" +import { ConnectButton } from "./ConnectButton" +import { Modal } from "./Modal" +import styles from "./Modal/Modal.module.css" + +import { connectorsMetadata } from "../connectors" export const ConnectWeb3Modal = ({ open, setOpen }) => { const { connectWallet } = useWeb3() @@ -19,7 +21,7 @@ export const ConnectWeb3Modal = ({ open, setOpen }) => { connectWallet(connector).then(() => { setOpen(false) }) - }; + } if (selectedConnector === "magic") { @@ -28,7 +30,7 @@ export const ConnectWeb3Modal = ({ open, setOpen }) => { open={true} setSelectedConnector={setSelectedConnector} /> - ); + ) } return ( @@ -55,7 +57,7 @@ export const ConnectWeb3Modal = ({ open, setOpen }) => { ))} - ); + ) } export default ConnectWeb3Modal diff --git a/src/package/components/ProfileView.tsx b/src/package/components/ProfileView.tsx new file mode 100644 index 0000000..de03937 --- /dev/null +++ b/src/package/components/ProfileView.tsx @@ -0,0 +1,79 @@ +import React, { useEffect, useState } from "react" +import { useWeb3 } from "@3rdweb/hooks" + +import { LogoutOutlined } from "@mui/icons-material" +import { Box, Button, Typography } from "@mui/material" + +import ConnectWeb3Modal from "./ConnectWeb3Modal" +import AddressView from "./AddressView" + +type ButtonProps = { + children: JSX.Element + onClick: () => void +} + +type Props = { + autoOpen: boolean + showDisconnect?: boolean + renderButton?: (props: ButtonProps) => JSX.Element +} + +const defaultRenderButton = ({ children, onClick }: ButtonProps) => ( + +) + +/** + * ConnectWallet + * @param param0 - autoOpen - If true, the modal will be opened on page load + * @param param0 - showDisconnect - If true, a button will be shown to disconnect + * @param param0 - renderButton - If provided, you can control how a button is rendered + * @returns {JSX.Element} + */ +export const ProfileView = ({ autoOpen = false, showDisconnect = true, renderButton = defaultRenderButton }: Props): JSX.Element => { + + const [open, setOpen] = useState(false) + + useEffect(() => { + // we do it here instead of default value so that the modal is opened on page load ONLY + if (autoOpen) { + setOpen(true) + } + }, []) + + const { address, disconnectWallet } = useWeb3() + + const copyAddress = () => { + navigator.clipboard.writeText(address) + + // TODO: show a snackbar + window.alert("Address copied to clipboard") + } + + return + + + {!address && (renderButton({ + children: <>Connect Wallet, + onClick: () => setOpen(true), + }))} + + {/* */} + {address && + + } + + {showDisconnect && address && (renderButton({ + children: , + onClick: () => disconnectWallet(), + }))} + + +} + +export default ProfileView diff --git a/src/package/index.tsx b/src/package/index.tsx index 8b6b436..d6290c6 100644 --- a/src/package/index.tsx +++ b/src/package/index.tsx @@ -1,10 +1,15 @@ +import { useWeb3, useSwitchNetwork } from "./hooks"; + import { ConnectWeb3Modal } from "./components/ConnectWeb3Modal"; import { IconButton } from "./components/IconButton"; import { Web3Provider } from "./components/Web3Provider"; -import { useWeb3, useSwitchNetwork } from "./hooks"; +import ProfileView from "./components/ProfileView"; +import AddressView from "./components/AddressView"; export { - ConnectWeb3Modal, + ConnectWeb3Modal, + ProfileView, + AddressView, Web3Provider, useWeb3, useSwitchNetwork, diff --git a/yarn.lock b/yarn.lock index e776499..f2293e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1882,6 +1882,13 @@ prop-types "^15.8.1" react-is "^17.0.2" +"@mui/icons-material@^5.8.4": + version "5.8.4" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.8.4.tgz#3f2907c9f8f5ce4d754cb8fb4b68b5a1abf4d095" + integrity sha512-9Z/vyj2szvEhGWDvb+gG875bOGm8b8rlHBKOD1+nA3PcgC3fV6W1AU6pfOorPeBfH2X4mb9Boe97vHvaSndQvA== + dependencies: + "@babel/runtime" "^7.17.2" + "@mui/material@^5.8.3": version "5.8.3" resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.8.3.tgz#86681d14c1a119d1d9b6b981c864736d075d095f"