UNPKG

@aptos-labs/wallet-adapter-mui-design

Version:
718 lines (710 loc) 23.7 kB
// src/WalletConnector.tsx import { useState as useState4 } from "react"; // src/WalletButton.tsx import { truncateAddress, useWallet as useWallet2 } from "@aptos-labs/wallet-adapter-react"; import { AccountBalanceWalletOutlined as AccountBalanceWalletOutlinedIcon } from "@mui/icons-material"; import { Avatar, Button, Typography } from "@mui/material"; import { useState as useState2 } from "react"; // src/WalletMenu.tsx import { useWallet } from "@aptos-labs/wallet-adapter-react"; import { List, ListItem, ListItemButton, ListItemText, Popover, Tooltip } from "@mui/material"; import { useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; function WalletMenu({ popoverAnchor, handlePopoverClose, handleNavigate }) { const { account, disconnect } = useWallet(); const popoverOpen = Boolean(popoverAnchor); const id = popoverOpen ? "wallet-popover" : void 0; const onAccountOptionClicked = () => { handleNavigate?.(); handlePopoverClose(); }; const handleLogout = () => { disconnect(); handlePopoverClose(); }; const [tooltipOpen, setTooltipOpen] = useState(false); const copyAddress = async () => { await navigator.clipboard.writeText(account?.address?.toString() ?? ""); setTooltipOpen(true); setTimeout(() => { setTooltipOpen(false); }, 2e3); }; return /* @__PURE__ */ jsx( Popover, { id, open: popoverOpen, anchorEl: popoverAnchor, onClose: handlePopoverClose, anchorOrigin: { vertical: "bottom", horizontal: "left" }, children: /* @__PURE__ */ jsxs(List, { children: [ /* @__PURE__ */ jsx( Tooltip, { title: "Copied", placement: "bottom-end", open: tooltipOpen, disableFocusListener: true, disableHoverListener: true, disableTouchListener: true, children: /* @__PURE__ */ jsx(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsx(ListItemButton, { onClick: copyAddress, children: /* @__PURE__ */ jsx(ListItemText, { primary: "Copy Address" }) }) }) } ), !!handleNavigate && /* @__PURE__ */ jsx(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsx(ListItemButton, { onClick: onAccountOptionClicked, children: /* @__PURE__ */ jsx(ListItemText, { primary: "Account" }) }) }), /* @__PURE__ */ jsx(ListItem, { disablePadding: true, children: /* @__PURE__ */ jsx(ListItemButton, { onClick: handleLogout, children: /* @__PURE__ */ jsx(ListItemText, { primary: "Logout" }) }) }) ] }) } ); } // src/WalletButton.tsx import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime"; function WalletButton({ handleModalOpen, handleNavigate }) { const { connected, account, wallet } = useWallet2(); const [popoverAnchor, setPopoverAnchor] = useState2( null ); const handleClick = (event) => { setPopoverAnchor(event.currentTarget); }; const handlePopoverClose = () => { setPopoverAnchor(null); }; const onConnectWalletClick = () => { handlePopoverClose(); handleModalOpen(); }; return /* @__PURE__ */ jsxs2(Fragment, { children: [ /* @__PURE__ */ jsx2( Button, { size: "large", variant: "contained", onClick: connected ? handleClick : onConnectWalletClick, className: "wallet-button", sx: { borderRadius: "10px" }, children: connected ? /* @__PURE__ */ jsxs2(Fragment, { children: [ /* @__PURE__ */ jsx2( Avatar, { alt: wallet?.name, src: wallet?.icon, sx: { width: 24, height: 24 } } ), /* @__PURE__ */ jsx2(Typography, { noWrap: true, ml: 2, children: account?.ansName || truncateAddress(account?.address?.toString()) || "Unknown" }) ] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [ /* @__PURE__ */ jsx2(AccountBalanceWalletOutlinedIcon, { sx: { marginRight: 1 } }), /* @__PURE__ */ jsx2(Typography, { noWrap: true, children: "Connect Wallet" }) ] }) } ), /* @__PURE__ */ jsx2( WalletMenu, { popoverAnchor, handlePopoverClose, handleNavigate } ) ] }); } // src/WalletModel.tsx import { AboutAptosConnect, AptosPrivacyPolicy, groupAndSortWallets, isInstallRequired, useWallet as useWallet3, WalletItem } from "@aptos-labs/wallet-adapter-react"; import { ArrowBack, ArrowForward, Close as CloseIcon, ExpandMore, LanOutlined as LanOutlinedIcon } from "@mui/icons-material"; import { Box, Button as Button2, Collapse, Dialog, Divider, IconButton, ListItem as ListItem2, ListItemText as ListItemText2, Stack, Tab, Tabs, Typography as Typography2, useTheme } from "@mui/material"; import { useState as useState3 } from "react"; // src/aptosColorPalette.ts var grey = { 50: "#fafafa", 100: "#f4f4f5", 200: "#e4e4e7", 300: "#d4d4d8", 400: "#a1a1aa", 450: "#909099", 500: "#4f5352", 600: "#363a39", 700: "#272b2a", 800: "#1b1f1e", 900: "#121615" }; // src/WalletModel.tsx import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime"; function WalletsModal({ handleClose, modalOpen, networkSupport, modalMaxWidth, crossChainWallets, ...walletSortingOptions }) { const theme = useTheme(); const [expanded, setExpanded] = useState3(false); const [tabValue, setTabValue] = useState3(0); const handleTabChange = (_event, newValue) => { setTabValue(newValue); }; const { wallets = [], notDetectedWallets = [] } = useWallet3(); const { aptosConnectWallets, availableWallets, installableWallets } = groupAndSortWallets( [...wallets, ...notDetectedWallets], walletSortingOptions ); const hasAptosConnectWallets = !!aptosConnectWallets.length; const crossChainMode = crossChainWallets && (crossChainWallets.evm || crossChainWallets.solana); const { evmWallets, solanaWallets, aptosWallets } = crossChainMode ? availableWallets.reduce( (acc, wallet) => { if (wallet.name.includes("Ethereum")) { acc.evmWallets.push(wallet); } else if (wallet.name.includes("Solana")) { acc.solanaWallets.push(wallet); } else { acc.aptosWallets.push(wallet); } return acc; }, { evmWallets: [], solanaWallets: [], aptosWallets: [] } ) : { evmWallets: [], solanaWallets: [], aptosWallets: availableWallets }; const { evmInstallableWallets, solanaInstallableWallets, aptosInstallableWallets } = crossChainMode ? installableWallets.reduce( (acc, wallet) => { if (wallet.name.includes("Ethereum")) { acc.evmInstallableWallets.push(wallet); } else if (wallet.name.includes("Solana")) { acc.solanaInstallableWallets.push(wallet); } else { acc.aptosInstallableWallets.push(wallet); } return acc; }, { evmInstallableWallets: [], solanaInstallableWallets: [], aptosInstallableWallets: [] } ) : { evmInstallableWallets: [], solanaInstallableWallets: [], aptosInstallableWallets: installableWallets }; const tabsConfig = crossChainMode ? [ { key: "aptos", label: "Aptos", enabled: true }, { key: "solana", label: "Solana", enabled: crossChainWallets.solana }, { key: "evm", label: "Ethereum", enabled: crossChainWallets.evm } ].filter((tab) => tab.enabled) : []; const getTabIndex = (key) => tabsConfig.findIndex((tab) => tab.key === key); const renderWalletList = (wallets2, installableWallets2) => /* @__PURE__ */ jsxs3(Fragment2, { children: [ wallets2.map((wallet) => /* @__PURE__ */ jsx3(WalletRow, { wallet, onConnect: handleClose }, wallet.name)), !!installableWallets2.length && /* @__PURE__ */ jsxs3(Fragment2, { children: [ /* @__PURE__ */ jsx3( Button2, { variant: "text", size: "small", onClick: () => setExpanded((prev) => !prev), endIcon: /* @__PURE__ */ jsx3(ExpandMore, { sx: { height: "20px", width: "20px" } }), children: "More Wallets" } ), /* @__PURE__ */ jsx3(Collapse, { in: expanded, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */ jsx3(Stack, { sx: { gap: 1 }, children: installableWallets2.map((wallet) => /* @__PURE__ */ jsx3( WalletRow, { wallet, onConnect: handleClose }, wallet.name )) }) }) ] }) ] }); return /* @__PURE__ */ jsx3( Dialog, { open: modalOpen, onClose: handleClose, "aria-label": "wallet selector modal", sx: { borderRadius: `${theme.shape.borderRadius}px` }, maxWidth: modalMaxWidth ?? "xs", fullWidth: true, children: /* @__PURE__ */ jsxs3( Stack, { sx: { top: "50%", left: "50%", bgcolor: "background.paper", boxShadow: 24, p: 3, gap: 2 }, children: [ /* @__PURE__ */ jsx3( IconButton, { onClick: handleClose, sx: { position: "absolute", right: 12, top: 12, color: grey[450] }, children: /* @__PURE__ */ jsx3(CloseIcon, {}) } ), /* @__PURE__ */ jsxs3(AboutAptosConnect, { renderEducationScreen, children: [ /* @__PURE__ */ jsx3( Typography2, { align: "center", variant: "h5", component: "h2", pt: 2, sx: { display: "flex", flexDirection: "column" }, children: hasAptosConnectWallets ? /* @__PURE__ */ jsxs3(Fragment2, { children: [ /* @__PURE__ */ jsx3("span", { children: "Log in or sign up" }), /* @__PURE__ */ jsx3("span", { children: "with Social + Petra Web" }) ] }) : "Connect Wallet" } ), networkSupport && /* @__PURE__ */ jsxs3( Box, { sx: { display: "flex", gap: 0.5, alignItems: "center", justifyContent: "center" }, children: [ /* @__PURE__ */ jsx3( LanOutlinedIcon, { sx: { fontSize: "0.9rem", color: grey[400] } } ), /* @__PURE__ */ jsxs3( Typography2, { sx: { display: "inline-flex", fontSize: "0.9rem", color: grey[400] }, align: "center", children: [ networkSupport, " only" ] } ) ] } ), hasAptosConnectWallets && /* @__PURE__ */ jsxs3(Stack, { gap: 1, children: [ aptosConnectWallets.map((wallet) => /* @__PURE__ */ jsx3( AptosConnectWalletRow, { wallet, onConnect: handleClose }, wallet.name )), /* @__PURE__ */ jsxs3( Typography2, { component: "p", fontSize: "14px", sx: { display: "flex", gap: 0.5, justifyContent: "center", alignItems: "center", color: grey[400] }, children: [ "Learn more about", " ", /* @__PURE__ */ jsxs3( Box, { component: AboutAptosConnect.Trigger, sx: { background: "none", border: "none", fontFamily: "inherit", fontSize: "inherit", cursor: "pointer", display: "flex", gap: 0.5, px: 0, py: 1.5, alignItems: "center", color: theme.palette.text.primary, appearance: "none" }, children: [ "Petra Web ", /* @__PURE__ */ jsx3(ArrowForward, { sx: { height: 16, width: 16 } }) ] } ) ] } ), /* @__PURE__ */ jsxs3( Stack, { component: AptosPrivacyPolicy, alignItems: "center", py: 0.5, children: [ /* @__PURE__ */ jsxs3(Typography2, { component: "p", fontSize: "12px", lineHeight: "20px", children: [ /* @__PURE__ */ jsx3(AptosPrivacyPolicy.Disclaimer, {}), " ", /* @__PURE__ */ jsx3( Box, { component: AptosPrivacyPolicy.Link, sx: { color: grey[400], textDecoration: "underline", textUnderlineOffset: "4px" } } ), /* @__PURE__ */ jsx3("span", { children: "." }) ] }), /* @__PURE__ */ jsx3( Box, { component: AptosPrivacyPolicy.PoweredBy, sx: { display: "flex", alignItems: "center", gap: 0.75, fontSize: "12px", lineHeight: "20px", color: grey[400] } } ) ] } ), /* @__PURE__ */ jsx3(Divider, { sx: { color: grey[400], pt: 2 }, children: "Or" }) ] }), crossChainMode ? /* @__PURE__ */ jsxs3(Fragment2, { children: [ /* @__PURE__ */ jsx3( Tabs, { value: tabValue, onChange: handleTabChange, textColor: "secondary", indicatorColor: "secondary", variant: "fullWidth", "aria-label": "cross chain wallets tabs", children: tabsConfig.map((tab, index) => /* @__PURE__ */ jsx3(Tab, { label: tab.label, ...a11yProps(index) }, tab.key)) } ), /* @__PURE__ */ jsx3(TabPanel, { value: tabValue, index: getTabIndex("aptos"), children: renderWalletList(aptosWallets, aptosInstallableWallets) }), crossChainWallets.solana && /* @__PURE__ */ jsx3(TabPanel, { value: tabValue, index: getTabIndex("solana"), children: renderWalletList(solanaWallets, solanaInstallableWallets) }), crossChainWallets.evm && /* @__PURE__ */ jsx3(TabPanel, { value: tabValue, index: getTabIndex("evm"), children: renderWalletList(evmWallets, evmInstallableWallets) }) ] }) : ( // Simple list mode (original WalletModel behavior) /* @__PURE__ */ jsx3(Stack, { sx: { gap: 1 }, children: renderWalletList(availableWallets, installableWallets) }) ) ] }) ] } ) } ); } function WalletRow({ wallet, onConnect }) { const theme = useTheme(); return /* @__PURE__ */ jsx3(WalletItem, { wallet, onConnect, asChild: true, children: /* @__PURE__ */ jsx3(ListItem2, { disablePadding: true, children: /* @__PURE__ */ jsxs3( Box, { sx: { display: "flex", alignItems: "center", width: "100%", px: 2, py: 1.5, gap: 2, border: "solid 1px", borderColor: theme.palette.mode === "dark" ? grey[700] : grey[200], borderRadius: `${theme.shape.borderRadius}px` }, children: [ /* @__PURE__ */ jsx3(Box, { component: WalletItem.Icon, sx: { width: 32, height: 32 } }), /* @__PURE__ */ jsx3( ListItemText2, { primary: wallet.name, primaryTypographyProps: { fontSize: "1.125rem" } } ), isInstallRequired(wallet) ? /* @__PURE__ */ jsx3(WalletItem.InstallLink, { asChild: true, children: /* @__PURE__ */ jsx3( Button2, { LinkComponent: "a", size: "small", className: "wallet-connect-install", children: "Install" } ) }) : /* @__PURE__ */ jsx3(WalletItem.ConnectButton, { asChild: true, children: /* @__PURE__ */ jsx3( Button2, { variant: "contained", size: "small", className: "wallet-connect-button", children: "Connect" } ) }) ] } ) }) }); } function AptosConnectWalletRow({ wallet, onConnect }) { return /* @__PURE__ */ jsx3(WalletItem, { wallet, onConnect, asChild: true, children: /* @__PURE__ */ jsx3(WalletItem.ConnectButton, { asChild: true, children: /* @__PURE__ */ jsxs3( Button2, { size: "large", variant: "outlined", sx: { display: "flex", alignItems: "center", gap: 1.5 }, children: [ /* @__PURE__ */ jsx3(Box, { component: WalletItem.Icon, sx: { width: 20, height: 20 } }), /* @__PURE__ */ jsx3(WalletItem.Name, {}) ] } ) }) }); } function renderEducationScreen(screen) { return /* @__PURE__ */ jsxs3(Fragment2, { children: [ /* @__PURE__ */ jsxs3( Box, { sx: { display: "grid", gridTemplateColumns: "1fr 4fr 1fr", alignItems: "center", justifyItems: "start" }, children: [ /* @__PURE__ */ jsx3(IconButton, { onClick: screen.cancel, children: /* @__PURE__ */ jsx3(ArrowBack, {}) }), /* @__PURE__ */ jsx3(Typography2, { variant: "body1", component: "h2", width: "100%", align: "center", children: "About Petra Web" }) ] } ), /* @__PURE__ */ jsx3( Box, { sx: { display: "flex", pb: 1.5, alignItems: "end", justifyContent: "center", height: "162px" }, children: /* @__PURE__ */ jsx3(screen.Graphic, {}) } ), /* @__PURE__ */ jsxs3(Stack, { sx: { gap: 1, textAlign: "center", pb: 2 }, children: [ /* @__PURE__ */ jsx3(Typography2, { component: screen.Title, variant: "h6" }), /* @__PURE__ */ jsx3( Typography2, { component: screen.Description, variant: "body2", color: (theme) => theme.palette.text.secondary, sx: { "&>a": { color: (theme) => theme.palette.text.primary, textDecoration: "underline", textUnderlineOffset: "4px" } } } ) ] }), /* @__PURE__ */ jsxs3( Box, { sx: { display: "grid", gridTemplateColumns: "repeat(3, minmax(0, 1fr))", alignItems: "center" }, children: [ /* @__PURE__ */ jsx3( Button2, { size: "small", variant: "text", onClick: screen.back, sx: { justifySelf: "start" }, children: "Back" } ), /* @__PURE__ */ jsx3( Box, { sx: { display: "flex", alignItems: "center", gap: 1, placeSelf: "center" }, children: screen.screenIndicators.map((ScreenIndicator, i) => /* @__PURE__ */ jsx3( Box, { component: ScreenIndicator, sx: { px: 0, py: 2, background: "none", border: "none", cursor: "pointer" }, children: /* @__PURE__ */ jsx3( Box, { sx: { height: "2px", width: "24px", bgcolor: (theme) => theme.palette.text.disabled, "[data-active]>&": { bgcolor: (theme) => theme.palette.text.primary } } } ) }, i )) } ), /* @__PURE__ */ jsx3( Button2, { size: "small", variant: "text", onClick: screen.next, sx: { justifySelf: "end" }, endIcon: /* @__PURE__ */ jsx3(ArrowForward, { sx: { height: 16, width: 16 } }), children: screen.screenIndex === screen.totalScreens - 1 ? "Finish" : "Next" } ) ] } ) ] }); } function TabPanel(props) { const { children, value, index, ...other } = props; return /* @__PURE__ */ jsx3( "div", { role: "tabpanel", hidden: value !== index, id: `simple-tabpanel-${index}`, "aria-labelledby": `simple-tab-${index}`, ...other, children: value === index && /* @__PURE__ */ jsx3(Stack, { sx: { gap: 1 }, children }) } ); } function a11yProps(index) { return { id: `simple-tab-${index}`, "aria-controls": `simple-tabpanel-${index}` }; } // src/WalletConnector.tsx import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime"; function WalletConnector({ networkSupport, handleNavigate, modalMaxWidth, crossChainWallets, ...walletSortingOptions }) { const [modalOpen, setModalOpen] = useState4(false); const handleModalOpen = () => setModalOpen(true); const handleClose = () => setModalOpen(false); return /* @__PURE__ */ jsxs4(Fragment3, { children: [ /* @__PURE__ */ jsx4( WalletButton, { handleModalOpen, handleNavigate } ), /* @__PURE__ */ jsx4( WalletsModal, { handleClose, modalOpen, networkSupport, modalMaxWidth, crossChainWallets, ...walletSortingOptions } ) ] }); } export { WalletConnector };