@aforoai/storefront-widgets 1.0.4 → 1.0.6
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/CHANGELOG.md +40 -0
- package/dist/index.cjs +77 -44
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +77 -44
- package/dist/loader.js +1 -1
- package/dist/loader.mjs +1 -1
- package/dist/sri.json +11 -11
- package/dist/vanilla/index.cjs +79 -44
- package/dist/vanilla/index.mjs +79 -44
- package/dist/vue/index.cjs +79 -44
- package/dist/vue/index.mjs +79 -44
- package/dist/widgets/checkout-flow.js +5 -5
- package/dist/widgets/invoice-list.js +6 -6
- package/dist/widgets/payment-method.js +5 -5
- package/dist/widgets/pricing-card.js +7 -7
- package/dist/widgets/subscribe-button.js +5 -5
- package/dist/widgets/subscription-manager.js +5 -5
- package/dist/widgets/upgrade-cancel.js +5 -5
- package/dist/widgets/usage-meter.js +5 -5
- package/loader.sri.txt +1 -1
- package/package.json +1 -1
package/dist/vanilla/index.cjs
CHANGED
|
@@ -27,7 +27,7 @@ var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
|
|
|
27
27
|
// src/vanilla/index.ts
|
|
28
28
|
|
|
29
29
|
// src/core/version.ts
|
|
30
|
-
var VERSION = "1.0.
|
|
30
|
+
var VERSION = "1.0.6";
|
|
31
31
|
|
|
32
32
|
// src/core/AforoEmbed.ts
|
|
33
33
|
var mountedElements = /* @__PURE__ */ new WeakMap();
|
|
@@ -182,6 +182,7 @@ function pricingCardConfigToProps(config) {
|
|
|
182
182
|
const theme = readEnum(extra.theme, ["light", "dark", "auto"], "auto");
|
|
183
183
|
const locale = typeof extra.locale === "string" ? extra.locale : void 0;
|
|
184
184
|
const maxPlans = typeof extra.maxPlans === "number" && Number.isFinite(extra.maxPlans) ? extra.maxPlans : void 0;
|
|
185
|
+
const borderRadius = typeof extra.borderRadius === "number" && Number.isFinite(extra.borderRadius) ? extra.borderRadius : void 0;
|
|
185
186
|
const ctaText = typeof extra.ctaText === "string" ? extra.ctaText : void 0;
|
|
186
187
|
const ctaUrl = typeof extra.ctaUrl === "string" ? extra.ctaUrl : void 0;
|
|
187
188
|
const showFeatures = typeof extra.showFeatures === "boolean" ? extra.showFeatures : void 0;
|
|
@@ -195,6 +196,7 @@ function pricingCardConfigToProps(config) {
|
|
|
195
196
|
theme,
|
|
196
197
|
locale,
|
|
197
198
|
maxPlans,
|
|
199
|
+
borderRadius,
|
|
198
200
|
showFeatures,
|
|
199
201
|
ctaText,
|
|
200
202
|
ctaUrl,
|
|
@@ -547,7 +549,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
547
549
|
throw await this.parseError(resp);
|
|
548
550
|
}
|
|
549
551
|
const body = await resp.json();
|
|
550
|
-
|
|
552
|
+
const data = body?.data ?? body;
|
|
553
|
+
if (!data || !data.sessionJwt || typeof data.expiresAt !== "number") {
|
|
551
554
|
throw new BridgeClientError(
|
|
552
555
|
"Malformed bridge exchange response",
|
|
553
556
|
500,
|
|
@@ -556,9 +559,9 @@ var _BridgeClient = class _BridgeClient {
|
|
|
556
559
|
);
|
|
557
560
|
}
|
|
558
561
|
return {
|
|
559
|
-
sessionJwt:
|
|
560
|
-
expiresAt:
|
|
561
|
-
customerId:
|
|
562
|
+
sessionJwt: data.sessionJwt,
|
|
563
|
+
expiresAt: data.expiresAt,
|
|
564
|
+
customerId: data.customerId ?? null
|
|
562
565
|
};
|
|
563
566
|
}
|
|
564
567
|
/**
|
|
@@ -644,16 +647,17 @@ var _BridgeClient = class _BridgeClient {
|
|
|
644
647
|
try {
|
|
645
648
|
const body = await resp.json();
|
|
646
649
|
if (!body || typeof body !== "object") return null;
|
|
650
|
+
const data = body.data ?? body;
|
|
647
651
|
return {
|
|
648
|
-
tenantSlug:
|
|
652
|
+
tenantSlug: data.tenantSlug,
|
|
649
653
|
branding: {
|
|
650
|
-
primaryColor:
|
|
651
|
-
secondaryColor:
|
|
652
|
-
logoUrl:
|
|
653
|
-
fontFamily:
|
|
654
|
+
primaryColor: data.primaryColor ?? null,
|
|
655
|
+
secondaryColor: data.secondaryColor ?? null,
|
|
656
|
+
logoUrl: data.logoUrl ?? null,
|
|
657
|
+
fontFamily: data.fontFamily ?? null
|
|
654
658
|
},
|
|
655
|
-
offerings: Array.isArray(
|
|
656
|
-
embeddableWidget:
|
|
659
|
+
offerings: Array.isArray(data.offerings) ? data.offerings : [],
|
|
660
|
+
embeddableWidget: data.embeddableWidget ?? null
|
|
657
661
|
};
|
|
658
662
|
} catch {
|
|
659
663
|
return null;
|
|
@@ -798,7 +802,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
798
802
|
false
|
|
799
803
|
);
|
|
800
804
|
}
|
|
801
|
-
|
|
805
|
+
const data = body?.data ?? body ?? {};
|
|
806
|
+
if (!data.checkoutUrl || !data.checkoutSessionId || !data.expiresAt) {
|
|
802
807
|
throw new BridgeClientError(
|
|
803
808
|
"Malformed checkout-initiate response (missing required fields)",
|
|
804
809
|
500,
|
|
@@ -807,9 +812,9 @@ var _BridgeClient = class _BridgeClient {
|
|
|
807
812
|
);
|
|
808
813
|
}
|
|
809
814
|
return {
|
|
810
|
-
checkoutUrl:
|
|
811
|
-
checkoutSessionId:
|
|
812
|
-
expiresAt:
|
|
815
|
+
checkoutUrl: data.checkoutUrl,
|
|
816
|
+
checkoutSessionId: data.checkoutSessionId,
|
|
817
|
+
expiresAt: data.expiresAt
|
|
813
818
|
};
|
|
814
819
|
}
|
|
815
820
|
/* ────────────────────────────────────────────────────────────────────
|
|
@@ -1617,13 +1622,16 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1617
1622
|
if (!resp.ok) return emptyPage;
|
|
1618
1623
|
try {
|
|
1619
1624
|
const body = await resp.json();
|
|
1620
|
-
if (!body || typeof body !== "object")
|
|
1625
|
+
if (!body || typeof body !== "object") {
|
|
1626
|
+
return emptyPage;
|
|
1627
|
+
}
|
|
1628
|
+
const data = body.data ?? body;
|
|
1621
1629
|
return {
|
|
1622
|
-
content: Array.isArray(
|
|
1623
|
-
totalElements: typeof
|
|
1624
|
-
totalPages: typeof
|
|
1625
|
-
page: typeof
|
|
1626
|
-
size: typeof
|
|
1630
|
+
content: Array.isArray(data.content) ? data.content : [],
|
|
1631
|
+
totalElements: typeof data.totalElements === "number" && Number.isFinite(data.totalElements) ? data.totalElements : 0,
|
|
1632
|
+
totalPages: typeof data.totalPages === "number" && Number.isFinite(data.totalPages) ? data.totalPages : 0,
|
|
1633
|
+
page: typeof data.page === "number" && Number.isFinite(data.page) ? data.page : filter.page ?? 0,
|
|
1634
|
+
size: typeof data.size === "number" && Number.isFinite(data.size) ? data.size : filter.size ?? 10
|
|
1627
1635
|
};
|
|
1628
1636
|
} catch {
|
|
1629
1637
|
return emptyPage;
|
|
@@ -3042,6 +3050,7 @@ function WidgetShell(props) {
|
|
|
3042
3050
|
var DEFAULT_LAYOUT = "horizontal";
|
|
3043
3051
|
var DEFAULT_MAX_PLANS = 4;
|
|
3044
3052
|
var DEFAULT_CTA_TEXT = "Get Started";
|
|
3053
|
+
var DEFAULT_CARD_RADIUS = 12;
|
|
3045
3054
|
function clampLayout(raw) {
|
|
3046
3055
|
return raw === "horizontal" || raw === "vertical" || raw === "table" ? raw : void 0;
|
|
3047
3056
|
}
|
|
@@ -3052,7 +3061,7 @@ function setTenantDefaultsIdempotent(setter, next) {
|
|
|
3052
3061
|
setter((prev) => {
|
|
3053
3062
|
if (prev === next) return prev;
|
|
3054
3063
|
if (!prev && !next) return prev;
|
|
3055
|
-
if (prev && next && prev.layout === next.layout && prev.theme === next.theme && prev.maxPlans === next.maxPlans && prev.showFeatures === next.showFeatures && prev.ctaText === next.ctaText) {
|
|
3064
|
+
if (prev && next && prev.layout === next.layout && prev.theme === next.theme && prev.maxPlans === next.maxPlans && prev.showFeatures === next.showFeatures && prev.ctaText === next.ctaText && prev.borderRadius === next.borderRadius) {
|
|
3056
3065
|
return prev;
|
|
3057
3066
|
}
|
|
3058
3067
|
return next;
|
|
@@ -3067,7 +3076,8 @@ function extractTenantDefaults(config) {
|
|
|
3067
3076
|
theme: typeof raw.theme === "string" ? raw.theme : void 0,
|
|
3068
3077
|
maxPlans: typeof raw.maxPlans === "number" && Number.isFinite(raw.maxPlans) ? raw.maxPlans : void 0,
|
|
3069
3078
|
showFeatures: typeof raw.showFeatures === "boolean" ? raw.showFeatures : void 0,
|
|
3070
|
-
ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0
|
|
3079
|
+
ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0,
|
|
3080
|
+
borderRadius: typeof raw.borderRadius === "number" && Number.isFinite(raw.borderRadius) ? raw.borderRadius : void 0
|
|
3071
3081
|
};
|
|
3072
3082
|
}
|
|
3073
3083
|
var DARK_TOKEN_OVERLAY = {
|
|
@@ -3127,6 +3137,20 @@ function safeFormatCurrency(priceCents, currency, locale, intlOverride) {
|
|
|
3127
3137
|
return `${currency} ${amount.toFixed(2)}`;
|
|
3128
3138
|
}
|
|
3129
3139
|
}
|
|
3140
|
+
function resolveDisplayPrice(offering, locale, intlOverride) {
|
|
3141
|
+
const flat = safeFormatCurrency(offering.priceCents, offering.currency, locale, intlOverride);
|
|
3142
|
+
if (flat !== "\u2014") return { text: flat, unitSuffix: null };
|
|
3143
|
+
const perUnitPlan = offering.ratePlans?.find(
|
|
3144
|
+
(rp) => rp.pricingModel === "PER_UNIT" && rp.perUnitPriceCents != null
|
|
3145
|
+
);
|
|
3146
|
+
if (perUnitPlan) {
|
|
3147
|
+
const unitPrice = safeFormatCurrency(perUnitPlan.perUnitPriceCents, offering.currency, locale, intlOverride);
|
|
3148
|
+
if (unitPrice !== "\u2014") {
|
|
3149
|
+
return { text: unitPrice, unitSuffix: perUnitPlan.unitLabel || "unit" };
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
return { text: "\u2014", unitSuffix: null };
|
|
3153
|
+
}
|
|
3130
3154
|
function localizedName(o) {
|
|
3131
3155
|
return o.localizedDisplayName || o.name || "(unnamed plan)";
|
|
3132
3156
|
}
|
|
@@ -3175,6 +3199,7 @@ function PricingCardBody(props) {
|
|
|
3175
3199
|
theme: themeProp,
|
|
3176
3200
|
locale: localeProp,
|
|
3177
3201
|
maxPlans: maxPlansProp,
|
|
3202
|
+
borderRadius: borderRadiusProp,
|
|
3178
3203
|
showFeatures: showFeaturesProp,
|
|
3179
3204
|
ctaText: ctaTextProp,
|
|
3180
3205
|
ctaUrl: ctaUrlProp,
|
|
@@ -3188,6 +3213,7 @@ function PricingCardBody(props) {
|
|
|
3188
3213
|
const maxPlans = typeof maxPlansProp === "number" && Number.isFinite(maxPlansProp) ? maxPlansProp : typeof tenantDefaults?.maxPlans === "number" && Number.isFinite(tenantDefaults.maxPlans) ? tenantDefaults.maxPlans : DEFAULT_MAX_PLANS;
|
|
3189
3214
|
const showFeatures = typeof showFeaturesProp === "boolean" ? showFeaturesProp : typeof tenantDefaults?.showFeatures === "boolean" ? tenantDefaults.showFeatures : true;
|
|
3190
3215
|
const ctaTextEffective = ctaTextProp ?? tenantDefaults?.ctaText ?? void 0;
|
|
3216
|
+
const cardRadius = typeof borderRadiusProp === "number" && Number.isFinite(borderRadiusProp) ? borderRadiusProp : typeof tenantDefaults?.borderRadius === "number" && Number.isFinite(tenantDefaults.borderRadius) ? tenantDefaults.borderRadius : DEFAULT_CARD_RADIUS;
|
|
3191
3217
|
const shell = useWidgetShell();
|
|
3192
3218
|
const { tokens: shellTokens, bridgeClient, telemetry, bus, tenantSlug } = shell;
|
|
3193
3219
|
const isDark = React7__namespace.useMemo(() => {
|
|
@@ -3405,7 +3431,8 @@ function PricingCardBody(props) {
|
|
|
3405
3431
|
{
|
|
3406
3432
|
layout,
|
|
3407
3433
|
tokens,
|
|
3408
|
-
prefersReducedMotion
|
|
3434
|
+
prefersReducedMotion,
|
|
3435
|
+
cardRadius
|
|
3409
3436
|
}
|
|
3410
3437
|
)
|
|
3411
3438
|
}
|
|
@@ -3477,7 +3504,8 @@ function PricingCardBody(props) {
|
|
|
3477
3504
|
ctaTextProp: ctaTextEffective,
|
|
3478
3505
|
featuredOverride: featuredOfferingId,
|
|
3479
3506
|
onCtaClick: handleCtaClick,
|
|
3480
|
-
intlOverride
|
|
3507
|
+
intlOverride,
|
|
3508
|
+
cardRadius
|
|
3481
3509
|
}
|
|
3482
3510
|
)
|
|
3483
3511
|
}
|
|
@@ -3492,7 +3520,8 @@ function PlanGrid({
|
|
|
3492
3520
|
ctaTextProp,
|
|
3493
3521
|
featuredOverride,
|
|
3494
3522
|
onCtaClick,
|
|
3495
|
-
intlOverride
|
|
3523
|
+
intlOverride,
|
|
3524
|
+
cardRadius
|
|
3496
3525
|
}) {
|
|
3497
3526
|
const isHorizontal = layout === "horizontal";
|
|
3498
3527
|
const gridStyle2 = isHorizontal ? {
|
|
@@ -3515,7 +3544,8 @@ function PlanGrid({
|
|
|
3515
3544
|
ctaTextProp,
|
|
3516
3545
|
featured: offeringIsFeatured(o, featuredOverride),
|
|
3517
3546
|
onCtaClick,
|
|
3518
|
-
intlOverride
|
|
3547
|
+
intlOverride,
|
|
3548
|
+
cardRadius
|
|
3519
3549
|
},
|
|
3520
3550
|
o.offeringId
|
|
3521
3551
|
)) });
|
|
@@ -3528,14 +3558,10 @@ function PlanCard({
|
|
|
3528
3558
|
ctaTextProp,
|
|
3529
3559
|
featured,
|
|
3530
3560
|
onCtaClick,
|
|
3531
|
-
intlOverride
|
|
3561
|
+
intlOverride,
|
|
3562
|
+
cardRadius
|
|
3532
3563
|
}) {
|
|
3533
|
-
const price =
|
|
3534
|
-
offering.priceCents,
|
|
3535
|
-
offering.currency,
|
|
3536
|
-
locale,
|
|
3537
|
-
intlOverride
|
|
3538
|
-
);
|
|
3564
|
+
const { text: price, unitSuffix } = resolveDisplayPrice(offering, locale, intlOverride);
|
|
3539
3565
|
const isContactSales = price === "\u2014";
|
|
3540
3566
|
const planName = localizedName(offering);
|
|
3541
3567
|
const description = localizedDescription(offering);
|
|
@@ -3544,7 +3570,7 @@ function PlanCard({
|
|
|
3544
3570
|
display: "flex",
|
|
3545
3571
|
flexDirection: "column",
|
|
3546
3572
|
padding: 24,
|
|
3547
|
-
borderRadius:
|
|
3573
|
+
borderRadius: cardRadius,
|
|
3548
3574
|
border: featured ? `2px solid ${tokens.primary}` : `1px solid ${tokens.border}`,
|
|
3549
3575
|
background: tokens.bg,
|
|
3550
3576
|
color: tokens.text,
|
|
@@ -3556,7 +3582,7 @@ function PlanCard({
|
|
|
3556
3582
|
"div",
|
|
3557
3583
|
{
|
|
3558
3584
|
role: "group",
|
|
3559
|
-
"aria-label": `${planName}, ${price} per ${offering.billingCycle}`,
|
|
3585
|
+
"aria-label": `${planName}, ${price} per ${unitSuffix ?? offering.billingCycle}`,
|
|
3560
3586
|
className: `aforo-w-pc-card${featured ? " aforo-w-pc-card-featured" : ""}`,
|
|
3561
3587
|
style: cardStyle2,
|
|
3562
3588
|
children: [
|
|
@@ -3621,14 +3647,14 @@ function PlanCard({
|
|
|
3621
3647
|
children: price
|
|
3622
3648
|
}
|
|
3623
3649
|
),
|
|
3624
|
-
!isContactSales && offering.billingCycle ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3650
|
+
!isContactSales && (unitSuffix || offering.billingCycle) ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3625
3651
|
"span",
|
|
3626
3652
|
{
|
|
3627
3653
|
className: "aforo-w-pc-cycle",
|
|
3628
3654
|
style: { fontSize: 13, color: tokens.textMuted },
|
|
3629
3655
|
children: [
|
|
3630
3656
|
"/ ",
|
|
3631
|
-
humanCycle(offering.billingCycle)
|
|
3657
|
+
unitSuffix ?? humanCycle(offering.billingCycle)
|
|
3632
3658
|
]
|
|
3633
3659
|
}
|
|
3634
3660
|
) : null
|
|
@@ -3786,6 +3812,7 @@ function TableLayout({
|
|
|
3786
3812
|
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", style: { ...headerCellStyle, color: tokens.textMuted, fontSize: 12 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "aforo-w-pc-sr-only", style: srOnlyStyle, children: "Feature" }) }),
|
|
3787
3813
|
offerings.map((o) => {
|
|
3788
3814
|
const featured = offeringIsFeatured(o, featuredOverride);
|
|
3815
|
+
const { text: tablePrice, unitSuffix: tableUnitSuffix } = resolveDisplayPrice(o, locale, intlOverride);
|
|
3789
3816
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3790
3817
|
"th",
|
|
3791
3818
|
{
|
|
@@ -3815,13 +3842,20 @@ function TableLayout({
|
|
|
3815
3842
|
children: "Most popular"
|
|
3816
3843
|
}
|
|
3817
3844
|
) : null,
|
|
3818
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3845
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 22, fontWeight: 700 }, children: [
|
|
3846
|
+
tablePrice,
|
|
3847
|
+
tableUnitSuffix ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 12, fontWeight: 400, color: tokens.textMuted }, children: [
|
|
3848
|
+
" ",
|
|
3849
|
+
"/ ",
|
|
3850
|
+
tableUnitSuffix
|
|
3851
|
+
] }) : null
|
|
3852
|
+
] }),
|
|
3819
3853
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3820
3854
|
"button",
|
|
3821
3855
|
{
|
|
3822
3856
|
type: "button",
|
|
3823
3857
|
onClick: () => onCtaClick(o),
|
|
3824
|
-
"aria-label": `${ctaLabel(o, ctaTextProp,
|
|
3858
|
+
"aria-label": `${ctaLabel(o, ctaTextProp, tablePrice === "\u2014")} for ${localizedName(o)}`,
|
|
3825
3859
|
style: {
|
|
3826
3860
|
inlineSize: "100%",
|
|
3827
3861
|
padding: "8px 12px",
|
|
@@ -3834,7 +3868,7 @@ function TableLayout({
|
|
|
3834
3868
|
cursor: "pointer",
|
|
3835
3869
|
fontFamily: tokens.fontFamily
|
|
3836
3870
|
},
|
|
3837
|
-
children: ctaLabel(o, ctaTextProp,
|
|
3871
|
+
children: ctaLabel(o, ctaTextProp, tablePrice === "\u2014")
|
|
3838
3872
|
}
|
|
3839
3873
|
)
|
|
3840
3874
|
] })
|
|
@@ -3886,7 +3920,8 @@ function cellAria(label, feature) {
|
|
|
3886
3920
|
function LoadingSkeleton({
|
|
3887
3921
|
layout,
|
|
3888
3922
|
tokens,
|
|
3889
|
-
prefersReducedMotion
|
|
3923
|
+
prefersReducedMotion,
|
|
3924
|
+
cardRadius
|
|
3890
3925
|
}) {
|
|
3891
3926
|
const shimmerStyle = prefersReducedMotion ? { background: tokens.border, opacity: 0.6 } : {
|
|
3892
3927
|
background: `linear-gradient(90deg, ${tokens.border} 0%, ${tokens.bg} 50%, ${tokens.border} 100%)`,
|
|
@@ -3919,7 +3954,7 @@ function LoadingSkeleton({
|
|
|
3919
3954
|
"aria-hidden": "true",
|
|
3920
3955
|
style: {
|
|
3921
3956
|
padding: 24,
|
|
3922
|
-
borderRadius:
|
|
3957
|
+
borderRadius: cardRadius,
|
|
3923
3958
|
border: `1px solid ${tokens.border}`,
|
|
3924
3959
|
background: tokens.bg,
|
|
3925
3960
|
minHeight: 280,
|
package/dist/vanilla/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
5
5
|
// src/vanilla/index.ts
|
|
6
6
|
|
|
7
7
|
// src/core/version.ts
|
|
8
|
-
var VERSION = "1.0.
|
|
8
|
+
var VERSION = "1.0.6";
|
|
9
9
|
|
|
10
10
|
// src/core/AforoEmbed.ts
|
|
11
11
|
var mountedElements = /* @__PURE__ */ new WeakMap();
|
|
@@ -160,6 +160,7 @@ function pricingCardConfigToProps(config) {
|
|
|
160
160
|
const theme = readEnum(extra.theme, ["light", "dark", "auto"], "auto");
|
|
161
161
|
const locale = typeof extra.locale === "string" ? extra.locale : void 0;
|
|
162
162
|
const maxPlans = typeof extra.maxPlans === "number" && Number.isFinite(extra.maxPlans) ? extra.maxPlans : void 0;
|
|
163
|
+
const borderRadius = typeof extra.borderRadius === "number" && Number.isFinite(extra.borderRadius) ? extra.borderRadius : void 0;
|
|
163
164
|
const ctaText = typeof extra.ctaText === "string" ? extra.ctaText : void 0;
|
|
164
165
|
const ctaUrl = typeof extra.ctaUrl === "string" ? extra.ctaUrl : void 0;
|
|
165
166
|
const showFeatures = typeof extra.showFeatures === "boolean" ? extra.showFeatures : void 0;
|
|
@@ -173,6 +174,7 @@ function pricingCardConfigToProps(config) {
|
|
|
173
174
|
theme,
|
|
174
175
|
locale,
|
|
175
176
|
maxPlans,
|
|
177
|
+
borderRadius,
|
|
176
178
|
showFeatures,
|
|
177
179
|
ctaText,
|
|
178
180
|
ctaUrl,
|
|
@@ -525,7 +527,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
525
527
|
throw await this.parseError(resp);
|
|
526
528
|
}
|
|
527
529
|
const body = await resp.json();
|
|
528
|
-
|
|
530
|
+
const data = body?.data ?? body;
|
|
531
|
+
if (!data || !data.sessionJwt || typeof data.expiresAt !== "number") {
|
|
529
532
|
throw new BridgeClientError(
|
|
530
533
|
"Malformed bridge exchange response",
|
|
531
534
|
500,
|
|
@@ -534,9 +537,9 @@ var _BridgeClient = class _BridgeClient {
|
|
|
534
537
|
);
|
|
535
538
|
}
|
|
536
539
|
return {
|
|
537
|
-
sessionJwt:
|
|
538
|
-
expiresAt:
|
|
539
|
-
customerId:
|
|
540
|
+
sessionJwt: data.sessionJwt,
|
|
541
|
+
expiresAt: data.expiresAt,
|
|
542
|
+
customerId: data.customerId ?? null
|
|
540
543
|
};
|
|
541
544
|
}
|
|
542
545
|
/**
|
|
@@ -622,16 +625,17 @@ var _BridgeClient = class _BridgeClient {
|
|
|
622
625
|
try {
|
|
623
626
|
const body = await resp.json();
|
|
624
627
|
if (!body || typeof body !== "object") return null;
|
|
628
|
+
const data = body.data ?? body;
|
|
625
629
|
return {
|
|
626
|
-
tenantSlug:
|
|
630
|
+
tenantSlug: data.tenantSlug,
|
|
627
631
|
branding: {
|
|
628
|
-
primaryColor:
|
|
629
|
-
secondaryColor:
|
|
630
|
-
logoUrl:
|
|
631
|
-
fontFamily:
|
|
632
|
+
primaryColor: data.primaryColor ?? null,
|
|
633
|
+
secondaryColor: data.secondaryColor ?? null,
|
|
634
|
+
logoUrl: data.logoUrl ?? null,
|
|
635
|
+
fontFamily: data.fontFamily ?? null
|
|
632
636
|
},
|
|
633
|
-
offerings: Array.isArray(
|
|
634
|
-
embeddableWidget:
|
|
637
|
+
offerings: Array.isArray(data.offerings) ? data.offerings : [],
|
|
638
|
+
embeddableWidget: data.embeddableWidget ?? null
|
|
635
639
|
};
|
|
636
640
|
} catch {
|
|
637
641
|
return null;
|
|
@@ -776,7 +780,8 @@ var _BridgeClient = class _BridgeClient {
|
|
|
776
780
|
false
|
|
777
781
|
);
|
|
778
782
|
}
|
|
779
|
-
|
|
783
|
+
const data = body?.data ?? body ?? {};
|
|
784
|
+
if (!data.checkoutUrl || !data.checkoutSessionId || !data.expiresAt) {
|
|
780
785
|
throw new BridgeClientError(
|
|
781
786
|
"Malformed checkout-initiate response (missing required fields)",
|
|
782
787
|
500,
|
|
@@ -785,9 +790,9 @@ var _BridgeClient = class _BridgeClient {
|
|
|
785
790
|
);
|
|
786
791
|
}
|
|
787
792
|
return {
|
|
788
|
-
checkoutUrl:
|
|
789
|
-
checkoutSessionId:
|
|
790
|
-
expiresAt:
|
|
793
|
+
checkoutUrl: data.checkoutUrl,
|
|
794
|
+
checkoutSessionId: data.checkoutSessionId,
|
|
795
|
+
expiresAt: data.expiresAt
|
|
791
796
|
};
|
|
792
797
|
}
|
|
793
798
|
/* ────────────────────────────────────────────────────────────────────
|
|
@@ -1595,13 +1600,16 @@ var _BridgeClient = class _BridgeClient {
|
|
|
1595
1600
|
if (!resp.ok) return emptyPage;
|
|
1596
1601
|
try {
|
|
1597
1602
|
const body = await resp.json();
|
|
1598
|
-
if (!body || typeof body !== "object")
|
|
1603
|
+
if (!body || typeof body !== "object") {
|
|
1604
|
+
return emptyPage;
|
|
1605
|
+
}
|
|
1606
|
+
const data = body.data ?? body;
|
|
1599
1607
|
return {
|
|
1600
|
-
content: Array.isArray(
|
|
1601
|
-
totalElements: typeof
|
|
1602
|
-
totalPages: typeof
|
|
1603
|
-
page: typeof
|
|
1604
|
-
size: typeof
|
|
1608
|
+
content: Array.isArray(data.content) ? data.content : [],
|
|
1609
|
+
totalElements: typeof data.totalElements === "number" && Number.isFinite(data.totalElements) ? data.totalElements : 0,
|
|
1610
|
+
totalPages: typeof data.totalPages === "number" && Number.isFinite(data.totalPages) ? data.totalPages : 0,
|
|
1611
|
+
page: typeof data.page === "number" && Number.isFinite(data.page) ? data.page : filter.page ?? 0,
|
|
1612
|
+
size: typeof data.size === "number" && Number.isFinite(data.size) ? data.size : filter.size ?? 10
|
|
1605
1613
|
};
|
|
1606
1614
|
} catch {
|
|
1607
1615
|
return emptyPage;
|
|
@@ -3020,6 +3028,7 @@ function WidgetShell(props) {
|
|
|
3020
3028
|
var DEFAULT_LAYOUT = "horizontal";
|
|
3021
3029
|
var DEFAULT_MAX_PLANS = 4;
|
|
3022
3030
|
var DEFAULT_CTA_TEXT = "Get Started";
|
|
3031
|
+
var DEFAULT_CARD_RADIUS = 12;
|
|
3023
3032
|
function clampLayout(raw) {
|
|
3024
3033
|
return raw === "horizontal" || raw === "vertical" || raw === "table" ? raw : void 0;
|
|
3025
3034
|
}
|
|
@@ -3030,7 +3039,7 @@ function setTenantDefaultsIdempotent(setter, next) {
|
|
|
3030
3039
|
setter((prev) => {
|
|
3031
3040
|
if (prev === next) return prev;
|
|
3032
3041
|
if (!prev && !next) return prev;
|
|
3033
|
-
if (prev && next && prev.layout === next.layout && prev.theme === next.theme && prev.maxPlans === next.maxPlans && prev.showFeatures === next.showFeatures && prev.ctaText === next.ctaText) {
|
|
3042
|
+
if (prev && next && prev.layout === next.layout && prev.theme === next.theme && prev.maxPlans === next.maxPlans && prev.showFeatures === next.showFeatures && prev.ctaText === next.ctaText && prev.borderRadius === next.borderRadius) {
|
|
3034
3043
|
return prev;
|
|
3035
3044
|
}
|
|
3036
3045
|
return next;
|
|
@@ -3045,7 +3054,8 @@ function extractTenantDefaults(config) {
|
|
|
3045
3054
|
theme: typeof raw.theme === "string" ? raw.theme : void 0,
|
|
3046
3055
|
maxPlans: typeof raw.maxPlans === "number" && Number.isFinite(raw.maxPlans) ? raw.maxPlans : void 0,
|
|
3047
3056
|
showFeatures: typeof raw.showFeatures === "boolean" ? raw.showFeatures : void 0,
|
|
3048
|
-
ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0
|
|
3057
|
+
ctaText: typeof raw.ctaText === "string" && raw.ctaText.length > 0 ? raw.ctaText : void 0,
|
|
3058
|
+
borderRadius: typeof raw.borderRadius === "number" && Number.isFinite(raw.borderRadius) ? raw.borderRadius : void 0
|
|
3049
3059
|
};
|
|
3050
3060
|
}
|
|
3051
3061
|
var DARK_TOKEN_OVERLAY = {
|
|
@@ -3105,6 +3115,20 @@ function safeFormatCurrency(priceCents, currency, locale, intlOverride) {
|
|
|
3105
3115
|
return `${currency} ${amount.toFixed(2)}`;
|
|
3106
3116
|
}
|
|
3107
3117
|
}
|
|
3118
|
+
function resolveDisplayPrice(offering, locale, intlOverride) {
|
|
3119
|
+
const flat = safeFormatCurrency(offering.priceCents, offering.currency, locale, intlOverride);
|
|
3120
|
+
if (flat !== "\u2014") return { text: flat, unitSuffix: null };
|
|
3121
|
+
const perUnitPlan = offering.ratePlans?.find(
|
|
3122
|
+
(rp) => rp.pricingModel === "PER_UNIT" && rp.perUnitPriceCents != null
|
|
3123
|
+
);
|
|
3124
|
+
if (perUnitPlan) {
|
|
3125
|
+
const unitPrice = safeFormatCurrency(perUnitPlan.perUnitPriceCents, offering.currency, locale, intlOverride);
|
|
3126
|
+
if (unitPrice !== "\u2014") {
|
|
3127
|
+
return { text: unitPrice, unitSuffix: perUnitPlan.unitLabel || "unit" };
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
return { text: "\u2014", unitSuffix: null };
|
|
3131
|
+
}
|
|
3108
3132
|
function localizedName(o) {
|
|
3109
3133
|
return o.localizedDisplayName || o.name || "(unnamed plan)";
|
|
3110
3134
|
}
|
|
@@ -3153,6 +3177,7 @@ function PricingCardBody(props) {
|
|
|
3153
3177
|
theme: themeProp,
|
|
3154
3178
|
locale: localeProp,
|
|
3155
3179
|
maxPlans: maxPlansProp,
|
|
3180
|
+
borderRadius: borderRadiusProp,
|
|
3156
3181
|
showFeatures: showFeaturesProp,
|
|
3157
3182
|
ctaText: ctaTextProp,
|
|
3158
3183
|
ctaUrl: ctaUrlProp,
|
|
@@ -3166,6 +3191,7 @@ function PricingCardBody(props) {
|
|
|
3166
3191
|
const maxPlans = typeof maxPlansProp === "number" && Number.isFinite(maxPlansProp) ? maxPlansProp : typeof tenantDefaults?.maxPlans === "number" && Number.isFinite(tenantDefaults.maxPlans) ? tenantDefaults.maxPlans : DEFAULT_MAX_PLANS;
|
|
3167
3192
|
const showFeatures = typeof showFeaturesProp === "boolean" ? showFeaturesProp : typeof tenantDefaults?.showFeatures === "boolean" ? tenantDefaults.showFeatures : true;
|
|
3168
3193
|
const ctaTextEffective = ctaTextProp ?? tenantDefaults?.ctaText ?? void 0;
|
|
3194
|
+
const cardRadius = typeof borderRadiusProp === "number" && Number.isFinite(borderRadiusProp) ? borderRadiusProp : typeof tenantDefaults?.borderRadius === "number" && Number.isFinite(tenantDefaults.borderRadius) ? tenantDefaults.borderRadius : DEFAULT_CARD_RADIUS;
|
|
3169
3195
|
const shell = useWidgetShell();
|
|
3170
3196
|
const { tokens: shellTokens, bridgeClient, telemetry, bus, tenantSlug } = shell;
|
|
3171
3197
|
const isDark = React7.useMemo(() => {
|
|
@@ -3383,7 +3409,8 @@ function PricingCardBody(props) {
|
|
|
3383
3409
|
{
|
|
3384
3410
|
layout,
|
|
3385
3411
|
tokens,
|
|
3386
|
-
prefersReducedMotion
|
|
3412
|
+
prefersReducedMotion,
|
|
3413
|
+
cardRadius
|
|
3387
3414
|
}
|
|
3388
3415
|
)
|
|
3389
3416
|
}
|
|
@@ -3455,7 +3482,8 @@ function PricingCardBody(props) {
|
|
|
3455
3482
|
ctaTextProp: ctaTextEffective,
|
|
3456
3483
|
featuredOverride: featuredOfferingId,
|
|
3457
3484
|
onCtaClick: handleCtaClick,
|
|
3458
|
-
intlOverride
|
|
3485
|
+
intlOverride,
|
|
3486
|
+
cardRadius
|
|
3459
3487
|
}
|
|
3460
3488
|
)
|
|
3461
3489
|
}
|
|
@@ -3470,7 +3498,8 @@ function PlanGrid({
|
|
|
3470
3498
|
ctaTextProp,
|
|
3471
3499
|
featuredOverride,
|
|
3472
3500
|
onCtaClick,
|
|
3473
|
-
intlOverride
|
|
3501
|
+
intlOverride,
|
|
3502
|
+
cardRadius
|
|
3474
3503
|
}) {
|
|
3475
3504
|
const isHorizontal = layout === "horizontal";
|
|
3476
3505
|
const gridStyle2 = isHorizontal ? {
|
|
@@ -3493,7 +3522,8 @@ function PlanGrid({
|
|
|
3493
3522
|
ctaTextProp,
|
|
3494
3523
|
featured: offeringIsFeatured(o, featuredOverride),
|
|
3495
3524
|
onCtaClick,
|
|
3496
|
-
intlOverride
|
|
3525
|
+
intlOverride,
|
|
3526
|
+
cardRadius
|
|
3497
3527
|
},
|
|
3498
3528
|
o.offeringId
|
|
3499
3529
|
)) });
|
|
@@ -3506,14 +3536,10 @@ function PlanCard({
|
|
|
3506
3536
|
ctaTextProp,
|
|
3507
3537
|
featured,
|
|
3508
3538
|
onCtaClick,
|
|
3509
|
-
intlOverride
|
|
3539
|
+
intlOverride,
|
|
3540
|
+
cardRadius
|
|
3510
3541
|
}) {
|
|
3511
|
-
const price =
|
|
3512
|
-
offering.priceCents,
|
|
3513
|
-
offering.currency,
|
|
3514
|
-
locale,
|
|
3515
|
-
intlOverride
|
|
3516
|
-
);
|
|
3542
|
+
const { text: price, unitSuffix } = resolveDisplayPrice(offering, locale, intlOverride);
|
|
3517
3543
|
const isContactSales = price === "\u2014";
|
|
3518
3544
|
const planName = localizedName(offering);
|
|
3519
3545
|
const description = localizedDescription(offering);
|
|
@@ -3522,7 +3548,7 @@ function PlanCard({
|
|
|
3522
3548
|
display: "flex",
|
|
3523
3549
|
flexDirection: "column",
|
|
3524
3550
|
padding: 24,
|
|
3525
|
-
borderRadius:
|
|
3551
|
+
borderRadius: cardRadius,
|
|
3526
3552
|
border: featured ? `2px solid ${tokens.primary}` : `1px solid ${tokens.border}`,
|
|
3527
3553
|
background: tokens.bg,
|
|
3528
3554
|
color: tokens.text,
|
|
@@ -3534,7 +3560,7 @@ function PlanCard({
|
|
|
3534
3560
|
"div",
|
|
3535
3561
|
{
|
|
3536
3562
|
role: "group",
|
|
3537
|
-
"aria-label": `${planName}, ${price} per ${offering.billingCycle}`,
|
|
3563
|
+
"aria-label": `${planName}, ${price} per ${unitSuffix ?? offering.billingCycle}`,
|
|
3538
3564
|
className: `aforo-w-pc-card${featured ? " aforo-w-pc-card-featured" : ""}`,
|
|
3539
3565
|
style: cardStyle2,
|
|
3540
3566
|
children: [
|
|
@@ -3599,14 +3625,14 @@ function PlanCard({
|
|
|
3599
3625
|
children: price
|
|
3600
3626
|
}
|
|
3601
3627
|
),
|
|
3602
|
-
!isContactSales && offering.billingCycle ? /* @__PURE__ */ jsxs(
|
|
3628
|
+
!isContactSales && (unitSuffix || offering.billingCycle) ? /* @__PURE__ */ jsxs(
|
|
3603
3629
|
"span",
|
|
3604
3630
|
{
|
|
3605
3631
|
className: "aforo-w-pc-cycle",
|
|
3606
3632
|
style: { fontSize: 13, color: tokens.textMuted },
|
|
3607
3633
|
children: [
|
|
3608
3634
|
"/ ",
|
|
3609
|
-
humanCycle(offering.billingCycle)
|
|
3635
|
+
unitSuffix ?? humanCycle(offering.billingCycle)
|
|
3610
3636
|
]
|
|
3611
3637
|
}
|
|
3612
3638
|
) : null
|
|
@@ -3764,6 +3790,7 @@ function TableLayout({
|
|
|
3764
3790
|
/* @__PURE__ */ jsx("th", { scope: "col", style: { ...headerCellStyle, color: tokens.textMuted, fontSize: 12 }, children: /* @__PURE__ */ jsx("span", { className: "aforo-w-pc-sr-only", style: srOnlyStyle, children: "Feature" }) }),
|
|
3765
3791
|
offerings.map((o) => {
|
|
3766
3792
|
const featured = offeringIsFeatured(o, featuredOverride);
|
|
3793
|
+
const { text: tablePrice, unitSuffix: tableUnitSuffix } = resolveDisplayPrice(o, locale, intlOverride);
|
|
3767
3794
|
return /* @__PURE__ */ jsx(
|
|
3768
3795
|
"th",
|
|
3769
3796
|
{
|
|
@@ -3793,13 +3820,20 @@ function TableLayout({
|
|
|
3793
3820
|
children: "Most popular"
|
|
3794
3821
|
}
|
|
3795
3822
|
) : null,
|
|
3796
|
-
/* @__PURE__ */
|
|
3823
|
+
/* @__PURE__ */ jsxs("div", { style: { fontSize: 22, fontWeight: 700 }, children: [
|
|
3824
|
+
tablePrice,
|
|
3825
|
+
tableUnitSuffix ? /* @__PURE__ */ jsxs("span", { style: { fontSize: 12, fontWeight: 400, color: tokens.textMuted }, children: [
|
|
3826
|
+
" ",
|
|
3827
|
+
"/ ",
|
|
3828
|
+
tableUnitSuffix
|
|
3829
|
+
] }) : null
|
|
3830
|
+
] }),
|
|
3797
3831
|
/* @__PURE__ */ jsx(
|
|
3798
3832
|
"button",
|
|
3799
3833
|
{
|
|
3800
3834
|
type: "button",
|
|
3801
3835
|
onClick: () => onCtaClick(o),
|
|
3802
|
-
"aria-label": `${ctaLabel(o, ctaTextProp,
|
|
3836
|
+
"aria-label": `${ctaLabel(o, ctaTextProp, tablePrice === "\u2014")} for ${localizedName(o)}`,
|
|
3803
3837
|
style: {
|
|
3804
3838
|
inlineSize: "100%",
|
|
3805
3839
|
padding: "8px 12px",
|
|
@@ -3812,7 +3846,7 @@ function TableLayout({
|
|
|
3812
3846
|
cursor: "pointer",
|
|
3813
3847
|
fontFamily: tokens.fontFamily
|
|
3814
3848
|
},
|
|
3815
|
-
children: ctaLabel(o, ctaTextProp,
|
|
3849
|
+
children: ctaLabel(o, ctaTextProp, tablePrice === "\u2014")
|
|
3816
3850
|
}
|
|
3817
3851
|
)
|
|
3818
3852
|
] })
|
|
@@ -3864,7 +3898,8 @@ function cellAria(label, feature) {
|
|
|
3864
3898
|
function LoadingSkeleton({
|
|
3865
3899
|
layout,
|
|
3866
3900
|
tokens,
|
|
3867
|
-
prefersReducedMotion
|
|
3901
|
+
prefersReducedMotion,
|
|
3902
|
+
cardRadius
|
|
3868
3903
|
}) {
|
|
3869
3904
|
const shimmerStyle = prefersReducedMotion ? { background: tokens.border, opacity: 0.6 } : {
|
|
3870
3905
|
background: `linear-gradient(90deg, ${tokens.border} 0%, ${tokens.bg} 50%, ${tokens.border} 100%)`,
|
|
@@ -3897,7 +3932,7 @@ function LoadingSkeleton({
|
|
|
3897
3932
|
"aria-hidden": "true",
|
|
3898
3933
|
style: {
|
|
3899
3934
|
padding: 24,
|
|
3900
|
-
borderRadius:
|
|
3935
|
+
borderRadius: cardRadius,
|
|
3901
3936
|
border: `1px solid ${tokens.border}`,
|
|
3902
3937
|
background: tokens.bg,
|
|
3903
3938
|
minHeight: 280,
|