@snowcone-app/canvas 0.33.1 → 0.35.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 (50) hide show
  1. package/dist/{CanvasRenderer-1j-twIbs.js → CanvasRenderer-BHBCxI-B.js} +4 -4
  2. package/dist/{CanvasRenderer-1j-twIbs.js.map → CanvasRenderer-BHBCxI-B.js.map} +1 -1
  3. package/dist/{CanvasStateV1-BmC1JfPv.js → CanvasStateV1-BoG8ld4D.js} +3 -3
  4. package/dist/{CanvasStateV1-BmC1JfPv.js.map → CanvasStateV1-BoG8ld4D.js.map} +1 -1
  5. package/dist/{ContextualToolbars-BrllZJTn.js → ContextualToolbars-TCO7dzu6.js} +6 -6
  6. package/dist/{ContextualToolbars-BrllZJTn.js.map → ContextualToolbars-TCO7dzu6.js.map} +1 -1
  7. package/dist/{EditorCanvasImpl-BiNG1dIj.js → EditorCanvasImpl-Dl75xnjk.js} +7 -7
  8. package/dist/{EditorCanvasImpl-BiNG1dIj.js.map → EditorCanvasImpl-Dl75xnjk.js.map} +1 -1
  9. package/dist/{ExportManager-Ci81K6xA.js → ExportManager-D1PAlOiE.js} +2 -2
  10. package/dist/{ExportManager-Ci81K6xA.js.map → ExportManager-D1PAlOiE.js.map} +1 -1
  11. package/dist/{FontAnalyzer-BrKY6XYn.js → FontAnalyzer-CEYA_6fY.js} +476 -439
  12. package/dist/FontAnalyzer-CEYA_6fY.js.map +1 -0
  13. package/dist/ImagePanel-Duh1AMdF.js +984 -0
  14. package/dist/ImagePanel-Duh1AMdF.js.map +1 -0
  15. package/dist/{SnowconeCanvas-DjQFFTDh.js → SnowconeCanvas-h8cfofsO.js} +296 -292
  16. package/dist/{SnowconeCanvas-DjQFFTDh.js.map → SnowconeCanvas-h8cfofsO.js.map} +1 -1
  17. package/dist/advanced.mjs +14 -14
  18. package/dist/api/stable.d.ts +1 -0
  19. package/dist/components/ImageBrowserDrawer.d.ts +4 -1
  20. package/dist/components/embed/SnowconeCanvas.d.ts +9 -0
  21. package/dist/contexts/CanvasServicesContext.d.ts +17 -1
  22. package/dist/core/ImageElement.d.ts +6 -0
  23. package/dist/core/ImageLoadEvents.d.ts +33 -0
  24. package/dist/{custom-icons-QEBlxVyq.js → custom-icons-DYIOjjXt.js} +2 -2
  25. package/dist/{custom-icons-QEBlxVyq.js.map → custom-icons-DYIOjjXt.js.map} +1 -1
  26. package/dist/{design-builder-D4izkvlb.js → design-builder-CqgTpp9B.js} +2 -2
  27. package/dist/{design-builder-D4izkvlb.js.map → design-builder-CqgTpp9B.js.map} +1 -1
  28. package/dist/{embed-C6kwN09N.js → embed-p_FskJ1G.js} +10 -10
  29. package/dist/{embed-C6kwN09N.js.map → embed-p_FskJ1G.js.map} +1 -1
  30. package/dist/embed.mjs +7 -7
  31. package/dist/{guards-BhaQgJrE.js → guards-DldCuuJq.js} +2 -2
  32. package/dist/{guards-BhaQgJrE.js.map → guards-DldCuuJq.js.map} +1 -1
  33. package/dist/index.mjs +9 -9
  34. package/dist/internals.mjs +6 -6
  35. package/dist/services/imageSearch.d.ts +24 -0
  36. package/dist/style.css +1 -1
  37. package/dist/{template-fields-xVQZRXvc.js → template-fields-jgE6czak.js} +5 -5
  38. package/dist/{template-fields-xVQZRXvc.js.map → template-fields-jgE6czak.js.map} +1 -1
  39. package/dist/testing.mjs +3 -3
  40. package/dist/{useCommands-DmewMc5w.js → useCommands-D16Tq-B-.js} +517 -499
  41. package/dist/{useCommands-DmewMc5w.js.map → useCommands-D16Tq-B-.js.map} +1 -1
  42. package/dist/{usePieceGuideBundle-CnSmYrmM.js → usePieceGuideBundle-BUQKb0Ja.js} +2 -2
  43. package/dist/{usePieceGuideBundle-CnSmYrmM.js.map → usePieceGuideBundle-BUQKb0Ja.js.map} +1 -1
  44. package/dist/{validation-CA6cMSOX.js → validation-8QF2gWih.js} +11 -11
  45. package/dist/{validation-CA6cMSOX.js.map → validation-8QF2gWih.js.map} +1 -1
  46. package/example/package.json +1 -1
  47. package/package.json +1 -1
  48. package/dist/FontAnalyzer-BrKY6XYn.js.map +0 -1
  49. package/dist/ImagePanel-Ckpc6QqR.js +0 -951
  50. package/dist/ImagePanel-Ckpc6QqR.js.map +0 -1
