@schematichq/schematic-components 1.3.0 → 1.4.1

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.
@@ -1848,6 +1848,7 @@ __export(index_exports, {
1848
1848
  Button: () => Button,
1849
1849
  ButtonElement: () => ButtonElement,
1850
1850
  Card: () => Card,
1851
+ CheckoutDialog: () => CheckoutDialog,
1851
1852
  Column: () => Column,
1852
1853
  Container: () => Container,
1853
1854
  Element: () => Element,
@@ -1881,6 +1882,7 @@ __export(index_exports, {
1881
1882
  UpcomingBill: () => UpcomingBill,
1882
1883
  Viewport: () => Viewport,
1883
1884
  cardBoxShadow: () => cardBoxShadow,
1885
+ createActiveUsageBasedEntitlementsReducer: () => createActiveUsageBasedEntitlementsReducer,
1884
1886
  defaultSettings: () => defaultSettings,
1885
1887
  defaultTheme: () => defaultTheme,
1886
1888
  iconsList: () => iconsList,
@@ -1943,8 +1945,8 @@ function getPriceValue(billingPrice) {
1943
1945
  const price = typeof billingPrice.priceDecimal === "string" ? Number(billingPrice.priceDecimal) : billingPrice.price;
1944
1946
  return price;
1945
1947
  }
1946
- function getPlanPrice(plan, period = "month") {
1947
- const billingPrice = period === "year" ? plan.yearlyPrice : plan.monthlyPrice;
1948
+ function getPlanPrice(plan, period = "month", options2 = { useSelectedPeriod: true }) {
1949
+ const billingPrice = options2.useSelectedPeriod ? period === "year" ? plan.yearlyPrice : plan.monthlyPrice : plan.yearlyPrice && !plan.monthlyPrice ? plan.yearlyPrice : plan.monthlyPrice;
1948
1950
  if (billingPrice) {
1949
1951
  return { ...billingPrice, price: getPriceValue(billingPrice) };
1950
1952
  }
@@ -4143,7 +4145,7 @@ attr.rem = function propAsRem(key, value) {
4143
4145
  };
4144
4146
 
4145
4147
  // src/hooks/useAvailablePlans.ts
4146
- function useAvailablePlans(activePeriod) {
4148
+ function useAvailablePlans(activePeriod, options2 = { useSelectedPeriod: true }) {
4147
4149
  const { data, settings } = useEmbed();
4148
4150
  const getAvailablePeriods = (0, import_react2.useCallback)(() => {
4149
4151
  const periods = [];
@@ -4157,12 +4159,15 @@ function useAvailablePlans(activePeriod) {
4157
4159
  }, [data?.activePlans, data?.activeAddOns]);
4158
4160
  const getActivePlans = (0, import_react2.useCallback)(
4159
4161
  (plans) => {
4160
- const activePlans = settings.mode === "edit" ? plans.slice() : plans.filter(
4161
- (plan) => activePeriod === "month" && plan.monthlyPrice || activePeriod === "year" && plan.yearlyPrice || plan.chargeType === ChargeType.oneTime
4162
- );
4162
+ const activePlans = settings.mode === "edit" ? plans.slice() : plans.filter((plan) => {
4163
+ if (options2.useSelectedPeriod) {
4164
+ return activePeriod === "month" && plan.monthlyPrice || activePeriod === "year" && plan.yearlyPrice || plan.chargeType === ChargeType.oneTime;
4165
+ }
4166
+ return plan.monthlyPrice || plan.yearlyPrice || plan.chargeType === ChargeType.oneTime;
4167
+ });
4163
4168
  return activePlans.map((plan) => ({ ...plan, isSelected: false }));
4164
4169
  },
4165
- [activePeriod, settings.mode]
4170
+ [activePeriod, options2.useSelectedPeriod, settings.mode]
4166
4171
  );
4167
4172
  return (0, import_react2.useMemo)(() => {
4168
4173
  return {
@@ -4264,6 +4269,7 @@ var stub = () => {
4264
4269
  var initialContext = {
4265
4270
  ...initialState,
4266
4271
  hydratePublic: stub,
4272
+ hydrate: stub,
4267
4273
  hydrateComponent: stub,
4268
4274
  hydrateExternal: stub,
4269
4275
  getUpcomingInvoice: stub,
@@ -4712,6 +4718,26 @@ var postProcessor = {
4712
4718
  return value;
4713
4719
  }
4714
4720
  };
4721
+ var PATH_KEY = Symbol("i18next/PATH_KEY");
4722
+ function createProxy() {
4723
+ const state = [];
4724
+ const handler = /* @__PURE__ */ Object.create(null);
4725
+ let proxy;
4726
+ handler.get = (target, key) => {
4727
+ proxy?.revoke?.();
4728
+ if (key === PATH_KEY) return state;
4729
+ state.push(key);
4730
+ proxy = Proxy.revocable(target, handler);
4731
+ return proxy.proxy;
4732
+ };
4733
+ return Proxy.revocable(/* @__PURE__ */ Object.create(null), handler).proxy;
4734
+ }
4735
+ function keysFromSelector(selector, opts) {
4736
+ const {
4737
+ [PATH_KEY]: path
4738
+ } = selector(createProxy());
4739
+ return path.join(opts?.keySeparator ?? ".");
4740
+ }
4715
4741
  var checkedLoadedFor = {};
4716
4742
  var shouldHandleAsObject = (res) => !isString(res) && typeof res !== "boolean" && typeof res !== "number";
4717
4743
  var Translator = class _Translator extends EventEmitter {
@@ -4773,6 +4799,7 @@ var Translator = class _Translator extends EventEmitter {
4773
4799
  };
4774
4800
  if (!opt) opt = {};
4775
4801
  if (keys == null) return "";
4802
+ if (typeof keys === "function") keys = keysFromSelector(keys, opt);
4776
4803
  if (!Array.isArray(keys)) keys = [String(keys)];
4777
4804
  const returnDetails = opt.returnDetails !== void 0 ? opt.returnDetails : this.options.returnDetails;
4778
4805
  const keySeparator = opt.keySeparator !== void 0 ? opt.keySeparator : this.options.keySeparator;
@@ -6026,7 +6053,7 @@ var I18n = class _I18n extends EventEmitter {
6026
6053
  });
6027
6054
  const usingLegacyFormatFunction = this.options.interpolation.format && this.options.interpolation.format !== defOpts.interpolation.format;
6028
6055
  if (usingLegacyFormatFunction) {
6029
- this.logger.warn(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
6056
+ this.logger.deprecate(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
6030
6057
  }
6031
6058
  if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
6032
6059
  s2.formatter = createClassOnDemand(formatter);
@@ -7404,6 +7431,7 @@ function BillingCreditBundleViewFromJSONTyped(json, ignoreDiscriminator) {
7404
7431
  expiryType: json["expiry_type"],
7405
7432
  expiryUnit: json["expiry_unit"],
7406
7433
  expiryUnitCount: json["expiry_unit_count"] == null ? void 0 : json["expiry_unit_count"],
7434
+ hasGrants: json["has_grants"],
7407
7435
  id: json["id"],
7408
7436
  name: json["name"],
7409
7437
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
@@ -7574,6 +7602,7 @@ function BillingProductForSubscriptionResponseDataFromJSONTyped(json, ignoreDisc
7574
7602
  }
7575
7603
  return {
7576
7604
  billingScheme: json["billing_scheme"],
7605
+ billingThreshold: json["billing_threshold"] == null ? void 0 : json["billing_threshold"],
7577
7606
  createdAt: new Date(json["created_at"]),
7578
7607
  currency: json["currency"],
7579
7608
  environmentId: json["environment_id"],
@@ -7592,6 +7621,7 @@ function BillingProductForSubscriptionResponseDataFromJSONTyped(json, ignoreDisc
7592
7621
  ),
7593
7622
  quantity: json["quantity"],
7594
7623
  subscriptionId: json["subscription_id"],
7624
+ subscriptionItemExternalId: json["subscription_item_external_id"] == null ? void 0 : json["subscription_item_external_id"],
7595
7625
  updatedAt: new Date(json["updated_at"]),
7596
7626
  usageType: json["usage_type"]
7597
7627
  };
@@ -8354,6 +8384,7 @@ function PlanEntitlementResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8354
8384
  return json;
8355
8385
  }
8356
8386
  return {
8387
+ billingThreshold: json["billing_threshold"] == null ? void 0 : json["billing_threshold"],
8357
8388
  consumptionRate: json["consumption_rate"] == null ? void 0 : json["consumption_rate"],
8358
8389
  createdAt: new Date(json["created_at"]),
8359
8390
  environmentId: json["environment_id"],
@@ -8569,6 +8600,9 @@ function CreditCompanyGrantViewFromJSONTyped(json, ignoreDiscriminator) {
8569
8600
  creditIcon: json["credit_icon"] == null ? void 0 : json["credit_icon"],
8570
8601
  creditName: json["credit_name"],
8571
8602
  expiresAt: json["expires_at"] == null ? void 0 : new Date(json["expires_at"]),
8603
+ expiryType: json["expiry_type"] == null ? void 0 : json["expiry_type"],
8604
+ expiryUnit: json["expiry_unit"] == null ? void 0 : json["expiry_unit"],
8605
+ expiryUnitCount: json["expiry_unit_count"] == null ? void 0 : json["expiry_unit_count"],
8572
8606
  grantReason: json["grant_reason"],
8573
8607
  id: json["id"],
8574
8608
  planId: json["plan_id"] == null ? void 0 : json["plan_id"],
@@ -8596,6 +8630,7 @@ function UsageBasedEntitlementResponseDataFromJSONTyped(json, ignoreDiscriminato
8596
8630
  return json;
8597
8631
  }
8598
8632
  return {
8633
+ billingThreshold: json["billing_threshold"] == null ? void 0 : json["billing_threshold"],
8599
8634
  consumptionRate: json["consumption_rate"] == null ? void 0 : json["consumption_rate"],
8600
8635
  featureId: json["feature_id"],
8601
8636
  meteredPrice: json["metered_price"] == null ? void 0 : BillingPriceViewFromJSON(json["metered_price"]),
@@ -8704,6 +8739,7 @@ function ComponentHydrateResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8704
8739
  ),
8705
8740
  defaultPlan: json["default_plan"] == null ? void 0 : PlanDetailResponseDataFromJSON(json["default_plan"]),
8706
8741
  featureUsage: json["feature_usage"] == null ? void 0 : FeatureUsageDetailResponseDataFromJSON(json["feature_usage"]),
8742
+ showPeriodToggle: json["show_period_toggle"],
8707
8743
  stripeEmbed: json["stripe_embed"] == null ? void 0 : StripeEmbedInfoFromJSON(json["stripe_embed"]),
8708
8744
  subscription: json["subscription"] == null ? void 0 : CompanySubscriptionResponseDataFromJSON(json["subscription"]),
8709
8745
  trialPaymentMethodRequired: json["trial_payment_method_required"] == null ? void 0 : json["trial_payment_method_required"],
@@ -8797,6 +8833,20 @@ function HydrateComponentResponseFromJSONTyped(json, ignoreDiscriminator) {
8797
8833
  };
8798
8834
  }
8799
8835
 
8836
+ // src/api/checkoutexternal/models/HydrateResponse.ts
8837
+ function HydrateResponseFromJSON(json) {
8838
+ return HydrateResponseFromJSONTyped(json, false);
8839
+ }
8840
+ function HydrateResponseFromJSONTyped(json, ignoreDiscriminator) {
8841
+ if (json == null) {
8842
+ return json;
8843
+ }
8844
+ return {
8845
+ data: ComponentHydrateResponseDataFromJSON(json["data"]),
8846
+ params: json["params"]
8847
+ };
8848
+ }
8849
+
8800
8850
  // src/api/checkoutexternal/models/HydrateUpcomingInvoiceResponse.ts
8801
8851
  function HydrateUpcomingInvoiceResponseFromJSON(json) {
8802
8852
  return HydrateUpcomingInvoiceResponseFromJSONTyped(json, false);
@@ -9168,6 +9218,38 @@ var CheckoutexternalApi = class extends BaseAPI {
9168
9218
  );
9169
9219
  return await response.value();
9170
9220
  }
9221
+ /**
9222
+ * Hydrate
9223
+ */
9224
+ async hydrateRaw(initOverrides) {
9225
+ const queryParameters = {};
9226
+ const headerParameters = {};
9227
+ if (this.configuration && this.configuration.apiKey) {
9228
+ headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey(
9229
+ "X-Schematic-Api-Key"
9230
+ );
9231
+ }
9232
+ const response = await this.request(
9233
+ {
9234
+ path: `/components/hydrate`,
9235
+ method: "GET",
9236
+ headers: headerParameters,
9237
+ query: queryParameters
9238
+ },
9239
+ initOverrides
9240
+ );
9241
+ return new JSONApiResponse(
9242
+ response,
9243
+ (jsonValue) => HydrateResponseFromJSON(jsonValue)
9244
+ );
9245
+ }
9246
+ /**
9247
+ * Hydrate
9248
+ */
9249
+ async hydrate(initOverrides) {
9250
+ const response = await this.hydrateRaw(initOverrides);
9251
+ return await response.value();
9252
+ }
9171
9253
  /**
9172
9254
  * Hydrate component
9173
9255
  */
@@ -10064,6 +10146,32 @@ function FeatureDetailResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
10064
10146
  };
10065
10147
  }
10066
10148
 
10149
+ // src/api/componentspublic/models/PlanCreditGrantView.ts
10150
+ function PlanCreditGrantViewFromJSON2(json) {
10151
+ return PlanCreditGrantViewFromJSONTyped3(json, false);
10152
+ }
10153
+ function PlanCreditGrantViewFromJSONTyped3(json, ignoreDiscriminator) {
10154
+ if (json == null) {
10155
+ return json;
10156
+ }
10157
+ return {
10158
+ createdAt: new Date(json["created_at"]),
10159
+ creditAmount: json["credit_amount"],
10160
+ creditDescription: json["credit_description"],
10161
+ creditIcon: json["credit_icon"] == null ? void 0 : json["credit_icon"],
10162
+ creditId: json["credit_id"],
10163
+ creditName: json["credit_name"],
10164
+ id: json["id"],
10165
+ planId: json["plan_id"],
10166
+ planName: json["plan_name"],
10167
+ pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
10168
+ resetCadence: json["reset_cadence"],
10169
+ resetStart: json["reset_start"],
10170
+ singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
10171
+ updatedAt: new Date(json["updated_at"])
10172
+ };
10173
+ }
10174
+
10067
10175
  // src/api/componentspublic/models/PlanResponseData.ts
10068
10176
  function PlanResponseDataFromJSON2(json) {
10069
10177
  return PlanResponseDataFromJSONTyped4(json, false);
@@ -10093,6 +10201,7 @@ function PlanEntitlementResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
10093
10201
  return json;
10094
10202
  }
10095
10203
  return {
10204
+ billingThreshold: json["billing_threshold"] == null ? void 0 : json["billing_threshold"],
10096
10205
  consumptionRate: json["consumption_rate"] == null ? void 0 : json["consumption_rate"],
10097
10206
  createdAt: new Date(json["created_at"]),
10098
10207
  environmentId: json["environment_id"],
@@ -10147,6 +10256,9 @@ function PlanViewPublicResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10147
10256
  ),
10148
10257
  icon: json["icon"],
10149
10258
  id: json["id"],
10259
+ includedCreditGrants: json["included_credit_grants"].map(
10260
+ PlanCreditGrantViewFromJSON2
10261
+ ),
10150
10262
  isCustom: json["is_custom"],
10151
10263
  isDefault: json["is_default"],
10152
10264
  isFree: json["is_free"],
@@ -10179,7 +10291,8 @@ function PublicPlansResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10179
10291
  addOnCompatibilities: json["add_on_compatibilities"].map(
10180
10292
  CompatiblePlansFromJSON2
10181
10293
  ),
10182
- capabilities: json["capabilities"] == null ? void 0 : ComponentCapabilitiesFromJSON2(json["capabilities"])
10294
+ capabilities: json["capabilities"] == null ? void 0 : ComponentCapabilitiesFromJSON2(json["capabilities"]),
10295
+ showPeriodToggle: json["show_period_toggle"]
10183
10296
  };
10184
10297
  }
10185
10298
 
@@ -10258,6 +10371,7 @@ var reducer = (state, action) => {
10258
10371
  };
10259
10372
  }
10260
10373
  case "HYDRATE_PUBLIC":
10374
+ case "HYDRATE":
10261
10375
  case "HYDRATE_COMPONENT":
10262
10376
  case "HYDRATE_EXTERNAL": {
10263
10377
  return {
@@ -10376,7 +10490,7 @@ var EmbedProvider = ({
10376
10490
  });
10377
10491
  const customHeaders = (0, import_react12.useMemo)(
10378
10492
  () => ({
10379
- "X-Schematic-Components-Version": "1.3.0",
10493
+ "X-Schematic-Components-Version": "1.4.1",
10380
10494
  "X-Schematic-Session-ID": sessionIdRef.current
10381
10495
  }),
10382
10496
  []
@@ -10412,6 +10526,28 @@ var EmbedProvider = ({
10412
10526
  () => (0, import_debounce.default)(hydratePublic, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10413
10527
  [hydratePublic]
10414
10528
  );
10529
+ const hydrate = (0, import_react12.useCallback)(async () => {
10530
+ dispatch({ type: "HYDRATE_STARTED" });
10531
+ try {
10532
+ const response = await api.checkout?.hydrate();
10533
+ if (response) {
10534
+ dispatch({
10535
+ type: "HYDRATE",
10536
+ data: response.data
10537
+ });
10538
+ }
10539
+ return response?.data;
10540
+ } catch (err2) {
10541
+ dispatch({
10542
+ type: "ERROR",
10543
+ error: isError(err2) ? err2 : ERROR_UNKNOWN
10544
+ });
10545
+ }
10546
+ }, [api.checkout]);
10547
+ const debouncedHydrate = (0, import_react12.useMemo)(
10548
+ () => (0, import_debounce.default)(hydrate, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10549
+ [hydrate]
10550
+ );
10415
10551
  const hydrateComponent = (0, import_react12.useCallback)(
10416
10552
  async (id) => {
10417
10553
  dispatch({ type: "HYDRATE_STARTED" });
@@ -10694,6 +10830,7 @@ var EmbedProvider = ({
10694
10830
  layout: state.layout,
10695
10831
  checkoutState: state.checkoutState,
10696
10832
  hydratePublic: debouncedHydratePublic,
10833
+ hydrate: debouncedHydrate,
10697
10834
  hydrateComponent: debouncedHydrateComponent,
10698
10835
  hydrateExternal: debouncedHydrateExternal,
10699
10836
  createSetupIntent: debouncedCreateSetupIntent,
@@ -11058,7 +11195,6 @@ var Button = dt.button(
11058
11195
  ${() => $selfAlignment && lt`
11059
11196
  align-self: ${$selfAlignment};
11060
11197
  `}
11061
- gap: 0.5rem;
11062
11198
  width: ${$fullWidth ? "100%" : "fit-content"};
11063
11199
  border: 1px solid transparent;
11064
11200
  transition: 0.1s;
@@ -11162,6 +11298,9 @@ var Button = dt.button(
11162
11298
  &::before {
11163
11299
  content: "";
11164
11300
  ${loaderStyles({ $color: theme[$color], $size, $isLoading })}
11301
+ ${$isLoading && lt`
11302
+ margin-right: 0.5rem;
11303
+ `}
11165
11304
  }
11166
11305
 
11167
11306
  &:disabled {
@@ -13639,7 +13778,8 @@ var Plan = ({
13639
13778
  selectedPlan,
13640
13779
  period,
13641
13780
  selectPlan,
13642
- shouldTrial
13781
+ shouldTrial,
13782
+ showPeriodToggle
13643
13783
  }) => {
13644
13784
  const { t: t2 } = useTranslation();
13645
13785
  const { data, settings } = useEmbed();
@@ -13678,8 +13818,9 @@ var Plan = ({
13678
13818
  $gap: "1rem",
13679
13819
  $flexGrow: 1,
13680
13820
  children: plans.map((plan, planIndex) => {
13681
- const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, period) || {};
13682
- const credits = isHydratedPlan(plan) ? groupPlanCreditGrants(plan.includedCreditGrants) : [];
13821
+ const planPeriod = showPeriodToggle ? period : plan.yearlyPrice && !plan.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
13822
+ const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, planPeriod) || {};
13823
+ const credits = groupPlanCreditGrants(plan.includedCreditGrants);
13683
13824
  const hasUsageBasedEntitlements = plan.entitlements.some(
13684
13825
  (entitlement) => !!entitlement.priceBehavior
13685
13826
  );
@@ -13738,7 +13879,7 @@ var Plan = ({
13738
13879
  $size: 16 / 30 * settings.theme.typography.heading2.fontSize,
13739
13880
  children: [
13740
13881
  "/",
13741
- period
13882
+ planPeriod
13742
13883
  ]
13743
13884
  }
13744
13885
  )
@@ -13834,7 +13975,7 @@ var Plan = ({
13834
13975
  priceTier: entitlementPriceTiers,
13835
13976
  currency: entitlementCurrency,
13836
13977
  packageSize: entitlementPackageSize = 1
13837
- } = getEntitlementPrice(entitlement, period) || {};
13978
+ } = getEntitlementPrice(entitlement, planPeriod) || {};
13838
13979
  const metricPeriodName = getMetricPeriodName(entitlement);
13839
13980
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
13840
13981
  Flex,
@@ -13880,13 +14021,13 @@ var Plan = ({
13880
14021
  " ",
13881
14022
  t2("per"),
13882
14023
  " ",
13883
- period
14024
+ planPeriod
13884
14025
  ] })
13885
14026
  ] }) : entitlement.priceBehavior === "tier" /* Tiered */ ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
13886
14027
  TieredPricingDetails,
13887
14028
  {
13888
14029
  entitlement,
13889
- period
14030
+ period: planPeriod
13890
14031
  }
13891
14032
  ) : entitlement.priceBehavior === "credit_burndown" /* Credit */ && entitlement.valueCredit ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
13892
14033
  entitlement.consumptionRate,
@@ -13943,7 +14084,7 @@ var Plan = ({
13943
14084
  ),
13944
14085
  entitlement.feature.featureType === "trait" /* Trait */ && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
13945
14086
  "/",
13946
- shortenPeriod(period)
14087
+ shortenPeriod(planPeriod)
13947
14088
  ] })
13948
14089
  ]
13949
14090
  }
@@ -13952,7 +14093,7 @@ var Plan = ({
13952
14093
  PricingTiersTooltip,
13953
14094
  {
13954
14095
  feature: entitlement.feature,
13955
- period,
14096
+ period: planPeriod,
13956
14097
  currency: entitlementCurrency,
13957
14098
  priceTiers: entitlementPriceTiers
13958
14099
  }
@@ -14085,7 +14226,7 @@ var Usage = ({ entitlements, updateQuantity, period }) => {
14085
14226
  $size: "lg",
14086
14227
  type: "number",
14087
14228
  value: entitlement.quantity,
14088
- min: 1,
14229
+ min: 0,
14089
14230
  autoFocus: true,
14090
14231
  onFocus: (event) => {
14091
14232
  event.target.select();
@@ -14093,7 +14234,7 @@ var Usage = ({ entitlements, updateQuantity, period }) => {
14093
14234
  onChange: (event) => {
14094
14235
  event.preventDefault();
14095
14236
  const value = parseInt(event.target.value);
14096
- if (!isNaN(value) && value > 0) {
14237
+ if (!isNaN(value)) {
14097
14238
  updateQuantity(entitlement.id, value);
14098
14239
  }
14099
14240
  }
@@ -14172,7 +14313,7 @@ var createActiveUsageBasedEntitlementsReducer = (entitlements, period) => (acc,
14172
14313
  const featureUsage = entitlements.find(
14173
14314
  (usage2) => usage2.feature?.id === entitlement.feature?.id
14174
14315
  );
14175
- const allocation = featureUsage?.allocation || 1;
14316
+ const allocation = featureUsage?.allocation || 0;
14176
14317
  const usage = featureUsage?.usage || 0;
14177
14318
  acc.push({
14178
14319
  ...entitlement,
@@ -14185,7 +14326,7 @@ var createActiveUsageBasedEntitlementsReducer = (entitlements, period) => (acc,
14185
14326
  };
14186
14327
  var CheckoutDialog = ({ top = 0 }) => {
14187
14328
  const { t: t2 } = useTranslation();
14188
- const { data, checkoutState, previewCheckout } = useEmbed();
14329
+ const { data, settings, isPending, checkoutState, previewCheckout } = useEmbed();
14189
14330
  const isLightBackground = useIsLightBackground();
14190
14331
  const contentRef = (0, import_react30.useRef)(null);
14191
14332
  const checkoutRef = (0, import_react30.useRef)(null);
@@ -14199,30 +14340,39 @@ var CheckoutDialog = ({ top = 0 }) => {
14199
14340
  );
14200
14341
  const [isLoading, setIsLoading] = (0, import_react30.useState)(false);
14201
14342
  const [error, setError] = (0, import_react30.useState)();
14202
- const currentPeriod = (0, import_react30.useMemo)(
14203
- () => checkoutState?.period || isCheckoutData(data) && data.company?.plan?.planPeriod || "month",
14204
- [data, checkoutState?.period]
14205
- );
14206
- const [planPeriod, setPlanPeriod] = (0, import_react30.useState)(currentPeriod);
14207
14343
  const {
14208
- plans: availablePlans,
14209
- addOns: availableAddOns,
14210
- periods: availablePeriods
14211
- } = useAvailablePlans(planPeriod);
14212
- const { currentPlanId, currentEntitlements, trialPaymentMethodRequired } = (0, import_react30.useMemo)(() => {
14344
+ currentPlanId,
14345
+ currentEntitlements,
14346
+ showPeriodToggle,
14347
+ trialPaymentMethodRequired
14348
+ } = (0, import_react30.useMemo)(() => {
14213
14349
  if (isCheckoutData(data)) {
14214
14350
  return {
14215
14351
  currentPlanId: data.company?.plan?.id,
14216
14352
  currentEntitlements: data.featureUsage ? data.featureUsage.features : [],
14353
+ showPeriodToggle: data.showPeriodToggle,
14217
14354
  trialPaymentMethodRequired: data.trialPaymentMethodRequired === true
14218
14355
  };
14219
14356
  }
14220
14357
  return {
14221
14358
  currentPlanId: void 0,
14222
14359
  currentEntitlements: [],
14360
+ showPeriodToggle: true,
14223
14361
  trialPaymentMethodRequired: false
14224
14362
  };
14225
14363
  }, [data]);
14364
+ const currentPeriod = (0, import_react30.useMemo)(
14365
+ () => checkoutState?.period || isCheckoutData(data) && data.company?.plan?.planPeriod || "month",
14366
+ [data, checkoutState?.period]
14367
+ );
14368
+ const [planPeriod, setPlanPeriod] = (0, import_react30.useState)(currentPeriod);
14369
+ const {
14370
+ plans: availablePlans,
14371
+ addOns: availableAddOns,
14372
+ periods: availablePeriods
14373
+ } = useAvailablePlans(planPeriod, {
14374
+ useSelectedPeriod: showPeriodToggle
14375
+ });
14226
14376
  const [selectedPlan, setSelectedPlan] = (0, import_react30.useState)(
14227
14377
  () => {
14228
14378
  return availablePlans.find(
@@ -14370,20 +14520,8 @@ var CheckoutDialog = ({ top = 0 }) => {
14370
14520
  if (checkoutState?.credits) {
14371
14521
  return "credits";
14372
14522
  }
14373
- if (checkoutState?.planId !== currentPlanId) {
14374
- const hasUsageStage = checkoutStages.some(
14375
- (stage) => stage.id === "usage"
14376
- );
14377
- const hasAddonsStage = checkoutStages.some(
14378
- (stage) => stage.id === "addons"
14379
- );
14380
- const hasAddonsUsageStage = checkoutStages.some(
14381
- (stage) => stage.id === "addonsUsage"
14382
- );
14383
- if (hasUsageStage) return "usage";
14384
- if (hasAddonsStage) return "addons";
14385
- if (hasAddonsUsageStage) return "addonsUsage";
14386
- return "plan";
14523
+ if (typeof checkoutState?.planId !== "undefined" && checkoutState.planId !== currentPlanId) {
14524
+ return checkoutStages.some((stage) => stage.id === "usage") ? "usage" : checkoutStages.some((stage) => stage.id === "addons") ? "addons" : checkoutStages.some((stage) => stage.id === "addonsUsage") ? "addonsUsage" : checkoutStages.some((stage) => stage.id === "credits") ? "credits" : "plan";
14387
14525
  }
14388
14526
  return "plan";
14389
14527
  });
@@ -14522,7 +14660,7 @@ var CheckoutDialog = ({ top = 0 }) => {
14522
14660
  ...entitlement,
14523
14661
  allocation: entitlement.valueNumeric || 0,
14524
14662
  usage: 0,
14525
- quantity: entitlement.priceBehavior === "pay_in_advance" /* PayInAdvance */ ? 1 : 0
14663
+ quantity: 0
14526
14664
  });
14527
14665
  }
14528
14666
  return acc;
@@ -14779,7 +14917,7 @@ var CheckoutDialog = ({ top = 0 }) => {
14779
14917
  ),
14780
14918
  activeCheckoutStage.description && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Text, { as: "p", children: activeCheckoutStage.description })
14781
14919
  ] }),
14782
- checkoutStage === "plan" && availablePeriods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14920
+ checkoutStage === "plan" && showPeriodToggle && availablePeriods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14783
14921
  PeriodToggle,
14784
14922
  {
14785
14923
  options: availablePeriods,
@@ -14791,7 +14929,17 @@ var CheckoutDialog = ({ top = 0 }) => {
14791
14929
  ]
14792
14930
  }
14793
14931
  ),
14794
- checkoutStage === "plan" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14932
+ isPending ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14933
+ Flex,
14934
+ {
14935
+ $width: "100%",
14936
+ $height: "100%",
14937
+ $alignItems: "center",
14938
+ $justifyContent: "center",
14939
+ $padding: `${settings.theme.card.padding / TEXT_BASE_SIZE}rem`,
14940
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Loader, { $size: "2xl" })
14941
+ }
14942
+ ) : checkoutStage === "plan" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14795
14943
  Plan,
14796
14944
  {
14797
14945
  isLoading,
@@ -14799,10 +14947,10 @@ var CheckoutDialog = ({ top = 0 }) => {
14799
14947
  plans: availablePlans,
14800
14948
  selectedPlan,
14801
14949
  selectPlan,
14802
- shouldTrial
14950
+ shouldTrial,
14951
+ showPeriodToggle
14803
14952
  }
14804
- ),
14805
- checkoutStage === "usage" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14953
+ ) : checkoutStage === "usage" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14806
14954
  Usage,
14807
14955
  {
14808
14956
  isLoading,
@@ -14811,8 +14959,7 @@ var CheckoutDialog = ({ top = 0 }) => {
14811
14959
  entitlements: payInAdvanceEntitlements,
14812
14960
  updateQuantity: updateUsageBasedEntitlementQuantity
14813
14961
  }
14814
- ),
14815
- checkoutStage === "addons" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14962
+ ) : checkoutStage === "addons" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14816
14963
  AddOns,
14817
14964
  {
14818
14965
  isLoading,
@@ -14820,8 +14967,7 @@ var CheckoutDialog = ({ top = 0 }) => {
14820
14967
  addOns,
14821
14968
  toggle: (id) => toggleAddOn(id)
14822
14969
  }
14823
- ),
14824
- checkoutStage === "addonsUsage" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14970
+ ) : checkoutStage === "addonsUsage" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14825
14971
  Usage,
14826
14972
  {
14827
14973
  isLoading,
@@ -14830,16 +14976,14 @@ var CheckoutDialog = ({ top = 0 }) => {
14830
14976
  entitlements: addOnUsageBasedEntitlements,
14831
14977
  updateQuantity: updateAddOnEntitlementQuantity
14832
14978
  }
14833
- ),
14834
- checkoutStage === "credits" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14979
+ ) : checkoutStage === "credits" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14835
14980
  Credits,
14836
14981
  {
14837
14982
  isLoading,
14838
14983
  bundles: creditBundles,
14839
14984
  updateCount: updateCreditBundleCount
14840
14985
  }
14841
- ),
14842
- checkoutStage === "checkout" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14986
+ ) : checkoutStage === "checkout" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14843
14987
  Checkout,
14844
14988
  {
14845
14989
  isPaymentMethodRequired,
@@ -18245,7 +18389,7 @@ var Plan2 = ({
18245
18389
  );
18246
18390
  const isActivePlan = isHydratedPlan(plan) && plan.current && currentPeriod === selectedPeriod;
18247
18391
  const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, selectedPeriod) || {};
18248
- const credits = isHydratedPlan(plan) ? groupPlanCreditGrants(plan.includedCreditGrants) : [];
18392
+ const credits = groupPlanCreditGrants(plan.includedCreditGrants);
18249
18393
  const hasUsageBasedEntitlements = plan.entitlements.some(
18250
18394
  (entitlement) => !!entitlement.priceBehavior
18251
18395
  );
@@ -18540,7 +18684,8 @@ var PricingTable = (0, import_react51.forwardRef)(
18540
18684
  const props = resolveDesignProps8(rest);
18541
18685
  const { t: t2 } = useTranslation();
18542
18686
  const { data, settings, isPending, hydratePublic } = useEmbed();
18543
- const { currentPeriod, isStandalone } = (0, import_react51.useMemo)(() => {
18687
+ const { currentPeriod, showPeriodToggle, isStandalone } = (0, import_react51.useMemo)(() => {
18688
+ const showPeriodToggle2 = data?.showPeriodToggle ?? props.showPeriodToggle;
18544
18689
  if (isCheckoutData(data)) {
18545
18690
  const billingSubscription = data.company?.billingSubscription;
18546
18691
  const isTrialSubscription = billingSubscription?.status === "trialing";
@@ -18549,6 +18694,7 @@ var PricingTable = (0, import_react51.forwardRef)(
18549
18694
  currentPeriod: data.company?.plan?.planPeriod || "month",
18550
18695
  currentAddOns: data.company?.addOns || [],
18551
18696
  canCheckout: data.capabilities?.checkout ?? true,
18697
+ showPeriodToggle: showPeriodToggle2,
18552
18698
  isTrialSubscription,
18553
18699
  willSubscriptionCancel,
18554
18700
  isStandalone: false
@@ -18558,13 +18704,16 @@ var PricingTable = (0, import_react51.forwardRef)(
18558
18704
  currentPeriod: "month",
18559
18705
  currentAddOns: [],
18560
18706
  canCheckout: true,
18707
+ showPeriodToggle: showPeriodToggle2,
18561
18708
  isTrialSubscription: false,
18562
18709
  willSubscriptionCancel: false,
18563
18710
  isStandalone: true
18564
18711
  };
18565
- }, [data]);
18712
+ }, [props.showPeriodToggle, data]);
18566
18713
  const [selectedPeriod, setSelectedPeriod] = (0, import_react51.useState)(currentPeriod);
18567
- const { plans, addOns, periods } = useAvailablePlans(selectedPeriod);
18714
+ const { plans, addOns, periods } = useAvailablePlans(selectedPeriod, {
18715
+ useSelectedPeriod: showPeriodToggle
18716
+ });
18568
18717
  const [entitlementCounts, setEntitlementCounts] = (0, import_react51.useState)(
18569
18718
  () => plans.reduce(entitlementCountsReducer, {})
18570
18719
  );
@@ -18591,7 +18740,7 @@ var PricingTable = (0, import_react51.forwardRef)(
18591
18740
  (0, import_react51.useEffect)(() => {
18592
18741
  setEntitlementCounts(plans.reduce(entitlementCountsReducer, {}));
18593
18742
  }, [plans]);
18594
- if (isStandalone && isPending) {
18743
+ if (isPending) {
18595
18744
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18596
18745
  Flex,
18597
18746
  {
@@ -18638,7 +18787,7 @@ var PricingTable = (0, import_react51.forwardRef)(
18638
18787
  children: props.header.isVisible && props.plans.isVisible && plans.length > 0 && t2("Plans")
18639
18788
  }
18640
18789
  ),
18641
- props.showPeriodToggle && periods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18790
+ showPeriodToggle && periods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18642
18791
  PeriodToggle,
18643
18792
  {
18644
18793
  options: periods,
@@ -18659,24 +18808,27 @@ var PricingTable = (0, import_react51.forwardRef)(
18659
18808
  $display: "grid",
18660
18809
  $gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
18661
18810
  $gap: "1rem",
18662
- children: plans.map((plan, index, self2) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18663
- Plan2,
18664
- {
18665
- plan,
18666
- index,
18667
- sharedProps: {
18668
- layout: props,
18669
- callToActionUrl,
18670
- callToActionTarget,
18671
- onCallToAction
18811
+ children: plans.map((plan, index, self2) => {
18812
+ const planPeriod = showPeriodToggle ? selectedPeriod : plan.yearlyPrice && !plan.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
18813
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18814
+ Plan2,
18815
+ {
18816
+ plan,
18817
+ index,
18818
+ sharedProps: {
18819
+ layout: props,
18820
+ callToActionUrl,
18821
+ callToActionTarget,
18822
+ onCallToAction
18823
+ },
18824
+ plans: self2,
18825
+ selectedPeriod: planPeriod,
18826
+ entitlementCounts,
18827
+ handleToggleShowAll
18672
18828
  },
18673
- plans: self2,
18674
- selectedPeriod,
18675
- entitlementCounts,
18676
- handleToggleShowAll
18677
- },
18678
- index
18679
- ))
18829
+ index
18830
+ );
18831
+ })
18680
18832
  }
18681
18833
  )
18682
18834
  ] }),
@@ -18703,20 +18855,23 @@ var PricingTable = (0, import_react51.forwardRef)(
18703
18855
  $display: "grid",
18704
18856
  $gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
18705
18857
  $gap: "1rem",
18706
- children: addOns.map((addOn, index) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18707
- AddOn2,
18708
- {
18709
- addOn,
18710
- sharedProps: {
18711
- layout: props,
18712
- callToActionUrl,
18713
- callToActionTarget,
18714
- onCallToAction
18858
+ children: addOns.map((addOn, index) => {
18859
+ const addOnPeriod = showPeriodToggle ? selectedPeriod : addOn.yearlyPrice && !addOn.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
18860
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18861
+ AddOn2,
18862
+ {
18863
+ addOn,
18864
+ sharedProps: {
18865
+ layout: props,
18866
+ callToActionUrl,
18867
+ callToActionTarget,
18868
+ onCallToAction
18869
+ },
18870
+ selectedPeriod: addOnPeriod
18715
18871
  },
18716
- selectedPeriod
18717
- },
18718
- index
18719
- ))
18872
+ index
18873
+ );
18874
+ })
18720
18875
  }
18721
18876
  )
18722
18877
  ] }) })