@schematichq/schematic-components 2.20.0 → 2.21.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.
@@ -778,7 +778,7 @@ var require_styled_components_cjs = __commonJS({
778
778
  var u = "undefined" != typeof process && void 0 !== process.env && (process.env.REACT_APP_SC_ATTR || process.env.SC_ATTR) || "data-styled";
779
779
  var d = "active";
780
780
  var h = "data-styled-version";
781
- var p = "6.4.3";
781
+ var p = "6.4.4";
782
782
  var f = "/*!sc*/\n";
783
783
  var m = "undefined" != typeof window && "undefined" != typeof document;
784
784
  var y = void 0 === a.default.createContext;
@@ -6823,6 +6823,9 @@ var en_default = {
6823
6823
  "After the trial, subscribe": "After the trial, subscription starts and you will be billed.",
6824
6824
  Agreement: "Agreement",
6825
6825
  "Amount off": "{{amount}} off",
6826
+ "Applied balance towards next invoice": "Applied balance towards next invoice",
6827
+ "Discount for months_one": "{{discount}} for next month",
6828
+ "Discount for months_other": "{{discount}} for next {{count}} months",
6826
6829
  "Auto Top-up": "Auto top-up",
6827
6830
  "Auto top-up enabled": "Auto top-up enabled",
6828
6831
  "Auto top-up disabled": "Auto top-up disabled",
@@ -6918,7 +6921,7 @@ var en_default = {
6918
6921
  Proration: "Proration",
6919
6922
  Quantity: "Quantity",
6920
6923
  "Quantity to pay for in advance": "Quantity to pay for in advance",
6921
- "Remaining balance": "Remaining balance",
6924
+ "Remaining balance after next invoice": "Remaining balance after next invoice",
6922
6925
  Remove: "Remove",
6923
6926
  "Remove add-on": "Remove add-on",
6924
6927
  Resets: "Resets {{date}}",
@@ -6993,6 +6996,14 @@ var en_default = {
6993
6996
  "X units per use": "{{amount}} {{units}} per use",
6994
6997
  "X time left in trial": "{{amount}} {{units}} left in trial",
6995
6998
  "Yearly total": "Yearly total",
6999
+ "You will be billed": "You will be billed {{price}} {{usage}}for this subscription every {{period}} {{schedule}}unless you unsubscribe.",
7000
+ "You will be billed with discount window": "You will be billed {{price}} {{usage}}for this subscription every {{period}} {{schedule}}{{window}}, then {{fullPrice}} every {{period}} afterward, unless you unsubscribe.",
7001
+ "You will be billed next bill discount": "You will be billed {{price}} {{usage}}for this subscription on your next bill, then {{fullPrice}} every {{period}} {{schedule}}afterward, unless you unsubscribe.",
7002
+ "plus usage based costs": "plus usage based costs",
7003
+ "on the day": "on the {{day}}",
7004
+ "of month": "of {{month}}",
7005
+ "for the next months_one": "for the next month",
7006
+ "for the next months_other": "for the next {{count}} months",
6996
7007
  "You will be downgraded at the end of your billing period.": "You will be downgraded to the {{plan}} plan at the end of your billing period on {{date}}.",
6997
7008
  "You will retain access to your plan until the end of the billing period, on": "You will retain access to your plan until the end of the billing period, on",
6998
7009
  "$X per unit": "{{cost}} per {{unit}}",
@@ -8673,6 +8684,20 @@ function EntitlementValueTypeFromJSONTyped(json, ignoreDiscriminator) {
8673
8684
  return json;
8674
8685
  }
8675
8686
 
8687
+ // src/api/checkoutexternal/models/WarningTier.ts
8688
+ function WarningTierFromJSON(json) {
8689
+ return WarningTierFromJSONTyped(json, false);
8690
+ }
8691
+ function WarningTierFromJSONTyped(json, ignoreDiscriminator) {
8692
+ if (json == null) {
8693
+ return json;
8694
+ }
8695
+ return {
8696
+ key: json["key"],
8697
+ value: json["value"]
8698
+ };
8699
+ }
8700
+
8676
8701
  // src/api/checkoutexternal/models/FeatureEntitlement.ts
8677
8702
  function FeatureEntitlementFromJSON(json) {
8678
8703
  return FeatureEntitlementFromJSONTyped(json, false);
@@ -8699,7 +8724,8 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
8699
8724
  monthReset: json["month_reset"] == null ? void 0 : MetricPeriodMonthResetFromJSON(json["month_reset"]),
8700
8725
  softLimit: json["soft_limit"] == null ? void 0 : json["soft_limit"],
8701
8726
  usage: json["usage"] == null ? void 0 : json["usage"],
8702
- valueType: EntitlementValueTypeFromJSON(json["value_type"])
8727
+ valueType: EntitlementValueTypeFromJSON(json["value_type"]),
8728
+ warningTiers: json["warning_tiers"] == null ? void 0 : json["warning_tiers"].map(WarningTierFromJSON)
8703
8729
  };
8704
8730
  }
8705
8731
 
@@ -9046,6 +9072,7 @@ function CompanyOverrideNoteResponseDataFromJSONTyped(json, ignoreDiscriminator)
9046
9072
  var FeatureType = {
9047
9073
  Boolean: "boolean",
9048
9074
  Event: "event",
9075
+ License: "license",
9049
9076
  Trait: "trait"
9050
9077
  };
9051
9078
  function FeatureTypeFromJSON(json) {
@@ -9078,13 +9105,15 @@ function FeatureResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9078
9105
  featureType: FeatureTypeFromJSON(json["feature_type"]),
9079
9106
  icon: json["icon"],
9080
9107
  id: json["id"],
9108
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
9081
9109
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
9082
9110
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
9083
9111
  name: json["name"],
9084
9112
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
9085
9113
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
9086
9114
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
9087
- updatedAt: new Date(json["updated_at"])
9115
+ updatedAt: new Date(json["updated_at"]),
9116
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
9088
9117
  };
9089
9118
  }
9090
9119
 
@@ -9436,6 +9465,7 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9436
9465
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON),
9437
9466
  icon: json["icon"],
9438
9467
  id: json["id"],
9468
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
9439
9469
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
9440
9470
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
9441
9471
  name: json["name"],
@@ -9444,7 +9474,8 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9444
9474
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
9445
9475
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON(json["trait"]),
9446
9476
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
9447
- updatedAt: new Date(json["updated_at"])
9477
+ updatedAt: new Date(json["updated_at"]),
9478
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
9448
9479
  };
9449
9480
  }
9450
9481
 
@@ -9521,6 +9552,20 @@ function PlanCreditGrantViewFromJSONTyped(json, ignoreDiscriminator) {
9521
9552
  };
9522
9553
  }
9523
9554
 
