@whop/react
Version:
React SDK for building embedded apps on Whop
93 lines (92 loc) • 3.75 kB
JavaScript
"use client";
import { EMBEDDED_CHECKOUT_IFRAME_ALLOW_STRING, getEmail, onWhopCheckoutMessage, setEmail, submitCheckoutFrame } from "@whop/checkout/util";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useIsHydrated } from "../util/use-is-hydrated.mjs";
import { isAccentColor } from "./colors.mjs";
import { EMBEDDED_CHECKOUT_IFRAME_SANDBOX_STRING, useEmbeddedCheckoutIframeUrl } from "./util.mjs";
function WhopCheckoutEmbedInner({ planId, ref, theme, sessionId, hidePrice = false, skipRedirect = false, onComplete, onStateChange, utm, styles, prefill, themeOptions, hideSubmitButton = false, hideTermsAndConditions = false, hideEmail = false, disableEmail = false }) {
const resolvedThemeOptions = useMemo(()=>{
return {
accentColor: isAccentColor(themeOptions?.accentColor) ? themeOptions.accentColor : undefined
};
}, [
themeOptions?.accentColor
]);
const iframeUrl = useEmbeddedCheckoutIframeUrl(planId, theme, sessionId, undefined, hidePrice, skipRedirect || !!onComplete, utm, styles, prefill, resolvedThemeOptions, hideSubmitButton, hideTermsAndConditions, hideEmail, disableEmail);
const iframeRef = useRef(null);
const [height, setHeight] = useState(480);
useEffect(()=>{
const iframe = iframeRef.current;
if (!iframe) return;
return onWhopCheckoutMessage(iframe, function handleWhopCheckoutMessage(message) {
switch(message.event){
case "resize":
{
setHeight(message.height);
break;
}
case "center":
{
iframe.scrollIntoView({
block: "center",
inline: "center"
});
break;
}
case "complete":
{
if (onComplete) {
onComplete(message.plan_id, message.receipt_id);
}
break;
}
case "state":
{
if (onStateChange) {
onStateChange(message.state);
}
break;
}
}
});
}, [
onComplete,
onStateChange
]);
if (ref) {
ref.current = {
submit: (opts)=>{
if (!iframeRef.current) return;
submitCheckoutFrame(iframeRef.current, opts);
},
getEmail: (timeout)=>{
if (!iframeRef.current) throw new Error("Whop embedded checkout frame not found");
return getEmail(iframeRef.current, timeout);
},
setEmail: (email, timeout)=>{
if (!iframeRef.current) throw new Error("Whop embedded checkout frame not found");
return setEmail(iframeRef.current, email, timeout);
}
};
}
return React.createElement("iframe", {
ref: iframeRef,
allow: EMBEDDED_CHECKOUT_IFRAME_ALLOW_STRING,
sandbox: EMBEDDED_CHECKOUT_IFRAME_SANDBOX_STRING,
title: "Whop Embedded Checkout",
src: iframeUrl,
style: {
border: "none",
height: `${height}px`,
width: "100%",
overflow: "hidden"
}
});
}
export function WhopCheckoutEmbed({ fallback = null, ...props }) {
const isHydrated = useIsHydrated();
if (!isHydrated) {
return fallback;
}
return React.createElement(WhopCheckoutEmbedInner, props);
}