@schematichq/schematic-react 0.2.0-rc.8 → 0.2.0-rc.9

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.
@@ -7875,6 +7875,35 @@ function HydrateComponentResponseFromJSONTyped(json, ignoreDiscriminator) {
7875
7875
  };
7876
7876
  }
7877
7877
 
7878
+ // src/api/models/PreviewSubscriptionChangeResponseData.ts
7879
+ function PreviewSubscriptionChangeResponseDataFromJSON(json) {
7880
+ return PreviewSubscriptionChangeResponseDataFromJSONTyped(json, false);
7881
+ }
7882
+ function PreviewSubscriptionChangeResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7883
+ if (json == null) {
7884
+ return json;
7885
+ }
7886
+ return {
7887
+ dueNow: json["due_now"],
7888
+ newCharges: json["new_charges"],
7889
+ proration: json["proration"]
7890
+ };
7891
+ }
7892
+
7893
+ // src/api/models/PreviewCheckoutResponse.ts
7894
+ function PreviewCheckoutResponseFromJSON(json) {
7895
+ return PreviewCheckoutResponseFromJSONTyped(json, false);
7896
+ }
7897
+ function PreviewCheckoutResponseFromJSONTyped(json, ignoreDiscriminator) {
7898
+ if (json == null) {
7899
+ return json;
7900
+ }
7901
+ return {
7902
+ data: PreviewSubscriptionChangeResponseDataFromJSON(json["data"]),
7903
+ params: json["params"]
7904
+ };
7905
+ }
7906
+
7878
7907
  // src/api/apis/CheckoutApi.ts
7879
7908
  var CheckoutApi = class extends BaseAPI {
7880
7909
  /**
@@ -7963,6 +7992,51 @@ var CheckoutApi = class extends BaseAPI {
7963
7992
  );
7964
7993
  return await response.value();
7965
7994
  }
7995
+ /**
7996
+ * Preview checkout
7997
+ */
7998
+ async previewCheckoutRaw(requestParameters, initOverrides) {
7999
+ if (requestParameters["changeSubscriptionRequestBody"] == null) {
8000
+ throw new RequiredError(
8001
+ "changeSubscriptionRequestBody",
8002
+ 'Required parameter "changeSubscriptionRequestBody" was null or undefined when calling previewCheckout().'
8003
+ );
8004
+ }
8005
+ const queryParameters = {};
8006
+ const headerParameters = {};
8007
+ headerParameters["Content-Type"] = "application/json";
8008
+ if (this.configuration && this.configuration.apiKey) {
8009
+ headerParameters["X-Schematic-Api-Key"] = await this.configuration.apiKey(
8010
+ "X-Schematic-Api-Key"
8011
+ );
8012
+ }
8013
+ const response = await this.request(
8014
+ {
8015
+ path: `/checkout/preview`,
8016
+ method: "POST",
8017
+ headers: headerParameters,
8018
+ query: queryParameters,
8019
+ body: ChangeSubscriptionRequestBodyToJSON(
8020
+ requestParameters["changeSubscriptionRequestBody"]
8021
+ )
8022
+ },
8023
+ initOverrides
8024
+ );
8025
+ return new JSONApiResponse(
8026
+ response,
8027
+ (jsonValue) => PreviewCheckoutResponseFromJSON(jsonValue)
8028
+ );
8029
+ }
8030
+ /**
8031
+ * Preview checkout
8032
+ */
8033
+ async previewCheckout(requestParameters, initOverrides) {
8034
+ const response = await this.previewCheckoutRaw(
8035
+ requestParameters,
8036
+ initOverrides
8037
+ );
8038
+ return await response.value();
8039
+ }
7966
8040
  };
7967
8041
 
7968
8042
  // src/context/embed.tsx
@@ -9707,11 +9781,19 @@ function toPrettyDate(date) {
9707
9781
  year: "numeric"
9708
9782
  }).format(new Date(date));
9709
9783
  }
9784
+ function getMonthName(date) {
9785
+ return new Intl.DateTimeFormat("en-US", {
9786
+ month: "long"
9787
+ }).format(new Date(date));
9788
+ }
9710
9789
 
9711
9790
  // src/utils/string.ts
9712
9791
  function camelToHyphen(str) {
9713
9792
  return str.replace(/([a-z][A-Z])/g, (g2) => `${g2[0]}-${g2[1].toLowerCase()}`);
9714
9793
  }
9794
+ function formatNumber(num) {
9795
+ return new Intl.NumberFormat("en-US").format(num);
9796
+ }
9715
9797
  function formatCurrency(amount) {
9716
9798
  try {
9717
9799
  const dollars = amount / 100;
@@ -9740,6 +9822,18 @@ function formatCurrency(amount) {
9740
9822
  }).format(amount / 100);
9741
9823
  }
9742
9824
  }
