@blocklet/payment-react
Version:
Reusable react components for payment kit v2
237 lines (236 loc) • 7.94 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { Box } from "@mui/material";
import { alpha, useTheme } from "@mui/material/styles";
import Header from "@blocklet/ui-react/lib/Header";
import { useMobile } from "../../hooks/mobile.js";
const hiddenScrollbar = {
overflowY: "auto",
"&::-webkit-scrollbar": { display: "none" },
scrollbarWidth: "none"
};
const mobileFadeIn = {
"@keyframes mobileFadeIn": {
from: { opacity: 0 },
to: { opacity: 1 }
},
animation: { xs: "mobileFadeIn 0.4s ease both", md: "none" }
};
const fadeIn = {
"@keyframes fadeIn": {
from: { opacity: 0, transform: "translateY(12px)" },
to: { opacity: 1, transform: "translateY(0)" }
},
animation: { xs: "none", md: "fadeIn 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.15s both" }
};
const isSafari = typeof navigator !== "undefined" && /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
const slideInFromRight = isSafari ? {
"@keyframes panelFadeIn": {
from: { opacity: 0, transform: "translateX(24px)" },
to: { opacity: 1, transform: "none" }
},
animation: { xs: "none", md: "panelFadeIn 0.5s cubic-bezier(0.16, 1, 0.3, 1) both" }
} : {
"@keyframes slideInRight": {
from: { transform: "translateX(100%)" },
to: { transform: "translateX(0)" }
},
animation: { xs: "none", md: "slideInRight 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards" }
};
export default function CheckoutLayout({ left, right, mode = "inline" }) {
const isFullScreen = mode === "standalone";
const { isMobile } = useMobile();
const theme = useTheme();
const isDark = theme.palette.mode === "dark";
const hideLeft = left === null;
const mobileSubmitBarSx = {};
if (isMobile && !hideLeft) {
mobileSubmitBarSx["& .cko-v2-submit-btn"] = {
position: "fixed",
bottom: 0,
left: 0,
right: 0,
zIndex: 999,
bgcolor: isDark ? "rgba(30,30,30,0.82)" : "background.paper",
backdropFilter: isDark ? "blur(12px)" : "none",
p: 1.5,
borderTop: "1px solid",
borderColor: "divider",
boxShadow: isDark ? "0 -4px 20px rgba(0,0,0,0.4)" : "0 -2px 10px rgba(0,0,0,0.08)"
};
}
if (!isFullScreen) {
return /* @__PURE__ */ jsxs(
Box,
{
sx: {
display: "flex",
flexDirection: { xs: "column", md: "row" },
width: "100%",
minHeight: { md: 640 },
maxWidth: 1120,
mx: "auto",
borderRadius: "16px",
overflow: "hidden",
boxShadow: 1,
border: 1,
borderColor: "divider",
borderLeft: "4px solid",
borderLeftColor: "primary.main",
// Same bg as left panel so slide-in reveals white over gradient
bgcolor: (t) => t.palette.mode === "dark" ? "background.default" : "#f8faff",
...mobileFadeIn
},
children: [
!hideLeft && /* @__PURE__ */ jsx(
Box,
{
sx: {
flex: 1,
minWidth: 0,
bgcolor: (t) => t.palette.mode === "dark" ? "background.default" : "#f8faff",
p: { xs: 3, md: 5 },
pt: { xs: 3, md: 4 },
display: "flex",
flexDirection: "column",
...fadeIn
},
children: left
}
),
/* @__PURE__ */ jsx(
Box,
{
sx: {
width: hideLeft ? "100%" : { xs: "100%", md: 480 },
flexShrink: 0,
bgcolor: "background.paper",
p: { xs: 3, md: 4 },
pt: { xs: 3, md: 4 },
display: "flex",
flexDirection: "column",
overflow: { md: "hidden" },
...hideLeft ? {} : slideInFromRight
},
children: right
}
)
]
}
);
}
const mobileBg = isDark ? theme.palette.background.default : theme.palette.grey[100];
const desktopBg = isDark ? theme.palette.background.default : "#f8faff";
return /* @__PURE__ */ jsxs(
Box,
{
sx: {
width: "100%",
height: { xs: "auto", md: "100vh" },
minHeight: { xs: "100vh" },
overflow: { md: "hidden" },
display: "flex",
flexDirection: { xs: "column", md: "row" },
position: "relative",
// Mobile: solid gray bg; Desktop: gradient over light blue
background: isMobile ? mobileBg : `linear-gradient(160deg, ${alpha(theme.palette.primary.main, 0.03)} 0%, ${alpha(theme.palette.primary.main, 0.07)} 50%, ${alpha(theme.palette.primary.main, 0.04)} 100%)`,
bgcolor: desktopBg,
...mobileFadeIn
},
children: [
/* @__PURE__ */ jsx(
Header,
{
sx: {
position: "absolute",
top: 20,
left: 0,
right: 0,
zIndex: 10,
background: "transparent",
"& .header-container": { height: "auto" }
},
hideNavMenu: true,
brand: null,
description: null,
addons: (buildIns) => {
const addons = buildIns.filter(
(addon) => ["locale-selector", "theme-mode-toggle", "session-user"].includes(addon.key)
);
return addons;
}
}
),
!hideLeft && /* @__PURE__ */ jsx(
Box,
{
sx: {
flex: { xs: "none", md: "0 0 50%" },
width: { xs: "100%" },
height: { xs: "auto", md: "100vh" },
display: "flex",
justifyContent: { md: "center" },
...isMobile ? { bgcolor: "background.paper", mt: 9 } : {},
...hiddenScrollbar
},
children: /* @__PURE__ */ jsx(
Box,
{
sx: {
width: "100%",
maxWidth: { md: 640 },
p: { xs: 3, md: 5 },
pt: { xs: 3, md: 10 },
display: "flex",
flexDirection: "column",
flex: 1,
...fadeIn
},
children: left
}
)
}
),
/* @__PURE__ */ jsx(
Box,
{
sx: {
flex: hideLeft ? "none" : { xs: "none", md: "0 0 50%" },
width: hideLeft ? "100%" : { xs: "100%" },
height: hideLeft ? "100vh" : { xs: "auto", md: "100vh" },
bgcolor: "background.paper",
boxShadow: hideLeft ? "none" : { md: "-4px 0 16px rgba(0,0,0,0.04)" },
position: "relative",
display: "flex",
flexDirection: "column",
...hideLeft ? {} : slideInFromRight,
...isMobile && !hideLeft ? { pb: "180px", mt: 2 } : {},
// Mobile: scroll entire panel; Desktop: let PaymentPanel handle internal scroll
overflowY: { xs: "auto", md: "hidden" },
"&::-webkit-scrollbar": { display: "none" },
scrollbarWidth: "none",
...mobileSubmitBarSx
},
children: /* @__PURE__ */ jsx(
Box,
{
sx: {
width: "100%",
maxWidth: { md: 600 },
mx: "auto",
p: { xs: 3, md: 4 },
pt: hideLeft ? { xs: 10, md: "10vh" } : { xs: 3, md: "10vh" },
display: "flex",
flexDirection: "column",
flex: 1,
minHeight: 0,
justifyContent: hideLeft ? "center" : void 0
},
children: right
}
)
}
)
]
}
);
}