vibrant-tool 0.1.4 → 0.1.5

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.
@@ -99601,7 +99601,7 @@ end`);
99601
99601
  const currentSide = useHistoryStore.getState().currentPage || "front";
99602
99602
  const editorPages = useEditorStore.getState().pages || {};
99603
99603
  const historyPages = useHistoryStore.getState().pages || {};
99604
- const currentUrl = getWorkareaDataUrl(canvas2);
99604
+ const currentUrl = getWorkareaDataUrl(canvas2, 2);
99605
99605
  const opposingSide = currentSide === "front" ? "back" : "front";
99606
99606
  const opposingJson = editorPages[opposingSide] || historyPages[opposingSide]?.history?.at(-1) || null;
99607
99607
  let opposingUrl = "";
@@ -99639,6 +99639,10 @@ end`);
99639
99639
  setRotY((dragRef.current.rotY + (e2.clientX - dragRef.current.x) * 0.5) % 360);
99640
99640
  setRotX(Math.max(-60, Math.min(60, dragRef.current.rotX - (e2.clientY - dragRef.current.y) * 0.5)));
99641
99641
  };
99642
+ const workarea = canvas2 ? canvas2.getObjects().find((o2) => o2.name === "workarea") : null;
99643
+ const waW = (workarea?.width ?? 1050) * (workarea?.scaleX ?? 1);
99644
+ const waH = (workarea?.height ?? 600) * (workarea?.scaleY ?? 1);
99645
+ const cardAspectRatio = waW && waH ? waW / waH : 1.75;
99642
99646
  const currentProof = activeSide === "front" ? frontUrl : backUrl;
99643
99647
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[99999] bg-black/60 backdrop-blur-sm flex items-center justify-center p-4 select-none", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-4xl bg-white border border-gray-200 rounded-2xl shadow-2xl overflow-hidden flex flex-col h-[85vh]", children: [
99644
99648
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-b border-gray-200 bg-gray-50/90", children: [
@@ -99684,7 +99688,7 @@ end`);
99684
99688
  onMouseUp: () => setIsDragging(false),
99685
99689
  onMouseLeave: () => setIsDragging(false),
99686
99690
  className: `flex-1 relative overflow-hidden flex items-center justify-center bg-gradient-to-b from-slate-50 to-slate-100 ${viewMode === "3d" ? "cursor-grab active:cursor-grabbing" : ""}`,
99687
- children: viewMode === "3d" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full h-full flex items-center justify-center [perspective:1200px]", children: [
99691
+ children: viewMode === "3d" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full h-full flex items-center justify-center [perspective:1200px] p-6", children: [
99688
99692
  /* @__PURE__ */ jsxRuntime.jsxs(
99689
99693
  "div",
99690
99694
  {
@@ -99692,10 +99696,13 @@ end`);
99692
99696
  transform: `rotateX(${rotX}deg) rotateY(${rotY}deg)`,
99693
99697
  transformStyle: "preserve-3d",
99694
99698
  transition: isDragging ? "none" : "transform 0.15s cubic-bezier(0.1, 0.9, 0.2, 1)",
99695
- width: "420px",
99696
- height: "260px"
99699
+ aspectRatio: cardAspectRatio,
99700
+ width: cardAspectRatio >= 1 ? "min(85%, 680px)" : "auto",
99701
+ height: cardAspectRatio < 1 ? "min(80%, 520px)" : "auto",
99702
+ maxHeight: "80%",
99703
+ maxWidth: "85%"
99697
99704
  },
99698
- className: "relative will-change-transform shadow-2xl",
99705
+ className: "relative will-change-transform shadow-2xl rounded-xl",
99699
99706
  children: [
99700
99707
  /* @__PURE__ */ jsxRuntime.jsxs(
99701
99708
  "div",
@@ -99703,12 +99710,12 @@ end`);
99703
99710
  style: { backfaceVisibility: "hidden" },
99704
99711
  className: "absolute inset-0 rounded-xl overflow-hidden bg-white shadow-xl border border-gray-200",
99705
99712
  children: [
99706
- frontUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: frontUrl, alt: "Front", className: "w-full h-full object-contain pointer-events-none" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-xs text-gray-400", children: "Front Design" }),
99713
+ frontUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: frontUrl, alt: "Front", className: "w-full h-full object-fill pointer-events-none block" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-xs text-gray-400", children: "Front Design" }),
99707
99714
  /* @__PURE__ */ jsxRuntime.jsx(
99708
99715
  "div",
99709
99716
  {
99710
99717
  style: {
99711
- background: `linear-gradient(${120 + rotY * 0.8}deg, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.1) 100%)`
99718
+ background: `linear-gradient(${120 + rotY * 0.8}deg, rgba(255,255,255,0.4) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.08) 100%)`
99712
99719
  },
99713
99720
  className: "absolute inset-0 pointer-events-none mix-blend-overlay opacity-80"
99714
99721
  }
@@ -99722,7 +99729,7 @@ end`);
99722
99729
  style: { transform: "rotateY(180deg)", backfaceVisibility: "hidden" },
99723
99730
  className: "absolute inset-0 rounded-xl overflow-hidden bg-white shadow-xl border border-gray-200",
