@primestyleai/tryon 5.1.0 → 5.2.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 +43 -17
  2. package/package.json +1 -1
@@ -4177,7 +4177,14 @@ function MeasurementOverlay({ lines, fitRows, show, imgWidth, imgHeight }) {
4177
4177
  const width = x2 - x1;
4178
4178
  const curveDepth = width * 0.06;
4179
4179
  const midX = (x1 + x2) / 2;
4180
- const fitRow = fitRows.find((r) => r.area.toLowerCase() === key);
4180
+ const fitRow = fitRows.find((r) => {
4181
+ const a = r.area.toLowerCase().trim();
4182
+ if (a === key) return true;
4183
+ if (key === "chest" && (a.includes("bust") || a.includes("chest"))) return true;
4184
+ if (key === "waist" && a.includes("waist")) return true;
4185
+ if (key === "hips" && (a.includes("hip") || a === "hips")) return true;
4186
+ return false;
4187
+ });
4181
4188
  const color = fitRow ? fitColor(fitRow.fit) : "#2154EF";
4182
4189
  const delay = i * 0.35;
4183
4190
  const curvePath = `M ${x1} ${cy} Q ${midX} ${cy + curveDepth} ${x2} ${cy}`;
@@ -4273,6 +4280,7 @@ const cellValFn = (row, colIdx, header) => {
4273
4280
  return "";
4274
4281
  };
4275
4282
  const fitLabelFn = (fit, t) => fit === "good" ? t("perfect fit") : fit === "too-tight" ? t("too tight") : fit === "tight" ? t("tight") : fit === "a-bit-tight" ? t("a bit tight") : fit === "too-loose" ? t("too loose") : fit === "loose" ? t("loose") : t("a bit loose");
4283
+ const lengthFitLabelFn = (fit, t) => fit === "good" ? t("perfect fit") : fit === "too-tight" ? t("too short") : fit === "tight" ? t("short") : fit === "a-bit-tight" ? t("a bit short") : fit === "too-loose" ? t("too long") : fit === "loose" ? t("long") : t("a bit long");
4276
4284
  const isLengthSection = (name) => /length|lunghezza|longueur|länge|largo/i.test(name);
4277
4285
  function findLengthForSection(sectionName, lengthEntries) {
4278
4286
  const base = sectionName.toLowerCase().replace(/\s*(size|sizing|—.*|–.*|\(.*?\))\s*/gi, "").trim();
@@ -4390,19 +4398,19 @@ function SectionDetailView({
4390
4398
  if (rMin2 > 0 && rMax2 > 0) {
4391
4399
  const range2 = rMax2 - rMin2;
4392
4400
  const threshold2 = range2 > 0 ? range2 * 0.5 : rMin2 * 0.05 || 3;
4393
- const tol2 = Math.max((rMax2 || rMin2) * 0.03, 0.5);
4401
+ const tol2 = Math.max((rMax2 || rMin2) * 5e-3, 0.25);
4394
4402
  if (userNum2 >= rMin2 - tol2 && userNum2 <= rMax2 + tol2) fit2 = "good";
4395
4403
  else if (userNum2 < rMin2) {
4396
4404
  const diff = rMin2 - userNum2;
4397
- fit2 = diff > threshold2 * 2 ? "too-loose" : diff > threshold2 ? "loose" : "a-bit-loose";
4405
+ fit2 = diff > threshold2 * 2 ? "too-tight" : diff > threshold2 ? "tight" : "a-bit-tight";
4398
4406
  } else {
4399
4407
  const diff = userNum2 - rMax2;
4400
- fit2 = diff > threshold2 * 2 ? "too-tight" : diff > threshold2 ? "tight" : "a-bit-tight";
4408
+ fit2 = diff > threshold2 * 2 ? "too-loose" : diff > threshold2 ? "loose" : "a-bit-loose";
4401
4409
  }
4402
4410
  }
4403
4411
  }
4404
4412
  }
4405
- return { area: m.measurement + " (" + activeLength + ")", userNum: userNum2, chartLabel: cleanNumFn(chartLabel2), fit: fit2 };
4413
+ return { area: m.measurement + " (" + activeLength + ")", userNum: userNum2, chartLabel: cleanNumFn(chartLabel2), fit: fit2, isLength: true };
4406
4414
  }
4407
4415
  const userNum = userMeasurements[m.measurement.toLowerCase()] || pNumFn(m.userValue);
4408
4416
  let { min: rMin, max: rMax } = pRangeFn(m.chartRange);
@@ -4418,7 +4426,7 @@ function SectionDetailView({
4418
4426
  const range = rMax - rMin;
4419
4427
  const threshold = range > 0 ? range * 0.5 : rMin * 0.05 || 3;
4420
4428
  let fit;
4421
- const tol = Math.max((rMax || rMin) * 0.03, 0.5);
4429
+ const tol = Math.max((rMax || rMin) * 5e-3, 0.25);
4422
4430
  if (userNum >= rMin - tol && userNum <= rMax + tol) fit = "good";
4423
4431
  else if (userNum < rMin) {
4424
4432
  const diff = rMin - userNum;
@@ -4427,10 +4435,15 @@ function SectionDetailView({
4427
4435
  const diff = userNum - rMax;
4428
4436
  fit = diff > threshold * 2 ? "too-tight" : diff > threshold ? "tight" : "a-bit-tight";
4429
4437
  }
4430
- return { area: m.measurement, userNum, chartLabel: cleanNumFn(chartLabel), fit };
4438
+ return { area: m.measurement, userNum, chartLabel: cleanNumFn(chartLabel), fit, isLength: false };
4431
4439
  });
4432
4440
  }, [sectionResult, lengthEntry, userMeasurements, displaySize, recSize, chartRangeFor, selectedLength, recLength]);
4433
4441
  return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sec-detail", children: [
4442
+ /* @__PURE__ */ jsx("div", { style: { marginBottom: "0.3vw" }, children: /* @__PURE__ */ jsxs("button", { className: "ps-bp-back-btn", onClick: onBack, type: "button", children: [
4443
+ /* @__PURE__ */ jsx("span", { className: "ps-bp-back-arrow", children: "←" }),
4444
+ " ",
4445
+ t("Back to sections")
4446
+ ] }) }),
4434
4447
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sec-detail-header", children: [
4435
4448
  /* @__PURE__ */ jsx("div", { className: "ps-tryon-sec-detail-icon", children: /* @__PURE__ */ jsx(GarmentIcon, { name: sectionName, size: 28 }) }),
4436
4449
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sec-detail-name", children: sectionName })
@@ -4460,7 +4473,7 @@ function SectionDetailView({
4460
4473
  unitLbl
4461
4474
  ] }),