9825
+ function formatOrdinal(n) {
9826
+ const enOrdinalRules = new Intl.PluralRules("en-US", { type: "ordinal" });
9827
+ const suffixes = /* @__PURE__ */ new Map([
9828
+ ["one", "st"],
9829
+ ["two", "nd"],
9830
+ ["few", "rd"],
9831
+ ["other", "th"]
9832
+ ]);
9833
+ const rule = enOrdinalRules.select(n);
9834
+ const suffix = suffixes.get(rule);
9835
+ return `${n}${suffix}`;
9836
+ }
9743
9837
 
9744
9838
  // src/const/index.ts
9745
9839
  var TEXT_BASE_SIZE = 16;
@@ -10701,8 +10795,8 @@ var FeatureName = ({
10701
10795
  if (entitlement.metricPeriod) {
10702
10796
  period = {
10703
10797
  current_day: "day",
10704
- current_month: "mo",
10705
- current_year: "yr"
10798
+ current_month: "month",
10799
+ current_year: "year"
10706
10800
  }[entitlement.metricPeriod];
10707
10801
  }
10708
10802
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
@@ -10713,12 +10807,8 @@ var FeatureName = ({
10713
10807
  $weight: theme.typography.text.fontWeight,
10714
10808
  $color: theme.typography.text.color,
10715
10809
  children: [
10716
- typeof entitlement.valueNumeric === "number" ? (0, import_pluralize.default)(
10717
- entitlement.feature.name,
10718
- entitlement.valueNumeric,
10719
- true
10720
- ) : `Unlimited ${(0, import_pluralize.default)(entitlement.feature.name)}`,
10721
- period && `/${period}`
10810
+ typeof entitlement.valueNumeric === "number" ? `${formatNumber(entitlement.valueNumeric)} ${(0, import_pluralize.default)(entitlement.feature.name, entitlement.valueNumeric)}` : `Unlimited ${(0, import_pluralize.default)(entitlement.feature.name)}`,
10811
+ period && ` per ${period}`
10722
10812
  ]
10723
10813
  }
10724
10814
  ) });
@@ -10744,6 +10834,7 @@ var CheckoutDialog = () => {
10744
10834
  () => data.company?.plan?.planPeriod || "month"
10745
10835
  );
10746
10836
  const [selectedPlan, setSelectedPlan] = (0, import_react10.useState)();
10837
+ const [charges, setCharges] = (0, import_react10.useState)();
10747
10838
  const [paymentMethodId, setPaymentMethodId] = (0, import_react10.useState)();
10748
10839
  const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
10749
10840
  const [error, setError] = (0, import_react10.useState)();
@@ -10786,9 +10877,54 @@ var CheckoutDialog = () => {
10786
10877
  }
10787
10878
  return 0;
10788
10879
  }, [selectedPlan]);