9555
+ // src/api/checkoutexternal/models/PlanCatalogMembershipResponseData.ts
9556
+ function PlanCatalogMembershipResponseDataFromJSON(json) {
9557
+ return PlanCatalogMembershipResponseDataFromJSONTyped(json, false);
9558
+ }
9559
+ function PlanCatalogMembershipResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9560
+ if (json == null) {
9561
+ return json;
9562
+ }
9563
+ return {
9564
+ id: json["id"],
9565
+ name: json["name"]
9566
+ };
9567
+ }
9568
+
9524
9569
  // src/api/checkoutexternal/models/PlanCurrencyPricesResponseData.ts
9525
9570
  function PlanCurrencyPricesResponseDataFromJSON(json) {
9526
9571
  return PlanCurrencyPricesResponseDataFromJSONTyped(json, false);
@@ -9677,6 +9722,9 @@ function CompanyPlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9677
9722
  ),
9678
9723
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9679
9724
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9725
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9726
+ PlanCatalogMembershipResponseDataFromJSON
9727
+ ),
9680
9728
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9681
9729
  companyCanTrial: json["company_can_trial"],
9682
9730
  companyCount: json["company_count"],
@@ -9850,6 +9898,9 @@ function PlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9850
9898
  ),
9851
9899
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9852
9900
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9901
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9902
+ PlanCatalogMembershipResponseDataFromJSON
9903
+ ),
9853
9904
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9854
9905
  companyCount: json["company_count"],
9855
9906
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -10019,6 +10070,7 @@ function ComponentResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10019
10070
  }
10020
10071
  return {
10021
10072
  ast: json["ast"] == null ? void 0 : json["ast"],
10073
+ catalogId: json["catalog_id"] == null ? void 0 : json["catalog_id"],
10022
10074
  createdAt: new Date(json["created_at"]),
10023
10075
  id: json["id"],
10024
10076
  name: json["name"],
@@ -10255,6 +10307,29 @@ function PreviewSubscriptionUpcomingInvoiceLineItemsFromJSONTyped(json, ignoreDi
10255
10307
  };
10256
10308
  }
10257
10309
 
10310
+ // src/api/checkoutexternal/models/PreviewSubscriptionDiscountResponseData.ts
10311
+ function PreviewSubscriptionDiscountResponseDataFromJSON(json) {
10312
+ return PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, false);
10313
+ }
10314
+ function PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10315
+ if (json == null) {
10316
+ return json;
10317
+ }
10318
+ return {
10319
+ amountOff: json["amount_off"] == null ? void 0 : json["amount_off"],
10320
+ couponName: json["coupon_name"],
10321
+ currency: json["currency"] == null ? void 0 : json["currency"],
10322
+ customerFacingCode: json["customer_facing_code"] == null ? void 0 : json["customer_facing_code"],
10323
+ duration: json["duration"],
10324
+ durationInMonths: json["duration_in_months"] == null ? void 0 : json["duration_in_months"],
10325
+ endedAt: json["ended_at"] == null ? void 0 : new Date(json["ended_at"]),
10326
+ isActive: json["is_active"],
10327
+ percentOff: json["percent_off"] == null ? void 0 : json["percent_off"],
10328
+ promoCodeExternalId: json["promo_code_external_id"] == null ? void 0 : json["promo_code_external_id"],
10329
+ startedAt: new Date(json["started_at"])
10330
+ };
10331
+ }
10332
+
10258
10333
  // src/api/checkoutexternal/models/PreviewSubscriptionFinanceResponseData.ts
10259
10334
  function PreviewSubscriptionFinanceResponseDataFromJSON(json) {
10260
10335
  return PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, false);
@@ -10265,6 +10340,9 @@ function PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, ignoreDiscrim
10265
10340
  }
10266
10341
  return {
10267
10342
  amountOff: json["amount_off"],
10343
+ discounts: json["discounts"].map(
10344
+ PreviewSubscriptionDiscountResponseDataFromJSON
10345
+ ),
10268
10346
  dueNow: json["due_now"],
10269
10347
  newCharges: json["new_charges"],
10270
10348
  percentOff: json["percent_off"],
@@ -11882,13 +11960,15 @@ function FeatureResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
11882
11960
  featureType: FeatureTypeFromJSON2(json["feature_type"]),
11883
11961
  icon: json["icon"],
11884
11962
  id: json["id"],
11963
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11885
11964
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11886
11965
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11887
11966
  name: json["name"],
11888
11967
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
11889
11968
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11890
11969
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11891
- updatedAt: new Date(json["updated_at"])
11970
+ updatedAt: new Date(json["updated_at"]),
11971
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11892
11972
  };
11893
11973
  }
11894
11974
 
@@ -11945,6 +12025,7 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11945
12025
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON2),
11946
12026
  icon: json["icon"],
11947
12027
  id: json["id"],
12028
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11948
12029
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11949
12030
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11950
12031
  name: json["name"],
@@ -11953,7 +12034,8 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11953
12034
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11954
12035
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON2(json["trait"]),
11955
12036
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11956
- updatedAt: new Date(json["updated_at"])
12037
+ updatedAt: new Date(json["updated_at"]),
12038
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11957
12039
  };
11958
12040
  }
11959
12041
 
@@ -12132,6 +12214,20 @@ function PlanCreditGrantViewFromJSONTyped3(json, ignoreDiscriminator) {
12132
12214
  };
12133
12215
  }
12134
12216
 
12217
+ // src/api/componentspublic/models/PlanCatalogMembershipResponseData.ts
12218
+ function PlanCatalogMembershipResponseDataFromJSON2(json) {
12219
+ return PlanCatalogMembershipResponseDataFromJSONTyped5(json, false);
12220
+ }
12221
+ function PlanCatalogMembershipResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
12222
+ if (json == null) {
12223
+ return json;
12224
+ }
12225
+ return {
12226
+ id: json["id"],
12227
+ name: json["name"]
12228
+ };
12229
+ }
12230
+
12135
12231
  // src/api/componentspublic/models/PlanCurrencyPricesResponseData.ts
12136
12232
  function PlanCurrencyPricesResponseDataFromJSON2(json) {
12137
12233
  return PlanCurrencyPricesResponseDataFromJSONTyped5(json, false);
@@ -12199,6 +12295,9 @@ function PlanViewPublicResponseDataFromJSONTyped(json, ignoreDiscriminator) {
12199
12295
  ),
12200
12296
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON2(json["billing_product"]),
12201
12297
  billingStrategy: BillingStrategyFromJSON2(json["billing_strategy"]),
12298
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
12299
+ PlanCatalogMembershipResponseDataFromJSON2
12300
+ ),
12202
12301
  chargeType: ChargeTypeFromJSON2(json["charge_type"]),
12203
12302
  companyCount: json["company_count"],
12204
12303
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -12816,7 +12915,7 @@ function getMetricPeriodName(entitlement) {
12816
12915
  const name = period ? PeriodName[period] : void 0;
12817
12916
  return name;
12818
12917
  }
