@primestyleai/tryon 3.10.0 → 3.11.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.
Files changed (2) hide show
  1. package/dist/react/index.js +95 -28
  2. package/package.json +1 -1
@@ -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, b as SUPPORTED_LOCALES, L as LOCALE_LABELS } from "../index-71-uiSXC.js";
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-71-uiSXC.js";
5
5
  const HEADER_ALIASES = {
6
6
  // ── Size label columns (skipped during field derivation) ──
7
7
  size: "__size__",
@@ -1707,6 +1707,42 @@ function PrimeStyleTryonInner({
1707
1707
  ] })
1708
1708
  ] }) });
1709
1709
  }
1710
+ function LangSwitcher({ activeLocale: current, onSelect }) {
1711
+ const [open, setOpen] = useState(false);
1712
+ const ref = useRef(null);
1713
+ const currentLabel = LOCALE_LABELS[current] || "English";
1714
+ useEffect(() => {
1715
+ if (!open) return;
1716
+ const handler = (e) => {
1717
+ if (ref.current && !ref.current.contains(e.target)) setOpen(false);
1718
+ };
1719
+ document.addEventListener("mousedown", handler);
1720
+ return () => document.removeEventListener("mousedown", handler);
1721
+ }, [open]);
1722
+ return /* @__PURE__ */ jsxs("div", { ref, className: "ps-tryon-lang-wrap", children: [
1723
+ /* @__PURE__ */ jsxs("button", { className: `ps-tryon-lang-trigger${open ? " ps-active" : ""}`, onClick: () => setOpen(!open), children: [
1724
+ /* @__PURE__ */ jsx(GlobeIcon, { size: 15 }),
1725
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-lang-current", children: currentLabel }),
1726
+ /* @__PURE__ */ jsx("span", { className: `ps-tryon-lang-arrow${open ? " ps-open" : ""}`, children: "▾" })
1727
+ ] }),
1728
+ open && /* @__PURE__ */ jsx("div", { className: "ps-tryon-lang-dropdown", children: /* @__PURE__ */ jsx("div", { className: "ps-tryon-lang-list", children: SUPPORTED_LOCALES.map((code) => /* @__PURE__ */ jsxs(
1729
+ "button",
1730
+ {
1731
+ className: `ps-tryon-lang-item${code === current ? " ps-selected" : ""}`,
1732
+ onClick: () => {
1733
+ onSelect(code);
1734
+ setOpen(false);
1735
+ },
1736
+ children: [
1737
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-lang-name", children: LOCALE_LABELS[code] || code }),
1738
+ /* @__PURE__ */ jsx("span", { className: "ps-tryon-lang-code", children: code.toUpperCase() }),
1739
+ code === current && /* @__PURE__ */ jsx("span", { className: "ps-tryon-lang-check", children: /* @__PURE__ */ jsx(CheckIcon, { size: 12 }) })
1740
+ ]
1741
+ },
1742
+ code
1743
+ )) }) })
1744
+ ] });
1745
+ }
1710
1746
  function renderBody() {
1711
1747
  switch (view) {
1712
1748
  case "welcome":
@@ -1740,18 +1776,7 @@ function PrimeStyleTryonInner({
1740
1776
  /* @__PURE__ */ jsxs("div", { className: cx("ps-tryon-header", cn.header), children: [
1741
1777
  /* @__PURE__ */ jsx("span", { className: cx("ps-tryon-title", cn.title), children: t("Virtual Try-On") }),
1742
1778
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-header-actions", children: [
1743
- /* @__PURE__ */ jsxs("div", { className: "ps-tryon-lang-switcher", children: [
1744
- /* @__PURE__ */ jsx(GlobeIcon, {}),
1745
- /* @__PURE__ */ jsx(
1746
- "select",
1747
- {
1748
- value: activeLocale,
1749
- onChange: (e) => setActiveLocale(e.target.value),
1750
- className: "ps-tryon-lang-select",
1751
- children: SUPPORTED_LOCALES.map((code) => /* @__PURE__ */ jsx("option", { value: code, children: LOCALE_LABELS[code] || code }, code))
1752
- }
1753
- )
1754
- ] }),
1779
+ /* @__PURE__ */ jsx(LangSwitcher, { activeLocale, onSelect: setActiveLocale }),
1755
1780
  profiles.length > 0 && /* @__PURE__ */ jsx("button", { className: "ps-tryon-header-icon", title: t("Profiles"), onClick: () => setDrawer(drawer === "profiles" ? null : "profiles"), children: /* @__PURE__ */ jsx(UserIcon, {}) }),
1756
1781
  history.length > 0 && /* @__PURE__ */ jsx("button", { className: "ps-tryon-header-icon", title: t("History"), onClick: () => setDrawer(drawer === "history" ? null : "history"), children: /* @__PURE__ */ jsx(ClockIcon, {}) }),
1757
1782
  /* @__PURE__ */ jsx("button", { onClick: handleClose, className: cx("ps-tryon-close", cn.closeButton), children: /* @__PURE__ */ jsx(XIcon, {}) })
@@ -1837,21 +1862,63 @@ const STYLES = `
1837
1862
  .ps-tryon-close:hover { background: rgba(255,255,255,0.1); }
1838
1863
 
1839
1864
  /* Language switcher */
1840
- .ps-tryon-lang-switcher {
1841
- position: relative; display: flex; align-items: center; gap: clamp(3px, 0.21vw, 4px);
1842
- padding: clamp(3px, 0.26vw, 5px) clamp(6px, 0.52vw, 10px);
1843
- border: 1.5px solid #333; border-radius: clamp(6px, 0.52vw, 10px);
1844
- background: transparent; cursor: pointer; color: #999; transition: all 0.2s;
1845
- }
1846
- .ps-tryon-lang-switcher:hover { border-color: #bb945c; color: #bb945c; }
1847
- .ps-tryon-lang-switcher svg { stroke: currentColor; fill: none; flex-shrink: 0; }
1848
- .ps-tryon-lang-select {
1849
- appearance: none; -webkit-appearance: none; background: transparent; border: none;
1850
- color: inherit; font-size: clamp(9px, 0.57vw, 11px); font-family: inherit;
1851
- cursor: pointer; outline: none; padding-right: clamp(8px, 0.52vw, 10px);
1852
- max-width: clamp(70px, 5.2vw, 100px);
1853
- }
1854
- .ps-tryon-lang-select option { background: #1a1b1a; color: #fff; }
1865
+ .ps-tryon-lang-wrap { position: relative; z-index: 10; }
1866
+ .ps-tryon-lang-trigger {
1867
+ display: flex; align-items: center; gap: clamp(5px, 0.36vw, 7px);
1868
+ padding: clamp(5px, 0.36vw, 7px) clamp(10px, 0.73vw, 14px);
1869
+ border: 1.5px solid #333; border-radius: clamp(8px, 0.57vw, 11px);
1870
+ background: transparent; cursor: pointer; color: #999;
1871
+ transition: all 0.25s ease; font-family: inherit; white-space: nowrap;
1872
+ }
1873
+ .ps-tryon-lang-trigger:hover, .ps-tryon-lang-trigger.ps-active {
1874
+ border-color: #bb945c; color: #bb945c; background: rgba(187,148,92,0.06);
1875
+ }
1876
+ .ps-tryon-lang-trigger svg { stroke: currentColor; fill: none; flex-shrink: 0; }
1877
+ .ps-tryon-lang-current {
1878
+ font-size: clamp(11px, 0.68vw, 13px); font-weight: 500; letter-spacing: 0.01em;
1879
+ }
1880
+ .ps-tryon-lang-arrow {
1881
+ font-size: clamp(10px, 0.57vw, 12px); transition: transform 0.25s ease; display: inline-block;
1882
+ }
1883
+ .ps-tryon-lang-arrow.ps-open { transform: rotate(180deg); }
1884
+
1885
+ .ps-tryon-lang-dropdown {
1886
+ position: absolute; top: calc(100% + clamp(6px, 0.42vw, 8px)); right: 0;
1887
+ min-width: clamp(180px, 13vw, 240px);
1888
+ background: #1a1b1a; border: 1.5px solid #333;
1889
+ border-radius: clamp(10px, 0.73vw, 14px);
1890
+ box-shadow: 0 clamp(12px, 1vw, 20px) clamp(40px, 3vw, 60px) rgba(0,0,0,0.5),
1891
+ 0 0 0 1px rgba(255,255,255,0.03);
1892
+ overflow: hidden;
1893
+ animation: ps-lang-open 0.2s ease both;
1894
+ }
1895
+ @keyframes ps-lang-open {
1896
+ from { opacity: 0; transform: translateY(clamp(-6px, -0.42vw, -8px)) scale(0.96); }
1897
+ to { opacity: 1; transform: translateY(0) scale(1); }
1898
+ }
1899
+
1900
+ .ps-tryon-lang-list {
1901
+ max-height: clamp(240px, 18vw, 340px); overflow-y: auto; padding: clamp(4px, 0.31vw, 6px);
1902
+ scrollbar-width: thin; scrollbar-color: #333 transparent;
1903
+ }
1904
+ .ps-tryon-lang-item {
1905
+ display: flex; align-items: center; gap: clamp(8px, 0.57vw, 12px);
1906
+ width: 100%; padding: clamp(8px, 0.57vw, 11px) clamp(12px, 0.83vw, 16px);
1907
+ border: none; background: transparent; color: #ccc; cursor: pointer;
1908
+ border-radius: clamp(6px, 0.47vw, 9px); transition: all 0.15s ease;
1909
+ font-family: inherit; text-align: left;
1910
+ }
1911
+ .ps-tryon-lang-item:hover { background: rgba(255,255,255,0.06); color: #fff; }
1912
+ .ps-tryon-lang-item.ps-selected { background: rgba(187,148,92,0.1); color: #bb945c; }
1913
+ .ps-tryon-lang-name {
1914
+ flex: 1; font-size: clamp(12px, 0.73vw, 14px); font-weight: 500;
1915
+ }
1916
+ .ps-tryon-lang-code {
1917
+ font-size: clamp(9px, 0.52vw, 11px); color: #666; font-weight: 600;
1918
+ letter-spacing: 0.05em; font-family: ui-monospace, monospace;
1919
+ }
1920
+ .ps-tryon-lang-item.ps-selected .ps-tryon-lang-code { color: #bb945c; opacity: 0.7; }
1921
+ .ps-tryon-lang-check { color: #bb945c; display: flex; align-items: center; }
1855
1922
 
1856
1923
  /* Stepper */
1857
1924
  .ps-tryon-stepper { padding: clamp(12px, 1.04vw, 20px) clamp(14px, 1.25vw, 24px) clamp(7px, 0.63vw, 12px); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "3.10.0",
3
+ "version": "3.11.0",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",