10880
+ const subscriptionPrice = (0, import_react10.useMemo)(() => {
10881
+ if (!selectedPlan || !selectedPlan.monthlyPrice || !selectedPlan.yearlyPrice) {
10882
+ return;
10883
+ }
10884
+ return formatCurrency(
10885
+ (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price
10886
+ );
10887
+ }, [selectedPlan, planPeriod]);
10789
10888
  const isLightBackground = (0, import_react10.useMemo)(() => {
10790
10889
  return hexToHSL(theme.card.background).l > 50;
10791
10890
  }, [theme.card.background]);
10891
+ const selectPlan = (0, import_react10.useCallback)(
10892
+ async (plan, newPeriod) => {
10893
+ setSelectedPlan(plan);
10894
+ setCharges(void 0);
10895
+ const period = newPeriod || planPeriod;
10896
+ const priceId = (period === "month" ? plan?.monthlyPrice : plan?.yearlyPrice)?.id;
10897
+ if (!priceId || !api) {
10898
+ return;
10899
+ }
10900
+ try {
10901
+ setIsLoading(true);
10902
+ const { data: data2 } = await api.previewCheckout({
10903
+ changeSubscriptionRequestBody: {
10904
+ newPlanId: plan.id,
10905
+ newPriceId: priceId
10906
+ }
10907
+ });
10908
+ setCharges(data2);
10909
+ } catch {
10910
+ setError(
10911
+ "Error retrieving plan details. Please try again in a moment."
10912
+ );
10913
+ } finally {
10914
+ setIsLoading(false);
10915
+ }
10916
+ },
10917
+ [api, planPeriod]
10918
+ );
10919
+ const changePlanPeriod = (0, import_react10.useCallback)(
10920
+ (period) => {
10921
+ setPlanPeriod(period);
10922
+ if (selectedPlan) {
10923
+ selectPlan(selectedPlan, period);
10924
+ }
10925
+ },
10926
+ [selectedPlan, selectPlan]
10927
+ );
10792
10928
  const allowCheckout = api && selectedPlan && selectedPlan?.id !== currentPlan?.id && (paymentMethod && !showPaymentForm || paymentMethodId) && !isLoading;
10793
10929
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Modal, { size: "lg", children: [
10794
10930
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ModalHeader, { bordered: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $gap: "1rem", children: [
@@ -10923,7 +11059,15 @@ var CheckoutDialog = () => {
10923
11059
  }
10924
11060
  )
10925
11061
  ] }),
10926
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $flexWrap: "wrap", $gap: "1rem", $flexGrow: "1", children: availablePlans?.map((plan) => {
11062
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $flexWrap: "wrap", $gap: "1rem", $flexGrow: "1", children: availablePlans.sort((a2, b2) => {
11063
+ if (planPeriod === "year" && a2.yearlyPrice && b2.yearlyPrice) {
11064
+ return a2.yearlyPrice?.price - b2.yearlyPrice?.price;
11065
+ }
11066
+ if (planPeriod === "month" && a2.monthlyPrice && b2.monthlyPrice) {
11067
+ return a2.monthlyPrice.price - b2.monthlyPrice.price;
11068
+ }
11069
+ return 0;
11070
+ }).map((plan) => {
10927
11071
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
10928
11072
  Flex,
10929
11073
  {
@@ -11065,7 +11209,7 @@ var CheckoutDialog = () => {
11065
11209
  {
11066
11210
  disabled: plan.valid === false,
11067
11211
  ...plan.valid === true && {
11068
- onClick: () => setSelectedPlan(plan)
11212
+ onClick: () => selectPlan(plan)
11069
11213
  },
11070
11214
  $size: "sm",
11071
11215
  $color: "primary",
@@ -11180,7 +11324,7 @@ var CheckoutDialog = () => {
11180
11324
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11181
11325
  Flex,
11182
11326
  {
11183
- onClick: () => setPlanPeriod("month"),
11327
+ onClick: () => changePlanPeriod("month"),
11184
11328
  $justifyContent: "center",
11185
11329
  $alignItems: "center",
11186
11330
  $padding: "0.25rem 0.5rem",
@@ -11204,7 +11348,7 @@ var CheckoutDialog = () => {
11204
11348
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11205
11349
  Flex,
11206
11350
  {
11207
- onClick: () => setPlanPeriod("year"),
11351
+ onClick: () => changePlanPeriod("year"),
11208
11352
  $justifyContent: "center",
11209
11353
  $alignItems: "center",
11210
11354
  $padding: "0.25rem 0.5rem",
@@ -11246,7 +11390,7 @@ var CheckoutDialog = () => {
11246
11390
  {
11247
11391
  $flexDirection: "column",
11248
11392
  $position: "relative",
11249
- $gap: "1rem",
11393
+ $gap: "0.5rem",
11250
11394
  $width: "100%",
11251
11395
  $height: "auto",
11252
11396
  $padding: "1.5rem",
@@ -11301,14 +11445,14 @@ var CheckoutDialog = () => {
11301
11445
  }
11302
11446
  ) })
11303
11447
  ] }),
11304
- selectedPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11448
+ selectedPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Box, { $marginBottom: "1rem", children: [
11305
11449
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11306
11450
  Box,
11307
11451
  {
11308
11452
  $width: "100%",
11309
11453
  $textAlign: "left",
11310
11454
  $opacity: "50%",
11311
- $marginBottom: "-0.25rem",
11455
+ $marginBottom: "0.25rem",
11312
11456
  $marginTop: "-0.25rem",
11313
11457
  children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11314
11458
  Icon2,
@@ -11350,6 +11494,51 @@ var CheckoutDialog = () => {
11350
11494
  ) })
11351
11495
  ] })
11352
11496
  ] })
11497
+ ] }),
11498
+ charges?.proration && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11499
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11500
+ Text,
11501
+ {
11502
+ $font: theme.typography.text.fontFamily,
11503
+ $size: 14,
11504
+ $weight: theme.typography.text.fontWeight,
11505
+ $color: theme.typography.text.color,
11506
+ children: charges?.proration && charges.proration > 0 ? "Proration" : "Credits"
11507
+ }
11508
+ ) }),
11509
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { $flexDirection: "column", $gap: "0.5rem", children: currentPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
11510
+ Flex,
11511
+ {
11512
+ $justifyContent: "space-between",
11513
+ $alignItems: "center",
11514
+ $gap: "1rem",
11515
+ children: [
11516
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
11517
+ Text,
11518
+ {
11519
+ $font: theme.typography.heading4.fontFamily,
11520
+ $size: theme.typography.heading4.fontSize,
11521
+ $weight: theme.typography.heading4.fontWeight,
11522
+ $color: theme.typography.heading4.color,
11523
+ children: [
11524
+ "Unused time with ",
11525
+ currentPlan.name
11526
+ ]
11527
+ }
11528
+ ) }),
11529
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Flex, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11530
+ Text,
11531
+ {
11532
+ $font: theme.typography.text.fontFamily,
11533
+ $size: theme.typography.text.fontSize,
11534
+ $weight: theme.typography.text.fontWeight,
11535
+ $color: theme.typography.text.color,
11536
+ children: formatCurrency(charges.proration)
11537
+ }
11538
+ ) })
11539
+ ]
11540
+ }
11541
+ ) })
11353
11542
  ] })
11354
11543
  ]
11355
11544
  }
