@daimo/pay
Version:
Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.
193 lines (190 loc) • 6.44 kB
JavaScript
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { getAddressContraction } from '@daimo/pay-common';
import { useWallet } from '@solana/wallet-adapter-react';
import { motion } from 'framer-motion';
import { useAccount } from 'wagmi';
import { Solana, Ethereum, Optimism, Arbitrum, Base, Polygon } from '../../../assets/chains.js';
import { USDC } from '../../../assets/coins.js';
import defaultTheme from '../../../constants/defaultTheme.js';
import { ROUTES } from '../../../constants/routes.js';
import { useDaimoPay } from '../../../hooks/useDaimoPay.js';
import useLocales from '../../../hooks/useLocales.js';
import { usePayContext } from '../../../hooks/usePayContext.js';
import styled from '../../../styles/styled/index.js';
import { formatUsd } from '../../../utils/format.js';
const OrderHeader = ({
minified = false,
show = "all"
}) => {
const { paymentState, route } = usePayContext();
const { isConnected: isEthConnected, address, connector } = useAccount();
const {
connected: isSolanaConnected,
publicKey,
wallet: solanaWallet
} = useWallet();
const { senderEnsName } = paymentState;
const { order } = useDaimoPay();
const ethWalletDisplayName = senderEnsName ?? (address ? getAddressContraction(address) : "wallet");
const solWalletDisplayName = getAddressContraction(
publicKey?.toBase58() ?? ""
);
const orderUsd = order?.destFinalCallTokenAmount.usd;
const locales = useLocales();
const titleAmountContent = (() => {
if (paymentState.isDepositFlow) {
return route === ROUTES.SELECT_TOKEN ? (
// TODO: make this match `ModalH1` font size for mobile
/* @__PURE__ */ jsx("span", { style: { fontSize: "19px", lineHeight: "22px" }, children: locales.yourBalances })
) : null;
} else {
return orderUsd != null ? /* @__PURE__ */ jsx("span", { children: formatUsd(orderUsd, "nearest") }) : null;
}
})();
const renderIcon = (icon, name, size = 32) => {
if (!icon) {
return null;
}
return /* @__PURE__ */ jsx(LogoContainer, { $size: size, $zIndex: 1, style: { borderRadius: "22.5%" }, children: typeof icon === "string" ? /* @__PURE__ */ jsx(
"img",
{
src: icon,
alt: name || "wallet",
style: { maxWidth: "100%", maxHeight: "100%" }
}
) : icon });
};
let walletIcon = renderIcon(connector?.icon);
let solanaIcon = renderIcon(
solanaWallet?.adapter.icon || /* @__PURE__ */ jsx(Solana, {}),
solanaWallet?.adapter.name
);
if (minified) {
if (titleAmountContent != null) {
return /* @__PURE__ */ jsxs(MinifiedContainer, { children: [
/* @__PURE__ */ jsx(MinifiedTitleAmount, { children: titleAmountContent }),
show === "evm" && isEthConnected && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(SubtitleContainer, { children: [
/* @__PURE__ */ jsx(Subtitle, { children: ethWalletDisplayName }),
walletIcon
] }) }),
show === "solana" && isSolanaConnected && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(SubtitleContainer, { children: [
/* @__PURE__ */ jsx(Subtitle, { children: solWalletDisplayName }),
solanaIcon
] }) })
] });
}
} else {
return /* @__PURE__ */ jsxs(Fragment, { children: [
titleAmountContent && /* @__PURE__ */ jsx(TitleAmount, { children: titleAmountContent }),
/* @__PURE__ */ jsxs(AnyChainAnyCoinContainer, { children: [
/* @__PURE__ */ jsx(CoinLogos, {}),
/* @__PURE__ */ jsx(Subtitle, { children: locales.tokensAccepted })
] })
] });
}
};
function CoinLogos({ $size = 24 }) {
const logos = [
/* @__PURE__ */ jsx(Ethereum, {}, "eth"),
/* @__PURE__ */ jsx(USDC, {}, "usdc"),
/* @__PURE__ */ jsx(Optimism, {}, "optimism"),
/* @__PURE__ */ jsx(Arbitrum, {}, "arbitrum"),
/* @__PURE__ */ jsx(Base, {}, "base"),
/* @__PURE__ */ jsx(Polygon, {}, "polygon"),
/* @__PURE__ */ jsx(Solana, {}, "solana")
];
const logoBlock = (element, index) => /* @__PURE__ */ jsx(
LogoContainer,
{
$marginLeft: index !== 0 ? -($size / 3) : 0,
$zIndex: logos.length - index,
$size,
transition: { duration: 0.5, ease: [0.175, 0.885, 0.32, 0.98] },
children: element
},
index
);
return /* @__PURE__ */ jsx(Logos, { children: logos.map((element, index) => logoBlock(element, index)) });
}
const TitleAmount = styled(motion.h1)`
margin-bottom: 24px;
padding: 0;
line-height: 66px;
font-size: 64px;
font-weight: var(--ck-modal-h1-font-weight, 600);
color: ${(props) => {
if (props.$error) return "var(--ck-body-color-danger)";
if (props.$valid) return "var(--ck-body-color-valid)";
return "var(--ck-body-color)";
}};
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
font-size: 64px;
}
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
`;
const Subtitle = styled(motion.div)`
font-size: 18px;
font-weight: 500;
line-height: 21px;
color: var(--ck-body-color-muted);
`;
const MinifiedTitleAmount = styled(motion.div)`
font-size: 32px;
font-weight: var(--ck-modal-h1-font-weight, 600);
line-height: 36px;
color: var(--ck-body-color);
display: flex;
align-items: center;
justify-content: start;
gap: 8px;
`;
const MinifiedContainer = styled(motion.div)`
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
margin-bottom: 24px;
`;
const AnyChainAnyCoinContainer = styled(motion.div)`
display: flex;
vertical-align: middle;
align-items: center;
justify-content: center;
text-align: center;
gap: 8px;
margin-bottom: 24px;
`;
const LogoContainer = styled(motion.div)`
display: block;
overflow: hidden;
user-select: none;
display: flex;
align-items: center;
justify-content: center;
margin-left: ${(props) => props.$marginLeft || 0}px;
z-index: ${(props) => props.$zIndex || 2};
width: ${(props) => props.$size}px;
height: ${(props) => props.$size}px;
border-radius: 9999px;
svg {
display: block;
width: 100%;
height: auto;
}
`;
const Logos = styled(motion.div)`
display: flex;
align-items: center;
justify-content: center;
`;
const SubtitleContainer = styled.div`
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
`;
export { OrderHeader };
//# sourceMappingURL=index.js.map