99724
99731
  children: [
99725
- isTwoSided ? backUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: backUrl, alt: "Back", className: "w-full h-full object-contain pointer-events-none" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-full flex flex-col items-center justify-center text-xs text-gray-400 p-4 text-center", children: [
99732
+ isTwoSided ? backUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: backUrl, alt: "Back", className: "w-full h-full object-fill pointer-events-none block" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-full flex flex-col items-center justify-center text-xs text-gray-400 p-4 text-center", children: [
99726
99733
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-gray-600", children: "Back Side" }),
99727
99734
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-gray-400 mt-1", children: "Design added to Back tab will render here" })
99728
99735
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-slate-50 flex items-center justify-center text-xs text-gray-400", children: "Single-sided Product" }),
@@ -99730,37 +99737,29 @@ end`);
99730
99737
  "div",
99731
99738
  {
99732
99739
  style: {
99733
- background: `linear-gradient(${120 - rotY * 0.8}deg, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.1) 100%)`
99740
+ background: `linear-gradient(${120 - rotY * 0.8}deg, rgba(255,255,255,0.4) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.08) 100%)`
99734
99741
  },
99735
99742
  className: "absolute inset-0 pointer-events-none mix-blend-overlay opacity-80"
99736
99743
  }
99737
99744
  )
99738
99745
  ]
99739
99746
  }
99740
- ),
99741
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { transform: "translateZ(-1px)" }, className: "absolute inset-0 rounded-xl bg-gray-300 -z-10 shadow-md" })
99747
+ )
99742
99748
  ]
99743
99749
  }
99744
99750
  ),
99745
- /* @__PURE__ */ jsxRuntime.jsx(
99746
- "div",
99747
- {
99748
- style: { transform: `rotateX(90deg) translateZ(-150px)` },
99749
- className: "absolute w-72 h-24 bg-black/20 blur-xl rounded-full pointer-events-none"
99750
- }
99751
- ),
99752
99751
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-4 left-4 bg-white/80 backdrop-blur-md px-3 py-1 rounded-full border border-gray-200 text-[11px] text-gray-600 pointer-events-none flex items-center gap-1.5 shadow-sm", children: [
99753
99752
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-2 h-2 rounded-full bg-[#02bc71] animate-ping" }),
99754
99753
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Drag to Rotate 360°" })
99755
99754
  ] })
99756
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 flex flex-col items-center justify-center", children: [
99757
- isTwoSided && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-4 bg-gray-200 p-0.5 rounded-lg border border-gray-300 text-xs", children: [
99755
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full h-full flex items-center justify-center p-6", children: [
99756
+ isTwoSided && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-4 left-1/2 -translate-x-1/2 flex items-center gap-2 bg-gray-200/90 backdrop-blur-sm p-1 rounded-xl border border-gray-300 text-xs shadow-sm z-20", children: [
99758
99757
  /* @__PURE__ */ jsxRuntime.jsx(
99759
99758
  "button",
99760
99759
  {
99761
99760
  type: "button",
99762
99761
  onClick: () => setActiveSide("front"),
99763
- className: `px-3 py-1 rounded-md font-semibold cursor-pointer ${activeSide === "front" ? "bg-[#02bc71] text-white shadow-sm" : "text-gray-600 hover:text-gray-900"}`,
99762
+ className: `px-3 py-1 rounded-lg font-semibold cursor-pointer transition-all ${activeSide === "front" ? "bg-[#02bc71] text-white shadow-sm" : "text-gray-600 hover:text-gray-900"}`,
99764
99763
  children: "Front Proof"
99765
99764
  }
99766
99765
  ),
@@ -99769,12 +99768,32 @@ end`);
99769
99768
  {
99770
99769
  type: "button",
99771
99770
  onClick: () => setActiveSide("back"),
99772
- className: `px-3 py-1 rounded-md font-semibold cursor-pointer ${activeSide === "back" ? "bg-[#02bc71] text-white shadow-sm" : "text-gray-600 hover:text-gray-900"}`,
99771
+ className: `px-3 py-1 rounded-lg font-semibold cursor-pointer transition-all ${activeSide === "back" ? "bg-[#02bc71] text-white shadow-sm" : "text-gray-600 hover:text-gray-900"}`,
99773
99772
  children: "Back Proof"
99774
99773
  }
99775
99774
  )
99776
99775
  ] }),
99777
- currentProof ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-2 shadow-xl max-w-full", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: currentProof, alt: "2D Proof", className: "max-h-[50vh] w-auto object-contain rounded-lg" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-8 text-center bg-gray-50 rounded-xl border border-gray-200 text-xs text-gray-400", children: [
99776
+ currentProof ? /* @__PURE__ */ jsxRuntime.jsx(
99777
+ "div",
99778
+ {
99779
+ style: {
99780
+ aspectRatio: cardAspectRatio,
99781
+ width: cardAspectRatio >= 1 ? "min(85%, 680px)" : "auto",
99782
+ height: cardAspectRatio < 1 ? "min(80%, 520px)" : "auto",
99783
+ maxHeight: "80%",
99784
+ maxWidth: "85%"
99785
+ },
99786
+ className: "relative rounded-xl overflow-hidden bg-white shadow-2xl border border-gray-200 flex items-center justify-center",
99787
+ children: /* @__PURE__ */ jsxRuntime.jsx(
99788
+ "img",
99789
+ {
99790
+ src: currentProof,
99791
+ alt: `${activeSide} 2D Proof`,
99792
+ className: "w-full h-full object-fill pointer-events-none block"
99793
+ }
99794
+ )
99795
+ }
99796
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-8 text-center bg-gray-50 rounded-xl border border-gray-200 text-xs text-gray-400", children: [
99778
99797
  "No preview available for ",
99779
99798
  activeSide,
99780
99799
  " side."
@@ -100388,7 +100407,7 @@ end`);
100388
100407
  onClick: () => setActivePanel(null)
100389
100408
  }
100390
100409
  ),
100391
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `fixed md:relative bottom-0 left-0 right-0 md:bottom-auto md:left-auto z-50 transition-all duration-300 ease-in-out`, children: [
100410
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `fixed md:relative bottom-0 left-0 right-0 md:bottom-auto md:left-auto z-50 transition-all duration-300 ease-in-out md:h-full`, children: [
100392
100411
  /* @__PURE__ */ jsxRuntime.jsxs(
100393
100412
  "div",
100394
100413
  {
@@ -100408,7 +100427,7 @@ end`);
100408
100427
  }
