@primestyleai/tryon 4.1.2 → 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" }),
|
|
@@ -1510,28 +1494,19 @@ function PrimeStyleTryonInner({
|
|
|
1510
1494
|
}
|
|
1511
1495
|
function SizeResultView() {
|
|
1512
1496
|
const unitLbl = sizingUnit === "cm" ? t("cm") : t("in");
|
|
1513
|
-
const [editing, setEditing] = useState(false);
|
|
1514
1497
|
const [editVals, setEditVals] = useState({});
|
|
1515
|
-
const
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
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 };
|
|
1521
1509
|
};
|
|
1522
|
-
const recSize = useMemo(() => {
|
|
1523
|
-
if (sizingResult?.recommendedSize) return sizingResult.recommendedSize;
|
|
1524
|
-
if (sizeGuide?.rows && sizeGuide.headers) {
|
|
1525
|
-
const sc = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
|
|
1526
|
-
const idx = sc >= 0 ? sc : 0;
|
|
1527
|
-
for (const row of sizeGuide.rows) {
|
|
1528
|
-
const label = row[idx]?.trim();
|
|
1529
|
-
if (label && /^(XXS|XS|S|M|L|XL|XXL|XXXL|\d{1,3})$/i.test(label)) return label;
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
return "";
|
|
1533
|
-
}, [sizingResult, sizeGuide]);
|
|
1534
|
-
const selSize = compareSize || recSize;
|
|
1535
1510
|
const sizeColIdx = useMemo(() => {
|
|
1536
1511
|
if (!sizeGuide?.headers || !sizeGuide?.rows) return -1;
|
|
1537
1512
|
const byName = sizeGuide.headers.findIndex((h) => /size|taglia|größe|taille/i.test(h.trim()));
|
|
@@ -1545,14 +1520,6 @@ function PrimeStyleTryonInner({
|
|
|
1545
1520
|
if (sizeColIdx < 0 || !sizeGuide?.rows) return [];
|
|
1546
1521
|
return sizeGuide.rows.map((r) => r[sizeColIdx]?.trim()).filter(Boolean);
|
|
1547
1522
|
}, [sizeGuide, sizeColIdx]);
|
|
1548
|
-
const pNum = (s) => {
|
|
1549
|
-
const n = parseFloat(s.replace(/[^\d.]/g, ""));
|
|
1550
|
-
return isNaN(n) ? 0 : n;
|
|
1551
|
-
};
|
|
1552
|
-
const pRange = (s) => {
|
|
1553
|
-
const ns = s.replace(/[^\d.\-–]/g, " ").trim().split(/[\s\-–]+/).filter(Boolean).map(Number).filter((n) => !isNaN(n));
|
|
1554
|
-
return ns.length ? { min: Math.min(...ns), max: Math.max(...ns) } : { min: 0, max: 0 };
|
|
1555
|
-
};
|
|
1556
1523
|
const chartRangeFor = useCallback((measurement, size) => {
|
|
1557
1524
|
if (!sizeGuide?.headers || !sizeGuide?.rows || sizeColIdx < 0) return null;
|
|
1558
1525
|
const mc = sizeGuide.headers.findIndex((h) => {
|
|
@@ -1563,6 +1530,29 @@ function PrimeStyleTryonInner({
|
|
|
1563
1530
|
const row = sizeGuide.rows.find((r) => r[sizeColIdx]?.trim() === size);
|
|
1564
1531
|
return row?.[mc] ? { range: row[mc], ...pRange(row[mc]) } : null;
|
|
1565
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;
|
|
1566
1556
|
const fitRows = useMemo(() => {
|
|
1567
1557
|
if (!sizingResult?.matchDetails?.length) return [];
|
|
1568
1558
|
return sizingResult.matchDetails.map((m) => {
|
|
@@ -1571,8 +1561,8 @@ function PrimeStyleTryonInner({
|
|
|
1571
1561
|
const userNum = edited !== void 0 && edited !== "" ? parseFloat(edited) : origNum;
|
|
1572
1562
|
let { min: rMin, max: rMax } = pRange(m.chartRange);
|
|
1573
1563
|
let chartLabel = m.chartRange;
|
|
1574
|
-
if (
|
|
1575
|
-
const alt = chartRangeFor(m.measurement,
|
|
1564
|
+
if (activeSize !== origSize) {
|
|
1565
|
+
const alt = chartRangeFor(m.measurement, activeSize);
|
|
1576
1566
|
if (alt) {
|
|
1577
1567
|
chartLabel = alt.range;
|
|
1578
1568
|
rMin = alt.min;
|
|
@@ -1580,129 +1570,88 @@ function PrimeStyleTryonInner({
|
|
|
1580
1570
|
}
|
|
1581
1571
|
}
|
|
1582
1572
|
const fit = userNum >= rMin && userNum <= rMax ? "good" : userNum < rMin ? "tight" : "loose";
|
|
1583
|
-
return { area: m.measurement, userNum, chartLabel:
|
|
1573
|
+
return { area: m.measurement, userNum, chartLabel: cleanNum(chartLabel), fit };
|
|
1584
1574
|
});
|
|
1585
|
-
}, [sizingResult,
|
|
1586
|
-
const suggestedSize = useMemo(() => {
|
|
1587
|
-
if (!Object.keys(editVals).length || !sizingResult?.matchDetails?.length || !allSizes.length) return null;
|
|
1588
|
-
let bestSize = "";
|
|
1589
|
-
let bestScore = -1;
|
|
1590
|
-
for (const size of allSizes) {
|
|
1591
|
-
let score = 0;
|
|
1592
|
-
for (const m of sizingResult.matchDetails) {
|
|
1593
|
-
const edited = editVals[m.measurement];
|
|
1594
|
-
const userNum = edited !== void 0 && edited !== "" ? parseFloat(edited) : pNum(m.userValue);
|
|
1595
|
-
const alt = chartRangeFor(m.measurement, size);
|
|
1596
|
-
if (alt && userNum >= alt.min && userNum <= alt.max) score++;
|
|
1597
|
-
}
|
|
1598
|
-
if (score > bestScore) {
|
|
1599
|
-
bestScore = score;
|
|
1600
|
-
bestSize = size;
|
|
1601
|
-
}
|
|
1602
|
-
}
|
|
1603
|
-
return bestSize && bestSize !== recSize ? bestSize : null;
|
|
1604
|
-
}, [editVals, sizingResult, allSizes, recSize, chartRangeFor]);
|
|
1575
|
+
}, [sizingResult, editVals, chartRangeFor, activeSize, origSize]);
|
|
1605
1576
|
const allIntlSizes = useMemo(() => {
|
|
1606
1577
|
const backendIntl = sizingResult?.internationalSizes || {};
|
|
1607
|
-
const upper =
|
|
1608
|
-
const fromTable = SIZE_CONVERSIONS[upper] || SIZE_CONVERSIONS[
|
|
1578
|
+
const upper = activeSize.toUpperCase().trim();
|
|
1579
|
+
const fromTable = SIZE_CONVERSIONS[upper] || SIZE_CONVERSIONS[activeSize] || {};
|
|
1609
1580
|
return { ...fromTable, ...backendIntl };
|
|
1610
|
-
}, [sizingResult,
|
|
1611
|
-
const confLabel = sizingResult?.confidence === "high" ? t("High Confidence") : sizingResult?.confidence === "medium" ? t("Medium Confidence") : t("Low Confidence");
|
|
1581
|
+
}, [sizingResult, activeSize]);
|
|
1612
1582
|
return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr", children: [
|
|
1613
1583
|
sizingLoading && !sizingResult && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-loading", children: [
|
|
1614
1584
|
/* @__PURE__ */ jsx("div", { className: "ps-tryon-size-loading-spinner" }),
|
|
1615
1585
|
/* @__PURE__ */ jsx("p", { children: t("Analyzing your size...") })
|
|
1616
1586
|
] }),
|
|
1617
1587
|
sizingResult && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1618
|
-
/* @__PURE__ */ jsxs("
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-hero-title", children: t("Your Size") }),
|
|
1622
|
-
/* @__PURE__ */ jsx("div", { className: `ps-tryon-sr-hero-conf ps-conf-${sizingResult.confidence}`, children: confLabel })
|
|
1623
|
-
] })
|
|
1624
|
-
] }),
|
|
1625
|
-
suggestedSize && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-suggestion", onClick: () => {
|
|
1626
|
-
setCompareSize(suggestedSize);
|
|
1588
|
+
/* @__PURE__ */ jsxs("button", { className: "ps-tryon-back", onClick: () => {
|
|
1589
|
+
setView("sizing-form");
|
|
1590
|
+
setEditVals({});
|
|
1627
1591
|
}, children: [
|
|
1628
|
-
/* @__PURE__ */ jsx(
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
" ",
|
|
1632
|
-
/* @__PURE__ */ jsx("strong", { children: suggestedSize }),
|
|
1633
|
-
" ",
|
|
1634
|
-
t("may be a better fit")
|
|
1635
|
-
] }),
|
|
1636
|
-
/* @__PURE__ */ jsx(ArrowRightIcon, {})
|
|
1637
|
-
] }),
|
|
1638
|
-
Object.keys(allIntlSizes).length > 0 && /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-intl", children: [
|
|
1639
|
-
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-section-title", children: t("Your size in other countries") }),
|
|
1640
|
-
/* @__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: [
|
|
1641
|
-
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-val", children: val }),
|
|
1642
|
-
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-intl-card-code", children: code })
|
|
1643
|
-
] }, code)) })
|
|
1592
|
+
/* @__PURE__ */ jsx(ArrowLeftIcon, {}),
|
|
1593
|
+
" ",
|
|
1594
|
+
t("Back")
|
|
1644
1595
|
] }),
|
|
1645
|
-
|
|
1646
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-
|
|
1647
|
-
/* @__PURE__ */
|
|
1648
|
-
|
|
1649
|
-
/* @__PURE__ */
|
|
1650
|
-
|
|
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)) })
|
|
1651
1618
|
] })
|
|
1652
1619
|
] }),
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
/* @__PURE__ */
|
|
1661
|
-
|
|
1662
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-body", children: [
|
|
1663
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-col", children: [
|
|
1664
|
-
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-fc-label", children: t("You") }),
|
|
1665
|
-
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: [
|
|
1666
1629
|
/* @__PURE__ */ jsx(
|
|
1667
1630
|
"input",
|
|
1668
1631
|
{
|
|
1669
1632
|
type: "number",
|
|
1670
|
-
className: "ps-tryon-sr-
|
|
1633
|
+
className: "ps-tryon-sr-meas-input",
|
|
1671
1634
|
value: editVals[row.area] !== void 0 ? editVals[row.area] : row.userNum,
|
|
1672
1635
|
onChange: (e) => setEditVals((prev) => ({ ...prev, [row.area]: e.target.value }))
|
|
1673
1636
|
}
|
|
1674
1637
|
),
|
|
1675
|
-
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-
|
|
1676
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-value", children: [
|
|
1677
|
-
row.userNum,
|
|
1678
|
-
" ",
|
|
1679
|
-
unitLbl
|
|
1680
|
-
] })
|
|
1681
|
-
] }),
|
|
1682
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-col", children: [
|
|
1683
|
-
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-fc-label", children: [
|
|
1684
|
-
t("Chart"),
|
|
1685
|
-
" (",
|
|
1686
|
-
selSize,
|
|
1687
|
-
")"
|
|
1638
|
+
/* @__PURE__ */ jsx("span", { className: "ps-tryon-sr-meas-unit", children: unitLbl })
|
|
1688
1639
|
] }),
|
|
1689
|
-
/* @__PURE__ */
|
|
1640
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-meas-vs", children: "vs" }),
|
|
1641
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-sr-meas-chart", children: [
|
|
1690
1642
|
row.chartLabel,
|
|
1691
1643
|
" ",
|
|
1692
1644
|
unitLbl
|
|
1693
1645
|
] })
|
|
1694
1646
|
] })
|
|
1695
|
-
] })
|
|
1696
|
-
|
|
1647
|
+
] }, i)),
|
|
1648
|
+
fitRows.length === 0 && sizingResult.reasoning && /* @__PURE__ */ jsx("div", { className: "ps-tryon-sr-reasoning", children: /* @__PURE__ */ jsx("p", { children: sizingResult.reasoning }) })
|
|
1649
|
+
] })
|
|
1697
1650
|
] }),
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
" ",
|
|
1703
|
-
/* @__PURE__ */ jsx(ArrowRightIcon, {})
|
|
1704
|
-
] }),
|
|
1705
|
-
/* @__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, {})
|
|
1706
1655
|
] })
|
|
1707
1656
|
] })
|
|
1708
1657
|
] });
|
|
@@ -1922,7 +1871,7 @@ function PrimeStyleTryonInner({
|
|
|
1922
1871
|
] }),
|
|
1923
1872
|
view !== "idle" && /* @__PURE__ */ jsx("div", { className: cx("ps-tryon-overlay", cn.overlay), onClick: (e) => {
|
|
1924
1873
|
if (e.target === e.currentTarget) handleClose();
|
|
1925
|
-
}, 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: [
|
|
1926
1875
|
/* @__PURE__ */ jsxs("div", { className: cx("ps-tryon-header", cn.header), children: [
|
|
1927
1876
|
/* @__PURE__ */ jsx("span", { className: cx("ps-tryon-title", cn.title), children: t("Virtual Try-On") }),
|
|
1928
1877
|
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-header-actions", children: [
|
|
@@ -2392,21 +2341,25 @@ const STYLES = `
|
|
|
2392
2341
|
.ps-tryon-sr-hero-conf { font-size: 0.73vw; font-weight: 600; }
|
|
2393
2342
|
.ps-conf-high { color: #4ade80; } .ps-conf-medium { color: #bb945c; } .ps-conf-low { color: #ef4444; }
|
|
2394
2343
|
|
|
2395
|
-
/* Suggestion banner */
|
|
2396
|
-
.ps-tryon-sr-suggestion {
|
|
2397
|
-
display: flex; align-items: center; gap: 0.52vw;
|
|
2398
|
-
padding: 0.62vw 0.83vw; border-radius: 0.52vw;
|
|
2399
|
-
background: linear-gradient(135deg, rgba(187,148,92,0.1), rgba(187,148,92,0.04));
|
|
2400
|
-
border: 1px solid rgba(187,148,92,0.25);
|
|
2401
|
-
font-size: 0.73vw; color: #d6ba7d; cursor: pointer;
|
|
2402
|
-
animation: ps-fade-up 0.3s ease both; transition: background 0.2s;
|
|
2403
|
-
}
|
|
2404
|
-
.ps-tryon-sr-suggestion:hover { background: rgba(187,148,92,0.14); }
|
|
2405
|
-
.ps-tryon-sr-suggestion svg { stroke: #bb945c; flex-shrink: 0; }
|
|
2406
|
-
.ps-tryon-sr-suggestion strong { color: #fff; }
|
|
2407
2344
|
.ps-tryon-sr-hero-badge-icon { background: linear-gradient(135deg, #333, #444); }
|
|
2408
2345
|
.ps-tryon-sr-hero-badge-icon svg { stroke: #bb945c; }
|
|
2409
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
|
+
|
|
2410
2363
|
/* Section titles */
|
|
2411
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; }
|
|
2412
2365
|
|
|
@@ -2448,82 +2401,44 @@ const STYLES = `
|
|
|
2448
2401
|
.ps-tryon-sr-comparing { font-size: 0.73vw; color: #bb945c; margin-top: 0.42vw; }
|
|
2449
2402
|
.ps-tryon-sr-comparing strong { color: #d6ba7d; }
|
|
2450
2403
|
|
|
2451
|
-
/*
|
|
2452
|
-
.ps-tryon-sr-
|
|
2453
|
-
|
|
2454
|
-
display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.52vw;
|
|
2455
|
-
}
|
|
2456
|
-
.ps-tryon-sr-edit-btn {
|
|
2457
|
-
display: inline-flex; align-items: center; gap: 0.31vw;
|
|
2458
|
-
padding: 0.31vw 0.73vw; border: 1px solid rgba(187,148,92,0.4); border-radius: 0.42vw;
|
|
2459
|
-
background: rgba(187,148,92,0.06); color: #bb945c; font-size: 0.68vw; font-weight: 600;
|
|
2460
|
-
cursor: pointer; font-family: inherit; transition: all 0.2s;
|
|
2461
|
-
}
|
|
2462
|
-
.ps-tryon-sr-edit-btn:hover { background: rgba(187,148,92,0.12); border-color: #bb945c; }
|
|
2463
|
-
.ps-tryon-sr-edit-btn svg { stroke: currentColor; }
|
|
2464
|
-
|
|
2465
|
-
.ps-tryon-sr-fit-cards { display: flex; flex-direction: column; gap: 0.42vw; }
|
|
2466
|
-
|
|
2467
|
-
.ps-tryon-sr-fc {
|
|
2468
|
-
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;
|
|
2469
2407
|
transition: border-color 0.2s;
|
|
2470
2408
|
}
|
|
2471
|
-
.ps-tryon-sr-
|
|
2472
|
-
.ps-tryon-sr-
|
|
2473
|
-
.ps-tryon-sr-
|
|
2474
|
-
|
|
2475
|
-
.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 {
|
|
2476
2413
|
display: flex; align-items: center; justify-content: space-between;
|
|
2477
|
-
padding: 0.
|
|
2478
|
-
}
|
|
2479
|
-
.ps-tryon-sr-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
}
|
|
2485
|
-
.ps-tryon-sr-
|
|
2486
|
-
.ps-tryon-sr-
|
|
2487
|
-
.ps-tryon-sr-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
.ps-tryon-sr-fc-value { font-size: 0.88vw; font-weight: 600; color: #ccc; }
|
|
2495
|
-
.ps-tryon-sr-fc-edit { display: flex; align-items: center; gap: 0.26vw; }
|
|
2496
|
-
.ps-tryon-sr-fc-input {
|
|
2497
|
-
width: 4.2vw; padding: 0.26vw 0.42vw; border: 1.5px solid #444; border-radius: 0.36vw;
|
|
2498
|
-
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;
|
|
2499
2431
|
outline: none; text-align: center; -moz-appearance: textfield;
|
|
2500
2432
|
transition: border-color 0.2s, background 0.2s;
|
|
2501
2433
|
}
|
|
2502
|
-
.ps-tryon-sr-
|
|
2503
|
-
.ps-tryon-sr-
|
|
2504
|
-
.ps-tryon-sr-
|
|
2505
|
-
.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; }
|
|
2506
2440
|
|
|
2507
|
-
/*
|
|
2508
|
-
.ps-tryon-sr-compare { }
|
|
2509
|
-
.ps-tryon-sr-compare-select {
|
|
2510
|
-
width: 100%; padding: 0.57vw 2vw 0.57vw 0.83vw; border: 1.5px solid #333; border-radius: 0.57vw;
|
|
2511
|
-
background: #1a1b1a; color: #fff; font-size: 0.83vw; font-weight: 600; font-family: inherit;
|
|
2512
|
-
appearance: none; -webkit-appearance: none; cursor: pointer; outline: none;
|
|
2513
|
-
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");
|
|
2514
|
-
background-repeat: no-repeat; background-position: right 0.73vw center;
|
|
2515
|
-
}
|
|
2516
|
-
.ps-tryon-sr-compare-select:focus { border-color: #bb945c; }
|
|
2517
|
-
.ps-tryon-sr-compare-select option { background: #1a1b1a; color: #fff; }
|
|
2518
|
-
.ps-tryon-sr-compare-note {
|
|
2519
|
-
font-size: 0.73vw; color: #bb945c; margin-top: 0.42vw; display: flex; align-items: center; gap: 0.52vw;
|
|
2520
|
-
}
|
|
2521
|
-
.ps-tryon-sr-compare-reset {
|
|
2522
|
-
background: none; border: 1px solid #bb945c; color: #bb945c; padding: 0.16vw 0.52vw;
|
|
2523
|
-
border-radius: 0.31vw; font-size: 0.63vw; font-weight: 600; cursor: pointer;
|
|
2524
|
-
font-family: inherit; transition: all 0.2s;
|
|
2525
|
-
}
|
|
2526
|
-
.ps-tryon-sr-compare-reset:hover { background: rgba(187,148,92,0.1); }
|
|
2441
|
+
/* (compare dropdown removed — recalculation is automatic) */
|
|
2527
2442
|
|
|
2528
2443
|
.ps-tryon-sr-fit-badge {
|
|
2529
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
|
}
|