@primestyleai/tryon 5.10.179 → 5.10.181

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.
@@ -11,6 +11,7 @@ interface MySizingProfilesViewProps {
11
11
  onDeleteProfile?: (id: string) => void;
12
12
  /** Called when user clicks delete — parent owns the confirmation modal */
13
13
  onRequestDelete: (id: string) => void;
14
+ onLogout: () => void;
14
15
  onClose: () => void;
15
16
  /** Forwarded to CreateProfileWizard for the pre-upload age check. */
16
17
  apiUrl?: string;
@@ -47,5 +48,5 @@ export declare function DeleteConfirmModal({ onConfirm, onCancel, t, }: {
47
48
  onCancel: () => void;
48
49
  t: TranslateFn;
49
50
  }): import("react/jsx-runtime").JSX.Element;
50
- export declare function MySizingProfilesView({ profiles, activeProfileId, onSelectProfile, onEditProfile, onSaveNewProfile, onSaveProfileMeasurements, onSaveBraSize, onRequestDelete, onClose, apiUrl, apiKey, onPhotoPreview, initialCreateDraft, onProfileDraftConsumed, onEstimateFromPhoto, estimatingProfileIds, t, onRegisterBackInterceptor, }: MySizingProfilesViewProps): import("react/jsx-runtime").JSX.Element;
51
+ export declare function MySizingProfilesView({ profiles, activeProfileId, onSelectProfile, onEditProfile, onSaveNewProfile, onSaveProfileMeasurements, onSaveBraSize, onRequestDelete, onLogout, onClose, apiUrl, apiKey, onPhotoPreview, initialCreateDraft, onProfileDraftConsumed, onEstimateFromPhoto, estimatingProfileIds, t, onRegisterBackInterceptor, }: MySizingProfilesViewProps): import("react/jsx-runtime").JSX.Element;
51
52
  export {};
@@ -11404,6 +11404,14 @@ function setStoredProfileSession(session) {
11404
11404
  } catch {
11405
11405
  }
11406
11406
  }