12819
- function getUsageDetails(entitlement, period, currency) {
12918
+ function getUsageDetails(entitlement, period, currency, options) {
12820
12919
  const billingPrice = currency ? getEntitlementPrice(entitlement, period ?? "month", currency) : period === "year" ? entitlement.yearlyUsageBasedPrice : period === "quarter" ? entitlement.quarterlyUsageBasedPrice : period === "month" ? entitlement.monthlyUsageBasedPrice : void 0;
12821
12920
  let limit;
12822
12921
  if ((!entitlement.priceBehavior || entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance) && typeof entitlement.allocation === "number") {
@@ -12864,8 +12963,21 @@ function getUsageDetails(entitlement, period, currency) {
12864
12963
  start = end + 1;
12865
12964
  }
12866
12965
  }
12966
+ if (options?.showWarningThresholdAsLimit) {
12967
+ const warningThreshold = getEntitlementWarningThreshold(
12968
+ entitlement.planEntitlement?.warningTiers
12969
+ );
12970
+ if (typeof warningThreshold === "number") {
12971
+ limit = warningThreshold;
12972
+ }
12973
+ }
12867
12974
  return { billingPrice, limit, amount, cost, currentTier };
12868
12975
  }
12976
+ var WARNING_TIER_DEFAULT_KEY = "default";
12977
+ function getEntitlementWarningThreshold(warningTiers) {
12978
+ const tier = warningTiers?.find((t2) => t2?.key === WARNING_TIER_DEFAULT_KEY);
12979
+ return typeof tier?.value === "number" ? tier.value : void 0;
12980
+ }
12869
12981
  function getCreditBasedEntitlementLimit(entitlement, credits) {
12870
12982
  const matchedCredit = credits.find(
12871
12983
  (credit) => credit.id === entitlement.valueCredit?.id
@@ -13413,85 +13525,6 @@ function modifyDate(date, days) {
13413
13525
  return copy2;
13414
13526
  }
13415
13527
 
13416
- // src/utils/error.ts
13417
- function isError(value) {
13418
- return value instanceof Error;
13419
- }
13420
- var ERROR_UNKNOWN = new Error("An unknown error occurred.");
13421
-
13422
- // src/utils/event.ts
13423
- var createKeyboardExecutionHandler = (fn) => {
13424
- const handler = (event) => {
13425
- if (event.key === "Enter" || event.key === " ") {
13426
- event.preventDefault();
13427
- fn?.(event);
13428
- }
13429
- };
13430
- return handler;
13431
- };
13432
-
13433
- // src/utils/markdown.tsx
13434
- var import_react13 = require("react");
13435
- var import_jsx_runtime2 = require("react/jsx-runtime");
13436
- var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
13437
- var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
13438
- var isSafeUrl = (url) => {
13439
- try {
13440
- const { protocol } = new URL(url);
13441
- return protocol === "http:" || protocol === "https:";
13442
- } catch {
13443
- return false;
13444
- }
13445
- };
13446
- var renderOptInMarkdown = (text) => {
13447
- if (!text) {
13448
- return null;
13449
- }
13450
- const nodes = [];
13451
- let lastIndex = 0;
13452
- let key = 0;
13453
- TOKEN.lastIndex = 0;
13454
- let match;
13455
- while ((match = TOKEN.exec(text)) !== null) {
13456
- if (match.index > lastIndex) {
13457
- nodes.push(
13458
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react13.Fragment, { children: text.slice(lastIndex, match.index) }, key++)
13459
- );
13460
- }
13461
- const [token, link, bold, italic] = match;
13462
- if (link) {
13463
- const parts = LINK.exec(link);
13464
- if (parts && isSafeUrl(parts[2])) {
13465
- nodes.push(
13466
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
13467
- Text,
13468
- {
13469
- as: "a",
13470
- display: "link",
13471
- href: parts[2],
13472
- target: "_blank",
13473
- rel: "noopener noreferrer",
13474
- children: parts[1]
13475
- },
13476
- key++
13477
- )
13478
- );
13479
- } else {
13480
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react13.Fragment, { children: parts ? parts[1] : token }, key++));
13481
- }
13482
- } else if (bold) {
13483
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: bold.slice(2, -2) }, key++));
13484
- } else if (italic) {
13485
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: italic.slice(1, -1) }, key++));
13486
- }
13487
- lastIndex = match.index + token.length;
13488
- }
13489
- if (lastIndex < text.length) {
13490
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react13.Fragment, { children: text.slice(lastIndex) }, key));
13491
- }
13492
- return nodes;
13493
- };
13494
-
13495
13528
  // src/utils/string.ts
