@primestyleai/tryon 5.6.7 → 5.6.8
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.
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { TranslateFn } from "../../i18n";
|
|
2
2
|
import type { Profile } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Edit profile dialog — opens as a dark overlay ABOVE the main modal
|
|
5
|
+
* (z-index matches the .ps-tryon-overlay max-int so it always stacks
|
|
6
|
+
* on top). Wraps ProfileEditView so the user gets a real editable form
|
|
7
|
+
* with name + gender + units + height/weight/age + Save / Cancel.
|
|
8
|
+
*
|
|
9
|
+
* Portaled to document.body so parent stacking contexts can't clip it.
|
|
10
|
+
*/
|
|
3
11
|
export declare function ProfileDetailModal({ profileDetail, setProfileDetail, setProfiles, activeProfileId, setActiveProfileId, t, }: {
|
|
4
12
|
profileDetail: Profile | null;
|
|
5
13
|
setProfileDetail: (p: Profile | null) => void;
|
|
@@ -7,4 +15,4 @@ export declare function ProfileDetailModal({ profileDetail, setProfileDetail, se
|
|
|
7
15
|
activeProfileId: string | null;
|
|
8
16
|
setActiveProfileId: (id: string | null) => void;
|
|
9
17
|
t: TranslateFn;
|
|
10
|
-
}): import("react
|
|
18
|
+
}): import("react").ReactPortal | null;
|
package/dist/react/index.js
CHANGED
|
@@ -2805,15 +2805,28 @@ const STYLES = `
|
|
|
2805
2805
|
}
|
|
2806
2806
|
.ps-tryon-drawer-clear:hover { color: var(--ps-error-color); }
|
|
2807
2807
|
|
|
2808
|
-
/* Profile detail modal
|
|
2808
|
+
/* Profile detail modal — portaled to body, sits ABOVE the main modal
|
|
2809
|
+
overlay (which has z-index 2147483647). Equal z-index + later DOM
|
|
2810
|
+
order means this stacks on top. Same trick as the language dropdown. */
|
|
2809
2811
|
.ps-tryon-detail-overlay {
|
|
2810
2812
|
position: fixed; inset: 0; background: rgba(0,0,0,0.55);
|
|
2811
2813
|
display: flex; align-items: center; justify-content: center;
|
|
2812
|
-
z-index:
|
|
2814
|
+
z-index: 2147483647; padding: 0.83vw; animation: ps-fade-in 0.2s ease;
|
|
2815
|
+
isolation: isolate;
|
|
2816
|
+
--ps-accent: #3B82F6;
|
|
2817
|
+
--ps-accent-hover: #2563EB;
|
|
2818
|
+
--ps-text-primary: #1C1D1E;
|
|
2819
|
+
--ps-text-secondary: #454545;
|
|
2820
|
+
--ps-text-muted: #84898C;
|
|
2821
|
+
--ps-border-color: #E7E7E7;
|
|
2822
|
+
--ps-border-subtle: #F0F0F0;
|
|
2823
|
+
--ps-bg-primary: #FFFFFF;
|
|
2824
|
+
--ps-bg-secondary: #F8FAFF;
|
|
2825
|
+
--ps-error-color: #E7000B;
|
|
2813
2826
|
}
|
|
2814
2827
|
.ps-tryon-detail-modal {
|
|
2815
|
-
background: var(--ps-bg-primary); border-radius:
|
|
2816
|
-
overflow-y: auto; box-shadow: 0
|
|
2828
|
+
background: var(--ps-bg-primary); border-radius: 14px; width: 100%; max-width: 480px; max-height: 85vh;
|
|
2829
|
+
overflow-y: auto; box-shadow: 0 24px 64px rgba(0,0,0,0.3); animation: ps-slide-up 0.25s ease;
|
|
2817
2830
|
font-family: var(--ps-modal-font, system-ui, sans-serif); color: var(--ps-text-primary);
|
|
2818
2831
|
}
|
|
2819
2832
|
.ps-tryon-detail-header {
|
|
@@ -3851,6 +3864,8 @@ const STYLES = `
|
|
|
3851
3864
|
}
|
|
3852
3865
|
.ps-msp-card-photo {
|
|
3853
3866
|
width: 100%; height: 100%; object-fit: cover; display: block;
|
|
3867
|
+
/* Same head-bias crop as the profile detail avatar */
|
|
3868
|
+
object-position: 50% 12%;
|
|
3854
3869
|
}
|
|
3855
3870
|
.ps-msp-avatar {
|
|
3856
3871
|
position: relative;
|
|
@@ -4045,15 +4060,17 @@ const STYLES = `
|
|
|
4045
4060
|
════════════════════════════════════════════════════════════════ */
|
|
4046
4061
|
.ps-cpw-root {
|
|
4047
4062
|
display: flex; flex-direction: column;
|
|
4048
|
-
|
|
4063
|
+
height: 100%; min-height: 0;
|
|
4064
|
+
margin: 0 -16px;
|
|
4049
4065
|
}
|
|
4050
4066
|
|
|
4051
|
-
/* Step header —
|
|
4067
|
+
/* Step header — sticky at top */
|
|
4052
4068
|
.ps-cpw-step-head {
|
|
4053
4069
|
display: flex; align-items: flex-start; justify-content: space-between;
|
|
4054
4070
|
gap: 16px;
|
|
4055
|
-
padding
|
|
4071
|
+
padding: 4px 16px 18px;
|
|
4056
4072
|
border-bottom: 1px solid var(--ps-border-subtle);
|
|
4073
|
+
flex-shrink: 0;
|
|
4057
4074
|
}
|
|
4058
4075
|
.ps-cpw-eyebrow {
|
|
4059
4076
|
font-size: 10px; font-weight: 700;
|
|
@@ -4091,6 +4108,9 @@ const STYLES = `
|
|
|
4091
4108
|
.ps-cpw-body {
|
|
4092
4109
|
display: flex; flex-direction: column;
|
|
4093
4110
|
gap: 24px;
|
|
4111
|
+
flex: 1; min-height: 0;
|
|
4112
|
+
overflow-y: auto; -webkit-overflow-scrolling: touch;
|
|
4113
|
+
padding: 18px 16px 24px;
|
|
4094
4114
|
}
|
|
4095
4115
|
|
|
4096
4116
|
/* Step 1 — Identity form */
|
|
@@ -4177,7 +4197,8 @@ const STYLES = `
|
|
|
4177
4197
|
}
|
|
4178
4198
|
.ps-cpw-photo-upload {
|
|
4179
4199
|
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
4180
|
-
gap:
|
|
4200
|
+
gap: 8px; padding: 38px 18px;
|
|
4201
|
+
min-height: 220px;
|
|
4181
4202
|
background: var(--ps-bg-secondary);
|
|
4182
4203
|
border: 2px dashed var(--ps-border-color);
|
|
4183
4204
|
border-radius: 12px;
|
|
@@ -4282,13 +4303,14 @@ const STYLES = `
|
|
|
4282
4303
|
color: var(--ps-accent);
|
|
4283
4304
|
}
|
|
4284
4305
|
|
|
4285
|
-
/* Footer actions */
|
|
4306
|
+
/* Footer actions — sticky at the bottom */
|
|
4286
4307
|
.ps-cpw-footer {
|
|
4287
4308
|
display: flex; align-items: center; justify-content: space-between;
|
|
4288
4309
|
gap: 12px;
|
|
4289
|
-
padding
|
|
4310
|
+
padding: 16px 16px;
|
|
4290
4311
|
border-top: 1px solid var(--ps-border-subtle);
|
|
4291
|
-
|
|
4312
|
+
background: var(--ps-bg-primary);
|
|
4313
|
+
flex-shrink: 0;
|
|
4292
4314
|
}
|
|
4293
4315
|
.ps-cpw-back-btn {
|
|
4294
4316
|
background: none; border: none;
|
|
@@ -4355,6 +4377,11 @@ const STYLES = `
|
|
|
4355
4377
|
}
|
|
4356
4378
|
.ps-pmv-hero-avatar img {
|
|
4357
4379
|
width: 100%; height: 100%; object-fit: cover;
|
|
4380
|
+
/* Bias the crop toward the top of the photo so the head/face shows
|
|
4381
|
+
through the circular avatar instead of the torso. Works for any
|
|
4382
|
+
full-body or head-and-torso photo where the head is in the upper
|
|
4383
|
+
portion of the frame. */
|
|
4384
|
+
object-position: 50% 12%;
|
|
4358
4385
|
}
|
|
4359
4386
|
.ps-pmv-hero-info { flex: 1; min-width: 0; }
|
|
4360
4387
|
.ps-pmv-hero-eyebrow {
|
|
@@ -5588,60 +5615,59 @@ function ProfileDetailModal({
|
|
|
5588
5615
|
setActiveProfileId: setActiveProfileId2,
|
|
5589
5616
|
t
|
|
5590
5617
|
}) {
|
|
5618
|
+
useEffect(() => {
|
|
5619
|
+
if (!profileDetail || typeof document === "undefined") return;
|
|
5620
|
+
const prev = document.body.style.overflow;
|
|
5621
|
+
document.body.style.overflow = "hidden";
|
|
5622
|
+
return () => {
|
|
5623
|
+
document.body.style.overflow = prev;
|
|
5624
|
+
};
|
|
5625
|
+
}, [profileDetail]);
|
|
5591
5626
|
if (!profileDetail) return null;
|
|
5592
|
-
|
|
5593
|
-
const
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
return
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
+
if (typeof document === "undefined") return null;
|
|
5628
|
+
const handleSave = (updated) => {
|
|
5629
|
+
setProfiles((prev) => prev.map(
|
|
5630
|
+
(p) => p.id === profileDetail.id ? {
|
|
5631
|
+
...p,
|
|
5632
|
+
...updated,
|
|
5633
|
+
// Keep id + createdAt + sizeHistory + measurements; bump lastEditedAt
|
|
5634
|
+
id: p.id,
|
|
5635
|
+
createdAt: p.createdAt,
|
|
5636
|
+
sizeHistory: p.sizeHistory,
|
|
5637
|
+
measurements: p.measurements,
|
|
5638
|
+
lastEditedAt: Date.now()
|
|
5639
|
+
} : p
|
|
5640
|
+
));
|
|
5641
|
+
setProfileDetail(null);
|
|
5642
|
+
};
|
|
5643
|
+
const handleClose = () => setProfileDetail(null);
|
|
5644
|
+
return createPortal(
|
|
5645
|
+
/* @__PURE__ */ jsx(
|
|
5646
|
+
"div",
|
|
5647
|
+
{
|
|
5648
|
+
className: "ps-tryon-detail-overlay",
|
|
5649
|
+
onClick: (e) => {
|
|
5650
|
+
if (e.target === e.currentTarget) handleClose();
|
|
5651
|
+
},
|
|
5652
|
+
children: /* @__PURE__ */ jsxs("div", { className: "ps-tryon-detail-modal", children: [
|
|
5653
|
+
/* @__PURE__ */ jsxs("div", { className: "ps-tryon-detail-header", children: [
|
|
5654
|
+
/* @__PURE__ */ jsx("span", { children: t("Edit Profile") }),
|
|
5655
|
+
/* @__PURE__ */ jsx("button", { onClick: handleClose, "aria-label": t("Close"), children: /* @__PURE__ */ jsx(XIcon, { size: 18 }) })
|
|
5656
|
+
] }),
|
|
5657
|
+
/* @__PURE__ */ jsx("div", { className: "ps-tryon-detail-body", children: /* @__PURE__ */ jsx(
|
|
5658
|
+
ProfileEditView,
|
|
5659
|
+
{
|
|
5660
|
+
profile: profileDetail,
|
|
5661
|
+
onSave: handleSave,
|
|
5662
|
+
onCancel: handleClose,
|
|
5663
|
+
t
|
|
5664
|
+
}
|
|
5665
|
+
) })
|
|
5627
5666
|
] })
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
new Date(p.createdAt).toLocaleDateString()
|
|
5633
|
-
] }),
|
|
5634
|
-
/* @__PURE__ */ jsxs("button", { className: "ps-tryon-detail-delete", onClick: () => {
|
|
5635
|
-
setProfiles((prev) => prev.filter((x) => x.id !== p.id));
|
|
5636
|
-
if (activeProfileId === p.id) setActiveProfileId2(null);
|
|
5637
|
-
setProfileDetail(null);
|
|
5638
|
-
}, children: [
|
|
5639
|
-
/* @__PURE__ */ jsx(TrashIcon, {}),
|
|
5640
|
-
" ",
|
|
5641
|
-
t("Delete Profile")
|
|
5642
|
-
] })
|
|
5643
|
-
] })
|
|
5644
|
-
] }) });
|
|
5667
|
+
}
|
|
5668
|
+
),
|
|
5669
|
+
document.body
|
|
5670
|
+
);
|
|
5645
5671
|
}
|
|
5646
5672
|
function WelcomeView({
|
|
5647
5673
|
productImage,
|
|
@@ -7690,6 +7716,10 @@ function ShapeSection({
|
|
|
7690
7716
|
}
|
|
7691
7717
|
function CreateProfileWizard({ onSave, onCancel, t }) {
|
|
7692
7718
|
const [step, setStep] = useState(1);
|
|
7719
|
+
const bodyScrollRef = useRef(null);
|
|
7720
|
+
useEffect(() => {
|
|
7721
|
+
if (bodyScrollRef.current) bodyScrollRef.current.scrollTop = 0;
|
|
7722
|
+
}, [step]);
|
|
7693
7723
|
const [name, setName] = useState("");
|
|
7694
7724
|
const [gender, setGender] = useState("male");
|
|
7695
7725
|
const [unit, setUnit] = useState("cm");
|
|
@@ -7807,7 +7837,7 @@ function CreateProfileWizard({ onSave, onCancel, t }) {
|
|
|
7807
7837
|
] })
|
|
7808
7838
|
] })
|
|
7809
7839
|
] }),
|
|
7810
|
-
/* @__PURE__ */ jsx("div", { className: "ps-cpw-body", children: step === 1 ? /* @__PURE__ */ jsxs("div", { className: "ps-cpw-identity", children: [
|
|
7840
|
+
/* @__PURE__ */ jsx("div", { className: "ps-cpw-body", ref: bodyScrollRef, children: step === 1 ? /* @__PURE__ */ jsxs("div", { className: "ps-cpw-identity", children: [
|
|
7811
7841
|
/* @__PURE__ */ jsxs("div", { className: "ps-cpw-field", children: [
|
|
7812
7842
|
/* @__PURE__ */ jsx("label", { className: "ps-cpw-field-label", children: t("PROFILE NAME") }),
|
|
7813
7843
|
/* @__PURE__ */ jsx(
|