@primestyleai/tryon 3.19.0 → 3.20.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.
@@ -311,6 +311,7 @@ const en = {
311
311
  "Your size in other countries": "Your size in other countries",
312
312
  "Showing fit for size": "Showing fit for size",
313
313
  "Back to": "Back to",
314
+ "Edit values": "Edit values",
314
315
  "Fit Analysis": "Fit Analysis",
315
316
  "Show more": "Show more",
316
317
  "Done": "Done",
@@ -1,5 +1,5 @@
1
- import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage } from "./index-DmAF7P54.js";
2
- import { P, b, T, d, r } from "./index-DmAF7P54.js";
1
+ import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage } from "./index-Dr4MxT8W.js";
2
+ import { P, b, T, d, r } from "./index-Dr4MxT8W.js";
3
3
  function detectProductImage() {
4
4
  const ogImage = document.querySelector(
5
5
  'meta[property="og:image"]'
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import { useState, useEffect, useMemo, useRef, useCallback } from "react";
4
- import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage, P as PrimeStyleError, L as LOCALE_LABELS, b as SUPPORTED_LOCALES } from "../index-DmAF7P54.js";
4
+ import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage, P as PrimeStyleError, L as LOCALE_LABELS, b as SUPPORTED_LOCALES } from "../index-Dr4MxT8W.js";
5
5
  const HEADER_ALIASES = {
6
6
  // ── Size label columns (skipped during field derivation) ──
7
7
  size: "__size__",
@@ -406,6 +406,26 @@ const FALLBACK_FIELDS_MALE = [
406
406
  { key: "inseam", label: "Inseam", required: false, unit: "cm", placeholder: "e.g. 81", category: "body" },
407
407
  { key: "footLengthCm", label: "Foot length", required: false, unit: "cm", placeholder: "e.g. 27", category: "shoe" }
408
408
  ];
409
+ const SIZE_CONVERSIONS = {
410
+ "XXS": { US: "XXS", UK: "4", EU: "30", IT: "36", FR: "32", DE: "30", JP: "3", KR: "40", AU: "4", BR: "PP" },
411
+ "XS": { US: "XS", UK: "6", EU: "32", IT: "38", FR: "34", DE: "32", JP: "5", KR: "44", AU: "6", BR: "PP" },
412
+ "S": { US: "S", UK: "8", EU: "36", IT: "42", FR: "38", DE: "36", JP: "9", KR: "55", AU: "10", BR: "P" },
413
+ "M": { US: "M", UK: "10", EU: "38", IT: "44", FR: "40", DE: "38", JP: "11", KR: "66", AU: "12", BR: "M" },
414
+ "L": { US: "L", UK: "12", EU: "40", IT: "46", FR: "42", DE: "40", JP: "13", KR: "77", AU: "14", BR: "G" },
415
+ "XL": { US: "XL", UK: "14", EU: "42", IT: "48", FR: "44", DE: "42", JP: "15", KR: "88", AU: "16", BR: "GG" },
416
+ "XXL": { US: "XXL", UK: "16", EU: "44", IT: "50", FR: "46", DE: "44", JP: "17", KR: "99", AU: "18", BR: "XG" },
417
+ "XXXL": { US: "XXXL", UK: "18", EU: "46", IT: "52", FR: "48", DE: "46", JP: "19", KR: "100", AU: "20", BR: "EG" },
418
+ // Numeric sizes (EU-based)
419
+ "34": { US: "XS", UK: "6", EU: "34", IT: "38", FR: "34", DE: "34", JP: "5", KR: "44", AU: "6" },
420
+ "36": { US: "S", UK: "8", EU: "36", IT: "40", FR: "36", DE: "36", JP: "7", KR: "55", AU: "8" },
421
+ "38": { US: "M", UK: "10", EU: "38", IT: "42", FR: "38", DE: "38", JP: "9", KR: "66", AU: "10" },
422
+ "40": { US: "L", UK: "12", EU: "40", IT: "44", FR: "40", DE: "40", JP: "11", KR: "77", AU: "12" },
423
+ "42": { US: "XL", UK: "14", EU: "42", IT: "46", FR: "42", DE: "42", JP: "13", KR: "88", AU: "14" },
424
+ "44": { US: "XXL", UK: "16", EU: "44", IT: "48", FR: "44", DE: "44", JP: "15", KR: "99", AU: "16" },
425
+ "46": { US: "XXXL", UK: "18", EU: "46", IT: "50", FR: "46", DE: "46", JP: "17", KR: "100", AU: "18" },
426
+ "48": { US: "XXXL", UK: "20", EU: "48", IT: "52", FR: "48", DE: "48", JP: "19", KR: "105", AU: "20" },
427
+ "50": { US: "XXXL", UK: "22", EU: "50", IT: "54", FR: "50", DE: "50", JP: "21", KR: "110", AU: "22" }
428
+ };
409
429
  const STEP_LABELS = ["", "Welcome", "Size", "Your Fit", "Try On"];
410
430
  const TOTAL_STEPS = 4;
411
431
  function detectLocale() {
@@ -433,6 +453,22 @@ function lbsToKg(lbs) {
433
453
  function ftInToCm(ft, inch) {
434
454
  return +(ft * 30.48 + inch * 2.54).toFixed(1);
435
455
  }
456
+ function SvgIcon({ d, size = 18, strokeWidth = 2 }) {
457
+ return /* @__PURE__ */ jsx(
458
+ "svg",
459
+ {
460
+ width: size,
461
+ height: size,
462
+ viewBox: "0 0 24 24",
463
+ fill: "none",
464
+ stroke: "currentColor",
465
+ strokeWidth,
466
+ strokeLinecap: "round",
467
+ strokeLinejoin: "round",
468
+ children: /* @__PURE__ */ jsx("path", { d })
469
+ }
470
+ );
471
+ }
436
472
  function CameraIcon({ size = 18 }) {
437
473
  return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
438
474
  /* @__PURE__ */ jsx("path", { d: "M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" }),
@@ -1472,8 +1508,11 @@ function PrimeStyleTryonInner({
1472
1508
  }
1473
1509
  function SizeResultView() {
1474
1510
  const unitLbl = sizingUnit === "cm" ? t("cm") : t("in");
1511
+ const [editing, setEditing] = useState(false);
1475
1512
  const [editVals, setEditVals] = useState({});
1476
1513
  const [compareSize, setCompareSize] = useState("");
1514
+ const recSize = sizingResult?.recommendedSize || "";
1515
+ const selSize = compareSize || recSize;
1477
1516
  const sizeColIdx = useMemo(() => {
1478
1517
  if (!sizeGuide?.headers || !sizeGuide?.rows) return -1;
1479
1518
  const byName = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
@@ -1508,7 +1547,6 @@ function PrimeStyleTryonInner({
1508
1547
  }, [sizeGuide, sizeColIdx]);
1509
1548
  const fitRows = useMemo(() => {
1510
1549
  if (!sizingResult?.matchDetails?.length) return [];
1511
- compareSize || sizingResult.recommendedSize || "";
1512
1550
  return sizingResult.matchDetails.map((m) => {
1513
1551
  const origNum = pNum(m.userValue);
1514
1552
  const edited = editVals[m.measurement];
@@ -1527,9 +1565,13 @@ function PrimeStyleTryonInner({
1527
1565
  return { area: m.measurement, userNum, chartLabel, fit };
1528
1566
  });
1529
1567
  }, [sizingResult, compareSize, editVals, chartRangeFor]);
1530
- const intlSizes = sizingResult?.internationalSizes || {};
1531
- const recSize = sizingResult?.recommendedSize || "";
1532
- const selSize = compareSize || recSize;
1568
+ const allIntlSizes = useMemo(() => {
1569
+ const backendIntl = sizingResult?.internationalSizes || {};
1570
+ const upper = recSize.toUpperCase().trim();
1571
+ const fromTable = SIZE_CONVERSIONS[upper] || SIZE_CONVERSIONS[recSize] || {};
1572
+ const merged = { ...fromTable, ...backendIntl };
1573
+ return merged;
1574
+ }, [sizingResult, recSize]);
1533
1575
  return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr", children: [
1534
1576
  sizingLoading && !sizingResult && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-loading", children: [
1535
1577
  /* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner" }),
@@ -1539,16 +1581,13 @@ function PrimeStyleTryonInner({
1539
1581
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-hero", children: [
1540
1582
  recSize && /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-hero-badge", children: recSize }),
1541
1583
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-hero-info", children: [
1542
- /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-hero-title", children: [
1543
- t("Your Size"),
1544
- recSize ? `: ${recSize}` : ""
1545
- ] }),
1584
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-hero-title", children: t("Your Size") }),
1546
1585
  /* @__PURE__ */ jsx("div", { className: `ps-tryon-sr-hero-conf ps-conf-${sizingResult.confidence}`, children: sizingResult.confidence === "high" ? t("High Confidence") : sizingResult.confidence === "medium" ? t("Medium Confidence") : t("Low Confidence") })
1547
1586
  ] })
1548
1587
  ] }),
1549
- Object.keys(intlSizes).length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
1588
+ Object.keys(allIntlSizes).length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
1550
1589
  /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Your size in other countries") }),
1551
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-primary", children: Object.entries(intlSizes).map(([code, val]) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-card", children: [
1590
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-primary", children: Object.entries(allIntlSizes).map(([code, val]) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-card", children: [
1552
1591
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-val", children: val }),
1553
1592
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-code", children: code })
1554
1593
  ] }, code)) })