100409
100428
  )
100410
100429
  ] }),
100411
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto pt-4", children: panelName })
100430
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-y-auto pt-4 flex flex-col custom-scrollbar", children: panelName })
100412
100431
  ]
100413
100432
  }
100414
100433
  ),
@@ -100573,7 +100592,7 @@ end`);
100573
100592
  }
100574
100593
  )
100575
100594
  ] }),
100576
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "h-[calc(100vh-125px)] overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 pb-12 mx-4", children: [
100595
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "h-[calc(100vh-125px)] overflow-auto custom-scrollbar", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 pb-12 mx-4", children: [
100577
100596
  templates.map((tpl) => /* @__PURE__ */ jsxRuntime.jsx(
100578
100597
  "button",
100579
100598
  {
@@ -101297,7 +101316,7 @@ end`);
101297
101316
  ] })
101298
101317
  ] }),
101299
101318
  /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "text-neutral-800 h-[0.5px]" }),
101300
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-[calc(100dvh-180px)] overflow-auto", children: [
101319
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-[calc(100dvh-180px)] overflow-auto custom-scrollbar", children: [
101301
101320
  recentItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-4", children: [
101302
101321
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-5", children: [
101303
101322
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
@@ -101554,7 +101573,7 @@ end`);
101554
101573
  )
101555
101574
  ] }),
101556
101575
  /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "text-neutral-800 h-[0.5px] my-4" }),
101557
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "h-[calc(100vh-250px)] overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 pb-12 mx-4", children: [
101576
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "h-[calc(100vh-250px)] overflow-auto custom-scrollbar", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 pb-12 mx-4", children: [
101558
101577
  textElements.map((tpl, index) => /* @__PURE__ */ jsxRuntime.jsx(
101559
101578
  "button",
101560
101579
  {
@@ -101736,6 +101755,23 @@ end`);
101736
101755
  );
101737
101756
  }
101738
101757
  const VibrantLogo = "data:image/png;base64,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";
101758
+ const VibrantImageService = {
101759
+ async getFolderData(params = {}) {
101760
+ const { item = "Small", page = 1, limit = 30, search = "" } = params;
101761
+ const query = new URLSearchParams();
101762
+ if (item) query.set("item", item);
101763
+ if (page) query.set("page", String(page));
101764
+ if (limit) query.set("limit", String(limit));
101765
+ if (search) query.set("search", search);
101766
+ const res = await apiUploadImage(
101767
+ `/folder-data?${query.toString()}`,
101768
+ {
101769
+ method: "GET"
101770
+ }
101771
+ );
101772
+ return res;
101773
+ }
101774
+ };
101739
101775
  function useSocialAuth({
101740
101776
  onImageSelect
101741
101777
  }) {
@@ -101893,10 +101929,12 @@ end`);
101893
101929
  ];
101894
101930
  function PhotosPanel() {
101895
101931
  const { startLoading, stopLoading, isLoading } = useLoaderStore();
101932
+ const [source, setSource] = React.useState("external");
101896
101933
  const [socialImages, setSocialImages] = React.useState([]);
101897
101934
  const [page, setPage] = React.useState(1);
101898
101935
  const [hasMore, setHasMore] = React.useState(true);
101899
101936
  const [category, setCategory] = React.useState(imageOptions[0]);
101937
+ const [searchQuery, setSearchQuery] = React.useState("");
101900
101938
  const scrollRef = React.useRef(null);
101901
101939
  const {
101902
101940
  handleGoogleAuth,
@@ -101921,32 +101959,57 @@ end`);
101921
101959
  }
101922
101960
  });