@@ -11364,7 +11553,7 @@ var CheckoutDialog = () => {
11364
11553
  $height: "auto",
11365
11554
  $padding: "1.5rem",
11366
11555
  children: [
11367
- selectedPlan && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $justifyContent: "space-between", children: [
11556
+ selectedPlan && subscriptionPrice && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $justifyContent: "space-between", children: [
11368
11557
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
11369
11558
  Text,
11370
11559
  {
@@ -11374,8 +11563,7 @@ var CheckoutDialog = () => {
11374
11563
  $color: theme.typography.text.color,
11375
11564
  children: [
11376
11565
  planPeriod === "month" ? "Monthly" : "Yearly",
11377
- " total:",
11378
- " "
11566
+ " total:"
11379
11567
  ]
11380
11568
  }
11381
11569
  ) }),
@@ -11387,15 +11575,35 @@ var CheckoutDialog = () => {
11387
11575
  $weight: theme.typography.text.fontWeight,
11388
11576
  $color: theme.typography.text.color,
11389
11577
  children: [
11390
- formatCurrency(
11391
- (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price ?? 0
11392
- ),
11578
+ subscriptionPrice,
11393
11579
  "/",
11394
11580
  planPeriod
11395
11581
  ]
11396
11582
  }
11397
11583
  ) })
11398
11584
  ] }),
11585
+ charges && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { $justifyContent: "space-between", children: [
11586
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11587
+ Text,
11588
+ {
11589
+ $font: theme.typography.text.fontFamily,
11590
+ $size: theme.typography.text.fontSize,
11591
+ $weight: theme.typography.text.fontWeight,
11592
+ $color: theme.typography.text.color,
11593
+ children: "Due today:"
11594
+ }
11595
+ ) }),
11596
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11597
+ Text,
11598
+ {
11599
+ $font: theme.typography.text.fontFamily,
11600
+ $size: theme.typography.text.fontSize,
11601
+ $weight: theme.typography.text.fontWeight,
11602
+ $color: theme.typography.text.color,
11603
+ children: formatCurrency(charges.dueNow)
11604
+ }
11605
+ ) })
11606
+ ] }),
11399
11607
  checkoutStage === "plan" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11400
11608
  StyledButton,
11401
11609
  {
@@ -11448,24 +11656,25 @@ var CheckoutDialog = () => {
11448
11656
  children: "Pay now"
11449
11657
  }
11450
11658
  ),
11451
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11659
+ !isLoading && error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11452
11660
  Text,
11453
11661
  {
11454
11662
  $font: theme.typography.text.fontFamily,
11455
11663
  $size: theme.typography.text.fontSize,
11456
- $weight: theme.typography.text.fontWeight,
11457
- $color: theme.typography.text.color,
11458
- children: "Discounts & credits applied at checkout"
11664
+ $weight: 500,
11665
+ $color: "#DB6669",
11666
+ children: error
11459
11667
  }
11460
11668
  ) }),
11461
- error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11669
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { $opacity: "0.625", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11462
11670
  Text,
11463
11671
  {
11464
11672
  $font: theme.typography.text.fontFamily,
11465
11673
  $size: theme.typography.text.fontSize,
11466
- $weight: 500,
11467
- $color: "#DB6669",
11468
- children: error
11674
+ $weight: theme.typography.text.fontWeight,
11675
+ $color: theme.typography.text.color,
11676
+ children: checkoutStage === "plan" ? "Discounts & credits applied at checkout" : subscriptionPrice && `You will be billed ${subscriptionPrice} for this subscription
11677
+ every ${planPeriod} on the ${data.subscription?.latestInvoice?.dueDate && formatOrdinal(new Date(data.subscription.latestInvoice.dueDate).getDate())} ${planPeriod === "year" && data.subscription?.latestInvoice?.dueDate ? `of ${getMonthName(data.subscription.latestInvoice.dueDate)}` : ""} unless you unsubscribe.`
11469
11678
  }
11470
11679
  ) })
11471
11680
  ]
