voltage-payments-component
Version:
Lightweight, framework-agnostic Bitcoin payment components for web applications using Voltage Payments
460 lines (451 loc) • 16.1 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
class PaymentInlineComponent {
constructor(options) {
this.svelteComponent = null;
this.container = null;
this.options = options;
}
async mount(selector) {
const target = typeof selector === "string" ? document.querySelector(selector) : selector;
if (!target) {
throw new Error(`Cannot find element: ${selector}`);
}
if (!(target instanceof HTMLElement)) {
throw new Error("Target must be an HTMLElement");
}
this.container = target;
const PaymentInlineModule = await import("./PaymentInline-DS0xmQAd.js").then((n) => n.F);
const PaymentInline = PaymentInlineModule.default;
this.svelteComponent = new PaymentInline({
target: this.container,
props: __spreadProps(__spreadValues({}, this.options), {
paymentKind: this.options.paymentKind || "bip21",
description: this.options.description || "",
appearance: this.options.appearance || {},
theme: this.options.theme || "auto",
showQRCode: this.options.showQRCode !== false,
showCopyButton: this.options.showCopyButton !== false,
pollingConfig: this.options.pollingConfig || {}
})
});
this.setupEventListeners();
}
unmount() {
if (this.svelteComponent) {
this.svelteComponent.$destroy();
this.svelteComponent = null;
}
this.container = null;
}
destroy() {
this.unmount();
}
updateOptions(newOptions) {
this.options = __spreadValues(__spreadValues({}, this.options), newOptions);
if (this.svelteComponent) {
this.svelteComponent.$set(__spreadProps(__spreadValues({}, this.options), {
paymentKind: this.options.paymentKind || "bip21",
description: this.options.description || "",
appearance: this.options.appearance || {},
theme: this.options.theme || "auto",
showQRCode: this.options.showQRCode !== false,
showCopyButton: this.options.showCopyButton !== false,
pollingConfig: this.options.pollingConfig || {}
}));
}
}
getStatus() {
return "generating";
}
getPaymentData() {
return null;
}
setupEventListeners() {
if (!this.svelteComponent) return;
this.svelteComponent.$on("ready", (event) => {
var _a, _b;
(_b = (_a = this.options).onReady) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("qrGenerated", (event) => {
var _a, _b;
const { qrData, paymentRequest } = event.detail;
(_b = (_a = this.options).onQRGenerated) == null ? void 0 : _b.call(_a, qrData, paymentRequest);
});
this.svelteComponent.$on("statusChange", (event) => {
var _a, _b;
const { status, payment } = event.detail;
(_b = (_a = this.options).onStatusChange) == null ? void 0 : _b.call(_a, status, payment);
});
this.svelteComponent.$on("success", (event) => {
var _a, _b;
(_b = (_a = this.options).onSuccess) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("error", (event) => {
var _a, _b;
(_b = (_a = this.options).onError) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("expired", (event) => {
var _a, _b;
(_b = (_a = this.options).onExpired) == null ? void 0 : _b.call(_a, event.detail);
});
}
}
class PaymentModalComponent {
constructor(options) {
this.svelteComponent = null;
this.container = null;
this.triggerButton = null;
this.options = options;
}
async mount(selector) {
const target = typeof selector === "string" ? document.querySelector(selector) : selector;
if (!target) {
throw new Error(`Cannot find element: ${selector}`);
}
if (!(target instanceof HTMLElement)) {
throw new Error("Target must be an HTMLElement");
}
this.container = target;
this.createTriggerButton();
const PaymentModalModule = await import("./PaymentModal-Bc2wPD9_.js");
const PaymentModal = PaymentModalModule.default;
this.svelteComponent = new PaymentModal({
target: document.body,
props: __spreadProps(__spreadValues({}, this.options), {
paymentKind: this.options.paymentKind || "bip21",
description: this.options.description || "",
appearance: this.options.appearance || {},
theme: this.options.theme || "auto",
showQRCode: this.options.showQRCode !== false,
showCopyButton: this.options.showCopyButton !== false,
pollingConfig: this.options.pollingConfig || {},
autoClose: this.options.autoClose !== false
})
});
this.setupEventListeners();
}
unmount() {
if (this.svelteComponent) {
this.svelteComponent.$destroy();
this.svelteComponent = null;
}
if (this.triggerButton && this.container) {
this.container.removeChild(this.triggerButton);
this.triggerButton = null;
}
this.container = null;
}
destroy() {
this.unmount();
}
updateOptions(newOptions) {
this.options = __spreadValues(__spreadValues({}, this.options), newOptions);
if (this.svelteComponent) {
this.svelteComponent.$set(__spreadProps(__spreadValues({}, this.options), {
paymentKind: this.options.paymentKind || "bip21",
description: this.options.description || "",
appearance: this.options.appearance || {},
theme: this.options.theme || "auto",
showQRCode: this.options.showQRCode !== false,
showCopyButton: this.options.showCopyButton !== false,
pollingConfig: this.options.pollingConfig || {},
autoClose: this.options.autoClose !== false
}));
}
if (this.triggerButton && newOptions.description) {
const buttonText = this.triggerButton.querySelector(
".voltage-modal-trigger-text"
);
if (buttonText) {
buttonText.textContent = newOptions.description;
}
}
}
getStatus() {
return "generating";
}
getPaymentData() {
return null;
}
// Modal-specific public methods
open() {
var _a, _b;
if (this.svelteComponent) {
this.svelteComponent.open();
(_b = (_a = this.options).onModalOpen) == null ? void 0 : _b.call(_a);
}
}
close() {
var _a, _b;
if (this.svelteComponent) {
this.svelteComponent.close();
(_b = (_a = this.options).onModalClose) == null ? void 0 : _b.call(_a);
}
}
createTriggerButton() {
if (!this.container) return;
this.triggerButton = document.createElement("button");
this.triggerButton.className = "voltage-modal-trigger";
this.triggerButton.innerHTML = `
<svg class="voltage-modal-trigger-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7v10c0 5.55 3.84 10 9 11 5.16-1 9-5.45 9-11V7z"/>
<path d="M9 12l2 2 4-4"/>
</svg>
<span class="voltage-modal-trigger-text">
${this.options.description || "Pay with Bitcoin"}
</span>
`;
this.triggerButton.addEventListener("click", () => {
this.open();
});
this.addTriggerButtonStyles();
this.container.appendChild(this.triggerButton);
}
addTriggerButtonStyles() {
var _a, _b, _c;
if (!this.triggerButton) return;
const primaryColor = ((_a = this.options.appearance) == null ? void 0 : _a.primaryColor) || "#f7931a";
const borderRadius = ((_b = this.options.appearance) == null ? void 0 : _b.borderRadius) || "8px";
const fontFamily = ((_c = this.options.appearance) == null ? void 0 : _c.fontFamily) || "system-ui, sans-serif";
if (!document.getElementById("voltage-modal-trigger-styles")) {
const style = document.createElement("style");
style.id = "voltage-modal-trigger-styles";
style.textContent = `
.voltage-modal-trigger {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1.5rem;
background: ${primaryColor};
color: white;
border: none;
border-radius: ${borderRadius};
font-family: ${fontFamily};
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 150ms ease-in-out;
text-decoration: none;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
.voltage-modal-trigger:hover {
opacity: 0.9;
transform: translateY(-1px);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.voltage-modal-trigger:active {
transform: translateY(0);
}
.voltage-modal-trigger:focus {
outline: 2px solid ${primaryColor};
outline-offset: 2px;
}
.voltage-modal-trigger-icon {
flex-shrink: 0;
}
.voltage-modal-trigger-text {
white-space: nowrap;
}
/* Dark theme support */
(prefers-color-scheme: dark) {
.voltage-modal-trigger {
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
}
.voltage-modal-trigger:hover {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
}
}
/* Mobile responsive */
(max-width: 640px) {
.voltage-modal-trigger {
padding: 0.625rem 1.25rem;
font-size: 0.875rem;
}
}
`;
document.head.appendChild(style);
}
}
setupEventListeners() {
if (!this.svelteComponent) return;
this.svelteComponent.$on("ready", (event) => {
var _a, _b;
(_b = (_a = this.options).onReady) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("qrGenerated", (event) => {
var _a, _b;
const { qrData, paymentRequest } = event.detail;
(_b = (_a = this.options).onQRGenerated) == null ? void 0 : _b.call(_a, qrData, paymentRequest);
});
this.svelteComponent.$on("statusChange", (event) => {
var _a, _b;
const { status, payment } = event.detail;
(_b = (_a = this.options).onStatusChange) == null ? void 0 : _b.call(_a, status, payment);
});
this.svelteComponent.$on("success", (event) => {
var _a, _b;
(_b = (_a = this.options).onSuccess) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("error", (event) => {
var _a, _b;
(_b = (_a = this.options).onError) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("expired", (event) => {
var _a, _b;
(_b = (_a = this.options).onExpired) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("modalClosed", () => {
var _a, _b;
(_b = (_a = this.options).onModalClose) == null ? void 0 : _b.call(_a);
});
}
}
class PaymentButtonComponent {
constructor(options) {
this.svelteComponent = null;
this.container = null;
this.options = options;
}
async mount(selector) {
const target = typeof selector === "string" ? document.querySelector(selector) : selector;
if (!target) {
throw new Error(`Cannot find element: ${selector}`);
}
if (!(target instanceof HTMLElement)) {
throw new Error("Target must be an HTMLElement");
}
this.container = target;
const PaymentButtonModule = await import("./PaymentButton-Cfmn4PL6.js");
const PaymentButton = PaymentButtonModule.default;
this.svelteComponent = new PaymentButton({
target: this.container,
props: __spreadProps(__spreadValues({}, this.options), {
paymentKind: this.options.paymentKind || "bip21",
description: this.options.description || "",
appearance: this.options.appearance || {},
theme: this.options.theme || "auto",
showQRCode: this.options.showQRCode !== false,
showCopyButton: this.options.showCopyButton !== false,
pollingConfig: this.options.pollingConfig || {}
})
});
this.setupEventListeners();
}
unmount() {
if (this.svelteComponent) {
this.svelteComponent.$destroy();
this.svelteComponent = null;
}
this.container = null;
}
destroy() {
this.unmount();
}
updateOptions(newOptions) {
this.options = __spreadValues(__spreadValues({}, this.options), newOptions);
if (this.svelteComponent) {
this.svelteComponent.$set(__spreadProps(__spreadValues({}, this.options), {
paymentKind: this.options.paymentKind || "bip21",
description: this.options.description || "",
appearance: this.options.appearance || {},
theme: this.options.theme || "auto",
showQRCode: this.options.showQRCode !== false,
showCopyButton: this.options.showCopyButton !== false,
pollingConfig: this.options.pollingConfig || {}
}));
}
}
getStatus() {
return "generating";
}
getPaymentData() {
return null;
}
// Button-specific public methods
togglePayment() {
if (this.svelteComponent) {
this.svelteComponent.togglePayment();
}
}
isPaymentVisible() {
return false;
}
setupEventListeners() {
if (!this.svelteComponent) return;
this.svelteComponent.$on("ready", (event) => {
var _a, _b;
(_b = (_a = this.options).onReady) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("qrGenerated", (event) => {
var _a, _b;
const { qrData, paymentRequest } = event.detail;
(_b = (_a = this.options).onQRGenerated) == null ? void 0 : _b.call(_a, qrData, paymentRequest);
});
this.svelteComponent.$on("statusChange", (event) => {
var _a, _b;
const { status, payment } = event.detail;
(_b = (_a = this.options).onStatusChange) == null ? void 0 : _b.call(_a, status, payment);
});
this.svelteComponent.$on("success", (event) => {
var _a, _b;
(_b = (_a = this.options).onSuccess) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("error", (event) => {
var _a, _b;
(_b = (_a = this.options).onError) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("expired", (event) => {
var _a, _b;
(_b = (_a = this.options).onExpired) == null ? void 0 : _b.call(_a, event.detail);
});
this.svelteComponent.$on("buttonActivated", () => {
var _a, _b;
(_b = (_a = this.options).onButtonActivated) == null ? void 0 : _b.call(_a);
});
this.svelteComponent.$on("buttonDeactivated", () => {
var _a, _b;
(_b = (_a = this.options).onButtonDeactivated) == null ? void 0 : _b.call(_a);
});
}
}
class VoltagePayments {
static create(options) {
const variant = options.variant || "inline";
console.log("options", options);
switch (variant) {
case "inline":
return new PaymentInlineComponent(options);
case "modal":
return new PaymentModalComponent(options);
case "button":
return new PaymentButtonComponent(options);
default:
throw new Error(`Unknown payment variant: ${variant}`);
}
}
static get version() {
return "0.1.0";
}
}
export {
VoltagePayments
};
//# sourceMappingURL=voltage-payments.esm.js.map