@schematichq/schematic-components 1.3.0 → 1.4.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.
@@ -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);
@@ -8704,6 +8731,7 @@ function ComponentHydrateResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8704
8731
  ),
8705
8732
  defaultPlan: json["default_plan"] == null ? void 0 : PlanDetailResponseDataFromJSON(json["default_plan"]),
8706
8733
  featureUsage: json["feature_usage"] == null ? void 0 : FeatureUsageDetailResponseDataFromJSON(json["feature_usage"]),
8734
+ showPeriodToggle: json["show_period_toggle"],
8707
8735
  stripeEmbed: json["stripe_embed"] == null ? void 0 : StripeEmbedInfoFromJSON(json["stripe_embed"]),
8708
8736
  subscription: json["subscription"] == null ? void 0 : CompanySubscriptionResponseDataFromJSON(json["subscription"]),
8709
8737
  trialPaymentMethodRequired: json["trial_payment_method_required"] == null ? void 0 : json["trial_payment_method_required"],
@@ -8797,6 +8825,20 @@ function HydrateComponentResponseFromJSONTyped(json, ignoreDiscriminator) {
8797
8825
  };
8798
8826
  }
8799
8827
 
8828
+ // src/api/checkoutexternal/models/HydrateResponse.ts
8829
+ function HydrateResponseFromJSON(json) {
8830
+ return HydrateResponseFromJSONTyped(json, false);
8831
+ }
8832
+ function HydrateResponseFromJSONTyped(json, ignoreDiscriminator) {
8833
+ if (json == null) {
8834
+ return json;
8835
+ }
8836
+ return {
8837
+ data: ComponentHydrateResponseDataFromJSON(json["data"]),
8838
+ params: json["params"]
8839
+ };
8840
+ }
8841
+
8800
8842
  // src/api/checkoutexternal/models/HydrateUpcomingInvoiceResponse.ts
8801
8843
  function HydrateUpcomingInvoiceResponseFromJSON(json) {
8802
8844
  return HydrateUpcomingInvoiceResponseFromJSONTyped(json, false);
@@ -9168,6 +9210,38 @@ var CheckoutexternalApi = class extends BaseAPI {
9168
9210
  );
9169
9211
  return await response.value();
9170
9212
  }
9213
+ /**
9214
+ * Hydrate
9215
+ */
9216
+ async hydrateRaw(initOverrides) {
9217
+ const queryParameters = {};
9218
+ const headerParameters = {};
9219
+ if (this.configuration && this.configuration.apiKey) {
9220
+ headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey(
9221
+ "X-Schematic-Api-Key"
9222
+ );
9223
+ }
9224
+ const response = await this.request(
9225
+ {
9226
+ path: `/components/hydrate`,
9227
+ method: "GET",
9228
+ headers: headerParameters,
9229
+ query: queryParameters
9230
+ },
9231
+ initOverrides
9232
+ );
9233
+ return new JSONApiResponse(
9234
+ response,
9235
+ (jsonValue) => HydrateResponseFromJSON(jsonValue)
9236
+ );
9237
+ }
9238
+ /**
9239
+ * Hydrate
9240
+ */
9241
+ async hydrate(initOverrides) {
9242
+ const response = await this.hydrateRaw(initOverrides);
9243
+ return await response.value();
9244
+ }
9171
9245
  /**
9172
9246
  * Hydrate component
9173
9247
  */
@@ -10064,6 +10138,32 @@ function FeatureDetailResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
10064
10138
  };
10065
10139
  }
10066
10140
 
10141
+ // src/api/componentspublic/models/PlanCreditGrantView.ts
10142
+ function PlanCreditGrantViewFromJSON2(json) {
10143
+ return PlanCreditGrantViewFromJSONTyped3(json, false);
10144
+ }
10145
+ function PlanCreditGrantViewFromJSONTyped3(json, ignoreDiscriminator) {
10146
+ if (json == null) {
10147
+ return json;
10148
+ }
10149
+ return {
10150
+ createdAt: new Date(json["created_at"]),
10151
+ creditAmount: json["credit_amount"],
10152
+ creditDescription: json["credit_description"],
10153
+ creditIcon: json["credit_icon"] == null ? void 0 : json["credit_icon"],
10154
+ creditId: json["credit_id"],
10155
+ creditName: json["credit_name"],
10156
+ id: json["id"],
10157
+ planId: json["plan_id"],
10158
+ planName: json["plan_name"],
10159
+ pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
10160
+ resetCadence: json["reset_cadence"],
10161
+ resetStart: json["reset_start"],
10162
+ singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
10163
+ updatedAt: new Date(json["updated_at"])
10164
+ };
10165
+ }
10166
+
10067
10167
  // src/api/componentspublic/models/PlanResponseData.ts
10068
10168
  function PlanResponseDataFromJSON2(json) {
10069
10169
  return PlanResponseDataFromJSONTyped4(json, false);
@@ -10147,6 +10247,9 @@ function PlanViewPublicResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10147
10247
  ),
10148
10248
  icon: json["icon"],
10149
10249
  id: json["id"],
10250
+ includedCreditGrants: json["included_credit_grants"].map(
10251
+ PlanCreditGrantViewFromJSON2
10252
+ ),
10150
10253
  isCustom: json["is_custom"],
10151
10254
  isDefault: json["is_default"],
10152
10255
  isFree: json["is_free"],
@@ -10258,6 +10361,7 @@ var reducer = (state, action) => {
10258
10361
  };
10259
10362
  }
10260
10363
  case "HYDRATE_PUBLIC":
10364
+ case "HYDRATE":
10261
10365
  case "HYDRATE_COMPONENT":
