@crediball/elements 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RBGPXBOH.js → chunk-AEVAHMRY.js} +113 -12
- package/dist/crediball-elements.iife.js +136 -12
- package/dist/index.d.ts +19 -7
- package/dist/index.js +1 -1
- package/dist/register.js +1 -1
- package/package.json +2 -2
|
@@ -164,6 +164,10 @@ function formatMoney(amount, currency) {
|
|
|
164
164
|
return `${amount.toFixed(2)} ${currency}`;
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
+
var CURRENCY_SYMBOLS = { EUR: "\u20AC", USD: "$", GBP: "\xA3" };
|
|
168
|
+
function currencySymbolFor(currency) {
|
|
169
|
+
return CURRENCY_SYMBOLS[currency.toUpperCase()] ?? currency;
|
|
170
|
+
}
|
|
167
171
|
var HTML_ESCAPES = {
|
|
168
172
|
"&": "&",
|
|
169
173
|
"<": "<",
|
|
@@ -217,6 +221,33 @@ var STYLE = `
|
|
|
217
221
|
border-radius: var(--crediball-radius, 9999px);
|
|
218
222
|
}
|
|
219
223
|
button.option .meta { opacity: 0.85; font-size: 14px; }
|
|
224
|
+
.custom-row { display: flex; gap: 8px; align-items: center; margin-top: 12px; }
|
|
225
|
+
.custom-row .sym { font-size: 14px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
226
|
+
.custom-row input {
|
|
227
|
+
flex: 1;
|
|
228
|
+
min-width: 0;
|
|
229
|
+
appearance: none;
|
|
230
|
+
font: inherit;
|
|
231
|
+
font-size: 15px;
|
|
232
|
+
padding: 10px 14px;
|
|
233
|
+
border-radius: var(--crediball-radius, 9999px);
|
|
234
|
+
border: 1px solid var(--crediball-hairline, #e0e0e0);
|
|
235
|
+
background: var(--crediball-canvas, #ffffff);
|
|
236
|
+
color: var(--crediball-ink, #1d1d1f);
|
|
237
|
+
outline: none;
|
|
238
|
+
}
|
|
239
|
+
button.custom-add {
|
|
240
|
+
appearance: none;
|
|
241
|
+
border: none;
|
|
242
|
+
cursor: pointer;
|
|
243
|
+
background: var(--crediball-accent, #0066cc);
|
|
244
|
+
color: var(--crediball-on-accent, #ffffff);
|
|
245
|
+
font: inherit;
|
|
246
|
+
font-size: 15px;
|
|
247
|
+
padding: 10px 18px;
|
|
248
|
+
border-radius: var(--crediball-radius, 9999px);
|
|
249
|
+
}
|
|
250
|
+
p.error { margin: 8px 0 0; font-size: 13px; color: var(--crediball-accent, #0066cc); }
|
|
220
251
|
button.close {
|
|
221
252
|
width: 100%;
|
|
222
253
|
margin-top: 12px;
|
|
@@ -261,6 +292,8 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
261
292
|
const legacyAmounts = amountsAttr ? amountsAttr.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n)) : [5, 10];
|
|
262
293
|
const packages = pkgs?.packages ?? [];
|
|
263
294
|
const plans = pkgs?.activeSubscription ? [] : pkgs?.subscriptionPlans ?? [];
|
|
295
|
+
const custom = pkgs?.customTopup;
|
|
296
|
+
const showCustom = Boolean(custom?.enabled);
|
|
264
297
|
this.shadow.innerHTML = `
|
|
265
298
|
<style>${STYLE}</style>
|
|
266
299
|
<div class="overlay" part="overlay">
|
|
@@ -287,13 +320,19 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
287
320
|
<span>${escapeHtml(p.name)}</span>
|
|
288
321
|
<span class="meta">${formatMoney(p.price, currency)} \xB7 ${formatCredits(p.credits)} cr</span>
|
|
289
322
|
</button>`
|
|
290
|
-
).join("") : legacyAmounts.map(
|
|
323
|
+
).join("") : showCustom ? "" : legacyAmounts.map(
|
|
291
324
|
(a) => `
|
|
292
325
|
<button class="option" data-kind="amount" data-amount="${a}">
|
|
293
326
|
<span>Add ${a}</span>
|
|
294
327
|
</button>`
|
|
295
328
|
).join("")}
|
|
296
329
|
</div>
|
|
330
|
+
${showCustom ? `<div class="custom-row">
|
|
331
|
+
<span class="sym">${escapeHtml(currencySymbolFor(currency))}</span>
|
|
332
|
+
<input class="custom-input" inputmode="decimal" placeholder="${custom?.minEur ?? ""}" aria-label="Custom amount" />
|
|
333
|
+
<button class="custom-add" type="button">Add</button>
|
|
334
|
+
</div>` : ""}
|
|
335
|
+
<p class="error" hidden></p>
|
|
297
336
|
<button class="close" part="close" type="button">Not now</button>
|
|
298
337
|
</div>
|
|
299
338
|
</div>
|
|
@@ -308,28 +347,90 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
308
347
|
const kind = btn.dataset.kind;
|
|
309
348
|
if (kind === "package") {
|
|
310
349
|
const pkg = packages.find((p) => p.id === btn.dataset.id);
|
|
311
|
-
if (pkg) {
|
|
312
|
-
this.
|
|
313
|
-
new CustomEvent("crediball-select-package", { detail: pkg, bubbles: true, composed: true })
|
|
314
|
-
);
|
|
350
|
+
if (pkg && this.emit("crediball-select-package", pkg)) {
|
|
351
|
+
void this.startCheckout({ packageId: pkg.id });
|
|
315
352
|
}
|
|
316
353
|
} else if (kind === "plan") {
|
|
317
354
|
const plan = plans.find((p) => p.id === btn.dataset.id);
|
|
318
|
-
if (plan) {
|
|
319
|
-
this.
|
|
320
|
-
new CustomEvent("crediball-select-plan", { detail: plan, bubbles: true, composed: true })
|
|
321
|
-
);
|
|
355
|
+
if (plan && this.emit("crediball-select-plan", plan)) {
|
|
356
|
+
void this.startSubscriptionCheckout(plan.id);
|
|
322
357
|
}
|
|
323
358
|
} else if (kind === "amount") {
|
|
324
359
|
const amount = Number(btn.dataset.amount);
|
|
325
|
-
this.
|
|
326
|
-
|
|
327
|
-
|
|
360
|
+
if (this.emit("crediball-topup", { amount })) {
|
|
361
|
+
void this.startCheckout({ eurAmount: amount });
|
|
362
|
+
}
|
|
328
363
|
}
|
|
329
364
|
});
|
|
330
365
|
});
|
|
366
|
+
if (showCustom) {
|
|
367
|
+
const input = this.shadow.querySelector(".custom-input");
|
|
368
|
+
const addBtn = this.shadow.querySelector(".custom-add");
|
|
369
|
+
const errEl = this.shadow.querySelector(".error");
|
|
370
|
+
const submit = () => {
|
|
371
|
+
const amount = Number(input?.value);
|
|
372
|
+
const sym = currencySymbolFor(currency);
|
|
373
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
374
|
+
return showError(errEl, "Enter a valid amount.");
|
|
375
|
+
}
|
|
376
|
+
if (custom?.minEur != null && amount < custom.minEur) {
|
|
377
|
+
return showError(errEl, `Minimum is ${sym}${custom.minEur}.`);
|
|
378
|
+
}
|
|
379
|
+
if (custom?.maxEur != null && amount > custom.maxEur) {
|
|
380
|
+
return showError(errEl, `Maximum is ${sym}${custom.maxEur}.`);
|
|
381
|
+
}
|
|
382
|
+
showError(errEl, null);
|
|
383
|
+
if (this.emit("crediball-topup", { amount })) {
|
|
384
|
+
void this.startCheckout({ eurAmount: amount });
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
addBtn?.addEventListener("click", submit);
|
|
388
|
+
input?.addEventListener("keydown", (e) => {
|
|
389
|
+
if (e.key === "Enter") submit();
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/** Dispatch a cancelable option event; returns true when the host did NOT preventDefault. */
|
|
394
|
+
emit(name, detail) {
|
|
395
|
+
const ev = new CustomEvent(name, { detail, bubbles: true, composed: true, cancelable: true });
|
|
396
|
+
this.dispatchEvent(ev);
|
|
397
|
+
return !ev.defaultPrevented;
|
|
398
|
+
}
|
|
399
|
+
returnPath() {
|
|
400
|
+
return typeof window !== "undefined" ? window.location.pathname + window.location.search : void 0;
|
|
401
|
+
}
|
|
402
|
+
/** Start the built-in top-up Checkout and redirect. Errors are surfaced in the dialog. */
|
|
403
|
+
startCheckout(input) {
|
|
404
|
+
if (!this.client) return Promise.resolve();
|
|
405
|
+
return this.redirect(this.client.createCheckout({ ...input, returnPath: this.returnPath() }));
|
|
406
|
+
}
|
|
407
|
+
/** Start the built-in recurring subscription Checkout and redirect. */
|
|
408
|
+
startSubscriptionCheckout(planId) {
|
|
409
|
+
if (!this.client) return Promise.resolve();
|
|
410
|
+
return this.redirect(
|
|
411
|
+
this.client.createSubscriptionCheckout({ planId, returnPath: this.returnPath() })
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
async redirect(session) {
|
|
415
|
+
try {
|
|
416
|
+
const { url } = await session;
|
|
417
|
+
if (typeof window !== "undefined") window.location.assign(url);
|
|
418
|
+
} catch (err) {
|
|
419
|
+
const errEl = this.shadow.querySelector(".error");
|
|
420
|
+
showError(errEl, err instanceof Error ? err.message : "Checkout failed. Please try again.");
|
|
421
|
+
}
|
|
331
422
|
}
|
|
332
423
|
};
|
|
424
|
+
function showError(el, message) {
|
|
425
|
+
if (!el) return;
|
|
426
|
+
if (message) {
|
|
427
|
+
el.textContent = message;
|
|
428
|
+
el.hidden = false;
|
|
429
|
+
} else {
|
|
430
|
+
el.textContent = "";
|
|
431
|
+
el.hidden = true;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
333
434
|
|
|
334
435
|
export {
|
|
335
436
|
CrediballElement,
|
|
@@ -122,6 +122,12 @@ var Crediball = (() => {
|
|
|
122
122
|
this.costOf = (event) => {
|
|
123
123
|
return this.store.get().costs[event]?.costCredits;
|
|
124
124
|
};
|
|
125
|
+
this.createCheckout = (input) => {
|
|
126
|
+
return this.postCheckout("/public/topup/checkout", input);
|
|
127
|
+
};
|
|
128
|
+
this.createSubscriptionCheckout = (input) => {
|
|
129
|
+
return this.postCheckout("/public/subscriptions/checkout", input);
|
|
130
|
+
};
|
|
125
131
|
this.refresh = async () => {
|
|
126
132
|
const { publishableKey, userId } = this.config;
|
|
127
133
|
const headers = { Authorization: `Bearer ${publishableKey}` };
|
|
@@ -182,6 +188,23 @@ var Crediball = (() => {
|
|
|
182
188
|
this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
|
|
183
189
|
this.pollIntervalMs = config.pollIntervalMs ?? DEFAULT_POLL_MS;
|
|
184
190
|
}
|
|
191
|
+
async postCheckout(path, input) {
|
|
192
|
+
const { publishableKey, userId } = this.config;
|
|
193
|
+
const res = await fetch(`${this.apiUrl}${path}`, {
|
|
194
|
+
method: "POST",
|
|
195
|
+
headers: {
|
|
196
|
+
"Content-Type": "application/json",
|
|
197
|
+
Authorization: `Bearer ${publishableKey}`
|
|
198
|
+
},
|
|
199
|
+
body: JSON.stringify({ userId, ...input })
|
|
200
|
+
});
|
|
201
|
+
if (!res.ok) {
|
|
202
|
+
const body = await res.json().catch(() => null);
|
|
203
|
+
const message = body && typeof body === "object" && "error" in body && String(body.error) || `Checkout request failed with ${res.status}`;
|
|
204
|
+
throw new Error(message);
|
|
205
|
+
}
|
|
206
|
+
return res.json();
|
|
207
|
+
}
|
|
185
208
|
pause() {
|
|
186
209
|
this.stopPolling();
|
|
187
210
|
this.disconnectSse();
|
|
@@ -445,6 +468,10 @@ var Crediball = (() => {
|
|
|
445
468
|
return `${amount.toFixed(2)} ${currency}`;
|
|
446
469
|
}
|
|
447
470
|
}
|
|
471
|
+
var CURRENCY_SYMBOLS = { EUR: "\u20AC", USD: "$", GBP: "\xA3" };
|
|
472
|
+
function currencySymbolFor(currency) {
|
|
473
|
+
return CURRENCY_SYMBOLS[currency.toUpperCase()] ?? currency;
|
|
474
|
+
}
|
|
448
475
|
var HTML_ESCAPES = {
|
|
449
476
|
"&": "&",
|
|
450
477
|
"<": "<",
|
|
@@ -498,6 +525,33 @@ var Crediball = (() => {
|
|
|
498
525
|
border-radius: var(--crediball-radius, 9999px);
|
|
499
526
|
}
|
|
500
527
|
button.option .meta { opacity: 0.85; font-size: 14px; }
|
|
528
|
+
.custom-row { display: flex; gap: 8px; align-items: center; margin-top: 12px; }
|
|
529
|
+
.custom-row .sym { font-size: 14px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
530
|
+
.custom-row input {
|
|
531
|
+
flex: 1;
|
|
532
|
+
min-width: 0;
|
|
533
|
+
appearance: none;
|
|
534
|
+
font: inherit;
|
|
535
|
+
font-size: 15px;
|
|
536
|
+
padding: 10px 14px;
|
|
537
|
+
border-radius: var(--crediball-radius, 9999px);
|
|
538
|
+
border: 1px solid var(--crediball-hairline, #e0e0e0);
|
|
539
|
+
background: var(--crediball-canvas, #ffffff);
|
|
540
|
+
color: var(--crediball-ink, #1d1d1f);
|
|
541
|
+
outline: none;
|
|
542
|
+
}
|
|
543
|
+
button.custom-add {
|
|
544
|
+
appearance: none;
|
|
545
|
+
border: none;
|
|
546
|
+
cursor: pointer;
|
|
547
|
+
background: var(--crediball-accent, #0066cc);
|
|
548
|
+
color: var(--crediball-on-accent, #ffffff);
|
|
549
|
+
font: inherit;
|
|
550
|
+
font-size: 15px;
|
|
551
|
+
padding: 10px 18px;
|
|
552
|
+
border-radius: var(--crediball-radius, 9999px);
|
|
553
|
+
}
|
|
554
|
+
p.error { margin: 8px 0 0; font-size: 13px; color: var(--crediball-accent, #0066cc); }
|
|
501
555
|
button.close {
|
|
502
556
|
width: 100%;
|
|
503
557
|
margin-top: 12px;
|
|
@@ -542,6 +596,8 @@ var Crediball = (() => {
|
|
|
542
596
|
const legacyAmounts = amountsAttr ? amountsAttr.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n)) : [5, 10];
|
|
543
597
|
const packages = pkgs?.packages ?? [];
|
|
544
598
|
const plans = pkgs?.activeSubscription ? [] : pkgs?.subscriptionPlans ?? [];
|
|
599
|
+
const custom = pkgs?.customTopup;
|
|
600
|
+
const showCustom = Boolean(custom?.enabled);
|
|
545
601
|
this.shadow.innerHTML = `
|
|
546
602
|
<style>${STYLE}</style>
|
|
547
603
|
<div class="overlay" part="overlay">
|
|
@@ -568,13 +624,19 @@ var Crediball = (() => {
|
|
|
568
624
|
<span>${escapeHtml(p.name)}</span>
|
|
569
625
|
<span class="meta">${formatMoney(p.price, currency)} \xB7 ${formatCredits(p.credits)} cr</span>
|
|
570
626
|
</button>`
|
|
571
|
-
).join("") : legacyAmounts.map(
|
|
627
|
+
).join("") : showCustom ? "" : legacyAmounts.map(
|
|
572
628
|
(a) => `
|
|
573
629
|
<button class="option" data-kind="amount" data-amount="${a}">
|
|
574
630
|
<span>Add ${a}</span>
|
|
575
631
|
</button>`
|
|
576
632
|
).join("")}
|
|
577
633
|
</div>
|
|
634
|
+
${showCustom ? `<div class="custom-row">
|
|
635
|
+
<span class="sym">${escapeHtml(currencySymbolFor(currency))}</span>
|
|
636
|
+
<input class="custom-input" inputmode="decimal" placeholder="${custom?.minEur ?? ""}" aria-label="Custom amount" />
|
|
637
|
+
<button class="custom-add" type="button">Add</button>
|
|
638
|
+
</div>` : ""}
|
|
639
|
+
<p class="error" hidden></p>
|
|
578
640
|
<button class="close" part="close" type="button">Not now</button>
|
|
579
641
|
</div>
|
|
580
642
|
</div>
|
|
@@ -589,28 +651,90 @@ var Crediball = (() => {
|
|
|
589
651
|
const kind = btn.dataset.kind;
|
|
590
652
|
if (kind === "package") {
|
|
591
653
|
const pkg = packages.find((p) => p.id === btn.dataset.id);
|
|
592
|
-
if (pkg) {
|
|
593
|
-
this.
|
|
594
|
-
new CustomEvent("crediball-select-package", { detail: pkg, bubbles: true, composed: true })
|
|
595
|
-
);
|
|
654
|
+
if (pkg && this.emit("crediball-select-package", pkg)) {
|
|
655
|
+
void this.startCheckout({ packageId: pkg.id });
|
|
596
656
|
}
|
|
597
657
|
} else if (kind === "plan") {
|
|
598
658
|
const plan = plans.find((p) => p.id === btn.dataset.id);
|
|
599
|
-
if (plan) {
|
|
600
|
-
this.
|
|
601
|
-
new CustomEvent("crediball-select-plan", { detail: plan, bubbles: true, composed: true })
|
|
602
|
-
);
|
|
659
|
+
if (plan && this.emit("crediball-select-plan", plan)) {
|
|
660
|
+
void this.startSubscriptionCheckout(plan.id);
|
|
603
661
|
}
|
|
604
662
|
} else if (kind === "amount") {
|
|
605
663
|
const amount = Number(btn.dataset.amount);
|
|
606
|
-
this.
|
|
607
|
-
|
|
608
|
-
|
|
664
|
+
if (this.emit("crediball-topup", { amount })) {
|
|
665
|
+
void this.startCheckout({ eurAmount: amount });
|
|
666
|
+
}
|
|
609
667
|
}
|
|
610
668
|
});
|
|
611
669
|
});
|
|
670
|
+
if (showCustom) {
|
|
671
|
+
const input = this.shadow.querySelector(".custom-input");
|
|
672
|
+
const addBtn = this.shadow.querySelector(".custom-add");
|
|
673
|
+
const errEl = this.shadow.querySelector(".error");
|
|
674
|
+
const submit = () => {
|
|
675
|
+
const amount = Number(input?.value);
|
|
676
|
+
const sym = currencySymbolFor(currency);
|
|
677
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
678
|
+
return showError(errEl, "Enter a valid amount.");
|
|
679
|
+
}
|
|
680
|
+
if (custom?.minEur != null && amount < custom.minEur) {
|
|
681
|
+
return showError(errEl, `Minimum is ${sym}${custom.minEur}.`);
|
|
682
|
+
}
|
|
683
|
+
if (custom?.maxEur != null && amount > custom.maxEur) {
|
|
684
|
+
return showError(errEl, `Maximum is ${sym}${custom.maxEur}.`);
|
|
685
|
+
}
|
|
686
|
+
showError(errEl, null);
|
|
687
|
+
if (this.emit("crediball-topup", { amount })) {
|
|
688
|
+
void this.startCheckout({ eurAmount: amount });
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
addBtn?.addEventListener("click", submit);
|
|
692
|
+
input?.addEventListener("keydown", (e) => {
|
|
693
|
+
if (e.key === "Enter") submit();
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
/** Dispatch a cancelable option event; returns true when the host did NOT preventDefault. */
|
|
698
|
+
emit(name, detail) {
|
|
699
|
+
const ev = new CustomEvent(name, { detail, bubbles: true, composed: true, cancelable: true });
|
|
700
|
+
this.dispatchEvent(ev);
|
|
701
|
+
return !ev.defaultPrevented;
|
|
702
|
+
}
|
|
703
|
+
returnPath() {
|
|
704
|
+
return typeof window !== "undefined" ? window.location.pathname + window.location.search : void 0;
|
|
705
|
+
}
|
|
706
|
+
/** Start the built-in top-up Checkout and redirect. Errors are surfaced in the dialog. */
|
|
707
|
+
startCheckout(input) {
|
|
708
|
+
if (!this.client) return Promise.resolve();
|
|
709
|
+
return this.redirect(this.client.createCheckout({ ...input, returnPath: this.returnPath() }));
|
|
710
|
+
}
|
|
711
|
+
/** Start the built-in recurring subscription Checkout and redirect. */
|
|
712
|
+
startSubscriptionCheckout(planId) {
|
|
713
|
+
if (!this.client) return Promise.resolve();
|
|
714
|
+
return this.redirect(
|
|
715
|
+
this.client.createSubscriptionCheckout({ planId, returnPath: this.returnPath() })
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
async redirect(session) {
|
|
719
|
+
try {
|
|
720
|
+
const { url } = await session;
|
|
721
|
+
if (typeof window !== "undefined") window.location.assign(url);
|
|
722
|
+
} catch (err) {
|
|
723
|
+
const errEl = this.shadow.querySelector(".error");
|
|
724
|
+
showError(errEl, err instanceof Error ? err.message : "Checkout failed. Please try again.");
|
|
725
|
+
}
|
|
612
726
|
}
|
|
613
727
|
};
|
|
728
|
+
function showError(el, message) {
|
|
729
|
+
if (!el) return;
|
|
730
|
+
if (message) {
|
|
731
|
+
el.textContent = message;
|
|
732
|
+
el.hidden = false;
|
|
733
|
+
} else {
|
|
734
|
+
el.textContent = "";
|
|
735
|
+
el.hidden = true;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
614
738
|
|
|
615
739
|
// src/register.ts
|
|
616
740
|
function define(name, ctor) {
|
package/dist/index.d.ts
CHANGED
|
@@ -88,13 +88,17 @@ declare class CrediballLowCreditWarningElement extends CrediballElement {
|
|
|
88
88
|
/**
|
|
89
89
|
* <crediball-paywall publishable-key="cb_pub_..." user-id="u123" title="..." description="..."></crediball-paywall>
|
|
90
90
|
*
|
|
91
|
-
* A themeable top-up dialog driven by the live packages/
|
|
92
|
-
* catalog. Call `.open()` / `.close()`, or toggle the `open`
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
91
|
+
* A themeable top-up dialog driven by the live packages/custom-topup/
|
|
92
|
+
* subscription-plans catalog. Call `.open()` / `.close()`, or toggle the `open`
|
|
93
|
+
* attribute.
|
|
94
|
+
*
|
|
95
|
+
* Everything pays out of the box: picking a package, entering a custom amount, or
|
|
96
|
+
* choosing a subscription plan starts a Crediball-hosted Stripe Checkout (using the
|
|
97
|
+
* publishable key) and redirects — the developer only has to connect payouts in the
|
|
98
|
+
* dashboard. Subscriptions bill recurringly and grant credits each period. Each
|
|
99
|
+
* choice first dispatches a bubbling, CANCELABLE event (`crediball-select-package` /
|
|
100
|
+
* `crediball-topup` / `crediball-select-plan`); call `event.preventDefault()` in a
|
|
101
|
+
* listener to suppress the built-in checkout and run your own flow instead.
|
|
98
102
|
*/
|
|
99
103
|
declare class CrediballPaywallElement extends CrediballElement {
|
|
100
104
|
private shadow;
|
|
@@ -103,6 +107,14 @@ declare class CrediballPaywallElement extends CrediballElement {
|
|
|
103
107
|
open(): void;
|
|
104
108
|
close(): void;
|
|
105
109
|
protected render(): void;
|
|
110
|
+
/** Dispatch a cancelable option event; returns true when the host did NOT preventDefault. */
|
|
111
|
+
private emit;
|
|
112
|
+
private returnPath;
|
|
113
|
+
/** Start the built-in top-up Checkout and redirect. Errors are surfaced in the dialog. */
|
|
114
|
+
private startCheckout;
|
|
115
|
+
/** Start the built-in recurring subscription Checkout and redirect. */
|
|
116
|
+
private startSubscriptionCheckout;
|
|
117
|
+
private redirect;
|
|
106
118
|
}
|
|
107
119
|
|
|
108
120
|
export { CrediballBalanceElement, CrediballElement, CrediballLowCreditWarningElement, CrediballPaywallElement, CrediballTopUpButtonElement, CrediballUsageElement };
|
package/dist/index.js
CHANGED
package/dist/register.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crediball/elements",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Framework-agnostic web components for showing Crediball credits inside your AI app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Filippo Rezzadore <filipporezzadore@gmail.com>",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prepublishOnly": "npm run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@crediball/core": "^0.
|
|
59
|
+
"@crediball/core": "^0.2.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"tsup": "^8.3.5",
|