13496
13529
  var ZERO_DECIMAL_CURRENCIES = /* @__PURE__ */ new Set([
13497
13530
  "BIF",
@@ -13640,6 +13673,168 @@ function getCurrencySymbol(currency) {
13640
13673
  }
13641
13674
  }
13642
13675
 
13676
+ // src/utils/discount.ts
13677
+ function getSubscriptionDiscount(discounts, subscriptionTotal, subscriptionCurrency) {
13678
+ const activeDiscounts = (discounts || []).filter(
13679
+ (discount2) => discount2.isActive && (typeof discount2.percentOff === "number" && discount2.percentOff > 0 || typeof discount2.amountOff === "number" && discount2.amountOff > 0)
13680
+ );
13681
+ if (activeDiscounts.length !== 1) {
13682
+ return void 0;
13683
+ }
13684
+ const discount = activeDiscounts[0];
13685
+ const isPercentOff = typeof discount.percentOff === "number" && discount.percentOff > 0;
13686
+ if (!isPercentOff && discount.currency && subscriptionCurrency && discount.currency.toLowerCase() !== subscriptionCurrency.toLowerCase()) {
13687
+ return void 0;
13688
+ }
13689
+ const discountedTotal = isPercentOff ? subscriptionTotal * (1 - discount.percentOff / 100) : Math.max(0, subscriptionTotal - (discount.amountOff ?? 0));
13690
+ if (discountedTotal >= subscriptionTotal) {
13691
+ return void 0;
13692
+ }
13693
+ return {
13694
+ duration: discount.duration,
13695
+ durationInMonths: discount.durationInMonths ?? void 0,
13696
+ discountedPrice: formatCurrency(
13697
+ discountedTotal,
13698
+ subscriptionCurrency ?? void 0
13699
+ )
13700
+ };
13701
+ }
13702
+ function getBillingPreviewText({
13703
+ subscriptionPrice,
13704
+ planPeriod,
13705
+ periodStart,
13706
+ hasUsageBasedCosts,
13707
+ discount
13708
+ }, t2) {
13709
+ if (!subscriptionPrice) {
13710
+ return null;
13711
+ }
13712
+ const usage = hasUsageBasedCosts ? `${t2("plus usage based costs")} ` : "";
13713
+ const scheduleParts = [];
13714
+ if (periodStart) {
13715
+ scheduleParts.push(
13716
+ t2("on the day", { day: formatOrdinal(periodStart.getDate()) })
13717
+ );
13718
+ }
13719
+ if (planPeriod === "year" && periodStart) {
13720
+ scheduleParts.push(t2("of month", { month: getMonthName(periodStart) }));
13721
+ }
13722
+ const schedule = scheduleParts.length > 0 ? `${scheduleParts.join(" ")} ` : "";
13723
+ if (!discount) {
13724
+ return t2("You will be billed", {
13725
+ price: subscriptionPrice,
13726
+ usage,
13727
+ period: planPeriod,
13728
+ schedule
13729
+ });
13730
+ }
13731
+ const { duration, durationInMonths, discountedPrice } = discount;
13732
+ if (duration === "forever") {
13733
+ return t2("You will be billed", {
13734
+ price: discountedPrice,
13735
+ usage,
13736
+ period: planPeriod,
13737
+ schedule
13738
+ });
13739
+ }
13740
+ if (duration === "repeating" && durationInMonths) {
13741
+ return t2("You will be billed with discount window", {
13742
+ price: discountedPrice,
13743
+ usage,
13744
+ period: planPeriod,
13745
+ schedule,
13746
+ window: t2("for the next months", { count: durationInMonths }),
13747
+ fullPrice: subscriptionPrice
13748
+ });
13749
+ }
13750
+ return t2("You will be billed next bill discount", {
13751
+ price: discountedPrice,
13752
+ usage,
13753
+ period: planPeriod,
13754
+ schedule,
13755
+ fullPrice: subscriptionPrice
13756
+ });
13757
+ }
13758
+
13759
+ // src/utils/error.ts
13760
+ function isError(value) {
13761
+ return value instanceof Error;
13762
+ }
13763
+ var ERROR_UNKNOWN = new Error("An unknown error occurred.");
13764
+
13765
+ // src/utils/event.ts
13766
+ var createKeyboardExecutionHandler = (fn) => {
13767
+ const handler = (event) => {
13768
+ if (event.key === "Enter" || event.key === " ") {
13769
+ event.preventDefault();
13770
+ fn?.(event);
13771
+ }
13772
+ };
13773
+ return handler;
13774
+ };
13775
+
13776
+ // src/utils/markdown.tsx
13777
+ var import_react13 = require("react");
13778
+ var import_jsx_runtime2 = require("react/jsx-runtime");
13779
+ var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
13780
+ var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
13781
+ var isSafeUrl = (url) => {
13782
+ try {
13783
+ const { protocol } = new URL(url);
13784
+ return protocol === "http:" || protocol === "https:";
13785
+ } catch {
13786
+ return false;
13787
+ }
13788
+ };
13789
+ var renderOptInMarkdown = (text) => {
13790
+ if (!text) {
13791
+ return null;
13792
+ }
13793
+ const nodes = [];
13794
+ let lastIndex = 0;
13795
+ let key = 0;
13796
+ TOKEN.lastIndex = 0;
13797
+ let match;
13798
+ while ((match = TOKEN.exec(text)) !== null) {
13799
+ if (match.index > lastIndex) {
13800
+ nodes.push(
13801
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react13.Fragment, { children: text.slice(lastIndex, match.index) }, key++)
13802
+ );
13803
+ }
13804
+ const [token, link, bold, italic] = match;
13805
+ if (link) {
13806
+ const parts = LINK.exec(link);
13807
+ if (parts && isSafeUrl(parts[2])) {
13808
+ nodes.push(
13809
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
13810
+ Text,
13811
+ {
13812
+ as: "a",
13813
+ display: "link",
13814
+ href: parts[2],
13815
+ target: "_blank",
13816
+ rel: "noopener noreferrer",
13817
+ children: parts[1]
13818
+ },
13819
+ key++
13820
+ )
13821
+ );
13822
+ } else {
13823
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react13.Fragment, { children: parts ? parts[1] : token }, key++));
13824
+ }
13825
+ } else if (bold) {
13826
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: bold.slice(2, -2) }, key++));
13827
+ } else if (italic) {
13828
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: italic.slice(1, -1) }, key++));
13829
+ }
13830
+ lastIndex = match.index + token.length;
13831
+ }
13832
+ if (lastIndex < text.length) {
13833
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react13.Fragment, { children: text.slice(lastIndex) }, key));
13834
+ }
13835
+ return nodes;
13836
+ };
13837
+
13643
13838
  // src/utils/style.ts
13644
13839
  var import_styled_components2 = __toESM(require_styled_components_cjs());