10262
10366
  case "HYDRATE_EXTERNAL": {
10263
10367
  return {
@@ -10376,7 +10480,7 @@ var EmbedProvider = ({
10376
10480
  });
10377
10481
  const customHeaders = (0, import_react12.useMemo)(
10378
10482
  () => ({
10379
- "X-Schematic-Components-Version": "1.3.0",
10483
+ "X-Schematic-Components-Version": "1.4.0",
10380
10484
  "X-Schematic-Session-ID": sessionIdRef.current
10381
10485
  }),
10382
10486
  []
@@ -10412,6 +10516,28 @@ var EmbedProvider = ({
10412
10516
  () => (0, import_debounce.default)(hydratePublic, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10413
10517
  [hydratePublic]
10414
10518
  );
10519
+ const hydrate = (0, import_react12.useCallback)(async () => {
10520
+ dispatch({ type: "HYDRATE_STARTED" });
10521
+ try {
10522
+ const response = await api.checkout?.hydrate();
10523
+ if (response) {
10524
+ dispatch({
10525
+ type: "HYDRATE",
10526
+ data: response.data
10527
+ });
10528
+ }
10529
+ return response?.data;
10530
+ } catch (err2) {
10531
+ dispatch({
10532
+ type: "ERROR",
10533
+ error: isError(err2) ? err2 : ERROR_UNKNOWN
10534
+ });
10535
+ }
10536
+ }, [api.checkout]);
10537
+ const debouncedHydrate = (0, import_react12.useMemo)(
10538
+ () => (0, import_debounce.default)(hydrate, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10539
+ [hydrate]
10540
+ );
10415
10541
  const hydrateComponent = (0, import_react12.useCallback)(
10416
10542
  async (id) => {
10417
10543
  dispatch({ type: "HYDRATE_STARTED" });
@@ -10694,6 +10820,7 @@ var EmbedProvider = ({
10694
10820
  layout: state.layout,
10695
10821
  checkoutState: state.checkoutState,
10696
10822
  hydratePublic: debouncedHydratePublic,
10823
+ hydrate: debouncedHydrate,
10697
10824
  hydrateComponent: debouncedHydrateComponent,
10698
10825
  hydrateExternal: debouncedHydrateExternal,
10699
10826
  createSetupIntent: debouncedCreateSetupIntent,
@@ -13639,7 +13766,8 @@ var Plan = ({
13639
13766
  selectedPlan,
13640
13767
  period,
13641
13768
  selectPlan,
13642
- shouldTrial
13769
+ shouldTrial,
13770
+ showPeriodToggle
13643
13771
  }) => {
13644
13772
  const { t: t2 } = useTranslation();
13645
13773
  const { data, settings } = useEmbed();
@@ -13678,8 +13806,9 @@ var Plan = ({
13678
13806
  $gap: "1rem",
13679
13807
  $flexGrow: 1,
13680
13808
  children: plans.map((plan, planIndex) => {
13681
- const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, period) || {};
13682
- const credits = isHydratedPlan(plan) ? groupPlanCreditGrants(plan.includedCreditGrants) : [];
13809
+ const planPeriod = showPeriodToggle ? period : plan.yearlyPrice && !plan.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
13810
+ const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, planPeriod) || {};
13811
+ const credits = groupPlanCreditGrants(plan.includedCreditGrants);
13683
13812
  const hasUsageBasedEntitlements = plan.entitlements.some(
13684
13813
  (entitlement) => !!entitlement.priceBehavior
13685
13814
  );
@@ -13738,7 +13867,7 @@ var Plan = ({
13738
13867
  $size: 16 / 30 * settings.theme.typography.heading2.fontSize,
13739
13868
  children: [
13740
13869
  "/",
13741
- period
13870
+ planPeriod
13742
13871
  ]
13743
13872
  }
13744
13873
  )
@@ -13834,7 +13963,7 @@ var Plan = ({
13834
13963
  priceTier: entitlementPriceTiers,
13835
13964
  currency: entitlementCurrency,
13836
13965
  packageSize: entitlementPackageSize = 1
13837
- } = getEntitlementPrice(entitlement, period) || {};
13966
+ } = getEntitlementPrice(entitlement, planPeriod) || {};
13838
13967
  const metricPeriodName = getMetricPeriodName(entitlement);
13839
13968
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
13840
13969
  Flex,
@@ -13880,13 +14009,13 @@ var Plan = ({
13880
14009
  " ",
13881
14010
  t2("per"),
13882
14011
  " ",
13883
- period
14012
+ planPeriod
13884
14013
  ] })
13885
14014
  ] }) : entitlement.priceBehavior === "tier" /* Tiered */ ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
13886
14015
  TieredPricingDetails,
13887
14016
  {
13888
14017
  entitlement,
13889
- period
14018
+ period: planPeriod
13890
14019
  }
13891
14020
  ) : entitlement.priceBehavior === "credit_burndown" /* Credit */ && entitlement.valueCredit ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
13892
14021
  entitlement.consumptionRate,
@@ -13943,7 +14072,7 @@ var Plan = ({
13943
14072
  ),
13944
14073
  entitlement.feature.featureType === "trait" /* Trait */ && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
13945
14074
  "/",
13946
- shortenPeriod(period)
14075
+ shortenPeriod(planPeriod)
13947
14076
  ] })
13948
14077
  ]
13949
14078
  }
@@ -13952,7 +14081,7 @@ var Plan = ({
13952
14081
  PricingTiersTooltip,
13953
14082
  {
13954
14083
  feature: entitlement.feature,
13955
- period,
14084
+ period: planPeriod,
13956
14085
  currency: entitlementCurrency,
13957
14086
  priceTiers: entitlementPriceTiers
13958
14087
  }
@@ -14209,17 +14338,24 @@ var CheckoutDialog = ({ top = 0 }) => {
14209
14338
  addOns: availableAddOns,
14210
14339
  periods: availablePeriods
14211
14340
  } = useAvailablePlans(planPeriod);
14212
- const { currentPlanId, currentEntitlements, trialPaymentMethodRequired } = (0, import_react30.useMemo)(() => {
14341
+ const {
14342
+ currentPlanId,
14343
+ currentEntitlements,
14344
+ showPeriodToggle,
14345
+ trialPaymentMethodRequired
14346
+ } = (0, import_react30.useMemo)(() => {
14213
14347
  if (isCheckoutData(data)) {
14214
14348
  return {
14215
14349
  currentPlanId: data.company?.plan?.id,
14216
14350
  currentEntitlements: data.featureUsage ? data.featureUsage.features : [],
14351
+ showPeriodToggle: data.showPeriodToggle,
14217
14352
  trialPaymentMethodRequired: data.trialPaymentMethodRequired === true
14218
14353
  };
14219
14354
  }
14220
14355
  return {
14221
14356
  currentPlanId: void 0,
14222
14357
  currentEntitlements: [],
14358
+ showPeriodToggle: true,
14223
14359
  trialPaymentMethodRequired: false
14224
14360
  };
14225
14361
  }, [data]);
@@ -14779,7 +14915,7 @@ var CheckoutDialog = ({ top = 0 }) => {
14779
14915
  ),
14780
14916
  activeCheckoutStage.description && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Text, { as: "p", children: activeCheckoutStage.description })
14781
14917
  ] }),
14782
- checkoutStage === "plan" && availablePeriods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14918
+ checkoutStage === "plan" && showPeriodToggle && availablePeriods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14783
14919
  PeriodToggle,
14784
14920
  {
14785
14921
  options: availablePeriods,
@@ -14799,7 +14935,8 @@ var CheckoutDialog = ({ top = 0 }) => {
14799
14935
  plans: availablePlans,
14800
14936
  selectedPlan,
14801
14937
  selectPlan,
14802
- shouldTrial
14938
+ shouldTrial,
14939
+ showPeriodToggle
14803
14940
  }
14804
14941
  ),
14805
14942
  checkoutStage === "usage" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
@@ -18245,7 +18382,7 @@ var Plan2 = ({
18245
18382
  );
18246
18383
  const isActivePlan = isHydratedPlan(plan) && plan.current && currentPeriod === selectedPeriod;
18247
18384
  const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, selectedPeriod) || {};
18248
- const credits = isHydratedPlan(plan) ? groupPlanCreditGrants(plan.includedCreditGrants) : [];
18385
+ const credits = groupPlanCreditGrants(plan.includedCreditGrants);
18249
18386
  const hasUsageBasedEntitlements = plan.entitlements.some(
18250
18387
  (entitlement) => !!entitlement.priceBehavior
18251
18388
  );
@@ -18540,7 +18677,7 @@ var PricingTable = (0, import_react51.forwardRef)(
18540
18677
  const props = resolveDesignProps8(rest);
18541
18678
  const { t: t2 } = useTranslation();
18542
18679
  const { data, settings, isPending, hydratePublic } = useEmbed();
18543
- const { currentPeriod, isStandalone } = (0, import_react51.useMemo)(() => {
18680
+ const { currentPeriod, showPeriodToggle, isStandalone } = (0, import_react51.useMemo)(() => {
18544
18681
  if (isCheckoutData(data)) {
18545
18682
  const billingSubscription = data.company?.billingSubscription;
18546
18683
  const isTrialSubscription = billingSubscription?.status === "trialing";
@@ -18549,6 +18686,7 @@ var PricingTable = (0, import_react51.forwardRef)(
18549
18686
  currentPeriod: data.company?.plan?.planPeriod || "month",
18550
18687
  currentAddOns: data.company?.addOns || [],
18551
18688
  canCheckout: data.capabilities?.checkout ?? true,
18689
+ showPeriodToggle: data.showPeriodToggle ?? props.showPeriodToggle,
18552
18690
  isTrialSubscription,
18553
18691
  willSubscriptionCancel,
18554
18692
  isStandalone: false
@@ -18558,13 +18696,16 @@ var PricingTable = (0, import_react51.forwardRef)(
18558
18696
  currentPeriod: "month",
18559
18697
  currentAddOns: [],
18560
18698
  canCheckout: true,
18699
+ showPeriodToggle: props.showPeriodToggle,
18561
18700
  isTrialSubscription: false,
18562
18701
  willSubscriptionCancel: false,
18563
18702
  isStandalone: true
18564
18703
  };
18565
- }, [data]);
18704
+ }, [props.showPeriodToggle, data]);
18566
18705
  const [selectedPeriod, setSelectedPeriod] = (0, import_react51.useState)(currentPeriod);
18567
- const { plans, addOns, periods } = useAvailablePlans(selectedPeriod);
18706
+ const { plans, addOns, periods } = useAvailablePlans(selectedPeriod, {
18707
+ useSelectedPeriod: showPeriodToggle
18708
+ });
18568
18709
  const [entitlementCounts, setEntitlementCounts] = (0, import_react51.useState)(
18569
18710
  () => plans.reduce(entitlementCountsReducer, {})
18570
18711
  );
@@ -18638,7 +18779,7 @@ var PricingTable = (0, import_react51.forwardRef)(
18638
18779
  children: props.header.isVisible && props.plans.isVisible && plans.length > 0 && t2("Plans")
18639
18780
  }
18640
18781
  ),
18641
- props.showPeriodToggle && periods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18782
+ showPeriodToggle && periods.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18642
18783
  PeriodToggle,
18643
18784
  {
18644
18785
  options: periods,
@@ -18659,24 +18800,27 @@ var PricingTable = (0, import_react51.forwardRef)(
18659
18800
  $display: "grid",
18660
18801
  $gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
18661
18802
  $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
18803
+ children: plans.map((plan, index, self2) => {
18804
+ const planPeriod = showPeriodToggle ? selectedPeriod : plan.yearlyPrice && !plan.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
18805
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18806
+ Plan2,
18807
+ {
18808
+ plan,
18809
+ index,
18810
+ sharedProps: {
18811
+ layout: props,
18812
+ callToActionUrl,
18813
+ callToActionTarget,
18814
+ onCallToAction
18815
+ },
18816
+ plans: self2,
18817
+ selectedPeriod: planPeriod,
18818
+ entitlementCounts,
18819
+ handleToggleShowAll
18672
18820
  },
18673
- plans: self2,
18674
- selectedPeriod,
18675
- entitlementCounts,
18676
- handleToggleShowAll
18677
- },
18678
- index
18679
- ))
18821
+ index
18822
+ );
18823
+ })
18680
18824
  }
18681
18825
  )
18682
18826
  ] }),
