@primestyleai/tryon 3.15.0 → 3.17.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.
|
@@ -306,6 +306,7 @@ const en = {
|
|
|
306
306
|
"tap to compare": "tap to compare",
|
|
307
307
|
"Comparing size": "Comparing size",
|
|
308
308
|
"Fit Analysis": "Fit Analysis",
|
|
309
|
+
"Show more": "Show more",
|
|
309
310
|
"Done": "Done",
|
|
310
311
|
// ── Try-on result ───────────────────────────────────
|
|
311
312
|
"Try-on result": "Try-on result",
|
package/dist/primestyle-tryon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage } from "./index-
|
|
2
|
-
import { P, b, T, d, r } from "./index-
|
|
1
|
+
import { c as createT, A as ApiClient, S as SseClient, i as isValidImageFile, a as compressImage } from "./index-DvAzTRFF.js";
|
|
2
|
+
import { P, b, T, d, r } from "./index-DvAzTRFF.js";
|
|
3
3
|
function detectProductImage() {
|
|
4
4
|
const ogImage = document.querySelector(
|
|
5
5
|
'meta[property="og:image"]'
|
package/dist/react/index.js
CHANGED
|
@@ -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-
|
|
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-DvAzTRFF.js";
|
|
5
5
|
const HEADER_ALIASES = {
|
|
6
6
|
// ── Size label columns (skipped during field derivation) ──
|
|
7
7
|
size: "__size__",
|
|
@@ -406,20 +406,6 @@ 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 SIZING_COUNTRIES = [
|
|
410
|
-
{ code: "US", label: "United States" },
|
|
411
|
-
{ code: "UK", label: "United Kingdom" },
|
|
412
|
-
{ code: "EU", label: "Europe (EU)" },
|
|
413
|
-
{ code: "FR", label: "France" },
|
|
414
|
-
{ code: "IT", label: "Italy" },
|
|
415
|
-
{ code: "DE", label: "Germany" },
|
|
416
|
-
{ code: "ES", label: "Spain" },
|
|
417
|
-
{ code: "JP", label: "Japan" },
|
|
418
|
-
{ code: "CN", label: "China" },
|
|
419
|
-
{ code: "KR", label: "South Korea" },
|
|
420
|
-
{ code: "AU", label: "Australia" },
|
|
421
|
-
{ code: "BR", label: "Brazil" }
|
|
422
|
-
];
|
|
423
409
|
const STEP_LABELS = ["", "Welcome", "Size", "Your Fit", "Try On"];
|
|
424
410
|
const TOTAL_STEPS = 4;
|
|
425
411
|
function detectLocale() {
|
|
@@ -840,7 +826,115 @@ function PrimeStyleTryonInner({
|
|
|
840
826
|
}
|
|
841
827
|
return formGender === "female" ? FALLBACK_FIELDS_FEMALE : FALLBACK_FIELDS_MALE;
|
|
842
828
|
}, [sizeGuide, formGender]);
|
|
829
|
+
const computeSizingLocally = useCallback(() => {
|
|
830
|
+
if (sizingMethod !== "exact" || !sizeGuide?.found || !sizeGuide.headers || !sizeGuide.rows) return null;
|
|
831
|
+
const HEADER_MAP = {
|
|
832
|
+
chest: "chest",
|
|
833
|
+
bust: "bust",
|
|
834
|
+
waist: "waist",
|
|
835
|
+
hips: "hips",
|
|
836
|
+
hip: "hips",
|
|
837
|
+
shoulder: "shoulderWidth",
|
|
838
|
+
shoulders: "shoulderWidth",
|
|
839
|
+
"shoulder width": "shoulderWidth",
|
|
840
|
+
sleeve: "sleeveLength",
|
|
841
|
+
"sleeve length": "sleeveLength",
|
|
842
|
+
inseam: "inseam",
|
|
843
|
+
neck: "neckCircumference",
|
|
844
|
+
foot: "footLengthCm",
|
|
845
|
+
"foot length": "footLengthCm"
|
|
846
|
+
};
|
|
847
|
+
const INTL = /* @__PURE__ */ new Set(["eu", "us", "uk", "it", "fr", "de", "jp", "cn", "kr", "au", "br", "eur"]);
|
|
848
|
+
const userMeas = {};
|
|
849
|
+
for (const f of dynamicFields) {
|
|
850
|
+
if (f.unit === "size" || ["shoeEU", "shoeUS", "shoeUK"].includes(f.key)) continue;
|
|
851
|
+
const raw = formRef.current[f.key];
|
|
852
|
+
if (!raw) continue;
|
|
853
|
+
const v = parseFloat(raw);
|
|
854
|
+
if (isNaN(v)) continue;
|
|
855
|
+
userMeas[f.key] = sizingUnit === "in" ? inToCm(v) : v;
|
|
856
|
+
}
|
|
857
|
+
for (const k of ["chest", "bust", "waist", "hips", "shoulderWidth", "sleeveLength", "inseam", "neckCircumference", "footLengthCm"]) {
|
|
858
|
+
if (userMeas[k] || !formRef.current[k]) continue;
|
|
859
|
+
const v = parseFloat(formRef.current[k]);
|
|
860
|
+
if (!isNaN(v)) userMeas[k] = sizingUnit === "in" ? inToCm(v) : v;
|
|
861
|
+
}
|
|
862
|
+
if (Object.keys(userMeas).length === 0) return null;
|
|
863
|
+
let idx = sizeGuide.headers.findIndex((h) => /^size$/i.test(h.trim()));
|
|
864
|
+
if (idx < 0) idx = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
|
|
865
|
+
if (idx < 0) {
|
|
866
|
+
const firstColVals = sizeGuide.rows.map((r) => r[0]?.trim() || "");
|
|
867
|
+
idx = firstColVals.some((v) => /^(XXS|XS|S|M|L|XL|XXL|XXXL|\d{1,3})$/i.test(v)) ? 0 : 0;
|
|
868
|
+
}
|
|
869
|
+
const colMap = [];
|
|
870
|
+
const intlCols = [];
|
|
871
|
+
sizeGuide.headers.forEach((h, i) => {
|
|
872
|
+
if (i === idx) return;
|
|
873
|
+
const lower = h.toLowerCase().trim().replace(/\s*\(.*\)/, "");
|
|
874
|
+
const clean = lower.replace(/\s*size\s*/gi, "").trim();
|
|
875
|
+
if (INTL.has(clean)) {
|
|
876
|
+
intlCols.push({ hi: i, code: clean.toUpperCase() });
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
let fk = HEADER_MAP[clean];
|
|
880
|
+
if (!fk) {
|
|
881
|
+
const pk = Object.keys(HEADER_MAP).find((k) => clean.includes(k));
|
|
882
|
+
if (pk) fk = HEADER_MAP[pk];
|
|
883
|
+
}
|
|
884
|
+
if (fk && userMeas[fk] !== void 0) colMap.push({ hi: i, formKey: fk, label: h.trim() });
|
|
885
|
+
});
|
|
886
|
+
if (colMap.length === 0) return null;
|
|
887
|
+
const parseRange = (cell) => {
|
|
888
|
+
const nums = cell.replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((n) => !isNaN(n));
|
|
889
|
+
if (nums.length === 0) return null;
|
|
890
|
+
return { min: Math.min(...nums), max: Math.max(...nums) };
|
|
891
|
+
};
|
|
892
|
+
const scores = [];
|
|
893
|
+
for (const row of sizeGuide.rows) {
|
|
894
|
+
const label = row[idx] || "";
|
|
895
|
+
let fitting = 0;
|
|
896
|
+
let total = 0;
|
|
897
|
+
let dist = 0;
|
|
898
|
+
const details = [];
|
|
899
|
+
for (const col of colMap) {
|
|
900
|
+
const range = parseRange(row[col.hi] || "");
|
|
901
|
+
if (!range) continue;
|
|
902
|
+
total++;
|
|
903
|
+
const uv = userMeas[col.formKey];
|
|
904
|
+
const fit = uv >= range.min && uv <= range.max ? "good" : uv < range.min ? "tight" : "loose";
|
|
905
|
+
if (fit === "good") fitting++;
|
|
906
|
+
dist += Math.abs(uv - (range.min + range.max) / 2);
|
|
907
|
+
const dispVal = sizingUnit === "in" ? `${cmToIn(uv)} in` : `${Math.round(uv)} cm`;
|
|
908
|
+
const dispRange = sizingUnit === "in" ? `${cmToIn(range.min)}–${cmToIn(range.max)} in` : `${Math.round(range.min)}–${Math.round(range.max)} cm`;
|
|
909
|
+
details.push({ measurement: col.label, userValue: dispVal, chartRange: dispRange, fit });
|
|
910
|
+
}
|
|
911
|
+
if (total === 0) continue;
|
|
912
|
+
const intl = {};
|
|
913
|
+
for (const ic of intlCols) {
|
|
914
|
+
if (row[ic.hi]) intl[ic.code] = row[ic.hi];
|
|
915
|
+
}
|
|
916
|
+
scores.push({ label, fitting, total, dist, details, intl, row });
|
|
917
|
+
}
|
|
918
|
+
if (scores.length === 0) return null;
|
|
919
|
+
scores.sort((a, b) => b.fitting - a.fitting || a.dist - b.dist);
|
|
920
|
+
const best = scores[0];
|
|
921
|
+
const conf = best.fitting === best.total ? "high" : best.fitting >= best.total * 0.6 ? "medium" : "low";
|
|
922
|
+
return {
|
|
923
|
+
recommendedSize: best.label,
|
|
924
|
+
confidence: conf,
|
|
925
|
+
reasoning: `Based on your measurements, size ${best.label} is the best fit.`,
|
|
926
|
+
internationalSizes: best.intl,
|
|
927
|
+
matchDetails: best.details,
|
|
928
|
+
method: "deterministic"
|
|
929
|
+
};
|
|
930
|
+
}, [sizingMethod, sizeGuide, dynamicFields, sizingUnit]);
|
|
843
931
|
const submitSizing = useCallback(async () => {
|
|
932
|
+
const localResult = computeSizingLocally();
|
|
933
|
+
if (localResult) {
|
|
934
|
+
setSizingResult(localResult);
|
|
935
|
+
setSizingLoading(false);
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
844
938
|
if (!apiRef.current) return;
|
|
845
939
|
const baseUrl = getApiUrl(apiUrl);
|
|
846
940
|
const key = getApiKey();
|
|
@@ -899,7 +993,7 @@ function PrimeStyleTryonInner({
|
|
|
899
993
|
} finally {
|
|
900
994
|
setSizingLoading(false);
|
|
901
995
|
}
|
|
902
|
-
}, [apiUrl, sizingMethod, sizingCountry, heightUnit, weightUnit, sizingUnit, sizeGuide, productTitle, dynamicFields]);
|
|
996
|
+
}, [apiUrl, sizingMethod, sizingCountry, heightUnit, weightUnit, sizingUnit, sizeGuide, productTitle, dynamicFields, computeSizingLocally]);
|
|
903
997
|
const handleTryOnSubmit = useCallback(async () => {
|
|
904
998
|
if (!selectedFile || !apiRef.current || !sseRef.current) {
|
|
905
999
|
const msg = !apiRef.current ? t("SDK not configured. Please provide an API key.") : t("Something went wrong");
|
|
@@ -1339,10 +1433,6 @@ function PrimeStyleTryonInner({
|
|
|
1339
1433
|
")"
|
|
1340
1434
|
] }, p.id))
|
|
1341
1435
|
] }) }),
|
|
1342
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-input-row", children: [
|
|
1343
|
-
/* @__PURE__ */ jsx("label", { children: t("Sizing region") }),
|
|
1344
|
-
/* @__PURE__ */ jsx("select", { className: "ps-tryon-country-select", value: sizingCountry, onChange: (e) => setSizingCountry(e.target.value), children: SIZING_COUNTRIES.map((c) => /* @__PURE__ */ jsx("option", { value: c.code, children: t(c.label) }, c.code)) })
|
|
1345
|
-
] }),
|
|
1346
1436
|
sizingMethod === "exact" && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-unit-tabs", children: [
|
|
1347
1437
|
/* @__PURE__ */ jsx("button", { className: `ps-tryon-unit-tab${isCm ? " ps-active" : ""}`, onClick: () => {
|
|
1348
1438
|
setSizingUnit("cm");
|
|
@@ -1515,8 +1605,14 @@ function PrimeStyleTryonInner({
|
|
|
1515
1605
|
foot: "footLengthCm",
|
|
1516
1606
|
"foot length": "footLengthCm"
|
|
1517
1607
|
};
|
|
1518
|
-
|
|
1519
|
-
|
|
1608
|
+
let idx = sizeGuide.headers.findIndex((h) => /^size$/i.test(h.trim()));
|
|
1609
|
+
if (idx < 0) idx = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
|
|
1610
|
+
if (idx < 0) {
|
|
1611
|
+
const firstColVals = sizeGuide.rows.map((r) => r[0]?.trim() || "");
|
|
1612
|
+
const looksLikeSize = firstColVals.some((v) => /^(XXS|XS|S|M|L|XL|XXL|XXXL|\d{1,3})$/i.test(v));
|
|
1613
|
+
idx = looksLikeSize ? 0 : -1;
|
|
1614
|
+
}
|
|
1615
|
+
if (idx < 0) idx = 0;
|
|
1520
1616
|
const measCols = [];
|
|
1521
1617
|
const intlCols = [];
|
|
1522
1618
|
sizeGuide.headers.forEach((h, i) => {
|
|
@@ -1527,8 +1623,10 @@ function PrimeStyleTryonInner({
|
|
|
1527
1623
|
intlCols.push({ headerIdx: i, code: clean.toUpperCase() });
|
|
1528
1624
|
} else if (MEAS_MAP[clean]) {
|
|
1529
1625
|
measCols.push({ headerIdx: i, label: h.trim(), formKey: MEAS_MAP[clean] });
|
|
1530
|
-
} else if (
|
|
1531
|
-
|
|
1626
|
+
} else if (clean && clean !== "size") {
|
|
1627
|
+
const partialKey = Object.keys(MEAS_MAP).find((k) => clean.includes(k));
|
|
1628
|
+
const fk = partialKey ? MEAS_MAP[partialKey] : clean.replace(/\s+/g, "");
|
|
1629
|
+
measCols.push({ headerIdx: i, label: h.trim(), formKey: fk });
|
|
1532
1630
|
}
|
|
1533
1631
|
});
|
|
1534
1632
|
const sizes = sizeGuide.rows.map((row) => {
|
|
@@ -1547,7 +1645,7 @@ function PrimeStyleTryonInner({
|
|
|
1547
1645
|
}
|
|
1548
1646
|
return { label, measurements, intl };
|
|
1549
1647
|
});
|
|
1550
|
-
return { sizes, measCols, intlCols };
|
|
1648
|
+
return { sizes: sizes.filter((s) => s.label.trim()), measCols, intlCols };
|
|
1551
1649
|
}, [sizeGuide]);
|
|
1552
1650
|
const getUserVal = useCallback((formKey2) => {
|
|
1553
1651
|
const edited = editedValues[formKey2];
|
|
@@ -1599,13 +1697,30 @@ function PrimeStyleTryonInner({
|
|
|
1599
1697
|
/* @__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") })
|
|
1600
1698
|
] })
|
|
1601
1699
|
] }),
|
|
1602
|
-
Object.keys(activeIntl).length > 0 &&
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1700
|
+
Object.keys(activeIntl).length > 0 && (() => {
|
|
1701
|
+
const PRIMARY_CODES = ["US", "UK", "EU", "IT", "FR", "DE"];
|
|
1702
|
+
const primary = PRIMARY_CODES.filter((c) => activeIntl[c]).map((c) => ({ code: c, val: activeIntl[c] }));
|
|
1703
|
+
const rest = Object.entries(activeIntl).filter(([c]) => !PRIMARY_CODES.includes(c)).map(([code, val]) => ({ code, val }));
|
|
1704
|
+
return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
|
|
1705
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Equivalent Sizes") }),
|
|
1706
|
+
primary.length > 0 && /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-primary", children: primary.map((s) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-card", children: [
|
|
1707
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-val", children: s.val }),
|
|
1708
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-code", children: s.code })
|
|
1709
|
+
] }, s.code)) }),
|
|
1710
|
+
rest.length > 0 && /* @__PURE__ */ jsxs("details", { className: "ps-tryon-sr-intl-more", children: [
|
|
1711
|
+
/* @__PURE__ */ jsxs("summary", { className: "ps-tryon-sr-intl-more-btn", children: [
|
|
1712
|
+
t("Show more"),
|
|
1713
|
+
" (",
|
|
1714
|
+
rest.length,
|
|
1715
|
+
")"
|
|
1716
|
+
] }),
|
|
1717
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-grid", children: rest.map((s) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-item", children: [
|
|
1718
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-code", children: s.code }),
|
|
1719
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-val", children: s.val })
|
|
1720
|
+
] }, s.code)) })
|
|
1721
|
+
] })
|
|
1722
|
+
] });
|
|
1723
|
+
})(),
|
|
1609
1724
|
chartData && chartData.sizes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-sizes", children: [
|
|
1610
1725
|
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-label", children: [
|
|
1611
1726
|
t("Size Chart"),
|
|
@@ -1633,49 +1748,72 @@ function PrimeStyleTryonInner({
|
|
|
1633
1748
|
/* @__PURE__ */ jsx("strong", { children: activeSize })
|
|
1634
1749
|
] })
|
|
1635
1750
|
] }),
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
" (",
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1751
|
+
(() => {
|
|
1752
|
+
const hasDynamic = activeFit && activeFit.length > 0;
|
|
1753
|
+
const hasBackend = sizingResult.matchDetails && sizingResult.matchDetails.length > 0;
|
|
1754
|
+
if (hasDynamic) return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit", children: [
|
|
1755
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Fit Analysis") }),
|
|
1756
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-table", children: [
|
|
1757
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-header", children: [
|
|
1758
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-area", children: t("Area") }),
|
|
1759
|
+
/* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-fit-col-you", children: [
|
|
1760
|
+
t("You"),
|
|
1761
|
+
" (",
|
|
1762
|
+
unitLabel,
|
|
1763
|
+
")"
|
|
1764
|
+
] }),
|
|
1765
|
+
/* @__PURE__ */ jsxs("span", { className: "ps-tryon-sr-fit-col-chart", children: [
|
|
1766
|
+
t("Chart"),
|
|
1767
|
+
" (",
|
|
1768
|
+
unitLabel,
|
|
1769
|
+
")"
|
|
1770
|
+
] }),
|
|
1771
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-fit", children: t("Fit") })
|
|
1652
1772
|
] }),
|
|
1653
|
-
/* @__PURE__ */
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
defaultValue: isCmResult ? Math.round(row.userVal) : cmToIn(row.userVal),
|
|
1663
|
-
onBlur: (e) => {
|
|
1664
|
-
const val = e.target.value;
|
|
1665
|
-
setEditedValues((prev) => ({ ...prev, [row.formKey]: val }));
|
|
1773
|
+
activeFit.map((row, i) => /* @__PURE__ */ jsxs("div", { className: `ps-tryon-sr-fit-row ps-fit-${row.fit}`, children: [
|
|
1774
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-area", children: row.label }),
|
|
1775
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-you", children: /* @__PURE__ */ jsx(
|
|
1776
|
+
"input",
|
|
1777
|
+
{
|
|
1778
|
+
type: "number",
|
|
1779
|
+
className: "ps-tryon-sr-fit-input",
|
|
1780
|
+
defaultValue: isCmResult ? Math.round(row.userVal) : cmToIn(row.userVal),
|
|
1781
|
+
onBlur: (e) => setEditedValues((prev) => ({ ...prev, [row.formKey]: e.target.value }))
|
|
1666
1782
|
}
|
|
1667
|
-
}
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
] }
|
|
1675
|
-
] }
|
|
1676
|
-
] })
|
|
1677
|
-
|
|
1678
|
-
|
|
1783
|
+
) }),
|
|
1784
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-chart", children: fmtRange(row.chartMin, row.chartMax) }),
|
|
1785
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-fit", children: /* @__PURE__ */ jsxs("span", { className: `ps-tryon-sr-fit-badge ps-fit-${row.fit}`, children: [
|
|
1786
|
+
row.fit === "good" ? "✓" : row.fit === "tight" ? "↑" : "↓",
|
|
1787
|
+
" ",
|
|
1788
|
+
row.fit === "good" ? t("within range") : row.fit === "tight" ? t("may be snug") : t("may be loose")
|
|
1789
|
+
] }) })
|
|
1790
|
+
] }, i))
|
|
1791
|
+
] })
|
|
1792
|
+
] });
|
|
1793
|
+
if (hasBackend) return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit", children: [
|
|
1794
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-label", children: t("Fit Analysis") }),
|
|
1795
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-table", children: [
|
|
1796
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fit-header", children: [
|
|
1797
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-area", children: t("Area") }),
|
|
1798
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-you", children: t("You") }),
|
|
1799
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-chart", children: t("Chart") }),
|
|
1800
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-fit", children: t("Fit") })
|
|
1801
|
+
] }),
|
|
1802
|
+
sizingResult.matchDetails.map((m, i) => /* @__PURE__ */ jsxs("div", { className: `ps-tryon-sr-fit-row ps-fit-${m.fit}`, children: [
|
|
1803
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-area", children: m.measurement }),
|
|
1804
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-you", children: m.userValue }),
|
|
1805
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-chart", children: m.chartRange }),
|
|
1806
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-fit-col-fit", children: /* @__PURE__ */ jsxs("span", { className: `ps-tryon-sr-fit-badge ps-fit-${m.fit}`, children: [
|
|
1807
|
+
m.fit === "good" ? "✓" : m.fit === "tight" ? "↑" : "↓",
|
|
1808
|
+
" ",
|
|
1809
|
+
m.fit === "good" ? t("within range") : m.fit === "tight" ? t("may be snug") : t("may be loose")
|
|
1810
|
+
] }) })
|
|
1811
|
+
] }, i))
|
|
1812
|
+
] })
|
|
1813
|
+
] });
|
|
1814
|
+
if (sizingResult.reasoning) return /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-reasoning", children: /* @__PURE__ */ jsx("p", { children: sizingResult.reasoning }) });
|
|
1815
|
+
return null;
|
|
1816
|
+
})(),
|
|
1679
1817
|
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-ctas", children: [
|
|
1680
1818
|
/* @__PURE__ */ jsxs("button", { className: "ps-tryon-cta", onClick: () => setView("upload"), children: [
|
|
1681
1819
|
t("See how it looks on you"),
|
|
@@ -2376,6 +2514,25 @@ const STYLES = `
|
|
|
2376
2514
|
.ps-tryon-sr-intl { }
|
|
2377
2515
|
.ps-tryon-sr-label { font-size: 0.78vw; font-weight: 700; color: #999; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 0.52vw; }
|
|
2378
2516
|
.ps-tryon-sr-label-hint { font-weight: 400; text-transform: none; letter-spacing: 0; color: #666; font-style: italic; }
|
|
2517
|
+
.ps-tryon-sr-intl-primary { display: flex; flex-wrap: wrap; gap: 0.42vw; margin-bottom: 0.52vw; }
|
|
2518
|
+
.ps-tryon-sr-intl-card {
|
|
2519
|
+
flex: 1; min-width: 3.5vw; display: flex; flex-direction: column; align-items: center;
|
|
2520
|
+
padding: 0.57vw 0.42vw; border: 1.5px solid #333; border-radius: 0.63vw;
|
|
2521
|
+
background: #1a1b1a; transition: border-color 0.2s;
|
|
2522
|
+
}
|
|
2523
|
+
.ps-tryon-sr-intl-card:hover { border-color: #555; }
|
|
2524
|
+
.ps-tryon-sr-intl-card-val { font-size: 1.04vw; font-weight: 800; color: #fff; line-height: 1.2; }
|
|
2525
|
+
.ps-tryon-sr-intl-card-code { font-size: 0.57vw; font-weight: 700; color: #666; text-transform: uppercase; letter-spacing: 0.08em; margin-top: 0.1vw; }
|
|
2526
|
+
|
|
2527
|
+
.ps-tryon-sr-intl-more { }
|
|
2528
|
+
.ps-tryon-sr-intl-more-btn {
|
|
2529
|
+
font-size: 0.73vw; color: #bb945c; font-weight: 600; cursor: pointer;
|
|
2530
|
+
list-style: none; margin-bottom: 0.42vw; font-family: inherit;
|
|
2531
|
+
}
|
|
2532
|
+
.ps-tryon-sr-intl-more-btn::-webkit-details-marker { display: none; }
|
|
2533
|
+
.ps-tryon-sr-intl-more-btn::before { content: "▸ "; }
|
|
2534
|
+
.ps-tryon-sr-intl-more[open] .ps-tryon-sr-intl-more-btn::before { content: "▾ "; }
|
|
2535
|
+
|
|
2379
2536
|
.ps-tryon-sr-intl-grid { display: flex; flex-wrap: wrap; gap: 0.42vw; }
|
|
2380
2537
|
.ps-tryon-sr-intl-item {
|
|
2381
2538
|
display: flex; align-items: center; border: 1.5px solid #333; border-radius: 0.52vw; overflow: hidden;
|