@@ -11515,9 +11724,9 @@ var PlanManager = (0, import_react11.forwardRef)(({ children, className, portal,
11515
11724
  const { currentPlan, canChangePlan } = (0, import_react11.useMemo)(() => {
11516
11725
  return {
11517
11726
  currentPlan: data.company?.plan,
11518
- canChangePlan: stripe !== null
11727
+ canChangePlan: data.activePlans.length > 0 && data.stripeEmbed?.publishableKey && data.stripeEmbed?.setupIntentClientSecret && stripe !== null
11519
11728
  };
11520
- }, [data.company, stripe]);
11729
+ }, [data.company, data.activePlans, data.stripeEmbed, stripe]);
11521
11730
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { ref, className, children: [
11522
11731
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
11523
11732
  Flex,
@@ -11620,6 +11829,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11620
11829
  const props = resolveDesignProps3(rest);
11621
11830
  const theme = nt();
11622
11831
  const { data } = useEmbed();
11832
+ const elements = (0, import_react12.useRef)([]);
11623
11833
  const features = (0, import_react12.useMemo)(() => {
11624
11834
  return (data.featureUsage?.features || []).map(
11625
11835
  ({
@@ -11650,6 +11860,34 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11650
11860
  const isLightBackground = (0, import_react12.useMemo)(() => {
11651
11861
  return hexToHSL(theme.card.background).l > 50;
11652
11862
  }, [theme.card.background]);
11863
+ (0, import_react12.useLayoutEffect)(() => {
11864
+ const assignRows = (parent) => {
11865
+ let isWrapped = true;
11866
+ [...parent.children].forEach((el) => {
11867
+ if (!(el instanceof HTMLElement)) {
11868
+ return;
11869
+ }
11870
+ if (!el.previousElementSibling || el.offsetLeft <= el.previousElementSibling.offsetLeft) {
11871
+ isWrapped = !isWrapped;
11872
+ }
11873
+ if (isWrapped) {
11874
+ el.style.textAlign = "left";
11875
+ } else if (el.previousElementSibling) {
11876
+ el.style.textAlign = "right";
11877
+ }
11878
+ });
11879
+ };
11880
+ elements.current.forEach((el) => {
11881
+ if (!el) return;
11882
+ const observer = new ResizeObserver((entries) => {
11883
+ entries.forEach((entry) => {
11884
+ assignRows(entry.target);
11885
+ });
11886
+ });
11887
+ observer.observe(el);
11888
+ assignRows(el);
11889
+ });
11890
+ }, [elements.current.length]);
11653
11891
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Flex, { ref, className, $flexDirection: "column", $gap: "1.5rem", children: [
11654
11892
  props.header.isVisible && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
11655
11893
  Text,
@@ -11671,6 +11909,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11671
11909
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
11672
11910
  Flex,
11673
11911
  {
11912
+ ref: (el) => elements.current.push(el),
11674
11913
  $flexWrap: "wrap",
11675
11914
  $justifyContent: "space-between",
11676
11915
  $alignItems: "center",
@@ -11699,7 +11938,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11699
11938
  }
11700
11939
  ) })
11701
11940
  ] }),
11702
- allocationType === "numeric" && feature?.name && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box, { $textAlign: "right", children: [
11941
+ allocationType === "numeric" && feature?.name && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box, { $textAlign: "right", $paddingLeft: "3.5rem", children: [
11703
11942
  props.entitlement.isVisible && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
11704
11943
  Text,
11705
11944
  {
@@ -11709,7 +11948,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11709
11948
  $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11710
11949
  $lineHeight: 1.5,
11711
11950
  $color: theme.typography[props.entitlement.fontStyle].color,
11712
- children: typeof allocation === "number" ? (0, import_pluralize2.default)(feature.name, allocation, true) : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11951
+ children: typeof allocation === "number" ? `${formatNumber(allocation)} ${(0, import_pluralize2.default)(feature.name, allocation)}` : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11713
11952
  }
11714
11953
  ),
11715
11954
  props.usage.isVisible && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
@@ -11721,7 +11960,7 @@ var IncludedFeatures = (0, import_react12.forwardRef)(({ className, ...rest }, r
11721
11960
  $weight: theme.typography[props.usage.fontStyle].fontWeight,
11722
11961
  $lineHeight: 1.5,
11723
11962
  $color: theme.typography[props.usage.fontStyle].color,
11724
- children: typeof allocation === "number" ? `${usage} of ${allocation} used` : `${usage} used`
11963
+ children: typeof usage === "number" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: typeof allocation === "number" ? `${formatNumber(usage)} of ${formatNumber(allocation)} used` : `${formatNumber(usage)} used` })
11725
11964
  }
11726
11965
  )
11727
11966
  ] })
@@ -11953,14 +12192,19 @@ var UpcomingBill = (0, import_react14.forwardRef)(({ className, ...rest }, ref)
11953
12192
  children: formatCurrency(upcomingInvoice.amountDue)
11954
12193
  }
11955
12194
  ) }),
11956
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
12195
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
11957
12196
  Text,
11958
12197
  {
11959
12198
  $font: theme.typography[props.contractEndDate.fontStyle].fontFamily,
11960
12199
  $size: theme.typography[props.contractEndDate.fontStyle].fontSize,
11961
12200
  $weight: theme.typography[props.contractEndDate.fontStyle].fontWeight,
11962
12201
  $color: theme.typography[props.contractEndDate.fontStyle].color,
11963
- children: "Estimated monthly bill."
12202
+ children: [
12203
+ "Estimated",
12204
+ " ",
12205
+ upcomingInvoice.interval === "year" ? "yearly" : "monthly",
12206
+ " bill."
12207
+ ]
11964
12208
  }
11965
12209
  ) })
11966
12210
  ] })
@@ -12069,10 +12313,10 @@ var Invoices = (0, import_react15.forwardRef)(({ className, ...rest }, ref) => {
12069
12313
  });
12070
12314
 
12071
12315
  // src/components/embed/ComponentTree.tsx
12072
- var import_react23 = require("react");
12316
+ var import_react22 = require("react");
12073
12317
 