@@ -18703,20 +18847,23 @@ var PricingTable = (0, import_react51.forwardRef)(
18703
18847
  $display: "grid",
18704
18848
  $gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
18705
18849
  $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
18850
+ children: addOns.map((addOn, index) => {
18851
+ const addOnPeriod = showPeriodToggle ? selectedPeriod : addOn.yearlyPrice && !addOn.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
18852
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18853
+ AddOn2,
18854
+ {
18855
+ addOn,
18856
+ sharedProps: {
18857
+ layout: props,
18858
+ callToActionUrl,
18859
+ callToActionTarget,
18860
+ onCallToAction
18861
+ },
18862
+ selectedPeriod: addOnPeriod
18715
18863
  },
18716
- selectedPeriod
18717
- },
18718
- index
18719
- ))
18864
+ index
18865
+ );
18866
+ })
18720
18867
  }
18721
18868
  )
18722
18869
  ] }) })
@@ -15,6 +15,10 @@ import { RefAttributes } from 'react';
15
15
  import { RuleSet } from 'styled-components';
16
16
  import { Substitute } from 'styled-components/dist/types';
17
17
 
18
+ declare interface AvailablePlanOptions {
19
+ useSelectedPeriod?: boolean;
20
+ }
21
+
18
22
  /**
19
23
  *
20
24
  * @export
@@ -1876,6 +1880,12 @@ declare interface ChangeSubscriptionRequestBody {
1876
1880
  skipTrial: boolean;
1877
1881
  }
1878
1882
 
1883
+ export declare const CheckoutDialog: ({ top }: CheckoutDialogProps) => JSX.Element;
1884
+
1885
+ declare interface CheckoutDialogProps {
1886
+ top?: number;
1887
+ }
1888
+
1879
1889
  /**
1880
1890
  *
1881
1891
  * @export
@@ -1896,6 +1906,13 @@ declare interface CheckoutResponse {
1896
1906
  params: object;
1897
1907
  }
1898
1908
 
1909
+ export declare interface CheckoutStage {
1910
+ id: string;
1911
+ name: string;
1912
+ label?: string;
1913
+ description?: string;
1914
+ }
1915
+
1899
1916
  export declare type CheckoutState = {
1900
1917
  period?: string;
1901
1918
  planId?: string | null;
@@ -2375,7 +2392,7 @@ declare interface CompanyPlanDetailResponseData {
2375
2392
  * @type {Array<PlanCreditGrantView>}
2376
2393
  * @memberof CompanyPlanDetailResponseData
2377
2394
  */
2378
- includedCreditGrants: Array<PlanCreditGrantView>;
2395
+ includedCreditGrants: Array<PlanCreditGrantView_2>;
2379
2396
  /**
2380
2397
  *
2381
2398
  * @type {boolean}
@@ -2811,6 +2828,12 @@ declare interface ComponentHydrateResponseData {
2811
2828
  * @memberof ComponentHydrateResponseData
2812
2829
  */
2813
2830
  featureUsage?: FeatureUsageDetailResponseData;