@@ -0,0 +1,984 @@
1
+ import { jsx as e, jsxs as t, Fragment as le } from "react/jsx-runtime";
2
+ import * as es from "react";
3
+ import Be, { useMemo as $e, useState as r, useRef as M, useEffect as ie, useCallback as fe } from "react";
4
+ import { u as ss, g as ts } from "./design-builder-CqgTpp9B.js";
5
+ import { o as cs, N as as, d as je, W as rs, I as p, O as me, B as W, u as ns, X as os, C as is } from "./useCommands-D16Tq-B-.js";
6
+ import { c as Ge, I as ls } from "./FontAnalyzer-CEYA_6fY.js";
7
+ import { T as C, S as ze, a as Ie, I as Re, L as ke } from "./custom-icons-DYIOjjXt.js";
8
+ import { a as ds } from "./guards-DldCuuJq.js";
9
+ const He = es.forwardRef(
10
+ ({ className: d, isInvalid: a, disabled: x, readOnly: k, required: u, variant: A, ...c }, g) => {
11
+ const o = cs(), i = A ?? (o.variant === "default" ? "filled" : "default");
12
+ return /* @__PURE__ */ e(
13
+ "textarea",
14
+ {
15
+ className: as(
16
+ "sc:flex sc:min-h-[80px] sc:w-full sc:rounded-input sc:px-2.5 sc:py-2 sc:text-sm sc:transition-colors",
17
+ "sc:text-foreground sc:border-none",
18
+ "sc:placeholder:text-foreground/50",
19
+ "sc:focus-visible:outline-none sc:focus-visible:ring-2 sc:focus-visible:ring-focus",
20
+ "sc:disabled:cursor-not-allowed sc:disabled:opacity-50",
21
+ // Variant styles - semantic: field on page vs field on surface
22
+ i === "default" && "sc:bg-field sc:shadow-soft sc:dark:shadow-none",
23
+ i === "filled" && "sc:bg-[var(--color-field-on-surface)]",
24
+ a && "sc:ring-2 sc:ring-danger sc:focus-visible:ring-danger",
25
+ d
26
+ ),
27
+ ref: g,
28
+ disabled: x,
29
+ readOnly: k,
30
+ required: u,
31
+ "aria-invalid": a,
32
+ ...c
33
+ }
34
+ );
35
+ }
36
+ );
37
+ He.displayName = "Textarea";
38
+ const _e = He;
39
+ _e.displayName = "TextArea";
40
+ const xe = Ge("ImageBrowser"), us = "Image search is temporarily unavailable.", Pe = "Image generation is temporarily unavailable.", ms = "Vector search is temporarily unavailable.", Ve = "Background removal is temporarily unavailable.";
41
+ function fs(d, a) {
42
+ const x = d instanceof Error ? d.message : "";
43
+ return !x || /VITE_|NEXT_PUBLIC_|\.env/i.test(x) ? a : x;
44
+ }
45
+ const gs = "1px", Ce = "1px", Ue = Be.memo(function({ image: a, onImageSelect: x, fixedHeight: k = !1 }) {
46
+ const [u, A] = r(!1), [c, g] = r(!1), [o, i] = r("top"), b = M(null), h = M(null), U = M(null), N = M(!0), [T, v] = r(!1), w = M(null), S = () => {
47
+ c || x(a);
48
+ }, Y = (R) => {
49
+ if (!U.current) return "top";
50
+ const m = U.current.getBoundingClientRect(), Z = R.clientX - m.left, z = R.clientY - m.top, y = m.width, L = m.height, P = {
51
+ top: z,
52
+ bottom: L - z,
53
+ left: Z,
54
+ right: y - Z
55
+ }, J = Math.min(P.top, P.bottom, P.left, P.right);
56
+ return J === P.top ? "top" : J === P.bottom ? "bottom" : J === P.left ? "left" : "right";
57
+ }, se = (R) => {
58
+ const m = Y(R);
59
+ w.current && (cancelAnimationFrame(w.current), w.current = null), m !== o ? (v(!0), i(m), w.current = requestAnimationFrame(() => {
60
+ w.current = requestAnimationFrame(() => {
61
+ v(!1), A(!0), w.current = null;
62
+ });
63
+ })) : (i(m), A(!0)), N.current = !1;
64
+ }, Q = (R) => {
65
+ w.current && (cancelAnimationFrame(w.current), w.current = null);
66
+ const m = Y(R);
67
+ i(m), v(!1), A(!1);
68
+ }, E = () => {
69
+ h.current && (clearTimeout(h.current), h.current = null), b.current = setTimeout(() => {
70
+ g(!0);
71
+ }, 400);
72
+ }, te = () => {
73
+ b.current && (clearTimeout(b.current), b.current = null), g(!1);
74
+ }, $ = () => {
75
+ b.current && (clearTimeout(b.current), b.current = null), h.current && (clearTimeout(h.current), h.current = null);
76
+ }, _ = () => {
77
+ g(!1);
78
+ }, D = a.source === "unsplash" ? "Unsplash" : "Pixabay", ce = u || c, q = () => {
79
+ if (!u) return `scale(${1.12})`;
80
+ switch (o) {
81
+ case "top":
82
+ return `scale(${1.12}) translateY(5%)`;
83
+ case "bottom":
84
+ return `scale(${1.12}) translateY(-5%)`;
85
+ case "left":
86
+ return `scale(${1.12}) translateX(5%)`;
87
+ case "right":
88
+ return `scale(${1.12}) translateX(-5%)`;
89
+ default:
90
+ return `scale(${1.12})`;
91
+ }
92
+ };
93
+ return /* @__PURE__ */ t(
94
+ "div",
95
+ {
96
+ ref: U,
97
+ onClick: S,
98
+ onMouseEnter: se,
99
+ onMouseLeave: Q,
100
+ className: `sc:group sc:relative sc:cursor-pointer sc:overflow-hidden ${k ? "sc:h-full sc:rounded-xs" : "sc:break-inside-avoid sc:rounded-lg"}`,
101
+ children: [
102
+ /* @__PURE__ */ e(
103
+ "img",
104
+ {
105
+ src: a.urls.small,
106
+ alt: a.alt || "Image",
107
+ className: `sc:duration-500 sc:ease-out ${T ? "sc:transition-none" : "sc:transition-transform"} ${k ? "sc:h-full sc:w-full sc:object-cover" : "sc:w-full sc:object-cover"}`,
108
+ style: {
109
+ transform: q(),
110
+ filter: u ? "brightness(1)" : "brightness(0.95)"
111
+ }
112
+ }
113
+ ),
114
+ /* @__PURE__ */ e("div", { className: "sc:absolute sc:top-2 sc:right-2 sc:z-10", children: /* @__PURE__ */ e(
115
+ "button",
116
+ {
117
+ className: `sc:relative sc:flex sc:h-6 sc:w-6 sc:items-center sc:justify-center sc:rounded-full sc:bg-black/30 sc:backdrop-blur-sm sc:transition-all sc:duration-300 sc:ease-in-out sc:hover:scale-110 ${ce ? "sc:opacity-100" : "sc:pointer-events-none sc:opacity-0"}`,
118
+ "aria-label": "Image info",
119
+ onMouseEnter: E,
120
+ onMouseLeave: te,
121
+ children: /* @__PURE__ */ e(p, { icon: "lucide:aperture", className: "sc:size-4 sc:text-white/80" })
122
+ }
123
+ ) }),
124
+ /* @__PURE__ */ e(
125
+ "div",
126
+ {
127
+ className: `sc:absolute sc:inset-x-0 sc:bottom-0 sc:z-0 sc:bg-linear-to-t sc:from-black/80 sc:via-black/60 sc:to-transparent sc:px-3 sc:py-3 sc:pt-8 sc:transition-transform sc:duration-300 sc:ease-out ${c ? "sc:translate-y-0" : "sc:translate-y-full"}`,
128
+ onMouseEnter: $,
129
+ onMouseLeave: _,
130
+ children: /* @__PURE__ */ t("div", { className: "sc:flex sc:flex-col sc:gap-1", children: [
131
+ /* @__PURE__ */ t("div", { className: "sc:flex sc:items-center sc:gap-2", children: [
132
+ /* @__PURE__ */ e(
133
+ p,
134
+ {
135
+ icon: a.source === "unsplash" ? "simple-icons:unsplash" : "simple-icons:pixabay",
136
+ className: "sc:size-3 sc:text-white/80"
137
+ }
138
+ ),
139
+ /* @__PURE__ */ e("span", { className: "sc:text-xs sc:font-medium sc:text-white/80", children: D })
140
+ ] }),
141
+ /* @__PURE__ */ t("div", { className: "sc:flex sc:flex-col sc:gap-0.5", children: [
142
+ /* @__PURE__ */ e("span", { className: "sc:text-xs sc:text-white/60", children: "Photo by" }),
143
+ /* @__PURE__ */ t("span", { className: "sc:text-sm sc:font-medium sc:text-white", children: [
144
+ a.attribution.profileUrl ? /* @__PURE__ */ e(
145
+ "a",
146
+ {
147
+ href: a.attribution.profileUrl,
148
+ target: "_blank",
149
+ rel: "noopener noreferrer",
150
+ onClick: (R) => R.stopPropagation(),
151
+ className: "sc:underline sc:decoration-white/40 sc:underline-offset-2 sc:hover:decoration-white",
152
+ children: a.attribution.name
153
+ }
154
+ ) : a.attribution.name,
155
+ a.attribution.sourceUrl && /* @__PURE__ */ t(le, { children: [
156
+ " ",
157
+ /* @__PURE__ */ e("span", { className: "sc:font-normal sc:text-white/60", children: "on" }),
158
+ " ",
159
+ /* @__PURE__ */ e(
160
+ "a",
161
+ {
162
+ href: a.attribution.sourceUrl,
163
+ target: "_blank",
164
+ rel: "noopener noreferrer",
165
+ onClick: (R) => R.stopPropagation(),
166
+ className: "sc:underline sc:decoration-white/40 sc:underline-offset-2 sc:hover:decoration-white",
167
+ children: D
168
+ }
169
+ )
170
+ ] })
171
+ ] })
172
+ ] })
173
+ ] })
174
+ }
175
+ )
176
+ ]
177
+ }
178
+ );
179
+ }), De = Be.memo(function({ vector: a, onVectorSelect: x, fixedHeight: k = !1 }) {
180
+ const [u, A] = r(!1), [c, g] = r(!1), o = M(null), i = M(null), b = () => {
181
+ c || x(a);
182
+ }, h = () => {
183
+ i.current && (clearTimeout(i.current), i.current = null), o.current = setTimeout(() => {
184
+ g(!0);
185
+ }, 400);
186
+ }, U = () => {
187
+ o.current && (clearTimeout(o.current), o.current = null), g(!1);
188
+ }, N = () => {
189
+ o.current && (clearTimeout(o.current), o.current = null), i.current && (clearTimeout(i.current), i.current = null);
190
+ }, T = () => {
191
+ g(!1);
192
+ }, v = u || c;
193
+ return /* @__PURE__ */ t(
194
+ "div",
195
+ {
196
+ onClick: b,
197
+ onMouseEnter: () => A(!0),
198
+ onMouseLeave: () => A(!1),
199
+ className: `sc:group sc:relative sc:cursor-pointer sc:overflow-hidden sc:bg-white/10 sc:transition-all sc:duration-300 ${k ? "sc:h-full sc:rounded-xs" : "sc:break-inside-avoid sc:rounded-lg"} ${u ? "sc:scale-105 sc:bg-white/20" : ""}`,
200
+ children: [
201
+ /* @__PURE__ */ e(
202
+ "div",
203
+ {
204
+ className: `sc:flex sc:items-center sc:justify-center sc:p-6 sc:transition-all sc:duration-300 ${k ? "sc:h-full sc:w-full" : "sc:aspect-square sc:w-full"}`,
205
+ children: /* @__PURE__ */ e(
206
+ "img",
207
+ {
208
+ src: a.urls.preview,
209
+ alt: a.term,
210
+ className: `sc:max-h-full sc:max-w-full sc:object-contain sc:transition-all sc:duration-300 ${u ? "sc:scale-110" : "sc:scale-100"}`,
211
+ style: {
212
+ filter: u ? "brightness(1.1)" : "brightness(0.95)"
213
+ }
214
+ }
215
+ )
216
+ }
217
+ ),
218
+ /* @__PURE__ */ t("div", { className: "sc:absolute sc:top-2 sc:right-2 sc:z-10 sc:flex sc:items-center sc:gap-2", children: [
219
+ !a.urls.svg && /* @__PURE__ */ e(
220
+ "span",
221
+ {
222
+ className: `sc:rounded-xs sc:bg-amber-500/90 sc:px-1.5 sc:py-0.5 sc:text-[10px] sc:font-semibold sc:uppercase sc:tracking-wide sc:text-white sc:shadow-sm sc:transition-all sc:duration-300 sc:ease-in-out ${v ? "sc:opacity-100" : "sc:pointer-events-none sc:opacity-0"}`,
223
+ children: "PNG"
224
+ }
225
+ ),
226
+ /* @__PURE__ */ e(
227
+ "button",
228
+ {
229
+ className: `sc:relative sc:flex sc:h-6 sc:w-6 sc:items-center sc:justify-center sc:rounded-full sc:bg-black/30 sc:backdrop-blur-sm sc:transition-all sc:duration-300 sc:ease-in-out sc:hover:scale-110 ${v ? "sc:opacity-100" : "sc:pointer-events-none sc:opacity-0"}`,
230
+ "aria-label": "Vector info",
231
+ onMouseEnter: h,
232
+ onMouseLeave: U,
233
+ children: /* @__PURE__ */ e(p, { icon: "lucide:aperture", className: "sc:size-4 sc:text-white/80" })
234
+ }
235
+ )
236
+ ] }),
237
+ /* @__PURE__ */ t(
238
+ "div",
239
+ {
240
+ className: `sc:absolute sc:inset-x-0 sc:bottom-0 sc:z-0 sc:bg-linear-to-t sc:from-black/80 sc:via-black/60 sc:to-transparent sc:px-3 sc:py-3 sc:pt-8 sc:transition-transform sc:duration-300 sc:ease-out ${c ? "sc:translate-y-0" : "sc:translate-y-full"}`,
241
+ onMouseEnter: N,
242
+ onMouseLeave: T,
243
+ children: [
244
+ /* @__PURE__ */ t("div", { className: "sc:mb-1", children: [
245
+ /* @__PURE__ */ e(p, { icon: "mdi:cube-outline", className: "sc:mr-2 sc:inline-block sc:size-3 sc:text-white/80" }),
246
+ /* @__PURE__ */ e("span", { className: "sc:text-xs sc:font-medium sc:text-white/80", children: "Noun Project" })
247
+ ] }),
248
+ /* @__PURE__ */ e("div", { className: "sc:text-xs sc:text-white/60", children: "Icon by" }),
249
+ /* @__PURE__ */ e("div", { className: "sc:text-sm sc:font-medium sc:text-white", children: a.uploader.name })
250
+ ]
251
+ }
252
+ )
253
+ ]
254
+ }
255
+ );
256
+ }), hs = ({
257
+ isOpen: d,
258
+ onToggle: a,
259
+ onImageSelect: x,
260
+ currentImageUrl: k,
261
+ placement: u = "bottom",
262
+ busy: A = !1
263
+ }) => {
264
+ const { imageSearch: c, generate: g, vectors: o, removeBackground: i } = je(), b = $e(
265
+ () => [
266
+ ...c ? ["search"] : [],
267
+ "url",
268
+ ...o ? ["vector"] : [],
269
+ ...g ? ["ai"] : []
270
+ ],
271
+ [c, o, g]
272
+ ), [h, U] = r(""), [N, T] = r(""), [v, w] = r([]), [S, Y] = r(!1), [se, Q] = r(null), [E, te] = r(b[0]), [$, _] = r(1), [D, ce] = r(!0), [q, R] = r("masonry"), [m, Z] = r(""), [z, y] = r([]), [L, P] = r(!1), [J, ae] = r(null), [j, be] = r(null), [K, ge] = r(!0), [re, ve] = r("grid"), [F, G] = r(""), [V, l] = r(!1), [O, de] = r(null), [H, he] = r(null), [B, ne] = r(!1), [oe, ee] = r(null), Ne = M(null), pe = M(null), Se = M(null);
273
+ ie(() => {
274
+ b.includes(E) || te(b[0]);
275
+ }, [b, E]), ie(() => {
276
+ d && k && (T(k), te("url"));
277
+ }, [d, k]), ie(() => {
278
+ d || (U(""), T(""), w([]), Q(null), _(1), ce(!0), Z(""), y([]), ae(null), be(null), ge(!0));
279
+ }, [d]);
280
+ const we = fe(
281
+ async (s, n, f) => {
282
+ if (c) {
283
+ Y(!0), Q(null);
284
+ try {
285
+ const I = await c.search({ query: s, page: n, perPage: 30 });
286
+ w((X) => f ? [...X, ...I.results] : I.results), _(I.page), ce(I.hasMore);
287
+ } catch (I) {
288
+ Q(us), xe.error("Error searching images:", I);
289
+ } finally {
290
+ Y(!1);
291
+ }
292
+ }
293
+ },
294
+ [c]
295
+ );
296
+ ie(() => {
297
+ d && !h && E === "search" && v.length === 0 && c && we("", 1, !1);
298
+ }, [d, E, c]);
299
+ const Fe = (s) => {
300
+ s.preventDefault(), we(h, 1, !1);
301
+ }, Le = fe(() => {
302
+ S || !D || we(h, $ + 1, !0);
303
+ }, [S, D, h, $, we]);
304
+ ie(() => {
305
+ const s = Ne.current;
306
+ if (!s || !d || E !== "search") return;
307
+ const n = new IntersectionObserver(
308
+ (f) => {
309
+ f[0].isIntersecting && D && !S && Le();
310
+ },
311
+ {
312
+ root: null,
313
+ // viewport
314
+ rootMargin: "200px",
315
+ // Trigger 200px before sentinel is visible
316
+ threshold: 0
317
+ }
318
+ );
319
+ return n.observe(s), () => {
320
+ n.disconnect();
321
+ };
322
+ }, [d, E, D, S, Le]);
323
+ const ye = fe(
324
+ async (s, n) => {
325
+ if (o) {
326
+ P(!0), ae(null);
327
+ try {
328
+ const { results: f, nextPage: I } = await o.search({ query: s, nextPage: n ?? null });
329
+ y(n ? (X) => {
330
+ const Ee = new Set(X.map((ue) => ue.id));
331
+ return [...X, ...f.filter((ue) => !Ee.has(ue.id))];
332
+ } : f), be(I), ge(I !== null);
333
+ } catch (f) {
334
+ ae(ms), xe.error("Error searching vectors:", f);
335
+ } finally {
336
+ P(!1);
337
+ }
338
+ }
339
+ },
340
+ [o]
341
+ );
342
+ ie(() => {
343
+ d && !m && E === "vector" && z.length === 0 && o && ye("");
344
+ }, [d, E, o]);
345
+ const Xe = (s) => {
346
+ s.preventDefault(), ye(m);
347
+ }, Me = fe(() => {
348
+ L || !K || !j || ye(m, j);
349
+ }, [L, K, j, m, ye]);
350
+ ie(() => {
351
+ const s = pe.current;
352
+ if (!s || !d || E !== "vector") return;
353
+ const n = new IntersectionObserver(
354
+ (f) => {
355
+ f[0].isIntersecting && K && !L && Me();
356
+ },
357
+ {
358
+ root: null,
359
+ rootMargin: "200px",
360
+ threshold: 0
361
+ }
362
+ );
363
+ return n.observe(s), () => {
364
+ n.disconnect();
365
+ };
366
+ }, [d, E, K, L, Me]);
367
+ const Ae = (s) => {
368
+ const n = s.selectUrl || s.urls.svg || s.urls.png;
369
+ n && (x(n), a(!1));
370
+ }, Te = (s) => {
371
+ var n;
372
+ try {
373
+ Promise.resolve((n = c == null ? void 0 : c.trackSelect) == null ? void 0 : n.call(c, s)).catch(() => {
374
+ });
375
+ } catch {
376
+ }
377
+ x(s.urls.regular), a(!1);
378
+ }, We = (s) => {
379
+ s.preventDefault(), N.trim() && (x(N.trim()), a(!1));
380
+ }, Ye = (s) => {
381
+ var f;
382
+ const n = (f = s.target.files) == null ? void 0 : f[0];
383
+ if (n && n.type.startsWith("image/")) {
384
+ const I = new FileReader();
385
+ I.onload = (X) => {
386
+ var ue;
387
+ const Ee = (ue = X.target) == null ? void 0 : ue.result;
388
+ T(Ee);
389
+ }, I.readAsDataURL(n);
390
+ }
391
+ }, Qe = () => {
392
+ var s;
393
+ (s = Se.current) == null || s.click();
394
+ }, qe = async () => {
395
+ if (!(!i || !N.trim())) {
396
+ ne(!0), ee(null);
397
+ try {
398
+ const s = await i(N);
399
+ T(s);
400
+ } catch (s) {
401
+ ee(Ve), xe.error("Error removing background:", s);
402
+ } finally {
403
+ ne(!1);
404
+ }
405
+ }
406
+ }, Ze = async (s) => {
407
+ var n, f;
408
+ if (s.preventDefault(), !!g) {
409
+ if (!F.trim()) {
410
+ de("Please enter a prompt");
411
+ return;
412
+ }
413
+ l(!0), de(null), he(null);
414
+ try {
415
+ const X = (f = (n = (await g.generate({
416
+ prompt: F,
417
+ width: 1024,
418
+ height: 1024,
419
+ numberResults: 1
420
+ })).images) == null ? void 0 : n[0]) == null ? void 0 : f.imageUrl;
421
+ if (!X)
422
+ throw new Error(Pe);
423
+ he(X);
424
+ } catch (I) {
425
+ de(fs(I, Pe)), xe.error("Error generating AI image:", I);
426
+ } finally {
427
+ l(!1);
428
+ }
429
+ }
430
+ }, Je = () => {
431
+ H && (x(H), a(!1));
432
+ }, Ke = async () => {
433
+ if (!(!i || !H)) {
434
+ ne(!0), ee(null);
435
+ try {
436
+ const s = await i(H);
437
+ he(s);
438
+ } catch (s) {
439
+ ee(Ve), xe.error("Error removing background:", s);
440
+ } finally {
441
+ ne(!1);
442
+ }
443
+ }
444
+ }, Oe = (s, n) => {
445
+ const f = s.width / s.height;
446
+ return n % 12 === 0 && f > 0.8 && f < 1.2 ? "sc:col-span-2 sc:row-span-2" : f < 0.75 ? "sc:row-span-2" : f > 1.5 ? "sc:col-span-2" : "";
447
+ };
448
+ return /* @__PURE__ */ t(
449
+ rs,
450
+ {
451
+ isOpen: d,
452
+ onClose: () => a(!1),
453
+ title: "Image Browser",
454
+ description: "Browse images or enter a custom image URL",
455
+ placement: u,
456
+ height: u === "bottom" ? "90vh" : void 0,
457
+ width: u !== "bottom" ? "500px" : void 0,
458
+ hideHandle: !0,
459
+ hideVisibleTitle: !0,
460
+ showCloseButton: !1,
461
+ "data-testid": "image-browser-drawer",
462
+ children: [
463
+ A && /* @__PURE__ */ t(
464
+ "div",
465
+ {
466
+ className: "sc:absolute sc:inset-0 sc:z-50 sc:flex sc:flex-col sc:items-center sc:justify-center sc:gap-3 sc:bg-background/70 sc:backdrop-blur-sm",
467
+ "data-testid": "image-browser-busy",
468
+ "aria-live": "polite",
469
+ children: [
470
+ /* @__PURE__ */ e("div", { className: "sc:size-8 sc:animate-spin sc:rounded-full sc:border-2 sc:border-divider sc:border-t-foreground" }),
471
+ /* @__PURE__ */ e("span", { className: "sc:text-foreground sc:text-sm", children: "Adding image…" })
472
+ ]
473
+ }
474
+ ),
475
+ /* @__PURE__ */ t(
476
+ C,
477
+ {
478
+ value: E,
479
+ onValueChange: (s) => te(s),
480
+ className: "sc:flex sc:flex-col",
481
+ "data-testid": "image-browser-container",
482
+ children: [
483
+ /* @__PURE__ */ e(C.ListContainer, { className: "sc:flex sc:justify-center sc:pt-4 sc:pb-2", children: /* @__PURE__ */ t(
484
+ C.List,
485
+ {
486
+ className: "sc:h-14 sc:gap-1 sc:px-1.5 sc:md:h-12",
487
+ "aria-label": "Image source",
488
+ children: [
489
+ c && /* @__PURE__ */ t(
490
+ C.Tab,
491
+ {
492
+ id: "search",
493
+ className: "sc:h-11 sc:w-14 sc:px-0 sc:md:h-9 sc:md:w-11",
494
+ "data-testid": "image-tab-search",
495
+ children: [
496
+ /* @__PURE__ */ e(p, { icon: me.image, className: "sc:size-6" }),
497
+ /* @__PURE__ */ e(C.Indicator, {})
498
+ ]
499
+ }
500
+ ),
501
+ /* @__PURE__ */ t(
502
+ C.Tab,
503
+ {
504
+ id: "url",
505
+ className: "sc:h-11 sc:w-14 sc:px-0 sc:md:h-9 sc:md:w-11",
506
+ "data-testid": "image-tab-url",
507
+ children: [
508
+ /* @__PURE__ */ e(p, { icon: me.link, className: "sc:size-6" }),
509
+ /* @__PURE__ */ e(C.Indicator, {})
510
+ ]
511
+ }
512
+ ),
513
+ o && /* @__PURE__ */ t(
514
+ C.Tab,
515
+ {
516
+ id: "vector",
517
+ className: "sc:h-11 sc:w-14 sc:px-0 sc:md:h-9 sc:md:w-11",
518
+ "data-testid": "image-tab-vector",
519
+ children: [
520
+ /* @__PURE__ */ e(p, { icon: "fa6-solid:icons", className: "sc:size-5" }),
521
+ /* @__PURE__ */ e(C.Indicator, {})
522
+ ]
523
+ }
524
+ ),
525
+ g && /* @__PURE__ */ t(
526
+ C.Tab,
527
+ {
528
+ id: "ai",
529
+ className: "sc:h-11 sc:w-14 sc:px-0 sc:md:h-9 sc:md:w-11",
530
+ "data-testid": "image-tab-ai",
531
+ children: [
532
+ /* @__PURE__ */ e(ze, { size: 24 }),
533
+ /* @__PURE__ */ e(C.Indicator, {})
534
+ ]
535
+ }
536
+ )
537
+ ]
538
+ }
539
+ ) }),
540
+ c && /* @__PURE__ */ t(C.Panel, { id: "search", className: "sc:flex sc:flex-col", children: [
541
+ /* @__PURE__ */ t("form", { onSubmit: Fe, className: "sc:sticky sc:top-0 sc:z-9 sc:flex sc:gap-2 sc:bg-surface sc:px-6 sc:pt-4 sc:pb-3", children: [
542
+ /* @__PURE__ */ e(Ie, { className: "sc:flex-1", "aria-label": "Search for images", children: /* @__PURE__ */ e(
543
+ Re,
544
+ {
545
+ type: "text",
546
+ placeholder: "Search for images...",
547
+ value: h,
548
+ onChange: (s) => U(s.target.value),
549
+ variant: "subtle",
550
+ "data-testid": "image-search-input"
551
+ }
552
+ ) }),
553
+ /* @__PURE__ */ e(W, { type: "submit", size: "icon", variant: "secondary", disabled: S, "aria-label": "Search", children: /* @__PURE__ */ e(p, { icon: me.search, className: "sc:size-5" }) }),
554
+ /* @__PURE__ */ e(
555
+ W,
556
+ {
557
+ size: "icon",
558
+ variant: "secondary",
559
+ onClick: () => R(q === "grid" ? "masonry" : "grid"),
560
+ "aria-label": q === "grid" ? "Switch to masonry view" : "Switch to grid view",
561
+ children: q === "grid" ? /* @__PURE__ */ e(p, { icon: "lucide:layout-grid", className: "sc:size-5" }) : /* @__PURE__ */ e(p, { icon: me.grip, className: "sc:size-5" })
562
+ }
563
+ )
564
+ ] }),
565
+ se && /* @__PURE__ */ e("div", { className: "sc:border-danger sc:bg-danger/10 sc:text-danger sc:mx-6 sc:mb-3 sc:rounded-2xl sc:border-2 sc:px-4 sc:py-3 sc:text-sm", children: se }),
566
+ S && v.length === 0 && /* @__PURE__ */ e("div", { className: "sc:text-muted sc:px-6 sc:py-8 sc:text-center sc:text-sm", children: "Loading images..." }),
567
+ v.length > 0 && /* @__PURE__ */ t("div", { className: "sc:mx-6 sc:overflow-hidden sc:rounded-t-2xl", children: [
568
+ q === "masonry" ? (
569
+ /* CSS Grid Masonry (Dense) */
570
+ /* @__PURE__ */ e(
571
+ "div",
572
+ {
573
+ className: "sc:grid sc:grid-flow-dense sc:pb-4",
574
+ style: {
575
+ display: "grid",
576
+ gridTemplateColumns: u === "bottom" ? "repeat(auto-fill, minmax(200px, 1fr))" : "repeat(3, 1fr)",
577
+ gridAutoRows: u === "bottom" ? "200px" : "120px",
578
+ gap: gs
579
+ },
580
+ children: v.map((s, n) => /* @__PURE__ */ e("div", { className: Oe(s, n), children: /* @__PURE__ */ e(Ue, { image: s, onImageSelect: Te, fixedHeight: !0 }) }, s.id))
581
+ }
582
+ )
583
+ ) : (
584
+ /* Fixed Height Grid - Square Tiles */
585
+ /* @__PURE__ */ e(
586
+ "div",
587
+ {
588
+ className: "sc:pb-4",
589
+ style: {
590
+ display: "grid",
591
+ gridTemplateColumns: u === "bottom" ? "repeat(auto-fill, minmax(150px, 1fr))" : "repeat(auto-fill, minmax(120px, 1fr))",
592
+ gap: Ce
593
+ },
594
+ children: v.map((s) => /* @__PURE__ */ e("div", { style: { aspectRatio: "1 / 1" }, children: /* @__PURE__ */ e(Ue, { image: s, onImageSelect: Te, fixedHeight: !0 }) }, s.id))
595
+ }
596
+ )
597
+ ),
598
+ D && /* @__PURE__ */ e("div", { ref: Ne, className: "sc:h-px" }),
599
+ S && /* @__PURE__ */ e("div", { className: "sc:text-muted sc:py-4 sc:text-center sc:text-sm", children: "Loading more..." }),
600
+ !D && !S && /* @__PURE__ */ e("div", { className: "sc:text-muted sc:py-6 sc:text-center sc:text-sm", children: "No more images" })
601
+ ] }),
602
+ !S && v.length === 0 && h && /* @__PURE__ */ t("div", { className: "sc:text-muted sc:px-6 sc:py-12 sc:text-center sc:text-sm", children: [
603
+ 'No images found for "',
604
+ h,
605
+ '"'
606
+ ] })
607
+ ] }),
608
+ /* @__PURE__ */ t(C.Panel, { id: "url", className: "sc:flex sc:flex-col sc:gap-5 sc:p-6", children: [
609
+ /* @__PURE__ */ e(
610
+ "input",
611
+ {
612
+ ref: Se,
613
+ type: "file",
614
+ accept: "image/*",
615
+ onChange: Ye,
616
+ className: "sc:hidden"
617
+ }
618
+ ),
619
+ /* @__PURE__ */ t(
620
+ "button",
621
+ {
622
+ type: "button",
623
+ onClick: Qe,
624
+ className: "sc:flex sc:flex-col sc:items-center sc:justify-center sc:gap-3 sc:rounded-2xl sc:border-2 sc:border-dashed sc:border-divider sc:bg-muted/30 sc:px-6 sc:py-10 sc:transition-colors sc:hover:bg-muted/50 sc:active:bg-muted/60",
625
+ "data-testid": "image-upload-btn",
626
+ children: [
627
+ /* @__PURE__ */ e(
628
+ p,
629
+ {
630
+ icon: "lucide:upload-cloud",
631
+ className: "sc:size-10 sc:text-foreground/60"
632
+ }
633
+ ),
634
+ /* @__PURE__ */ t("div", { className: "sc:flex sc:flex-col sc:items-center sc:gap-1", children: [
635
+ /* @__PURE__ */ e("span", { className: "sc:text-base sc:font-medium sc:text-foreground", children: "Upload from device" }),
636
+ /* @__PURE__ */ e("span", { className: "sc:text-xs sc:text-muted-foreground", children: "PNG · JPG · SVG · GIF" })
637
+ ] })
638
+ ]
639
+ }
640
+ ),
641
+ /* @__PURE__ */ t("div", { className: "sc:relative sc:flex sc:items-center sc:gap-3", children: [
642
+ /* @__PURE__ */ e("div", { className: "sc:h-px sc:flex-1 sc:bg-divider" }),
643
+ /* @__PURE__ */ e("span", { className: "sc:text-muted-foreground sc:text-xs sc:uppercase sc:tracking-wider", children: "or paste a link" }),
644
+ /* @__PURE__ */ e("div", { className: "sc:h-px sc:flex-1 sc:bg-divider" })
645
+ ] }),
646
+ /* @__PURE__ */ t(
647
+ "form",
648
+ {
649
+ onSubmit: We,
650
+ className: "sc:flex sc:flex-col sc:gap-3",
651
+ children: [
652
+ /* @__PURE__ */ t(Ie, { children: [
653
+ /* @__PURE__ */ e(ke, { className: "sc:sr-only", children: "Image URL" }),
654
+ /* @__PURE__ */ e(
655
+ Re,
656
+ {
657
+ type: "url",
658
+ placeholder: "https://example.com/image.jpg",
659
+ value: N,
660
+ onChange: (s) => T(s.target.value),
661
+ variant: "subtle",
662
+ "data-testid": "image-url-input"
663
+ }
664
+ )
665
+ ] }),
666
+ /* @__PURE__ */ e(
667
+ W,
668
+ {
669
+ type: "submit",
670
+ variant: "default",
671
+ disabled: !N.trim(),
672
+ className: "sc:w-full",
673
+ "data-testid": "image-url-submit-btn",
674
+ children: "Use This Image"
675
+ }
676
+ )
677
+ ]
678
+ }
679
+ ),
680
+ N.trim() && /* @__PURE__ */ t("div", { className: "sc:flex sc:flex-col sc:gap-3 sc:rounded-2xl sc:border sc:border-divider sc:bg-muted/30 sc:p-4", children: [
681
+ /* @__PURE__ */ t("div", { className: "sc:flex sc:items-center sc:justify-between sc:gap-3", children: [
682
+ /* @__PURE__ */ e("span", { className: "sc:text-xs sc:font-medium sc:uppercase sc:tracking-wider sc:text-muted-foreground", children: "Preview" }),
683
+ i && /* @__PURE__ */ e(
684
+ W,
685
+ {
686
+ onClick: qe,
687
+ disabled: B || !N.trim(),
688
+ variant: "secondary",
689
+ size: "sm",
690
+ className: "sc:gap-2",
691
+ "data-testid": "remove-background-btn",
692
+ children: B ? /* @__PURE__ */ t(le, { children: [
693
+ /* @__PURE__ */ e(
694
+ p,
695
+ {
696
+ icon: "eos-icons:loading",
697
+ className: "sc:size-4 sc:animate-spin"
698
+ }
699
+ ),
700
+ "Removing…"
701
+ ] }) : /* @__PURE__ */ t(le, { children: [
702
+ /* @__PURE__ */ e(p, { icon: "mdi:image-remove", className: "sc:size-4" }),
703
+ "Remove BG"
704
+ ] })
705
+ }
706
+ )
707
+ ] }),
708
+ oe && /* @__PURE__ */ e("div", { className: "sc:rounded-lg sc:border sc:border-danger sc:bg-danger/10 sc:px-3 sc:py-2 sc:text-xs sc:text-danger", children: oe }),
709
+ /* @__PURE__ */ e(
710
+ "img",
711
+ {
712
+ src: N,
713
+ alt: "Preview",
714
+ className: "sc:max-h-[280px] sc:w-full sc:rounded-lg sc:object-contain",
715
+ onError: (s) => {
716
+ s.target.style.display = "none";
717
+ },
718
+ onLoad: (s) => {
719
+ s.target.style.display = "block";
720
+ }
721
+ }
722
+ )
723
+ ] })
724
+ ] }),
725
+ o && /* @__PURE__ */ t(C.Panel, { id: "vector", className: "sc:flex sc:flex-col", children: [
726
+ /* @__PURE__ */ t("form", { onSubmit: Xe, className: "sc:sticky sc:top-0 sc:z-9 sc:flex sc:gap-2 sc:bg-surface sc:px-6 sc:pt-4 sc:pb-3", children: [
727
+ /* @__PURE__ */ e(Ie, { className: "sc:flex-1", "aria-label": "Search for vector graphics", children: /* @__PURE__ */ e(
728
+ Re,
729
+ {
730
+ type: "text",
731
+ placeholder: "Search for icons...",
732
+ value: m,
733
+ onChange: (s) => Z(s.target.value),
734
+ variant: "subtle",
735
+ "data-testid": "vector-search-input"
736
+ }
737
+ ) }),
738
+ /* @__PURE__ */ e(W, { type: "submit", size: "icon", variant: "secondary", disabled: L, "aria-label": "Search", children: /* @__PURE__ */ e(p, { icon: me.search, className: "sc:size-5" }) }),
739
+ /* @__PURE__ */ e(
740
+ W,
741
+ {
742
+ size: "icon",
743
+ variant: "secondary",
744
+ onClick: () => ve(re === "grid" ? "masonry" : "grid"),
745
+ "aria-label": re === "grid" ? "Switch to masonry view" : "Switch to grid view",
746
+ children: re === "grid" ? /* @__PURE__ */ e(p, { icon: "lucide:layout-grid", className: "sc:size-5" }) : /* @__PURE__ */ e(p, { icon: me.grip, className: "sc:size-5" })
747
+ }
748
+ )
749
+ ] }),
750
+ J && /* @__PURE__ */ e("div", { className: "sc:border-danger sc:bg-danger/10 sc:text-danger sc:mx-6 sc:mb-3 sc:rounded-2xl sc:border-2 sc:px-4 sc:py-3 sc:text-sm", children: J }),
751
+ L && z.length === 0 && /* @__PURE__ */ e("div", { className: "sc:text-muted sc:px-6 sc:py-8 sc:text-center sc:text-sm", children: "Loading vectors..." }),
752
+ z.length > 0 && /* @__PURE__ */ t("div", { className: "sc:mx-6 sc:overflow-hidden sc:rounded-t-2xl", children: [
753
+ re === "masonry" ? (
754
+ /* CSS Grid Masonry */
755
+ /* @__PURE__ */ e(
756
+ "div",
757
+ {
758
+ className: "sc:grid sc:grid-flow-dense sc:pb-4",
759
+ style: {
760
+ display: "grid",
761
+ gridTemplateColumns: u === "bottom" ? "repeat(auto-fill, minmax(150px, 1fr))" : "repeat(3, 1fr)",
762
+ gridAutoRows: u === "bottom" ? "150px" : "120px",
763
+ gap: Ce
764
+ },
765
+ children: z.map((s) => /* @__PURE__ */ e("div", { children: /* @__PURE__ */ e(De, { vector: s, onVectorSelect: Ae, fixedHeight: !0 }) }, s.id))
766
+ }
767
+ )
768
+ ) : (
769
+ /* Fixed Height Grid - Square Tiles */
770
+ /* @__PURE__ */ e(
771
+ "div",
772
+ {
773
+ className: "sc:pb-4",
774
+ style: {
775
+ display: "grid",
776
+ gridTemplateColumns: u === "bottom" ? "repeat(auto-fill, minmax(120px, 1fr))" : "repeat(auto-fill, minmax(100px, 1fr))",
777
+ gap: Ce
778
+ },
779
+ children: z.map((s) => /* @__PURE__ */ e("div", { style: { aspectRatio: "1 / 1" }, children: /* @__PURE__ */ e(De, { vector: s, onVectorSelect: Ae, fixedHeight: !0 }) }, s.id))
780
+ }
781
+ )
782
+ ),
783
+ K && /* @__PURE__ */ e("div", { ref: pe, className: "sc:h-px" }),
784
+ L && /* @__PURE__ */ e("div", { className: "sc:text-muted sc:py-4 sc:text-center sc:text-sm", children: "Loading more..." }),
785
+ !K && !L && /* @__PURE__ */ e("div", { className: "sc:text-muted sc:py-6 sc:text-center sc:text-sm", children: "No more vectors" })
786
+ ] }),
787
+ !L && z.length === 0 && m && /* @__PURE__ */ t("div", { className: "sc:text-muted sc:px-6 sc:py-12 sc:text-center sc:text-sm", children: [
788
+ 'No vectors found for "',
789
+ m,
790
+ '"'
791
+ ] })
792
+ ] }),
793
+ g && /* @__PURE__ */ t(C.Panel, { id: "ai", className: "sc:flex sc:flex-col sc:gap-6 sc:p-6", children: [
794
+ /* @__PURE__ */ t("form", { onSubmit: Ze, className: "sc:flex sc:flex-col sc:gap-6", children: [
795
+ /* @__PURE__ */ t(Ie, { children: [
796
+ /* @__PURE__ */ e(ke, { children: "Prompt" }),
797
+ /* @__PURE__ */ e(
798
+ _e,
799
+ {
800
+ placeholder: "Describe the image you want to generate... (e.g., 'avocado, transparent background')",
801
+ value: F,
802
+ onChange: (s) => G(s.target.value),
803
+ className: "sc:min-h-[100px] sc:resize-y",
804
+ rows: 4,
805
+ "data-testid": "ai-prompt-input",
806
+ disabled: V
807
+ }
808
+ )
809
+ ] }),
810
+ /* @__PURE__ */ e(
811
+ W,
812
+ {
813
+ type: "submit",
814
+ variant: "default",
815
+ disabled: !F.trim() || V,
816
+ className: "sc:w-full",
817
+ "data-testid": "ai-generate-btn",
818
+ children: V ? /* @__PURE__ */ t(le, { children: [
819
+ /* @__PURE__ */ e(p, { icon: "eos-icons:loading", className: "sc:size-5 sc:animate-spin" }),
820
+ "Generating..."
821
+ ] }) : /* @__PURE__ */ t(le, { children: [
822
+ /* @__PURE__ */ e(ze, { size: 24 }),
823
+ "Generate Image"
824
+ ] })
825
+ }
826
+ )
827
+ ] }),
828
+ O && /* @__PURE__ */ e("div", { className: "sc:border-danger sc:bg-danger/10 sc:text-danger sc:rounded-2xl sc:border-2 sc:px-4 sc:py-3 sc:text-sm", children: O }),
829
+ H && /* @__PURE__ */ t("div", { className: "sc:flex sc:flex-col sc:gap-4 sc:rounded-2xl sc:border sc:border-divider sc:bg-muted/40 sc:p-6", children: [
830
+ /* @__PURE__ */ e("div", { className: "sc:flex sc:items-center sc:justify-between", children: /* @__PURE__ */ e(ke, { className: "sc:text-muted sc:text-xs sc:uppercase sc:tracking-wide", children: "Generated Image" }) }),
831
+ /* @__PURE__ */ e("div", { className: "sc:flex sc:w-fit sc:items-center sc:justify-center sc:overflow-hidden sc:rounded-lg sc:bg-white/50 sc:dark:bg-black/50", style: { maxHeight: "500px", maxWidth: "100%" }, children: /* @__PURE__ */ e(
832
+ "img",
833
+ {
834
+ src: H,
835
+ alt: F,
836
+ className: "sc:max-h-full sc:max-w-full sc:object-contain"
837
+ }
838
+ ) }),
839
+ /* @__PURE__ */ t("div", { className: "sc:flex sc:flex-col sc:gap-1", children: [
840
+ /* @__PURE__ */ e(ke, { className: "sc:text-muted sc:text-xs", children: "Prompt" }),
841
+ /* @__PURE__ */ e("p", { className: "sc:text-sm", children: F })
842
+ ] }),
843
+ /* @__PURE__ */ t("div", { className: "sc:flex sc:flex-col sc:gap-3", children: [
844
+ i && /* @__PURE__ */ e(
845
+ W,
846
+ {
847
+ onClick: Ke,
848
+ disabled: B || !H,
849
+ variant: "secondary",
850
+ size: "sm",
851
+ className: "sc:w-full sc:gap-2",
852
+ "data-testid": "ai-remove-background-btn",
853
+ children: B ? /* @__PURE__ */ t(le, { children: [
854
+ /* @__PURE__ */ e(p, { icon: "eos-icons:loading", className: "sc:size-4 sc:animate-spin" }),
855
+ "Removing..."
856
+ ] }) : /* @__PURE__ */ t(le, { children: [
857
+ /* @__PURE__ */ e(p, { icon: "mdi:image-remove", className: "sc:size-4" }),
858
+ "Remove Background"
859
+ ] })
860
+ }
861
+ ),
862
+ oe && /* @__PURE__ */ e("div", { className: "sc:border-danger sc:bg-danger/10 sc:text-danger sc:rounded-xl sc:border-2 sc:px-3 sc:py-2 sc:text-xs", children: oe }),
863
+ /* @__PURE__ */ e(
864
+ W,
865
+ {
866
+ onClick: Je,
867
+ variant: "default",
868
+ className: "sc:w-full",
869
+ "data-testid": "ai-use-image-btn",
870
+ children: "Use This Image"
871
+ }
872
+ )
873
+ ] })
874
+ ] })
875
+ ] })
876
+ ]
877
+ }
878
+ )
879
+ ]
880
+ }
881
+ );
882
+ }, ps = Ge("ImagePanel"), ks = ({
883
+ isOpen: d,
884
+ onOpenChange: a,
885
+ onImageAdded: x,
886
+ onImageChanged: k,
887
+ changingElementId: u,
888
+ onChangingElementIdChange: A,
889
+ services: c
890
+ }) => {
891
+ var z;
892
+ const { elements: g, setElements: o, canvasEditorRef: i, artboardManager: b, executeAddElement: h, executeElementUpdate: U } = ss(), { selectedId: N, setSelectedId: T } = ts(), { activeArtboardId: v } = ns(), w = je(), S = $e(() => {
893
+ if (w.ingestImage) return w.ingestImage;
894
+ if (c != null && c.ingestImage) return c.ingestImage;
895
+ if (c != null && c.ingestImageUrl) return os(c.ingestImageUrl);
896
+ }, [w.ingestImage, c == null ? void 0 : c.ingestImage, c == null ? void 0 : c.ingestImageUrl]), Y = M(S);
897
+ Y.current = S;
898
+ const se = M(g);
899
+ se.current = g;
900
+ const Q = M(N);
901
+ Q.current = N;
902
+ const [E, te] = r(null), $ = u ?? E, _ = A ?? te, [D, ce] = r(!1), q = fe(
903
+ async (y) => {
904
+ var ve, F;
905
+ const L = Y.current;
906
+ if (L) {
907
+ ce(!0);
908
+ try {
909
+ y = await L(y);
910
+ } catch (G) {
911
+ ps.warn("Image ingest failed; placing the original URL", G);
912
+ } finally {
913
+ ce(!1);
914
+ }
915
+ }
916
+ const P = se.current, J = Q.current;
917
+ if ($) {
918
+ const G = P.find((V) => V.id === $);
919
+ if (G && ds(G)) {
920
+ const V = G, l = G.clone(), O = ((ve = i.current) == null ? void 0 : ve.getZoom()) || 1, de = V.transformData.width || 300 / O, H = V.transformData.height || 300 / O;
921
+ l.imageUrl = y, l.transformData.cropX = 0, l.transformData.cropY = 0, l.transformData.cropWidth = 1, l.transformData.cropHeight = 1, l.transformData.flipHorizontal = !1, l.transformData.flipVertical = !1, l.transformData.borderRadius = 0, l.imageLoaded = !1, l.imageElement = null, l.isCropping = !1, l.preserveDimensions = !1, l.transformData.width = de, l.transformData.height = H, l.onLoadCallback = (he) => {
922
+ const B = he, ne = B.transformData.width, oe = B.transformData.height, ee = Math.min(de / ne, H / oe, 1);
923
+ ee < 1 && (B.transformData.width = ne * ee, B.transformData.height = oe * ee), o((Ne) => Ne.map((pe) => pe.id === B.id ? B : pe));
924
+ }, l.loadImage(y), U(V, l), k && k(l);
925
+ }
926
+ _(null);
927
+ return;
928
+ }
929
+ if (!v) {
930
+ alert("Please create or select an artboard first");
931
+ return;
932
+ }
933
+ const ae = `element-${Date.now()}`, j = b.getActiveArtboard(), be = j ? j.x + j.width / 2 : window.innerWidth / 2, K = j ? j.y + j.height / 2 : window.innerHeight / 2, ge = ((F = i.current) == null ? void 0 : F.getZoom()) || 1, re = new ls({
934
+ id: ae,
935
+ x: be,
936
+ y: K,
937
+ imageUrl: y,
938
+ transformData: {
939
+ width: 300 / ge,
940
+ height: 300 / ge
941
+ },
942
+ onLoadCallback: (G) => {
943
+ const V = G;
944
+ o((l) => l.map((O) => O.id === V.id ? V : O));
945
+ }
946
+ });
947
+ b.addElementToArtboard(ae, v), h(re, v, J || void 0), T(ae), x && x(re);
948
+ },
949
+ [
950
+ $,
951
+ // Note: elements and selectedId are accessed via refs (elementsRef, selectedIdRef)
952
+ // to prevent callback recreation on every context update
953
+ b,
954
+ h,
955
+ U,
956
+ v,
957
+ i,
958
+ o,
959
+ T,
960
+ _,
961
+ x,
962
+ k
963
+ ]
964
+ ), R = fe(
965
+ (y) => {
966
+ a(y), y || _(null);
967
+ },
968
+ [a, _]
969
+ ), m = $ ? (z = g.find((y) => y.id === $)) == null ? void 0 : z.imageUrl : void 0, Z = /* @__PURE__ */ e(
970
+ hs,
971
+ {
972
+ isOpen: d,
973
+ onToggle: R,
974
+ onImageSelect: q,
975
+ currentImageUrl: m,
976
+ busy: D
977
+ }
978
+ );
979
+ return c ? /* @__PURE__ */ e(is, { services: c, children: Z }) : Z;
980
+ };
981
+ export {
982
+ ks as ImagePanel
983
+ };
984
+ //# sourceMappingURL=ImagePanel-Duh1AMdF.js.map