12074
12318
  // src/components/embed/renderer.ts
12075
- var import_react22 = require("react");
12319
+ var import_react21 = require("react");
12076
12320
 
12077
12321
  // src/components/layout/root/Root.tsx
12078
12322
  var import_react16 = require("react");
@@ -12096,53 +12340,131 @@ var StyledViewport = dt.div`
12096
12340
  `;
12097
12341
 
12098
12342
  // src/components/layout/RenderLayout.tsx
12099
- var import_react17 = require("react");
12100
12343
  var import_react18 = require("react");
12344
+
12345
+ // src/components/layout/card/Card.tsx
12346
+ var import_react17 = require("react");
12347
+
12348
+ // src/components/layout/card/styles.ts
12349
+ var StyledCard = dt.div(
12350
+ ({
12351
+ theme,
12352
+ $sectionLayout = "merged",
12353
+ $borderRadius = 8,
12354
+ $padding = 48,
12355
+ $shadow = true
12356
+ }) => {
12357
+ return lt`
12358
+ box-sizing: border-box;
12359
+ font-size: ${TEXT_BASE_SIZE}px;
12360
+
12361
+ *,
12362
+ *::before,
12363
+ *::after {
12364
+ box-sizing: inherit;
12365
+ }
12366
+
12367
+ > * {
12368
+ padding: ${$padding * 0.75 / TEXT_BASE_SIZE}rem
12369
+ ${$padding / TEXT_BASE_SIZE}rem;
12370
+ color: ${theme.typography.text.color};
12371
+ }
12372
+
12373
+ ${() => {
12374
+ const { l: l2 } = hexToHSL(theme.card.background);
12375
+ const borderColor = l2 > 50 ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)";
12376
+ const borderRadius = `${$borderRadius / TEXT_BASE_SIZE}rem`;
12377
+ const boxShadow = "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A";
12378
+ if ($sectionLayout === "merged") {
12379
+ return lt`
12380
+ background: ${({ theme: theme2 }) => theme2.card.background};
12381
+ border-radius: ${borderRadius};
12382
+
12383
+ ${$shadow && `box-shadow: ${boxShadow};`}
12384
+
12385
+ > :not(:last-child) {
12386
+ border-bottom: 1px solid ${borderColor};
12387
+ }
12388
+ `;
12389
+ }
12390
+ return lt`
12391
+ > :not(:last-child) {
12392
+ margin-bottom: 1rem;
12393
+ }
12394
+
12395
+ > * {
12396
+ background: ${theme.card.background};
12397
+ border-radius: ${borderRadius};
12398
+ ${$shadow && `box-shadow: ${boxShadow};`}
12399
+ }
12400
+ `;
12401
+ }}
12402
+ `;
12403
+ }
12404
+ );
12405
+
12406
+ // src/components/layout/card/Card.tsx
12101
12407
  var import_jsx_runtime18 = require("react/jsx-runtime");