2831
+ /**
2832
+ *
2833
+ * @type {boolean}
2834
+ * @memberof ComponentHydrateResponseData
2835
+ */
2836
+ showPeriodToggle: boolean;
2814
2837
  /**
2815
2838
  *
2816
2839
  * @type {StripeEmbedInfo}
@@ -2921,6 +2944,8 @@ declare interface ConfigurationParameters {
2921
2944
 
2922
2945
  export declare const Container: IStyledComponentBase<"web", FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
2923
2946
 
2947
+ export declare const createActiveUsageBasedEntitlementsReducer: (entitlements: FeatureUsageResponseData[], period: string) => (acc: UsageBasedEntitlement[], entitlement: PlanEntitlementResponseData_2) => UsageBasedEntitlement[];
2948
+
2924
2949
  /**
2925
2950
  *
2926
2951
  * @export
@@ -3422,6 +3447,7 @@ export declare const EmbedContext: Context<EmbedContextProps>;
3422
3447
 
3423
3448
  export declare interface EmbedContextProps extends EmbedState {
3424
3449
  hydratePublic: () => DebouncedApiPromise<PublicPlansResponseData>;
3450
+ hydrate: () => DebouncedApiPromise<ComponentHydrateResponseData>;
3425
3451
  hydrateComponent: (id: string) => DebouncedApiPromise<ComponentHydrateResponseData>;
3426
3452
  hydrateExternal: (fn: () => Promise<ComponentHydrateResponseData>) => DebouncedApiPromise<ComponentHydrateResponseData>;
3427
3453
  getUpcomingInvoice: (id: string) => DebouncedApiPromise<HydrateUpcomingInvoiceResponse>;
@@ -4761,6 +4787,7 @@ export declare type IncludedFeaturesProps = DesignProps_2;
4761
4787
 
4762
4788
  export declare const initialContext: {
4763
4789
  hydratePublic: () => never;
4790
+ hydrate: () => never;
4764
4791
  hydrateComponent: () => never;
4765
4792
  hydrateExternal: () => never;
4766
4793
  getUpcomingInvoice: () => never;
@@ -5268,6 +5295,109 @@ declare interface PlanCreditGrantView {
5268
5295
  updatedAt: Date;
5269
5296
  }
5270
5297
 
5298
+ /**
5299
+ * Schematic API
5300
+ * Schematic API
5301
+ *
5302
+ * The version of the OpenAPI document: 0.1
5303
+ *
5304
+ *
5305
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
5306
+ * https://openapi-generator.tech
5307
+ * Do not edit the class manually.
5308
+ */
5309
+ /**
5310
+ *
5311
+ * @export
5312
+ * @interface PlanCreditGrantView
5313
+ */
5314
+ declare interface PlanCreditGrantView_2 {
5315
+ /**
5316
+ *
5317
+ * @type {Date}
5318
+ * @memberof PlanCreditGrantView
5319
+ */
5320
+ createdAt: Date;
5321
+ /**
5322
+ *
5323
+ * @type {number}
5324
+ * @memberof PlanCreditGrantView
5325
+ */
5326
+ creditAmount: number;
5327
+ /**
5328
+ *
5329
+ * @type {string}
5330
+ * @memberof PlanCreditGrantView
5331
+ */
5332
+ creditDescription: string;
5333
+ /**
5334
+ *
5335
+ * @type {string}
5336
+ * @memberof PlanCreditGrantView
5337
+ */
5338
+ creditIcon?: string | null;
5339
+ /**
5340
+ *
5341
+ * @type {string}
5342
+ * @memberof PlanCreditGrantView
5343
+ */
5344
+ creditId: string;
5345
+ /**
5346
+ *
5347
+ * @type {string}
5348
+ * @memberof PlanCreditGrantView
5349
+ */
5350
+ creditName: string;
5351
+ /**
5352
+ *
5353
+ * @type {string}
5354
+ * @memberof PlanCreditGrantView
5355
+ */
5356
+ id: string;
5357
+ /**
5358
+ *
5359
+ * @type {string}
5360
+ * @memberof PlanCreditGrantView
5361
+ */
5362
+ planId: string;
5363
+ /**
5364
+ *
5365
+ * @type {string}
5366
+ * @memberof PlanCreditGrantView
5367
+ */
5368
+ planName: string;
5369
+ /**
5370
+ *
5371
+ * @type {string}
5372
+ * @memberof PlanCreditGrantView
5373
+ */
5374
+ pluralName?: string | null;
5375
+ /**
5376
+ *
5377
+ * @type {string}
5378
+ * @memberof PlanCreditGrantView
5379
+ */
5380
+ resetCadence: string;
5381
+ /**
5382
+ *
5383
+ * @type {string}
5384
+ * @memberof PlanCreditGrantView
5385
+ */
5386
+ resetStart: string;
5387
+ /**
5388
+ *
5389
+ * @type {string}
5390
+ * @memberof PlanCreditGrantView
5391
+ */
5392
+ singularName?: string | null;
5393
+ /**
5394
+ *
5395
+ * @type {Date}
5396
+ * @memberof PlanCreditGrantView
5397
+ */
5398
+ updatedAt: Date;
5399
+ }
5400
+
5271
5401
  /**
5272
5402
  *
5273
5403
  * @export
@@ -5930,6 +6060,12 @@ declare interface PlanViewPublicResponseData {
5930
6060
  * @memberof PlanViewPublicResponseData
5931
6061
  */
5932
6062
  id: string;
6063
+ /**
6064
+ *
6065
+ * @type {Array<PlanCreditGrantView>}
6066
+ * @memberof PlanViewPublicResponseData
6067
+ */
6068
+ includedCreditGrants: Array<PlanCreditGrantView>;
5933
6069
  /**
5934
6070
  *
5935
6071
  * @type {boolean}
@@ -7035,7 +7171,7 @@ declare type SelectedPlan = Plan & {
7035
7171
  * Do not edit the class manually.
7036
7172
  */
7037
7173
  /**
7038
- *
7174
+ * The returned resource
7039
7175
  * @export
7040
7176
  * @interface SetupIntentResponseData
7041
7177
  */
@@ -7326,6 +7462,12 @@ declare interface UpdatePaymentMethodResponse {
7326
7462
  params: object;
7327
7463
  }
7328
7464
 
