@varianta/sdk 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +6 -6
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1053 -902
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +6 -6
- package/dist/index.umd.js.map +1 -1
- package/dist/react.cjs.js +1 -1
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.esm.js +204 -185
- package/dist/react.esm.js.map +1 -1
- package/dist/types/react/Customizer.d.ts.map +1 -1
- package/dist/types/react/useCustomizer.d.ts +19 -3
- package/dist/types/react/useCustomizer.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +33 -1
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/vanilla/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/react.esm.js
CHANGED
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import { initCustomizer as
|
|
4
|
-
const
|
|
5
|
-
(
|
|
1
|
+
import { jsx as O } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as j, useRef as D, useEffect as p, useImperativeHandle as H, useState as l, useCallback as c } from "react";
|
|
3
|
+
import { initCustomizer as J } from "./index.esm.js";
|
|
4
|
+
const K = j(
|
|
5
|
+
(b, T) => {
|
|
6
6
|
const {
|
|
7
|
-
templateId:
|
|
8
|
-
productId:
|
|
9
|
-
apiUrl:
|
|
10
|
-
theme:
|
|
11
|
-
mode:
|
|
12
|
-
debug:
|
|
13
|
-
className:
|
|
14
|
-
style:
|
|
15
|
-
initialDesign:
|
|
16
|
-
showCloseButton:
|
|
17
|
-
showSaveButton:
|
|
18
|
-
onReady:
|
|
19
|
-
onChange:
|
|
20
|
-
onLayerSelect:
|
|
21
|
-
onLayerAdd:
|
|
22
|
-
onLayerRemove:
|
|
23
|
-
onLayerUpdate:
|
|
24
|
-
onError:
|
|
25
|
-
onFinalize:
|
|
26
|
-
onViewChange:
|
|
27
|
-
onClose:
|
|
28
|
-
onSave:
|
|
29
|
-
} =
|
|
30
|
-
onReady:
|
|
31
|
-
onChange:
|
|
32
|
-
onLayerSelect:
|
|
33
|
-
onLayerAdd:
|
|
34
|
-
onLayerRemove:
|
|
35
|
-
onLayerUpdate:
|
|
36
|
-
onError:
|
|
37
|
-
onFinalize:
|
|
38
|
-
onViewChange:
|
|
39
|
-
onClose:
|
|
40
|
-
onSave:
|
|
7
|
+
templateId: g,
|
|
8
|
+
productId: w,
|
|
9
|
+
apiUrl: r,
|
|
10
|
+
theme: s = "light",
|
|
11
|
+
mode: z = "edit",
|
|
12
|
+
debug: F = !1,
|
|
13
|
+
className: U,
|
|
14
|
+
style: k,
|
|
15
|
+
initialDesign: h,
|
|
16
|
+
showCloseButton: V,
|
|
17
|
+
showSaveButton: A,
|
|
18
|
+
onReady: d,
|
|
19
|
+
onChange: y,
|
|
20
|
+
onLayerSelect: f,
|
|
21
|
+
onLayerAdd: m,
|
|
22
|
+
onLayerRemove: E,
|
|
23
|
+
onLayerUpdate: L,
|
|
24
|
+
onError: R,
|
|
25
|
+
onFinalize: C,
|
|
26
|
+
onViewChange: a,
|
|
27
|
+
onClose: v,
|
|
28
|
+
onSave: S
|
|
29
|
+
} = b, I = D(null), e = D(null), i = D({
|
|
30
|
+
onReady: d,
|
|
31
|
+
onChange: y,
|
|
32
|
+
onLayerSelect: f,
|
|
33
|
+
onLayerAdd: m,
|
|
34
|
+
onLayerRemove: E,
|
|
35
|
+
onLayerUpdate: L,
|
|
36
|
+
onError: R,
|
|
37
|
+
onFinalize: C,
|
|
38
|
+
onViewChange: a,
|
|
39
|
+
onClose: v,
|
|
40
|
+
onSave: S
|
|
41
41
|
});
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
onReady:
|
|
45
|
-
onChange:
|
|
46
|
-
onLayerSelect:
|
|
47
|
-
onLayerAdd:
|
|
48
|
-
onLayerRemove:
|
|
49
|
-
onLayerUpdate:
|
|
50
|
-
onError:
|
|
51
|
-
onFinalize:
|
|
52
|
-
onViewChange:
|
|
53
|
-
onClose:
|
|
54
|
-
onSave:
|
|
42
|
+
return p(() => {
|
|
43
|
+
i.current = {
|
|
44
|
+
onReady: d,
|
|
45
|
+
onChange: y,
|
|
46
|
+
onLayerSelect: f,
|
|
47
|
+
onLayerAdd: m,
|
|
48
|
+
onLayerRemove: E,
|
|
49
|
+
onLayerUpdate: L,
|
|
50
|
+
onError: R,
|
|
51
|
+
onFinalize: C,
|
|
52
|
+
onViewChange: a,
|
|
53
|
+
onClose: v,
|
|
54
|
+
onSave: S
|
|
55
55
|
};
|
|
56
|
-
}, [
|
|
57
|
-
if (!
|
|
58
|
-
const
|
|
59
|
-
templateId:
|
|
60
|
-
productId:
|
|
61
|
-
apiUrl:
|
|
62
|
-
theme:
|
|
63
|
-
mode:
|
|
64
|
-
debug:
|
|
65
|
-
initialDesign:
|
|
66
|
-
showCloseButton:
|
|
67
|
-
showSaveButton:
|
|
56
|
+
}, [d, y, f, m, E, L, R, C, a, v, S]), p(() => {
|
|
57
|
+
if (!I.current) return;
|
|
58
|
+
const o = {
|
|
59
|
+
templateId: g,
|
|
60
|
+
productId: w,
|
|
61
|
+
apiUrl: r,
|
|
62
|
+
theme: s,
|
|
63
|
+
mode: z,
|
|
64
|
+
debug: F,
|
|
65
|
+
initialDesign: h,
|
|
66
|
+
showCloseButton: V,
|
|
67
|
+
showSaveButton: A,
|
|
68
68
|
// Use callback refs to always get latest callbacks
|
|
69
|
-
onReady: () =>
|
|
70
|
-
onChange: (t) =>
|
|
71
|
-
onLayerSelect: (t) =>
|
|
72
|
-
onLayerAdd: (t) =>
|
|
73
|
-
onLayerRemove: (t) =>
|
|
74
|
-
onLayerUpdate: (t) =>
|
|
75
|
-
onError: (t) =>
|
|
76
|
-
onFinalize: (t) =>
|
|
77
|
-
onViewChange: (t) =>
|
|
78
|
-
onClose: () =>
|
|
79
|
-
onSave: (t) =>
|
|
69
|
+
onReady: () => i.current.onReady?.(),
|
|
70
|
+
onChange: (t) => i.current.onChange?.(t),
|
|
71
|
+
onLayerSelect: (t) => i.current.onLayerSelect?.(t),
|
|
72
|
+
onLayerAdd: (t) => i.current.onLayerAdd?.(t),
|
|
73
|
+
onLayerRemove: (t) => i.current.onLayerRemove?.(t),
|
|
74
|
+
onLayerUpdate: (t) => i.current.onLayerUpdate?.(t),
|
|
75
|
+
onError: (t) => i.current.onError?.(t),
|
|
76
|
+
onFinalize: (t) => i.current.onFinalize?.(t),
|
|
77
|
+
onViewChange: (t) => i.current.onViewChange?.(t),
|
|
78
|
+
onClose: () => i.current.onClose?.(),
|
|
79
|
+
onSave: (t) => i.current.onSave?.(t)
|
|
80
80
|
};
|
|
81
81
|
try {
|
|
82
|
-
const t =
|
|
82
|
+
const t = J(I.current, o);
|
|
83
83
|
e.current = t;
|
|
84
84
|
} catch (t) {
|
|
85
|
-
console.error("[Customizer React] Failed to initialize:", t),
|
|
85
|
+
console.error("[Customizer React] Failed to initialize:", t), i.current.onError?.({
|
|
86
86
|
code: "INIT_ERROR",
|
|
87
87
|
message: t instanceof Error ? t.message : "Unknown error",
|
|
88
88
|
details: t
|
|
@@ -91,22 +91,22 @@ const M = b(
|
|
|
91
91
|
return () => {
|
|
92
92
|
e.current && (e.current.destroy(), e.current = null);
|
|
93
93
|
};
|
|
94
|
-
}, [
|
|
95
|
-
e.current && e.current.setTheme(
|
|
96
|
-
}, [
|
|
97
|
-
e.current && e.current.setMode(
|
|
98
|
-
}, [
|
|
99
|
-
|
|
94
|
+
}, [g, w, r, F, h, V, A]), p(() => {
|
|
95
|
+
e.current && e.current.setTheme(s);
|
|
96
|
+
}, [s]), p(() => {
|
|
97
|
+
e.current && e.current.setMode(z);
|
|
98
|
+
}, [z]), H(
|
|
99
|
+
T,
|
|
100
100
|
() => ({
|
|
101
101
|
getDesign: () => {
|
|
102
102
|
if (!e.current)
|
|
103
103
|
throw new Error("Editor not initialized");
|
|
104
104
|
return e.current.getDesign();
|
|
105
105
|
},
|
|
106
|
-
setDesign: (
|
|
106
|
+
setDesign: (o) => {
|
|
107
107
|
if (!e.current)
|
|
108
108
|
throw new Error("Editor not initialized");
|
|
109
|
-
e.current.setDesign(
|
|
109
|
+
e.current.setDesign(o);
|
|
110
110
|
},
|
|
111
111
|
undo: () => {
|
|
112
112
|
if (!e.current)
|
|
@@ -125,43 +125,48 @@ const M = b(
|
|
|
125
125
|
throw new Error("Editor not initialized");
|
|
126
126
|
return e.current.finalize();
|
|
127
127
|
},
|
|
128
|
-
|
|
128
|
+
waitForResult: async (o, t) => {
|
|
129
129
|
if (!e.current)
|
|
130
130
|
throw new Error("Editor not initialized");
|
|
131
|
-
e.current.
|
|
131
|
+
return e.current.waitForResult(o, t);
|
|
132
132
|
},
|
|
133
|
-
|
|
133
|
+
addTextLayer: (o) => {
|
|
134
134
|
if (!e.current)
|
|
135
135
|
throw new Error("Editor not initialized");
|
|
136
|
-
|
|
136
|
+
e.current.addTextLayer(o);
|
|
137
137
|
},
|
|
138
|
-
|
|
138
|
+
addImageLayer: async (o) => {
|
|
139
139
|
if (!e.current)
|
|
140
140
|
throw new Error("Editor not initialized");
|
|
141
|
-
e.current.
|
|
141
|
+
return e.current.addImageLayer(o);
|
|
142
142
|
},
|
|
143
|
-
|
|
143
|
+
removeLayer: (o) => {
|
|
144
144
|
if (!e.current)
|
|
145
145
|
throw new Error("Editor not initialized");
|
|
146
|
-
e.current.
|
|
146
|
+
e.current.removeLayer(o);
|
|
147
|
+
},
|
|
148
|
+
selectLayer: (o) => {
|
|
149
|
+
if (!e.current)
|
|
150
|
+
throw new Error("Editor not initialized");
|
|
151
|
+
e.current.selectLayer(o);
|
|
147
152
|
},
|
|
148
153
|
getSelectedLayerId: () => e.current ? e.current.getSelectedLayerId() : null,
|
|
149
154
|
getActiveView: () => e.current ? e.current.getActiveView() : null,
|
|
150
155
|
getViews: () => e.current ? e.current.getViews() : [],
|
|
151
|
-
setActiveView: (
|
|
156
|
+
setActiveView: (o) => {
|
|
152
157
|
if (!e.current)
|
|
153
158
|
throw new Error("Editor not initialized");
|
|
154
|
-
e.current.setActiveView(
|
|
159
|
+
e.current.setActiveView(o);
|
|
155
160
|
},
|
|
156
|
-
setTheme: (
|
|
161
|
+
setTheme: (o) => {
|
|
157
162
|
if (!e.current)
|
|
158
163
|
throw new Error("Editor not initialized");
|
|
159
|
-
e.current.setTheme(
|
|
164
|
+
e.current.setTheme(o);
|
|
160
165
|
},
|
|
161
|
-
setMode: (
|
|
166
|
+
setMode: (o) => {
|
|
162
167
|
if (!e.current)
|
|
163
168
|
throw new Error("Editor not initialized");
|
|
164
|
-
e.current.setMode(
|
|
169
|
+
e.current.setMode(o);
|
|
165
170
|
},
|
|
166
171
|
destroy: () => {
|
|
167
172
|
e.current && (e.current.destroy(), e.current = null);
|
|
@@ -174,130 +179,144 @@ const M = b(
|
|
|
174
179
|
}),
|
|
175
180
|
[]
|
|
176
181
|
// Empty deps is OK - we always read from instanceRef.current
|
|
177
|
-
), /* @__PURE__ */
|
|
182
|
+
), /* @__PURE__ */ O(
|
|
178
183
|
"div",
|
|
179
184
|
{
|
|
180
|
-
ref:
|
|
181
|
-
className:
|
|
185
|
+
ref: I,
|
|
186
|
+
className: U,
|
|
182
187
|
style: {
|
|
183
188
|
width: "100%",
|
|
184
189
|
height: "100%",
|
|
185
|
-
...
|
|
190
|
+
...k
|
|
186
191
|
}
|
|
187
192
|
}
|
|
188
193
|
);
|
|
189
194
|
}
|
|
190
195
|
);
|
|
191
|
-
|
|
192
|
-
function
|
|
196
|
+
K.displayName = "Customizer";
|
|
197
|
+
function P(b = {}) {
|
|
193
198
|
const {
|
|
194
|
-
autoSave:
|
|
195
|
-
autoSaveKey:
|
|
196
|
-
autoSaveDebounce:
|
|
197
|
-
} =
|
|
199
|
+
autoSave: T = !1,
|
|
200
|
+
autoSaveKey: g = "customizer-design",
|
|
201
|
+
autoSaveDebounce: w = 1e3
|
|
202
|
+
} = b, r = D(null), [s, z] = l(null), [F, U] = l(!1), [k, h] = l(!1), [V, A] = l(null), [d, y] = l(!1), [f, m] = l(!1), [E, L] = l(
|
|
198
203
|
null
|
|
199
|
-
),
|
|
200
|
-
|
|
201
|
-
if (!(!
|
|
202
|
-
return
|
|
204
|
+
), [R, C] = l(null), a = D(void 0);
|
|
205
|
+
p(() => {
|
|
206
|
+
if (!(!T || !s))
|
|
207
|
+
return a.current && clearTimeout(a.current), a.current = setTimeout(() => {
|
|
203
208
|
try {
|
|
204
|
-
localStorage.setItem(
|
|
205
|
-
} catch (
|
|
206
|
-
console.error("[useCustomizer] Auto-save failed:",
|
|
209
|
+
localStorage.setItem(g, JSON.stringify(s));
|
|
210
|
+
} catch (n) {
|
|
211
|
+
console.error("[useCustomizer] Auto-save failed:", n);
|
|
207
212
|
}
|
|
208
|
-
},
|
|
209
|
-
|
|
213
|
+
}, w), () => {
|
|
214
|
+
a.current && clearTimeout(a.current);
|
|
210
215
|
};
|
|
211
|
-
}, [
|
|
212
|
-
const
|
|
213
|
-
if (!
|
|
216
|
+
}, [s, T, g, w]);
|
|
217
|
+
const v = c(() => {
|
|
218
|
+
if (!r.current) return null;
|
|
214
219
|
try {
|
|
215
|
-
return
|
|
216
|
-
} catch (
|
|
217
|
-
return console.error("[useCustomizer] getDesign failed:",
|
|
220
|
+
return r.current.getDesign();
|
|
221
|
+
} catch (n) {
|
|
222
|
+
return console.error("[useCustomizer] getDesign failed:", n), null;
|
|
218
223
|
}
|
|
219
|
-
}, []),
|
|
220
|
-
if (
|
|
224
|
+
}, []), S = c((n) => {
|
|
225
|
+
if (r.current)
|
|
221
226
|
try {
|
|
222
|
-
|
|
223
|
-
} catch (
|
|
224
|
-
console.error("[useCustomizer] setDesign failed:",
|
|
227
|
+
r.current.setDesign(n), z(n);
|
|
228
|
+
} catch (u) {
|
|
229
|
+
console.error("[useCustomizer] setDesign failed:", u);
|
|
225
230
|
}
|
|
226
|
-
}, []),
|
|
227
|
-
if (
|
|
231
|
+
}, []), I = c(() => {
|
|
232
|
+
if (r.current)
|
|
228
233
|
try {
|
|
229
|
-
|
|
230
|
-
} catch (
|
|
231
|
-
console.error("[useCustomizer] undo failed:",
|
|
234
|
+
r.current.undo(), U(r.current.canUndo()), h(r.current.canRedo());
|
|
235
|
+
} catch (n) {
|
|
236
|
+
console.error("[useCustomizer] undo failed:", n);
|
|
232
237
|
}
|
|
233
|
-
}, []),
|
|
234
|
-
if (
|
|
238
|
+
}, []), e = c(() => {
|
|
239
|
+
if (r.current)
|
|
235
240
|
try {
|
|
236
|
-
|
|
237
|
-
} catch (
|
|
238
|
-
console.error("[useCustomizer] redo failed:",
|
|
241
|
+
r.current.redo(), U(r.current.canUndo()), h(r.current.canRedo());
|
|
242
|
+
} catch (n) {
|
|
243
|
+
console.error("[useCustomizer] redo failed:", n);
|
|
239
244
|
}
|
|
240
|
-
}, []),
|
|
241
|
-
if (!
|
|
242
|
-
|
|
245
|
+
}, []), i = c(async () => {
|
|
246
|
+
if (!r.current || d) return null;
|
|
247
|
+
y(!0);
|
|
243
248
|
try {
|
|
244
|
-
const
|
|
245
|
-
return
|
|
246
|
-
} catch (
|
|
247
|
-
return console.error("[useCustomizer] finalize failed:",
|
|
249
|
+
const n = await r.current.finalize();
|
|
250
|
+
return L(n), n;
|
|
251
|
+
} catch (n) {
|
|
252
|
+
return console.error("[useCustomizer] finalize failed:", n), null;
|
|
248
253
|
} finally {
|
|
249
|
-
|
|
254
|
+
y(!1);
|
|
250
255
|
}
|
|
251
|
-
}, [
|
|
252
|
-
if (
|
|
256
|
+
}, [d]), o = c(async (n, u) => {
|
|
257
|
+
if (!r.current || f) return null;
|
|
258
|
+
m(!0);
|
|
259
|
+
try {
|
|
260
|
+
const x = await r.current.waitForResult(n, u);
|
|
261
|
+
return C(x), x;
|
|
262
|
+
} catch (x) {
|
|
263
|
+
return console.error("[useCustomizer] waitForResult failed:", x), null;
|
|
264
|
+
} finally {
|
|
265
|
+
m(!1);
|
|
266
|
+
}
|
|
267
|
+
}, [f]), t = c((n) => {
|
|
268
|
+
if (r.current)
|
|
253
269
|
try {
|
|
254
|
-
|
|
255
|
-
} catch (
|
|
256
|
-
console.error("[useCustomizer] addTextLayer failed:",
|
|
270
|
+
r.current.addTextLayer(n);
|
|
271
|
+
} catch (u) {
|
|
272
|
+
console.error("[useCustomizer] addTextLayer failed:", u);
|
|
257
273
|
}
|
|
258
|
-
}, []),
|
|
259
|
-
if (
|
|
274
|
+
}, []), N = c(async (n) => {
|
|
275
|
+
if (r.current)
|
|
260
276
|
try {
|
|
261
|
-
await
|
|
262
|
-
} catch (
|
|
263
|
-
console.error("[useCustomizer] addImageLayer failed:",
|
|
277
|
+
await r.current.addImageLayer(n);
|
|
278
|
+
} catch (u) {
|
|
279
|
+
console.error("[useCustomizer] addImageLayer failed:", u);
|
|
264
280
|
}
|
|
265
|
-
}, []),
|
|
266
|
-
if (
|
|
281
|
+
}, []), M = c((n) => {
|
|
282
|
+
if (r.current)
|
|
267
283
|
try {
|
|
268
|
-
|
|
269
|
-
} catch (
|
|
270
|
-
console.error("[useCustomizer] removeLayer failed:",
|
|
284
|
+
r.current.removeLayer(n);
|
|
285
|
+
} catch (u) {
|
|
286
|
+
console.error("[useCustomizer] removeLayer failed:", u);
|
|
271
287
|
}
|
|
272
|
-
}, []),
|
|
273
|
-
if (
|
|
288
|
+
}, []), B = c((n) => {
|
|
289
|
+
if (r.current)
|
|
274
290
|
try {
|
|
275
|
-
|
|
276
|
-
} catch (
|
|
277
|
-
console.error("[useCustomizer] selectLayer failed:",
|
|
291
|
+
r.current.selectLayer(n), A(n);
|
|
292
|
+
} catch (u) {
|
|
293
|
+
console.error("[useCustomizer] selectLayer failed:", u);
|
|
278
294
|
}
|
|
279
295
|
}, []);
|
|
280
296
|
return {
|
|
281
|
-
customizerRef:
|
|
282
|
-
design:
|
|
283
|
-
canUndo:
|
|
284
|
-
canRedo:
|
|
285
|
-
selectedLayerId:
|
|
286
|
-
isFinalizing:
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
+
customizerRef: r,
|
|
298
|
+
design: s,
|
|
299
|
+
canUndo: F,
|
|
300
|
+
canRedo: k,
|
|
301
|
+
selectedLayerId: V,
|
|
302
|
+
isFinalizing: d,
|
|
303
|
+
isRendering: f,
|
|
304
|
+
finalizeResult: E,
|
|
305
|
+
renderResult: R,
|
|
306
|
+
getDesign: v,
|
|
307
|
+
setDesign: S,
|
|
308
|
+
undo: I,
|
|
309
|
+
redo: e,
|
|
310
|
+
finalize: i,
|
|
311
|
+
waitForResult: o,
|
|
312
|
+
addTextLayer: t,
|
|
313
|
+
addImageLayer: N,
|
|
314
|
+
removeLayer: M,
|
|
315
|
+
selectLayer: B
|
|
297
316
|
};
|
|
298
317
|
}
|
|
299
318
|
export {
|
|
300
|
-
|
|
301
|
-
|
|
319
|
+
K as Customizer,
|
|
320
|
+
P as useCustomizer
|
|
302
321
|
};
|
|
303
322
|
//# sourceMappingURL=react.esm.js.map
|
package/dist/react.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.esm.js","sources":["../src/react/Customizer.tsx","../src/react/useCustomizer.ts"],"sourcesContent":["/**\n * React wrapper for Customizer Editor\n * @packageDocumentation\n */\n\nimport {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n type CSSProperties,\n} from 'react';\nimport { initCustomizer } from '../vanilla';\nimport type {\n CustomizerOptions,\n CustomizerInstance,\n DesignJSON,\n FinalizeResult,\n CustomizerError,\n} from '../types';\n\n/**\n * Props for the Customizer React component\n */\nexport interface CustomizerProps {\n /**\n * Template ID to load. Required unless productId is provided.\n */\n templateId?: string;\n\n /**\n * Product ID to load (fetches all views/templates for the product).\n * Alternative to templateId. Exactly one of templateId or productId must be provided.\n */\n productId?: string;\n\n /**\n * API base URL for fetching templates and finalizing designs\n * @default 'https://api.varianta.io'\n */\n apiUrl?: string;\n\n /**\n * Visual theme\n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /**\n * Editor mode\n * @default 'edit'\n */\n mode?: 'edit' | 'preview';\n\n /**\n * Enable debug mode with additional logging\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom CSS class name\n */\n className?: string;\n\n /**\n * Custom inline styles\n */\n style?: CSSProperties;\n\n /**\n * Initial design data to load\n */\n initialDesign?: DesignJSON;\n\n /**\n * Called when the editor is ready\n */\n onReady?: () => void;\n\n /**\n * Called when the design changes\n */\n onChange?: (design: DesignJSON) => void;\n\n /**\n * Called when a layer is selected\n */\n onLayerSelect?: (layerId: string | null) => void;\n\n /**\n * Called when a layer is added\n */\n onLayerAdd?: (layerId: string) => void;\n\n /**\n * Called when a layer is removed\n */\n onLayerRemove?: (layerId: string) => void;\n\n /**\n * Called when a layer is updated\n */\n onLayerUpdate?: (layerId: string) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: CustomizerError) => void;\n\n /**\n * Called when finalization is complete\n */\n onFinalize?: (result: FinalizeResult) => void;\n\n /**\n * Called when the active view changes (only relevant when using productId)\n */\n onViewChange?: (viewName: string) => void;\n\n /**\n * Show the Close button in the toolbar\n * @default true\n */\n showCloseButton?: boolean;\n\n /**\n * Show the Save Customization button in the toolbar.\n * When false, the button never appears even when the design is dirty.\n * @default true\n */\n showSaveButton?: boolean;\n\n /**\n * Called when the Close button is clicked\n */\n onClose?: () => void;\n\n /**\n * Called when the Save button is clicked and finalization completes successfully\n */\n onSave?: (result: FinalizeResult) => void;\n}\n\n/**\n * Handle type exposed via ref\n */\nexport type CustomizerHandle = CustomizerInstance;\n\n/**\n * Customizer React Component\n *\n * @example\n * ```tsx\n * import { Customizer, CustomizerHandle } from '@varianta/sdk/react';\n * import { useRef } from 'react';\n *\n * function App() {\n * const customizerRef = useRef<CustomizerHandle>(null);\n *\n * const handleFinalize = async () => {\n * if (customizerRef.current) {\n * const result = await customizerRef.current.finalize();\n * console.log('Finalized:', result);\n * }\n * };\n *\n * return (\n * <div style={{ width: '100vw', height: '100vh' }}>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * theme=\"light\"\n * onChange={(design) => console.log('Design changed:', design)}\n * onReady={() => console.log('Editor ready!')}\n * />\n * <button onClick={handleFinalize}>Finalize Design</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const Customizer = forwardRef<CustomizerHandle, CustomizerProps>(\n (props, ref) => {\n const {\n templateId,\n productId,\n apiUrl,\n theme = 'light',\n mode = 'edit',\n debug = false,\n className,\n style,\n initialDesign,\n showCloseButton,\n showSaveButton,\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const instanceRef = useRef<CustomizerInstance | null>(null);\n\n // Store latest callbacks in a ref to avoid stale closures\n const callbacksRef = useRef({\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n });\n\n // Update callbacks ref whenever they change\n useEffect(() => {\n callbacksRef.current = {\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n };\n }, [onReady, onChange, onLayerSelect, onLayerAdd, onLayerRemove, onLayerUpdate, onError, onFinalize, onViewChange, onClose, onSave]);\n\n // Initialize the editor\n useEffect(() => {\n if (!containerRef.current) return;\n\n const options: CustomizerOptions = {\n templateId,\n productId,\n apiUrl,\n theme,\n mode,\n debug,\n initialDesign,\n showCloseButton,\n showSaveButton,\n // Use callback refs to always get latest callbacks\n onReady: () => callbacksRef.current.onReady?.(),\n onChange: (design) => callbacksRef.current.onChange?.(design),\n onLayerSelect: (layerId) => callbacksRef.current.onLayerSelect?.(layerId),\n onLayerAdd: (layerId) => callbacksRef.current.onLayerAdd?.(layerId),\n onLayerRemove: (layerId) => callbacksRef.current.onLayerRemove?.(layerId),\n onLayerUpdate: (layerId) => callbacksRef.current.onLayerUpdate?.(layerId),\n onError: (error) => callbacksRef.current.onError?.(error),\n onFinalize: (result) => callbacksRef.current.onFinalize?.(result),\n onViewChange: (viewName) => callbacksRef.current.onViewChange?.(viewName),\n onClose: () => callbacksRef.current.onClose?.(),\n onSave: (result) => callbacksRef.current.onSave?.(result),\n };\n\n try {\n const instance = initCustomizer(containerRef.current, options);\n instanceRef.current = instance;\n } catch (error) {\n console.error('[Customizer React] Failed to initialize:', error);\n callbacksRef.current.onError?.({\n code: 'INIT_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n });\n }\n\n // Cleanup\n return () => {\n if (instanceRef.current) {\n instanceRef.current.destroy();\n instanceRef.current = null;\n }\n };\n }, [templateId, productId, apiUrl, debug, initialDesign, showCloseButton, showSaveButton]); // Only re-initialize on structural changes\n\n // Update theme when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setTheme(theme);\n }\n }, [theme]);\n\n // Update mode when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setMode(mode);\n }\n }, [mode]);\n\n // Expose methods via ref\n useImperativeHandle(\n ref,\n () => {\n // Return API that always uses current instanceRef\n return {\n getDesign: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getDesign();\n },\n setDesign: (design: DesignJSON) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setDesign(design);\n },\n undo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.undo();\n },\n redo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.redo();\n },\n canUndo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canUndo();\n },\n canRedo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canRedo();\n },\n finalize: async () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.finalize();\n },\n addTextLayer: (text?: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.addTextLayer(text);\n },\n addImageLayer: async (url: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.addImageLayer(url);\n },\n removeLayer: (layerId: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.removeLayer(layerId);\n },\n selectLayer: (layerId: string | null) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.selectLayer(layerId);\n },\n getSelectedLayerId: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getSelectedLayerId();\n },\n getActiveView: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getActiveView();\n },\n getViews: () => {\n if (!instanceRef.current) return [];\n return instanceRef.current.getViews();\n },\n setActiveView: (viewName: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setActiveView(viewName);\n },\n setTheme: (newTheme: 'light' | 'dark') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setTheme(newTheme);\n },\n setMode: (newMode: 'edit' | 'preview') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setMode(newMode);\n },\n destroy: () => {\n if (!instanceRef.current) return;\n instanceRef.current.destroy();\n instanceRef.current = null;\n },\n getElement: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getElement();\n },\n };\n },\n [] // Empty deps is OK - we always read from instanceRef.current\n );\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n />\n );\n }\n);\n\nCustomizer.displayName = 'Customizer';\n","/**\n * React hook for controlling the customizer editor\n * @packageDocumentation\n */\n\nimport { useRef, useCallback, useState, useEffect } from 'react';\nimport type { CustomizerHandle } from './Customizer';\nimport type { DesignJSON, FinalizeResult } from '../types';\n\n/**\n * Options for the useCustomizer hook\n */\nexport interface UseCustomizerOptions {\n /**\n * Auto-save design to localStorage\n */\n autoSave?: boolean;\n\n /**\n * localStorage key for auto-save\n * @default 'customizer-design'\n */\n autoSaveKey?: string;\n\n /**\n * Debounce time for auto-save in ms\n * @default 1000\n */\n autoSaveDebounce?: number;\n}\n\n/**\n * Return type for useCustomizer hook\n */\nexport interface UseCustomizerReturn {\n /**\n * Ref to attach to the Customizer component\n */\n customizerRef: React.RefObject<CustomizerHandle | null>;\n\n /**\n * Current design state\n */\n design: DesignJSON | null;\n\n /**\n * Whether undo is available\n */\n canUndo: boolean;\n\n /**\n * Whether redo is available\n */\n canRedo: boolean;\n\n /**\n * Selected layer ID\n */\n selectedLayerId: string | null;\n\n /**\n * Whether finalization is in progress\n */\n isFinalizing: boolean;\n\n /**\n * Finalization result\n */\n finalizeResult: FinalizeResult | null;\n\n /**\n * Get the current design\n */\n getDesign: () => DesignJSON | null;\n\n /**\n * Set a new design\n */\n setDesign: (design: DesignJSON) => void;\n\n /**\n * Undo the last action\n */\n undo: () => void;\n\n /**\n * Redo the last undone action\n */\n redo: () => void;\n\n /**\n * Finalize the design\n */\n finalize: () => Promise<FinalizeResult | null>;\n\n /**\n * Add a text layer\n */\n addTextLayer: (text?: string) => void;\n\n /**\n * Add an image layer\n */\n addImageLayer: (url: string) => Promise<void>;\n\n /**\n * Remove a layer\n */\n removeLayer: (layerId: string) => void;\n\n /**\n * Select a layer\n */\n selectLayer: (layerId: string | null) => void;\n}\n\n/**\n * React hook for controlling the customizer editor\n *\n * @example\n * ```tsx\n * import { Customizer } from '@varianta/sdk/react';\n * import { useCustomizer } from '@varianta/sdk/react';\n *\n * function App() {\n * const {\n * customizerRef,\n * design,\n * canUndo,\n * canRedo,\n * undo,\n * redo,\n * finalize,\n * isFinalizing,\n * } = useCustomizer({ autoSave: true });\n *\n * return (\n * <>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * onChange={(d) => console.log('Changed:', d)}\n * />\n * <button onClick={undo} disabled={!canUndo}>Undo</button>\n * <button onClick={redo} disabled={!canRedo}>Redo</button>\n * <button onClick={finalize} disabled={isFinalizing}>\n * {isFinalizing ? 'Finalizing...' : 'Finalize'}\n * </button>\n * </>\n * );\n * }\n * ```\n */\nexport function useCustomizer(\n options: UseCustomizerOptions = {}\n): UseCustomizerReturn {\n const {\n autoSave = false,\n autoSaveKey = 'customizer-design',\n autoSaveDebounce = 1000,\n } = options;\n\n const customizerRef = useRef<CustomizerHandle>(null);\n const [design, setDesign] = useState<DesignJSON | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n const [selectedLayerId, setSelectedLayerId] = useState<string | null>(null);\n const [isFinalizing, setIsFinalizing] = useState(false);\n const [finalizeResult, setFinalizeResult] = useState<FinalizeResult | null>(\n null\n );\n\n const autoSaveTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n\n // Auto-save to localStorage\n useEffect(() => {\n if (!autoSave || !design) return;\n\n // Clear existing timeout\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n\n // Set new timeout\n autoSaveTimeoutRef.current = setTimeout(() => {\n try {\n localStorage.setItem(autoSaveKey, JSON.stringify(design));\n } catch (error) {\n console.error('[useCustomizer] Auto-save failed:', error);\n }\n }, autoSaveDebounce);\n\n return () => {\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n };\n }, [design, autoSave, autoSaveKey, autoSaveDebounce]);\n\n const getDesign = useCallback(() => {\n if (!customizerRef.current) return null;\n try {\n return customizerRef.current.getDesign();\n } catch (error) {\n console.error('[useCustomizer] getDesign failed:', error);\n return null;\n }\n }, []);\n\n const setDesignCallback = useCallback((newDesign: DesignJSON) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.setDesign(newDesign);\n setDesign(newDesign);\n } catch (error) {\n console.error('[useCustomizer] setDesign failed:', error);\n }\n }, []);\n\n const undo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.undo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] undo failed:', error);\n }\n }, []);\n\n const redo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.redo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] redo failed:', error);\n }\n }, []);\n\n const finalize = useCallback(async () => {\n if (!customizerRef.current || isFinalizing) return null;\n\n setIsFinalizing(true);\n try {\n const result = await customizerRef.current.finalize();\n setFinalizeResult(result);\n return result;\n } catch (error) {\n console.error('[useCustomizer] finalize failed:', error);\n return null;\n } finally {\n setIsFinalizing(false);\n }\n }, [isFinalizing]);\n\n const addTextLayer = useCallback((text?: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.addTextLayer(text);\n } catch (error) {\n console.error('[useCustomizer] addTextLayer failed:', error);\n }\n }, []);\n\n const addImageLayer = useCallback(async (url: string) => {\n if (!customizerRef.current) return;\n try {\n await customizerRef.current.addImageLayer(url);\n } catch (error) {\n console.error('[useCustomizer] addImageLayer failed:', error);\n }\n }, []);\n\n const removeLayer = useCallback((layerId: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.removeLayer(layerId);\n } catch (error) {\n console.error('[useCustomizer] removeLayer failed:', error);\n }\n }, []);\n\n const selectLayer = useCallback((layerId: string | null) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.selectLayer(layerId);\n setSelectedLayerId(layerId);\n } catch (error) {\n console.error('[useCustomizer] selectLayer failed:', error);\n }\n }, []);\n\n return {\n customizerRef,\n design,\n canUndo,\n canRedo,\n selectedLayerId,\n isFinalizing,\n finalizeResult,\n getDesign,\n setDesign: setDesignCallback,\n undo,\n redo,\n finalize,\n addTextLayer,\n addImageLayer,\n removeLayer,\n selectLayer,\n };\n}\n"],"names":["Customizer","forwardRef","props","ref","templateId","productId","apiUrl","theme","mode","debug","className","style","initialDesign","showCloseButton","showSaveButton","onReady","onChange","onLayerSelect","onLayerAdd","onLayerRemove","onLayerUpdate","onError","onFinalize","onViewChange","onClose","onSave","containerRef","useRef","instanceRef","callbacksRef","useEffect","options","design","layerId","error","result","viewName","instance","initCustomizer","useImperativeHandle","text","url","newTheme","newMode","jsx","useCustomizer","autoSave","autoSaveKey","autoSaveDebounce","customizerRef","setDesign","useState","canUndo","setCanUndo","canRedo","setCanRedo","selectedLayerId","setSelectedLayerId","isFinalizing","setIsFinalizing","finalizeResult","setFinalizeResult","autoSaveTimeoutRef","getDesign","useCallback","setDesignCallback","newDesign","undo","redo","finalize","addTextLayer","addImageLayer","removeLayer","selectLayer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.esm.js","sources":["../src/react/Customizer.tsx","../src/react/useCustomizer.ts"],"sourcesContent":["/**\n * React wrapper for Customizer Editor\n * @packageDocumentation\n */\n\nimport {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n type CSSProperties,\n} from 'react';\nimport { initCustomizer } from '../vanilla';\nimport type {\n CustomizerOptions,\n CustomizerInstance,\n DesignJSON,\n FinalizeResult,\n CustomizerError,\n} from '../types';\n\n/**\n * Props for the Customizer React component\n */\nexport interface CustomizerProps {\n /**\n * Template ID to load. Required unless productId is provided.\n */\n templateId?: string;\n\n /**\n * Product ID to load (fetches all views/templates for the product).\n * Alternative to templateId. Exactly one of templateId or productId must be provided.\n */\n productId?: string;\n\n /**\n * API base URL for fetching templates and finalizing designs\n * @default 'https://api.varianta.io'\n */\n apiUrl?: string;\n\n /**\n * Visual theme\n * @default 'light'\n */\n theme?: 'light' | 'dark';\n\n /**\n * Editor mode\n * @default 'edit'\n */\n mode?: 'edit' | 'preview';\n\n /**\n * Enable debug mode with additional logging\n * @default false\n */\n debug?: boolean;\n\n /**\n * Custom CSS class name\n */\n className?: string;\n\n /**\n * Custom inline styles\n */\n style?: CSSProperties;\n\n /**\n * Initial design data to load\n */\n initialDesign?: DesignJSON;\n\n /**\n * Called when the editor is ready\n */\n onReady?: () => void;\n\n /**\n * Called when the design changes\n */\n onChange?: (design: DesignJSON) => void;\n\n /**\n * Called when a layer is selected\n */\n onLayerSelect?: (layerId: string | null) => void;\n\n /**\n * Called when a layer is added\n */\n onLayerAdd?: (layerId: string) => void;\n\n /**\n * Called when a layer is removed\n */\n onLayerRemove?: (layerId: string) => void;\n\n /**\n * Called when a layer is updated\n */\n onLayerUpdate?: (layerId: string) => void;\n\n /**\n * Called when an error occurs\n */\n onError?: (error: CustomizerError) => void;\n\n /**\n * Called when finalization is complete\n */\n onFinalize?: (result: FinalizeResult) => void;\n\n /**\n * Called when the active view changes (only relevant when using productId)\n */\n onViewChange?: (viewName: string) => void;\n\n /**\n * Show the Close button in the toolbar\n * @default true\n */\n showCloseButton?: boolean;\n\n /**\n * Show the Save Customization button in the toolbar.\n * When false, the button never appears even when the design is dirty.\n * @default true\n */\n showSaveButton?: boolean;\n\n /**\n * Called when the Close button is clicked\n */\n onClose?: () => void;\n\n /**\n * Called when the Save button is clicked and finalization completes successfully\n */\n onSave?: (result: FinalizeResult) => void;\n}\n\n/**\n * Handle type exposed via ref\n */\nexport type CustomizerHandle = CustomizerInstance;\n\n/**\n * Customizer React Component\n *\n * @example\n * ```tsx\n * import { Customizer, CustomizerHandle } from '@varianta/sdk/react';\n * import { useRef } from 'react';\n *\n * function App() {\n * const customizerRef = useRef<CustomizerHandle>(null);\n *\n * const handleFinalize = async () => {\n * if (customizerRef.current) {\n * const result = await customizerRef.current.finalize();\n * console.log('Finalized:', result);\n * }\n * };\n *\n * return (\n * <div style={{ width: '100vw', height: '100vh' }}>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * theme=\"light\"\n * onChange={(design) => console.log('Design changed:', design)}\n * onReady={() => console.log('Editor ready!')}\n * />\n * <button onClick={handleFinalize}>Finalize Design</button>\n * </div>\n * );\n * }\n * ```\n */\nexport const Customizer = forwardRef<CustomizerHandle, CustomizerProps>(\n (props, ref) => {\n const {\n templateId,\n productId,\n apiUrl,\n theme = 'light',\n mode = 'edit',\n debug = false,\n className,\n style,\n initialDesign,\n showCloseButton,\n showSaveButton,\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const instanceRef = useRef<CustomizerInstance | null>(null);\n\n // Store latest callbacks in a ref to avoid stale closures\n const callbacksRef = useRef({\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n });\n\n // Update callbacks ref whenever they change\n useEffect(() => {\n callbacksRef.current = {\n onReady,\n onChange,\n onLayerSelect,\n onLayerAdd,\n onLayerRemove,\n onLayerUpdate,\n onError,\n onFinalize,\n onViewChange,\n onClose,\n onSave,\n };\n }, [onReady, onChange, onLayerSelect, onLayerAdd, onLayerRemove, onLayerUpdate, onError, onFinalize, onViewChange, onClose, onSave]);\n\n // Initialize the editor\n useEffect(() => {\n if (!containerRef.current) return;\n\n const options: CustomizerOptions = {\n templateId,\n productId,\n apiUrl,\n theme,\n mode,\n debug,\n initialDesign,\n showCloseButton,\n showSaveButton,\n // Use callback refs to always get latest callbacks\n onReady: () => callbacksRef.current.onReady?.(),\n onChange: (design) => callbacksRef.current.onChange?.(design),\n onLayerSelect: (layerId) => callbacksRef.current.onLayerSelect?.(layerId),\n onLayerAdd: (layerId) => callbacksRef.current.onLayerAdd?.(layerId),\n onLayerRemove: (layerId) => callbacksRef.current.onLayerRemove?.(layerId),\n onLayerUpdate: (layerId) => callbacksRef.current.onLayerUpdate?.(layerId),\n onError: (error) => callbacksRef.current.onError?.(error),\n onFinalize: (result) => callbacksRef.current.onFinalize?.(result),\n onViewChange: (viewName) => callbacksRef.current.onViewChange?.(viewName),\n onClose: () => callbacksRef.current.onClose?.(),\n onSave: (result) => callbacksRef.current.onSave?.(result),\n };\n\n try {\n const instance = initCustomizer(containerRef.current, options);\n instanceRef.current = instance;\n } catch (error) {\n console.error('[Customizer React] Failed to initialize:', error);\n callbacksRef.current.onError?.({\n code: 'INIT_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n });\n }\n\n // Cleanup\n return () => {\n if (instanceRef.current) {\n instanceRef.current.destroy();\n instanceRef.current = null;\n }\n };\n }, [templateId, productId, apiUrl, debug, initialDesign, showCloseButton, showSaveButton]); // Only re-initialize on structural changes\n\n // Update theme when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setTheme(theme);\n }\n }, [theme]);\n\n // Update mode when it changes\n useEffect(() => {\n if (instanceRef.current) {\n instanceRef.current.setMode(mode);\n }\n }, [mode]);\n\n // Expose methods via ref\n useImperativeHandle(\n ref,\n () => {\n // Return API that always uses current instanceRef\n return {\n getDesign: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getDesign();\n },\n setDesign: (design: DesignJSON) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setDesign(design);\n },\n undo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.undo();\n },\n redo: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.redo();\n },\n canUndo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canUndo();\n },\n canRedo: () => {\n if (!instanceRef.current) return false;\n return instanceRef.current.canRedo();\n },\n finalize: async () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.finalize();\n },\n waitForResult: async (designIds: string[], waitOptions?: {\n pollInterval?: number;\n maxPolls?: number;\n signal?: AbortSignal;\n }) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.waitForResult(designIds, waitOptions);\n },\n addTextLayer: (text?: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.addTextLayer(text);\n },\n addImageLayer: async (url: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.addImageLayer(url);\n },\n removeLayer: (layerId: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.removeLayer(layerId);\n },\n selectLayer: (layerId: string | null) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.selectLayer(layerId);\n },\n getSelectedLayerId: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getSelectedLayerId();\n },\n getActiveView: () => {\n if (!instanceRef.current) return null;\n return instanceRef.current.getActiveView();\n },\n getViews: () => {\n if (!instanceRef.current) return [];\n return instanceRef.current.getViews();\n },\n setActiveView: (viewName: string) => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setActiveView(viewName);\n },\n setTheme: (newTheme: 'light' | 'dark') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setTheme(newTheme);\n },\n setMode: (newMode: 'edit' | 'preview') => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n instanceRef.current.setMode(newMode);\n },\n destroy: () => {\n if (!instanceRef.current) return;\n instanceRef.current.destroy();\n instanceRef.current = null;\n },\n getElement: () => {\n if (!instanceRef.current) {\n throw new Error('Editor not initialized');\n }\n return instanceRef.current.getElement();\n },\n };\n },\n [] // Empty deps is OK - we always read from instanceRef.current\n );\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n width: '100%',\n height: '100%',\n ...style,\n }}\n />\n );\n }\n);\n\nCustomizer.displayName = 'Customizer';\n","/**\n * React hook for controlling the customizer editor\n * @packageDocumentation\n */\n\nimport { useRef, useCallback, useState, useEffect } from 'react';\nimport type { CustomizerHandle } from './Customizer';\nimport type { DesignJSON, FinalizeResult, RenderStatusResult } from '../types';\n\n/**\n * Options for the useCustomizer hook\n */\nexport interface UseCustomizerOptions {\n /**\n * Auto-save design to localStorage\n */\n autoSave?: boolean;\n\n /**\n * localStorage key for auto-save\n * @default 'customizer-design'\n */\n autoSaveKey?: string;\n\n /**\n * Debounce time for auto-save in ms\n * @default 1000\n */\n autoSaveDebounce?: number;\n}\n\n/**\n * Return type for useCustomizer hook\n */\nexport interface UseCustomizerReturn {\n /**\n * Ref to attach to the Customizer component\n */\n customizerRef: React.RefObject<CustomizerHandle | null>;\n\n /**\n * Current design state\n */\n design: DesignJSON | null;\n\n /**\n * Whether undo is available\n */\n canUndo: boolean;\n\n /**\n * Whether redo is available\n */\n canRedo: boolean;\n\n /**\n * Selected layer ID\n */\n selectedLayerId: string | null;\n\n /**\n * Whether finalization (API submission) is in progress\n */\n isFinalizing: boolean;\n\n /**\n * Whether the background render is in progress (after finalize returned)\n */\n isRendering: boolean;\n\n /**\n * Finalization result (from API submission)\n */\n finalizeResult: FinalizeResult | null;\n\n /**\n * Render result (from polling after finalize)\n */\n renderResult: RenderStatusResult | null;\n\n /**\n * Poll for render completion after finalize\n */\n waitForResult: (designIds: string[], options?: {\n pollInterval?: number;\n maxPolls?: number;\n signal?: AbortSignal;\n }) => Promise<RenderStatusResult | null>;\n\n /**\n * Get the current design\n */\n getDesign: () => DesignJSON | null;\n\n /**\n * Set a new design\n */\n setDesign: (design: DesignJSON) => void;\n\n /**\n * Undo the last action\n */\n undo: () => void;\n\n /**\n * Redo the last undone action\n */\n redo: () => void;\n\n /**\n * Finalize the design\n */\n finalize: () => Promise<FinalizeResult | null>;\n\n /**\n * Add a text layer\n */\n addTextLayer: (text?: string) => void;\n\n /**\n * Add an image layer\n */\n addImageLayer: (url: string) => Promise<void>;\n\n /**\n * Remove a layer\n */\n removeLayer: (layerId: string) => void;\n\n /**\n * Select a layer\n */\n selectLayer: (layerId: string | null) => void;\n}\n\n/**\n * React hook for controlling the customizer editor\n *\n * @example\n * ```tsx\n * import { Customizer } from '@varianta/sdk/react';\n * import { useCustomizer } from '@varianta/sdk/react';\n *\n * function App() {\n * const {\n * customizerRef,\n * design,\n * canUndo,\n * canRedo,\n * undo,\n * redo,\n * finalize,\n * isFinalizing,\n * } = useCustomizer({ autoSave: true });\n *\n * return (\n * <>\n * <Customizer\n * ref={customizerRef}\n * templateId=\"tshirt-001\"\n * onChange={(d) => console.log('Changed:', d)}\n * />\n * <button onClick={undo} disabled={!canUndo}>Undo</button>\n * <button onClick={redo} disabled={!canRedo}>Redo</button>\n * <button onClick={finalize} disabled={isFinalizing}>\n * {isFinalizing ? 'Finalizing...' : 'Finalize'}\n * </button>\n * </>\n * );\n * }\n * ```\n */\nexport function useCustomizer(\n options: UseCustomizerOptions = {}\n): UseCustomizerReturn {\n const {\n autoSave = false,\n autoSaveKey = 'customizer-design',\n autoSaveDebounce = 1000,\n } = options;\n\n const customizerRef = useRef<CustomizerHandle>(null);\n const [design, setDesign] = useState<DesignJSON | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n const [selectedLayerId, setSelectedLayerId] = useState<string | null>(null);\n const [isFinalizing, setIsFinalizing] = useState(false);\n const [isRendering, setIsRendering] = useState(false);\n const [finalizeResult, setFinalizeResult] = useState<FinalizeResult | null>(\n null\n );\n const [renderResult, setRenderResult] = useState<RenderStatusResult | null>(null);\n\n const autoSaveTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\n\n // Auto-save to localStorage\n useEffect(() => {\n if (!autoSave || !design) return;\n\n // Clear existing timeout\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n\n // Set new timeout\n autoSaveTimeoutRef.current = setTimeout(() => {\n try {\n localStorage.setItem(autoSaveKey, JSON.stringify(design));\n } catch (error) {\n console.error('[useCustomizer] Auto-save failed:', error);\n }\n }, autoSaveDebounce);\n\n return () => {\n if (autoSaveTimeoutRef.current) {\n clearTimeout(autoSaveTimeoutRef.current);\n }\n };\n }, [design, autoSave, autoSaveKey, autoSaveDebounce]);\n\n const getDesign = useCallback(() => {\n if (!customizerRef.current) return null;\n try {\n return customizerRef.current.getDesign();\n } catch (error) {\n console.error('[useCustomizer] getDesign failed:', error);\n return null;\n }\n }, []);\n\n const setDesignCallback = useCallback((newDesign: DesignJSON) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.setDesign(newDesign);\n setDesign(newDesign);\n } catch (error) {\n console.error('[useCustomizer] setDesign failed:', error);\n }\n }, []);\n\n const undo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.undo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] undo failed:', error);\n }\n }, []);\n\n const redo = useCallback(() => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.redo();\n setCanUndo(customizerRef.current.canUndo());\n setCanRedo(customizerRef.current.canRedo());\n } catch (error) {\n console.error('[useCustomizer] redo failed:', error);\n }\n }, []);\n\n const finalize = useCallback(async () => {\n if (!customizerRef.current || isFinalizing) return null;\n\n setIsFinalizing(true);\n try {\n const result = await customizerRef.current.finalize();\n setFinalizeResult(result);\n return result;\n } catch (error) {\n console.error('[useCustomizer] finalize failed:', error);\n return null;\n } finally {\n setIsFinalizing(false);\n }\n }, [isFinalizing]);\n\n const waitForResult = useCallback(async (\n designIds: string[],\n waitOptions?: { pollInterval?: number; maxPolls?: number; signal?: AbortSignal },\n ): Promise<RenderStatusResult | null> => {\n if (!customizerRef.current || isRendering) return null;\n\n setIsRendering(true);\n try {\n const result = await customizerRef.current.waitForResult(designIds, waitOptions);\n setRenderResult(result);\n return result;\n } catch (error) {\n console.error('[useCustomizer] waitForResult failed:', error);\n return null;\n } finally {\n setIsRendering(false);\n }\n }, [isRendering]);\n\n const addTextLayer = useCallback((text?: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.addTextLayer(text);\n } catch (error) {\n console.error('[useCustomizer] addTextLayer failed:', error);\n }\n }, []);\n\n const addImageLayer = useCallback(async (url: string) => {\n if (!customizerRef.current) return;\n try {\n await customizerRef.current.addImageLayer(url);\n } catch (error) {\n console.error('[useCustomizer] addImageLayer failed:', error);\n }\n }, []);\n\n const removeLayer = useCallback((layerId: string) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.removeLayer(layerId);\n } catch (error) {\n console.error('[useCustomizer] removeLayer failed:', error);\n }\n }, []);\n\n const selectLayer = useCallback((layerId: string | null) => {\n if (!customizerRef.current) return;\n try {\n customizerRef.current.selectLayer(layerId);\n setSelectedLayerId(layerId);\n } catch (error) {\n console.error('[useCustomizer] selectLayer failed:', error);\n }\n }, []);\n\n return {\n customizerRef,\n design,\n canUndo,\n canRedo,\n selectedLayerId,\n isFinalizing,\n isRendering,\n finalizeResult,\n renderResult,\n getDesign,\n setDesign: setDesignCallback,\n undo,\n redo,\n finalize,\n waitForResult,\n addTextLayer,\n addImageLayer,\n removeLayer,\n selectLayer,\n };\n}\n"],"names":["Customizer","forwardRef","props","ref","templateId","productId","apiUrl","theme","mode","debug","className","style","initialDesign","showCloseButton","showSaveButton","onReady","onChange","onLayerSelect","onLayerAdd","onLayerRemove","onLayerUpdate","onError","onFinalize","onViewChange","onClose","onSave","containerRef","useRef","instanceRef","callbacksRef","useEffect","options","design","layerId","error","result","viewName","instance","initCustomizer","useImperativeHandle","designIds","waitOptions","text","url","newTheme","newMode","jsx","useCustomizer","autoSave","autoSaveKey","autoSaveDebounce","customizerRef","setDesign","useState","canUndo","setCanUndo","canRedo","setCanRedo","selectedLayerId","setSelectedLayerId","isFinalizing","setIsFinalizing","isRendering","setIsRendering","finalizeResult","setFinalizeResult","renderResult","setRenderResult","autoSaveTimeoutRef","getDesign","useCallback","setDesignCallback","newDesign","undo","redo","finalize","waitForResult","addTextLayer","addImageLayer","removeLayer","selectLayer"],"mappings":"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"}
|