101923
101961
  const fetchImages = React.useCallback(
101924
- async (q2, pageNo) => {
101962
+ async (q2, pageNo, currentSource = source) => {
101925
101963
  startLoading();
101926
101964
  try {
101927
- const res = await ShapeService.getAllExternal({
101928
- page: pageNo,
101929
- limit: 30,
101930
- keyType: "all",
101931
- isVector: false,
101932
- query: q2
101933
- });
101934
- const newItems = res.items.filter(
101935
- (x2) => x2.status && x2.image
101936
- );
101937
- setSocialImages(
101938
- (prev) => pageNo === 1 ? newItems : [...prev, ...newItems]
101939
- );
101940
- if (newItems.length < 20) setHasMore(false);
101965
+ if (currentSource === "vibrant") {
101966
+ const res = await VibrantImageService.getFolderData({
101967
+ item: "Small",
101968
+ page: pageNo,
101969
+ limit: 30,
101970
+ search: q2 || void 0
101971
+ });
101972
+ const newItems = (res.files || []).map((f) => ({
101973
+ _id: f.key,
101974
+ status: true,
101975
+ category: "vibrant",
101976
+ image: f.smallUrl || f.url,
101977
+ largeImage: f.largeUrl || f.url,
101978
+ tags: [f.name]
101979
+ }));
101980
+ setSocialImages(
101981
+ (prev) => pageNo === 1 ? newItems : [...prev, ...newItems]
101982
+ );
101983
+ if (newItems.length < 20) setHasMore(false);
101984
+ else setHasMore(true);
101985
+ } else {
101986
+ const res = await ShapeService.getAllExternal({
101987
+ page: pageNo,
101988
+ limit: 30,
101989
+ keyType: "all",
101990
+ isVector: false,
101991
+ query: q2
101992
+ });
101993
+ const newItems = res.items.filter(
101994
+ (x2) => x2.status && x2.image
101995
+ );
101996
+ setSocialImages(
101997
+ (prev) => pageNo === 1 ? newItems : [...prev, ...newItems]
101998
+ );
101999
+ if (newItems.length < 20) setHasMore(false);
102000
+ else setHasMore(true);
102001
+ }
102002
+ } catch (err) {
102003
+ console.error("Failed to fetch images:", err);
101941
102004
  } finally {
101942
102005
  stopLoading();
101943
102006
  }
101944
102007
  },
101945
- [startLoading, stopLoading]
102008
+ [startLoading, stopLoading, source]
101946
102009
  );
101947
102010
  React.useEffect(() => {
101948
- fetchImages(category, 1);
101949
- }, []);
102011
+ fetchImages(searchQuery || (source === "vibrant" ? "" : category), 1, source);
102012
+ }, [source]);
101950
102013
  React.useEffect(() => {
101951
102014
  const el = scrollRef.current;
101952
102015
  if (!el) return;
@@ -101955,13 +102018,13 @@ end`);
101955
102018
  if (el.scrollTop + el.clientHeight >= el.scrollHeight - 200) {
101956
102019
  const next = page + 1;
101957
102020
  setPage(next);
101958
- fetchImages(category, next);
102021
+ fetchImages(searchQuery || (source === "vibrant" ? "" : category), next, source);
101959
102022
  }
101960
102023
  };
101961
102024
  el.addEventListener("scroll", onScroll);
101962
102025
  return () => el.removeEventListener("scroll", onScroll);
101963
- }, [hasMore, isLoading]);
101964
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
102026
+ }, [hasMore, isLoading, page, searchQuery, category, source, fetchImages]);
102027
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full min-h-0", children: [
101965
102028
  /* @__PURE__ */ jsxRuntime.jsx("script", { src: "https://apis.google.com/js/api.js" }),
101966
102029
  /* @__PURE__ */ jsxRuntime.jsx(
101967
102030
  "script",
@@ -101981,73 +102044,159 @@ end`);
101981
102044
  });
101982
102045
  }
101983
102046
  } }),