7465
+ declare interface UsageBasedEntitlement extends PlanEntitlementResponseData_2 {
7466
+ allocation: number;
7467
+ usage: number;
7468
+ quantity: number;
7469
+ }
7470
+
7329
7471
  /**
7330
7472
  *
7331
7473
  * @export
@@ -7400,7 +7542,7 @@ declare interface UsageBasedEntitlementResponseData {
7400
7542
  yearlyUsageBasedPrice?: BillingPriceView_2;
7401
7543
  }
7402
7544
 
7403
- export declare function useAvailablePlans(activePeriod: string): {
7545
+ export declare function useAvailablePlans(activePeriod: string, options?: AvailablePlanOptions): {
7404
7546
  plans: SelectedPlan[];
7405
7547
  addOns: SelectedPlan[];
7406
7548
  periods: string[];
@@ -1879,8 +1879,8 @@ function getPriceValue(billingPrice) {
1879
1879
  const price = typeof billingPrice.priceDecimal === "string" ? Number(billingPrice.priceDecimal) : billingPrice.price;
1880
1880
  return price;
1881
1881
  }
1882
- function getPlanPrice(plan, period = "month") {
1883
- const billingPrice = period === "year" ? plan.yearlyPrice : plan.monthlyPrice;
1882
+ function getPlanPrice(plan, period = "month", options2 = { useSelectedPeriod: true }) {
1883
+ const billingPrice = options2.useSelectedPeriod ? period === "year" ? plan.yearlyPrice : plan.monthlyPrice : plan.yearlyPrice && !plan.monthlyPrice ? plan.yearlyPrice : plan.monthlyPrice;
1884
1884
  if (billingPrice) {
1885
1885
  return { ...billingPrice, price: getPriceValue(billingPrice) };
1886
1886
  }
@@ -4079,7 +4079,7 @@ attr.rem = function propAsRem(key, value) {
4079
4079
  };
4080
4080
 
4081
4081
  // src/hooks/useAvailablePlans.ts
4082
- function useAvailablePlans(activePeriod) {
4082
+ function useAvailablePlans(activePeriod, options2 = { useSelectedPeriod: true }) {
4083
4083
  const { data, settings } = useEmbed();
4084
4084
  const getAvailablePeriods = useCallback(() => {
4085
4085
  const periods = [];
@@ -4093,12 +4093,15 @@ function useAvailablePlans(activePeriod) {
4093
4093
  }, [data?.activePlans, data?.activeAddOns]);
4094
4094
  const getActivePlans = useCallback(
4095
4095
  (plans) => {
4096
- const activePlans = settings.mode === "edit" ? plans.slice() : plans.filter(
4097
- (plan) => activePeriod === "month" && plan.monthlyPrice || activePeriod === "year" && plan.yearlyPrice || plan.chargeType === ChargeType.oneTime
4098
- );
4096
+ const activePlans = settings.mode === "edit" ? plans.slice() : plans.filter((plan) => {
4097
+ if (options2.useSelectedPeriod) {
4098
+ return activePeriod === "month" && plan.monthlyPrice || activePeriod === "year" && plan.yearlyPrice || plan.chargeType === ChargeType.oneTime;
4099
+ }
4100
+ return plan.monthlyPrice || plan.yearlyPrice || plan.chargeType === ChargeType.oneTime;
4101
+ });
4099
4102
  return activePlans.map((plan) => ({ ...plan, isSelected: false }));
4100
4103
  },
4101
- [activePeriod, settings.mode]
4104
+ [activePeriod, options2.useSelectedPeriod, settings.mode]
4102
4105
  );
4103
4106
  return useMemo(() => {
4104
4107
  return {
@@ -4200,6 +4203,7 @@ var stub = () => {
4200
4203
  var initialContext = {
4201
4204
  ...initialState,
4202
4205
  hydratePublic: stub,
4206
+ hydrate: stub,
4203
4207
  hydrateComponent: stub,
4204
4208
  hydrateExternal: stub,
4205
4209
  getUpcomingInvoice: stub,
@@ -4648,6 +4652,26 @@ var postProcessor = {
4648
4652
  return value;
4649
4653
  }
4650
4654
  };
4655
+ var PATH_KEY = Symbol("i18next/PATH_KEY");
4656
+ function createProxy() {
4657
+ const state = [];
4658
+ const handler = /* @__PURE__ */ Object.create(null);
4659
+ let proxy;
4660
+ handler.get = (target, key) => {
4661
+ proxy?.revoke?.();
4662
+ if (key === PATH_KEY) return state;
4663
+ state.push(key);
4664
+ proxy = Proxy.revocable(target, handler);
4665
+ return proxy.proxy;
4666
+ };
4667
+ return Proxy.revocable(/* @__PURE__ */ Object.create(null), handler).proxy;
4668
+ }
4669
+ function keysFromSelector(selector, opts) {
4670
+ const {
4671
+ [PATH_KEY]: path
4672
+ } = selector(createProxy());
4673
+ return path.join(opts?.keySeparator ?? ".");
4674
+ }
4651
4675
  var checkedLoadedFor = {};
4652
4676
  var shouldHandleAsObject = (res) => !isString(res) && typeof res !== "boolean" && typeof res !== "number";
4653
4677
  var Translator = class _Translator extends EventEmitter {
@@ -4709,6 +4733,7 @@ var Translator = class _Translator extends EventEmitter {
4709
4733
  };
4710
4734
  if (!opt) opt = {};
4711
4735
  if (keys == null) return "";
4736
+ if (typeof keys === "function") keys = keysFromSelector(keys, opt);
4712
4737
  if (!Array.isArray(keys)) keys = [String(keys)];
4713
4738
  const returnDetails = opt.returnDetails !== void 0 ? opt.returnDetails : this.options.returnDetails;
4714
4739
  const keySeparator = opt.keySeparator !== void 0 ? opt.keySeparator : this.options.keySeparator;
@@ -5962,7 +5987,7 @@ var I18n = class _I18n extends EventEmitter {
5962
5987
  });
5963
5988
  const usingLegacyFormatFunction = this.options.interpolation.format && this.options.interpolation.format !== defOpts.interpolation.format;
5964
5989
  if (usingLegacyFormatFunction) {
5965
- this.logger.warn(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
5990
+ this.logger.deprecate(`init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting`);
5966
5991
  }
5967
5992
  if (formatter && (!this.options.interpolation.format || this.options.interpolation.format === defOpts.interpolation.format)) {
5968
5993
  s2.formatter = createClassOnDemand(formatter);
@@ -8647,6 +8672,7 @@ function ComponentHydrateResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8647
8672
  ),
8648
8673
  defaultPlan: json["default_plan"] == null ? void 0 : PlanDetailResponseDataFromJSON(json["default_plan"]),
8649
8674
  featureUsage: json["feature_usage"] == null ? void 0 : FeatureUsageDetailResponseDataFromJSON(json["feature_usage"]),
8675
+ showPeriodToggle: json["show_period_toggle"],
8650
8676
  stripeEmbed: json["stripe_embed"] == null ? void 0 : StripeEmbedInfoFromJSON(json["stripe_embed"]),
8651
8677
  subscription: json["subscription"] == null ? void 0 : CompanySubscriptionResponseDataFromJSON(json["subscription"]),
8652
8678
  trialPaymentMethodRequired: json["trial_payment_method_required"] == null ? void 0 : json["trial_payment_method_required"],
@@ -8740,6 +8766,20 @@ function HydrateComponentResponseFromJSONTyped(json, ignoreDiscriminator) {
8740
8766
  };
8741
8767
  }
8742
8768
 
8769
+ // src/api/checkoutexternal/models/HydrateResponse.ts
8770
+ function HydrateResponseFromJSON(json) {
8771
+ return HydrateResponseFromJSONTyped(json, false);
8772
+ }
8773
+ function HydrateResponseFromJSONTyped(json, ignoreDiscriminator) {
8774
+ if (json == null) {
8775
+ return json;
8776
+ }
8777
+ return {
8778
+ data: ComponentHydrateResponseDataFromJSON(json["data"]),
8779
+ params: json["params"]
8780
+ };
8781
+ }
8782
+
8743
8783
  // src/api/checkoutexternal/models/HydrateUpcomingInvoiceResponse.ts
