@primestyleai/tryon 5.10.178 → 5.10.180
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.
- package/dist/api-client.d.ts +4 -0
- package/dist/index-CYT0nGWX.js.map +1 -1
- package/dist/react/PrimeStyleTryonInner.d.ts +1 -1
- package/dist/react/index.js +5635 -5425
- package/dist/react/index.js.map +1 -1
- package/dist/react/styles.d.ts +1 -1
- package/dist/react/types.d.ts +2 -0
- package/dist/react/views/MySizingProfilesView.d.ts +2 -1
- package/dist/sizing/fit-compute.d.ts +3 -4
- package/dist/storefront/primestyle-tryon.js +455 -75
- package/dist/storefront/size-guide-modal.d.ts +1 -0
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
|
@@ -10225,6 +10225,52 @@ function parseNum(s) {
|
|
|
10225
10225
|
const n2 = parseFloat(s.replace(/[^\d.]/g, ""));
|
|
10226
10226
|
return isNaN(n2) ? 0 : n2;
|
|
10227
10227
|
}
|
|
10228
|
+
function normalizeUnit(unit) {
|
|
10229
|
+
const u2 = (unit || "").toLowerCase();
|
|
10230
|
+
if (u2 === "in" || u2 === "inch" || u2 === "inches") return "in";
|
|
10231
|
+
if (u2 === "cm") return "cm";
|
|
10232
|
+
if (u2 === "mm") return "mm";
|
|
10233
|
+
return null;
|
|
10234
|
+
}
|
|
10235
|
+
function detectUnitFromText(text) {
|
|
10236
|
+
const t2 = String(text || "");
|
|
10237
|
+
if (/\bmm\b/i.test(t2)) return "mm";
|
|
10238
|
+
if (/\bcm\b/i.test(t2)) return "cm";
|
|
10239
|
+
if (/\bin\b|inch|inches|["”]/i.test(t2)) return "in";
|
|
10240
|
+
return null;
|
|
10241
|
+
}
|
|
10242
|
+
function convertValue(value, from, to) {
|
|
10243
|
+
if (from === to) return value;
|
|
10244
|
+
const inMm = from === "mm" ? value : from === "cm" ? value * 10 : value * 25.4;
|
|
10245
|
+
if (to === "mm") return inMm;
|
|
10246
|
+
if (to === "cm") return inMm / 10;
|
|
10247
|
+
return inMm / 25.4;
|
|
10248
|
+
}
|
|
10249
|
+
function formatUnitNumber(value, unit) {
|
|
10250
|
+
const precision = unit === "mm" ? 0 : 1;
|
|
10251
|
+
const rounded = Number(value.toFixed(precision));
|
|
10252
|
+
return Number.isInteger(rounded) ? String(rounded) : String(rounded);
|
|
10253
|
+
}
|
|
10254
|
+
function convertNumberTextToUnit(text, from, to) {
|
|
10255
|
+
if (from === to) return text;
|
|
10256
|
+
const converted = text.replace(/\s*(cm|mm|in|inch|inches)\b/ig, "").replace(/(\d+(?:\.\d+)?)/g, (raw) => formatUnitNumber(convertValue(Number(raw), from, to), to)).trim();
|
|
10257
|
+
return converted ? `${converted} ${to}` : text;
|
|
10258
|
+
}
|
|
10259
|
+
function normalizeMeasurementValueText(measurement, value, targetUnit) {
|
|
10260
|
+
if (isUnitlessShoeSizeMeasurement(measurement)) return formatUserMeasurementValue(measurement, value);
|
|
10261
|
+
const sourceUnit = detectUnitFromText(value);
|
|
10262
|
+
if (sourceUnit) return convertNumberTextToUnit(value, sourceUnit, targetUnit);
|
|
10263
|
+
const trimmed = String(value || "").trim();
|
|
10264
|
+
return /\d/.test(trimmed) ? `${trimmed} ${targetUnit}` : trimmed;
|
|
10265
|
+
}
|
|
10266
|
+
function normalizeRangeText(range, targetUnit, header) {
|
|
10267
|
+
const sourceUnit = detectUnitFromText(range) || detectUnitFromText(header);
|
|
10268
|
+
if (!sourceUnit) return String(range || "").trim();
|
|
10269
|
+
return convertNumberTextToUnit(range, sourceUnit, targetUnit);
|
|
10270
|
+
}
|
|
10271
|
+
function promptHeaderLabel(header) {
|
|
10272
|
+
return String(header || "").replace(/\s*\((?:cm|mm|in|inch|inches)\)\s*/ig, "").trim();
|
|
10273
|
+
}
|
|
10228
10274
|
function isUnitlessShoeSizeMeasurement(measurement) {
|
|
10229
10275
|
const normalized = measurement.toLowerCase().replace(/\s*\(.*?\)\s*/g, " ").trim();
|
|
10230
10276
|
if (/foot\s*length|length\s*\(cm\)|cm\s*\/\s*jp|mondo|mondopoint/i.test(normalized)) return false;
|
|
@@ -10235,11 +10281,15 @@ function formatUserMeasurementValue(measurement, value) {
|
|
|
10235
10281
|
return value.replace(/\s*(cm|mm|in|inch|inches)\b/ig, "").trim();
|
|
10236
10282
|
}
|
|
10237
10283
|
function computeFit(userValue, chartRange, unit) {
|
|
10238
|
-
const
|
|
10284
|
+
const targetUnit = normalizeUnit(unit) || detectUnitFromText(chartRange) || "in";
|
|
10285
|
+
const chartUnit = detectUnitFromText(chartRange);
|
|
10286
|
+
const parsed = parseRange(chartRange);
|
|
10287
|
+
const rMin = chartUnit && chartUnit !== targetUnit ? convertValue(parsed.min, chartUnit, targetUnit) : parsed.min;
|
|
10288
|
+
const rMax = chartUnit && chartUnit !== targetUnit ? convertValue(parsed.max, chartUnit, targetUnit) : parsed.max;
|
|
10239
10289
|
if (rMin === 0 && rMax === 0) return "good";
|
|
10240
|
-
const perfectTol =
|
|
10241
|
-
const aBitTol =
|
|
10242
|
-
const tooFarTol =
|
|
10290
|
+
const perfectTol = targetUnit === "cm" ? 1.27 : targetUnit === "mm" ? 12.7 : 0.5;
|
|
10291
|
+
const aBitTol = targetUnit === "cm" ? 2.54 : targetUnit === "mm" ? 25.4 : 1;
|
|
10292
|
+
const tooFarTol = targetUnit === "cm" ? 5.08 : targetUnit === "mm" ? 50.8 : 2;
|
|
10243
10293
|
const inRange = userValue >= rMin && userValue <= rMax;
|
|
10244
10294
|
const overEdge = inRange ? 0 : userValue > rMax ? userValue - rMax : rMin - userValue;
|
|
10245
10295
|
if (inRange || overEdge <= perfectTol) return "good";
|
|
@@ -10262,14 +10312,17 @@ const SKIP_AREAS_FOR_FIT = /* @__PURE__ */ new Set([
|
|
|
10262
10312
|
]);
|
|
10263
10313
|
function buildFitInfo(matchDetails, poseLines, unit) {
|
|
10264
10314
|
return matchDetails.filter((m2) => !SKIP_AREAS_FOR_FIT.has(m2.measurement.toLowerCase().replace(/\s*\(.*?\)\s*/g, "").trim())).map((m2) => {
|
|
10265
|
-
const
|
|
10266
|
-
const
|
|
10315
|
+
const targetUnit = normalizeUnit(unit) || detectUnitFromText(m2.userValue) || detectUnitFromText(m2.chartRange) || "in";
|
|
10316
|
+
const userValueText = normalizeMeasurementValueText(m2.measurement, m2.userValue, targetUnit);
|
|
10317
|
+
const chartRangeText = normalizeRangeText(m2.chartRange, targetUnit);
|
|
10318
|
+
const userNum = parseNum(userValueText);
|
|
10319
|
+
const fit = computeFit(userNum, chartRangeText, targetUnit);
|
|
10267
10320
|
const info = {
|
|
10268
10321
|
area: m2.measurement,
|
|
10269
10322
|
section: m2.section || void 0,
|
|
10270
10323
|
fit,
|
|
10271
10324
|
userValue: userNum || void 0,
|
|
10272
|
-
garmentRange:
|
|
10325
|
+
garmentRange: chartRangeText || void 0
|
|
10273
10326
|
};
|
|
10274
10327
|
if (poseLines) {
|
|
10275
10328
|
const poseKey = AREA_TO_POSE_KEY[m2.measurement.toLowerCase()];
|
|
@@ -10286,6 +10339,7 @@ function buildFitInfo(matchDetails, poseLines, unit) {
|
|
|
10286
10339
|
function buildSilhouetteContext(sizingResult, sizeGuide, selectedSizeOverride, userHeight, userWeight) {
|
|
10287
10340
|
if (!sizingResult && !sizeGuide && !userHeight && !userWeight) return void 0;
|
|
10288
10341
|
const out = {};
|
|
10342
|
+
const promptUnit = normalizeUnit(sizingResult?.unit) || detectUnitFromText(sizingResult?.matchDetails?.[0]?.userValue) || detectUnitFromText(Object.values(sizingResult?.sections || {})[0]?.matchDetails?.[0]?.userValue) || "in";
|
|
10289
10343
|
const baseSize = (selectedSizeOverride || sizingResult?.recommendedSize || "").toString().trim();
|
|
10290
10344
|
if (userHeight) out.userHeight = userHeight;
|
|
10291
10345
|
if (userWeight) out.userWeight = userWeight;
|
|
@@ -10311,7 +10365,7 @@ function buildSilhouetteContext(sizingResult, sizeGuide, selectedSizeOverride, u
|
|
|
10311
10365
|
chartRowFit = vStr;
|
|
10312
10366
|
continue;
|
|
10313
10367
|
}
|
|
10314
|
-
if (vStr) bits.push(`${h} ${vStr}`);
|
|
10368
|
+
if (vStr) bits.push(`${promptHeaderLabel(h) || h} ${normalizeRangeText(vStr, promptUnit, h)}`);
|
|
10315
10369
|
if (chartRowLength == null && /^length\b|inseam/i.test(h) && vStr) {
|
|
10316
10370
|
chartRowLength = vStr;
|
|
10317
10371
|
}
|
|
@@ -10360,7 +10414,7 @@ function buildSilhouetteContext(sizingResult, sizeGuide, selectedSizeOverride, u
|
|
|
10360
10414
|
const h = (secChart.headers[i] || "").trim();
|
|
10361
10415
|
const baseHeader = h.replace(/\s*\(.*?\)\s*/g, "").trim();
|
|
10362
10416
|
if (vStr && !/^(size|standard|country|fit|silhouette|category|body[\s_]?type|eu|uk|us|it|jp|cn|kr|ru|br|au)$/i.test(baseHeader)) {
|
|
10363
|
-
bits.push(`${h} ${vStr}`);
|
|
10417
|
+
bits.push(`${promptHeaderLabel(h) || h} ${normalizeRangeText(vStr, promptUnit, h)}`);
|
|
10364
10418
|
}
|
|
10365
10419
|
}
|
|
10366
10420
|
if (bits.length) measurementParts.push(`${cleanSec} ${secSize}: ${bits.join(", ")}`);
|
|
@@ -10370,29 +10424,33 @@ function buildSilhouetteContext(sizingResult, sizeGuide, selectedSizeOverride, u
|
|
|
10370
10424
|
if (labelParts.length) out.recommendedSize = labelParts.join(", ");
|
|
10371
10425
|
if (measurementParts.length) out.recommendedSizeMeasurements = measurementParts.join(" | ");
|
|
10372
10426
|
}
|
|
10373
|
-
const
|
|
10427
|
+
const seenUserMeasurements = /* @__PURE__ */ new Set();
|
|
10428
|
+
const seenSelectedMeasurements = /* @__PURE__ */ new Set();
|
|
10374
10429
|
const userLines = [];
|
|
10375
|
-
const
|
|
10430
|
+
const selectedMeasurementLines = [];
|
|
10431
|
+
const push = (md2, sectionName) => {
|
|
10376
10432
|
if (!md2) return;
|
|
10377
10433
|
for (const m2 of md2) {
|
|
10378
|
-
const
|
|
10379
|
-
if (
|
|
10380
|
-
|
|
10381
|
-
if (m2.userValue
|
|
10434
|
+
const normalizedMeasurement = m2.measurement.toLowerCase().replace(/\s*\(.*?\)\s*/g, "").trim();
|
|
10435
|
+
if (SKIP_AREAS_FOR_FIT.has(normalizedMeasurement)) continue;
|
|
10436
|
+
const selectedKey = sectionName ? `${sectionName.toLowerCase()}:${normalizedMeasurement}` : normalizedMeasurement;
|
|
10437
|
+
if (m2.userValue && !seenUserMeasurements.has(normalizedMeasurement)) {
|
|
10438
|
+
seenUserMeasurements.add(normalizedMeasurement);
|
|
10439
|
+
userLines.push(`${m2.measurement} ${normalizeMeasurementValueText(m2.measurement, m2.userValue, promptUnit)}`);
|
|
10440
|
+
}
|
|
10441
|
+
if (m2.chartRange && !seenSelectedMeasurements.has(selectedKey)) {
|
|
10442
|
+
seenSelectedMeasurements.add(selectedKey);
|
|
10443
|
+
const prefix = sectionName ? `${sectionName} ${m2.measurement}` : m2.measurement;
|
|
10444
|
+
selectedMeasurementLines.push(`${prefix} ${normalizeRangeText(m2.chartRange, promptUnit)}`);
|
|
10445
|
+
}
|
|
10382
10446
|
}
|
|
10383
10447
|
};
|
|
10384
10448
|
push(sizingResult?.matchDetails);
|
|
10385
10449
|
if (sizingResult?.sections) {
|
|
10386
|
-
for (const sec of Object.
|
|
10450
|
+
for (const [secName, sec] of Object.entries(sizingResult.sections)) push(sec.matchDetails, secName);
|
|
10387
10451
|
}
|
|
10388
10452
|
if (userLines.length) out.userMeasurementsText = userLines.join(", ");
|
|
10389
|
-
if (
|
|
10390
|
-
const hdrs = sizeGuide.headers;
|
|
10391
|
-
const rowStrings = sizeGuide.rows.slice(0, 20).map(
|
|
10392
|
-
(row) => hdrs.map((h, i) => `${h} ${row[i] ?? "—"}`).join(", ")
|
|
10393
|
-
);
|
|
10394
|
-
out.sizeChartSummary = rowStrings.join(" | ");
|
|
10395
|
-
}
|
|
10453
|
+
if (selectedMeasurementLines.length) out.recommendedSizeMeasurements = selectedMeasurementLines.join(", ");
|
|
10396
10454
|
return Object.keys(out).length ? out : void 0;
|
|
10397
10455
|
}
|
|
10398
10456
|
const FALLBACK_FIELDS_FEMALE = [
|
|
@@ -11346,6 +11404,14 @@ function setStoredProfileSession(session) {
|
|
|
11346
11404
|
} catch {
|
|
11347
11405
|
}
|
|
11348
11406
|
}
|
|
11407
|
+
function clearStoredProfileSession() {
|
|
11408
|
+
const storage = readStorage();
|
|
11409
|
+
if (!storage) return;
|
|
11410
|
+
try {
|
|
11411
|
+
storage.removeItem(SESSION_KEY);
|
|
11412
|
+
} catch {
|
|
11413
|
+
}
|
|
11414
|
+
}
|
|
11349
11415
|
function startSocialProfileLogin(provider, apiUrl) {
|
|
11350
11416
|
if (typeof window === "undefined") {
|
|
11351
11417
|
return Promise.reject(new Error("Social login must run in the browser."));
|
|
@@ -11627,7 +11693,7 @@ function productFitTypeToMeasurementType(fitType) {
|
|
|
11627
11693
|
}
|
|
11628
11694
|
return "body";
|
|
11629
11695
|
}
|
|
11630
|
-
const STYLES
|
|
11696
|
+
const STYLES = `
|
|
11631
11697
|
/* Variable defaults must live on BOTH the root (for the trigger button)
|
|
11632
11698
|
and the overlay (which is React-portaled to <body> and therefore not
|
|
11633
11699
|
a descendant of .ps-tryon-root, so the cascade is broken). Without
|
|
@@ -11694,6 +11760,7 @@ const STYLES$1 = `
|
|
|
11694
11760
|
position: fixed; inset: 0; background: var(--ps-modal-overlay, rgba(0,0,0,0.6));
|
|
11695
11761
|
display: flex; align-items: center; justify-content: center;
|
|
11696
11762
|
z-index: 2147483647;
|
|
11763
|
+
pointer-events: auto;
|
|
11697
11764
|
isolation: isolate;
|
|
11698
11765
|
contain: layout style;
|
|
11699
11766
|
padding: 0.83vw;
|
|
@@ -12183,11 +12250,20 @@ const STYLES$1 = `
|
|
|
12183
12250
|
min-height: 0;
|
|
12184
12251
|
}
|
|
12185
12252
|
.ps-tryon-v2-result-panel .ps-tryon-photo-strip {
|
|
12186
|
-
flex: 0
|
|
12253
|
+
flex: 0 0 auto;
|
|
12187
12254
|
min-height: 0;
|
|
12255
|
+
margin-top: clamp(10px, 0.75vw, 14px);
|
|
12256
|
+
margin-bottom: clamp(8px, 0.7vw, 12px);
|
|
12188
12257
|
}
|
|
12189
12258
|
.ps-tryon-v2-result-panel .ps-tryon-sr-card-v2 {
|
|
12190
|
-
min-height: 10.5vw;
|
|
12259
|
+
min-height: clamp(140px, 10.5vw, 165px);
|
|
12260
|
+
}
|
|
12261
|
+
.ps-tryon-v2-result-panel .ps-tryon-sr-card-v2.ps-full {
|
|
12262
|
+
min-height: clamp(140px, 10.5vw, 165px);
|
|
12263
|
+
}
|
|
12264
|
+
.ps-tryon-v2-result-panel .ps-tryon-photo-strip-cell {
|
|
12265
|
+
aspect-ratio: 1 / 1;
|
|
12266
|
+
height: auto;
|
|
12191
12267
|
}
|
|
12192
12268
|
.ps-tryon-v2-result-actions {
|
|
12193
12269
|
display: flex;
|
|
@@ -12682,9 +12758,12 @@ const STYLES$1 = `
|
|
|
12682
12758
|
.ps-tryon-photo-strip-row {
|
|
12683
12759
|
display: grid;
|
|
12684
12760
|
grid-template-columns: repeat(3, 1fr);
|
|
12685
|
-
gap: 0.
|
|
12761
|
+
gap: 0.45vw;
|
|
12686
12762
|
animation: ps-tryon-photo-strip-fade 0.5s ease;
|
|
12687
12763
|
}
|
|
12764
|
+
.ps-tryon-photo-strip-row.ps-count-1 .ps-tryon-photo-strip-cell {
|
|
12765
|
+
grid-column: 2;
|
|
12766
|
+
}
|
|
12688
12767
|
.ps-tryon-photo-strip-cell {
|
|
12689
12768
|
position: relative;
|
|
12690
12769
|
display: block;
|
|
@@ -12707,7 +12786,7 @@ const STYLES$1 = `
|
|
|
12707
12786
|
object-position: center center;
|
|
12708
12787
|
padding: 0;
|
|
12709
12788
|
box-sizing: border-box;
|
|
12710
|
-
transform:
|
|
12789
|
+
transform: none;
|
|
12711
12790
|
transform-origin: center center;
|
|
12712
12791
|
user-select: none;
|
|
12713
12792
|
pointer-events: none;
|
|
@@ -12748,7 +12827,7 @@ const STYLES$1 = `
|
|
|
12748
12827
|
}
|
|
12749
12828
|
.ps-tryon-photo-strip-cell > img {
|
|
12750
12829
|
object-position: center center;
|
|
12751
|
-
transform:
|
|
12830
|
+
transform: none;
|
|
12752
12831
|
}
|
|
12753
12832
|
}
|
|
12754
12833
|
|
|
@@ -18087,7 +18166,56 @@ const STYLES$1 = `
|
|
|
18087
18166
|
overflow-y: auto; -webkit-overflow-scrolling: touch;
|
|
18088
18167
|
padding: 4px;
|
|
18089
18168
|
}
|
|
18169
|
+
.ps-msp-home {
|
|
18170
|
+
height: 100%;
|
|
18171
|
+
min-height: 0;
|
|
18172
|
+
display: flex;
|
|
18173
|
+
flex-direction: column;
|
|
18174
|
+
gap: max(12px, 0.95vw);
|
|
18175
|
+
}
|
|
18176
|
+
.ps-msp-welcome-panel,
|
|
18177
|
+
.ps-msp-cards-panel {
|
|
18178
|
+
min-width: 0;
|
|
18179
|
+
min-height: 0;
|
|
18180
|
+
background: var(--ps-bg-primary);
|
|
18181
|
+
}
|
|
18182
|
+
.ps-msp-welcome-panel {
|
|
18183
|
+
display: flex;
|
|
18184
|
+
align-items: flex-start;
|
|
18185
|
+
justify-content: space-between;
|
|
18186
|
+
gap: max(12px, 1vw);
|
|
18187
|
+
padding: max(12px, 1vw) 0 max(12px, 0.95vw);
|
|
18188
|
+
border-bottom: 1px solid var(--ps-border-subtle);
|
|
18189
|
+
}
|
|
18190
|
+
.ps-msp-cards-panel {
|
|
18191
|
+
display: flex;
|
|
18192
|
+
flex-direction: column;
|
|
18193
|
+
overflow: hidden;
|
|
18194
|
+
flex: 1;
|
|
18195
|
+
}
|
|
18196
|
+
.ps-msp-cards-scroll {
|
|
18197
|
+
flex: 1;
|
|
18198
|
+
min-height: 0;
|
|
18199
|
+
overflow-y: auto;
|
|
18200
|
+
-webkit-overflow-scrolling: touch;
|
|
18201
|
+
padding: max(4px, 0.35vw) 0 max(8px, 0.65vw);
|
|
18202
|
+
}
|
|
18090
18203
|
.ps-msp-header { margin-bottom: max(10px, 0.85vw); }
|
|
18204
|
+
.ps-msp-header-row {
|
|
18205
|
+
display: flex;
|
|
18206
|
+
align-items: flex-start;
|
|
18207
|
+
justify-content: space-between;
|
|
18208
|
+
gap: max(10px, 0.8vw);
|
|
18209
|
+
}
|
|
18210
|
+
.ps-msp-header-copy { min-width: 0; }
|
|
18211
|
+
.ps-msp-kicker {
|
|
18212
|
+
font-size: max(9px, 0.58vw);
|
|
18213
|
+
font-weight: 800;
|
|
18214
|
+
letter-spacing: 0.12em;
|
|
18215
|
+
text-transform: uppercase;
|
|
18216
|
+
color: var(--ps-accent);
|
|
18217
|
+
margin-bottom: max(4px, 0.32vw);
|
|
18218
|
+
}
|
|
18091
18219
|
.ps-msp-title {
|
|
18092
18220
|
font-size: max(13px, 0.95vw);
|
|
18093
18221
|
font-weight: 700;
|
|
@@ -18096,16 +18224,56 @@ const STYLES$1 = `
|
|
|
18096
18224
|
letter-spacing: -0.005em;
|
|
18097
18225
|
}
|
|
18098
18226
|
.ps-msp-subtitle {
|
|
18099
|
-
font-size: max(
|
|
18227
|
+
font-size: max(11px, 0.72vw);
|
|
18100
18228
|
color: var(--ps-text-muted);
|
|
18101
|
-
margin: 0;
|
|
18229
|
+
margin: 0;
|
|
18230
|
+
line-height: 1.55;
|
|
18231
|
+
max-width: 54ch;
|
|
18232
|
+
}
|
|
18233
|
+
.ps-msp-header-actions {
|
|
18234
|
+
display: flex;
|
|
18235
|
+
align-items: center;
|
|
18236
|
+
gap: max(8px, 0.65vw);
|
|
18237
|
+
flex-shrink: 0;
|
|
18238
|
+
}
|
|
18239
|
+
.ps-msp-primary-create {
|
|
18240
|
+
border: 0;
|
|
18241
|
+
border-radius: 999px;
|
|
18242
|
+
background: var(--ps-accent);
|
|
18243
|
+
color: #FFFFFF;
|
|
18244
|
+
font-family: inherit;
|
|
18245
|
+
font-size: max(10px, 0.66vw);
|
|
18246
|
+
font-weight: 800;
|
|
18247
|
+
padding: max(7px, 0.52vw) max(11px, 0.8vw);
|
|
18248
|
+
cursor: pointer;
|
|
18249
|
+
transition: opacity 0.15s, transform 0.15s;
|
|
18250
|
+
}
|
|
18251
|
+
.ps-msp-primary-create:hover { opacity: 0.88; }
|
|
18252
|
+
.ps-msp-primary-create:active { transform: scale(0.98); }
|
|
18253
|
+
.ps-msp-logout {
|
|
18254
|
+
flex-shrink: 0;
|
|
18255
|
+
border: 1px solid var(--ps-border-color);
|
|
18256
|
+
border-radius: 999px;
|
|
18257
|
+
background: #FFFFFF;
|
|
18258
|
+
color: #DC2626;
|
|
18259
|
+
font-family: inherit;
|
|
18260
|
+
font-size: max(10px, 0.62vw);
|
|
18261
|
+
font-weight: 700;
|
|
18262
|
+
padding: max(6px, 0.42vw) max(9px, 0.68vw);
|
|
18263
|
+
cursor: pointer;
|
|
18264
|
+
transition: border-color 0.15s, color 0.15s, background 0.15s;
|
|
18265
|
+
}
|
|
18266
|
+
.ps-msp-logout:hover {
|
|
18267
|
+
border-color: #DC2626;
|
|
18268
|
+
color: #B91C1C;
|
|
18269
|
+
background: #FEF2F2;
|
|
18102
18270
|
}
|
|
18103
18271
|
|
|
18104
18272
|
/* Card grid — compact saved profile cards */
|
|
18105
18273
|
.ps-msp-grid {
|
|
18106
18274
|
display: grid;
|
|
18107
|
-
grid-template-columns: repeat(auto-fill, minmax(max(
|
|
18108
|
-
gap: max(
|
|
18275
|
+
grid-template-columns: repeat(auto-fill, minmax(max(160px, 12vw), 1fr));
|
|
18276
|
+
gap: max(10px, 0.8vw);
|
|
18109
18277
|
margin-bottom: max(14px, 1.2vw);
|
|
18110
18278
|
}
|
|
18111
18279
|
.ps-msp-card {
|
|
@@ -18406,27 +18574,28 @@ const STYLES$1 = `
|
|
|
18406
18574
|
}
|
|
18407
18575
|
/* When create card is the only item (no saved profiles), make it wider */
|
|
18408
18576
|
.ps-msp-grid > .ps-msp-card-create:only-child {
|
|
18409
|
-
grid-column:
|
|
18410
|
-
|
|
18411
|
-
|
|
18412
|
-
|
|
18577
|
+
grid-column: auto;
|
|
18578
|
+
width: max(150px, 12vw);
|
|
18579
|
+
min-height: max(96px, 7.4vw);
|
|
18580
|
+
max-width: max(150px, 12vw);
|
|
18581
|
+
margin: 0;
|
|
18413
18582
|
}
|
|
18414
18583
|
.ps-msp-create-icon {
|
|
18415
|
-
width: max(
|
|
18416
|
-
height: max(
|
|
18584
|
+
width: max(28px, 2.2vw);
|
|
18585
|
+
height: max(28px, 2.2vw);
|
|
18417
18586
|
background: var(--ps-accent); color: #FFFFFF;
|
|
18418
18587
|
border-radius: max(4px, 0.35vw);
|
|
18419
18588
|
display: flex; align-items: center; justify-content: center;
|
|
18420
18589
|
margin-bottom: max(6px, 0.55vw);
|
|
18421
18590
|
}
|
|
18422
18591
|
.ps-msp-create-title {
|
|
18423
|
-
font-size: max(
|
|
18592
|
+
font-size: max(10px, 0.68vw);
|
|
18424
18593
|
font-weight: 700;
|
|
18425
18594
|
color: var(--ps-text-primary);
|
|
18426
18595
|
margin-bottom: max(2px, 0.2vw);
|
|
18427
18596
|
}
|
|
18428
18597
|
.ps-msp-create-sub {
|
|
18429
|
-
font-size: max(
|
|
18598
|
+
font-size: max(7px, 0.46vw);
|
|
18430
18599
|
font-weight: 700;
|
|
18431
18600
|
letter-spacing: 0.14em; text-transform: uppercase;
|
|
18432
18601
|
color: var(--ps-text-muted);
|
|
@@ -18696,11 +18865,34 @@ const STYLES$1 = `
|
|
|
18696
18865
|
|
|
18697
18866
|
@media (max-width: 768px) {
|
|
18698
18867
|
/* Profile card grid */
|
|
18868
|
+
.ps-msp-home {
|
|
18869
|
+
height: auto;
|
|
18870
|
+
gap: 3vw;
|
|
18871
|
+
}
|
|
18872
|
+
.ps-msp-welcome-panel {
|
|
18873
|
+
gap: 3vw;
|
|
18874
|
+
padding: 3vw 0;
|
|
18875
|
+
}
|
|
18876
|
+
.ps-msp-cards-scroll {
|
|
18877
|
+
max-height: 66vh;
|
|
18878
|
+
padding: 1vw 0 3vw;
|
|
18879
|
+
}
|
|
18880
|
+
.ps-msp-header-actions { width: 100%; gap: 2vw; }
|
|
18881
|
+
.ps-msp-primary-create { font-size: 3vw; padding: 2.4vw 3.4vw; }
|
|
18882
|
+
.ps-msp-header-actions .ps-msp-primary-create { flex: 1; }
|
|
18699
18883
|
.ps-msp-grid { grid-template-columns: 1fr; gap: 3vw; }
|
|
18700
18884
|
.ps-msp-card-create { min-height: 22vw; }
|
|
18885
|
+
.ps-msp-grid > .ps-msp-card-create:only-child {
|
|
18886
|
+
width: 46vw;
|
|
18887
|
+
max-width: 46vw;
|
|
18888
|
+
min-height: 30vw;
|
|
18889
|
+
}
|
|
18701
18890
|
.ps-msp-header { margin-bottom: 3vw; }
|
|
18891
|
+
.ps-msp-header-row { align-items: flex-start; gap: 3vw; }
|
|
18892
|
+
.ps-msp-kicker { font-size: 2.4vw; margin-bottom: 1vw; }
|
|
18702
18893
|
.ps-msp-title { font-size: 5.6vw; }
|
|
18703
18894
|
.ps-msp-subtitle { font-size: 3vw; }
|
|
18895
|
+
.ps-msp-logout { font-size: 2.8vw; padding: 2vw 2.8vw; }
|
|
18704
18896
|
.ps-msp-card { padding: 3.5vw; border-radius: 3vw; }
|
|
18705
18897
|
.ps-msp-card-tag { font-size: 2.3vw; padding: 1vw 2vw; border-radius: 1vw; }
|
|
18706
18898
|
.ps-msp-card-circle { width: 18vw; height: 18vw; margin: 2vw auto 3vw; }
|
|
@@ -22269,7 +22461,7 @@ function ProductPhotoCarouselCard({
|
|
|
22269
22461
|
const slide = entries.slice(start, start + PER_SLIDE);
|
|
22270
22462
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-photo-strip", role: "group", "aria-label": t2("Product photos"), children: [
|
|
22271
22463
|
isCompleteLook && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-photo-strip-head", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-photo-strip-badge", children: t2("Complete the look") }) }),
|
|
22272
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className:
|
|
22464
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `ps-tryon-photo-strip-row ps-count-${slide.length}`, children: slide.map((item, i) => {
|
|
22273
22465
|
const content = /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: item.image, alt: item.title || productTitle || "", draggable: false });
|
|
22274
22466
|
return item.href ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22275
22467
|
"a",
|
|
@@ -27982,6 +28174,7 @@ function MySizingProfilesView({
|
|
|
27982
28174
|
onSaveProfileMeasurements,
|
|
27983
28175
|
onSaveBraSize,
|
|
27984
28176
|
onRequestDelete,
|
|
28177
|
+
onLogout,
|
|
27985
28178
|
onClose,
|
|
27986
28179
|
apiUrl,
|
|
27987
28180
|
apiKey,
|
|
@@ -27993,18 +28186,9 @@ function MySizingProfilesView({
|
|
|
27993
28186
|
t: t2,
|
|
27994
28187
|
onRegisterBackInterceptor
|
|
27995
28188
|
}) {
|
|
27996
|
-
const [creating, setCreating] = reactExports.useState(
|
|
28189
|
+
const [creating, setCreating] = reactExports.useState(false);
|
|
27997
28190
|
const [viewingId, setViewingId] = reactExports.useState(null);
|
|
27998
|
-
const handledDraftKeyRef = reactExports.useRef(initialCreateDraft?.createdAt ?? null);
|
|
27999
28191
|
const viewingProfile = viewingId ? profiles.find((p2) => p2.id === viewingId) || null : null;
|
|
28000
|
-
reactExports.useEffect(() => {
|
|
28001
|
-
if (!initialCreateDraft) return;
|
|
28002
|
-
const draftKey = initialCreateDraft.createdAt ?? "draft";
|
|
28003
|
-
if (handledDraftKeyRef.current === draftKey && creating) return;
|
|
28004
|
-
handledDraftKeyRef.current = draftKey;
|
|
28005
|
-
setViewingId(null);
|
|
28006
|
-
setCreating(true);
|
|
28007
|
-
}, [creating, initialCreateDraft]);
|
|
28008
28192
|
reactExports.useEffect(() => {
|
|
28009
28193
|
if (viewingId && !profiles.find((p2) => p2.id === viewingId)) {
|
|
28010
28194
|
setViewingId(null);
|
|
@@ -28075,12 +28259,19 @@ function MySizingProfilesView({
|
|
|
28075
28259
|
t: t2
|
|
28076
28260
|
},
|
|
28077
28261
|
`create-${initialCreateDraft?.createdAt ?? "blank"}`
|
|
28078
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
28079
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
28080
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
28081
|
-
|
|
28262
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-home", children: [
|
|
28263
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "ps-msp-welcome-panel", "aria-label": t2("Profile welcome"), children: [
|
|
28264
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
28265
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msp-kicker", children: t2("Welcome") }),
|
|
28266
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-msp-title", children: t2("My Sizing Profiles") }),
|
|
28267
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-msp-subtitle", children: profiles.length > 0 ? t2("Choose a saved profile or create a new one before finding your best fit.") : t2("Create your first fit profile to save your measurements, photo, and size history.") })
|
|
28268
|
+
] }),
|
|
28269
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-header-actions", children: [
|
|
28270
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-msp-primary-create", onClick: () => setCreating(true), children: t2("Create New Profile") }),
|
|
28271
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-msp-logout", onClick: onLogout, children: t2("Sign out") })
|
|
28272
|
+
] })
|
|
28082
28273
|
] }),
|
|
28083
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-grid", children: [
|
|
28274
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("section", { className: "ps-msp-cards-panel", "aria-label": t2("Your profiles"), children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msp-cards-scroll", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-grid", children: [
|
|
28084
28275
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CreateProfileCard, { onClick: () => setCreating(true), t: t2 }),
|
|
28085
28276
|
profiles.map((p2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28086
28277
|
ProfileCard,
|
|
@@ -28095,7 +28286,7 @@ function MySizingProfilesView({
|
|
|
28095
28286
|
},
|
|
28096
28287
|
p2.id
|
|
28097
28288
|
))
|
|
28098
|
-
] })
|
|
28289
|
+
] }) }) })
|
|
28099
28290
|
] }) }) });
|
|
28100
28291
|
}
|
|
28101
28292
|
const googleIcon = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2048%2048'%3e%3cpath%20fill='%23FFC107'%20d='M43.6%2020.5H42V20H24v8h11.3C33.7%2032.7%2029.3%2036%2024%2036c-6.6%200-12-5.4-12-12s5.4-12%2012-12c3.1%200%205.9%201.2%208%203.1l5.7-5.7C34.1%206.1%2029.3%204%2024%204%2012.9%204%204%2012.9%204%2024s8.9%2020%2020%2020%2020-8.9%2020-20c0-1.3-.1-2.4-.4-3.5z'/%3e%3cpath%20fill='%23FF3D00'%20d='M6.3%2014.7l6.6%204.8C14.7%2015.1%2019%2012%2024%2012c3.1%200%205.9%201.2%208%203.1l5.7-5.7C34.1%206.1%2029.3%204%2024%204%2016.2%204%209.5%208.5%206.3%2014.7z'/%3e%3cpath%20fill='%234CAF50'%20d='M24%2044c5.2%200%209.9-2%2013.4-5.2l-6.2-5.2C29.2%2035.1%2026.7%2036%2024%2036c-5.2%200-9.6-3.3-11.3-7.8l-6.5%205C9.4%2039.6%2016.1%2044%2024%2044z'/%3e%3cpath%20fill='%231976D2'%20d='M43.6%2020.5H42V20H24v8h11.3c-.8%202.3-2.3%204.2-4.1%205.6l6.2%205.2C36.9%2039.2%2044%2034%2044%2024c0-1.3-.1-2.4-.4-3.5z'/%3e%3c/svg%3e";
|
|
@@ -32102,7 +32293,7 @@ if (typeof document !== "undefined") {
|
|
|
32102
32293
|
if (!document.getElementById(id2)) {
|
|
32103
32294
|
const el2 = document.createElement("style");
|
|
32104
32295
|
el2.id = id2;
|
|
32105
|
-
el2.textContent = STYLES
|
|
32296
|
+
el2.textContent = STYLES;
|
|
32106
32297
|
document.head.appendChild(el2);
|
|
32107
32298
|
}
|
|
32108
32299
|
}
|
|
@@ -32154,6 +32345,27 @@ function sanitizeHistoryEntry(entry) {
|
|
|
32154
32345
|
hasResult: entry.hasResult || !!entry.resultImageUrl || void 0
|
|
32155
32346
|
};
|
|
32156
32347
|
}
|
|
32348
|
+
function comparableProductId(value) {
|
|
32349
|
+
return String(value || "").trim().replace(/^gid:\/\/shopify\/Product\//i, "").replace(/^Product\//i, "");
|
|
32350
|
+
}
|
|
32351
|
+
function historyEntryMatchesProduct(entry, productId, productTitle) {
|
|
32352
|
+
const currentId = comparableProductId(productId);
|
|
32353
|
+
const entryId = comparableProductId(entry.productId);
|
|
32354
|
+
if (currentId && entryId) return currentId === entryId;
|
|
32355
|
+
const currentTitle = String(productTitle || "").trim().toLowerCase();
|
|
32356
|
+
const entryTitle = String(entry.productTitle || "").trim().toLowerCase();
|
|
32357
|
+
return !!currentTitle && !!entryTitle && currentTitle === entryTitle;
|
|
32358
|
+
}
|
|
32359
|
+
function hasCompletedTryOnResult(entry) {
|
|
32360
|
+
return !!(entry.resultImageUrl || entry.hasResult);
|
|
32361
|
+
}
|
|
32362
|
+
function dispatchTryOnCompleteEvent(detail) {
|
|
32363
|
+
if (typeof window === "undefined") return;
|
|
32364
|
+
try {
|
|
32365
|
+
window.dispatchEvent(new CustomEvent("primestyle:tryon-complete", { detail }));
|
|
32366
|
+
} catch {
|
|
32367
|
+
}
|
|
32368
|
+
}
|
|
32157
32369
|
function computeMatchScore(recData) {
|
|
32158
32370
|
if (!recData) return null;
|
|
32159
32371
|
const all = [];
|
|
@@ -32209,6 +32421,7 @@ function PrimeStyleTryonInner({
|
|
|
32209
32421
|
productDescription,
|
|
32210
32422
|
productMaterial,
|
|
32211
32423
|
buttonText,
|
|
32424
|
+
limitOneColorTryOnPerProduct = false,
|
|
32212
32425
|
apiUrl,
|
|
32213
32426
|
showPoweredBy = true,
|
|
32214
32427
|
showIcon = true,
|
|
@@ -32542,6 +32755,12 @@ function PrimeStyleTryonInner({
|
|
|
32542
32755
|
setProfileAuthLoadingProvider(null);
|
|
32543
32756
|
}
|
|
32544
32757
|
}, [activeProfileId, apiUrl, hydrateProfileStore, profiles, t2]);
|
|
32758
|
+
const handleProfileLogout = reactExports.useCallback(() => {
|
|
32759
|
+
clearStoredProfileSession();
|
|
32760
|
+
setProfileSession(null);
|
|
32761
|
+
setProfileAuthError(null);
|
|
32762
|
+
setProfileAuthLoadingProvider(null);
|
|
32763
|
+
}, []);
|
|
32545
32764
|
const fileInputRef = reactExports.useRef(null);
|
|
32546
32765
|
const apiRef = reactExports.useRef(null);
|
|
32547
32766
|
const sseRef = reactExports.useRef(null);
|
|
@@ -33201,6 +33420,14 @@ function PrimeStyleTryonInner({
|
|
|
33201
33420
|
cleanupJob();
|
|
33202
33421
|
setTryOnProcessing(false);
|
|
33203
33422
|
setTryOnStartedAt(null);
|
|
33423
|
+
dispatchTryOnCompleteEvent({
|
|
33424
|
+
jobId: update.galleryId,
|
|
33425
|
+
historyEntryId: currentHistoryEntryIdRef.current,
|
|
33426
|
+
productId: effectiveProductId,
|
|
33427
|
+
productTitle,
|
|
33428
|
+
recommendedSize: sizingResultRef.current?.recommendedSize,
|
|
33429
|
+
resultImageUrl: update.imageUrl
|
|
33430
|
+
});
|
|
33204
33431
|
onComplete?.({ jobId: update.galleryId, imageUrl: update.imageUrl });
|
|
33205
33432
|
}
|
|
33206
33433
|
} else if (update.status === "failed") {
|
|
@@ -34404,6 +34631,21 @@ function PrimeStyleTryonInner({
|
|
|
34404
34631
|
setDrawer(null);
|
|
34405
34632
|
setView("size-result");
|
|
34406
34633
|
}, [cleanupJob, productId, productTitle, effectiveProductImages, effectiveProductCarouselItems]);
|
|
34634
|
+
const savedOneColorFitEntry = reactExports.useMemo(() => {
|
|
34635
|
+
if (!limitOneColorTryOnPerProduct) return null;
|
|
34636
|
+
return history.find(
|
|
34637
|
+
(entry) => hasCompletedTryOnResult(entry) && !!entry.recommendedSize && historyEntryMatchesProduct(entry, effectiveProductId, productTitle)
|
|
34638
|
+
) || null;
|
|
34639
|
+
}, [limitOneColorTryOnPerProduct, history, effectiveProductId, productTitle]);
|
|
34640
|
+
const storefrontButtonText = savedOneColorFitEntry?.recommendedSize ? `${t2("Your size is")} ${savedOneColorFitEntry.recommendedSize}` : resolvedButtonText;
|
|
34641
|
+
const handleStorefrontButtonClick = reactExports.useCallback(() => {
|
|
34642
|
+
if (savedOneColorFitEntry) {
|
|
34643
|
+
onOpen?.();
|
|
34644
|
+
restoreHistory(savedOneColorFitEntry);
|
|
34645
|
+
return;
|
|
34646
|
+
}
|
|
34647
|
+
handleOpen();
|
|
34648
|
+
}, [handleOpen, onOpen, restoreHistory, savedOneColorFitEntry]);
|
|
34407
34649
|
const updateField = reactExports.useCallback((key, val) => {
|
|
34408
34650
|
formRef.current[key] = val;
|
|
34409
34651
|
}, []);
|
|
@@ -34814,6 +35056,7 @@ function PrimeStyleTryonInner({
|
|
|
34814
35056
|
lsSet("profiles", lsGet("profiles", []).filter((p2) => p2.id !== id2));
|
|
34815
35057
|
},
|
|
34816
35058
|
onRequestDelete: (id2) => setDeleteConfirmId(id2),
|
|
35059
|
+
onLogout: handleProfileLogout,
|
|
34817
35060
|
onClose: () => setView("body-profile"),
|
|
34818
35061
|
onRegisterBackInterceptor: handleRegisterProfilesBack,
|
|
34819
35062
|
t: t2
|
|
@@ -34873,15 +35116,12 @@ function PrimeStyleTryonInner({
|
|
|
34873
35116
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
34874
35117
|
"button",
|
|
34875
35118
|
{
|
|
34876
|
-
onClick:
|
|
34877
|
-
console.log("[ps-sdk] button click event fired", e);
|
|
34878
|
-
handleOpen();
|
|
34879
|
-
},
|
|
35119
|
+
onClick: handleStorefrontButtonClick,
|
|
34880
35120
|
className: cx(cx("ps-tryon-btn", isTextTrigger ? "ps-tryon-btn--text" : void 0), cn.button),
|
|
34881
35121
|
type: "button",
|
|
34882
35122
|
children: [
|
|
34883
35123
|
!isTextTrigger && showIcon !== false && (buttonIcon || /* @__PURE__ */ jsxRuntimeExports.jsx(CameraIcon$1, {})),
|
|
34884
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children:
|
|
35124
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: storefrontButtonText })
|
|
34885
35125
|
]
|
|
34886
35126
|
}
|
|
34887
35127
|
),
|
|
@@ -35159,7 +35399,7 @@ class PrimeStyleTryonErrorBoundary extends reactExports.Component {
|
|
|
35159
35399
|
function PrimeStyleTryon(props) {
|
|
35160
35400
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(PrimeStyleTryonErrorBoundary, { ...props });
|
|
35161
35401
|
}
|
|
35162
|
-
const
|
|
35402
|
+
const SIZE_GUIDE_STYLES = `
|
|
35163
35403
|
.ps-sg-btn {
|
|
35164
35404
|
display: inline-flex;
|
|
35165
35405
|
align-items: center;
|
|
@@ -35322,7 +35562,7 @@ function injectStyles() {
|
|
|
35322
35562
|
if (stylesInjected) return;
|
|
35323
35563
|
const tag = document.createElement("style");
|
|
35324
35564
|
tag.id = "ps-sg-styles";
|
|
35325
|
-
tag.textContent =
|
|
35565
|
+
tag.textContent = SIZE_GUIDE_STYLES;
|
|
35326
35566
|
document.head.appendChild(tag);
|
|
35327
35567
|
stylesInjected = true;
|
|
35328
35568
|
}
|
|
@@ -35514,10 +35754,112 @@ function installProductViewTracking() {
|
|
|
35514
35754
|
roots.forEach((r2) => maybeFireProductView(r2));
|
|
35515
35755
|
}
|
|
35516
35756
|
const TAG = "[primestyle-tryon]";
|
|
35517
|
-
|
|
35757
|
+
const SHADOW_STYLE_ATTR = "data-primestyle-sdk";
|
|
35758
|
+
const DOCUMENT_STYLE_ATTR = "data-primestyle-sdk-document";
|
|
35759
|
+
const SHADOW_MOUNT_ATTR = "data-primestyle-mount";
|
|
35760
|
+
const PORTAL_HOST_ATTR = "data-primestyle-portal-host";
|
|
35761
|
+
const PORTAL_MOUNT_ATTR = "data-primestyle-portal-mount";
|
|
35762
|
+
const SDK_CSS = `${STYLES}
|
|
35763
|
+
|
|
35764
|
+
${SIZE_GUIDE_STYLES}`;
|
|
35765
|
+
console.log(`${TAG} storefront bundle loaded`);
|
|
35518
35766
|
installCartHook();
|
|
35519
35767
|
installProductViewTracking();
|
|
35520
35768
|
const MOUNTED = /* @__PURE__ */ new WeakMap();
|
|
35769
|
+
const MOUNT_SIGNATURES = /* @__PURE__ */ new WeakMap();
|
|
35770
|
+
const MOUNTING = /* @__PURE__ */ new WeakSet();
|
|
35771
|
+
function ensureDocumentStyles() {
|
|
35772
|
+
if (typeof document === "undefined" || !document.head) return;
|
|
35773
|
+
let styleTag = document.head.querySelector(`style[${DOCUMENT_STYLE_ATTR}]`);
|
|
35774
|
+
if (!styleTag) {
|
|
35775
|
+
styleTag = document.createElement("style");
|
|
35776
|
+
styleTag.setAttribute(DOCUMENT_STYLE_ATTR, "true");
|
|
35777
|
+
document.head.appendChild(styleTag);
|
|
35778
|
+
}
|
|
35779
|
+
if (styleTag.textContent !== SDK_CSS) {
|
|
35780
|
+
styleTag.textContent = SDK_CSS;
|
|
35781
|
+
}
|
|
35782
|
+
}
|
|
35783
|
+
function getPortalHost() {
|
|
35784
|
+
if (typeof document === "undefined" || !document.body) return void 0;
|
|
35785
|
+
let portalHost = document.querySelector(`[${PORTAL_HOST_ATTR}]`);
|
|
35786
|
+
if (!portalHost) {
|
|
35787
|
+
portalHost = document.createElement("div");
|
|
35788
|
+
portalHost.setAttribute(PORTAL_HOST_ATTR, "true");
|
|
35789
|
+
document.body.appendChild(portalHost);
|
|
35790
|
+
}
|
|
35791
|
+
portalHost.style.setProperty("display", "block", "important");
|
|
35792
|
+
portalHost.style.setProperty("position", "fixed", "important");
|
|
35793
|
+
portalHost.style.setProperty("inset", "0", "important");
|
|
35794
|
+
portalHost.style.setProperty("width", "100vw", "important");
|
|
35795
|
+
portalHost.style.setProperty("height", "100vh", "important");
|
|
35796
|
+
portalHost.style.setProperty("z-index", "2147483647", "important");
|
|
35797
|
+
portalHost.style.setProperty("visibility", "visible", "important");
|
|
35798
|
+
portalHost.style.setProperty("opacity", "1", "important");
|
|
35799
|
+
portalHost.style.setProperty("pointer-events", "none", "important");
|
|
35800
|
+
portalHost.style.setProperty("transform", "none", "important");
|
|
35801
|
+
portalHost.style.setProperty("margin", "0", "important");
|
|
35802
|
+
portalHost.style.setProperty("padding", "0", "important");
|
|
35803
|
+
if (typeof portalHost.attachShadow === "function") {
|
|
35804
|
+
try {
|
|
35805
|
+
const shadow = portalHost.shadowRoot || portalHost.attachShadow({ mode: "open" });
|
|
35806
|
+
let styleTag = shadow.querySelector(`style[${SHADOW_STYLE_ATTR}]`);
|
|
35807
|
+
if (!styleTag) {
|
|
35808
|
+
styleTag = document.createElement("style");
|
|
35809
|
+
styleTag.setAttribute(SHADOW_STYLE_ATTR, "true");
|
|
35810
|
+
shadow.appendChild(styleTag);
|
|
35811
|
+
}
|
|
35812
|
+
if (styleTag.textContent !== SDK_CSS) {
|
|
35813
|
+
styleTag.textContent = SDK_CSS;
|
|
35814
|
+
}
|
|
35815
|
+
let portalMount = shadow.querySelector(`[${PORTAL_MOUNT_ATTR}]`);
|
|
35816
|
+
if (!portalMount) {
|
|
35817
|
+
portalMount = document.createElement("div");
|
|
35818
|
+
portalMount.setAttribute(PORTAL_MOUNT_ATTR, "true");
|
|
35819
|
+
portalMount.className = "ps-tryon-portal-mount";
|
|
35820
|
+
shadow.appendChild(portalMount);
|
|
35821
|
+
}
|
|
35822
|
+
portalMount.style.setProperty("display", "block", "important");
|
|
35823
|
+
portalMount.style.setProperty("width", "100%", "important");
|
|
35824
|
+
portalMount.style.setProperty("height", "100%", "important");
|
|
35825
|
+
portalMount.style.setProperty("pointer-events", "none", "important");
|
|
35826
|
+
return portalMount;
|
|
35827
|
+
} catch (err) {
|
|
35828
|
+
console.warn(`${TAG} portal shadow DOM mount failed; falling back to page DOM`, err);
|
|
35829
|
+
}
|
|
35830
|
+
}
|
|
35831
|
+
ensureDocumentStyles();
|
|
35832
|
+
return portalHost;
|
|
35833
|
+
}
|
|
35834
|
+
function createShadowMountTarget(el2) {
|
|
35835
|
+
if (!(el2 instanceof HTMLElement) || typeof el2.attachShadow !== "function") {
|
|
35836
|
+
return { mountTarget: el2 };
|
|
35837
|
+
}
|
|
35838
|
+
try {
|
|
35839
|
+
const shadow = el2.shadowRoot || el2.attachShadow({ mode: "open" });
|
|
35840
|
+
let styleTag = shadow.querySelector(`style[${SHADOW_STYLE_ATTR}]`);
|
|
35841
|
+
if (!styleTag) {
|
|
35842
|
+
styleTag = document.createElement("style");
|
|
35843
|
+
styleTag.setAttribute(SHADOW_STYLE_ATTR, "true");
|
|
35844
|
+
shadow.appendChild(styleTag);
|
|
35845
|
+
}
|
|
35846
|
+
if (styleTag.textContent !== SDK_CSS) {
|
|
35847
|
+
styleTag.textContent = SDK_CSS;
|
|
35848
|
+
}
|
|
35849
|
+
let mountTarget = shadow.querySelector(`[${SHADOW_MOUNT_ATTR}]`);
|
|
35850
|
+
if (!mountTarget) {
|
|
35851
|
+
mountTarget = document.createElement("div");
|
|
35852
|
+
mountTarget.setAttribute(SHADOW_MOUNT_ATTR, "true");
|
|
35853
|
+
mountTarget.className = "ps-tryon-shadow-mount";
|
|
35854
|
+
shadow.appendChild(mountTarget);
|
|
35855
|
+
}
|
|
35856
|
+
el2.setAttribute("data-primestyle-shadow", "true");
|
|
35857
|
+
return { mountTarget, portalContainer: getPortalHost() ?? document.body };
|
|
35858
|
+
} catch (err) {
|
|
35859
|
+
console.warn(`${TAG} shadow DOM mount failed; falling back to page DOM`, err);
|
|
35860
|
+
return { mountTarget: el2 };
|
|
35861
|
+
}
|
|
35862
|
+
}
|
|
35521
35863
|
function readDataAttrs(el2) {
|
|
35522
35864
|
const out = {};
|
|
35523
35865
|
for (const attr of Array.from(el2.attributes)) {
|
|
@@ -35536,6 +35878,13 @@ function parseJsonAttr(raw, fallback) {
|
|
|
35536
35878
|
return fallback;
|
|
35537
35879
|
}
|
|
35538
35880
|
}
|
|
35881
|
+
function buildMountSignature(data) {
|
|
35882
|
+
const relevant = {};
|
|
35883
|
+
for (const key of Object.keys(data).sort()) {
|
|
35884
|
+
relevant[key] = data[key];
|
|
35885
|
+
}
|
|
35886
|
+
return JSON.stringify(relevant);
|
|
35887
|
+
}
|
|
35539
35888
|
function resolveProductUrl(raw) {
|
|
35540
35889
|
const source = raw || (typeof window !== "undefined" ? window.location.href : "");
|
|
35541
35890
|
if (!source) return void 0;
|
|
@@ -35556,13 +35905,18 @@ function buildPropsFromDataAttrs(data) {
|
|
|
35556
35905
|
productTitle: data.productTitle,
|
|
35557
35906
|
productUrl: resolveProductUrl(data.productUrl),
|
|
35558
35907
|
productImage: data.productImage,
|
|
35559
|
-
|
|
35908
|
+
productImages: parseJsonAttr(data.productImages, void 0),
|
|
35909
|
+
productCarouselItems: parseJsonAttr(
|
|
35910
|
+
data.productCarouselItems,
|
|
35911
|
+
void 0
|
|
35912
|
+
),
|
|
35560
35913
|
productDescription: data.productDescription,
|
|
35561
35914
|
productGender: data.productGender,
|
|
35562
35915
|
productType: data.productType,
|
|
35563
35916
|
productVendor: data.productVendor,
|
|
35564
35917
|
productTags: data.productTags ? data.productTags.split(",").map((t2) => t2.trim()).filter(Boolean) : void 0,
|
|
35565
35918
|
buttonText: data.buttonText || "Find Your Size",
|
|
35919
|
+
limitOneColorTryOnPerProduct: data.limitOneColorTryOnPerProduct === "true",
|
|
35566
35920
|
locale: data.locale,
|
|
35567
35921
|
sizeGuideData: parseJsonAttr(data.cachedSizeguide, void 0),
|
|
35568
35922
|
sizingCountry: data.sizingCountry,
|
|
@@ -35599,22 +35953,39 @@ async function fetchSizeGuideForProduct(proxyUrl, productId) {
|
|
|
35599
35953
|
}
|
|
35600
35954
|
}
|
|
35601
35955
|
async function mount(el2) {
|
|
35602
|
-
|
|
35603
|
-
|
|
35956
|
+
const data = readDataAttrs(el2);
|
|
35957
|
+
const signature = buildMountSignature(data);
|
|
35958
|
+
const existingRoot = MOUNTED.get(el2);
|
|
35959
|
+
if (existingRoot) {
|
|
35960
|
+
if (MOUNT_SIGNATURES.get(el2) === signature) {
|
|
35961
|
+
console.log(`${TAG} already mounted on`, el2);
|
|
35962
|
+
return;
|
|
35963
|
+
}
|
|
35964
|
+
console.log(`${TAG} data changed; remounting on`, el2);
|
|
35965
|
+
try {
|
|
35966
|
+
existingRoot.unmount();
|
|
35967
|
+
} catch (err) {
|
|
35968
|
+
console.warn(`${TAG} previous React root failed to unmount`, err);
|
|
35969
|
+
}
|
|
35970
|
+
MOUNTED.delete(el2);
|
|
35971
|
+
MOUNT_SIGNATURES.delete(el2);
|
|
35972
|
+
}
|
|
35973
|
+
if (MOUNTING.has(el2)) {
|
|
35974
|
+
console.log(`${TAG} mount already in progress on`, el2);
|
|
35604
35975
|
return;
|
|
35605
35976
|
}
|
|
35977
|
+
MOUNTING.add(el2);
|
|
35606
35978
|
console.log(`${TAG} mounting on element`, el2);
|
|
35607
|
-
const data = readDataAttrs(el2);
|
|
35608
35979
|
console.log(`${TAG} read data attributes`, data);
|
|
35609
35980
|
const props = buildPropsFromDataAttrs(data);
|
|
35610
|
-
const
|
|
35981
|
+
const shouldRenderStandaloneSizeGuide = !!data.cachedSizeguide && data.disableSizeGuideButton !== "true";
|
|
35611
35982
|
if (!props.sizeGuideData && props.productId && props.apiUrl) {
|
|
35612
35983
|
const fetched = await fetchSizeGuideForProduct(props.apiUrl, props.productId);
|
|
35613
35984
|
if (fetched) {
|
|
35614
35985
|
props.sizeGuideData = fetched;
|
|
35615
35986
|
}
|
|
35616
35987
|
}
|
|
35617
|
-
if (
|
|
35988
|
+
if (shouldRenderStandaloneSizeGuide && props.sizeGuideData) {
|
|
35618
35989
|
try {
|
|
35619
35990
|
const buttonStyles = props.buttonStyles;
|
|
35620
35991
|
createSizeGuideButton(el2, props.sizeGuideData, {
|
|
@@ -35626,13 +35997,22 @@ async function mount(el2) {
|
|
|
35626
35997
|
}
|
|
35627
35998
|
}
|
|
35628
35999
|
try {
|
|
35629
|
-
const
|
|
35630
|
-
root
|
|
36000
|
+
const { mountTarget, portalContainer } = createShadowMountTarget(el2);
|
|
36001
|
+
const root = createRoot(mountTarget);
|
|
36002
|
+
root.render(
|
|
36003
|
+
reactExports.createElement(PrimeStyleTryon, {
|
|
36004
|
+
...props,
|
|
36005
|
+
portalContainer
|
|
36006
|
+
})
|
|
36007
|
+
);
|
|
35631
36008
|
MOUNTED.set(el2, root);
|
|
36009
|
+
MOUNT_SIGNATURES.set(el2, signature);
|
|
35632
36010
|
console.log(`${TAG} ✓ mounted React component`);
|
|
35633
36011
|
maybeFireProductView(el2);
|
|
35634
36012
|
} catch (err) {
|
|
35635
36013
|
console.error(`${TAG} ✗ React mount failed`, err);
|
|
36014
|
+
} finally {
|
|
36015
|
+
MOUNTING.delete(el2);
|
|
35636
36016
|
}
|
|
35637
36017
|
}
|
|
35638
36018
|
function mountAll() {
|