@primestyleai/tryon 4.1.1 → 4.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.
|
@@ -314,6 +314,8 @@ const en = {
|
|
|
314
314
|
"Edit values": "Edit values",
|
|
315
315
|
"Based on your updated measurements, size": "Based on your updated measurements, size",
|
|
316
316
|
"may be a better fit": "may be a better fit",
|
|
317
|
+
"Updated to": "Updated to",
|
|
318
|
+
"Your Measurements": "Your Measurements",
|
|
317
319
|
"Fit Analysis": "Fit Analysis",
|
|
318
320
|
"Show more": "Show more",
|
|
319
321
|
"Done": "Done",
|
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-CILUifQv.js";
|
|
2
|
+
import { P, b, T, d, r } from "./index-CILUifQv.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-CILUifQv.js";
|
|
5
5
|
const HEADER_ALIASES = {
|
|
6
6
|
// ── Size label columns (skipped during field derivation) ──
|
|
7
7
|
size: "__size__",
|
|
@@ -453,22 +453,6 @@ function lbsToKg(lbs) {
|
|
|
453
453
|
function ftInToCm(ft, inch) {
|
|
454
454
|
return +(ft * 30.48 + inch * 2.54).toFixed(1);
|
|
455
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
|
-
}
|
|
472
456
|
function CameraIcon({ size = 18 }) {
|
|
473
457
|
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
474
458
|
/* @__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" }),
|
|
@@ -873,6 +857,8 @@ function PrimeStyleTryonInner({
|
|
|
873
857
|
if (sizeGuide.sections) payload.sizeGuide = { ...sizeGuide, sections: sizeGuide.sections };
|
|
874
858
|
}
|
|
875
859
|
payload.sizingUnit = sizingUnit;
|
|
860
|
+
console.log("[PS-SDK] sizeGuide state:", JSON.stringify({ found: sizeGuide?.found, hasHeaders: !!sizeGuide?.headers, hasRows: !!sizeGuide?.rows, headers: sizeGuide?.headers, rowCount: sizeGuide?.rows?.length }));
|
|
861
|
+
console.log("[PS-SDK] payload.sizeGuide:", payload.sizeGuide ? "present" : "MISSING");
|
|
876
862
|
if (sizingMethod === "exact") {
|
|
877
863
|
const m = { gender: formRef.current.gender || "male", sizingUnit };
|
|
878
864
|
const numericKeys = /* @__PURE__ */ new Set();
|
|
@@ -1508,28 +1494,19 @@ function PrimeStyleTryonInner({
|
|
|
1508
1494
|
}
|
|
1509
1495
|
function SizeResultView() {
|
|
1510
1496
|
const unitLbl = sizingUnit === "cm" ? t("cm") : t("in");
|
|
1511
|
-
const [editing, setEditing] = useState(false);
|
|
1512
1497
|
const [editVals, setEditVals] = useState({});
|
|
1513
|
-
const
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1498
|
+
const cleanNum = (s) => {
|
|
1499
|
+
const ns = s.replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map((n) => parseFloat(n)).filter((n) => !isNaN(n));
|
|
1500
|
+
return ns.length === 1 ? `${ns[0]}` : ns.length > 1 ? `${ns[0]}–${ns[1]}` : s;
|
|
1501
|
+
};
|
|
1502
|
+
const pNum = (s) => {
|
|
1503
|
+
const n = parseFloat(s.replace(/[^\d.]/g, ""));
|
|
1504
|
+
return isNaN(n) ? 0 : n;
|
|
1505
|
+
};
|
|
1506
|
+
const pRange = (s) => {
|
|
1507
|
+
const ns = s.replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((n) => !isNaN(n));
|
|
1508
|
+
return ns.length ? { min: Math.min(...ns), max: Math.max(...ns) } : { min: 0, max: 0 };
|
|
1519
1509
|
};
|
|
1520
|
-
const recSize = useMemo(() => {
|
|
1521
|
-
if (sizingResult?.recommendedSize) return sizingResult.recommendedSize;
|
|
1522
|
-
if (sizeGuide?.rows && sizeGuide.headers) {
|
|
1523
|
-
const sc = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
|
|
1524
|
-
const idx = sc >= 0 ? sc : 0;
|
|
1525
|
-
for (const row of sizeGuide.rows) {
|
|
1526
|
-
const label = row[idx]?.trim();
|
|
1527
|
-
if (label && /^(XXS|XS|S|M|L|XL|XXL|XXXL|\d{1,3})$/i.test(label)) return label;
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
return "";
|
|
1531
|
-
}, [sizingResult, sizeGuide]);
|
|
1532
|
-
const selSize = compareSize || recSize;
|
|
1533
1510
|
const sizeColIdx = useMemo(() => {
|
|
1534
1511
|
if (!sizeGuide?.headers || !sizeGuide?.rows) return -1;
|
|
1535
1512
|
const byName = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
|
|
@@ -1543,14 +1520,6 @@ function PrimeStyleTryonInner({
|
|
|
1543
1520
|
if (sizeColIdx < 0 || !sizeGuide?.rows) return [];
|
|
1544
1521
|
return sizeGuide.rows.map((r) => r[sizeColIdx]?.trim()).filter(Boolean);
|
|
1545
1522
|
}, [sizeGuide, sizeColIdx]);
|
|
1546
|
-
const pNum = (s) => {
|
|
1547
|
-
const n = parseFloat(s.replace(/[^\d.]/g, ""));
|
|
1548
|
-
return isNaN(n) ? 0 : n;
|
|
1549
|
-
};
|
|
1550
|
-
const pRange = (s) => {
|
|
1551
|
-
const ns = s.replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((n) => !isNaN(n));
|
|
1552
|
-
return ns.length ? { min: Math.min(...ns), max: Math.max(...ns) } : { min: 0, max: 0 };
|
|
1553
|
-
};
|
|
1554
1523
|
const chartRangeFor = useCallback((measurement, size) => {
|
|
1555
1524
|
if (!sizeGuide?.headers || !sizeGuide?.rows || sizeColIdx < 0) return null;
|
|
1556
1525
|
const mc = sizeGuide.headers.findIndex((h) => {
|
|
@@ -1561,6 +1530,29 @@ function PrimeStyleTryonInner({
|
|
|
1561
1530
|
const row = sizeGuide.rows.find((r) => r[sizeColIdx]?.trim() === size);
|
|
1562
1531
|
return row?.[mc] ? { range: row[mc], ...pRange(row[mc]) } : null;
|
|
1563
1532
|
}, [sizeGuide, sizeColIdx]);
|
|
1533
|
+
const bestSize = useMemo(() => {
|
|
1534
|
+
if (!sizingResult?.matchDetails?.length || !allSizes.length) return sizingResult?.recommendedSize || "";
|
|
1535
|
+
if (!Object.keys(editVals).length) return sizingResult?.recommendedSize || "";
|
|
1536
|
+
let best = "";
|
|
1537
|
+
let bestScore = -1;
|
|
1538
|
+
for (const size of allSizes) {
|
|
1539
|
+
let score = 0;
|
|
1540
|
+
for (const m of sizingResult.matchDetails) {
|
|
1541
|
+
const edited = editVals[m.measurement];
|
|
1542
|
+
const userNum = edited !== void 0 && edited !== "" ? parseFloat(edited) : pNum(m.userValue);
|
|
1543
|
+
const alt = chartRangeFor(m.measurement, size);
|
|
1544
|
+
if (alt && userNum >= alt.min && userNum <= alt.max) score++;
|
|
1545
|
+
}
|
|
1546
|
+
if (score > bestScore) {
|
|
1547
|
+
bestScore = score;
|
|
1548
|
+
best = size;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
return best || sizingResult?.recommendedSize || "";
|
|
1552
|
+
}, [editVals, sizingResult, allSizes, chartRangeFor]);
|
|
1553
|
+
const origSize = sizingResult?.recommendedSize || "";
|
|
1554
|
+
const activeSize = bestSize || origSize;
|
|
1555
|
+
const sizeChanged = Object.keys(editVals).length > 0 && bestSize !== origSize;
|
|
1564
1556
|
const fitRows = useMemo(() => {
|
|
1565
1557
|
if (!sizingResult?.matchDetails?.length) return [];
|
|
1566
1558
|
return sizingResult.matchDetails.map((m) => {
|
|
@@ -1569,8 +1561,8 @@ function PrimeStyleTryonInner({
|
|
|
1569
1561
|
const userNum = edited !== void 0 && edited !== "" ? parseFloat(edited) : origNum;
|
|
1570
1562
|
let { min: rMin, max: rMax } = pRange(m.chartRange);
|
|
1571
1563
|
let chartLabel = m.chartRange;
|
|
1572
|
-
if (
|
|
1573
|
-
const alt = chartRangeFor(m.measurement,
|
|
1564
|
+
if (activeSize !== origSize) {
|
|
1565
|
+
const alt = chartRangeFor(m.measurement, activeSize);
|
|
1574
1566
|
if (alt) {
|
|
1575
1567
|
chartLabel = alt.range;
|
|
1576
1568
|
rMin = alt.min;
|
|
@@ -1578,129 +1570,88 @@ function PrimeStyleTryonInner({
|
|
|
1578
1570
|
}
|
|
1579
1571
|
}
|
|
1580
1572
|
const fit = userNum >= rMin && userNum <= rMax ? "good" : userNum < rMin ? "tight" : "loose";
|
|
1581
|
-
return { area: m.measurement, userNum, chartLabel:
|
|
1573
|
+
return { area: m.measurement, userNum, chartLabel: cleanNum(chartLabel), fit };
|
|
1582
1574
|
});
|
|
1583
|
-
}, [sizingResult,
|
|
1584
|
-
const suggestedSize = useMemo(() => {
|
|
1585
|
-
if (!Object.keys(editVals).length || !sizingResult?.matchDetails?.length || !allSizes.length) return null;
|
|
1586
|
-
let bestSize = "";
|
|
1587
|
-
let bestScore = -1;
|
|
1588
|
-
for (const size of allSizes) {
|
|
1589
|
-
let score = 0;
|
|
1590
|
-
for (const m of sizingResult.matchDetails) {
|
|
1591
|
-
const edited = editVals[m.measurement];
|
|
1592
|
-
const userNum = edited !== void 0 && edited !== "" ? parseFloat(edited) : pNum(m.userValue);
|
|
1593
|
-
const alt = chartRangeFor(m.measurement, size);
|
|
1594
|
-
if (alt && userNum >= alt.min && userNum <= alt.max) score++;
|
|
1595
|
-
}
|
|
1596
|
-
if (score > bestScore) {
|
|
1597
|
-
bestScore = score;
|
|
1598
|
-
bestSize = size;
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
return bestSize && bestSize !== recSize ? bestSize : null;
|
|
1602
|
-
}, [editVals, sizingResult, allSizes, recSize, chartRangeFor]);
|
|
1575
|
+
}, [sizingResult, editVals, chartRangeFor, activeSize, origSize]);
|
|
1603
1576
|
const allIntlSizes = useMemo(() => {
|
|
1604
1577
|
const backendIntl = sizingResult?.internationalSizes || {};
|
|
1605
|
-
const upper =
|
|
1606
|
-
const fromTable = SIZE_CONVERSIONS[upper] || SIZE_CONVERSIONS[
|
|
1578
|
+
const upper = activeSize.toUpperCase().trim();
|
|
1579
|
+
const fromTable = SIZE_CONVERSIONS[upper] || SIZE_CONVERSIONS[activeSize] || {};
|
|
1607
1580
|
return { ...fromTable, ...backendIntl };
|
|
1608
|
-
}, [sizingResult,
|
|
1609
|
-
const confLabel = sizingResult?.confidence === "high" ? t("High Confidence") : sizingResult?.confidence === "medium" ? t("Medium Confidence") : t("Low Confidence");
|
|
1581
|
+
}, [sizingResult, activeSize]);
|
|
1610
1582
|
return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr", children: [
|
|
1611
1583
|
sizingLoading && !sizingResult && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-loading", children: [
|
|
1612
1584
|
/* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner" }),
|
|
1613
1585
|
/* @__PURE__ */ jsx("p", { children: t("Analyzing your size...") })
|
|
1614
1586
|
] }),
|
|
1615
1587
|
sizingResult && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1616
|
-
/* @__PURE__ */ jsxs("
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-hero-title", children: t("Your Size") }),
|
|
1620
|
-
/* @__PURE__ */ jsx("div", { className: `ps-tryon-sr-hero-conf ps-conf-${sizingResult.confidence}`, children: confLabel })
|
|
1621
|
-
] })
|
|
1622
|
-
] }),
|
|
1623
|
-
suggestedSize && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-suggestion", onClick: () => {
|
|
1624
|
-
setCompareSize(suggestedSize);
|
|
1588
|
+
/* @__PURE__ */ jsxs("button", { className: "ps-tryon-back", onClick: () => {
|
|
1589
|
+
setView("sizing-form");
|
|
1590
|
+
setEditVals({});
|
|
1625
1591
|
}, children: [
|
|
1626
|
-
/* @__PURE__ */ jsx(
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
" ",
|
|
1630
|
-
/* @__PURE__ */ jsx("strong", { children: suggestedSize }),
|
|
1631
|
-
" ",
|
|
1632
|
-
t("may be a better fit")
|
|
1633
|
-
] }),
|
|
1634
|
-
/* @__PURE__ */ jsx(ArrowRightIcon, {})
|
|
1635
|
-
] }),
|
|
1636
|
-
Object.keys(allIntlSizes).length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
|
|
1637
|
-
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-section-title", children: t("Your size in other countries") }),
|
|
1638
|
-
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-grid", children: Object.entries(allIntlSizes).map(([code, val]) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-card", children: [
|
|
1639
|
-
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-val", children: val }),
|
|
1640
|
-
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-code", children: code })
|
|
1641
|
-
] }, code)) })
|
|
1592
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon, {}),
|
|
1593
|
+
" ",
|
|
1594
|
+
t("Back")
|
|
1642
1595
|
] }),
|
|
1643
|
-
|
|
1644
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-
|
|
1645
|
-
/* @__PURE__ */
|
|
1646
|
-
|
|
1647
|
-
/* @__PURE__ */
|
|
1648
|
-
|
|
1596
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-split", children: [
|
|
1597
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-left", children: [
|
|
1598
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-hero", children: [
|
|
1599
|
+
activeSize ? /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-hero-badge", children: activeSize }) : /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-hero-badge ps-tryon-sr-hero-badge-icon", children: /* @__PURE__ */ jsx(RulerIcon, { size: 22 }) }),
|
|
1600
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-hero-info", children: [
|
|
1601
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-hero-title", children: t("Your Size") }),
|
|
1602
|
+
/* @__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") })
|
|
1603
|
+
] })
|
|
1604
|
+
] }),
|
|
1605
|
+
sizeChanged && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-size-changed", children: [
|
|
1606
|
+
/* @__PURE__ */ jsx(SparkleIcon, { size: 13 }),
|
|
1607
|
+
" ",
|
|
1608
|
+
t("Updated to"),
|
|
1609
|
+
" ",
|
|
1610
|
+
/* @__PURE__ */ jsx("strong", { children: activeSize })
|
|
1611
|
+
] }),
|
|
1612
|
+
Object.keys(allIntlSizes).length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
|
|
1613
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-section-title", children: t("Your size in other countries") }),
|
|
1614
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-intl-grid", children: Object.entries(allIntlSizes).map(([code, val]) => /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl-card", children: [
|
|
1615
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-val", children: val }),
|
|
1616
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-code", children: code })
|
|
1617
|
+
] }, code)) })
|
|
1649
1618
|
] })
|
|
1650
1619
|
] }),
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
/* @__PURE__ */
|
|
1659
|
-
|
|
1660
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-body", children: [
|
|
1661
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-col", children: [
|
|
1662
|
-
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-fc-label", children: t("You") }),
|
|
1663
|
-
editing ? /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-edit", children: [
|
|
1620
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-right", children: [
|
|
1621
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-section-title", children: t("Your Measurements") }),
|
|
1622
|
+
fitRows.map((row, i) => /* @__PURE__ */ jsxs("div", { className: `ps-tryon-sr-meas ps-fit-${row.fit}`, children: [
|
|
1623
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-meas-head", children: [
|
|
1624
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-meas-area", children: row.area }),
|
|
1625
|
+
/* @__PURE__ */ jsx("span", { className: `ps-tryon-sr-meas-badge ps-fit-${row.fit}`, children: row.fit === "good" ? `✓ ${t("within range")}` : row.fit === "tight" ? `↑ ${t("may be snug")}` : `↓ ${t("may be loose")}` })
|
|
1626
|
+
] }),
|
|
1627
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-meas-row", children: [
|
|
1628
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-meas-input-wrap", children: [
|
|
1664
1629
|
/* @__PURE__ */ jsx(
|
|
1665
1630
|
"input",
|
|
1666
1631
|
{
|
|
1667
1632
|
type: "number",
|
|
1668
|
-
className: "ps-tryon-sr-
|
|
1633
|
+
className: "ps-tryon-sr-meas-input",
|
|
1669
1634
|
value: editVals[row.area] !== void 0 ? editVals[row.area] : row.userNum,
|
|
1670
1635
|
onChange: (e) => setEditVals((prev) => ({ ...prev, [row.area]: e.target.value }))
|
|
1671
1636
|
}
|
|
1672
1637
|
),
|
|
1673
|
-
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-
|
|
1674
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-value", children: [
|
|
1675
|
-
row.userNum,
|
|
1676
|
-
" ",
|
|
1677
|
-
unitLbl
|
|
1678
|
-
] })
|
|
1679
|
-
] }),
|
|
1680
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-col", children: [
|
|
1681
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-label", children: [
|
|
1682
|
-
t("Chart"),
|
|
1683
|
-
" (",
|
|
1684
|
-
selSize,
|
|
1685
|
-
")"
|
|
1638
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-meas-unit", children: unitLbl })
|
|
1686
1639
|
] }),
|
|
1687
|
-
/* @__PURE__ */
|
|
1640
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-meas-vs", children: "vs" }),
|
|
1641
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-meas-chart", children: [
|
|
1688
1642
|
row.chartLabel,
|
|
1689
1643
|
" ",
|
|
1690
1644
|
unitLbl
|
|
1691
1645
|
] })
|
|
1692
1646
|
] })
|
|
1693
|
-
] })
|
|
1694
|
-
|
|
1647
|
+
] }, i)),
|
|
1648
|
+
fitRows.length === 0 && sizingResult.reasoning && /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-reasoning", children: /* @__PURE__ */ jsx("p", { children: sizingResult.reasoning }) })
|
|
1649
|
+
] })
|
|
1695
1650
|
] }),
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
" ",
|
|
1701
|
-
/* @__PURE__ */ jsx(ArrowRightIcon, {})
|
|
1702
|
-
] }),
|
|
1703
|
-
/* @__PURE__ */ jsx("button", { className: "ps-tryon-btn-secondary", onClick: handleClose, children: t("Done") })
|
|
1651
|
+
/* @__PURE__ */ jsxs("button", { className: "ps-tryon-cta", onClick: () => setView("upload"), children: [
|
|
1652
|
+
t("See how it looks on you"),
|
|
1653
|
+
" ",
|
|
1654
|
+
/* @__PURE__ */ jsx(ArrowRightIcon, {})
|
|
1704
1655
|
] })
|
|
1705
1656
|
] })
|
|
1706
1657
|
] });
|
|
@@ -1920,7 +1871,7 @@ function PrimeStyleTryonInner({
|
|
|
1920
1871
|
] }),
|
|
1921
1872
|
view !== "idle" && /* @__PURE__ */ jsx("div", { className: cx("ps-tryon-overlay", cn.overlay), onClick: (e) => {
|
|
1922
1873
|
if (e.target === e.currentTarget) handleClose();
|
|
1923
|
-
}, children: /* @__PURE__ */ jsxs("div", { className: cx(`ps-tryon-modal${view === "result" && resultImageUrl && sizingResult ? " ps-tryon-modal-wide" : ""}`, cn.modal), onClick: (e) => e.stopPropagation(), children: [
|
|
1874
|
+
}, children: /* @__PURE__ */ jsxs("div", { className: cx(`ps-tryon-modal${view === "result" && resultImageUrl && sizingResult || view === "size-result" ? " ps-tryon-modal-wide" : ""}`, cn.modal), onClick: (e) => e.stopPropagation(), children: [
|
|
1924
1875
|
/* @__PURE__ */ jsxs("div", { className: cx("ps-tryon-header", cn.header), children: [
|
|
1925
1876
|
/* @__PURE__ */ jsx("span", { className: cx("ps-tryon-title", cn.title), children: t("Virtual Try-On") }),
|
|
1926
1877
|
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-header-actions", children: [
|
|
@@ -2390,21 +2341,25 @@ const STYLES = `
|
|
|
2390
2341
|
.ps-tryon-sr-hero-conf { font-size: 0.73vw; font-weight: 600; }
|
|
2391
2342
|
.ps-conf-high { color: #4ade80; } .ps-conf-medium { color: #bb945c; } .ps-conf-low { color: #ef4444; }
|
|
2392
2343
|
|
|
2393
|
-
/* Suggestion banner */
|
|
2394
|
-
.ps-tryon-sr-suggestion {
|
|
2395
|
-
display: flex; align-items: center; gap: 0.52vw;
|
|
2396
|
-
padding: 0.62vw 0.83vw; border-radius: 0.52vw;
|
|
2397
|
-
background: linear-gradient(135deg, rgba(187,148,92,0.1), rgba(187,148,92,0.04));
|
|
2398
|
-
border: 1px solid rgba(187,148,92,0.25);
|
|
2399
|
-
font-size: 0.73vw; color: #d6ba7d; cursor: pointer;
|
|
2400
|
-
animation: ps-fade-up 0.3s ease both; transition: background 0.2s;
|
|
2401
|
-
}
|
|
2402
|
-
.ps-tryon-sr-suggestion:hover { background: rgba(187,148,92,0.14); }
|
|
2403
|
-
.ps-tryon-sr-suggestion svg { stroke: #bb945c; flex-shrink: 0; }
|
|
2404
|
-
.ps-tryon-sr-suggestion strong { color: #fff; }
|
|
2405
2344
|
.ps-tryon-sr-hero-badge-icon { background: linear-gradient(135deg, #333, #444); }
|
|
2406
2345
|
.ps-tryon-sr-hero-badge-icon svg { stroke: #bb945c; }
|
|
2407
2346
|
|
|
2347
|
+
/* Size changed notice */
|
|
2348
|
+
.ps-tryon-sr-size-changed {
|
|
2349
|
+
display: flex; align-items: center; gap: 0.36vw;
|
|
2350
|
+
padding: 0.42vw 0.68vw; border-radius: 0.42vw;
|
|
2351
|
+
background: rgba(187,148,92,0.08); border: 1px solid rgba(187,148,92,0.2);
|
|
2352
|
+
font-size: 0.73vw; color: #d6ba7d; margin-top: 0.52vw;
|
|
2353
|
+
animation: ps-fade-up 0.25s ease both;
|
|
2354
|
+
}
|
|
2355
|
+
.ps-tryon-sr-size-changed svg { stroke: #bb945c; }
|
|
2356
|
+
.ps-tryon-sr-size-changed strong { color: #fff; }
|
|
2357
|
+
|
|
2358
|
+
/* Split layout */
|
|
2359
|
+
.ps-tryon-sr-split { display: flex; gap: 1.5vw; min-height: 0; }
|
|
2360
|
+
.ps-tryon-sr-left { flex: 0 0 45%; display: flex; flex-direction: column; gap: 1vw; }
|
|
2361
|
+
.ps-tryon-sr-right { flex: 1; display: flex; flex-direction: column; gap: 0.52vw; }
|
|
2362
|
+
|
|
2408
2363
|
/* Section titles */
|
|
2409
2364
|
.ps-tryon-sr-section-title { font-size: 0.73vw; font-weight: 700; color: #666; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 0.52vw; }
|
|
2410
2365
|
|
|
@@ -2446,82 +2401,44 @@ const STYLES = `
|
|
|
2446
2401
|
.ps-tryon-sr-comparing { font-size: 0.73vw; color: #bb945c; margin-top: 0.42vw; }
|
|
2447
2402
|
.ps-tryon-sr-comparing strong { color: #d6ba7d; }
|
|
2448
2403
|
|
|
2449
|
-
/*
|
|
2450
|
-
.ps-tryon-sr-
|
|
2451
|
-
|
|
2452
|
-
display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.52vw;
|
|
2453
|
-
}
|
|
2454
|
-
.ps-tryon-sr-edit-btn {
|
|
2455
|
-
display: inline-flex; align-items: center; gap: 0.31vw;
|
|
2456
|
-
padding: 0.31vw 0.73vw; border: 1px solid rgba(187,148,92,0.4); border-radius: 0.42vw;
|
|
2457
|
-
background: rgba(187,148,92,0.06); color: #bb945c; font-size: 0.68vw; font-weight: 600;
|
|
2458
|
-
cursor: pointer; font-family: inherit; transition: all 0.2s;
|
|
2459
|
-
}
|
|
2460
|
-
.ps-tryon-sr-edit-btn:hover { background: rgba(187,148,92,0.12); border-color: #bb945c; }
|
|
2461
|
-
.ps-tryon-sr-edit-btn svg { stroke: currentColor; }
|
|
2462
|
-
|
|
2463
|
-
.ps-tryon-sr-fit-cards { display: flex; flex-direction: column; gap: 0.42vw; }
|
|
2464
|
-
|
|
2465
|
-
.ps-tryon-sr-fc {
|
|
2466
|
-
border: 1px solid #282828; border-radius: 0.63vw; overflow: hidden;
|
|
2404
|
+
/* Measurement rows (right column) */
|
|
2405
|
+
.ps-tryon-sr-meas {
|
|
2406
|
+
border: 1px solid #282828; border-radius: 0.57vw; overflow: hidden;
|
|
2467
2407
|
transition: border-color 0.2s;
|
|
2468
2408
|
}
|
|
2469
|
-
.ps-tryon-sr-
|
|
2470
|
-
.ps-tryon-sr-
|
|
2471
|
-
.ps-tryon-sr-
|
|
2472
|
-
|
|
2473
|
-
.ps-tryon-sr-fc-head {
|
|
2409
|
+
.ps-tryon-sr-meas.ps-fit-good { border-left: 3px solid #4ade80; }
|
|
2410
|
+
.ps-tryon-sr-meas.ps-fit-tight { border-left: 3px solid #f59e0b; }
|
|
2411
|
+
.ps-tryon-sr-meas.ps-fit-loose { border-left: 3px solid #60a5fa; }
|
|
2412
|
+
.ps-tryon-sr-meas-head {
|
|
2474
2413
|
display: flex; align-items: center; justify-content: space-between;
|
|
2475
|
-
padding: 0.
|
|
2476
|
-
}
|
|
2477
|
-
.ps-tryon-sr-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
}
|
|
2483
|
-
.ps-tryon-sr-
|
|
2484
|
-
.ps-tryon-sr-
|
|
2485
|
-
.ps-tryon-sr-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
.ps-tryon-sr-fc-value { font-size: 0.88vw; font-weight: 600; color: #ccc; }
|
|
2493
|
-
.ps-tryon-sr-fc-edit { display: flex; align-items: center; gap: 0.26vw; }
|
|
2494
|
-
.ps-tryon-sr-fc-input {
|
|
2495
|
-
width: 4.2vw; padding: 0.26vw 0.42vw; border: 1.5px solid #444; border-radius: 0.36vw;
|
|
2496
|
-
background: #0c0c0d; color: #fff; font-size: 0.88vw; font-weight: 600; font-family: inherit;
|
|
2414
|
+
padding: 0.47vw 0.73vw; background: #161616;
|
|
2415
|
+
}
|
|
2416
|
+
.ps-tryon-sr-meas-area { font-size: 0.78vw; font-weight: 700; color: #fff; }
|
|
2417
|
+
.ps-tryon-sr-meas-badge {
|
|
2418
|
+
display: inline-flex; align-items: center; gap: 0.21vw; padding: 0.16vw 0.47vw;
|
|
2419
|
+
border-radius: 0.26vw; font-size: 0.57vw; font-weight: 700; white-space: nowrap;
|
|
2420
|
+
}
|
|
2421
|
+
.ps-tryon-sr-meas-badge.ps-fit-good { background: rgba(74,222,128,0.08); color: #4ade80; }
|
|
2422
|
+
.ps-tryon-sr-meas-badge.ps-fit-tight { background: rgba(245,158,11,0.08); color: #f59e0b; }
|
|
2423
|
+
.ps-tryon-sr-meas-badge.ps-fit-loose { background: rgba(96,165,250,0.08); color: #60a5fa; }
|
|
2424
|
+
.ps-tryon-sr-meas-row {
|
|
2425
|
+
display: flex; align-items: center; gap: 0.52vw; padding: 0.47vw 0.73vw;
|
|
2426
|
+
}
|
|
2427
|
+
.ps-tryon-sr-meas-input-wrap { display: flex; align-items: center; gap: 0.21vw; }
|
|
2428
|
+
.ps-tryon-sr-meas-input {
|
|
2429
|
+
width: 3.8vw; padding: 0.26vw 0.36vw; border: 1.5px solid #444; border-radius: 0.31vw;
|
|
2430
|
+
background: #0c0c0d; color: #fff; font-size: 0.83vw; font-weight: 600; font-family: inherit;
|
|
2497
2431
|
outline: none; text-align: center; -moz-appearance: textfield;
|
|
2498
2432
|
transition: border-color 0.2s, background 0.2s;
|
|
2499
2433
|
}
|
|
2500
|
-
.ps-tryon-sr-
|
|
2501
|
-
.ps-tryon-sr-
|
|
2502
|
-
.ps-tryon-sr-
|
|
2503
|
-
.ps-tryon-sr-
|
|
2434
|
+
.ps-tryon-sr-meas-input::-webkit-outer-spin-button,
|
|
2435
|
+
.ps-tryon-sr-meas-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
|
2436
|
+
.ps-tryon-sr-meas-input:focus { border-color: #bb945c; background: #1a1a1a; }
|
|
2437
|
+
.ps-tryon-sr-meas-unit { font-size: 0.63vw; color: #555; }
|
|
2438
|
+
.ps-tryon-sr-meas-vs { font-size: 0.63vw; color: #444; font-weight: 700; }
|
|
2439
|
+
.ps-tryon-sr-meas-chart { font-size: 0.83vw; font-weight: 600; color: #888; }
|
|
2504
2440
|
|
|
2505
|
-
/*
|
|
2506
|
-
.ps-tryon-sr-compare { }
|
|
2507
|
-
.ps-tryon-sr-compare-select {
|
|
2508
|
-
width: 100%; padding: 0.57vw 2vw 0.57vw 0.83vw; border: 1.5px solid #333; border-radius: 0.57vw;
|
|
2509
|
-
background: #1a1b1a; color: #fff; font-size: 0.83vw; font-weight: 600; font-family: inherit;
|
|
2510
|
-
appearance: none; -webkit-appearance: none; cursor: pointer; outline: none;
|
|
2511
|
-
background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.5 4.5L6 8L9.5 4.5' stroke='%23999' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
2512
|
-
background-repeat: no-repeat; background-position: right 0.73vw center;
|
|
2513
|
-
}
|
|
2514
|
-
.ps-tryon-sr-compare-select:focus { border-color: #bb945c; }
|
|
2515
|
-
.ps-tryon-sr-compare-select option { background: #1a1b1a; color: #fff; }
|
|
2516
|
-
.ps-tryon-sr-compare-note {
|
|
2517
|
-
font-size: 0.73vw; color: #bb945c; margin-top: 0.42vw; display: flex; align-items: center; gap: 0.52vw;
|
|
2518
|
-
}
|
|
2519
|
-
.ps-tryon-sr-compare-reset {
|
|
2520
|
-
background: none; border: 1px solid #bb945c; color: #bb945c; padding: 0.16vw 0.52vw;
|
|
2521
|
-
border-radius: 0.31vw; font-size: 0.63vw; font-weight: 600; cursor: pointer;
|
|
2522
|
-
font-family: inherit; transition: all 0.2s;
|
|
2523
|
-
}
|
|
2524
|
-
.ps-tryon-sr-compare-reset:hover { background: rgba(187,148,92,0.1); }
|
|
2441
|
+
/* (compare dropdown removed — recalculation is automatic) */
|
|
2525
2442
|
|
|
2526
2443
|
.ps-tryon-sr-fit-badge {
|
|
2527
2444
|
display: inline-flex; align-items: center; gap: 0.26vw; padding: 0.21vw 0.52vw;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primestyleai/tryon",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.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",
|
|
@@ -53,5 +53,8 @@
|
|
|
53
53
|
"terser": "^5.31.0",
|
|
54
54
|
"typescript": "^5.5.0",
|
|
55
55
|
"vite": "^5.4.0"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@primestyleai/tryon": "^4.1.2"
|
|
56
59
|
}
|
|
57
60
|
}
|