@primestyleai/tryon 3.6.5 → 3.7.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.
Files changed (2) hide show
  1. package/dist/react/index.js +51 -21
  2. package/package.json +1 -1
@@ -261,11 +261,11 @@ function PrimeStyleTryonInner({
261
261
  const progressBarRef = useRef(null);
262
262
  const progressTextRef = useRef(null);
263
263
  const progressStatusRef = useRef(null);
264
+ const progressIntervalRef = useRef(null);
264
265
  useEffect(() => {
265
266
  if (view === "processing") {
267
+ if (progressIntervalRef.current) return;
266
268
  progressRef.current = 0;
267
- if (progressBarRef.current) progressBarRef.current.style.width = "0%";
268
- if (progressTextRef.current) progressTextRef.current.textContent = "0%";
269
269
  const statuses = [
270
270
  { at: 0, text: "Preparing your image..." },
271
271
  { at: 15, text: "Analyzing body proportions..." },
@@ -274,7 +274,7 @@ function PrimeStyleTryonInner({
274
274
  { at: 75, text: "Refining details..." },
275
275
  { at: 90, text: "Almost there..." }
276
276
  ];
277
- const interval = setInterval(() => {
277
+ progressIntervalRef.current = setInterval(() => {
278
278
  const p = progressRef.current;
279
279
  if (p >= 100) return;
280
280
  const increment = p < 30 ? 1.2 : p < 60 ? 0.8 : p < 80 ? 0.4 : p < 95 ? 0.15 : 0;
@@ -287,7 +287,15 @@ function PrimeStyleTryonInner({
287
287
  if (status) progressStatusRef.current.textContent = status.text;
288
288
  }
289
289
  }, 200);
290
- return () => clearInterval(interval);
290
+ return () => {
291
+ clearInterval(progressIntervalRef.current);
292
+ progressIntervalRef.current = null;
293
+ };
294
+ } else {
295
+ if (progressIntervalRef.current) {
296
+ clearInterval(progressIntervalRef.current);
297
+ progressIntervalRef.current = null;
298
+ }
291
299
  }
292
300
  }, [view]);
293
301
  useEffect(() => {
@@ -958,9 +966,17 @@ function PrimeStyleTryonInner({
958
966
  sizingMethod === "exact" ? /* @__PURE__ */ jsx(Fragment, { children: (() => {
959
967
  const reqFields = dynamicFields.filter((f) => f.required);
960
968
  const optFields = dynamicFields.filter((f) => !f.required);
969
+ const isShoeProduct = reqFields.some((f) => f.category === "shoe");
970
+ const isClothingProduct = reqFields.some((f) => f.category === "body");
961
971
  const renderField = (field) => {
962
972
  if (["shoeEU", "shoeUS", "shoeUK"].includes(field.key)) {
963
- return /* @__PURE__ */ jsx(InputRow, { label: `${field.label} *`, fieldKey: field.key, placeholder: field.placeholder }, field.key);
973
+ const regionField = shoeField;
974
+ const key = regionField.key;
975
+ const showOriginal = field.key !== key;
976
+ return /* @__PURE__ */ jsxs("span", { children: [
977
+ /* @__PURE__ */ jsx(InputRow, { label: `${regionField.label}${field.required ? " *" : ""}`, fieldKey: key, placeholder: regionField.ph }),
978
+ showOriginal && /* @__PURE__ */ jsx(InputRow, { label: field.label, fieldKey: field.key, placeholder: field.placeholder })
979
+ ] }, field.key);
964
980
  }
965
981
  const phNum = parseFloat(field.placeholder?.replace(/[^0-9.]/g, "") || "");
966
982
  const phIn = !isNaN(phNum) && phNum > 0 && field.unit === "cm" ? String(Math.round(phNum / 2.54)) : "";
@@ -977,6 +993,20 @@ function PrimeStyleTryonInner({
977
993
  field.key
978
994
  );
979
995
  };
996
+ const profileExtras = [];
997
+ if (isShoeProduct && !dynamicFields.some((f) => f.category === "body")) {
998
+ const bodyFields = isFemale ? FALLBACK_FIELDS_FEMALE : FALLBACK_FIELDS_MALE;
999
+ for (const f of bodyFields) {
1000
+ if (!dynamicFields.some((d) => d.key === f.key)) {
1001
+ profileExtras.push({ ...f, required: false });
1002
+ }
1003
+ }
1004
+ }
1005
+ if (isClothingProduct && !dynamicFields.some((f) => f.category === "shoe")) {
1006
+ profileExtras.push({ key: "footLengthCm", label: "Foot length", required: false, unit: "cm", placeholder: "e.g. 27", category: "shoe" });
1007
+ profileExtras.push({ key: shoeField.key, label: shoeField.label, required: false, unit: "size", placeholder: shoeField.ph, category: "shoe" });
1008
+ }
1009
+ const allOptFields = [...optFields, ...profileExtras];
980
1010
  return /* @__PURE__ */ jsxs(Fragment, { children: [
981
1011
  reqFields.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
982
1012
  /* @__PURE__ */ jsx("div", { className: "ps-tryon-section-label", children: "Required for this product" }),
@@ -998,7 +1028,7 @@ function PrimeStyleTryonInner({
998
1028
  fp
999
1029
  )) })
1000
1030
  ] }),
1001
- optFields.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-optional-section", children: [
1031
+ allOptFields.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-optional-section", children: [
1002
1032
  /* @__PURE__ */ jsxs("button", { className: "ps-tryon-optional-toggle", onClick: (e) => {
1003
1033
  const wrap = e.target.closest(".ps-tryon-optional-section").querySelector(".ps-tryon-optional-fields");
1004
1034
  const arrow = e.target.closest(".ps-tryon-optional-toggle").querySelector(".ps-tryon-chevron");
@@ -1011,18 +1041,7 @@ function PrimeStyleTryonInner({
1011
1041
  /* @__PURE__ */ jsx("span", { children: "Optional — improve accuracy & save to profile" }),
1012
1042
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-chevron", children: "▾" })
1013
1043
  ] }),
1014
- /* @__PURE__ */ jsxs("div", { className: "ps-tryon-optional-fields", style: { display: "none" }, children: [
1015
- optFields.map(renderField),
1016
- !dynamicFields.some((f) => f.category === "shoe") && /* @__PURE__ */ jsxs(Fragment, { children: [
1017
- /* @__PURE__ */ jsx(InputRow, { label: "Foot length", fieldKey: "footLengthCm", placeholder: isCm ? "e.g. 27" : "e.g. 10.5", type: "number", unit: sizingUnit }),
1018
- /* @__PURE__ */ jsx(InputRow, { label: shoeField.label, fieldKey: shoeField.key, placeholder: shoeField.ph })
1019
- ] })
1020
- ] })
1021
- ] }),
1022
- optFields.length === 0 && !dynamicFields.some((f) => f.category === "shoe") && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-shoe-section", children: [
1023
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-shoe-title", children: "Shoe sizing (optional)" }),
1024
- /* @__PURE__ */ jsx(InputRow, { label: "Foot length", fieldKey: "footLengthCm", placeholder: isCm ? "e.g. 27" : "e.g. 10.5", type: "number", unit: sizingUnit }),
1025
- /* @__PURE__ */ jsx(InputRow, { label: shoeField.label, fieldKey: shoeField.key, placeholder: shoeField.ph })
1044
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-optional-fields", style: { display: "none" }, children: allOptFields.map(renderField) })
1026
1045
  ] })
1027
1046
  ] });
1028
1047
  })() }) : /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1071,6 +1090,17 @@ function PrimeStyleTryonInner({
1071
1090
  ] }, `form-${formGender}-${sizingUnit}-${heightUnit}-${sizingCountry}-${formKey}`);
1072
1091
  }
1073
1092
  function ProcessingView() {
1093
+ const barCb = useCallback((el) => {
1094
+ progressBarRef.current = el;
1095
+ if (el) el.style.width = `${Math.round(progressRef.current)}%`;
1096
+ }, []);
1097
+ const pctCb = useCallback((el) => {
1098
+ progressTextRef.current = el;
1099
+ if (el) el.textContent = `${Math.round(progressRef.current)}%`;
1100
+ }, []);
1101
+ const statusCb = useCallback((el) => {
1102
+ progressStatusRef.current = el;
1103
+ }, []);
1074
1104
  return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-processing", children: [
1075
1105
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-processing-image-wrap", children: [
1076
1106
  previewUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1081,10 +1111,10 @@ function PrimeStyleTryonInner({
1081
1111
  /* @__PURE__ */ jsx("div", { className: "ps-tryon-scan-overlay" })
1082
1112
  ] }),
1083
1113
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-progress-section", children: [
1084
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-progress-bar-wrap", children: /* @__PURE__ */ jsx("div", { ref: progressBarRef, className: "ps-tryon-progress-bar-fill" }) }),
1085
- /* @__PURE__ */ jsx("span", { ref: progressTextRef, className: "ps-tryon-progress-pct", children: "0%" })
1114
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-progress-bar-wrap", children: /* @__PURE__ */ jsx("div", { ref: barCb, className: "ps-tryon-progress-bar-fill" }) }),
1115
+ /* @__PURE__ */ jsx("span", { ref: pctCb, className: "ps-tryon-progress-pct", children: "0%" })
1086
1116
  ] }),
1087
- /* @__PURE__ */ jsx("div", { ref: progressStatusRef, className: cx("ps-tryon-processing-text", cn.processingText), children: "Preparing your image..." }),
1117
+ /* @__PURE__ */ jsx("div", { ref: statusCb, className: cx("ps-tryon-processing-text", cn.processingText), children: "Preparing your image..." }),
1088
1118
  /* @__PURE__ */ jsx("p", { className: cx("ps-tryon-processing-sub", cn.processingSubText), children: "This usually takes 15-25 seconds" })
1089
1119
  ] });
1090
1120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "3.6.5",
3
+ "version": "3.7.0",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",