@@ -1571,7 +1610,13 @@ function PrimeStyleTryonInner({
1571
1610
  ] })
1572
1611
  ] }),
1573
1612
  fitRows.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit", children: [
1574
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Fit Analysis") }),
1613
+ /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-header-row", children: [
1614
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-label", children: t("Fit Analysis") }),
1615
+ /* @__PURE__ */ jsxs("button", { className: "ps-tryon-sr-edit-btn", onClick: () => setEditing(!editing), children: [
1616
+ /* @__PURE__ */ jsx(SvgIcon, { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7", size: 12 }),
1617
+ editing ? t("Done") : t("Edit values")
1618
+ ] })
1619
+ ] }),
1575
1620
  fitRows.map((row, i) => /* @__PURE__ */ jsxs("div", { className: `ps-tryon-sr-fit-card ps-fit-${row.fit}`, children: [
1576
1621
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-card-top", children: [
1577
1622
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-area", children: row.area }),
@@ -1580,7 +1625,7 @@ function PrimeStyleTryonInner({
1580
1625
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-card-bottom", children: [
1581
1626
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-val", children: [
1582
1627
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-val-label", children: t("You") }),
1583
- /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-val-input-wrap", children: [
1628
+ editing ? /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-val-input-wrap", children: [
1584
1629
  /* @__PURE__ */ jsx(
1585
1630
  "input",
1586
1631
  {
@@ -1591,6 +1636,10 @@ function PrimeStyleTryonInner({
1591
1636
  }
1592
1637
  ),
1593
1638
  /* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-unit", children: unitLbl })
1639
+ ] }) : /* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-fit-val-text", children: [
1640
+ row.userNum,
1641
+ " ",
1642
+ unitLbl
1594
1643
  ] })
1595
1644
  ] }),
1596
1645
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-val", children: [
@@ -1888,7 +1937,7 @@ const STYLES = `
1888
1937
  .ps-tryon-modal {
1889
1938
  background: var(--ps-modal-bg, #111211); color: var(--ps-modal-color, #fff);
1890
1939
  border-radius: var(--ps-modal-radius, 0.83vw); width: var(--ps-modal-width, 100%);
1891
- max-width: var(--ps-modal-max-width, 27vw); max-height: 92vh; overflow-y: auto;
1940
+ max-width: var(--ps-modal-max-width, 32vw); max-height: 92vh; overflow-y: auto;
1892
1941
  font-family: var(--ps-modal-font, system-ui, -apple-system, sans-serif);
1893
1942
  box-shadow: 0 1.3vw 2.6vw rgba(0,0,0,0.4); animation: ps-slide-up 0.3s ease;
1894
1943
  scrollbar-width: thin; scrollbar-color: #333 transparent;
@@ -2358,6 +2407,17 @@ const STYLES = `
2358
2407
 
2359
2408
  /* Fit analysis cards */
2360
2409
  .ps-tryon-sr-fit { display: flex; flex-direction: column; gap: 0.52vw; }
2410
+ .ps-tryon-sr-fit-header-row {
2411
+ display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.1vw;
2412
+ }
2413
+ .ps-tryon-sr-edit-btn {
2414
+ display: inline-flex; align-items: center; gap: 0.31vw;
2415
+ padding: 0.26vw 0.63vw; border: 1.5px solid #bb945c; border-radius: 0.36vw;
2416
+ background: transparent; color: #bb945c; font-size: 0.63vw; font-weight: 600;
2417
+ cursor: pointer; font-family: inherit; transition: all 0.2s;
2418
+ }
2419
+ .ps-tryon-sr-edit-btn:hover { background: rgba(187,148,92,0.1); }
2420
+ .ps-tryon-sr-edit-btn svg { stroke: currentColor; }
2361
2421
  .ps-tryon-sr-fit-card {
2362
2422
  border: 1.5px solid #333; border-radius: 0.63vw; overflow: hidden; transition: border-color 0.2s;
2363
2423
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "3.19.0",
3
+ "version": "3.20.0",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",