@schematichq/schematic-components 1.5.0 → 1.6.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.
@@ -6805,6 +6805,7 @@ var en_default = {
6805
6805
  Expired: "Expired",
6806
6806
  "Expires in X months": "Expires in {{months}} mo",
6807
6807
  Expires: "Expires {{date}}",
6808
+ Free: "Free",
6808
6809
  "Hide all": "Hide all",
6809
6810
  "Hide balance details": "Hide balance details",
6810
6811
  "Hide details": "Hide details",
@@ -7096,7 +7097,7 @@ var import_debounce = __toESM(require_debounce());
7096
7097
  var import_merge2 = __toESM(require_merge());
7097
7098
  var import_react12 = require("react");
7098
7099
 
7099
- // node_modules/uuid/dist/esm-browser/stringify.js
7100
+ // node_modules/uuid/dist-browser/stringify.js
7100
7101
  var byteToHex = [];
7101
7102
  for (let i2 = 0; i2 < 256; ++i2) {
7102
7103
  byteToHex.push((i2 + 256).toString(16).slice(1));
@@ -7105,7 +7106,7 @@ function unsafeStringify(arr, offset = 0) {
7105
7106
  return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
7106
7107
  }
7107
7108
 
7108
- // node_modules/uuid/dist/esm-browser/rng.js
7109
+ // node_modules/uuid/dist-browser/rng.js
7109
7110
  var getRandomValues;
7110
7111
  var rnds8 = new Uint8Array(16);
7111
7112
  function rng() {
@@ -7118,15 +7119,12 @@ function rng() {
7118
7119
  return getRandomValues(rnds8);
7119
7120
  }
7120
7121
 
7121
- // node_modules/uuid/dist/esm-browser/native.js
7122
+ // node_modules/uuid/dist-browser/native.js
7122
7123
  var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
7123
7124
  var native_default = { randomUUID };
7124
7125
 
7125
- // node_modules/uuid/dist/esm-browser/v4.js
7126
- function v4(options, buf, offset) {
7127
- if (native_default.randomUUID && !buf && !options) {
7128
- return native_default.randomUUID();
7129
- }
7126
+ // node_modules/uuid/dist-browser/v4.js
7127
+ function _v4(options, buf, offset) {
7130
7128
  options = options || {};
7131
7129
  const rnds = options.random ?? options.rng?.() ?? rng();
7132
7130
  if (rnds.length < 16) {
@@ -7146,6 +7144,12 @@ function v4(options, buf, offset) {
7146
7144
  }
7147
7145
  return unsafeStringify(rnds);
7148
7146
  }
7147
+ function v4(options, buf, offset) {
7148
+ if (native_default.randomUUID && !buf && !options) {
7149
+ return native_default.randomUUID();
7150
+ }
7151
+ return _v4(options, buf, offset);
7152
+ }
7149
7153
  var v4_default = v4;
7150
7154
 
7151
7155
  // src/api/checkoutexternal/runtime.ts
@@ -8804,6 +8808,7 @@ function ComponentHydrateResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8804
8808
  defaultPlan: json["default_plan"] == null ? void 0 : PlanDetailResponseDataFromJSON(json["default_plan"]),
8805
8809
  featureUsage: json["feature_usage"] == null ? void 0 : FeatureUsageDetailResponseDataFromJSON(json["feature_usage"]),
8806
8810
  showPeriodToggle: json["show_period_toggle"],
8811
+ showZeroPriceAsFree: json["show_zero_price_as_free"],
8807
8812
  stripeEmbed: json["stripe_embed"] == null ? void 0 : StripeEmbedInfoFromJSON(json["stripe_embed"]),
8808
8813
  subscription: json["subscription"] == null ? void 0 : CompanySubscriptionResponseDataFromJSON(json["subscription"]),
8809
8814
  trialPaymentMethodRequired: json["trial_payment_method_required"] == null ? void 0 : json["trial_payment_method_required"],
@@ -10356,7 +10361,8 @@ function PublicPlansResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10356
10361
  CompatiblePlansFromJSON2
10357
10362
  ),
10358
10363
  capabilities: json["capabilities"] == null ? void 0 : ComponentCapabilitiesFromJSON2(json["capabilities"]),
10359
- showPeriodToggle: json["show_period_toggle"]
10364
+ showPeriodToggle: json["show_period_toggle"],
10365
+ showZeroPriceAsFree: json["show_zero_price_as_free"]
10360
10366
  };
10361
10367
  }
10362
10368
 
@@ -10554,7 +10560,7 @@ var EmbedProvider = ({
10554
10560
  });
10555
10561
  const customHeaders = (0, import_react12.useMemo)(
10556
10562
  () => ({
10557
- "X-Schematic-Components-Version": "1.5.0",
10563
+ "X-Schematic-Components-Version": "1.6.0",
10558
10564
  "X-Schematic-Session-ID": sessionIdRef.current
10559
10565
  }),
10560
10566
  []
@@ -12779,6 +12785,10 @@ var Sidebar = ({
12779
12785
  () => creditBundles.filter((bundle) => bundle.count > 0),
12780
12786
  [creditBundles]
12781
12787
  );
12788
+ const discountApplied = (0, import_react27.useMemo)(
12789
+ () => promoCode && (amountOff > 0 || percentOff > 0),
12790
+ [promoCode, amountOff, percentOff]
12791
+ );
12782
12792
  const handleCheckout = (0, import_react27.useCallback)(async () => {
12783
12793
  const planId = selectedPlan?.id;
12784
12794
  const priceId = (planPeriod === "year" ? selectedPlan?.yearlyPrice : selectedPlan?.monthlyPrice)?.id;
@@ -12845,7 +12855,7 @@ var Sidebar = ({
12845
12855
  },
12846
12856
  []
12847
12857
  ),
12848
- skipTrial: !willTrialWithoutPaymentMethod,
12858
+ skipTrial: !shouldTrial,
12849
12859
  ...paymentMethodId && { paymentMethodId },
12850
12860
  ...promoCode && { promoCode }
12851
12861
  });
@@ -12871,7 +12881,7 @@ var Sidebar = ({
12871
12881
  setLayout,
12872
12882
  payInAdvanceEntitlements,
12873
12883
  addOnUsageBasedEntitlements,
12874
- willTrialWithoutPaymentMethod,
12884
+ shouldTrial,
12875
12885
  promoCode
12876
12886
  ]);
12877
12887
  const handleUnsubscribe = (0, import_react27.useCallback)(async () => {
@@ -13248,7 +13258,7 @@ var Sidebar = ({
13248
13258
  $width: "100%",
13249
13259
  $padding: "1.5rem",
13250
13260
  children: [
13251
- promoCode && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
13261
+ discountApplied && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
13252
13262
  Flex,
13253
13263
  {
13254
13264
  $justifyContent: "space-between",
@@ -13920,10 +13930,18 @@ var Plan = ({
13920
13930
  const [entitlementCounts, setEntitlementCounts] = (0, import_react29.useState)(
13921
13931
  () => plans.reduce(entitlementCountsReducer, {})
13922
13932
  );
13923
- const isTrialing = (0, import_react29.useMemo)(
13924
- () => isCheckoutData(data) && data.subscription?.status === "trialing",
13925
- [data]
13926
- );
13933
+ const { isTrialing, showZeroPriceAsFree } = (0, import_react29.useMemo)(() => {
13934
+ if (isCheckoutData(data)) {
13935
+ return {
13936
+ isTrialing: data.subscription?.status === "trialing",
13937
+ showZeroPriceAsFree: data.showZeroPriceAsFree
13938
+ };
13939
+ }
13940
+ return {
13941
+ isTrialing: false,
13942
+ showZeroPriceAsFree: false
13943
+ };
13944
+ }, [data]);
13927
13945
  const handleToggleShowAll = (id) => {
13928
13946
  setEntitlementCounts((prev2) => {
13929
13947
  const count = prev2[id] ? { ...prev2[id] } : void 0;
@@ -13957,7 +13975,8 @@ var Plan = ({
13957
13975
  const hasUsageBasedEntitlements = plan.entitlements.some(
13958
13976
  (entitlement) => !!entitlement.priceBehavior
13959
13977
  );
13960
- const isUsageBasedPlan = planPrice === 0 && hasUsageBasedEntitlements;
13978
+ const isFreePlan = planPrice === 0;
13979
+ const isUsageBasedPlan = isFreePlan && hasUsageBasedEntitlements;
13961
13980
  const headerPriceFontStyle = settings.theme.typography.heading2;
13962
13981
  const count = entitlementCounts[plan.id];
13963
13982
  const isExpanded = count && count.limit > VISIBLE_ENTITLEMENT_COUNT;
@@ -14002,10 +14021,10 @@ var Plan = ({
14002
14021
  $size: headerPriceFontStyle.fontSize,
14003
14022
  $weight: headerPriceFontStyle.fontWeight,
14004
14023
  $color: headerPriceFontStyle.color,
14005
- children: plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : formatCurrency(planPrice ?? 0, planCurrency)
14024
+ children: plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : isFreePlan && showZeroPriceAsFree ? t2("Free") : formatCurrency(planPrice ?? 0, planCurrency)
14006
14025
  }
14007
14026
  ),
14008
- !plan.custom && !isUsageBasedPlan && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
14027
+ !plan.custom && !isFreePlan && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
14009
14028
  Text,
14010
14029
  {
14011
14030
  display: "heading2",
@@ -16826,7 +16845,7 @@ var MeteredFeatures = (0, import_react43.forwardRef)(({ className, ...rest }, re
16826
16845
  )
16827
16846
  );
16828
16847
  }, []);
16829
- const shouldShowFeatures = meteredFeatures.length > 0;
16848
+ const shouldShowFeatures = meteredFeatures.length > 0 || creditGroups.length > 0;
16830
16849
  if (!shouldShowFeatures) {
16831
16850
  return null;
16832
16851
  }
@@ -17981,6 +18000,7 @@ var PlanManager = (0, import_react48.forwardRef)(({ children, className, portal,
17981
18000
  canCheckout,
17982
18001
  defaultPlan,
17983
18002
  featureUsage,
18003
+ showZeroPriceAsFree,
17984
18004
  trialPaymentMethodRequired
17985
18005
  } = (0, import_react48.useMemo)(() => {
17986
18006
  if (isCheckoutData(data)) {
@@ -17991,6 +18011,7 @@ var PlanManager = (0, import_react48.forwardRef)(({ children, className, portal,
17991
18011
  capabilities,
17992
18012
  defaultPlan: defaultPlan2,
17993
18013
  featureUsage: featureUsage2,
18014
+ showZeroPriceAsFree: showZeroPriceAsFree2,
17994
18015
  trialPaymentMethodRequired: trialPaymentMethodRequired2
17995
18016
  } = data;
17996
18017
  const creditGroups2 = groupCreditGrants(creditGrants, {
@@ -18020,6 +18041,7 @@ var PlanManager = (0, import_react48.forwardRef)(({ children, className, portal,
18020
18041
  canCheckout: capabilities?.checkout ?? true,
18021
18042
  defaultPlan: defaultPlan2,
18022
18043
  featureUsage: featureUsage2?.features || [],
18044
+ showZeroPriceAsFree: showZeroPriceAsFree2,
18023
18045
  trialPaymentMethodRequired: trialPaymentMethodRequired2
18024
18046
  };
18025
18047
  }
@@ -18032,6 +18054,7 @@ var PlanManager = (0, import_react48.forwardRef)(({ children, className, portal,
18032
18054
  canCheckout: false,
18033
18055
  defaultPlan: void 0,
18034
18056
  featureUsage: [],
18057
+ showZeroPriceAsFree: false,
18035
18058
  trialPaymentMethodRequired: false
18036
18059
  };
18037
18060
  }, [data]);
@@ -18056,7 +18079,8 @@ var PlanManager = (0, import_react48.forwardRef)(({ children, className, portal,
18056
18079
  willSubscriptionCancel: willSubscriptionCancel2
18057
18080
  };
18058
18081
  }, [billingSubscription]);
18059
- const isUsageBasedPlan = currentPlan?.planPrice === 0 && usageBasedEntitlements.length > 0;
18082
+ const isFreePlan = currentPlan?.planPrice === 0;
18083
+ const isUsageBasedPlan = isFreePlan && usageBasedEntitlements.length > 0;
18060
18084
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
18061
18085
  isTrialSubscription && !willSubscriptionCancel ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
18062
18086
  Notice,
@@ -18130,13 +18154,13 @@ var PlanManager = (0, import_react48.forwardRef)(({ children, className, portal,
18130
18154
  Text,
18131
18155
  {
18132
18156
  display: isUsageBasedPlan ? "heading3" : props.header.price.fontStyle,
18133
- children: isUsageBasedPlan ? t2("Usage-based") : formatCurrency(
18157
+ children: isUsageBasedPlan ? t2("Usage-based") : isFreePlan && showZeroPriceAsFree ? t2("Free") : formatCurrency(
18134
18158
  currentPlan.planPrice,
18135
18159
  subscriptionCurrency
18136
18160
  )
18137
18161
  }
18138
18162
  ),
18139
- !isUsageBasedPlan && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { display: props.header.price.fontStyle, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("sub", { children: [
18163
+ !isFreePlan && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { display: props.header.price.fontStyle, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("sub", { children: [
18140
18164
  "/",
18141
18165
  shortenPeriod(currentPlan.planPeriod)
18142
18166
  ] }) })
@@ -18695,7 +18719,8 @@ var Plan2 = ({
18695
18719
  isTrialSubscription,
18696
18720
  willSubscriptionCancel,
18697
18721
  isStandalone,
18698
- showCallToAction
18722
+ showCallToAction,
18723
+ showZeroPriceAsFree
18699
18724
  } = (0, import_react50.useMemo)(() => {
18700
18725
  if (isCheckoutData(data)) {
18701
18726
  const billingSubscription = data.company?.billingSubscription;
@@ -18707,7 +18732,8 @@ var Plan2 = ({
18707
18732
  isTrialSubscription: isTrialSubscription2,
18708
18733
  willSubscriptionCancel: willSubscriptionCancel2,
18709
18734
  isStandalone: false,
18710
- showCallToAction: true
18735
+ showCallToAction: true,
18736
+ showZeroPriceAsFree: data.showZeroPriceAsFree
18711
18737
  };
18712
18738
  }
18713
18739
  return {
@@ -18716,7 +18742,8 @@ var Plan2 = ({
18716
18742
  isTrialSubscription: false,
18717
18743
  willSubscriptionCancel: false,
18718
18744
  isStandalone: true,
18719
- showCallToAction: typeof sharedProps.callToActionUrl === "string" || typeof sharedProps.onCallToAction === "function"
18745
+ showCallToAction: typeof sharedProps.callToActionUrl === "string" || typeof sharedProps.onCallToAction === "function",
18746
+ showZeroPriceAsFree: false
18720
18747
  };
18721
18748
  }, [data, sharedProps.callToActionUrl, sharedProps.onCallToAction]);
18722
18749
  const callToActionTarget = (0, import_react50.useMemo)(() => {
@@ -18744,7 +18771,8 @@ var Plan2 = ({
18744
18771
  const hasUsageBasedEntitlements = plan.entitlements.some(
18745
18772
  (entitlement) => !!entitlement.priceBehavior
18746
18773
  );
18747
- const isUsageBasedPlan = planPrice === 0 && hasUsageBasedEntitlements;
18774
+ const isFreePlan = planPrice === 0;
18775
+ const isUsageBasedPlan = isFreePlan && hasUsageBasedEntitlements;
18748
18776
  const headerPriceFontStyle = settings.theme.typography[layout.plans.name.fontStyle];
18749
18777
  const count = entitlementCounts[plan.id];
18750
18778
  const isExpanded = count && count.limit > VISIBLE_ENTITLEMENT_COUNT;
@@ -18786,8 +18814,8 @@ var Plan2 = ({
18786
18814
  $weight: headerPriceFontStyle.fontWeight,
18787
18815
  $color: headerPriceFontStyle.color,
18788
18816
  children: [
18789
- plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : formatCurrency(planPrice ?? 0, planCurrency),
18790
- !plan.custom && !isUsageBasedPlan && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("sub", { children: [
18817
+ plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : isFreePlan && showZeroPriceAsFree ? t2("Free") : formatCurrency(planPrice ?? 0, planCurrency),
18818
+ !plan.custom && !isFreePlan && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("sub", { children: [
18791
18819
  "/",
18792
18820
  selectedPeriod
18793
18821
  ] })
@@ -2909,6 +2909,12 @@ declare interface ComponentHydrateResponseData {
2909
2909
  * @memberof ComponentHydrateResponseData
2910
2910
  */
2911
2911
  showPeriodToggle: boolean;
2912
+ /**
2913
+ *
2914
+ * @type {boolean}
2915
+ * @memberof ComponentHydrateResponseData
2916
+ */
2917
+ showZeroPriceAsFree: boolean;
2912
2918
  /**
2913
2919
  *
2914
2920
  * @type {StripeEmbedInfo}
@@ -6854,6 +6860,12 @@ declare interface PublicPlansResponseData {
6854
6860
  * @memberof PublicPlansResponseData
6855
6861
  */
6856
6862
  showPeriodToggle: boolean;
6863
+ /**
6864
+ *
6865
+ * @type {boolean}
6866
+ * @memberof PublicPlansResponseData
6867
+ */
6868
+ showZeroPriceAsFree: boolean;
6857
6869
  }
6858
6870
 
6859
6871
  declare interface RequestContext {
@@ -6739,6 +6739,7 @@ var en_default = {
6739
6739
  Expired: "Expired",
6740
6740
  "Expires in X months": "Expires in {{months}} mo",
6741
6741
  Expires: "Expires {{date}}",
6742
+ Free: "Free",
6742
6743
  "Hide all": "Hide all",
6743
6744
  "Hide balance details": "Hide balance details",
6744
6745
  "Hide details": "Hide details",
@@ -7037,7 +7038,7 @@ import {
7037
7038
  useState as useState2
7038
7039
  } from "react";
7039
7040
 
7040
- // node_modules/uuid/dist/esm-browser/stringify.js
7041
+ // node_modules/uuid/dist-browser/stringify.js
7041
7042
  var byteToHex = [];
7042
7043
  for (let i2 = 0; i2 < 256; ++i2) {
7043
7044
  byteToHex.push((i2 + 256).toString(16).slice(1));
@@ -7046,7 +7047,7 @@ function unsafeStringify(arr, offset = 0) {
7046
7047
  return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
7047
7048
  }
7048
7049
 
7049
- // node_modules/uuid/dist/esm-browser/rng.js
7050
+ // node_modules/uuid/dist-browser/rng.js
7050
7051
  var getRandomValues;
7051
7052
  var rnds8 = new Uint8Array(16);
7052
7053
  function rng() {
@@ -7059,15 +7060,12 @@ function rng() {
7059
7060
  return getRandomValues(rnds8);
7060
7061
  }
7061
7062
 
7062
- // node_modules/uuid/dist/esm-browser/native.js
7063
+ // node_modules/uuid/dist-browser/native.js
7063
7064
  var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
7064
7065
  var native_default = { randomUUID };
7065
7066
 
7066
- // node_modules/uuid/dist/esm-browser/v4.js
7067
- function v4(options, buf, offset) {
7068
- if (native_default.randomUUID && !buf && !options) {
7069
- return native_default.randomUUID();
7070
- }
7067
+ // node_modules/uuid/dist-browser/v4.js
7068
+ function _v4(options, buf, offset) {
7071
7069
  options = options || {};
7072
7070
  const rnds = options.random ?? options.rng?.() ?? rng();
7073
7071
  if (rnds.length < 16) {
@@ -7087,6 +7085,12 @@ function v4(options, buf, offset) {
7087
7085
  }
7088
7086
  return unsafeStringify(rnds);
7089
7087
  }
7088
+ function v4(options, buf, offset) {
7089
+ if (native_default.randomUUID && !buf && !options) {
7090
+ return native_default.randomUUID();
7091
+ }
7092
+ return _v4(options, buf, offset);
7093
+ }
7090
7094
  var v4_default = v4;
7091
7095
 
7092
7096
  // src/api/checkoutexternal/runtime.ts
@@ -8745,6 +8749,7 @@ function ComponentHydrateResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8745
8749
  defaultPlan: json["default_plan"] == null ? void 0 : PlanDetailResponseDataFromJSON(json["default_plan"]),
8746
8750
  featureUsage: json["feature_usage"] == null ? void 0 : FeatureUsageDetailResponseDataFromJSON(json["feature_usage"]),
8747
8751
  showPeriodToggle: json["show_period_toggle"],
8752
+ showZeroPriceAsFree: json["show_zero_price_as_free"],
8748
8753
  stripeEmbed: json["stripe_embed"] == null ? void 0 : StripeEmbedInfoFromJSON(json["stripe_embed"]),
8749
8754
  subscription: json["subscription"] == null ? void 0 : CompanySubscriptionResponseDataFromJSON(json["subscription"]),
8750
8755
  trialPaymentMethodRequired: json["trial_payment_method_required"] == null ? void 0 : json["trial_payment_method_required"],
@@ -10297,7 +10302,8 @@ function PublicPlansResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10297
10302
  CompatiblePlansFromJSON2
10298
10303
  ),
10299
10304
  capabilities: json["capabilities"] == null ? void 0 : ComponentCapabilitiesFromJSON2(json["capabilities"]),
10300
- showPeriodToggle: json["show_period_toggle"]
10305
+ showPeriodToggle: json["show_period_toggle"],
10306
+ showZeroPriceAsFree: json["show_zero_price_as_free"]
10301
10307
  };
10302
10308
  }
10303
10309
 
@@ -10495,7 +10501,7 @@ var EmbedProvider = ({
10495
10501
  });
10496
10502
  const customHeaders = useMemo3(
10497
10503
  () => ({
10498
- "X-Schematic-Components-Version": "1.5.0",
10504
+ "X-Schematic-Components-Version": "1.6.0",
10499
10505
  "X-Schematic-Session-ID": sessionIdRef.current
10500
10506
  }),
10501
10507
  []
@@ -12730,6 +12736,10 @@ var Sidebar = ({
12730
12736
  () => creditBundles.filter((bundle) => bundle.count > 0),
12731
12737
  [creditBundles]
12732
12738
  );
12739
+ const discountApplied = useMemo7(
12740
+ () => promoCode && (amountOff > 0 || percentOff > 0),
12741
+ [promoCode, amountOff, percentOff]
12742
+ );
12733
12743
  const handleCheckout = useCallback8(async () => {
12734
12744
  const planId = selectedPlan?.id;
12735
12745
  const priceId = (planPeriod === "year" ? selectedPlan?.yearlyPrice : selectedPlan?.monthlyPrice)?.id;
@@ -12796,7 +12806,7 @@ var Sidebar = ({
12796
12806
  },
12797
12807
  []
12798
12808
  ),
12799
- skipTrial: !willTrialWithoutPaymentMethod,
12809
+ skipTrial: !shouldTrial,
12800
12810
  ...paymentMethodId && { paymentMethodId },
12801
12811
  ...promoCode && { promoCode }
12802
12812
  });
@@ -12822,7 +12832,7 @@ var Sidebar = ({
12822
12832
  setLayout,
12823
12833
  payInAdvanceEntitlements,
12824
12834
  addOnUsageBasedEntitlements,
12825
- willTrialWithoutPaymentMethod,
12835
+ shouldTrial,
12826
12836
  promoCode
12827
12837
  ]);
12828
12838
  const handleUnsubscribe = useCallback8(async () => {
@@ -13199,7 +13209,7 @@ var Sidebar = ({
13199
13209
  $width: "100%",
13200
13210
  $padding: "1.5rem",
13201
13211
  children: [
13202
- promoCode && /* @__PURE__ */ jsxs9(
13212
+ discountApplied && /* @__PURE__ */ jsxs9(
13203
13213
  Flex,
13204
13214
  {
13205
13215
  $justifyContent: "space-between",
@@ -13871,10 +13881,18 @@ var Plan = ({
13871
13881
  const [entitlementCounts, setEntitlementCounts] = useState8(
13872
13882
  () => plans.reduce(entitlementCountsReducer, {})
13873
13883
  );
13874
- const isTrialing = useMemo8(
13875
- () => isCheckoutData(data) && data.subscription?.status === "trialing",
13876
- [data]
13877
- );
13884
+ const { isTrialing, showZeroPriceAsFree } = useMemo8(() => {
13885
+ if (isCheckoutData(data)) {
13886
+ return {
13887
+ isTrialing: data.subscription?.status === "trialing",
13888
+ showZeroPriceAsFree: data.showZeroPriceAsFree
13889
+ };
13890
+ }
13891
+ return {
13892
+ isTrialing: false,
13893
+ showZeroPriceAsFree: false
13894
+ };
13895
+ }, [data]);
13878
13896
  const handleToggleShowAll = (id) => {
13879
13897
  setEntitlementCounts((prev2) => {
13880
13898
  const count = prev2[id] ? { ...prev2[id] } : void 0;
@@ -13908,7 +13926,8 @@ var Plan = ({
13908
13926
  const hasUsageBasedEntitlements = plan.entitlements.some(
13909
13927
  (entitlement) => !!entitlement.priceBehavior
13910
13928
  );
13911
- const isUsageBasedPlan = planPrice === 0 && hasUsageBasedEntitlements;
13929
+ const isFreePlan = planPrice === 0;
13930
+ const isUsageBasedPlan = isFreePlan && hasUsageBasedEntitlements;
13912
13931
  const headerPriceFontStyle = settings.theme.typography.heading2;
13913
13932
  const count = entitlementCounts[plan.id];
13914
13933
  const isExpanded = count && count.limit > VISIBLE_ENTITLEMENT_COUNT;
@@ -13953,10 +13972,10 @@ var Plan = ({
13953
13972
  $size: headerPriceFontStyle.fontSize,
13954
13973
  $weight: headerPriceFontStyle.fontWeight,
13955
13974
  $color: headerPriceFontStyle.color,
13956
- children: plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : formatCurrency(planPrice ?? 0, planCurrency)
13975
+ children: plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : isFreePlan && showZeroPriceAsFree ? t2("Free") : formatCurrency(planPrice ?? 0, planCurrency)
13957
13976
  }
13958
13977
  ),
13959
- !plan.custom && !isUsageBasedPlan && /* @__PURE__ */ jsxs14(
13978
+ !plan.custom && !isFreePlan && /* @__PURE__ */ jsxs14(
13960
13979
  Text,
13961
13980
  {
13962
13981
  display: "heading2",
@@ -16782,7 +16801,7 @@ var MeteredFeatures = forwardRef9(({ className, ...rest }, ref) => {
16782
16801
  )
16783
16802
  );
16784
16803
  }, []);
16785
- const shouldShowFeatures = meteredFeatures.length > 0;
16804
+ const shouldShowFeatures = meteredFeatures.length > 0 || creditGroups.length > 0;
16786
16805
  if (!shouldShowFeatures) {
16787
16806
  return null;
16788
16807
  }
@@ -17937,6 +17956,7 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
17937
17956
  canCheckout,
17938
17957
  defaultPlan,
17939
17958
  featureUsage,
17959
+ showZeroPriceAsFree,
17940
17960
  trialPaymentMethodRequired
17941
17961
  } = useMemo23(() => {
17942
17962
  if (isCheckoutData(data)) {
@@ -17947,6 +17967,7 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
17947
17967
  capabilities,
17948
17968
  defaultPlan: defaultPlan2,
17949
17969
  featureUsage: featureUsage2,
17970
+ showZeroPriceAsFree: showZeroPriceAsFree2,
17950
17971
  trialPaymentMethodRequired: trialPaymentMethodRequired2
17951
17972
  } = data;
17952
17973
  const creditGroups2 = groupCreditGrants(creditGrants, {
@@ -17976,6 +17997,7 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
17976
17997
  canCheckout: capabilities?.checkout ?? true,
17977
17998
  defaultPlan: defaultPlan2,
17978
17999
  featureUsage: featureUsage2?.features || [],
18000
+ showZeroPriceAsFree: showZeroPriceAsFree2,
17979
18001
  trialPaymentMethodRequired: trialPaymentMethodRequired2
17980
18002
  };
17981
18003
  }
@@ -17988,6 +18010,7 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
17988
18010
  canCheckout: false,
17989
18011
  defaultPlan: void 0,
17990
18012
  featureUsage: [],
18013
+ showZeroPriceAsFree: false,
17991
18014
  trialPaymentMethodRequired: false
17992
18015
  };
17993
18016
  }, [data]);
@@ -18012,7 +18035,8 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
18012
18035
  willSubscriptionCancel: willSubscriptionCancel2
18013
18036
  };
18014
18037
  }, [billingSubscription]);
18015
- const isUsageBasedPlan = currentPlan?.planPrice === 0 && usageBasedEntitlements.length > 0;
18038
+ const isFreePlan = currentPlan?.planPrice === 0;
18039
+ const isUsageBasedPlan = isFreePlan && usageBasedEntitlements.length > 0;
18016
18040
  return /* @__PURE__ */ jsxs34(Fragment20, { children: [
18017
18041
  isTrialSubscription && !willSubscriptionCancel ? /* @__PURE__ */ jsxs34(
18018
18042
  Notice,
@@ -18086,13 +18110,13 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
18086
18110
  Text,
18087
18111
  {
18088
18112
  display: isUsageBasedPlan ? "heading3" : props.header.price.fontStyle,
18089
- children: isUsageBasedPlan ? t2("Usage-based") : formatCurrency(
18113
+ children: isUsageBasedPlan ? t2("Usage-based") : isFreePlan && showZeroPriceAsFree ? t2("Free") : formatCurrency(
18090
18114
  currentPlan.planPrice,
18091
18115
  subscriptionCurrency
18092
18116
  )
18093
18117
  }
18094
18118
  ),
18095
- !isUsageBasedPlan && /* @__PURE__ */ jsx43(Text, { display: props.header.price.fontStyle, children: /* @__PURE__ */ jsxs34("sub", { children: [
18119
+ !isFreePlan && /* @__PURE__ */ jsx43(Text, { display: props.header.price.fontStyle, children: /* @__PURE__ */ jsxs34("sub", { children: [
18096
18120
  "/",
18097
18121
  shortenPeriod(currentPlan.planPeriod)
18098
18122
  ] }) })
@@ -18657,7 +18681,8 @@ var Plan2 = ({
18657
18681
  isTrialSubscription,
18658
18682
  willSubscriptionCancel,
18659
18683
  isStandalone,
18660
- showCallToAction
18684
+ showCallToAction,
18685
+ showZeroPriceAsFree
18661
18686
  } = useMemo25(() => {
18662
18687
  if (isCheckoutData(data)) {
18663
18688
  const billingSubscription = data.company?.billingSubscription;
@@ -18669,7 +18694,8 @@ var Plan2 = ({
18669
18694
  isTrialSubscription: isTrialSubscription2,
18670
18695
  willSubscriptionCancel: willSubscriptionCancel2,
18671
18696
  isStandalone: false,
18672
- showCallToAction: true
18697
+ showCallToAction: true,
18698
+ showZeroPriceAsFree: data.showZeroPriceAsFree
18673
18699
  };
18674
18700
  }
18675
18701
  return {
@@ -18678,7 +18704,8 @@ var Plan2 = ({
18678
18704
  isTrialSubscription: false,
18679
18705
  willSubscriptionCancel: false,
18680
18706
  isStandalone: true,
18681
- showCallToAction: typeof sharedProps.callToActionUrl === "string" || typeof sharedProps.onCallToAction === "function"
18707
+ showCallToAction: typeof sharedProps.callToActionUrl === "string" || typeof sharedProps.onCallToAction === "function",
18708
+ showZeroPriceAsFree: false
18682
18709
  };
18683
18710
  }, [data, sharedProps.callToActionUrl, sharedProps.onCallToAction]);
18684
18711
  const callToActionTarget = useMemo25(() => {
@@ -18706,7 +18733,8 @@ var Plan2 = ({
18706
18733
  const hasUsageBasedEntitlements = plan.entitlements.some(
18707
18734
  (entitlement) => !!entitlement.priceBehavior
18708
18735
  );
18709
- const isUsageBasedPlan = planPrice === 0 && hasUsageBasedEntitlements;
18736
+ const isFreePlan = planPrice === 0;
18737
+ const isUsageBasedPlan = isFreePlan && hasUsageBasedEntitlements;
18710
18738
  const headerPriceFontStyle = settings.theme.typography[layout.plans.name.fontStyle];
18711
18739
  const count = entitlementCounts[plan.id];
18712
18740
  const isExpanded = count && count.limit > VISIBLE_ENTITLEMENT_COUNT;
@@ -18748,8 +18776,8 @@ var Plan2 = ({
18748
18776
  $weight: headerPriceFontStyle.fontWeight,
18749
18777
  $color: headerPriceFontStyle.color,
18750
18778
  children: [
18751
- plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : formatCurrency(planPrice ?? 0, planCurrency),
18752
- !plan.custom && !isUsageBasedPlan && /* @__PURE__ */ jsxs37("sub", { children: [
18779
+ plan.custom ? plan.customPlanConfig?.priceText ? plan.customPlanConfig.priceText : t2("Custom price") : isUsageBasedPlan ? t2("Usage-based") : isFreePlan && showZeroPriceAsFree ? t2("Free") : formatCurrency(planPrice ?? 0, planCurrency),
18780
+ !plan.custom && !isFreePlan && /* @__PURE__ */ jsxs37("sub", { children: [
18753
18781
  "/",
18754
18782
  selectedPeriod
18755
18783
  ] })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-components",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "main": "dist/schematic-components.cjs.js",
5
5
  "module": "dist/schematic-components.esm.js",
6
6
  "types": "dist/schematic-components.d.ts",
@@ -34,15 +34,15 @@
34
34
  "dependencies": {
35
35
  "@schematichq/schematic-icons": "^0.5.2",
36
36
  "@stripe/stripe-js": "^7.9.0",
37
- "i18next": "^25.5.0",
37
+ "i18next": "^25.5.2",
38
38
  "lodash": "^4.17.21",
39
39
  "pako": "^2.1.0",
40
40
  "react-i18next": "^15.7.3",
41
41
  "styled-components": "^6.1.19",
42
- "uuid": "^11.1.0"
42
+ "uuid": "^12.0.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@eslint/js": "^9.34.0",
45
+ "@eslint/js": "^9.35.0",
46
46
  "@eslint/json": "^0.13.2",
47
47
  "@eslint/markdown": "^7.2.0",
48
48
  "@microsoft/api-extractor": "^7.52.11",
@@ -54,7 +54,7 @@
54
54
  "@types/react": "^19.1.12",
55
55
  "@types/react-dom": "^19.1.9",
56
56
  "esbuild": "^0.25.9",
57
- "eslint": "^9.34.0",
57
+ "eslint": "^9.35.0",
58
58
  "eslint-import-resolver-typescript": "^4.4.4",
59
59
  "eslint-plugin-import": "^2.32.0",
60
60
  "eslint-plugin-react": "^7.37.5",