11407
+ function clearStoredProfileSession() {
11408
+ const storage = readStorage();
11409
+ if (!storage) return;
11410
+ try {
11411
+ storage.removeItem(SESSION_KEY);
11412
+ } catch {
11413
+ }
11414
+ }
11407
11415
  function startSocialProfileLogin(provider, apiUrl) {
11408
11416
  if (typeof window === "undefined") {
11409
11417
  return Promise.reject(new Error("Social login must run in the browser."));
@@ -12730,7 +12738,7 @@ const STYLES = `
12730
12738
  }
12731
12739
 
12732
12740
  /* ── Product photo strip (single-garment, below the size card) ──
12733
- Three thumbnails per slide, evenly spaced, auto-advances. Lives at
12741
+ Two thumbnails per row, evenly spaced, auto-advances. Lives at
12734
12742
  the bottom of the right panel as decoration / entertainment. */
12735
12743
  .ps-tryon-photo-strip {
12736
12744
  margin-top: 0.65vw;
@@ -12749,12 +12757,13 @@ const STYLES = `
12749
12757
  }
12750
12758
  .ps-tryon-photo-strip-row {
12751
12759
  display: grid;
12752
- grid-template-columns: repeat(3, 1fr);
12760
+ grid-template-columns: repeat(2, minmax(0, 1fr));
12753
12761
  gap: 0.45vw;
12754
12762
  animation: ps-tryon-photo-strip-fade 0.5s ease;
12755
12763
  }
12756
- .ps-tryon-photo-strip-row.ps-count-1 .ps-tryon-photo-strip-cell {
12757
- grid-column: 2;
12764
+ .ps-tryon-photo-strip-row.ps-count-1 {
12765
+ grid-template-columns: minmax(0, calc((100% - 0.45vw) / 2));
12766
+ justify-content: center;
12758
12767
  }
12759
12768
  .ps-tryon-photo-strip-cell {
12760
12769
  position: relative;
@@ -12814,6 +12823,9 @@ const STYLES = `
12814
12823
  .ps-tryon-photo-strip-row {
12815
12824
  gap: 8px;
12816
12825
  }
12826
+ .ps-tryon-photo-strip-row.ps-count-1 {
12827
+ grid-template-columns: minmax(0, calc((100% - 8px) / 2));
12828
+ }
12817
12829
  .ps-tryon-photo-strip-cell {
12818
12830
  aspect-ratio: 1 / 1; border-radius: 12px;
12819
12831
  }
@@ -18158,7 +18170,56 @@ const STYLES = `
18158
18170
  overflow-y: auto; -webkit-overflow-scrolling: touch;
18159
18171
  padding: 4px;
18160
18172
  }
18173
+ .ps-msp-home {
18174
+ height: 100%;
18175
+ min-height: 0;
18176
+ display: flex;
18177
+ flex-direction: column;
18178
+ gap: max(12px, 0.95vw);
18179
+ }
18180
+ .ps-msp-welcome-panel,
18181
+ .ps-msp-cards-panel {
18182
+ min-width: 0;
18183
+ min-height: 0;
18184
+ background: var(--ps-bg-primary);
18185
+ }
18186
+ .ps-msp-welcome-panel {
18187
+ display: flex;
18188
+ align-items: flex-start;
18189
+ justify-content: space-between;
18190
+ gap: max(12px, 1vw);
18191
+ padding: max(12px, 1vw) 0 max(12px, 0.95vw);
18192
+ border-bottom: 1px solid var(--ps-border-subtle);
18193
+ }
18194
+ .ps-msp-cards-panel {
18195
+ display: flex;
18196
+ flex-direction: column;
18197
+ overflow: hidden;
18198
+ flex: 1;
18199
+ }
18200
+ .ps-msp-cards-scroll {
18201
+ flex: 1;
18202
+ min-height: 0;
18203
+ overflow-y: auto;
18204
+ -webkit-overflow-scrolling: touch;
18205
+ padding: max(4px, 0.35vw) 0 max(8px, 0.65vw);
18206
+ }
18161
18207
  .ps-msp-header { margin-bottom: max(10px, 0.85vw); }
18208
+ .ps-msp-header-row {
18209
+ display: flex;
18210
+ align-items: flex-start;
18211
+ justify-content: space-between;
18212
+ gap: max(10px, 0.8vw);
18213
+ }
18214
+ .ps-msp-header-copy { min-width: 0; }
18215
+ .ps-msp-kicker {
18216
+ font-size: max(9px, 0.58vw);
18217
+ font-weight: 800;
18218
+ letter-spacing: 0.12em;
18219
+ text-transform: uppercase;
18220
+ color: var(--ps-accent);
18221
+ margin-bottom: max(4px, 0.32vw);
18222
+ }
18162
18223
  .ps-msp-title {
18163
18224
  font-size: max(13px, 0.95vw);
18164
18225
  font-weight: 700;
@@ -18167,16 +18228,56 @@ const STYLES = `
18167
18228
  letter-spacing: -0.005em;
18168
18229
  }
18169
18230
  .ps-msp-subtitle {
18170
- font-size: max(10px, 0.7vw);
18231
+ font-size: max(11px, 0.72vw);
18171
18232
  color: var(--ps-text-muted);
18172
- margin: 0; line-height: 1.5;
18233
+ margin: 0;
18234
+ line-height: 1.55;
18235
+ max-width: 54ch;
18236
+ }
18237
+ .ps-msp-header-actions {
18238
+ display: flex;
18239
+ align-items: center;
18240
+ gap: max(8px, 0.65vw);
18241
+ flex-shrink: 0;
18242
+ }
18243
+ .ps-msp-primary-create {
18244
+ border: 0;
18245
+ border-radius: 999px;
18246
+ background: var(--ps-accent);
18247
+ color: #FFFFFF;
18248
+ font-family: inherit;
18249
+ font-size: max(10px, 0.66vw);
18250
+ font-weight: 800;
18251
+ padding: max(7px, 0.52vw) max(11px, 0.8vw);
18252
+ cursor: pointer;
18253
+ transition: opacity 0.15s, transform 0.15s;
18254
+ }
18255
+ .ps-msp-primary-create:hover { opacity: 0.88; }
18256
+ .ps-msp-primary-create:active { transform: scale(0.98); }
18257
+ .ps-msp-logout {
18258
+ flex-shrink: 0;
18259
+ border: 1px solid var(--ps-border-color);
18260
+ border-radius: 999px;
18261
+ background: #FFFFFF;
18262
+ color: #DC2626;
18263
+ font-family: inherit;
18264
+ font-size: max(10px, 0.62vw);
18265
+ font-weight: 700;
18266
+ padding: max(6px, 0.42vw) max(9px, 0.68vw);
18267
+ cursor: pointer;
18268
+ transition: border-color 0.15s, color 0.15s, background 0.15s;
18269
+ }
18270
+ .ps-msp-logout:hover {
18271
+ border-color: #DC2626;
18272
+ color: #B91C1C;
18273
+ background: #FEF2F2;
18173
18274
  }
18174
18275
 
18175
18276
  /* Card grid — compact saved profile cards */
18176
18277
  .ps-msp-grid {
18177
18278
  display: grid;
18178
- grid-template-columns: repeat(auto-fill, minmax(max(140px, 11vw), 1fr));
18179
- gap: max(8px, 0.7vw);
18279
+ grid-template-columns: repeat(auto-fill, minmax(max(160px, 12vw), 1fr));
18280
+ gap: max(10px, 0.8vw);
18180
18281
  margin-bottom: max(14px, 1.2vw);
18181
18282
  }
18182
18283
  .ps-msp-card {
@@ -18477,27 +18578,28 @@ const STYLES = `
18477
18578
  }
18478
18579
  /* When create card is the only item (no saved profiles), make it wider */
18479
18580
  .ps-msp-grid > .ps-msp-card-create:only-child {
18480
- grid-column: 1 / -1;
18481
- min-height: max(160px, 12vw);
18482
- max-width: 380px;
18483
- margin: 0 auto;
18581
+ grid-column: auto;
18582
+ width: max(150px, 12vw);
18583
+ min-height: max(96px, 7.4vw);
18584
+ max-width: max(150px, 12vw);
18585
+ margin: 0;
18484
18586
  }
18485
18587
  .ps-msp-create-icon {
18486
- width: max(32px, 2.6vw);
18487
- height: max(32px, 2.6vw);
18588
+ width: max(28px, 2.2vw);
18589
+ height: max(28px, 2.2vw);
18488
18590
  background: var(--ps-accent); color: #FFFFFF;
18489
18591
  border-radius: max(4px, 0.35vw);
18490
18592
  display: flex; align-items: center; justify-content: center;
18491
18593
  margin-bottom: max(6px, 0.55vw);
18492
18594
  }
18493
18595
  .ps-msp-create-title {
18494
- font-size: max(11px, 0.78vw);
18596
+ font-size: max(10px, 0.68vw);
18495
18597
  font-weight: 700;
18496
18598
  color: var(--ps-text-primary);
18497
18599
  margin-bottom: max(2px, 0.2vw);
18498
18600
  }
18499
18601
  .ps-msp-create-sub {
18500
- font-size: max(8px, 0.55vw);
18602
+ font-size: max(7px, 0.46vw);
18501
18603
  font-weight: 700;
18502
18604
  letter-spacing: 0.14em; text-transform: uppercase;
18503
18605
  color: var(--ps-text-muted);
@@ -18767,11 +18869,34 @@ const STYLES = `
18767
18869
 
18768
18870
  @media (max-width: 768px) {
18769
18871
  /* Profile card grid */
18872
+ .ps-msp-home {
18873
+ height: auto;
18874
+ gap: 3vw;
18875
+ }
18876
+ .ps-msp-welcome-panel {
18877
+ gap: 3vw;
18878
+ padding: 3vw 0;
18879
+ }
18880
+ .ps-msp-cards-scroll {
18881
+ max-height: 66vh;
18882
+ padding: 1vw 0 3vw;
18883
+ }
18884
+ .ps-msp-header-actions { width: 100%; gap: 2vw; }
18885
+ .ps-msp-primary-create { font-size: 3vw; padding: 2.4vw 3.4vw; }
18886
+ .ps-msp-header-actions .ps-msp-primary-create { flex: 1; }
18770
18887
  .ps-msp-grid { grid-template-columns: 1fr; gap: 3vw; }
18771
18888
  .ps-msp-card-create { min-height: 22vw; }
18889
+ .ps-msp-grid > .ps-msp-card-create:only-child {
18890
+ width: 46vw;
18891
+ max-width: 46vw;
18892
+ min-height: 30vw;
18893
+ }
18772
18894
  .ps-msp-header { margin-bottom: 3vw; }
18895
+ .ps-msp-header-row { align-items: flex-start; gap: 3vw; }
18896
+ .ps-msp-kicker { font-size: 2.4vw; margin-bottom: 1vw; }
18773
18897
  .ps-msp-title { font-size: 5.6vw; }
18774
18898
  .ps-msp-subtitle { font-size: 3vw; }
18899
+ .ps-msp-logout { font-size: 2.8vw; padding: 2vw 2.8vw; }
18775
18900
  .ps-msp-card { padding: 3.5vw; border-radius: 3vw; }
18776
18901
  .ps-msp-card-tag { font-size: 2.3vw; padding: 1vw 2vw; border-radius: 1vw; }
18777
18902
  .ps-msp-card-circle { width: 18vw; height: 18vw; margin: 2vw auto 3vw; }
@@ -22314,7 +22439,7 @@ function MultiSectionMobile({
22314
22439
  sizeGuide ? null : null
22315
22440
  ] });
22316
22441
  }
22317
- const PER_SLIDE = 3;
22442
+ const PER_SLIDE = 2;
22318
22443
  const CYCLE_MS = 4e3;
22319
22444
  function ProductPhotoCarouselCard({
22320
22445
  photos,
@@ -28053,6 +28178,7 @@ function MySizingProfilesView({
28053
28178
  onSaveProfileMeasurements,
28054
28179
  onSaveBraSize,
28055
28180
  onRequestDelete,
28181
+ onLogout,
28056
28182
  onClose,
28057
28183
  apiUrl,
28058
28184
  apiKey,
@@ -28064,18 +28190,9 @@ function MySizingProfilesView({
28064
28190
  t: t2,
28065
28191
  onRegisterBackInterceptor
28066
28192
  }) {
28067
- const [creating, setCreating] = reactExports.useState(() => !!initialCreateDraft);
28193
+ const [creating, setCreating] = reactExports.useState(false);
28068
28194
  const [viewingId, setViewingId] = reactExports.useState(null);
28069
- const handledDraftKeyRef = reactExports.useRef(initialCreateDraft?.createdAt ?? null);
28070
28195
  const viewingProfile = viewingId ? profiles.find((p2) => p2.id === viewingId) || null : null;
28071
- reactExports.useEffect(() => {
28072
- if (!initialCreateDraft) return;
28073
- const draftKey = initialCreateDraft.createdAt ?? "draft";
28074
- if (handledDraftKeyRef.current === draftKey && creating) return;
28075
- handledDraftKeyRef.current = draftKey;
28076
- setViewingId(null);
28077
- setCreating(true);
28078
- }, [creating, initialCreateDraft]);
28079
28196
  reactExports.useEffect(() => {
28080
28197
  if (viewingId && !profiles.find((p2) => p2.id === viewingId)) {
28081
28198
  setViewingId(null);
@@ -28146,12 +28263,19 @@ function MySizingProfilesView({
28146
28263
  t: t2
28147
28264
  },
28148
28265
  `create-${initialCreateDraft?.createdAt ?? "blank"}`
28149
- ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
28150
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-header", children: [
28151
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-msp-title", children: t2("My Sizing Profiles") }),
28152
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-msp-subtitle", children: t2("Manage your bespoke silhouettes. Switch between profiles for different fits or create a new one for specific garment types.") })
28266
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-home", children: [
28267
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "ps-msp-welcome-panel", "aria-label": t2("Profile welcome"), children: [
28268
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
28269
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msp-kicker", children: t2("Welcome") }),
28270
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-msp-title", children: t2("My Sizing Profiles") }),
28271
+ /* @__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.") })
28272
+ ] }),
28273
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-header-actions", children: [
28274
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-msp-primary-create", onClick: () => setCreating(true), children: t2("Create New Profile") }),
28275
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-msp-logout", onClick: onLogout, children: t2("Sign out") })
28276
+ ] })
28153
28277
  ] }),
28154
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msp-grid", children: [
28278
+ /* @__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: [
28155
28279
  /* @__PURE__ */ jsxRuntimeExports.jsx(CreateProfileCard, { onClick: () => setCreating(true), t: t2 }),
28156
28280
  profiles.map((p2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
28157
28281
  ProfileCard,
@@ -28166,7 +28290,7 @@ function MySizingProfilesView({
28166
28290
  },
28167
28291
  p2.id
28168
28292
  ))
28169
- ] })
28293
+ ] }) }) })
28170
28294
  ] }) }) });
28171
28295
  }
28172
28296
  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";
@@ -32635,6 +32759,12 @@ function PrimeStyleTryonInner({
32635
32759
  setProfileAuthLoadingProvider(null);
32636
32760
  }
32637
32761
  }, [activeProfileId, apiUrl, hydrateProfileStore, profiles, t2]);
32762
+ const handleProfileLogout = reactExports.useCallback(() => {
32763
+ clearStoredProfileSession();
32764
+ setProfileSession(null);
32765
+ setProfileAuthError(null);
32766
+ setProfileAuthLoadingProvider(null);
32767
+ }, []);
32638
32768
  const fileInputRef = reactExports.useRef(null);
32639
32769
  const apiRef = reactExports.useRef(null);
32640
32770
  const sseRef = reactExports.useRef(null);
@@ -34930,6 +35060,7 @@ function PrimeStyleTryonInner({
34930
35060
  lsSet("profiles", lsGet("profiles", []).filter((p2) => p2.id !== id2));
34931
35061
  },
34932
35062
  onRequestDelete: (id2) => setDeleteConfirmId(id2),
35063
+ onLogout: handleProfileLogout,
34933
35064
  onClose: () => setView("body-profile"),
34934
35065
  onRegisterBackInterceptor: handleRegisterProfilesBack,
34935
35066
  t: t2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "5.10.179",
3
+ "version": "5.10.181",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",