8744
8784
  function HydrateUpcomingInvoiceResponseFromJSON(json) {
8745
8785
  return HydrateUpcomingInvoiceResponseFromJSONTyped(json, false);
@@ -9111,6 +9151,38 @@ var CheckoutexternalApi = class extends BaseAPI {
9111
9151
  );
9112
9152
  return await response.value();
9113
9153
  }
9154
+ /**
9155
+ * Hydrate
9156
+ */
9157
+ async hydrateRaw(initOverrides) {
9158
+ const queryParameters = {};
9159
+ const headerParameters = {};
9160
+ if (this.configuration && this.configuration.apiKey) {
9161
+ headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey(
9162
+ "X-Schematic-Api-Key"
9163
+ );
9164
+ }
9165
+ const response = await this.request(
9166
+ {
9167
+ path: `/components/hydrate`,
9168
+ method: "GET",
9169
+ headers: headerParameters,
9170
+ query: queryParameters
9171
+ },
9172
+ initOverrides
9173
+ );
9174
+ return new JSONApiResponse(
9175
+ response,
9176
+ (jsonValue) => HydrateResponseFromJSON(jsonValue)
9177
+ );
9178
+ }
9179
+ /**
9180
+ * Hydrate
9181
+ */
9182
+ async hydrate(initOverrides) {
9183
+ const response = await this.hydrateRaw(initOverrides);
9184
+ return await response.value();
9185
+ }
9114
9186
  /**
9115
9187
  * Hydrate component
9116
9188
  */
@@ -10007,6 +10079,32 @@ function FeatureDetailResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
10007
10079
  };
10008
10080
  }
10009
10081
 
10082
+ // src/api/componentspublic/models/PlanCreditGrantView.ts
10083
+ function PlanCreditGrantViewFromJSON2(json) {
10084
+ return PlanCreditGrantViewFromJSONTyped3(json, false);
10085
+ }
10086
+ function PlanCreditGrantViewFromJSONTyped3(json, ignoreDiscriminator) {
10087
+ if (json == null) {
10088
+ return json;
10089
+ }
10090
+ return {
10091
+ createdAt: new Date(json["created_at"]),
10092
+ creditAmount: json["credit_amount"],
10093
+ creditDescription: json["credit_description"],
10094
+ creditIcon: json["credit_icon"] == null ? void 0 : json["credit_icon"],
10095
+ creditId: json["credit_id"],
10096
+ creditName: json["credit_name"],
10097
+ id: json["id"],
10098
+ planId: json["plan_id"],
10099
+ planName: json["plan_name"],
10100
+ pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
10101
+ resetCadence: json["reset_cadence"],
10102
+ resetStart: json["reset_start"],
10103
+ singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
10104
+ updatedAt: new Date(json["updated_at"])
10105
+ };
10106
+ }
10107
+
10010
10108
  // src/api/componentspublic/models/PlanResponseData.ts
10011
10109
  function PlanResponseDataFromJSON2(json) {
10012
10110
  return PlanResponseDataFromJSONTyped4(json, false);
@@ -10090,6 +10188,9 @@ function PlanViewPublicResponseDataFromJSONTyped(json, ignoreDiscriminator) {
10090
10188
  ),
10091
10189
  icon: json["icon"],
10092
10190
  id: json["id"],
10191
+ includedCreditGrants: json["included_credit_grants"].map(
10192
+ PlanCreditGrantViewFromJSON2
10193
+ ),
10093
10194
  isCustom: json["is_custom"],
10094
10195
  isDefault: json["is_default"],
10095
10196
  isFree: json["is_free"],
@@ -10201,6 +10302,7 @@ var reducer = (state, action) => {
10201
10302
  };
10202
10303
  }
10203
10304
  case "HYDRATE_PUBLIC":
10305
+ case "HYDRATE":
10204
10306
  case "HYDRATE_COMPONENT":