4462
4475
  /* @__PURE__ */ jsx("td", { className: "ps-tryon-sr-ft-garment", children: row.chartLabel }),
4463
- /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("span", { className: `ps-tryon-sr-fit-status ps-fit-${row.fit}`, children: fitLabelFn(row.fit, t) }) })
4476
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("span", { className: `ps-tryon-sr-fit-status ps-fit-${row.fit}`, children: row.isLength ? lengthFitLabelFn(row.fit, t) : fitLabelFn(row.fit, t) }) })
4464
4477
  ] }, i)) })
4465
4478
  ] }),
4466
4479
  allSizes.length > 1 && (() => {
@@ -4633,15 +4646,21 @@ function SizeResultView({
4633
4646
  const allSectionEntries = useMemo(() => {
4634
4647
  if (!isMultiSection || !sizeGuide?.sections) return [];
4635
4648
  return Object.entries(sizeGuide.sections).map(([name, section]) => {
4636
- const secResult = sizingResult?.sections?.[name] || (() => {
4637
- if (!sizingResult?.matchDetails?.length) return { recommendedSize: sizingResult?.recommendedSize || "", matchDetails: [] };
4638
- const secHeaderKeys = new Set(section.requiredFields.map((f) => f.key.toLowerCase()));
4639
- const secHeaderLabels = new Set(section.headers.map((h) => h.toLowerCase().replace(/\s*\(.*?\)\s*/g, "").trim()));
4640
- const relevantDetails = sizingResult.matchDetails.filter((m) => {
4641
- const mLower = m.measurement.toLowerCase();
4642
- return secHeaderKeys.has(mLower) || secHeaderLabels.has(mLower);
4643
- });
4644
- return { recommendedSize: sizingResult.recommendedSize, matchDetails: relevantDetails };
4649
+ const secResult = (() => {
4650
+ const fromSections = sizingResult?.sections?.[name];
4651
+ if (fromSections?.matchDetails?.length) return fromSections;
4652
+ if (sizingResult?.matchDetails?.length) {
4653
+ const secHeaderKeys = new Set(section.requiredFields.map((f) => f.key.toLowerCase()));
4654
+ const secHeaderLabels = new Set(section.headers.map((h) => h.toLowerCase().replace(/\s*\(.*?\)\s*/g, "").trim()));
4655
+ const relevantDetails = sizingResult.matchDetails.filter((m) => {
4656
+ const mLower = m.measurement.toLowerCase();
4657
+ return secHeaderKeys.has(mLower) || secHeaderLabels.has(mLower);
4658
+ });
4659
+ if (relevantDetails.length) {
4660
+ return { recommendedSize: fromSections?.recommendedSize || sizingResult.recommendedSize, matchDetails: relevantDetails };
4661
+ }
4662
+ }
4663
+ return fromSections || { recommendedSize: sizingResult?.recommendedSize || "", matchDetails: [] };
4645
4664
  })();
4646
4665
  const userMeasurements = {};
4647
4666
  if (sizingResult?.matchDetails) {
@@ -5059,6 +5078,13 @@ function SizeResultView({
5059
5078
  /* @__PURE__ */ jsx("br", {}),
5060
5079
  t("Don't apply filters or edits")
5061
5080
  ] })
5081
+ ] }),
5082
+ /* @__PURE__ */ jsxs("div", { style: { background: "rgba(59,130,246,0.08)", border: "1px solid rgba(59,130,246,0.2)", borderRadius: "0.5vw", padding: "0.5vw 0.8vw" }, children: [
5083
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.3vw", marginBottom: "0.2vw" }, children: [
5084
+ /* @__PURE__ */ jsx(SparkleIcon, { size: 12 }),
5085
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--ps-accent)", fontSize: "0.65vw", fontWeight: 700 }, children: t("Pro Tip") })
5086
+ ] }),
5087
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "0.55vw", color: "var(--ps-text-secondary)", lineHeight: 1.7 }, children: t("Our AI works best with front-facing, full-body photos in fitted clothing. Better photos = more accurate virtual try-on!") })
5062
5088
  ] })
5063
5089
  ] })
5064
5090
  ] }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",