@schematichq/schematic-components 1.4.2 → 1.4.3

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.
@@ -1852,7 +1852,7 @@ var HOURS_IN_MS = MINUTES_IN_MS * 60;
1852
1852
  var DAYS_IN_MS = HOURS_IN_MS * 24;
1853
1853
 
1854
1854
  // src/const/debounce.ts
1855
- var debounceOptions = {
1855
+ var DEBOUNCE_SETTINGS = {
1856
1856
  leading: true,
1857
1857
  trailing: false
1858
1858
  };
@@ -4207,6 +4207,7 @@ var initialContext = {
4207
4207
  hydrateComponent: stub,
4208
4208
  hydrateExternal: stub,
4209
4209
  getUpcomingInvoice: stub,
4210
+ getCustomerBalance: stub,
4210
4211
  listInvoices: stub,
4211
4212
  createSetupIntent: stub,
4212
4213
  updatePaymentMethod: stub,
@@ -4219,7 +4220,8 @@ var initialContext = {
4219
4220
  setLayout: stub,
4220
4221
  setCheckoutState: stub,
4221
4222
  setData: stub,
4222
- updateSettings: stub
4223
+ updateSettings: stub,
4224
+ debug: stub
4223
4225
  };
4224
4226
  var EmbedContext = createContext(initialContext);
4225
4227
 
@@ -6713,8 +6715,10 @@ var en_default = {
6713
6715
  "Choose add-on": "Choose add-on",
6714
6716
  "Choose plan": "Choose plan",
6715
6717
  "Choose your base plan": "Choose your base plan",
6716
- "Credits to be applied to future invoices": "Credits to be applied to future invoices",
6718
+ "Credit bundles": "Credit bundles",
6717
6719
  Credits: "Credits",
6720
+ "Credits in plan": "Credits in plan",
6721
+ "Credits to be applied to future invoices": "Credits to be applied to future invoices",
6718
6722
  "Current plan": "Current plan",
6719
6723
  "Current usage exceeds the limit of this plan.": "Current usage exceeds the limit of this plan.",
6720
6724
  "Currently using": "Currently using {{quantity}} {{unit}}",
@@ -6765,8 +6769,10 @@ var en_default = {
6765
6769
  "Please provide an access token.": "Please provide an access token.",
6766
6770
  "Powered by": "Powered by",
6767
6771
  "Price by unit based on final tier reached.": "Price by unit based on final tier reached.",
6772
+ "Promotional credits": "Promotional credits",
6768
6773
  Proration: "Proration",
6769
6774
  "Quantity to pay for in advance": "Quantity to pay for in advance",
6775
+ "Remaining balance": "Remaining balance",
6770
6776
  "Remove add-on": "Remove add-on",
6771
6777
  Resets: "Resets {{date}}",
6772
6778
  "Save payment method": "Save payment method",
@@ -10462,7 +10468,7 @@ var EmbedProvider = ({
10462
10468
  });
10463
10469
  const customHeaders = useMemo3(
10464
10470
  () => ({
10465
- "X-Schematic-Components-Version": "1.4.2",
10471
+ "X-Schematic-Components-Version": "1.4.3",
10466
10472
  "X-Schematic-Session-ID": sessionIdRef.current
10467
10473
  }),
10468
10474
  []
@@ -10495,7 +10501,7 @@ var EmbedProvider = ({
10495
10501
  }
10496
10502
  }, [api.public]);
10497
10503
  const debouncedHydratePublic = useMemo3(
10498
- () => (0, import_debounce.default)(hydratePublic, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10504
+ () => (0, import_debounce.default)(hydratePublic, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10499
10505
  [hydratePublic]
10500
10506
  );
10501
10507
  const hydrate = useCallback3(async () => {
@@ -10517,7 +10523,7 @@ var EmbedProvider = ({
10517
10523
  }
10518
10524
  }, [api.checkout]);
10519
10525
  const debouncedHydrate = useMemo3(
10520
- () => (0, import_debounce.default)(hydrate, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10526
+ () => (0, import_debounce.default)(hydrate, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10521
10527
  [hydrate]
10522
10528
  );
10523
10529
  const hydrateComponent = useCallback3(
@@ -10544,7 +10550,7 @@ var EmbedProvider = ({
10544
10550
  [api.checkout]
10545
10551
  );
10546
10552
  const debouncedHydrateComponent = useMemo3(
10547
- () => (0, import_debounce.default)(hydrateComponent, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10553
+ () => (0, import_debounce.default)(hydrateComponent, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10548
10554
  [hydrateComponent]
10549
10555
  );
10550
10556
  const hydrateExternal = useCallback3(async function(fn) {
@@ -10564,14 +10570,14 @@ var EmbedProvider = ({
10564
10570
  }
10565
10571
  }, []);
10566
10572
  const debouncedHydrateExternal = useMemo3(
10567
- () => (0, import_debounce.default)(hydrateExternal, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10573
+ () => (0, import_debounce.default)(hydrateExternal, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10568
10574
  [hydrateExternal]
10569
10575
  );
10570
10576
  const createSetupIntent = useCallback3(async () => {
10571
10577
  return api.checkout?.createSetupIntent();
10572
10578
  }, [api.checkout]);
10573
10579
  const debouncedCreateSetupIntent = useMemo3(
10574
- () => (0, import_debounce.default)(createSetupIntent, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10580
+ () => (0, import_debounce.default)(createSetupIntent, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10575
10581
  [createSetupIntent]
10576
10582
  );
10577
10583
  const updatePaymentMethod = useCallback3(
@@ -10590,7 +10596,7 @@ var EmbedProvider = ({
10590
10596
  [api.checkout]
10591
10597
  );
10592
10598
  const debouncedUpdatePaymentMethod = useMemo3(
10593
- () => (0, import_debounce.default)(updatePaymentMethod, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10599
+ () => (0, import_debounce.default)(updatePaymentMethod, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10594
10600
  [updatePaymentMethod]
10595
10601
  );
10596
10602
  const deletePaymentMethod = useCallback3(
@@ -10609,7 +10615,7 @@ var EmbedProvider = ({
10609
10615
  [api.checkout]
10610
10616
  );
10611
10617
  const debouncedDeletePaymentMethod = useMemo3(
10612
- () => (0, import_debounce.default)(deletePaymentMethod, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10618
+ () => (0, import_debounce.default)(deletePaymentMethod, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10613
10619
  [deletePaymentMethod]
10614
10620
  );
10615
10621
  const checkout = useCallback3(
@@ -10628,7 +10634,7 @@ var EmbedProvider = ({
10628
10634
  [api.checkout]
10629
10635
  );
10630
10636
  const debouncedCheckout = useMemo3(
10631
- () => (0, import_debounce.default)(checkout, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10637
+ () => (0, import_debounce.default)(checkout, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10632
10638
  [checkout]
10633
10639
  );
10634
10640
  const previewCheckout = useCallback3(
@@ -10638,7 +10644,12 @@ var EmbedProvider = ({
10638
10644
  [api.checkout]
10639
10645
  );
10640
10646
  const debouncedPreviewCheckout = useMemo3(
10641
- () => (0, import_debounce.default)(previewCheckout, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10647
+ () => (0, import_debounce.default)(previewCheckout, FETCH_DEBOUNCE_TIMEOUT, {
10648
+ // invoke immediately for minimal latency
10649
+ leading: true,
10650
+ // but also ensure latest data is fetched
10651
+ trailing: true
10652
+ }),
10642
10653
  [previewCheckout]
10643
10654
  );
10644
10655
  const unsubscribe = useCallback3(async () => {
@@ -10652,7 +10663,7 @@ var EmbedProvider = ({
10652
10663
  return response;
10653
10664
  }, [api.checkout]);
10654
10665
  const debouncedUnsubscribe = useMemo3(
10655
- () => (0, import_debounce.default)(unsubscribe, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10666
+ () => (0, import_debounce.default)(unsubscribe, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10656
10667
  [unsubscribe]
10657
10668
  );
10658
10669
  const getUpcomingInvoice = useCallback3(
@@ -10664,19 +10675,30 @@ var EmbedProvider = ({
10664
10675
  [api.checkout]
10665
10676
  );
10666
10677
  const debouncedGetUpcomingInvoice = useMemo3(
10667
- () => (0, import_debounce.default)(getUpcomingInvoice, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10678
+ () => (0, import_debounce.default)(getUpcomingInvoice, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10668
10679
  [getUpcomingInvoice]
10669
10680
  );
10681
+ const getCustomerBalance = useCallback3(async () => {
10682
+ return api.checkout?.fetchCustomerBalance();
10683
+ }, [api.checkout]);
10684
+ const debouncedGetCustomerBalance = useMemo3(
10685
+ () => (0, import_debounce.default)(getCustomerBalance, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10686
+ [getCustomerBalance]
10687
+ );
10670
10688
  const listInvoices = useCallback3(async () => {
10671
10689
  return api.checkout?.listInvoices();
10672
10690
  }, [api.checkout]);
10673
10691
  const debouncedListInvoices = useMemo3(
10674
- () => (0, import_debounce.default)(listInvoices, FETCH_DEBOUNCE_TIMEOUT, debounceOptions),
10692
+ () => (0, import_debounce.default)(listInvoices, FETCH_DEBOUNCE_TIMEOUT, DEBOUNCE_SETTINGS),
10675
10693
  [listInvoices]
10676
10694
  );
10677
- const setError = useCallback3((error) => {
10678
- dispatch({ type: "ERROR", error });
10679
- }, []);
10695
+ const setError = useCallback3(
10696
+ (error) => {
10697
+ debug(error.message);
10698
+ dispatch({ type: "ERROR", error });
10699
+ },
10700
+ [debug]
10701
+ );
10680
10702
  const setAccessToken = useCallback3((token2) => {
10681
10703
  dispatch({ type: "SET_ACCESS_TOKEN", token: token2 });
10682
10704
  }, []);
@@ -10701,13 +10723,13 @@ var EmbedProvider = ({
10701
10723
  );
10702
10724
  if (element) {
10703
10725
  styleRef.current = element;
10704
- return;
10726
+ } else {
10727
+ const style = document.createElement("link");
10728
+ style.id = "schematic-fonts";
10729
+ style.rel = "stylesheet";
10730
+ document.head.appendChild(style);
10731
+ styleRef.current = style;
10705
10732
  }
10706
- const style = document.createElement("link");
10707
- style.id = "schematic-fonts";
10708
- style.rel = "stylesheet";
10709
- document.head.appendChild(style);
10710
- styleRef.current = style;
10711
10733
  const darkModeQuery = matchMedia("(prefers-color-scheme: dark)");
10712
10734
  const colorMode = darkModeQuery.matches ? "dark" : "light";
10713
10735
  dispatch({
@@ -10718,13 +10740,17 @@ var EmbedProvider = ({
10718
10740
  }
10719
10741
  }
10720
10742
  });
10721
- darkModeQuery.addEventListener("change", (event) => {
10743
+ function darkModeQueryHandler(event) {
10722
10744
  const newColorMode = event.matches ? "dark" : "light";
10723
10745
  dispatch({
10724
10746
  type: "UPDATE_SETTINGS",
10725
10747
  settings: { theme: { colorMode: newColorMode } }
10726
10748
  });
10727
- });
10749
+ }
10750
+ darkModeQuery.addEventListener("change", darkModeQueryHandler);
10751
+ return () => {
10752
+ darkModeQuery.removeEventListener("change", darkModeQueryHandler);
10753
+ };
10728
10754
  }, []);
10729
10755
  useEffect2(() => {
10730
10756
  const fontSet = /* @__PURE__ */ new Set([]);
@@ -10770,24 +10796,19 @@ var EmbedProvider = ({
10770
10796
  }));
10771
10797
  }
10772
10798
  }, [state.accessToken, apiConfig, customHeaders]);
10773
- useEffect2(() => {
10774
- if (state.error) {
10775
- debug(state.error.message);
10776
- }
10777
- }, [debug, state.error]);
10778
10799
  useEffect2(() => {
10779
10800
  const providedSettings = { ...options.settings || {} };
10780
10801
  updateSettings(providedSettings, { update: false });
10781
10802
  }, [options.settings, updateSettings]);
10782
10803
  useEffect2(() => {
10783
- const planChanged = (event) => {
10804
+ function planChangedHandler(event) {
10784
10805
  if (event instanceof CustomEvent) {
10785
10806
  debug("plan changed", event.detail);
10786
10807
  }
10787
- };
10788
- window.addEventListener("plan-changed", planChanged);
10808
+ }
10809
+ window.addEventListener("plan-changed", planChangedHandler);
10789
10810
  return () => {
10790
- window.removeEventListener("plan-changed", planChanged);
10811
+ window.removeEventListener("plan-changed", planChangedHandler);
10791
10812
  };
10792
10813
  }, [debug]);
10793
10814
  return /* @__PURE__ */ jsx(
@@ -10812,13 +10833,15 @@ var EmbedProvider = ({
10812
10833
  previewCheckout: debouncedPreviewCheckout,
10813
10834
  unsubscribe: debouncedUnsubscribe,
10814
10835
  getUpcomingInvoice: debouncedGetUpcomingInvoice,
10836
+ getCustomerBalance: debouncedGetCustomerBalance,
10815
10837
  listInvoices: debouncedListInvoices,
10816
10838
  setError,
10817
10839
  setAccessToken,
10818
10840
  setLayout,
10819
10841
  setCheckoutState,
10820
10842
  setData,
10821
- updateSettings
10843
+ updateSettings,
10844
+ debug
10822
10845
  },
10823
10846
  children: /* @__PURE__ */ jsxs(ot, { theme: state.settings.theme, children: [
10824
10847
  /* @__PURE__ */ jsx(IconStyles, {}),
@@ -14663,11 +14686,12 @@ var CheckoutDialog = ({ top = 0 }) => {
14663
14686
  const entitlements = plan.entitlements.reduce(
14664
14687
  (acc, entitlement) => {
14665
14688
  if (entitlement.priceBehavior && (period === "month" && entitlement.meteredMonthlyPrice || period === "year" && entitlement.meteredYearlyPrice)) {
14689
+ const allocation = entitlement.valueNumeric || 0;
14666
14690
  acc.push({
14667
14691
  ...entitlement,
14668
- allocation: entitlement.valueNumeric || 0,
14692
+ allocation,
14669
14693
  usage: 0,
14670
- quantity: 0
14694
+ quantity: allocation
14671
14695
  });
14672
14696
  }
14673
14697
  return acc;
@@ -17757,11 +17781,29 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
17757
17781
  featureUsage: featureUsage2,
17758
17782
  trialPaymentMethodRequired: trialPaymentMethodRequired2
17759
17783
  } = data;
17784
+ const creditGroups2 = groupCreditGrants(creditGrants, {
17785
+ groupBy: "bundle"
17786
+ }).reduce(
17787
+ (acc, grant) => {
17788
+ switch (grant.grantReason) {
17789
+ case "plan" /* Plan */:
17790
+ acc.plan.push(grant);
17791
+ break;
17792
+ case "purchased" /* Purchased */:
17793
+ acc.bundles.push(grant);
17794
+ break;
17795
+ case "free" /* Free */:
17796
+ acc.promotional.push(grant);
17797
+ }
17798
+ return acc;
17799
+ },
17800
+ { plan: [], bundles: [], promotional: [] }
17801
+ );
17760
17802
  return {
17761
17803
  currentPlan: company?.plan,
17762
17804
  currentAddOns: company?.addOns || [],
17763
17805
  creditBundles: creditBundles2,
17764
- creditGroups: groupCreditGrants(creditGrants, { groupBy: "bundle" }),
17806
+ creditGroups: creditGroups2,
17765
17807
  billingSubscription: company?.billingSubscription,
17766
17808
  canCheckout: capabilities?.checkout ?? true,
17767
17809
  defaultPlan: defaultPlan2,
@@ -17773,7 +17815,7 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
17773
17815
  currentPlan: void 0,
17774
17816
  currentAddOns: [],
17775
17817
  creditBundles: [],
17776
- creditGroups: [],
17818
+ creditGroups: { plan: [], bundles: [], promotional: [] },
17777
17819
  billingSubscription: void 0,
17778
17820
  canCheckout: false,
17779
17821
  defaultPlan: void 0,
@@ -17930,77 +17972,151 @@ var PlanManager = forwardRef11(({ children, className, portal, ...rest }, ref) =
17930
17972
  );
17931
17973
  }) })
17932
17974
  ] }),
17933
- props.addOns.isVisible && creditGroups.length > 0 && /* @__PURE__ */ jsxs34(Flex, { $flexDirection: "column", $gap: "0.5rem", children: [
17975
+ props.addOns.isVisible && creditGroups.plan.length > 0 && /* @__PURE__ */ jsxs34(Flex, { $flexDirection: "column", $gap: "0.5rem", children: [
17934
17976
  props.addOns.showLabel && /* @__PURE__ */ jsx42(
17935
17977
  Text,
17936
17978
  {
17937
17979
  $color: isLightBackground ? darken(settings.theme.card.background, 0.46) : lighten(settings.theme.card.background, 0.46),
17938
17980
  $leading: 1,
17939
- children: t2("Credits")
17981
+ children: t2("Credits in plan")
17940
17982
  }
17941
17983
  ),
17942
- /* @__PURE__ */ jsx42(Flex, { $flexDirection: "column", $gap: "1rem", children: creditGroups.reduce(
17943
- (acc, group, groupIndex) => {
17944
- const bundle = group.grantReason === "purchased" /* Purchased */ && group?.bundleId ? creditBundles.find((b2) => b2.id === group.bundleId) : void 0;
17945
- acc.push(
17946
- /* @__PURE__ */ jsxs34(
17947
- Flex,
17948
- {
17949
- $justifyContent: "space-between",
17950
- $alignItems: "center",
17951
- $flexWrap: "wrap",
17952
- $gap: "0.5rem",
17953
- children: [
17954
- group.grantReason === "plan" /* Plan */ ? /* @__PURE__ */ jsxs34(Text, { display: props.addOns.fontStyle, children: [
17955
- group.quantity,
17956
- " ",
17957
- getFeatureName(group, group.quantity),
17984
+ /* @__PURE__ */ jsx42(Flex, { $flexDirection: "column", $gap: "1rem", children: creditGroups.plan.map((group, groupIndex) => {
17985
+ return /* @__PURE__ */ jsxs34(
17986
+ Flex,
17987
+ {
17988
+ $justifyContent: "space-between",
17989
+ $alignItems: "center",
17990
+ $flexWrap: "wrap",
17991
+ $gap: "0.5rem",
17992
+ children: [
17993
+ /* @__PURE__ */ jsxs34(Text, { display: props.addOns.fontStyle, children: [
17994
+ group.quantity,
17995
+ " ",
17996
+ getFeatureName(group, group.quantity),
17997
+ " ",
17998
+ subscriptionInterval && /* @__PURE__ */ jsxs34(Fragment20, { children: [
17999
+ t2("per"),
18000
+ " ",
18001
+ t2(subscriptionInterval)
18002
+ ] })
18003
+ ] }),
18004
+ group.total.used > 0 && /* @__PURE__ */ jsxs34(
18005
+ Text,
18006
+ {
18007
+ style: { opacity: 0.54 },
18008
+ $size: 0.875 * settings.theme.typography.text.fontSize,
18009
+ $color: settings.theme.typography.text.color,
18010
+ children: [
18011
+ group.total.used,
17958
18012
  " ",
17959
- subscriptionInterval && /* @__PURE__ */ jsxs34(Fragment20, { children: [
17960
- t2("per"),
17961
- " ",
17962
- t2(subscriptionInterval)
17963
- ] })
17964
- ] }) : bundle ? /* @__PURE__ */ jsxs34(Text, { display: props.addOns.fontStyle, children: [
17965
- group.grants.length > 1 && /* @__PURE__ */ jsxs34(Text, { style: { opacity: 0.5 }, children: [
17966
- "(",
17967
- group.grants.length,
17968
- ")",
17969
- " "
17970
- ] }),
17971
- bundle.name,
17972
- " (",
17973
- group.quantity,
18013
+ t2("used")
18014
+ ]
18015
+ }
18016
+ )
18017
+ ]
18018
+ },
18019
+ groupIndex
18020
+ );
18021
+ }) })
18022
+ ] }),
18023
+ props.addOns.isVisible && creditGroups.bundles.length > 0 && /* @__PURE__ */ jsxs34(Flex, { $flexDirection: "column", $gap: "0.5rem", children: [
18024
+ props.addOns.showLabel && /* @__PURE__ */ jsx42(
18025
+ Text,
18026
+ {
18027
+ $color: isLightBackground ? darken(settings.theme.card.background, 0.46) : lighten(settings.theme.card.background, 0.46),
18028
+ $leading: 1,
18029
+ children: t2("Credit bundles")
18030
+ }
18031
+ ),
18032
+ /* @__PURE__ */ jsx42(Flex, { $flexDirection: "column", $gap: "1rem", children: creditGroups.bundles.map((group, groupIndex) => {
18033
+ const bundle = group?.bundleId ? creditBundles.find((b2) => b2.id === group.bundleId) : void 0;
18034
+ return /* @__PURE__ */ jsxs34(
18035
+ Flex,
18036
+ {
18037
+ $justifyContent: "space-between",
18038
+ $alignItems: "center",
18039
+ $flexWrap: "wrap",
18040
+ $gap: "0.5rem",
18041
+ children: [
18042
+ bundle ? /* @__PURE__ */ jsxs34(Text, { display: props.addOns.fontStyle, children: [
18043
+ group.grants.length > 1 && /* @__PURE__ */ jsxs34(Text, { style: { opacity: 0.5 }, children: [
18044
+ "(",
18045
+ group.grants.length,
18046
+ ")",
18047
+ " "
18048
+ ] }),
18049
+ bundle.name,
18050
+ " (",
18051
+ group.quantity,
18052
+ " ",
18053
+ getFeatureName(group, group.quantity),
18054
+ ")"
18055
+ ] }) : /* @__PURE__ */ jsxs34(Text, { display: props.addOns.fontStyle, children: [
18056
+ group.quantity,
18057
+ " ",
18058
+ getFeatureName(group, group.quantity)
18059
+ ] }),
18060
+ group.total.used > 0 && /* @__PURE__ */ jsxs34(
18061
+ Text,
18062
+ {
18063
+ style: { opacity: 0.54 },
18064
+ $size: 0.875 * settings.theme.typography.text.fontSize,
18065
+ $color: settings.theme.typography.text.color,
18066
+ children: [
18067
+ group.total.used,
17974
18068
  " ",
17975
- getFeatureName(group, group.quantity),
17976
- ")"
17977
- ] }) : /* @__PURE__ */ jsxs34(Text, { display: props.addOns.fontStyle, children: [
17978
- group.quantity,
18069
+ t2("used")
18070
+ ]
18071
+ }
18072
+ )
18073
+ ]
18074
+ },
18075
+ groupIndex
18076
+ );
18077
+ }) })
18078
+ ] }),
18079
+ props.addOns.isVisible && creditGroups.promotional.length > 0 && /* @__PURE__ */ jsxs34(Flex, { $flexDirection: "column", $gap: "0.5rem", children: [
18080
+ props.addOns.showLabel && /* @__PURE__ */ jsx42(
18081
+ Text,
18082
+ {
18083
+ $color: isLightBackground ? darken(settings.theme.card.background, 0.46) : lighten(settings.theme.card.background, 0.46),
18084
+ $leading: 1,
18085
+ children: t2("Promotional credits")
18086
+ }
18087
+ ),
18088
+ /* @__PURE__ */ jsx42(Flex, { $flexDirection: "column", $gap: "1rem", children: creditGroups.promotional.map((group, groupIndex) => {
18089
+ return /* @__PURE__ */ jsxs34(
18090
+ Flex,
18091
+ {
18092
+ $justifyContent: "space-between",
18093
+ $alignItems: "center",
18094
+ $flexWrap: "wrap",
18095
+ $gap: "0.5rem",
18096
+ children: [
18097
+ /* @__PURE__ */ jsxs34(Text, { display: props.addOns.fontStyle, children: [
18098
+ group.quantity,
18099
+ " ",
18100
+ getFeatureName(group, group.quantity)
18101
+ ] }),
18102
+ group.total.used > 0 && /* @__PURE__ */ jsxs34(
18103
+ Text,
18104
+ {
18105
+ style: { opacity: 0.54 },
18106
+ $size: 0.875 * settings.theme.typography.text.fontSize,
18107
+ $color: settings.theme.typography.text.color,
18108
+ children: [
18109
+ group.total.used,
17979
18110
  " ",
17980
- getFeatureName(group, group.quantity)
17981
- ] }),
17982
- group.total.used > 0 && /* @__PURE__ */ jsxs34(
17983
- Text,
17984
- {
17985
- style: { opacity: 0.54 },
17986
- $size: 0.875 * settings.theme.typography.text.fontSize,
17987
- $color: settings.theme.typography.text.color,
17988
- children: [
17989
- group.total.used,
17990
- " ",
17991
- t2("used")
17992
- ]
17993
- }
17994
- )
17995
- ]
17996
- },
17997
- groupIndex
17998
- )
17999
- );
18000
- return acc;
18001
- },
18002
- []
18003
- ) })
18111
+ t2("used")
18112
+ ]
18113
+ }
18114
+ )
18115
+ ]
18116
+ },
18117
+ groupIndex
18118
+ );
18119
+ }) })
18004
18120
  ] }),
18005
18121
  canCheckout && props.callToAction.isVisible && /* @__PURE__ */ jsx42(
18006
18122
  Button,
@@ -19019,11 +19135,12 @@ function resolveDesignProps11(props) {
19019
19135
  var UpcomingBill = forwardRef15(({ className, ...rest }, ref) => {
19020
19136
  const props = resolveDesignProps11(rest);
19021
19137
  const { t: t2 } = useTranslation();
19022
- const { data, settings, getUpcomingInvoice } = useEmbed();
19138
+ const { data, settings, debug, getUpcomingInvoice, getCustomerBalance } = useEmbed();
19023
19139
  const isLightBackground = useIsLightBackground();
19024
19140
  const [isLoading, setIsLoading] = useState18(false);
19025
19141
  const [error, setError] = useState18();
19026
19142
  const [upcomingInvoice, setUpcomingInvoice] = useState18();
19143
+ const [balances, setBalances] = useState18([]);
19027
19144
  const discounts = useMemo28(() => {
19028
19145
  return (isCheckoutData(data) && data.subscription?.discounts || []).map(
19029
19146
  (discount) => ({
@@ -19052,9 +19169,22 @@ var UpcomingBill = forwardRef15(({ className, ...rest }, ref) => {
19052
19169
  }
19053
19170
  }
19054
19171
  }, [data, getUpcomingInvoice]);
19172
+ const getBalances = useCallback13(async () => {
19173
+ try {
19174
+ const response = await getCustomerBalance();
19175
+ if (response) {
19176
+ setBalances(response.data.balances);
19177
+ }
19178
+ } catch (err2) {
19179
+ debug("Failed to fetch customer balance.", err2);
19180
+ }
19181
+ }, [debug, getCustomerBalance]);
19055
19182
  useEffect9(() => {
19056
19183
  getInvoice();
19057
19184
  }, [getInvoice]);
19185
+ useEffect9(() => {
19186
+ getBalances();
19187
+ }, [getBalances]);
19058
19188
  if (!isCheckoutData(data) || !data.subscription || data.subscription.cancelAt) {
19059
19189
  return null;
19060
19190
  }
@@ -19104,6 +19234,19 @@ var UpcomingBill = forwardRef15(({ className, ...rest }, ref) => {
19104
19234
  ]
19105
19235
  }
19106
19236
  ),
19237
+ balances.length > 0 && /* @__PURE__ */ jsxs39(
19238
+ Flex,
19239
+ {
19240
+ as: TransitionBox,
19241
+ $justifyContent: "space-between",
19242
+ $alignItems: "start",
19243
+ $gap: "1rem",
19244
+ children: [
19245
+ /* @__PURE__ */ jsx49(Text, { $weight: 600, children: t2("Remaining balance") }),
19246
+ /* @__PURE__ */ jsx49(Flex, { $flexDirection: "column", $gap: "0.5rem", children: balances.map((item, idx) => /* @__PURE__ */ jsx49(Text, { children: formatCurrency(item.balance, item.currency) }, idx)) })
19247
+ ]
19248
+ }
19249
+ ),
19107
19250
  discounts.length > 0 && /* @__PURE__ */ jsxs39(
19108
19251
  Flex,
19109
19252
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-components",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "main": "dist/schematic-components.cjs.js",
5
5
  "module": "dist/schematic-components.esm.js",
6
6
  "types": "dist/schematic-components.d.ts",
@@ -33,35 +33,35 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@schematichq/schematic-icons": "^0.5.2",
36
- "@stripe/stripe-js": "^7.8.0",
37
- "i18next": "^25.4.0",
36
+ "@stripe/stripe-js": "^7.9.0",
37
+ "i18next": "^25.4.2",
38
38
  "lodash": "^4.17.21",
39
39
  "pako": "^2.1.0",
40
- "react-i18next": "^15.7.1",
40
+ "react-i18next": "^15.7.3",
41
41
  "styled-components": "^6.1.19",
42
42
  "uuid": "^11.1.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@eslint/js": "^9.33.0",
46
- "@eslint/json": "^0.13.0",
45
+ "@eslint/js": "^9.34.0",
46
+ "@eslint/json": "^0.13.2",
47
47
  "@eslint/markdown": "^7.2.0",
48
48
  "@microsoft/api-extractor": "^7.52.11",
49
- "@openapitools/openapi-generator-cli": "^2.23.0",
50
- "@stripe/react-stripe-js": "^3.9.1",
49
+ "@openapitools/openapi-generator-cli": "^2.23.1",
50
+ "@stripe/react-stripe-js": "^3.9.2",
51
51
  "@types/jest": "^30.0.0",
52
52
  "@types/lodash": "^4.17.20",
53
53
  "@types/pako": "^2.0.4",
54
- "@types/react": "^19.1.11",
55
- "@types/react-dom": "^19.1.7",
54
+ "@types/react": "^19.1.12",
55
+ "@types/react-dom": "^19.1.9",
56
56
  "esbuild": "^0.25.9",
57
- "eslint": "^9.33.0",
57
+ "eslint": "^9.34.0",
58
58
  "eslint-import-resolver-typescript": "^4.4.4",
59
59
  "eslint-plugin-import": "^2.32.0",
60
60
  "eslint-plugin-react": "^7.37.5",
61
61
  "eslint-plugin-react-hooks": "^5.2.0",
62
62
  "globals": "^16.3.0",
63
- "jest": "^30.0.4",
64
- "jest-environment-jsdom": "^30.0.4",
63
+ "jest": "^30.1.1",
64
+ "jest-environment-jsdom": "^30.1.1",
65
65
  "jest-esbuild": "^0.4.0",
66
66
  "jest-fetch-mock": "^3.0.3",
67
67
  "prettier": "^3.6.2",
@@ -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.40.0"
72
+ "typescript-eslint": "^8.41.0"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@stripe/react-stripe-js": ">=3",