10205
10307
  case "HYDRATE_EXTERNAL": {
10206
10308
  return {
@@ -10319,7 +10421,7 @@ var EmbedProvider = ({
10319
10421
  });
10320
10422
  const customHeaders = useMemo3(
10321
10423
  () => ({
10322
- "X-Schematic-Components-Version": "1.3.0",
10424
+ "X-Schematic-Components-Version": "1.4.0",
10323
10425
  "X-Schematic-Session-ID": sessionIdRef.current
10324
10426
  }),
10325
10427
  []
@@ -10355,6 +10457,28 @@ var EmbedProvider = ({
10355
10457
  () => (0, import_debounce.default)(hydratePublic, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10356
10458
  [hydratePublic]
10357
10459
  );
10460
+ const hydrate = useCallback3(async () => {
10461
+ dispatch({ type: "HYDRATE_STARTED" });
10462
+ try {
10463
+ const response = await api.checkout?.hydrate();
10464
+ if (response) {
10465
+ dispatch({
10466
+ type: "HYDRATE",
10467
+ data: response.data
10468
+ });
10469
+ }
10470
+ return response?.data;
10471
+ } catch (err2) {
10472
+ dispatch({
10473
+ type: "ERROR",
10474
+ error: isError(err2) ? err2 : ERROR_UNKNOWN
10475
+ });
10476
+ }
10477
+ }, [api.checkout]);
10478
+ const debouncedHydrate = useMemo3(
10479
+ () => (0, import_debounce.default)(hydrate, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10480
+ [hydrate]
10481
+ );
10358
10482
  const hydrateComponent = useCallback3(
10359
10483
  async (id) => {
10360
10484
  dispatch({ type: "HYDRATE_STARTED" });
@@ -10637,6 +10761,7 @@ var EmbedProvider = ({
10637
10761
  layout: state.layout,
10638
10762
  checkoutState: state.checkoutState,
10639
10763
  hydratePublic: debouncedHydratePublic,
10764
+ hydrate: debouncedHydrate,
10640
10765
  hydrateComponent: debouncedHydrateComponent,
10641
10766
  hydrateExternal: debouncedHydrateExternal,
10642
10767
  createSetupIntent: debouncedCreateSetupIntent,
@@ -13592,7 +13717,8 @@ var Plan = ({
13592
13717
  selectedPlan,
13593
13718
  period,
13594
13719
  selectPlan,
13595
- shouldTrial
13720
+ shouldTrial,
13721
+ showPeriodToggle
13596
13722
  }) => {
13597
13723
  const { t: t2 } = useTranslation();
13598
13724
  const { data, settings } = useEmbed();
@@ -13631,8 +13757,9 @@ var Plan = ({
13631
13757
  $gap: "1rem",
13632
13758
  $flexGrow: 1,
13633
13759
  children: plans.map((plan, planIndex) => {
13634
- const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, period) || {};
13635
- const credits = isHydratedPlan(plan) ? groupPlanCreditGrants(plan.includedCreditGrants) : [];
13760
+ const planPeriod = showPeriodToggle ? period : plan.yearlyPrice && !plan.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
13761
+ const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, planPeriod) || {};
13762
+ const credits = groupPlanCreditGrants(plan.includedCreditGrants);
13636
13763
  const hasUsageBasedEntitlements = plan.entitlements.some(
13637
13764
  (entitlement) => !!entitlement.priceBehavior
13638
13765
  );
@@ -13691,7 +13818,7 @@ var Plan = ({
13691
13818
  $size: 16 / 30 * settings.theme.typography.heading2.fontSize,
13692
13819
  children: [
13693
13820
  "/",
13694
- period
13821
+ planPeriod
13695
13822
  ]
13696
13823
  }
13697
13824
  )
@@ -13787,7 +13914,7 @@ var Plan = ({
13787
13914
  priceTier: entitlementPriceTiers,
13788
13915
  currency: entitlementCurrency,
13789
13916
  packageSize: entitlementPackageSize = 1
13790
- } = getEntitlementPrice(entitlement, period) || {};
13917
+ } = getEntitlementPrice(entitlement, planPeriod) || {};
13791
13918
  const metricPeriodName = getMetricPeriodName(entitlement);
13792
13919
  return /* @__PURE__ */ jsx18(
13793
13920
  Flex,
@@ -13833,13 +13960,13 @@ var Plan = ({
13833
13960
  " ",
13834
13961
  t2("per"),
13835
13962
  " ",
13836
- period
13963
+ planPeriod
13837
13964
  ] })
13838
13965
  ] }) : entitlement.priceBehavior === "tier" /* Tiered */ ? /* @__PURE__ */ jsx18(
13839
13966
  TieredPricingDetails,
13840
13967
  {
13841
13968
  entitlement,
13842
- period
13969
+ period: planPeriod
13843
13970
  }
13844
13971
  ) : entitlement.priceBehavior === "credit_burndown" /* Credit */ && entitlement.valueCredit ? /* @__PURE__ */ jsxs14(Fragment8, { children: [
13845
13972
  entitlement.consumptionRate,
@@ -13896,7 +14023,7 @@ var Plan = ({
13896
14023
  ),
13897
14024
  entitlement.feature.featureType === "trait" /* Trait */ && /* @__PURE__ */ jsxs14(Fragment8, { children: [
13898
14025
  "/",
13899
- shortenPeriod(period)
14026
+ shortenPeriod(planPeriod)
13900
14027
  ] })
13901
14028
  ]
13902
14029
  }
@@ -13905,7 +14032,7 @@ var Plan = ({
13905
14032
  PricingTiersTooltip,
13906
14033
  {
13907
14034
  feature: entitlement.feature,
13908
- period,
14035
+ period: planPeriod,
13909
14036
  currency: entitlementCurrency,
13910
14037
  priceTiers: entitlementPriceTiers
13911
14038
  }
@@ -14162,17 +14289,24 @@ var CheckoutDialog = ({ top = 0 }) => {
14162
14289
  addOns: availableAddOns,
14163
14290
  periods: availablePeriods
14164
14291
  } = useAvailablePlans(planPeriod);
14165
- const { currentPlanId, currentEntitlements, trialPaymentMethodRequired } = useMemo9(() => {
14292
+ const {
14293
+ currentPlanId,
14294
+ currentEntitlements,
14295
+ showPeriodToggle,
14296
+ trialPaymentMethodRequired
14297
+ } = useMemo9(() => {
14166
14298
  if (isCheckoutData(data)) {
14167
14299
  return {
14168
14300
  currentPlanId: data.company?.plan?.id,
14169
14301
  currentEntitlements: data.featureUsage ? data.featureUsage.features : [],
14302
+ showPeriodToggle: data.showPeriodToggle,
14170
14303
  trialPaymentMethodRequired: data.trialPaymentMethodRequired === true
14171
14304
  };
14172
14305
  }
14173
14306
  return {
14174
14307
  currentPlanId: void 0,
14175
14308
  currentEntitlements: [],
14309
+ showPeriodToggle: true,
14176
14310
  trialPaymentMethodRequired: false
14177
14311
  };
14178
14312
  }, [data]);
@@ -14732,7 +14866,7 @@ var CheckoutDialog = ({ top = 0 }) => {
14732
14866
  ),
14733
14867
  activeCheckoutStage.description && /* @__PURE__ */ jsx20(Text, { as: "p", children: activeCheckoutStage.description })
14734
14868
  ] }),
14735
- checkoutStage === "plan" && availablePeriods.length > 1 && /* @__PURE__ */ jsx20(
14869
+ checkoutStage === "plan" && showPeriodToggle && availablePeriods.length > 1 && /* @__PURE__ */ jsx20(
14736
14870
  PeriodToggle,
14737
14871
  {
14738
14872
  options: availablePeriods,
@@ -14752,7 +14886,8 @@ var CheckoutDialog = ({ top = 0 }) => {
14752
14886
  plans: availablePlans,
14753
14887
  selectedPlan,
14754
14888
  selectPlan,
14755
- shouldTrial
14889
+ shouldTrial,
14890
+ showPeriodToggle
14756
14891
  }
14757
14892
  ),
14758
14893
  checkoutStage === "usage" && /* @__PURE__ */ jsx20(
@@ -18208,7 +18343,7 @@ var Plan2 = ({
18208
18343
  );
18209
18344
  const isActivePlan = isHydratedPlan(plan) && plan.current && currentPeriod === selectedPeriod;
18210
18345
  const { price: planPrice, currency: planCurrency } = getPlanPrice(plan, selectedPeriod) || {};
18211
- const credits = isHydratedPlan(plan) ? groupPlanCreditGrants(plan.includedCreditGrants) : [];
18346
+ const credits = groupPlanCreditGrants(plan.includedCreditGrants);
18212
18347
  const hasUsageBasedEntitlements = plan.entitlements.some(
18213
18348
  (entitlement) => !!entitlement.priceBehavior
18214
18349
  );
@@ -18503,7 +18638,7 @@ var PricingTable = forwardRef12(
18503
18638
  const props = resolveDesignProps8(rest);
18504
18639
  const { t: t2 } = useTranslation();
18505
18640
  const { data, settings, isPending, hydratePublic } = useEmbed();
18506
- const { currentPeriod, isStandalone } = useMemo26(() => {
18641
+ const { currentPeriod, showPeriodToggle, isStandalone } = useMemo26(() => {
18507
18642
  if (isCheckoutData(data)) {
18508
18643
  const billingSubscription = data.company?.billingSubscription;
18509
18644
  const isTrialSubscription = billingSubscription?.status === "trialing";
@@ -18512,6 +18647,7 @@ var PricingTable = forwardRef12(
18512
18647
  currentPeriod: data.company?.plan?.planPeriod || "month",
18513
18648
  currentAddOns: data.company?.addOns || [],
18514
18649
  canCheckout: data.capabilities?.checkout ?? true,
18650
+ showPeriodToggle: data.showPeriodToggle ?? props.showPeriodToggle,
18515
18651
  isTrialSubscription,
18516
18652
  willSubscriptionCancel,
18517
18653
  isStandalone: false
@@ -18521,13 +18657,16 @@ var PricingTable = forwardRef12(
18521
18657
  currentPeriod: "month",
18522
18658
  currentAddOns: [],
18523
18659
  canCheckout: true,
18660
+ showPeriodToggle: props.showPeriodToggle,
18524
18661
  isTrialSubscription: false,
18525
18662
  willSubscriptionCancel: false,
18526
18663
  isStandalone: true
18527
18664
  };
18528
- }, [data]);
18665
+ }, [props.showPeriodToggle, data]);
18529
18666
  const [selectedPeriod, setSelectedPeriod] = useState17(currentPeriod);
18530
- const { plans, addOns, periods } = useAvailablePlans(selectedPeriod);
18667
+ const { plans, addOns, periods } = useAvailablePlans(selectedPeriod, {
18668
+ useSelectedPeriod: showPeriodToggle
18669
+ });
18531
18670
  const [entitlementCounts, setEntitlementCounts] = useState17(
18532
18671
  () => plans.reduce(entitlementCountsReducer, {})
18533
18672
  );
@@ -18601,7 +18740,7 @@ var PricingTable = forwardRef12(
18601
18740
  children: props.header.isVisible && props.plans.isVisible && plans.length > 0 && t2("Plans")
18602
18741
  }
18603
18742
  ),
18604
- props.showPeriodToggle && periods.length > 1 && /* @__PURE__ */ jsx46(
18743
+ showPeriodToggle && periods.length > 1 && /* @__PURE__ */ jsx46(
18605
18744
  PeriodToggle,
18606
18745
  {
18607
18746
  options: periods,
@@ -18622,24 +18761,27 @@ var PricingTable = forwardRef12(
18622
18761
  $display: "grid",
18623
18762
  $gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
18624
18763
  $gap: "1rem",
18625
- children: plans.map((plan, index, self2) => /* @__PURE__ */ jsx46(
18626
- Plan2,
18627
- {
18628
- plan,
18629
- index,
18630
- sharedProps: {
18631
- layout: props,
18632
- callToActionUrl,
18633
- callToActionTarget,
18634
- onCallToAction
18764
+ children: plans.map((plan, index, self2) => {
18765
+ const planPeriod = showPeriodToggle ? selectedPeriod : plan.yearlyPrice && !plan.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
18766
+ return /* @__PURE__ */ jsx46(
18767
+ Plan2,
18768
+ {
18769
+ plan,
18770
+ index,
18771
+ sharedProps: {
18772
+ layout: props,
18773
+ callToActionUrl,
18774
+ callToActionTarget,
18775
+ onCallToAction
18776
+ },
18777
+ plans: self2,
18778
+ selectedPeriod: planPeriod,
18779
+ entitlementCounts,
18780
+ handleToggleShowAll
18635
18781
  },
18636
- plans: self2,
18637
- selectedPeriod,
18638
- entitlementCounts,
18639
- handleToggleShowAll
18640
- },
18641
- index
18642
- ))
18782
+ index
18783
+ );
18784
+ })
18643
18785
  }
18644
18786
  )
18645
18787
  ] }),
@@ -18666,20 +18808,23 @@ var PricingTable = forwardRef12(
18666
18808
  $display: "grid",
18667
18809
  $gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
18668
18810
  $gap: "1rem",
18669
- children: addOns.map((addOn, index) => /* @__PURE__ */ jsx46(
18670
- AddOn2,
18671
- {
18672
- addOn,
18673
- sharedProps: {
18674
- layout: props,
18675
- callToActionUrl,
18676
- callToActionTarget,
18677
- onCallToAction
18811
+ children: addOns.map((addOn, index) => {
18812
+ const addOnPeriod = showPeriodToggle ? selectedPeriod : addOn.yearlyPrice && !addOn.monthlyPrice ? "year" /* Year */ : "month" /* Month */;
18813
+ return /* @__PURE__ */ jsx46(
18814
+ AddOn2,
18815
+ {
18816
+ addOn,
18817
+ sharedProps: {
18818
+ layout: props,
18819
+ callToActionUrl,
18820
+ callToActionTarget,
18821
+ onCallToAction
18822
+ },
18823
+ selectedPeriod: addOnPeriod
18678
18824
  },
18679
- selectedPeriod
18680
- },
18681
- index
18682
- ))
18825
+ index
18826
+ );
18827
+ })
18683
18828
  }
18684
18829
  )
18685
18830
  ] }) })
@@ -23323,6 +23468,7 @@ export {
23323
23468
  Button,
23324
23469
  ButtonElement,
23325
23470
  Card,
23471
+ CheckoutDialog,
23326
23472
  Column,
23327
23473
  Container,
23328
23474
  Element,
@@ -23356,6 +23502,7 @@ export {
23356
23502
  UpcomingBill,
23357
23503
  Viewport,
23358
23504
  cardBoxShadow,
23505
+ createActiveUsageBasedEntitlementsReducer,
23359
23506
  defaultSettings,
23360
23507
  defaultTheme,
23361
23508
  iconsList,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-components",
3
- "version": "1.3.0",
3
+ "version": "1.4.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,10 +34,10 @@
34
34
  "dependencies": {
35
35
  "@schematichq/schematic-icons": "^0.5.2",
36
36
  "@stripe/stripe-js": "^7.8.0",
37
- "i18next": "^25.3.4",
37
+ "i18next": "^25.4.0",
38
38
  "lodash": "^4.17.21",
39
39
  "pako": "^2.1.0",
40
- "react-i18next": "^15.6.1",
40
+ "react-i18next": "^15.7.0",
41
41
  "styled-components": "^6.1.19",
42
42
  "uuid": "^11.1.0"
43
43
  },
@@ -45,15 +45,15 @@
45
45
  "@eslint/js": "^9.33.0",
46
46
  "@eslint/json": "^0.13.0",
47
47
  "@eslint/markdown": "^7.1.0",
48
- "@microsoft/api-extractor": "^7.52.10",
49
- "@openapitools/openapi-generator-cli": "^2.21.4",
50
- "@stripe/react-stripe-js": "^3.9.0",
48
+ "@microsoft/api-extractor": "^7.52.11",
49
+ "@openapitools/openapi-generator-cli": "^2.22.0",
50
+ "@stripe/react-stripe-js": "^3.9.1",
51
51
  "@types/jest": "^30.0.0",
52
52
  "@types/lodash": "^4.17.20",
53
- "@types/pako": "^2.0.3",
54
- "@types/react": "^19.1.9",
53
+ "@types/pako": "^2.0.4",
54
+ "@types/react": "^19.1.10",
55
55
  "@types/react-dom": "^19.1.7",
56
- "esbuild": "^0.25.8",
56
+ "esbuild": "^0.25.9",
57
57
  "eslint": "^9.33.0",
58
58
  "eslint-import-resolver-typescript": "^4.4.4",
59
59
  "eslint-plugin-import": "^2.32.0",
@@ -69,7 +69,7 @@
69
69
  "react-dom": "^19.1.1",
70
70
  "ts-jest": "^29.4.1",
71
71
  "typescript": "^5.9.2",
72
- "typescript-eslint": "^8.39.0"
72
+ "typescript-eslint": "^8.40.0"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@stripe/react-stripe-js": ">=3",