101984
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-neutral-800 px-3 py-2 rounded flex items-center gap-2 mb-4 mx-4", children: /* @__PURE__ */ jsxRuntime.jsx(
101985
- "input",
101986
- {
101987
- className: "bg-transparent outline-none text-sm text-gray-300 w-full",
101988
- onKeyDown: (e2) => {
101989
- e2.stopPropagation();
101990
- if (e2.key === "Enter") {
101991
- fetchImages(e2.target.value, 1);
102047
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 pt-4", children: [
102048
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-neutral-800 px-3 py-2 rounded flex items-center gap-2 mb-3 mx-4", children: /* @__PURE__ */ jsxRuntime.jsx(
102049
+ "input",
102050
+ {
102051
+ className: "bg-transparent outline-none text-sm text-gray-300 w-full",
102052
+ placeholder: source === "vibrant" ? "Search Vibrant Images..." : "Search Stock Photos...",
102053
+ value: searchQuery,
102054
+ onChange: (e2) => setSearchQuery(e2.target.value),
102055
+ onKeyDown: (e2) => {
102056
+ e2.stopPropagation();
102057
+ if (e2.key === "Enter") {
102058
+ setPage(1);
102059
+ fetchImages(searchQuery, 1, source);
102060
+ }
101992
102061
  }
101993
102062
  }
101994
- }
101995
- ) }),
101996
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "m-4", children: [
101997
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-md font-medium mb-3", children: "Upload From Other Media" }),
101998
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
101999
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "cursor-pointer", onClick: () => handleGoogleAuth("googledrives"), children: /* @__PURE__ */ jsxRuntime.jsx(GoogleDriveIcon, {}) }),
102000
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "cursor-pointer", onClick: () => handleGoogleAuth("googlephotos"), children: /* @__PURE__ */ jsxRuntime.jsx(GooglePhotoIcon, {}) }),
102001
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "cursor-pointer", onClick: handleDropboxAuth, children: /* @__PURE__ */ jsxRuntime.jsx(
102002
- "img",
102003
- {
102004
- src: "https://vibrantprintshopimage.s3.amazonaws.com/dropbox.svg",
102005
- alt: "dropbox",
102006
- height: 30,
102007
- width: 30,
102008
- className: "object-contain"
102009
- }
102010
- ) }),
102011
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "cursor-pointer", onClick: handleFacebookAuth, children: /* @__PURE__ */ jsxRuntime.jsx(FacebookIcon, {}) }),
102012
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "cursor-pointer", onClick: handleInstagramAuth, children: /* @__PURE__ */ jsxRuntime.jsx(InstagramIcon, {}) }),
102013
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "cursor-pointer", children: /* @__PURE__ */ jsxRuntime.jsx(
102014
- "img",
102063
+ ) }),
102064
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-4 mb-3", children: [
102065
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-md font-medium mb-2 text-gray-200", children: "Upload From Other Media" }),
102066
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
102067
+ /* @__PURE__ */ jsxRuntime.jsx(
102068
+ "button",
102069
+ {
102070
+ type: "button",
102071
+ className: "cursor-pointer p-1.5 rounded-lg hover:bg-white/10 transition-colors",
102072
+ onClick: () => handleGoogleAuth("googledrives"),
102073
+ title: "Google Drive",
102074
+ children: /* @__PURE__ */ jsxRuntime.jsx(GoogleDriveIcon, {})
102075
+ }
102076
+ ),
102077
+ /* @__PURE__ */ jsxRuntime.jsx(
102078
+ "button",
102079
+ {
102080
+ type: "button",
102081
+ className: "cursor-pointer p-1.5 rounded-lg hover:bg-white/10 transition-colors",
102082
+ onClick: () => handleGoogleAuth("googlephotos"),
102083
+ title: "Google Photos",
102084
+ children: /* @__PURE__ */ jsxRuntime.jsx(GooglePhotoIcon, {})
102085
+ }
102086
+ ),
102087
+ /* @__PURE__ */ jsxRuntime.jsx(
102088
+ "button",
102089
+ {
102090
+ type: "button",
102091
+ className: "cursor-pointer p-1.5 rounded-lg hover:bg-white/10 transition-colors",
102092
+ onClick: handleDropboxAuth,
102093
+ title: "Dropbox",
102094
+ children: /* @__PURE__ */ jsxRuntime.jsx(
102095
+ "img",
102096
+ {
102097
+ src: "https://vibrantprintshopimage.s3.amazonaws.com/dropbox.svg",
102098
+ alt: "dropbox",
102099
+ height: 26,
102100
+ width: 26,
102101
+ className: "object-contain"
102102
+ }
102103
+ )
102104
+ }
102105
+ ),
102106
+ /* @__PURE__ */ jsxRuntime.jsx(
102107
+ "button",
102108
+ {
102109
+ type: "button",
102110
+ className: "cursor-pointer p-1.5 rounded-lg hover:bg-white/10 transition-colors",
102111
+ onClick: handleFacebookAuth,
102112
+ title: "Facebook",
102113
+ children: /* @__PURE__ */ jsxRuntime.jsx(FacebookIcon, {})
102114
+ }
102115
+ ),
102116
+ /* @__PURE__ */ jsxRuntime.jsx(
102117
+ "button",
102118
+ {
102119
+ type: "button",
102120
+ className: "cursor-pointer p-1.5 rounded-lg hover:bg-white/10 transition-colors",
102121
+ onClick: handleInstagramAuth,
102122
+ title: "Instagram",
102123
+ children: /* @__PURE__ */ jsxRuntime.jsx(InstagramIcon, {})
102124
+ }
102125
+ ),
102126
+ /* @__PURE__ */ jsxRuntime.jsx(
102127
+ "button",
102128
+ {
102129
+ type: "button",
102130
+ onClick: () => {
102131
+ setSource("vibrant");
102132
+ setPage(1);
102133
+ setSearchQuery("");
102134
+ fetchImages("", 1, "vibrant");
102135
+ },
102136
+ title: "Vibrant Stock Images",
102137
+ className: "cursor-pointer",
102138
+ children: /* @__PURE__ */ jsxRuntime.jsx(
102139
+ "img",
102140
+ {
102141
+ src: VibrantLogo,
102142
+ alt: "vibrant",
102143
+ height: 64,
102144
+ width: 64,
102145
+ className: "object-contain"
102146
+ }
102147
+ )
102148
+ }
102149
+ )
102150
+ ] })
102151
+ ] }),
102152
+ /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "text-neutral-800 h-[0.5px] my-3" }),
102153
+ source === "external" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-4 mb-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2 overflow-auto scrollbar-none custom-scrollbar", children: imageOptions.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
102154
+ "button",
102155
+ {
102156
+ className: `px-2 py-1 rounded-sm shrink-0 text-xs ${item === category ? "bg-[#02bc71] text-white" : "bg-[#8f99a826]"}`,
102157
+ onClick: () => {
102158
+ setCategory(item);
102159
+ setSocialImages([]);
102160
+ setPage(1);
102161
+ fetchImages(item.toLowerCase(), 1, "external");
102162
+ },
102163
+ children: item
102164
+ },
102165
+ item
102166
+ )) }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-4 mb-3 flex items-center justify-between", children: [
102167
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-semibold text-[#02bc71] flex items-center gap-1.5", children: [
102168
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block w-2 h-2 rounded-full bg-[#02bc71]" }),
102169
+ "Vibrant Cloud Images"
102170
+ ] }),
102171
+ /* @__PURE__ */ jsxRuntime.jsx(
102172
+ "button",
102015
102173
  {
102016
- src: VibrantLogo,
102017
- alt: "vibrant",
102018
- height: 60,
102019
- width: 60,
102020
- className: "object-contain"
102174
+ type: "button",
102175
+ onClick: () => {
102176
+ setSource("external");
102177
+ setPage(1);
102178
+ setSearchQuery("");
102179
+ fetchImages(category.toLowerCase(), 1, "external");
102180
+ },
102181
+ className: "text-[11px] text-gray-400 hover:text-white cursor-pointer underline",
102182
+ children: "Explore Stock Categories"
102021
102183
  }
102022
- ) })
102184
+ )
102023
102185
  ] })
