@crediball/elements 0.9.0 → 0.11.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-MLNG4RJB.js → chunk-FOMDJR2B.js} +64 -20
- package/dist/crediball-elements.iife.js +64 -20
- package/dist/index.d.ts +7 -3
- package/dist/index.js +1 -1
- package/dist/register.js +1 -1
- package/package.json +2 -2
|
@@ -217,13 +217,24 @@ var STYLE = `
|
|
|
217
217
|
.card {
|
|
218
218
|
width: 100%;
|
|
219
219
|
max-width: 420px;
|
|
220
|
+
/* Cap to the overlay's own (viewport-correct, since it's fixed/inset:0)
|
|
221
|
+
content box and scroll internally past that \u2014 otherwise a host with
|
|
222
|
+
many optional sections enabled (balance, subscribe, promo code,
|
|
223
|
+
packages, custom amount, auto top-up, referral) can produce a card
|
|
224
|
+
taller than the mobile viewport, which the centered overlay then
|
|
225
|
+
clips top and bottom with no way to reach the rest. */
|
|
226
|
+
max-height: 100%;
|
|
227
|
+
overflow-y: auto;
|
|
228
|
+
-webkit-overflow-scrolling: touch;
|
|
229
|
+
overscroll-behavior: contain;
|
|
230
|
+
box-sizing: border-box;
|
|
220
231
|
padding: 32px;
|
|
221
232
|
border-radius: var(--crediball-radius-card, 18px);
|
|
222
233
|
background: var(--crediball-canvas, #ffffff);
|
|
223
234
|
color: var(--crediball-ink, #1d1d1f);
|
|
224
235
|
}
|
|
225
236
|
.balance-row { margin-bottom: 24px; padding-bottom: 20px; border-bottom: 1px solid var(--crediball-hairline, #e0e0e0); }
|
|
226
|
-
.eyebrow { font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
|
|
237
|
+
.eyebrow { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; color: var(--crediball-ink-muted, #7a7a7a); margin-bottom: 4px; }
|
|
227
238
|
.balance-value { font-size: 22px; font-weight: 600; }
|
|
228
239
|
h3 { margin: 0; font-size: 24px; font-weight: 600; letter-spacing: -0.01em; }
|
|
229
240
|
p.desc { margin: 8px 0 0; font-size: 14px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
@@ -236,14 +247,17 @@ var STYLE = `
|
|
|
236
247
|
display: flex;
|
|
237
248
|
justify-content: space-between;
|
|
238
249
|
align-items: center;
|
|
250
|
+
gap: 16px;
|
|
239
251
|
background: var(--crediball-accent, #0066cc);
|
|
240
252
|
color: var(--crediball-on-accent, #ffffff);
|
|
241
253
|
font: inherit;
|
|
242
|
-
font-size: 17px;
|
|
243
254
|
padding: 11px 22px;
|
|
244
255
|
border-radius: var(--crediball-radius, 9999px);
|
|
245
256
|
}
|
|
246
|
-
|
|
257
|
+
.option-left { display: flex; flex-direction: column; align-items: flex-start; flex: 1; min-width: 0; }
|
|
258
|
+
.option-name { font-size: 17px; font-weight: 600; line-height: 1.2; }
|
|
259
|
+
.option-credits { font-size: 13px; opacity: 0.85; line-height: 1.2; }
|
|
260
|
+
.option-price { font-size: 17px; font-weight: 600; white-space: nowrap; flex-shrink: 0; }
|
|
247
261
|
.custom-row { display: flex; gap: 8px; align-items: center; margin-top: 12px; }
|
|
248
262
|
.custom-row .sym { font-size: 14px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
249
263
|
.custom-row input {
|
|
@@ -304,6 +318,8 @@ var STYLE = `
|
|
|
304
318
|
color: var(--crediball-ink, #1d1d1f);
|
|
305
319
|
outline: none;
|
|
306
320
|
}
|
|
321
|
+
.promo-code-input.invalid { border-color: var(--crediball-accent, #0066cc); }
|
|
322
|
+
.promo-code-error { margin: 6px 0 0; font-size: 12px; color: var(--crediball-accent, #0066cc); }
|
|
307
323
|
.autotopup { margin-top: 16px; }
|
|
308
324
|
.autotopup-toggle {
|
|
309
325
|
appearance: none; border: none; cursor: pointer; background: transparent; padding: 0;
|
|
@@ -326,7 +342,7 @@ var STYLE = `
|
|
|
326
342
|
}
|
|
327
343
|
.autotopup-hint { margin: 6px 0 0; font-size: 11px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
328
344
|
.referral { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--crediball-hairline, #e0e0e0); }
|
|
329
|
-
.referral-label { margin-bottom: 8px; font-size: 12px; font-weight: 600; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
345
|
+
.referral-label { margin-bottom: 8px; font-size: 12px; font-weight: 600; color: var(--crediball-ink-muted, #7a7a7a); white-space: pre-line; }
|
|
330
346
|
.referral-row { display: flex; gap: 8px; align-items: center; }
|
|
331
347
|
.referral-row .link {
|
|
332
348
|
flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
@@ -414,6 +430,10 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
414
430
|
const plans = pkgs?.activeSubscription ? [] : pkgs?.subscriptionPlans ?? [];
|
|
415
431
|
const custom = pkgs?.customTopup;
|
|
416
432
|
const showCustom = Boolean(custom?.enabled);
|
|
433
|
+
const referralReward = this.referral?.rewardCredits ?? 0;
|
|
434
|
+
const referredReward = this.referral?.referredRewardCredits ?? 0;
|
|
435
|
+
const defaultReferralLabel = referredReward > 0 ? "Refer a friend.\nYou earn {credits} credits and your friend {referredCredits} credits" : "Refer a friend \xB7 earn {credits} credits";
|
|
436
|
+
const referralLabel = (this.getAttribute("referral-label") ?? defaultReferralLabel).replace("{credits}", formatCredits(referralReward)).replace("{referredCredits}", formatCredits(referredReward));
|
|
417
437
|
this.shadow.innerHTML = `
|
|
418
438
|
<style>${STYLE}</style>
|
|
419
439
|
<div class="overlay" part="overlay">
|
|
@@ -428,18 +448,23 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
428
448
|
${plans.map(
|
|
429
449
|
(p) => `
|
|
430
450
|
<button class="option" data-kind="plan" data-id="${escapeHtml(p.id)}">
|
|
431
|
-
<
|
|
432
|
-
|
|
451
|
+
<div class="option-left">
|
|
452
|
+
<div class="option-name">${escapeHtml(p.name)}</div>
|
|
453
|
+
<div class="option-credits">${formatCredits(p.credits)} credits</div>
|
|
454
|
+
</div>
|
|
455
|
+
<div class="option-price">${formatMoney(p.price, currency)}/${PERIOD_SUFFIX[p.period] ?? p.period}</div>
|
|
433
456
|
</button>`
|
|
434
457
|
).join("")}
|
|
435
458
|
</div>` : ""}
|
|
436
|
-
${this.renderPromoCode()}
|
|
437
459
|
<div class="list">
|
|
438
460
|
${packages.length ? packages.map(
|
|
439
461
|
(p) => `
|
|
440
462
|
<button class="option" data-kind="package" data-id="${escapeHtml(p.id)}">
|
|
441
|
-
<
|
|
442
|
-
|
|
463
|
+
<div class="option-left">
|
|
464
|
+
<div class="option-name">${escapeHtml(p.name)}</div>
|
|
465
|
+
<div class="option-credits">${formatCredits(p.credits)} credits</div>
|
|
466
|
+
</div>
|
|
467
|
+
<div class="option-price">${formatMoney(p.price, currency)}</div>
|
|
443
468
|
</button>`
|
|
444
469
|
).join("") : showCustom ? "" : legacyAmounts.map(
|
|
445
470
|
(a) => `
|
|
@@ -454,16 +479,12 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
454
479
|
<button class="custom-add" type="button">${escapeHtml(addButtonText)}</button>
|
|
455
480
|
</div>
|
|
456
481
|
<p class="custom-preview" hidden></p>` : ""}
|
|
482
|
+
${this.renderPromoCode(Boolean(pkgs?.hasActiveCheckoutPromotion))}
|
|
457
483
|
${this.renderAutoTopup(packages, pkgs?.autoTopup, currency)}
|
|
458
484
|
<p class="error" hidden></p>
|
|
459
485
|
<button class="close" part="close" type="button">Not now</button>
|
|
460
486
|
${this.referral?.link ? `<div class="referral">
|
|
461
|
-
<div class="referral-label">${escapeHtml(
|
|
462
|
-
(this.getAttribute("referral-label") ?? "Refer a friend \xB7 earn {credits} credits").replace(
|
|
463
|
-
"{credits}",
|
|
464
|
-
formatCredits(this.referral.rewardCredits ?? 0)
|
|
465
|
-
)
|
|
466
|
-
)}</div>
|
|
487
|
+
<div class="referral-label">${escapeHtml(referralLabel)}</div>
|
|
467
488
|
<div class="referral-row">
|
|
468
489
|
<div class="link" title="${escapeHtml(this.referral.link)}">${escapeHtml(this.referral.link)}</div>
|
|
469
490
|
<button class="referral-copy" type="button">${this.referralCopied ? "Copied!" : "Copy"}</button>
|
|
@@ -505,6 +526,24 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
505
526
|
this.promoCodeOpen = true;
|
|
506
527
|
this.render();
|
|
507
528
|
});
|
|
529
|
+
const promoInput = this.shadow.querySelector(".promo-code-input");
|
|
530
|
+
const promoErrorEl = this.shadow.querySelector(".promo-code-error");
|
|
531
|
+
if (promoInput && promoErrorEl) {
|
|
532
|
+
let promoTouched = false;
|
|
533
|
+
const checkPromoFormat = () => {
|
|
534
|
+
const value = promoInput.value.trim();
|
|
535
|
+
const valid = !value || /^[A-Za-z0-9_-]+$/.test(value);
|
|
536
|
+
const showError2 = promoTouched && !valid;
|
|
537
|
+
promoInput.classList.toggle("invalid", showError2);
|
|
538
|
+
promoErrorEl.hidden = !showError2;
|
|
539
|
+
if (showError2) promoErrorEl.textContent = "Promo codes only contain letters, numbers, - and _.";
|
|
540
|
+
};
|
|
541
|
+
promoInput.addEventListener("blur", () => {
|
|
542
|
+
promoTouched = true;
|
|
543
|
+
checkPromoFormat();
|
|
544
|
+
});
|
|
545
|
+
promoInput.addEventListener("input", checkPromoFormat);
|
|
546
|
+
}
|
|
508
547
|
if (showCustom) {
|
|
509
548
|
const input = this.shadow.querySelector(".custom-input");
|
|
510
549
|
const addBtn = this.shadow.querySelector(".custom-add");
|
|
@@ -568,11 +607,15 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
568
607
|
}
|
|
569
608
|
});
|
|
570
609
|
}
|
|
571
|
-
/** HTML for the "Have a promo code?" toggle-open field.
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
|
|
575
|
-
|
|
610
|
+
/** HTML for the "Have a promo code?" toggle-open field. Shown automatically
|
|
611
|
+
* once the app has an active Checkout promotion (same as the custom-amount
|
|
612
|
+
* field auto-following the dashboard's custom-topup config) — the
|
|
613
|
+
* `allow-promo-code` attribute is only needed to force it on before you've
|
|
614
|
+
* set one up. Format-only client check (flags an obvious typo/paste
|
|
615
|
+
* mistake on blur, see wireUpPromoCode()) — whether the code is actually
|
|
616
|
+
* active/redeemable is only known server-side when a purchase is made. */
|
|
617
|
+
renderPromoCode(hasActiveCheckoutPromotion) {
|
|
618
|
+
if (!this.hasAttribute("allow-promo-code") && !hasActiveCheckoutPromotion) return "";
|
|
576
619
|
const label = this.getAttribute("promo-code-label") ?? "Have a promo code?";
|
|
577
620
|
if (!this.promoCodeOpen) {
|
|
578
621
|
return `<div class="promo-code">
|
|
@@ -582,6 +625,7 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
582
625
|
return `<div class="promo-code">
|
|
583
626
|
<div class="promo-code-label">${escapeHtml(label)}</div>
|
|
584
627
|
<input class="promo-code-input" placeholder="PROMOCODE" aria-label="Promo code" />
|
|
628
|
+
<p class="promo-code-error" hidden></p>
|
|
585
629
|
</div>`;
|
|
586
630
|
}
|
|
587
631
|
/** The current promo code input value (uppercased, trimmed), or undefined
|
|
@@ -631,13 +631,24 @@ var Crediball = (() => {
|
|
|
631
631
|
.card {
|
|
632
632
|
width: 100%;
|
|
633
633
|
max-width: 420px;
|
|
634
|
+
/* Cap to the overlay's own (viewport-correct, since it's fixed/inset:0)
|
|
635
|
+
content box and scroll internally past that \u2014 otherwise a host with
|
|
636
|
+
many optional sections enabled (balance, subscribe, promo code,
|
|
637
|
+
packages, custom amount, auto top-up, referral) can produce a card
|
|
638
|
+
taller than the mobile viewport, which the centered overlay then
|
|
639
|
+
clips top and bottom with no way to reach the rest. */
|
|
640
|
+
max-height: 100%;
|
|
641
|
+
overflow-y: auto;
|
|
642
|
+
-webkit-overflow-scrolling: touch;
|
|
643
|
+
overscroll-behavior: contain;
|
|
644
|
+
box-sizing: border-box;
|
|
634
645
|
padding: 32px;
|
|
635
646
|
border-radius: var(--crediball-radius-card, 18px);
|
|
636
647
|
background: var(--crediball-canvas, #ffffff);
|
|
637
648
|
color: var(--crediball-ink, #1d1d1f);
|
|
638
649
|
}
|
|
639
650
|
.balance-row { margin-bottom: 24px; padding-bottom: 20px; border-bottom: 1px solid var(--crediball-hairline, #e0e0e0); }
|
|
640
|
-
.eyebrow { font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
|
|
651
|
+
.eyebrow { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; color: var(--crediball-ink-muted, #7a7a7a); margin-bottom: 4px; }
|
|
641
652
|
.balance-value { font-size: 22px; font-weight: 600; }
|
|
642
653
|
h3 { margin: 0; font-size: 24px; font-weight: 600; letter-spacing: -0.01em; }
|
|
643
654
|
p.desc { margin: 8px 0 0; font-size: 14px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
@@ -650,14 +661,17 @@ var Crediball = (() => {
|
|
|
650
661
|
display: flex;
|
|
651
662
|
justify-content: space-between;
|
|
652
663
|
align-items: center;
|
|
664
|
+
gap: 16px;
|
|
653
665
|
background: var(--crediball-accent, #0066cc);
|
|
654
666
|
color: var(--crediball-on-accent, #ffffff);
|
|
655
667
|
font: inherit;
|
|
656
|
-
font-size: 17px;
|
|
657
668
|
padding: 11px 22px;
|
|
658
669
|
border-radius: var(--crediball-radius, 9999px);
|
|
659
670
|
}
|
|
660
|
-
|
|
671
|
+
.option-left { display: flex; flex-direction: column; align-items: flex-start; flex: 1; min-width: 0; }
|
|
672
|
+
.option-name { font-size: 17px; font-weight: 600; line-height: 1.2; }
|
|
673
|
+
.option-credits { font-size: 13px; opacity: 0.85; line-height: 1.2; }
|
|
674
|
+
.option-price { font-size: 17px; font-weight: 600; white-space: nowrap; flex-shrink: 0; }
|
|
661
675
|
.custom-row { display: flex; gap: 8px; align-items: center; margin-top: 12px; }
|
|
662
676
|
.custom-row .sym { font-size: 14px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
663
677
|
.custom-row input {
|
|
@@ -718,6 +732,8 @@ var Crediball = (() => {
|
|
|
718
732
|
color: var(--crediball-ink, #1d1d1f);
|
|
719
733
|
outline: none;
|
|
720
734
|
}
|
|
735
|
+
.promo-code-input.invalid { border-color: var(--crediball-accent, #0066cc); }
|
|
736
|
+
.promo-code-error { margin: 6px 0 0; font-size: 12px; color: var(--crediball-accent, #0066cc); }
|
|
721
737
|
.autotopup { margin-top: 16px; }
|
|
722
738
|
.autotopup-toggle {
|
|
723
739
|
appearance: none; border: none; cursor: pointer; background: transparent; padding: 0;
|
|
@@ -740,7 +756,7 @@ var Crediball = (() => {
|
|
|
740
756
|
}
|
|
741
757
|
.autotopup-hint { margin: 6px 0 0; font-size: 11px; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
742
758
|
.referral { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--crediball-hairline, #e0e0e0); }
|
|
743
|
-
.referral-label { margin-bottom: 8px; font-size: 12px; font-weight: 600; color: var(--crediball-ink-muted, #7a7a7a); }
|
|
759
|
+
.referral-label { margin-bottom: 8px; font-size: 12px; font-weight: 600; color: var(--crediball-ink-muted, #7a7a7a); white-space: pre-line; }
|
|
744
760
|
.referral-row { display: flex; gap: 8px; align-items: center; }
|
|
745
761
|
.referral-row .link {
|
|
746
762
|
flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
@@ -828,6 +844,10 @@ var Crediball = (() => {
|
|
|
828
844
|
const plans = pkgs?.activeSubscription ? [] : pkgs?.subscriptionPlans ?? [];
|
|
829
845
|
const custom = pkgs?.customTopup;
|
|
830
846
|
const showCustom = Boolean(custom?.enabled);
|
|
847
|
+
const referralReward = this.referral?.rewardCredits ?? 0;
|
|
848
|
+
const referredReward = this.referral?.referredRewardCredits ?? 0;
|
|
849
|
+
const defaultReferralLabel = referredReward > 0 ? "Refer a friend.\nYou earn {credits} credits and your friend {referredCredits} credits" : "Refer a friend \xB7 earn {credits} credits";
|
|
850
|
+
const referralLabel = (this.getAttribute("referral-label") ?? defaultReferralLabel).replace("{credits}", formatCredits(referralReward)).replace("{referredCredits}", formatCredits(referredReward));
|
|
831
851
|
this.shadow.innerHTML = `
|
|
832
852
|
<style>${STYLE}</style>
|
|
833
853
|
<div class="overlay" part="overlay">
|
|
@@ -842,18 +862,23 @@ var Crediball = (() => {
|
|
|
842
862
|
${plans.map(
|
|
843
863
|
(p) => `
|
|
844
864
|
<button class="option" data-kind="plan" data-id="${escapeHtml(p.id)}">
|
|
845
|
-
<
|
|
846
|
-
|
|
865
|
+
<div class="option-left">
|
|
866
|
+
<div class="option-name">${escapeHtml(p.name)}</div>
|
|
867
|
+
<div class="option-credits">${formatCredits(p.credits)} credits</div>
|
|
868
|
+
</div>
|
|
869
|
+
<div class="option-price">${formatMoney(p.price, currency)}/${PERIOD_SUFFIX[p.period] ?? p.period}</div>
|
|
847
870
|
</button>`
|
|
848
871
|
).join("")}
|
|
849
872
|
</div>` : ""}
|
|
850
|
-
${this.renderPromoCode()}
|
|
851
873
|
<div class="list">
|
|
852
874
|
${packages.length ? packages.map(
|
|
853
875
|
(p) => `
|
|
854
876
|
<button class="option" data-kind="package" data-id="${escapeHtml(p.id)}">
|
|
855
|
-
<
|
|
856
|
-
|
|
877
|
+
<div class="option-left">
|
|
878
|
+
<div class="option-name">${escapeHtml(p.name)}</div>
|
|
879
|
+
<div class="option-credits">${formatCredits(p.credits)} credits</div>
|
|
880
|
+
</div>
|
|
881
|
+
<div class="option-price">${formatMoney(p.price, currency)}</div>
|
|
857
882
|
</button>`
|
|
858
883
|
).join("") : showCustom ? "" : legacyAmounts.map(
|
|
859
884
|
(a) => `
|
|
@@ -868,16 +893,12 @@ var Crediball = (() => {
|
|
|
868
893
|
<button class="custom-add" type="button">${escapeHtml(addButtonText)}</button>
|
|
869
894
|
</div>
|
|
870
895
|
<p class="custom-preview" hidden></p>` : ""}
|
|
896
|
+
${this.renderPromoCode(Boolean(pkgs?.hasActiveCheckoutPromotion))}
|
|
871
897
|
${this.renderAutoTopup(packages, pkgs?.autoTopup, currency)}
|
|
872
898
|
<p class="error" hidden></p>
|
|
873
899
|
<button class="close" part="close" type="button">Not now</button>
|
|
874
900
|
${this.referral?.link ? `<div class="referral">
|
|
875
|
-
<div class="referral-label">${escapeHtml(
|
|
876
|
-
(this.getAttribute("referral-label") ?? "Refer a friend \xB7 earn {credits} credits").replace(
|
|
877
|
-
"{credits}",
|
|
878
|
-
formatCredits(this.referral.rewardCredits ?? 0)
|
|
879
|
-
)
|
|
880
|
-
)}</div>
|
|
901
|
+
<div class="referral-label">${escapeHtml(referralLabel)}</div>
|
|
881
902
|
<div class="referral-row">
|
|
882
903
|
<div class="link" title="${escapeHtml(this.referral.link)}">${escapeHtml(this.referral.link)}</div>
|
|
883
904
|
<button class="referral-copy" type="button">${this.referralCopied ? "Copied!" : "Copy"}</button>
|
|
@@ -919,6 +940,24 @@ var Crediball = (() => {
|
|
|
919
940
|
this.promoCodeOpen = true;
|
|
920
941
|
this.render();
|
|
921
942
|
});
|
|
943
|
+
const promoInput = this.shadow.querySelector(".promo-code-input");
|
|
944
|
+
const promoErrorEl = this.shadow.querySelector(".promo-code-error");
|
|
945
|
+
if (promoInput && promoErrorEl) {
|
|
946
|
+
let promoTouched = false;
|
|
947
|
+
const checkPromoFormat = () => {
|
|
948
|
+
const value = promoInput.value.trim();
|
|
949
|
+
const valid = !value || /^[A-Za-z0-9_-]+$/.test(value);
|
|
950
|
+
const showError2 = promoTouched && !valid;
|
|
951
|
+
promoInput.classList.toggle("invalid", showError2);
|
|
952
|
+
promoErrorEl.hidden = !showError2;
|
|
953
|
+
if (showError2) promoErrorEl.textContent = "Promo codes only contain letters, numbers, - and _.";
|
|
954
|
+
};
|
|
955
|
+
promoInput.addEventListener("blur", () => {
|
|
956
|
+
promoTouched = true;
|
|
957
|
+
checkPromoFormat();
|
|
958
|
+
});
|
|
959
|
+
promoInput.addEventListener("input", checkPromoFormat);
|
|
960
|
+
}
|
|
922
961
|
if (showCustom) {
|
|
923
962
|
const input = this.shadow.querySelector(".custom-input");
|
|
924
963
|
const addBtn = this.shadow.querySelector(".custom-add");
|
|
@@ -982,11 +1021,15 @@ var Crediball = (() => {
|
|
|
982
1021
|
}
|
|
983
1022
|
});
|
|
984
1023
|
}
|
|
985
|
-
/** HTML for the "Have a promo code?" toggle-open field.
|
|
986
|
-
*
|
|
987
|
-
*
|
|
988
|
-
|
|
989
|
-
|
|
1024
|
+
/** HTML for the "Have a promo code?" toggle-open field. Shown automatically
|
|
1025
|
+
* once the app has an active Checkout promotion (same as the custom-amount
|
|
1026
|
+
* field auto-following the dashboard's custom-topup config) — the
|
|
1027
|
+
* `allow-promo-code` attribute is only needed to force it on before you've
|
|
1028
|
+
* set one up. Format-only client check (flags an obvious typo/paste
|
|
1029
|
+
* mistake on blur, see wireUpPromoCode()) — whether the code is actually
|
|
1030
|
+
* active/redeemable is only known server-side when a purchase is made. */
|
|
1031
|
+
renderPromoCode(hasActiveCheckoutPromotion) {
|
|
1032
|
+
if (!this.hasAttribute("allow-promo-code") && !hasActiveCheckoutPromotion) return "";
|
|
990
1033
|
const label = this.getAttribute("promo-code-label") ?? "Have a promo code?";
|
|
991
1034
|
if (!this.promoCodeOpen) {
|
|
992
1035
|
return `<div class="promo-code">
|
|
@@ -996,6 +1039,7 @@ var Crediball = (() => {
|
|
|
996
1039
|
return `<div class="promo-code">
|
|
997
1040
|
<div class="promo-code-label">${escapeHtml(label)}</div>
|
|
998
1041
|
<input class="promo-code-input" placeholder="PROMOCODE" aria-label="Promo code" />
|
|
1042
|
+
<p class="promo-code-error" hidden></p>
|
|
999
1043
|
</div>`;
|
|
1000
1044
|
}
|
|
1001
1045
|
/** The current promo code input value (uppercased, trimmed), or undefined
|
package/dist/index.d.ts
CHANGED
|
@@ -123,9 +123,13 @@ declare class CrediballPaywallElement extends CrediballElement {
|
|
|
123
123
|
open(): void;
|
|
124
124
|
close(): void;
|
|
125
125
|
protected render(): void;
|
|
126
|
-
/** HTML for the "Have a promo code?" toggle-open field.
|
|
127
|
-
*
|
|
128
|
-
*
|
|
126
|
+
/** HTML for the "Have a promo code?" toggle-open field. Shown automatically
|
|
127
|
+
* once the app has an active Checkout promotion (same as the custom-amount
|
|
128
|
+
* field auto-following the dashboard's custom-topup config) — the
|
|
129
|
+
* `allow-promo-code` attribute is only needed to force it on before you've
|
|
130
|
+
* set one up. Format-only client check (flags an obvious typo/paste
|
|
131
|
+
* mistake on blur, see wireUpPromoCode()) — whether the code is actually
|
|
132
|
+
* active/redeemable is only known server-side when a purchase is made. */
|
|
129
133
|
private renderPromoCode;
|
|
130
134
|
/** The current promo code input value (uppercased, trimmed), or undefined
|
|
131
135
|
* when the field isn't shown/filled in. Read at click time — never re-render
|
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.11.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.9.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"tsup": "^8.3.5",
|