12102
- var DisabledState = () => {
12408
+ var Card = (0, import_react17.forwardRef)(
12409
+ ({ children, className }, ref) => {
12410
+ const theme = nt();
12411
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12412
+ StyledCard,
12413
+ {
12414
+ ref,
12415
+ className,
12416
+ $sectionLayout: theme?.sectionLayout,
12417
+ $borderRadius: theme?.card?.borderRadius,
12418
+ $padding: theme?.card?.padding,
12419
+ $shadow: theme?.card?.hasShadow,
12420
+ children
12421
+ }
12422
+ );
12423
+ }
12424
+ );
12425
+
12426
+ // src/components/layout/RenderLayout.tsx
12427
+ var import_jsx_runtime19 = require("react/jsx-runtime");
12428
+ var Disabled = () => {
12103
12429
  const theme = nt();
12104
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Box, { $width: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
12430
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $width: "max-content", $height: "max-content", $margin: "0 auto", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
12105
12431
  Flex,
12106
12432
  {
12107
12433
  $flexDirection: "column",
12108
- $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem`,
12109
- $width: "100%",
12110
- $height: "auto",
12111
- $borderRadius: `${theme.card.borderRadius / TEXT_BASE_SIZE}rem`,
12112
- $backgroundColor: theme.card.background,
12113
- $alignItems: "center",
12114
12434
  $justifyContent: "center",
12435
+ $alignItems: "center",
12436
+ $whiteSpace: "nowrap",
12115
12437
  children: [
12116
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12117
- Box,
12438
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $marginBottom: "0.5rem", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12439
+ Text,
12118
12440
  {
12119
- $marginBottom: "8px",
12120
- $fontSize: `${theme.typography.heading1.fontSize / TEXT_BASE_SIZE}rem`,
12121
- $fontFamily: theme.typography.heading1.fontFamily,
12122
- $fontWeight: theme.typography.heading1.fontWeight,
12441
+ as: "h1",
12442
+ $font: theme.typography.heading1.fontFamily,
12443
+ $size: theme.typography.heading1.fontSize,
12444
+ $weight: theme.typography.heading1.fontWeight,
12123
12445
  $color: theme.typography.heading1.color,
12124
- children: "Coming soon"
12446
+ children: "Portal not found"
12125
12447
  }
12126
- ),
12127
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12128
- Box,
12448
+ ) }),
12449
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12450
+ Text,
12129
12451
  {
12130
- $marginBottom: "8px",
12131
- $fontSize: `${theme.typography.text.fontSize / TEXT_BASE_SIZE}rem`,
12132
- $fontFamily: theme.typography.text.fontFamily,
12133
- $fontWeight: theme.typography.text.fontWeight,
12452
+ as: "p",
12453
+ $font: theme.typography.text.fontFamily,
12454
+ $size: theme.typography.text.fontSize,
12455
+ $weight: theme.typography.text.fontWeight,
12134
12456
  $color: theme.typography.text.color,
12135
- children: "The plan manager will be back very soon."
12457
+ children: "Please try again later."
12136
12458
  }
12137
12459
  )
12138
12460
  ]
12139
12461
  }
12140
- ) });
12462
+ ) }) });
12141
12463
  };
12142
- var SuccessState = () => {
12143
- const [isOpen, setIsOpen] = (0, import_react17.useState)(true);
12464
+ var Success = () => {
12144
12465
  const theme = nt();
12145
12466
  const { hydrate, data, api, setLayout, isPending } = useEmbed();
12467
+ const [isOpen, setIsOpen] = (0, import_react18.useState)(true);
12146
12468
  (0, import_react18.useEffect)(() => {
12147
12469
  if (api && data.component?.id) {
12148
12470
  hydrate();
@@ -12154,31 +12476,23 @@ var SuccessState = () => {
12154
12476
  setLayout("portal");
12155
12477
  }
12156
12478
  }, [isPending, isOpen, setLayout]);
12157
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
12479
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $width: "max-content", $height: "max-content", $margin: "0 auto", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Card, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
12158
12480
  Flex,
12159
12481
  {
12160
12482
  $flexDirection: "column",
12161
12483
  $justifyContent: "center",
12162
12484
  $alignItems: "center",
12163
- $gap: `${32 / TEXT_BASE_SIZE}rem`,
12164
- $width: "min-content",
12165
- $height: "min-content",
12166
- $margin: "auto",
12167
- $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem ${theme.card.padding * 1.5 / TEXT_BASE_SIZE}rem`,
12168
12485
  $whiteSpace: "nowrap",
12169
- $backgroundColor: theme.card.background,
12170
- $borderRadius: "0.5rem",
12171
- $boxShadow: "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A;",
12172
12486
  children: [
12173
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12487
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $marginBottom: "1.5rem", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12174
12488
  IconRound,
12175
12489
  {
12176
12490
  name: "check",
12177
12491
  size: "3xl",
12178
12492
  colors: [theme.card.background, theme.primary]
12179
12493
  }
12180
- ),
12181
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12494
+ ) }),
12495
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Box, { $marginBottom: "0.5rem", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12182
12496
  Text,
12183
12497
  {
12184
12498
  as: "h1",
@@ -12188,8 +12502,8 @@ var SuccessState = () => {
12188
12502
  $color: theme.typography.heading1.color,
12189
12503
  children: "Subscription updated!"
12190
12504
  }
12191
- ),
12192
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
12505
+ ) }),
12506
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12193
12507
  Text,
12194
12508
  {
12195
12509
  as: "p",
@@ -12197,126 +12511,45 @@ var SuccessState = () => {
12197
12511
  $size: theme.typography.text.fontSize,
12198
12512
  $weight: theme.typography.text.fontWeight,
12199
12513
  $color: theme.typography.text.color,
12200
- children: "Loading..."
12514
+ children: "Loading\u2026"
12201
12515
  }
12202
12516
  )
12203
12517
  ]
12204
12518
  }
12205
- );
12519
+ ) }) });
12206
12520
  };
12207
12521
  var RenderLayout = ({ children }) => {
12208
12522
  const { layout } = useEmbed();
12209
12523
  switch (layout) {
12210
12524
  case "disabled":
12211
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DisabledState, {});
12525
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Disabled, {});
12212
12526
  case "success":
12213
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SuccessState, {});
12527
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Success, {});
12214
12528
  default:
12215
12529
  return children;
12216
12530
  }
12217
12531
  };
12218
12532
 
12219
12533
  // src/components/layout/viewport/Viewport.tsx
12220
- var import_jsx_runtime19 = require("react/jsx-runtime");
12534
+ var import_jsx_runtime20 = require("react/jsx-runtime");
12221
12535
  var Viewport = (0, import_react19.forwardRef)(
12222
12536
  ({ children, ...props }, ref) => {
12223
12537
  const theme = nt();
12224
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
12538
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12225
12539
  StyledViewport,
12226
12540
  {
12227
12541
  ref,
12228
12542
  $numberOfColumns: theme.numberOfColumns,
12229
12543
  ...props,
12230
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RenderLayout, { children })
12544
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(RenderLayout, { children })
12231
12545
  }
12232
12546
  );
