@whop/embedded-components-react-js
Version:
React components for Whop.js
88 lines (87 loc) • 2.5 kB
JavaScript
"use client";
import { __publicField } from "./chunk-NSSMTXJJ.mjs";
import React, { useSyncExternalStore } from "react";
import { createContext, useContext, useEffect, useMemo } from "react";
const ElementsContext = createContext(null);
function useElements() {
const ctx = useContext(ElementsContext);
if (!ctx) {
throw new Error("useElements must be used within a ElementsProvider");
}
return ctx.elements;
}
function normalizeElementsProp(prop) {
if (prop instanceof Promise) return prop;
return Promise.resolve(prop);
}
class PromiseStore {
constructor(promise){
__publicField(this, "subscribers", new Set());
__publicField(this, "value", {
state: "pending"
});
__publicField(this, "subscribe", (listener)=>{
this.subscribers.add(listener);
return ()=>{
this.subscribers.delete(listener);
};
});
promise.then((value)=>{
this.value = {
state: "fulfilled",
value
};
for (const subscriber of this.subscribers){
subscriber();
}
}).catch((err)=>{
this.value = {
state: "rejected",
error: err
};
for (const subscriber of this.subscribers){
subscriber();
}
});
}
getSnapshot() {
return this.value;
}
}
function useAwaitElements(elements) {
const store = useMemo(()=>new PromiseStore(Promise.resolve(elements)), [
elements
]);
const state = useSyncExternalStore(store.subscribe, ()=>{
const snapshot = store.getSnapshot();
if (snapshot.state === "fulfilled") {
return snapshot.value;
}
return null;
}, ()=>null);
return state;
}
function Elements({ children, elements: elementsProp, appearance, locale }) {
const elementsPromise = normalizeElementsProp(elementsProp);
const elements = useAwaitElements(elementsPromise);
useEffect(()=>{
if (!elements) return;
elements.updateOptions({
appearance,
locale
});
}, [
elements,
appearance,
locale
]);
const value = useMemo(()=>({
elements
}), [
elements
]);
return React.createElement(ElementsContext.Provider, {
value
}, children);
}
export { Elements, useElements };