13645
13840
  function attr(key, value) {
@@ -13896,7 +14091,7 @@ var reducer = (state, action) => {
13896
14091
  // src/context/EmbedProvider.tsx
13897
14092
  var import_jsx_runtime3 = require("react/jsx-runtime");
13898
14093
  var getCustomHeaders = (sessionId) => ({
13899
- "X-Schematic-Components-Version": "2.20.0",
14094
+ "X-Schematic-Components-Version": "2.21.0",
13900
14095
  "X-Schematic-Session-ID": sessionId
13901
14096
  });
13902
14097
  var normalizeCurrencyFilter = (filter) => {
@@ -13920,6 +14115,7 @@ var EmbedProvider = ({
13920
14115
  apiKey,
13921
14116
  apiConfig,
13922
14117
  currencyFilter,
14118
+ warningThresholdConfig,
13923
14119
  checkoutPrefill,
13924
14120
  ...options
13925
14121
  }) => {
@@ -13935,6 +14131,7 @@ var EmbedProvider = ({
13935
14131
  const providedState = {
13936
14132
  settings: opts.settings || {},
13937
14133
  currencyFilter: normalizeCurrencyFilter(currencyFilter),
14134
+ warningThresholdConfig,
13938
14135
  checkoutPrefill: normalizeCheckoutPrefill(checkoutPrefill)
13939
14136
  };
13940
14137
  const resolvedState = (0, import_merge2.default)({}, initialState, providedState);
@@ -14363,6 +14560,7 @@ var EmbedProvider = ({
14363
14560
  layout: state.layout,
14364
14561
  checkoutState: state.checkoutState,
14365
14562
  currencyFilter: state.currencyFilter,
14563
+ warningThresholdConfig: state.warningThresholdConfig,
14366
14564
  checkoutPrefill: state.checkoutPrefill,
14367
14565
  hydratePublic: debouncedHydratePublic,
14368
14566
  hydrate: debouncedHydrate,
@@ -16316,7 +16514,8 @@ var Entitlement = ({
16316
16514
  currency: selectedCurrency
16317
16515
  }) => {
16318
16516
  const { t: t2 } = useTranslation();
16319
- const { data, settings } = useEmbed();
16517
+ const { data, settings, warningThresholdConfig } = useEmbed();
16518
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
16320
16519
  const isLightBackground = useIsLightBackground();
16321
16520
  const showCredits = data?.displaySettings?.showCredits ?? true;
16322
16521
  const showFeatureDescription = data?.displaySettings?.showFeatureDescription ?? false;
@@ -16340,7 +16539,8 @@ var Entitlement = ({
16340
16539
  return;
16341
16540
  }
16342
16541
  const hasNumericValue = entitlement.valueType === EntitlementValueType.Numeric || entitlement.valueType === EntitlementValueType.Unlimited || entitlement.valueType === EntitlementValueType.Trait;
16343
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
16542
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
16543
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
16344
16544
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
16345
16545
  entitlement,
16346
16546
  credits
@@ -16433,7 +16633,8 @@ var Entitlement = ({
16433
16633
  currency,
16434
16634
  packageSize,
16435
16635
  tiered,
16436
- selectedCurrency
16636
+ selectedCurrency,
16637
+ showWarningThresholdAsLimit
16437
16638
  ]);
16438
16639
  const usageText = (0, import_react31.useMemo)(() => {
16439
16640
  if (!entitlement.feature) {
@@ -17164,7 +17365,8 @@ var AddOns = ({
17164
17365
  currency
17165
17366
  }) => {
17166
17367
  const { t: t2 } = useTranslation();
17167
- const { settings } = useEmbed();
17368
+ const { settings, warningThresholdConfig } = useEmbed();
17369
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
17168
17370
  const isLightBackground = useIsLightBackground();
17169
17371
  const periodKey = period === "year" ? "yearlyPrice" : period === "quarter" ? "quarterlyPrice" : "monthlyPrice";
17170
17372
  const cardPadding = settings.theme.card.padding / TEXT_BASE_SIZE;
@@ -17196,10 +17398,14 @@ var AddOns = ({
17196
17398
  period,
17197
17399
  currency
17198
17400
  );
17401
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
17199
17402
  return {
17200
17403
  isUnlimited: false,
17201
17404
  priceBehavior: entitlement.priceBehavior,
17202
17405
  softLimit: entitlement.softLimit,
17406
+ // The limit shown next to the feature: the warning threshold when
17407
+ // the option is on and one is configured, else the overage soft limit.
17408
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
17203
17409
  price: priceData?.price ?? 0,
17204
17410
  currency: priceData?.currency || addOnCurrency,
17205
17411
  featureName: entitlement.feature?.name,
@@ -17348,7 +17554,7 @@ var AddOns = ({
17348
17554
  {
17349
17555
  $flexDirection: "column",
17350
17556
  $justifyContent: "center",
17351
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Text, { children: meteredEntitlement.priceBehavior === EntitlementPriceBehavior.Overage && meteredEntitlement.softLimit ? `${meteredEntitlement.softLimit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
17557
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
17352
17558
  }
17353
17559
  )
17354
17560
  ] }),
@@ -20634,7 +20840,7 @@ var SubscriptionSidebar = (0, import_react43.forwardRef)(
20634
20840
  );
20635
20841
  return { payAsYouGoEntitlements, payInAdvanceEntitlements: payInAdvanceEntitlements2 };
20636
20842
  }, [usageBasedEntitlements]);
20637
- const subscriptionPrice = (0, import_react43.useMemo)(() => {
20843
+ const { subscriptionPrice, subscriptionTotal, subscriptionCurrency } = (0, import_react43.useMemo)(() => {
20638
20844
  let planPrice;
20639
20845
  let resolvedCurrency;
20640
20846
  if (selectedPlan) {
@@ -20670,7 +20876,11 @@ var SubscriptionSidebar = (0, import_react43.forwardRef)(
20670
20876
  0
20671
20877
  );
20672
20878
  total += addOnPayInAdvanceCost;
20673
- return formatCurrency(total, resolvedCurrency);
20879
+ return {
20880
+ subscriptionPrice: formatCurrency(total, resolvedCurrency),
20881
+ subscriptionTotal: total,
20882
+ subscriptionCurrency: resolvedCurrency
20883
+ };
20674
20884
  }, [
20675
20885
  selectedPlan,
20676
20886
  currentPlan,
@@ -20797,6 +21007,14 @@ var SubscriptionSidebar = (0, import_react43.forwardRef)(
20797
21007
  () => promoCode && (amountOff > 0 || percentOff > 0),
20798
21008
  [promoCode, amountOff, percentOff]
20799
21009
  );
21010
+ const subscriptionDiscount = (0, import_react43.useMemo)(
21011
+ () => getSubscriptionDiscount(
21012
+ charges?.discounts,
21013
+ subscriptionTotal,
21014
+ subscriptionCurrency
21015
+ ),
21016
+ [charges?.discounts, subscriptionTotal, subscriptionCurrency]
21017
+ );
20800
21018
  const handleCheckout = (0, import_react43.useCallback)(async () => {
20801
21019
  const planId = selectedPlan?.id;
20802
21020
  const currencyPrice = selectedPlan ? getPlanPrice(
@@ -21043,6 +21261,16 @@ var SubscriptionSidebar = (0, import_react43.forwardRef)(
21043
21261
  if (isSelectedPlanTrialable && selectedPlan.trialDays) {
21044
21262
  trialEndsOn.setDate(trialEndsOn.getDate() + selectedPlan.trialDays);
21045
21263
  }
21264
+ const billingPreviewText = getBillingPreviewText(
21265
+ {
21266
+ subscriptionPrice,
21267
+ planPeriod,
21268
+ periodStart: renewDate,
21269
+ hasUsageBasedCosts: usageBasedEntitlements.length > 0,
21270
+ discount: subscriptionDiscount
21271
+ },
21272
+ t2
21273
+ );
21046
21274
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
21047
21275
  Flex,
21048
21276
  {
@@ -21591,9 +21819,7 @@ var SubscriptionSidebar = (0, import_react43.forwardRef)(
21591
21819
  }
21592
21820
  )
21593
21821
  }
21594
- ) : subscriptionPrice && // TODO: localize
21595
- `You will be billed ${subscriptionPrice} ${usageBasedEntitlements.length > 0 ? "plus usage based costs" : ""} for this subscription
21596
- every ${planPeriod} ${renewDate ? `on the ${formatOrdinal(renewDate.getDate())}` : ""} ${planPeriod === "year" && renewDate ? `of ${getMonthName(renewDate)}` : ""} unless you unsubscribe.` }) })
21822
+ ) : billingPreviewText }) })
21597
21823
  ]
21598
21824
  }
21599
21825
  )
@@ -22114,7 +22340,8 @@ var UsageDetails = ({ entitlement, layout }) => {
22114
22340
  metricResetAt
22115
22341
  } = entitlement;
22116
22342
  const { t: t2 } = useTranslation();
22117
- const { data } = useEmbed();
22343
+ const { data, warningThresholdConfig } = useEmbed();
22344
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22118
22345
  const period = getSubscriptionPeriod(data?.company?.billingSubscription) ?? data?.company?.plan?.planPeriod ?? void 0;
22119
22346
  const showCredits = data?.displaySettings?.showCredits ?? true;
22120
22347
  const {
@@ -22130,7 +22357,9 @@ var UsageDetails = ({ entitlement, layout }) => {
22130
22357
  } = (0, import_react48.useMemo)(() => {
22131
22358
  const { billingPrice, amount, limit: limit2, cost: cost2, currentTier: currentTier2 } = getUsageDetails(
22132
22359
  entitlement,
22133
- period
22360
+ period,
22361
+ void 0,
22362
+ { showWarningThresholdAsLimit }
22134
22363
  );
22135
22364
  const {
22136
22365
  price: price2,
@@ -22151,7 +22380,7 @@ var UsageDetails = ({ entitlement, layout }) => {
22151
22380
  tiersMode: tiersMode2,
22152
22381
  tiered: priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(billingPrice)
22153
22382
  };
22154
- }, [entitlement, period, priceBehavior]);
22383
+ }, [entitlement, period, priceBehavior, showWarningThresholdAsLimit]);
22155
22384
  const text = (0, import_react48.useMemo)(() => {
22156
22385
  if (!feature || feature.featureType !== FeatureType.Event && feature.featureType !== FeatureType.Trait) {
22157
22386
  return;
@@ -22201,9 +22430,10 @@ var UsageDetails = ({ entitlement, layout }) => {
22201
22430
  });
22202
22431
  }
22203
22432
  if (!priceBehavior && typeof allocation === "number") {
22433
+ const numericLimit = limit ?? allocation;
22204
22434
  return t2("X units", {
22205
- amount: formatNumber(allocation),
22206
- units: getFeatureName(feature, allocation)
22435
+ amount: formatNumber(numericLimit),
22436
+ units: getFeatureName(feature, numericLimit)
22207
22437
  });
22208
22438
  }
22209
22439
  if (!priceBehavior && allocationType === "unlimited") {
@@ -22289,7 +22519,7 @@ var UsageDetails = ({ entitlement, layout }) => {
22289
22519
  if (typeof usage === "number") {
22290
22520
  return typeof allocation === "number" ? t2("usage.limited", {
22291
22521
  amount: formatNumber(usage),
22292
- allocation: formatNumber(allocation)
22522
+ allocation: formatNumber(limit ?? allocation)
22293
22523
  }) : t2("usage.unlimited", {
22294
22524
  amount: formatNumber(usage)
22295
22525
  });
@@ -22303,6 +22533,7 @@ var UsageDetails = ({ entitlement, layout }) => {
22303
22533
  priceBehavior,
22304
22534
  packageSize,
22305
22535
  allocation,
22536
+ limit,
22306
22537
  usage,
22307
22538
  metricResetAt,
22308
22539
  cost,
@@ -22734,7 +22965,12 @@ var import_react51 = require("react");
22734
22965
  var import_jsx_runtime51 = require("react/jsx-runtime");
22735
22966
  var Meter = ({ entitlement }) => {
22736
22967
  const { allocation, priceBehavior, softLimit, usage } = entitlement;
22737
- const limit = softLimit ?? allocation;
22968
+ const { warningThresholdConfig } = useEmbed();
22969
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22970
+ const warningThreshold = getEntitlementWarningThreshold(
22971
+ entitlement.planEntitlement?.warningTiers
22972
+ );
22973
+ const limit = showWarningThresholdAsLimit && typeof warningThreshold === "number" ? warningThreshold : softLimit ?? allocation;
22738
22974
  if (typeof usage !== "number" || typeof limit !== "number") {
22739
22975
  return null;
22740
22976
  }
@@ -22874,14 +23110,7 @@ var import_jsx_runtime53 = require("react/jsx-runtime");
22874
23110
  var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22875
23111
  const { t: t2 } = useTranslation();
22876
23112
  const { data } = useEmbed();
22877
- const {
22878
- feature,
22879
- planEntitlement,
22880
- priceBehavior,
22881
- allocation,
22882
- usage,
22883
- metricResetAt
22884
- } = entitlement;
23113
+ const { feature, planEntitlement, priceBehavior, usage, metricResetAt } = entitlement;
22885
23114
  const { billingPrice, limit, cost, currentTier } = usageDetails;
22886
23115
  const acc = [];
22887
23116
  acc.push(
@@ -22903,8 +23132,8 @@ var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22903
23132
  }) : priceBehavior === EntitlementPriceBehavior.CreditBurndown && typeof feature !== "undefined" && typeof limit === "number" ? t2("X units remaining", {
22904
23133
  amount: formatNumber(limit),
22905
23134
  units: getFeatureName(feature, limit)
22906
- }) : typeof allocation === "number" ? t2("Limit of", {
22907
- amount: formatNumber(allocation)
23135
+ }) : typeof limit === "number" ? t2("Limit of", {
23136
+ amount: formatNumber(limit)
22908
23137
  }) : t2("No limit")
22909
23138
  );
22910
23139
  if (metricResetAt) {
@@ -22959,7 +23188,8 @@ var MeteredFeatures = (0, import_react51.forwardRef)(({ className, ...rest }, re
22959
23188
  const elementsRef = (0, import_react51.useRef)([]);
22960
23189
  const shouldWrapChildren = useWrapChildren(elementsRef);
22961
23190
  const { t: t2 } = useTranslation();
22962
- const { data, settings, setCheckoutState } = useEmbed();
23191
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
23192
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22963
23193
  const isLightBackground = useIsLightBackground();
22964
23194
  const meteredFeatures = (0, import_react51.useMemo)(() => {
22965
23195
  const orderedFeatureUsage = props.visibleFeatures?.reduce(
@@ -23013,7 +23243,9 @@ var MeteredFeatures = (0, import_react51.forwardRef)(({ className, ...rest }, re
23013
23243
  return acc;
23014
23244
  }
23015
23245
  const { feature, priceBehavior, usage } = entitlement;
23016
- const usageDetails = getUsageDetails(entitlement, period);
23246
+ const usageDetails = getUsageDetails(entitlement, period, void 0, {
23247
+ showWarningThresholdAsLimit
23248
+ });
23017
23249
  const { limit } = usageDetails;
23018
23250
  acc.push(
23019
23251
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Element, { as: Flex, $flexDirection: "column", $gap: "1.5rem", children: [
@@ -23631,7 +23863,7 @@ var registerWrapper = function registerWrapper2(stripe, startTime) {
23631
23863
  }
23632
23864
  stripe._registerWrapper({
23633
23865
  name: "stripe-js",
23634
- version: "9.9.0",
23866
+ version: "9.12.0",
23635
23867
  startTime
23636
23868
  });
23637
23869
  };
@@ -23709,7 +23941,7 @@ var initStripe = function initStripe2(maybeStripe, args, startTime) {
23709
23941
  var version = runtimeVersionToUrlVersion(maybeStripe.version);
23710
23942
  var expectedVersion = RELEASE_TRAIN;
23711
23943
  if (isTestKey && version !== expectedVersion) {
23712
- console.warn("Stripe.js@".concat(version, " was loaded on the page, but @stripe/stripe-js@").concat("9.9.0", " expected Stripe.js@").concat(expectedVersion, ". This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning"));
23944
+ console.warn("Stripe.js@".concat(version, " was loaded on the page, but @stripe/stripe-js@").concat("9.12.0", " expected Stripe.js@").concat(expectedVersion, ". This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning"));
23713
23945
  }
23714
23946
  var stripe = maybeStripe.apply(void 0, args);
23715
23947
  registerWrapper(stripe, startTime);
@@ -24123,14 +24355,17 @@ var UsageDetails2 = ({
24123
24355
  layout
24124
24356
  }) => {
24125
24357
  const { t: t2 } = useTranslation();
24126
- const { settings } = useEmbed();
24358
+ const { settings, warningThresholdConfig } = useEmbed();
24359
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24127
24360
  const {
24128
24361
  billingPrice,
24129
24362
  limit,
24130
24363
  cost = 0
24131
24364
  } = (0, import_react55.useMemo)(
24132
- () => getUsageDetails(entitlement, period, currency),
24133
- [entitlement, period, currency]
24365
+ () => getUsageDetails(entitlement, period, currency, {
24366
+ showWarningThresholdAsLimit
24367
+ }),
24368
+ [entitlement, period, currency, showWarningThresholdAsLimit]
24134
24369
  );
24135
24370
  const description = (0, import_react55.useMemo)(() => {
24136
24371
  const acc = [];
@@ -24892,7 +25127,8 @@ var AddOn2 = ({
24892
25127
  }) => {
24893
25128
  const { layout } = sharedProps;
24894
25129
  const { t: t2 } = useTranslation();
24895
- const { data, settings, setCheckoutState } = useEmbed();
25130
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
25131
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24896
25132
  const isLightBackground = useIsLightBackground();
24897
25133
  const { currentAddOns, canCheckout, isStandalone } = (0, import_react57.useMemo)(() => {
24898
25134
  const isStandalone2 = typeof data?.component === "undefined";
@@ -24921,12 +25157,16 @@ var AddOn2 = ({
24921
25157
  selectedPeriod,
24922
25158
  currency
24923
25159
  );
25160
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
24924
25161
  return {
24925
25162
  isUnlimited: false,
24926
25163
  featureName: entitlement.feature?.name,
24927
25164
  feature: entitlement.feature,
24928
25165
  priceBehavior: entitlement.priceBehavior,
24929
25166
  softLimit: entitlement.softLimit,
25167
+ // The limit shown next to the feature: the warning threshold when the
25168
+ // option is on and one is configured, else the overage soft limit.
25169
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
24930
25170
  price: priceData?.price ?? 0,
24931
25171
  currency: priceData?.currency || addOnCurrency,
24932
25172
  packageSize: priceData?.packageSize ?? 1,
@@ -25096,7 +25336,7 @@ var AddOn2 = ({
25096
25336
  rounded: true
25097
25337
  }
25098
25338
  ),
25099
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Flex, { $flexDirection: "column", $justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Text, { children: meteredEntitlement.priceBehavior === EntitlementPriceBehavior.Overage && meteredEntitlement.softLimit ? `${meteredEntitlement.softLimit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) }) })
25339
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Flex, { $flexDirection: "column", $justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) }) })
25100
25340
  ] }),
25101
25341
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
25102
25342
  Text,
@@ -25167,7 +25407,8 @@ var Entitlement2 = ({
25167
25407
  }) => {
25168
25408
  const { layout } = sharedProps;
25169
25409
  const { t: t2 } = useTranslation();
25170
- const { settings } = useEmbed();
25410
+ const { settings, warningThresholdConfig } = useEmbed();
25411
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
25171
25412
  const isLightBackground = useIsLightBackground();
25172
25413
  const entitlementBillingPrice = getEntitlementPrice(
25173
25414
  entitlement,
@@ -25182,7 +25423,8 @@ var Entitlement2 = ({
25182
25423
  tiersMode: entitlementTiersMode
25183
25424
  } = entitlementBillingPrice || {};
25184
25425
  const tiered = entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(entitlementBillingPrice);
25185
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
25426
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
25427
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
25186
25428
  const metricPeriodName = getMetricPeriodName(entitlement);
25187
25429
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
25188
25430
  entitlement,
@@ -26072,20 +26314,27 @@ function resolveDesignProps11(props) {
26072
26314
  var UpcomingBill = (0, import_react62.forwardRef)(({ className, ...rest }, ref) => {
26073
26315
  const props = resolveDesignProps11(rest);
26074
26316
  const { t: t2 } = useTranslation();
26075
- const { data, settings, debug, getUpcomingInvoice, getCustomerBalance } = useEmbed();
26317
+ const { data, settings, getUpcomingInvoice } = useEmbed();
26076
26318
  const isLightBackground = useIsLightBackground();
26077
26319
  const [isLoading, setIsLoading] = (0, import_react62.useState)(false);
26078
26320
  const [error, setError] = (0, import_react62.useState)();
26079
26321
  const [upcomingInvoice, setUpcomingInvoice] = (0, import_react62.useState)(data?.upcomingInvoice);
26080
- const [balances, setBalances] = (0, import_react62.useState)([]);
26081
26322
  const discounts = (0, import_react62.useMemo)(() => {
26082
- return (data?.subscription?.discounts || []).map((discount) => ({
26323
+ return (data?.subscription?.discounts || []).filter(
26324
+ (discount) => (
26325
+ // Only surface discounts that are currently active and actually
26326
+ // reduce the bill; the API computes `isActive` at read time, so an
26327
+ // expired coupon must not linger in the account summary.
26328
+ discount.isActive && (typeof discount.percentOff === "number" && discount.percentOff > 0 || typeof discount.amountOff === "number" && discount.amountOff > 0)
26329
+ )
26330
+ ).map((discount) => ({
26083
26331
  couponId: discount.couponId,
26084
26332
  customerFacingCode: discount.customerFacingCode || void 0,
26085
26333
  currency: discount.currency || void 0,
26086
26334
  amountOff: discount.amountOff ?? void 0,
26087
26335
  percentOff: discount.percentOff ?? void 0,
26088
- isActive: discount.isActive
26336
+ duration: discount.duration,
26337
+ durationInMonths: discount.durationInMonths ?? void 0
26089
26338
  }));
26090
26339
  }, [data?.subscription?.discounts]);
26091
26340
  const getInvoice = (0, import_react62.useCallback)(async () => {
@@ -26104,27 +26353,30 @@ var UpcomingBill = (0, import_react62.forwardRef)(({ className, ...rest }, ref)
26104
26353
  }
26105
26354
  }
26106
26355
  }, [data?.component?.id, data?.subscription, getUpcomingInvoice]);
26107
- const getBalances = (0, import_react62.useCallback)(async () => {
26108
- try {
26109
- const response = await getCustomerBalance();
26110
- if (response) {
26111
- setBalances(response.data.balances);
26112
- }
26113
- } catch (err) {
26114
- debug("Failed to fetch customer balance.", err);
26115
- }
26116
- }, [debug, getCustomerBalance]);
26117
26356
  (0, import_react62.useEffect)(() => {
26118
26357
  getInvoice();
26119
26358
  }, [getInvoice]);
26120
- (0, import_react62.useEffect)(() => {
26121
- getBalances();
26122
- }, [getBalances]);
26123
26359
  (0, import_react62.useEffect)(() => {
26124
26360
  if (data?.upcomingInvoice) {
26125
26361
  setUpcomingInvoice(data.upcomingInvoice);
26126
26362
  }
26127
26363
  }, [data?.upcomingInvoice]);
26364
+ const { currency, applied, remaining } = (0, import_react62.useMemo)(() => {
26365
+ const currency2 = upcomingInvoice?.currency;
26366
+ const startingBalance = upcomingInvoice?.startingBalance ?? 0;
26367
+ const endingBalance = upcomingInvoice?.endingBalance ?? 0;
26368
+ const credit = Math.max(0, -startingBalance);
26369
+ const subtotal = Math.max(0, upcomingInvoice?.subtotal ?? 0);
26370
+ const applied2 = endingBalance < 0 ? credit + endingBalance : Math.min(credit, subtotal);
26371
+ return { currency: currency2, applied: applied2, remaining: credit - applied2 };
26372
+ }, [
26373
+ upcomingInvoice?.currency,
26374
+ upcomingInvoice?.startingBalance,
26375
+ upcomingInvoice?.endingBalance,
26376
+ upcomingInvoice?.subtotal
26377
+ ]);
26378
+ const hasApplied = applied > 0;
26379
+ const hasBalance = remaining > 0 || applied > 0;
26128
26380
  if (!data?.subscription || data.subscription.cancelAt) {
26129
26381
  return null;
26130
26382
  }
@@ -26174,7 +26426,7 @@ var UpcomingBill = (0, import_react62.forwardRef)(({ className, ...rest }, ref)
26174
26426
  ]
26175
26427
  }
26176
26428
  ),
26177
- balances.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26429
+ hasApplied && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26178
26430
  Flex,
26179
26431
  {
26180
26432
  as: TransitionBox,
@@ -26182,8 +26434,21 @@ var UpcomingBill = (0, import_react62.forwardRef)(({ className, ...rest }, ref)
26182
26434
  $alignItems: "start",
26183
26435
  $gap: "1rem",
26184
26436
  children: [
26185
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { $weight: 600, children: t2("Remaining balance") }),
26186
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Flex, { $flexDirection: "column", $gap: "0.5rem", children: balances.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: formatCurrency(item.balance, item.currency) }, idx)) })
26437
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { $weight: 600, children: t2("Applied balance towards next invoice") }),
26438
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: formatCurrency(-applied, currency) })
26439
+ ]
26440
+ }
26441
+ ),
26442
+ hasBalance && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26443
+ Flex,
26444
+ {
26445
+ as: TransitionBox,
26446
+ $justifyContent: "space-between",
26447
+ $alignItems: "start",
26448
+ $gap: "1rem",
26449
+ children: [
26450
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { $weight: 600, children: t2("Remaining balance after next invoice") }),
26451
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: formatCurrency(remaining, currency) })
26187
26452
  ]
26188
26453
  }
26189
26454
  ),
@@ -26201,54 +26466,50 @@ var UpcomingBill = (0, import_react62.forwardRef)(({ className, ...rest }, ref)
26201
26466
  $flexDirection: "column",
26202
26467
  $alignItems: "end",
26203
26468
  $gap: "0.5rem",
26204
- children: discounts.reduce(
26205
- (acc, discount) => {
26206
- if (typeof discount.percentOff === "number" || typeof discount.amountOff === "number") {
26207
- acc.push(
26208
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26469
+ children: discounts.map((discount) => {
26470
+ const label = typeof discount.percentOff === "number" && discount.percentOff > 0 ? t2("Percent off", {
26471
+ percent: discount.percentOff
26472
+ }) : t2("Amount off", {
26473
+ amount: formatCurrency(
26474
+ discount.amountOff,
26475
+ // active discounts always carry a positive amount or percent
26476
+ discount?.currency
26477
+ )
26478
+ });
26479
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26480
+ Flex,
26481
+ {
26482
+ $alignItems: "center",
26483
+ $gap: "0.5rem",
26484
+ children: [
26485
+ discount.customerFacingCode && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
26209
26486
  Flex,
26210
26487
  {
26211
26488
  $alignItems: "center",
26212
- $gap: "0.5rem",
26213
- children: [
26214
- discount.customerFacingCode && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
26215
- Flex,
26216
- {
26217
- $alignItems: "center",
26218
- $padding: "0.1875rem 0.375rem",
26219
- $borderWidth: "1px",
26220
- $borderStyle: "solid",
26221
- $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
26222
- $borderRadius: "0.3125rem",
26223
- children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
26224
- Text,
26225
- {
26226
- $size: 0.75 * settings.theme.typography.text.fontSize,
26227
- style: { textTransform: "uppercase" },
26228
- children: discount.customerFacingCode
26229
- }
26230
- )
26231
- }
26232
- ),
26233
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: typeof discount.percentOff === "number" ? t2("Percent off", {
26234
- percent: discount.percentOff
26235
- }) : t2("Amount off", {
26236
- amount: formatCurrency(
26237
- discount.amountOff,
26238
- // we already checked for `number` type
26239
- discount?.currency
26240
- )
26241
- }) }) })
26242
- ]
26243
- },
26244
- discount.couponId
26245
- )
26246
- );
26247
- }
26248
- return acc;
26249
- },
26250
- []
26251
- )
26489
+ $padding: "0.1875rem 0.375rem",
26490
+ $borderWidth: "1px",
26491
+ $borderStyle: "solid",
26492
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
26493
+ $borderRadius: "0.3125rem",
26494
+ children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
26495
+ Text,
26496
+ {
26497
+ $size: 0.75 * settings.theme.typography.text.fontSize,
26498
+ style: { textTransform: "uppercase" },
26499
+ children: discount.customerFacingCode
26500
+ }
26501
+ )
26502
+ }
26503
+ ),
26504
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: discount.duration === "repeating" && discount.durationInMonths ? t2("Discount for months", {
26505
+ discount: label,
26506
+ count: discount.durationInMonths
26507
+ }) : label }) })
26508
+ ]
26509
+ },
26510
+ discount.couponId
26511
+ );
26512
+ })
26252
26513
  }
26253
26514
  )
26254
26515
  ]