12233
12547
  }
12234
12548
  );
12235
12549
 
12236
12550
  // src/components/layout/column/Column.tsx
12237
- var import_react21 = require("react");
12238
-
12239
- // src/components/layout/card/Card.tsx
12240
12551
  var import_react20 = require("react");
12241
12552
 
12242
- // src/components/layout/card/styles.ts
12243
- var StyledCard = dt.div(
12244
- ({
12245
- theme,
12246
- $sectionLayout = "merged",
12247
- $borderRadius = 8,
12248
- $padding = 48,
12249
- $shadow = true
12250
- }) => {
12251
- return lt`
12252
- box-sizing: border-box;
12253
- font-size: ${TEXT_BASE_SIZE}px;
12254
-
12255
- *,
12256
- *::before,
12257
- *::after {
12258
- box-sizing: inherit;
12259
- }
12260
-
12261
- > * {
12262
- padding: ${$padding * 0.75 / TEXT_BASE_SIZE}rem
12263
- ${$padding / TEXT_BASE_SIZE}rem;
12264
- color: ${theme.typography.text.color};
12265
- }
12266
-
12267
- ${() => {
12268
- const { l: l2 } = hexToHSL(theme.card.background);
12269
- const borderColor = l2 > 50 ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)";
12270
- const borderRadius = `${$borderRadius / TEXT_BASE_SIZE}rem`;
12271
- const boxShadow = "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A";
12272
- if ($sectionLayout === "merged") {
12273
- return lt`
12274
- background: ${({ theme: theme2 }) => theme2.card.background};
12275
- border-radius: ${borderRadius};
12276
-
12277
- ${$shadow && `box-shadow: ${boxShadow};`}
12278
-
12279
- > :not(:last-child) {
12280
- border-bottom: 1px solid ${borderColor};
12281
- }
12282
- `;
12283
- }
12284
- return lt`
12285
- > :not(:last-child) {
12286
- margin-bottom: 1rem;
12287
- }
12288
-
12289
- > * {
12290
- background: ${theme.card.background};
12291
- border-radius: ${borderRadius};
12292
- ${$shadow && `box-shadow: ${boxShadow};`}
12293
- }
12294
- `;
12295
- }}
12296
- `;
12297
- }
12298
- );
12299
-
12300
- // src/components/layout/card/Card.tsx
12301
- var import_jsx_runtime20 = require("react/jsx-runtime");
12302
- var Card = (0, import_react20.forwardRef)(
12303
- ({ children, className }, ref) => {
12304
- const theme = nt();
12305
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12306
- StyledCard,
12307
- {
12308
- ref,
12309
- className,
12310
- $sectionLayout: theme?.sectionLayout,
12311
- $borderRadius: theme?.card?.borderRadius,
12312
- $padding: theme?.card?.padding,
12313
- $shadow: theme?.card?.hasShadow,
12314
- children
12315
- }
12316
- );
12317
- }
12318
- );
12319
-
12320
12553
  // src/components/layout/column/styles.ts
12321
12554
  var StyledColumn = dt.div`
12322
12555
  flex-grow: 1;
@@ -12324,7 +12557,7 @@ var StyledColumn = dt.div`
12324
12557
 
12325
12558
  // src/components/layout/column/Column.tsx
12326
12559
  var import_jsx_runtime21 = require("react/jsx-runtime");
12327
- var Column = (0, import_react21.forwardRef)(
12560
+ var Column = (0, import_react20.forwardRef)(
12328
12561
  ({ children, basis, ...props }, ref) => {
12329
12562
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StyledColumn, { ref, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Card, { children }) });
12330
12563
  }
@@ -12359,7 +12592,7 @@ function createRenderer(options) {
12359
12592
  const { className, ...rest } = props;
12360
12593
  const resolvedProps = component === "div" ? rest : props;
12361
12594
  const resolvedChildren = children.map(renderNode);
12362
- return (0, import_react22.createElement)(
12595
+ return (0, import_react21.createElement)(
12363
12596
  component,
12364
12597
  {
12365
12598
  key: index,
@@ -12429,15 +12662,15 @@ var Error2 = ({ message }) => {
12429
12662
  };
12430
12663
  var ComponentTree = () => {
12431
12664
  const { error, nodes } = useEmbed();
12432
- const [children, setChildren] = (0, import_react23.useState)(/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Loading, {}));
12433
- (0, import_react23.useEffect)(() => {
12665
+ const [children, setChildren] = (0, import_react22.useState)(/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Loading, {}));
12666
+ (0, import_react22.useEffect)(() => {
12434
12667
  const renderer = createRenderer();
12435
12668
  setChildren(nodes.map(renderer));
12436
12669
  }, [nodes]);
12437
12670
  if (error) {
12438
12671
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Error2, { message: error.message });
12439
12672
  }
12440
- if (import_react23.Children.count(children) === 0) {
12673
+ if (import_react22.Children.count(children) === 0) {
12441
12674
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Loading, {});
12442
12675
  }
12443
12676
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children });