102024
102186
  ] }),
102025
- /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "text-neutral-800 h-[0.5px] my-4" }),
102026
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "m-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2 overflow-auto", children: imageOptions.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
102027
- "button",
102028
- {
102029
- className: `px-2 py-1 rounded-sm shrink-0 ${item === category ? "bg-[#02bc71] text-white" : "bg-[#8f99a826]"}`,
102030
- onClick: () => {
102031
- setCategory(item);
102032
- setSocialImages([]);
102033
- fetchImages(item.toLowerCase(), 1);
102034
- },
102035
- children: item
102036
- },
102037
- item
102038
- )) }) }),
102039
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[calc(100vh-288px)] overflow-auto", ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-4 md:grid-cols-3 gap-3 mx-4 pb-5", children: socialImages.length > 0 && socialImages.map((item, i2) => {
102187
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-y-auto pb-8 custom-scrollbar", ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-4 md:grid-cols-3 gap-3 mx-4 pb-5", children: socialImages.length > 0 ? socialImages.map((item, i2) => {
102040
102188
  return /* @__PURE__ */ jsxRuntime.jsx(
102041
102189
  "button",
102042
102190
  {
102043
- className: "relative aspect-square rounded overflow-hidden group cursor-pointer",
102191
+ className: "relative aspect-square rounded overflow-hidden group cursor-pointer bg-neutral-900 transition-all",
102044
102192
  onClick: async () => {
102045
102193
  try {
102046
102194
  startLoading();
102047
- const image = await ShapeService.convertImages(item.largeImage);
102048
- const imageUrl = image?.success ? image?.url : null;
102049
- if (!imageUrl) return;
102050
- addImageToCanvas(imageUrl);
102195
+ const targetUrl = item.largeImage || item.image;
102196
+ if (!targetUrl) return;
102197
+ const image = await ShapeService.convertImages(targetUrl);
102198
+ const imageUrl = image?.success ? image?.url : targetUrl;
102199
+ if (imageUrl) addImageToCanvas(imageUrl);
102051
102200
  if (window.innerWidth < 768) {
102052
102201
  useSidePanelStore.getState().setActivePanel(null);
102053
102202
  }
@@ -102063,14 +102212,14 @@ end`);
102063
102212
  src: item.image,
102064
102213
  height: 300,
102065
102214
  width: 300,
102066
- alt: "stock",
102215
+ alt: item.tags?.[0] || "stock",
102067
102216
  className: "object-cover w-full h-full group-hover:scale-105 transition-transform"
102068
102217
  }
102069
102218
  )
102070
102219
  },
102071
102220
  i2
102072
102221
  );
102073
- }) }) })
102222
+ }) : !isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-full py-8 text-center text-xs text-gray-500", children: "No images found" }) : null }) })
102074
102223
  ] });
102075
102224
  }
102076
102225
  async function addBackgroundImage(url) {
@@ -102085,7 +102234,7 @@ end`);
102085
102234
  const bounds = workarea.getBoundingRect();
102086
102235
  const centerX = bounds.left + bounds.width / 2;
102087
102236
  const centerY = bounds.top + bounds.height / 2;
102088
- oa.fromURL(url, { crossOrigin: "anonymous" }).then((img) => {
102237
+ oa.fromURL(url + "?t=vb", { crossOrigin: "anonymous" }).then((img) => {
102089
102238
  img.set({
102090
102239
  left: centerX,
102091
102240
  top: centerY,
@@ -102154,6 +102303,13 @@ end`);
102154
102303
  if (obj.type === "image" && obj.name !== "qr" && obj.name !== "barcode" && !obj._objects) {
102155
102304
  return;
102156
102305
  }
102306
+ if (obj.type === "textbox" || obj.type === "i-text" || obj.type === "text") {
102307
+ const fill22 = obj.get?.("fill") ?? obj.fill;
102308
+ if (typeof fill22 === "string" && fill22 !== "none" && fill22 !== "transparent" && fill22 !== "") {
102309
+ addColor(fill22);
102310
+ }
102311
+ return;
102312
+ }
102157
102313
  if (obj.type === "group" && obj.name === "qr") {
102158
102314
  if (obj.__qrDark) addColor(obj.__qrDark);
102159
102315
  if (obj.__qrLight) addColor(obj.__qrLight);
@@ -102584,8 +102740,9 @@ end`);
102584
102740
  "div",
102585
102741
  {
102586
102742
  ref: popoverRef,
102743
+ "data-cmyk-popover": "true",
102587
102744
  style: { position: "fixed", top: `${coords.top}px`, left: `${coords.left}px`, zIndex: 999999 },
102588
- className: "bg-white rounded-2xl shadow-2xl p-3.5 w-[270px] text-gray-800 border border-gray-100 select-none font-sans",
102745
+ className: "cmyk-picker-popover bg-white rounded-2xl shadow-2xl p-3.5 w-[270px] text-gray-800 border border-gray-100 select-none font-sans",
102589
102746
  children: [
102590
102747
  /* @__PURE__ */ jsxRuntime.jsx(
102591
102748
  "div",
@@ -102876,7 +103033,7 @@ end`);
102876
103033
  hex
102877
103034
  ))
102878
103035
  ] }),
102879
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[calc(100vh-165px)] overflow-auto", ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3 mx-4 pb-5", children: backgroundImages.map((item, i2) => /* @__PURE__ */ jsxRuntime.jsx(
103036
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[calc(100vh-165px)] overflow-auto custom-scrollbar", ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3 mx-4 pb-5", children: backgroundImages.map((item, i2) => /* @__PURE__ */ jsxRuntime.jsx(
102880
103037
  "button",
102881
103038
  {
102882
103039
  className: "relative aspect-square rounded overflow-hidden group cursor-pointer",
@@ -105463,7 +105620,7 @@ END:VCARD`;
105463
105620
  ]
105464
105621
  }
105465
105622
  ) }),
105466
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-[calc(100vh-200px)] overflow-auto", children: [
105623
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-[calc(100vh-200px)] overflow-auto custom-scrollbar", children: [
105467
105624
  type === "url" && /* @__PURE__ */ jsxRuntime.jsx(FormField$1, { label: "Website URL", error: errors.url, children: /* @__PURE__ */ jsxRuntime.jsx(
105468
105625
  "input",
105469
105626
  {
@@ -106773,7 +106930,7 @@ END:VCARD`;
106773
106930
  { id: "natural", label: "Natural" },
106774
106931
  { id: "warm", label: "Warm" }
106775
106932
  ];
106776
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto custom-scrollbar overflow-x-hidden px-4", children: [
106933
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto custom-scrollbar overflow-x-hidden px-4 custom-scrollbar", children: [
106777
106934
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3 mb-6", children: PRESETS.map((p2) => /* @__PURE__ */ jsxRuntime.jsx(
106778
106935
  "button",
106779
106936
  {
@@ -107359,7 +107516,7 @@ END:VCARD`;
107359
107516
  saveState();
107360
107517
  setActivePanel(null);
107361
107518
  };
107362
- return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "bg-neutral-900 border-r border-neutral-800 p-4 text-white h-full overflow-y-auto", children: [
107519
+ return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "bg-neutral-900 border-r border-neutral-800 p-4 text-white h-full overflow-y-auto custom-scrollbar", children: [
107363
107520
  /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: () => setActivePanel(null), className: "cursor-pointer mb-2", children: "← Back" }),
107364
107521
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-between items-center mb-4", children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold ", children: "Mask image" }) }),
107365
107522
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: mask.map((m2, index) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -107533,7 +107690,7 @@ END:VCARD`;
107533
107690
  )
107534
107691
  ] }),
107535
107692
  /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "text-neutral-800 h-[0.5px]" }),
107536
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[calc(100vh-126px)] overflow-auto", ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-4 py-5", children: fontData.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-gray-400 text-sm text-center", children: "No results found" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
107693
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[calc(100vh-126px)] overflow-auto custom-scrollbar", ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-4 py-5", children: fontData.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-gray-400 text-sm text-center", children: "No results found" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
107537
107694
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-4", children: fontData.map((item, i2) => /* @__PURE__ */ jsxRuntime.jsx(
107538
107695
  "button",
107539
107696
  {
@@ -152845,7 +153002,7 @@ ${elements2.join("\n")}
152845
153002
  }
152846
153003
  };
152847
153004
  const stopPropagation = (e2) => e2.stopPropagation();
152848
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col h-full mx-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto space-y-5 pr-2", children: [
153005
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col h-full mx-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto space-y-5 pr-2 custom-scrollbar", children: [
152849
153006
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-white", children: "Bar Code" }),
152850
153007
  /* @__PURE__ */ jsxRuntime.jsx(FormField, { label: "Select Bar Code Type", children: /* @__PURE__ */ jsxRuntime.jsx(
152851
153008
  "select",
@@ -152979,7 +153136,7 @@ ${elements2.join("\n")}
152979
153136
  "div",
152980
153137
  {
152981
153138
  ref: scrollRef,
152982
- className: "flex-1 min-h-0 overflow-y-auto flex flex-col gap-3 px-4 py-2",
153139
+ className: "flex-1 min-h-0 overflow-y-auto flex flex-col gap-3 px-4 py-2 custom-scrollbar",
152983
153140
  children: [
152984
153141
  quotes.map((q2, i2) => /* @__PURE__ */ jsxRuntime.jsxs(
152985
153142
  "button",
@@ -153031,7 +153188,7 @@ ${elements2.join("\n")}
153031
153188
  if (params?.status !== void 0) searchParams.append("status", String(params.status));
153032
153189
  searchParams.append("limit", String(params?.limit || 100));
153033
153190
  if (params?.page) searchParams.append("page", String(params.page));
153034
- const res = await apiFetch(`/colors?${searchParams.toString()}`, {
153191
+ const res = await apiFetch(`/api/colors?${searchParams.toString()}`, {
153035
153192
  method: "GET"
153036
153193
  });
153037
153194
  if (Array.isArray(res)) return res;
@@ -153247,8 +153404,8 @@ ${elements2.join("\n")}
153247
153404
  }
153248
153405
  )
153249
153406
  ] }) }),
153250
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto space-y-5 p-4 pr-3", children: [
153251
- objectColors.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
153407
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto space-y-5 p-4 pr-3 custom-scrollbar", children: [
153408
+ objectColors.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
153252
153409
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
153253
153410
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[11px] font-bold text-neutral-400 uppercase tracking-wider", children: [
153254
153411
  "Object Colors (",
@@ -153894,6 +154051,36 @@ ${elements2.join("\n")}
153894
154051
  const [strokeColor, setStrokeColor] = React.useState("#000000");
153895
154052
  const [strokeSize, setStrokeSize] = React.useState(0);
153896
154053
  const [strokeStyle, setStrokeStyle] = React.useState("Line");
154054
+ const strokeControlsRef = React.useRef(null);
154055
+ const textPopupRef = React.useRef(null);
154056
+ const textPopupButtonRef = React.useRef(null);
154057
+ React.useEffect(() => {
154058
+ if (!showStrokeControls) return;
154059
+ const handleClickOutside = (e2) => {
154060
+ const target = e2.target;
154061
+ if (!target) return;
154062
+ if (strokeControlsRef.current?.contains(target)) return;
154063
+ if (target.closest?.('[data-cmyk-popover="true"], .cmyk-picker-popover')) return;
154064
+ setShowStrokeControls(false);
154065
+ };
154066
+ document.addEventListener("mousedown", handleClickOutside);
154067
+ return () => {
154068
+ document.removeEventListener("mousedown", handleClickOutside);
154069
+ };
154070
+ }, [showStrokeControls]);
154071
+ React.useEffect(() => {
154072
+ if (!showTextPopup) return;
154073
+ const handleClickOutside = (e2) => {
154074
+ const target = e2.target;
154075
+ if (!target) return;
154076
+ if (textPopupRef.current?.contains(target) || textPopupButtonRef.current?.contains(target)) return;
154077
+ setShowTextPopup(false);
154078
+ };
154079
+ document.addEventListener("mousedown", handleClickOutside);
154080
+ return () => {
154081
+ document.removeEventListener("mousedown", handleClickOutside);
154082
+ };
154083
+ }, [showTextPopup]);
153897
154084
  const text = React.useMemo(() => {
153898
154085
  if (type !== "textbox") return null;
153899
154086
  return isTextbox(objects[0]) ? objects[0] : null;
@@ -154020,6 +154207,7 @@ ${elements2.join("\n")}
154020
154207
  /* @__PURE__ */ jsxRuntime.jsx(
154021
154208
  "button",
154022
154209
  {
154210
+ ref: textPopupButtonRef,
154023
154211
  type: "button",
154024
154212
  "aria-expanded": showTextPopup,
154025
154213
  className: `cursor-pointer rounded p-1 transition-colors duration-150 ${showTextPopup ? "bg-neutral-700 text-white ring-1 ring-neutral-600 shadow-sm" : "hover:bg-neutral-700"}`,
@@ -154041,6 +154229,7 @@ ${elements2.join("\n")}
154041
154229
  showTextPopup && /* @__PURE__ */ jsxRuntime.jsxs(
154042
154230
  "div",
154043
154231
  {
154232
+ ref: textPopupRef,
154044
154233
  className: "fixed md:absolute z-[9999] md:z-50 bg-[#1d1d1d] text-white shadow-[0_12px_30px_rgba(0,0,0,0.35)] rounded-lg p-4 top-[112px] md:top-[40px] left-1/2 md:left-auto md:right-0 -translate-x-1/2 md:-translate-x-0 border border-neutral-700",
154045
154234
  style: {
154046
154235
  width: "230px"
@@ -154133,7 +154322,7 @@ ${elements2.join("\n")}
154133
154322
  children: "Aa"
154134
154323
  }
154135
154324
  ),
154136
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
154325
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: strokeControlsRef, children: [
154137
154326
  /* @__PURE__ */ jsxRuntime.jsx(
154138
154327
  "button",
154139
154328
  {
@@ -154144,20 +154333,17 @@ ${elements2.join("\n")}
154144
154333
  }
154145
154334
  ),
154146
154335
  showStrokeControls && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute left-0 top-full z-50 mt-2 flex items-center gap-3 rounded-md border border-neutral-700 bg-[#1d1d1d] px-3 py-2 text-white shadow-[0_12px_30px_rgba(0,0,0,0.35)]", children: [
154147
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-[13px] font-medium text-white", children: [
154336
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-[13px] font-medium text-white", children: [
154148
154337
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Color" }),
154149
154338
  /* @__PURE__ */ jsxRuntime.jsx(
154150
- "input",
154339
+ CMYKColorPicker,
154151
154340
  {
154152
- type: "color",
154153
154341
  value: strokeColor,
154154
- onChange: (e2) => {
154155
- const nextColor = e2.target.value;
154342
+ onChange: (hex) => {
154343
+ const nextColor = typeof hex === "string" ? hex : "#000000";
154156
154344
  setStrokeColor(nextColor);
154157
154345
  applyTextStroke(nextColor, strokeSize, strokeStyle);
154158
- },
154159
- className: "h-8 w-10 cursor-pointer rounded border border-neutral-600 bg-transparent p-0",
154160
- "aria-label": "Text stroke color"
154346
+ }
154161
154347
  }
154162
154348
  )
154163
154349
  ] }),