@solvapay/react 1.0.1-preview.2 → 1.0.2

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.
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.tsx
@@ -985,6 +995,7 @@ var PaymentForm = ({
985
995
  };
986
996
 
987
997
  // src/components/ProductBadge.tsx
998
+ var import_react6 = __toESM(require("react"), 1);
988
999
  var import_jsx_runtime5 = require("react/jsx-runtime");
989
1000
  var ProductBadge = ({
990
1001
  children,
@@ -992,8 +1003,14 @@ var ProductBadge = ({
992
1003
  className
993
1004
  }) => {
994
1005
  const { purchases, loading, hasPaidPurchase, activePurchase } = usePurchase();
1006
+ const [hasLoadedOnce, setHasLoadedOnce] = import_react6.default.useState(false);
1007
+ import_react6.default.useEffect(() => {
1008
+ if (!loading) {
1009
+ setHasLoadedOnce(true);
1010
+ }
1011
+ }, [loading]);
995
1012
  const planToDisplay = activePurchase?.productName || null;
996
- const shouldShow = !loading && planToDisplay !== null;
1013
+ const shouldShow = planToDisplay !== null && (!loading || hasLoadedOnce);
997
1014
  if (children) {
998
1015
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: children({ purchases, loading, displayPlan: planToDisplay, shouldShow }) });
999
1016
  }
@@ -1032,35 +1049,35 @@ var PurchaseGate = ({ requirePlan, requireProduct, children }) => {
1032
1049
  };
1033
1050
 
1034
1051
  // src/components/PricingSelector.tsx
1035
- var import_react7 = require("react");
1052
+ var import_react8 = require("react");
1036
1053
 
1037
1054
  // src/hooks/usePlans.ts
1038
- var import_react6 = require("react");
1055
+ var import_react7 = require("react");
1039
1056
  var plansCache = /* @__PURE__ */ new Map();
1040
1057
  var CACHE_DURATION2 = 5 * 60 * 1e3;
1041
1058
  function usePlans(options) {
1042
1059
  const { fetcher, productRef, filter, sortBy, autoSelectFirstPaid = false } = options;
1043
- const [plans, setPlans] = (0, import_react6.useState)([]);
1044
- const [loading, setLoading] = (0, import_react6.useState)(true);
1045
- const [error, setError] = (0, import_react6.useState)(null);
1046
- const [selectedPlanIndex, setSelectedPlanIndex] = (0, import_react6.useState)(0);
1047
- const fetcherRef = (0, import_react6.useRef)(fetcher);
1048
- const filterRef = (0, import_react6.useRef)(filter);
1049
- const sortByRef = (0, import_react6.useRef)(sortBy);
1050
- const autoSelectFirstPaidRef = (0, import_react6.useRef)(autoSelectFirstPaid);
1051
- (0, import_react6.useEffect)(() => {
1060
+ const [plans, setPlans] = (0, import_react7.useState)([]);
1061
+ const [loading, setLoading] = (0, import_react7.useState)(true);
1062
+ const [error, setError] = (0, import_react7.useState)(null);
1063
+ const [selectedPlanIndex, setSelectedPlanIndex] = (0, import_react7.useState)(0);
1064
+ const fetcherRef = (0, import_react7.useRef)(fetcher);
1065
+ const filterRef = (0, import_react7.useRef)(filter);
1066
+ const sortByRef = (0, import_react7.useRef)(sortBy);
1067
+ const autoSelectFirstPaidRef = (0, import_react7.useRef)(autoSelectFirstPaid);
1068
+ (0, import_react7.useEffect)(() => {
1052
1069
  fetcherRef.current = fetcher;
1053
1070
  }, [fetcher]);
1054
- (0, import_react6.useEffect)(() => {
1071
+ (0, import_react7.useEffect)(() => {
1055
1072
  filterRef.current = filter;
1056
1073
  }, [filter]);
1057
- (0, import_react6.useEffect)(() => {
1074
+ (0, import_react7.useEffect)(() => {
1058
1075
  sortByRef.current = sortBy;
1059
1076
  }, [sortBy]);
1060
- (0, import_react6.useEffect)(() => {
1077
+ (0, import_react7.useEffect)(() => {
1061
1078
  autoSelectFirstPaidRef.current = autoSelectFirstPaid;
1062
1079
  }, [autoSelectFirstPaid]);
1063
- const fetchPlans = (0, import_react6.useCallback)(
1080
+ const fetchPlans = (0, import_react7.useCallback)(
1064
1081
  async (force = false) => {
1065
1082
  if (!productRef) {
1066
1083
  setError(new Error("Product reference not configured"));
@@ -1138,13 +1155,13 @@ function usePlans(options) {
1138
1155
  },
1139
1156
  [productRef]
1140
1157
  );
1141
- (0, import_react6.useEffect)(() => {
1158
+ (0, import_react7.useEffect)(() => {
1142
1159
  fetchPlans();
1143
1160
  }, [fetchPlans]);
1144
- const selectedPlan = (0, import_react6.useMemo)(() => {
1161
+ const selectedPlan = (0, import_react7.useMemo)(() => {
1145
1162
  return plans[selectedPlanIndex] || null;
1146
1163
  }, [plans, selectedPlanIndex]);
1147
- const selectPlan = (0, import_react6.useCallback)(
1164
+ const selectPlan = (0, import_react7.useCallback)(
1148
1165
  (planRef) => {
1149
1166
  const index = plans.findIndex((p) => p.reference === planRef);
1150
1167
  if (index >= 0) {
@@ -1185,20 +1202,20 @@ var PricingSelector = ({
1185
1202
  autoSelectFirstPaid
1186
1203
  });
1187
1204
  const { plans } = plansHook;
1188
- const isPaidPlan = (0, import_react7.useCallback)(
1205
+ const isPaidPlan = (0, import_react8.useCallback)(
1189
1206
  (planRef) => {
1190
1207
  const plan = plans.find((p) => p.reference === planRef);
1191
1208
  return plan ? (plan.price ?? 0) > 0 && !plan.isFreeTier : true;
1192
1209
  },
1193
1210
  [plans]
1194
1211
  );
1195
- const activePurchase = (0, import_react7.useMemo)(() => {
1212
+ const activePurchase = (0, import_react8.useMemo)(() => {
1196
1213
  const activePurchases = purchases.filter((p) => p.status === "active");
1197
1214
  return activePurchases.sort(
1198
1215
  (a, b) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime()
1199
1216
  )[0] || null;
1200
1217
  }, [purchases]);
1201
- const isCurrentPlan = (0, import_react7.useCallback)(
1218
+ const isCurrentPlan = (0, import_react8.useCallback)(
1202
1219
  (planRef) => {
1203
1220
  return activePurchase?.planSnapshot?.reference === planRef;
1204
1221
  },
@@ -1214,13 +1231,13 @@ var PricingSelector = ({
1214
1231
  var PlanSelector = PricingSelector;
1215
1232
 
1216
1233
  // src/hooks/usePurchaseStatus.ts
1217
- var import_react8 = require("react");
1234
+ var import_react9 = require("react");
1218
1235
  function usePurchaseStatus() {
1219
1236
  const { purchases } = usePurchase();
1220
- const isPaidPurchase2 = (0, import_react8.useCallback)((p) => {
1237
+ const isPaidPurchase2 = (0, import_react9.useCallback)((p) => {
1221
1238
  return (p.amount ?? 0) > 0;
1222
1239
  }, []);
1223
- const purchaseData = (0, import_react8.useMemo)(() => {
1240
+ const purchaseData = (0, import_react9.useMemo)(() => {
1224
1241
  const cancelledPaidPurchases = purchases.filter((p) => {
1225
1242
  return p.status === "active" && p.cancelledAt && isPaidPurchase2(p);
1226
1243
  });
@@ -1233,7 +1250,7 @@ function usePurchaseStatus() {
1233
1250
  shouldShowCancelledNotice
1234
1251
  };
1235
1252
  }, [purchases, isPaidPurchase2]);
1236
- const formatDate = (0, import_react8.useCallback)((dateString) => {
1253
+ const formatDate = (0, import_react9.useCallback)((dateString) => {
1237
1254
  if (!dateString) return null;
1238
1255
  return new Date(dateString).toLocaleDateString("en-US", {
1239
1256
  year: "numeric",
@@ -1241,7 +1258,7 @@ function usePurchaseStatus() {
1241
1258
  day: "numeric"
1242
1259
  });
1243
1260
  }, []);
1244
- const getDaysUntilExpiration = (0, import_react8.useCallback)((endDate) => {
1261
+ const getDaysUntilExpiration = (0, import_react9.useCallback)((endDate) => {
1245
1262
  if (!endDate) return null;
1246
1263
  const now = /* @__PURE__ */ new Date();
1247
1264
  const expiration = new Date(endDate);
package/dist/index.d.cts CHANGED
@@ -512,7 +512,8 @@ declare const PaymentForm: React$1.FC<PaymentFormProps>;
512
512
  * Displays purchase status with complete styling control.
513
513
  * Supports render props, custom components, or className patterns.
514
514
  *
515
- * Hidden while loading or when no active purchase exists to prevent flickering.
515
+ * Hidden before initial data load or when no active purchase exists.
516
+ * Remains visible during background refetches to avoid flickering.
516
517
  *
517
518
  * @example
518
519
  * ```tsx
package/dist/index.d.ts CHANGED
@@ -512,7 +512,8 @@ declare const PaymentForm: React$1.FC<PaymentFormProps>;
512
512
  * Displays purchase status with complete styling control.
513
513
  * Supports render props, custom components, or className patterns.
514
514
  *
515
- * Hidden while loading or when no active purchase exists to prevent flickering.
515
+ * Hidden before initial data load or when no active purchase exists.
516
+ * Remains visible during background refetches to avoid flickering.
516
517
  *
517
518
  * @example
518
519
  * ```tsx
package/dist/index.js CHANGED
@@ -920,6 +920,7 @@ var PaymentForm = ({
920
920
  };
921
921
 
922
922
  // src/components/ProductBadge.tsx
923
+ import React4 from "react";
923
924
  import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
924
925
  var ProductBadge = ({
925
926
  children,
@@ -927,8 +928,14 @@ var ProductBadge = ({
927
928
  className
928
929
  }) => {
929
930
  const { purchases, loading, hasPaidPurchase, activePurchase } = usePurchase();
931
+ const [hasLoadedOnce, setHasLoadedOnce] = React4.useState(false);
932
+ React4.useEffect(() => {
933
+ if (!loading) {
934
+ setHasLoadedOnce(true);
935
+ }
936
+ }, [loading]);
930
937
  const planToDisplay = activePurchase?.productName || null;
931
- const shouldShow = !loading && planToDisplay !== null;
938
+ const shouldShow = planToDisplay !== null && (!loading || hasLoadedOnce);
932
939
  if (children) {
933
940
  return /* @__PURE__ */ jsx5(Fragment2, { children: children({ purchases, loading, displayPlan: planToDisplay, shouldShow }) });
934
941
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solvapay/react",
3
- "version": "1.0.1-preview.2",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -51,7 +51,7 @@
51
51
  "react-dom": "^19.2.4",
52
52
  "typescript": "^5.9.3",
53
53
  "vitest": "^4.1.2",
54
- "@solvapay/server": "1.0.1-preview.2",
54
+ "@solvapay/server": "1.0.2",
55
55
  "@solvapay/test-utils": "0.0.0"
56
56
  },
57
57
  "scripts": {