labellife-design-tool 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -1
- package/dist/lib/lib/index.js +103 -52
- package/dist/lib/wordpress.js +103 -52
- package/dist/types/CanvasEditor.d.ts.map +1 -1
- package/dist/types/context/CanvasStoreContext.d.ts +10 -0
- package/dist/types/context/CanvasStoreContext.d.ts.map +1 -0
- package/dist/types/lib/index.d.ts +1 -0
- package/dist/types/lib/index.d.ts.map +1 -1
- package/dist/types/types/Config.d.ts +3 -0
- package/dist/types/types/Config.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,7 +146,71 @@ interface CustomPanelDefinition {
|
|
|
146
146
|
|
|
147
147
|
#### Add Elements from a Custom Panel
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
**Option 1: Use the `useCanvasStore` hook (recommended)**
|
|
150
|
+
|
|
151
|
+
Any component inside `CanvasEditor` can access the store using the hook:
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
import { useCanvasStore } from 'labellife-design-tool';
|
|
155
|
+
|
|
156
|
+
const MyComponent = () => {
|
|
157
|
+
const store = useCanvasStore();
|
|
158
|
+
|
|
159
|
+
const handleAddImage = () => {
|
|
160
|
+
store.activePage.addElement({
|
|
161
|
+
type: "image",
|
|
162
|
+
src: "https://example.com/img.jpg",
|
|
163
|
+
x: 100,
|
|
164
|
+
y: 100,
|
|
165
|
+
width: 200,
|
|
166
|
+
height: 200,
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const handleLoadTemplate = async () => {
|
|
171
|
+
try {
|
|
172
|
+
const templateData = {
|
|
173
|
+
name: "My Template",
|
|
174
|
+
width: 800,
|
|
175
|
+
height: 600,
|
|
176
|
+
pages: [
|
|
177
|
+
{
|
|
178
|
+
id: "page-1",
|
|
179
|
+
name: "Page 1",
|
|
180
|
+
elements: [
|
|
181
|
+
{
|
|
182
|
+
type: "text",
|
|
183
|
+
text: "Hello World",
|
|
184
|
+
x: 100,
|
|
185
|
+
y: 100,
|
|
186
|
+
fontSize: 24,
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
await store.loadJSON(templateData);
|
|
194
|
+
console.log("Template loaded successfully!");
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.error("Failed to load template:", error);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<div style={{ color: "white", padding: 16 }}>
|
|
202
|
+
<p>Current page: {store.activePage.id}</p>
|
|
203
|
+
<p>Canvas size: {store.width} × {store.height}</p>
|
|
204
|
+
<button onClick={handleAddImage}>Add Image</button>
|
|
205
|
+
<button onClick={handleLoadTemplate}>Load Template</button>
|
|
206
|
+
</div>
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Option 2: Panel prop approach**
|
|
212
|
+
|
|
213
|
+
Every panel (built-in or custom) also receives a `store` prop with a Polotno-like API:
|
|
150
214
|
|
|
151
215
|
```tsx
|
|
152
216
|
// Your custom panel component
|
|
@@ -192,6 +256,7 @@ const MyImagesPanel = ({ store }) => {
|
|
|
192
256
|
```typescript
|
|
193
257
|
interface CanvasStore {
|
|
194
258
|
activePage: {
|
|
259
|
+
id: string;
|
|
195
260
|
addElement: (element: {
|
|
196
261
|
type: string;
|
|
197
262
|
src?: string;
|
|
@@ -204,6 +269,8 @@ interface CanvasStore {
|
|
|
204
269
|
width: number;
|
|
205
270
|
height: number;
|
|
206
271
|
openSidePanel: (panelId: string | null) => void;
|
|
272
|
+
deletePages: (pageIds: string[]) => void;
|
|
273
|
+
loadJSON: (jsonData: any) => Promise<void>;
|
|
207
274
|
}
|
|
208
275
|
```
|
|
209
276
|
|
|
@@ -216,12 +283,21 @@ const MyPanel = ({ store }) => {
|
|
|
216
283
|
const closeAllPanels = () => store.openSidePanel(null);
|
|
217
284
|
const tryOpenUnknown = () => store.openSidePanel("nonexistent"); // closes all panels
|
|
218
285
|
|
|
286
|
+
const deletePage1 = () => store.deletePages(["page-1"]);
|
|
287
|
+
const deleteMultiplePages = () => store.deletePages(["page-1", "page-2", "page-3"]);
|
|
288
|
+
|
|
219
289
|
return (
|
|
220
290
|
<div style={{ color: "white", padding: 16 }}>
|
|
291
|
+
<p>Current page ID: {store.activePage.id}</p>
|
|
292
|
+
<p>Canvas size: {store.width} × {store.height}</p>
|
|
293
|
+
|
|
221
294
|
<button onClick={openTextPanel}>Open Text Panel</button>
|
|
222
295
|
<button onClick={openCustomPanel}>Open Custom Panel</button>
|
|
223
296
|
<button onClick={closeAllPanels}>Close All Panels</button>
|
|
224
297
|
<button onClick={tryOpenUnknown}>Try Unknown Panel (closes all)</button>
|
|
298
|
+
|
|
299
|
+
<button onClick={deletePage1}>Delete Page 1</button>
|
|
300
|
+
<button onClick={deleteMultiplePages}>Delete Multiple Pages</button>
|
|
225
301
|
</div>
|
|
226
302
|
);
|
|
227
303
|
};
|
package/dist/lib/lib/index.js
CHANGED
|
@@ -23,7 +23,7 @@ function initJsxCompat() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// src/CanvasEditor.tsx
|
|
26
|
-
import
|
|
26
|
+
import React19, { useState as useState3, useRef as useRef5, useEffect as useEffect4, useMemo, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
|
|
27
27
|
import { Stage, Layer, Rect as Rect2 } from "react-konva";
|
|
28
28
|
import {
|
|
29
29
|
PlusCircle,
|
|
@@ -3091,6 +3091,17 @@ var TemplateInputModal = ({
|
|
|
3091
3091
|
};
|
|
3092
3092
|
var TemplateInputModal_default = TemplateInputModal;
|
|
3093
3093
|
|
|
3094
|
+
// src/context/CanvasStoreContext.tsx
|
|
3095
|
+
import { createContext, useContext } from "react";
|
|
3096
|
+
var CanvasStoreContext = createContext(null);
|
|
3097
|
+
var useCanvasStore = () => {
|
|
3098
|
+
const store = useContext(CanvasStoreContext);
|
|
3099
|
+
if (!store) {
|
|
3100
|
+
throw new Error("useCanvasStore must be used within a CanvasEditor component");
|
|
3101
|
+
}
|
|
3102
|
+
return store;
|
|
3103
|
+
};
|
|
3104
|
+
|
|
3094
3105
|
// src/CanvasEditor.tsx
|
|
3095
3106
|
var CanvasEditor = forwardRef(({
|
|
3096
3107
|
name,
|
|
@@ -3613,6 +3624,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3613
3624
|
};
|
|
3614
3625
|
const store = useMemo(() => ({
|
|
3615
3626
|
activePage: {
|
|
3627
|
+
id: currentPage.id,
|
|
3616
3628
|
addElement: (element) => {
|
|
3617
3629
|
const newElement = {
|
|
3618
3630
|
id: `element-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
@@ -3656,6 +3668,42 @@ var CanvasEditor = forwardRef(({
|
|
|
3656
3668
|
} else {
|
|
3657
3669
|
setActivePanelId(null);
|
|
3658
3670
|
}
|
|
3671
|
+
},
|
|
3672
|
+
deletePages: (pageIds) => {
|
|
3673
|
+
setDesign((prev) => {
|
|
3674
|
+
const remainingPages = prev.pages.filter((page) => !pageIds.includes(page.id));
|
|
3675
|
+
if (remainingPages.length === 0) {
|
|
3676
|
+
console.warn("Cannot delete all pages. At least one page must remain.");
|
|
3677
|
+
return prev;
|
|
3678
|
+
}
|
|
3679
|
+
const currentPageWasDeleted = pageIds.includes(currentPage.id);
|
|
3680
|
+
const newCurrentPageId = currentPageWasDeleted ? remainingPages[0].id : currentPage.id;
|
|
3681
|
+
if (currentPageWasDeleted) {
|
|
3682
|
+
setTimeout(() => {
|
|
3683
|
+
const newCurrentPage = remainingPages[0];
|
|
3684
|
+
}, 0);
|
|
3685
|
+
}
|
|
3686
|
+
return {
|
|
3687
|
+
...prev,
|
|
3688
|
+
pages: remainingPages,
|
|
3689
|
+
currentPageId: newCurrentPageId
|
|
3690
|
+
};
|
|
3691
|
+
});
|
|
3692
|
+
},
|
|
3693
|
+
loadJSON: async (jsonData) => {
|
|
3694
|
+
return new Promise((resolve, reject) => {
|
|
3695
|
+
importFromJSONData(jsonData, (loadedDesign) => {
|
|
3696
|
+
setDesign(loadedDesign);
|
|
3697
|
+
resolve();
|
|
3698
|
+
}, (errorMessage) => {
|
|
3699
|
+
console.error("Failed to load JSON:", errorMessage);
|
|
3700
|
+
reject(new Error(errorMessage));
|
|
3701
|
+
}, (inputs, onComplete) => {
|
|
3702
|
+
setPendingInputs(inputs);
|
|
3703
|
+
setShowInputModal(true);
|
|
3704
|
+
window.__pendingImportComplete = onComplete;
|
|
3705
|
+
});
|
|
3706
|
+
});
|
|
3659
3707
|
}
|
|
3660
3708
|
}), [currentPage.id, design.width, design.height, config, setActivePanelId]);
|
|
3661
3709
|
const panelConfigs = useMemo(() => {
|
|
@@ -3818,12 +3866,12 @@ var CanvasEditor = forwardRef(({
|
|
|
3818
3866
|
const DynamicPanelRenderer = () => {
|
|
3819
3867
|
const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
|
|
3820
3868
|
if (!activePanelConfig) {
|
|
3821
|
-
return /* @__PURE__ */
|
|
3869
|
+
return /* @__PURE__ */ React19.createElement("div", {
|
|
3822
3870
|
className: "text-white"
|
|
3823
3871
|
}, "Panel not found");
|
|
3824
3872
|
}
|
|
3825
3873
|
const PanelComponent = activePanelConfig.component;
|
|
3826
|
-
return /* @__PURE__ */
|
|
3874
|
+
return /* @__PURE__ */ React19.createElement(PanelComponent, {
|
|
3827
3875
|
...activePanelConfig.props
|
|
3828
3876
|
});
|
|
3829
3877
|
};
|
|
@@ -3876,9 +3924,11 @@ var CanvasEditor = forwardRef(({
|
|
|
3876
3924
|
setHistoryIndex(0);
|
|
3877
3925
|
}
|
|
3878
3926
|
}, []);
|
|
3879
|
-
return /* @__PURE__ */
|
|
3927
|
+
return /* @__PURE__ */ React19.createElement(CanvasStoreContext.Provider, {
|
|
3928
|
+
value: store
|
|
3929
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3880
3930
|
className: "h-screen flex flex-col bg-gray-900"
|
|
3881
|
-
}, /* @__PURE__ */
|
|
3931
|
+
}, /* @__PURE__ */ React19.createElement(Header_default, {
|
|
3882
3932
|
name,
|
|
3883
3933
|
zoom,
|
|
3884
3934
|
historyIndex,
|
|
@@ -3890,37 +3940,37 @@ var CanvasEditor = forwardRef(({
|
|
|
3890
3940
|
onZoomReset: () => setZoom(calculateFitToScreenZoom(design.width, design.height)),
|
|
3891
3941
|
onSetActivePanel: setActivePanelId,
|
|
3892
3942
|
navbarConfig: config?.navbar
|
|
3893
|
-
}), /* @__PURE__ */
|
|
3943
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3894
3944
|
className: "flex-1 flex overflow-hidden"
|
|
3895
|
-
}, /* @__PURE__ */
|
|
3945
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3896
3946
|
className: "w-80 bg-gray-800 border-r border-gray-700 flex"
|
|
3897
|
-
}, /* @__PURE__ */
|
|
3947
|
+
}, /* @__PURE__ */ React19.createElement(LeftMenu_default, {
|
|
3898
3948
|
tool,
|
|
3899
3949
|
activePanel: activePanelId,
|
|
3900
3950
|
onSetTool: setTool,
|
|
3901
3951
|
onSetActivePanel: setActivePanelId,
|
|
3902
3952
|
config
|
|
3903
|
-
}), /* @__PURE__ */
|
|
3953
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3904
3954
|
className: "flex-1 p-4 overflow-y-auto"
|
|
3905
|
-
}, /* @__PURE__ */
|
|
3955
|
+
}, /* @__PURE__ */ React19.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React19.createElement("div", {
|
|
3906
3956
|
className: "flex-1 bg-gray-700 overflow-hidden relative",
|
|
3907
3957
|
ref: containerRef
|
|
3908
|
-
}, /* @__PURE__ */
|
|
3958
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3909
3959
|
className: "absolute inset-0 flex items-center justify-center"
|
|
3910
|
-
}, /* @__PURE__ */
|
|
3960
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3911
3961
|
className: "bg-white shadow-2xl",
|
|
3912
3962
|
style: {
|
|
3913
3963
|
transform: `scale(${zoom})`,
|
|
3914
3964
|
transformOrigin: "center center"
|
|
3915
3965
|
}
|
|
3916
|
-
}, /* @__PURE__ */
|
|
3966
|
+
}, /* @__PURE__ */ React19.createElement(Stage, {
|
|
3917
3967
|
key: `canvas-${design.id || design.width}-${design.height}`,
|
|
3918
3968
|
ref: stageRef,
|
|
3919
3969
|
width: design.width,
|
|
3920
3970
|
height: design.height,
|
|
3921
3971
|
onClick: handleStageClick,
|
|
3922
3972
|
onTap: handleStageClick
|
|
3923
|
-
}, /* @__PURE__ */
|
|
3973
|
+
}, /* @__PURE__ */ React19.createElement(Layer, null, /* @__PURE__ */ React19.createElement(Rect2, {
|
|
3924
3974
|
x: 0,
|
|
3925
3975
|
y: 0,
|
|
3926
3976
|
width: design.width,
|
|
@@ -3931,7 +3981,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3931
3981
|
}), currentPage.elements.map((element) => {
|
|
3932
3982
|
switch (element.type) {
|
|
3933
3983
|
case "text":
|
|
3934
|
-
return
|
|
3984
|
+
return React19.createElement(EditableTextElement, {
|
|
3935
3985
|
key: element.id,
|
|
3936
3986
|
element,
|
|
3937
3987
|
isSelected: element.id === selectedId,
|
|
@@ -3942,7 +3992,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3942
3992
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3943
3993
|
});
|
|
3944
3994
|
case "image":
|
|
3945
|
-
return
|
|
3995
|
+
return React19.createElement(UrlImageElement, {
|
|
3946
3996
|
key: element.id,
|
|
3947
3997
|
element,
|
|
3948
3998
|
isSelected: element.id === selectedId,
|
|
@@ -3953,7 +4003,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3953
4003
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3954
4004
|
});
|
|
3955
4005
|
case "shape":
|
|
3956
|
-
return
|
|
4006
|
+
return React19.createElement(ShapeElement, {
|
|
3957
4007
|
key: element.id,
|
|
3958
4008
|
element,
|
|
3959
4009
|
isSelected: element.id === selectedId,
|
|
@@ -3966,27 +4016,27 @@ var CanvasEditor = forwardRef(({
|
|
|
3966
4016
|
default:
|
|
3967
4017
|
return null;
|
|
3968
4018
|
}
|
|
3969
|
-
}))))), config?.multiPage && /* @__PURE__ */
|
|
4019
|
+
}))))), config?.multiPage && /* @__PURE__ */ React19.createElement("div", {
|
|
3970
4020
|
className: "absolute bottom-4 left-4 flex items-center space-x-2"
|
|
3971
|
-
}, design.pages.map((page, index) => /* @__PURE__ */
|
|
4021
|
+
}, design.pages.map((page, index) => /* @__PURE__ */ React19.createElement("div", {
|
|
3972
4022
|
key: page.id,
|
|
3973
4023
|
className: "relative group"
|
|
3974
|
-
}, /* @__PURE__ */
|
|
4024
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
3975
4025
|
onClick: () => setCurrentPageId(page.id),
|
|
3976
4026
|
className: `px-3 py-1 rounded text-sm ${page.id === currentPageId ? "bg-blue-600 text-white" : "bg-gray-800 text-gray-300 hover:bg-gray-700"}`
|
|
3977
|
-
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */
|
|
4027
|
+
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React19.createElement("button", {
|
|
3978
4028
|
onClick: () => deletePage(page.id),
|
|
3979
4029
|
className: "absolute -top-1 -right-1 w-4 h-4 bg-red-500 text-white rounded-full flex items-center justify-center transition-opacity duration-200 hover:bg-red-600",
|
|
3980
4030
|
title: `Delete Page ${index + 1}`
|
|
3981
|
-
}, /* @__PURE__ */
|
|
4031
|
+
}, /* @__PURE__ */ React19.createElement(X2, {
|
|
3982
4032
|
className: "w-3 h-3"
|
|
3983
|
-
})))), /* @__PURE__ */
|
|
4033
|
+
})))), /* @__PURE__ */ React19.createElement("button", {
|
|
3984
4034
|
onClick: addPage,
|
|
3985
4035
|
className: "p-1 bg-gray-800 text-gray-300 rounded hover:bg-gray-700",
|
|
3986
4036
|
title: "Add Page"
|
|
3987
|
-
}, /* @__PURE__ */
|
|
4037
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
3988
4038
|
className: "w-4 h-4"
|
|
3989
|
-
})))), /* @__PURE__ */
|
|
4039
|
+
})))), /* @__PURE__ */ React19.createElement(RightSidebar_default, {
|
|
3990
4040
|
currentPageElements: currentPage.elements,
|
|
3991
4041
|
selectedElement,
|
|
3992
4042
|
selectedId,
|
|
@@ -3996,34 +4046,34 @@ var CanvasEditor = forwardRef(({
|
|
|
3996
4046
|
onMoveElementUp: moveElementUp,
|
|
3997
4047
|
onMoveElementDown: moveElementDown,
|
|
3998
4048
|
onDeleteSelected: deleteSelected
|
|
3999
|
-
})), /* @__PURE__ */
|
|
4049
|
+
})), /* @__PURE__ */ React19.createElement("input", {
|
|
4000
4050
|
ref: fileInputRef,
|
|
4001
4051
|
type: "file",
|
|
4002
4052
|
accept: "image/*",
|
|
4003
4053
|
onChange: handleImageUpload,
|
|
4004
4054
|
className: "hidden",
|
|
4005
4055
|
multiple: true
|
|
4006
|
-
}), /* @__PURE__ */
|
|
4056
|
+
}), /* @__PURE__ */ React19.createElement("input", {
|
|
4007
4057
|
ref: jsonInputRef,
|
|
4008
4058
|
type: "file",
|
|
4009
4059
|
accept: ".json",
|
|
4010
4060
|
onChange: handleImportJSON,
|
|
4011
4061
|
className: "hidden"
|
|
4012
|
-
}), showInputModal && /* @__PURE__ */
|
|
4062
|
+
}), showInputModal && /* @__PURE__ */ React19.createElement(TemplateInputModal_default, {
|
|
4013
4063
|
inputs: pendingInputs,
|
|
4014
4064
|
onComplete: handleInputModalComplete,
|
|
4015
4065
|
onCancel: handleInputModalCancel
|
|
4016
|
-
}), showUnsplash && /* @__PURE__ */
|
|
4066
|
+
}), showUnsplash && /* @__PURE__ */ React19.createElement("div", {
|
|
4017
4067
|
className: "fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-8"
|
|
4018
|
-
}, /* @__PURE__ */
|
|
4068
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4019
4069
|
className: "bg-gray-800 rounded-lg w-full max-w-4xl max-h-full overflow-hidden flex flex-col"
|
|
4020
|
-
}, /* @__PURE__ */
|
|
4070
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4021
4071
|
className: "p-6 border-b border-gray-700"
|
|
4022
|
-
}, /* @__PURE__ */
|
|
4072
|
+
}, /* @__PURE__ */ React19.createElement("h3", {
|
|
4023
4073
|
className: "text-xl font-semibold text-white mb-4"
|
|
4024
|
-
}, "Search Unsplash"), /* @__PURE__ */
|
|
4074
|
+
}, "Search Unsplash"), /* @__PURE__ */ React19.createElement("div", {
|
|
4025
4075
|
className: "flex space-x-4"
|
|
4026
|
-
}, /* @__PURE__ */
|
|
4076
|
+
}, /* @__PURE__ */ React19.createElement("input", {
|
|
4027
4077
|
type: "text",
|
|
4028
4078
|
value: unsplashQuery,
|
|
4029
4079
|
onChange: (e) => setUnsplashQuery(e.target.value),
|
|
@@ -4031,64 +4081,65 @@ var CanvasEditor = forwardRef(({
|
|
|
4031
4081
|
placeholder: "Search for images...",
|
|
4032
4082
|
className: "flex-1 bg-gray-700 text-white border border-gray-600 rounded px-4 py-2 focus:border-blue-500 focus:outline-none",
|
|
4033
4083
|
autoFocus: true
|
|
4034
|
-
}), /* @__PURE__ */
|
|
4084
|
+
}), /* @__PURE__ */ React19.createElement("button", {
|
|
4035
4085
|
onClick: searchUnsplash,
|
|
4036
4086
|
className: "px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
|
4037
|
-
}, "Search"), /* @__PURE__ */
|
|
4087
|
+
}, "Search"), /* @__PURE__ */ React19.createElement("button", {
|
|
4038
4088
|
onClick: () => {
|
|
4039
4089
|
setShowUnsplash(false);
|
|
4040
4090
|
setUnsplashQuery("");
|
|
4041
4091
|
setUnsplashResults([]);
|
|
4042
4092
|
},
|
|
4043
4093
|
className: "px-6 py-2 bg-gray-700 text-white rounded hover:bg-gray-600"
|
|
4044
|
-
}, "Cancel"))), /* @__PURE__ */
|
|
4094
|
+
}, "Cancel"))), /* @__PURE__ */ React19.createElement("div", {
|
|
4045
4095
|
className: "flex-1 overflow-y-auto p-6"
|
|
4046
|
-
}, unsplashResults.length > 0 ? /* @__PURE__ */
|
|
4096
|
+
}, unsplashResults.length > 0 ? /* @__PURE__ */ React19.createElement("div", {
|
|
4047
4097
|
className: "grid grid-cols-3 gap-4"
|
|
4048
|
-
}, unsplashResults.map((result) => /* @__PURE__ */
|
|
4098
|
+
}, unsplashResults.map((result) => /* @__PURE__ */ React19.createElement("button", {
|
|
4049
4099
|
key: result.id,
|
|
4050
4100
|
onClick: () => addUnsplashImage(result.urls.regular),
|
|
4051
4101
|
className: "relative group overflow-hidden rounded-lg aspect-square"
|
|
4052
|
-
}, /* @__PURE__ */
|
|
4102
|
+
}, /* @__PURE__ */ React19.createElement("img", {
|
|
4053
4103
|
src: result.urls.thumb,
|
|
4054
4104
|
alt: "",
|
|
4055
4105
|
className: "w-full h-full object-cover group-hover:scale-110 transition-transform duration-200"
|
|
4056
|
-
}), /* @__PURE__ */
|
|
4106
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4057
4107
|
className: "absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-50 transition-opacity duration-200 flex items-center justify-center"
|
|
4058
|
-
}, /* @__PURE__ */
|
|
4108
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
4059
4109
|
className: "w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
|
|
4060
|
-
}))))) : /* @__PURE__ */
|
|
4110
|
+
}))))) : /* @__PURE__ */ React19.createElement("div", {
|
|
4061
4111
|
className: "text-center text-gray-400 py-12"
|
|
4062
|
-
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */
|
|
4112
|
+
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React19.createElement("div", {
|
|
4063
4113
|
className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
|
|
4064
|
-
}, /* @__PURE__ */
|
|
4114
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4065
4115
|
className: "bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-auto"
|
|
4066
|
-
}, /* @__PURE__ */
|
|
4116
|
+
}, /* @__PURE__ */ React19.createElement("h2", {
|
|
4067
4117
|
className: "text-white text-xl font-semibold mb-4"
|
|
4068
|
-
}, "Load JSON Data"), /* @__PURE__ */
|
|
4118
|
+
}, "Load JSON Data"), /* @__PURE__ */ React19.createElement("p", {
|
|
4069
4119
|
className: "text-gray-300 mb-4"
|
|
4070
|
-
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */
|
|
4120
|
+
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React19.createElement("textarea", {
|
|
4071
4121
|
value: jsonInputText,
|
|
4072
4122
|
onChange: (e) => setJsonInputText(e.target.value),
|
|
4073
4123
|
className: "w-full h-64 p-3 bg-gray-700 text-white border border-gray-600 rounded font-mono text-sm resize-none",
|
|
4074
4124
|
placeholder: '{"width": 800, "height": 600, "pages": [...]}'
|
|
4075
|
-
}), /* @__PURE__ */
|
|
4125
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4076
4126
|
className: "flex justify-end space-x-3 mt-4"
|
|
4077
|
-
}, /* @__PURE__ */
|
|
4127
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
4078
4128
|
onClick: () => {
|
|
4079
4129
|
setShowJsonModal(false);
|
|
4080
4130
|
setJsonInputText("");
|
|
4081
4131
|
},
|
|
4082
4132
|
className: "px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
|
|
4083
|
-
}, "Cancel"), /* @__PURE__ */
|
|
4133
|
+
}, "Cancel"), /* @__PURE__ */ React19.createElement("button", {
|
|
4084
4134
|
onClick: handleImportJSONData,
|
|
4085
4135
|
className: "px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
|
|
4086
|
-
}, "Load JSON")))));
|
|
4136
|
+
}, "Load JSON"))))));
|
|
4087
4137
|
});
|
|
4088
4138
|
var CanvasEditor_default = CanvasEditor;
|
|
4089
4139
|
// src/lib/index.ts
|
|
4090
4140
|
initJsxCompat();
|
|
4091
4141
|
export {
|
|
4142
|
+
useCanvasStore,
|
|
4092
4143
|
setUnsplashAccessKey,
|
|
4093
4144
|
replaceUserInputs,
|
|
4094
4145
|
loadTemplateFromJSON,
|
package/dist/lib/wordpress.js
CHANGED
|
@@ -23,7 +23,7 @@ function initJsxCompat() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// src/CanvasEditor.tsx
|
|
26
|
-
import
|
|
26
|
+
import React19, { useState as useState3, useRef as useRef5, useEffect as useEffect4, useMemo, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
|
|
27
27
|
import { Stage, Layer, Rect as Rect2 } from "react-konva";
|
|
28
28
|
import {
|
|
29
29
|
PlusCircle,
|
|
@@ -3091,6 +3091,17 @@ var TemplateInputModal = ({
|
|
|
3091
3091
|
};
|
|
3092
3092
|
var TemplateInputModal_default = TemplateInputModal;
|
|
3093
3093
|
|
|
3094
|
+
// src/context/CanvasStoreContext.tsx
|
|
3095
|
+
import { createContext, useContext } from "react";
|
|
3096
|
+
var CanvasStoreContext = createContext(null);
|
|
3097
|
+
var useCanvasStore = () => {
|
|
3098
|
+
const store = useContext(CanvasStoreContext);
|
|
3099
|
+
if (!store) {
|
|
3100
|
+
throw new Error("useCanvasStore must be used within a CanvasEditor component");
|
|
3101
|
+
}
|
|
3102
|
+
return store;
|
|
3103
|
+
};
|
|
3104
|
+
|
|
3094
3105
|
// src/CanvasEditor.tsx
|
|
3095
3106
|
var CanvasEditor = forwardRef(({
|
|
3096
3107
|
name,
|
|
@@ -3613,6 +3624,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3613
3624
|
};
|
|
3614
3625
|
const store = useMemo(() => ({
|
|
3615
3626
|
activePage: {
|
|
3627
|
+
id: currentPage.id,
|
|
3616
3628
|
addElement: (element) => {
|
|
3617
3629
|
const newElement = {
|
|
3618
3630
|
id: `element-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
@@ -3656,6 +3668,42 @@ var CanvasEditor = forwardRef(({
|
|
|
3656
3668
|
} else {
|
|
3657
3669
|
setActivePanelId(null);
|
|
3658
3670
|
}
|
|
3671
|
+
},
|
|
3672
|
+
deletePages: (pageIds) => {
|
|
3673
|
+
setDesign((prev) => {
|
|
3674
|
+
const remainingPages = prev.pages.filter((page) => !pageIds.includes(page.id));
|
|
3675
|
+
if (remainingPages.length === 0) {
|
|
3676
|
+
console.warn("Cannot delete all pages. At least one page must remain.");
|
|
3677
|
+
return prev;
|
|
3678
|
+
}
|
|
3679
|
+
const currentPageWasDeleted = pageIds.includes(currentPage.id);
|
|
3680
|
+
const newCurrentPageId = currentPageWasDeleted ? remainingPages[0].id : currentPage.id;
|
|
3681
|
+
if (currentPageWasDeleted) {
|
|
3682
|
+
setTimeout(() => {
|
|
3683
|
+
const newCurrentPage = remainingPages[0];
|
|
3684
|
+
}, 0);
|
|
3685
|
+
}
|
|
3686
|
+
return {
|
|
3687
|
+
...prev,
|
|
3688
|
+
pages: remainingPages,
|
|
3689
|
+
currentPageId: newCurrentPageId
|
|
3690
|
+
};
|
|
3691
|
+
});
|
|
3692
|
+
},
|
|
3693
|
+
loadJSON: async (jsonData) => {
|
|
3694
|
+
return new Promise((resolve, reject) => {
|
|
3695
|
+
importFromJSONData(jsonData, (loadedDesign) => {
|
|
3696
|
+
setDesign(loadedDesign);
|
|
3697
|
+
resolve();
|
|
3698
|
+
}, (errorMessage) => {
|
|
3699
|
+
console.error("Failed to load JSON:", errorMessage);
|
|
3700
|
+
reject(new Error(errorMessage));
|
|
3701
|
+
}, (inputs, onComplete) => {
|
|
3702
|
+
setPendingInputs(inputs);
|
|
3703
|
+
setShowInputModal(true);
|
|
3704
|
+
window.__pendingImportComplete = onComplete;
|
|
3705
|
+
});
|
|
3706
|
+
});
|
|
3659
3707
|
}
|
|
3660
3708
|
}), [currentPage.id, design.width, design.height, config, setActivePanelId]);
|
|
3661
3709
|
const panelConfigs = useMemo(() => {
|
|
@@ -3818,12 +3866,12 @@ var CanvasEditor = forwardRef(({
|
|
|
3818
3866
|
const DynamicPanelRenderer = () => {
|
|
3819
3867
|
const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
|
|
3820
3868
|
if (!activePanelConfig) {
|
|
3821
|
-
return /* @__PURE__ */
|
|
3869
|
+
return /* @__PURE__ */ React19.createElement("div", {
|
|
3822
3870
|
className: "text-white"
|
|
3823
3871
|
}, "Panel not found");
|
|
3824
3872
|
}
|
|
3825
3873
|
const PanelComponent = activePanelConfig.component;
|
|
3826
|
-
return /* @__PURE__ */
|
|
3874
|
+
return /* @__PURE__ */ React19.createElement(PanelComponent, {
|
|
3827
3875
|
...activePanelConfig.props
|
|
3828
3876
|
});
|
|
3829
3877
|
};
|
|
@@ -3876,9 +3924,11 @@ var CanvasEditor = forwardRef(({
|
|
|
3876
3924
|
setHistoryIndex(0);
|
|
3877
3925
|
}
|
|
3878
3926
|
}, []);
|
|
3879
|
-
return /* @__PURE__ */
|
|
3927
|
+
return /* @__PURE__ */ React19.createElement(CanvasStoreContext.Provider, {
|
|
3928
|
+
value: store
|
|
3929
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3880
3930
|
className: "h-screen flex flex-col bg-gray-900"
|
|
3881
|
-
}, /* @__PURE__ */
|
|
3931
|
+
}, /* @__PURE__ */ React19.createElement(Header_default, {
|
|
3882
3932
|
name,
|
|
3883
3933
|
zoom,
|
|
3884
3934
|
historyIndex,
|
|
@@ -3890,37 +3940,37 @@ var CanvasEditor = forwardRef(({
|
|
|
3890
3940
|
onZoomReset: () => setZoom(calculateFitToScreenZoom(design.width, design.height)),
|
|
3891
3941
|
onSetActivePanel: setActivePanelId,
|
|
3892
3942
|
navbarConfig: config?.navbar
|
|
3893
|
-
}), /* @__PURE__ */
|
|
3943
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3894
3944
|
className: "flex-1 flex overflow-hidden"
|
|
3895
|
-
}, /* @__PURE__ */
|
|
3945
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3896
3946
|
className: "w-80 bg-gray-800 border-r border-gray-700 flex"
|
|
3897
|
-
}, /* @__PURE__ */
|
|
3947
|
+
}, /* @__PURE__ */ React19.createElement(LeftMenu_default, {
|
|
3898
3948
|
tool,
|
|
3899
3949
|
activePanel: activePanelId,
|
|
3900
3950
|
onSetTool: setTool,
|
|
3901
3951
|
onSetActivePanel: setActivePanelId,
|
|
3902
3952
|
config
|
|
3903
|
-
}), /* @__PURE__ */
|
|
3953
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3904
3954
|
className: "flex-1 p-4 overflow-y-auto"
|
|
3905
|
-
}, /* @__PURE__ */
|
|
3955
|
+
}, /* @__PURE__ */ React19.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React19.createElement("div", {
|
|
3906
3956
|
className: "flex-1 bg-gray-700 overflow-hidden relative",
|
|
3907
3957
|
ref: containerRef
|
|
3908
|
-
}, /* @__PURE__ */
|
|
3958
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3909
3959
|
className: "absolute inset-0 flex items-center justify-center"
|
|
3910
|
-
}, /* @__PURE__ */
|
|
3960
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3911
3961
|
className: "bg-white shadow-2xl",
|
|
3912
3962
|
style: {
|
|
3913
3963
|
transform: `scale(${zoom})`,
|
|
3914
3964
|
transformOrigin: "center center"
|
|
3915
3965
|
}
|
|
3916
|
-
}, /* @__PURE__ */
|
|
3966
|
+
}, /* @__PURE__ */ React19.createElement(Stage, {
|
|
3917
3967
|
key: `canvas-${design.id || design.width}-${design.height}`,
|
|
3918
3968
|
ref: stageRef,
|
|
3919
3969
|
width: design.width,
|
|
3920
3970
|
height: design.height,
|
|
3921
3971
|
onClick: handleStageClick,
|
|
3922
3972
|
onTap: handleStageClick
|
|
3923
|
-
}, /* @__PURE__ */
|
|
3973
|
+
}, /* @__PURE__ */ React19.createElement(Layer, null, /* @__PURE__ */ React19.createElement(Rect2, {
|
|
3924
3974
|
x: 0,
|
|
3925
3975
|
y: 0,
|
|
3926
3976
|
width: design.width,
|
|
@@ -3931,7 +3981,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3931
3981
|
}), currentPage.elements.map((element) => {
|
|
3932
3982
|
switch (element.type) {
|
|
3933
3983
|
case "text":
|
|
3934
|
-
return
|
|
3984
|
+
return React19.createElement(EditableTextElement, {
|
|
3935
3985
|
key: element.id,
|
|
3936
3986
|
element,
|
|
3937
3987
|
isSelected: element.id === selectedId,
|
|
@@ -3942,7 +3992,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3942
3992
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3943
3993
|
});
|
|
3944
3994
|
case "image":
|
|
3945
|
-
return
|
|
3995
|
+
return React19.createElement(UrlImageElement, {
|
|
3946
3996
|
key: element.id,
|
|
3947
3997
|
element,
|
|
3948
3998
|
isSelected: element.id === selectedId,
|
|
@@ -3953,7 +4003,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3953
4003
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3954
4004
|
});
|
|
3955
4005
|
case "shape":
|
|
3956
|
-
return
|
|
4006
|
+
return React19.createElement(ShapeElement, {
|
|
3957
4007
|
key: element.id,
|
|
3958
4008
|
element,
|
|
3959
4009
|
isSelected: element.id === selectedId,
|
|
@@ -3966,27 +4016,27 @@ var CanvasEditor = forwardRef(({
|
|
|
3966
4016
|
default:
|
|
3967
4017
|
return null;
|
|
3968
4018
|
}
|
|
3969
|
-
}))))), config?.multiPage && /* @__PURE__ */
|
|
4019
|
+
}))))), config?.multiPage && /* @__PURE__ */ React19.createElement("div", {
|
|
3970
4020
|
className: "absolute bottom-4 left-4 flex items-center space-x-2"
|
|
3971
|
-
}, design.pages.map((page, index) => /* @__PURE__ */
|
|
4021
|
+
}, design.pages.map((page, index) => /* @__PURE__ */ React19.createElement("div", {
|
|
3972
4022
|
key: page.id,
|
|
3973
4023
|
className: "relative group"
|
|
3974
|
-
}, /* @__PURE__ */
|
|
4024
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
3975
4025
|
onClick: () => setCurrentPageId(page.id),
|
|
3976
4026
|
className: `px-3 py-1 rounded text-sm ${page.id === currentPageId ? "bg-blue-600 text-white" : "bg-gray-800 text-gray-300 hover:bg-gray-700"}`
|
|
3977
|
-
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */
|
|
4027
|
+
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React19.createElement("button", {
|
|
3978
4028
|
onClick: () => deletePage(page.id),
|
|
3979
4029
|
className: "absolute -top-1 -right-1 w-4 h-4 bg-red-500 text-white rounded-full flex items-center justify-center transition-opacity duration-200 hover:bg-red-600",
|
|
3980
4030
|
title: `Delete Page ${index + 1}`
|
|
3981
|
-
}, /* @__PURE__ */
|
|
4031
|
+
}, /* @__PURE__ */ React19.createElement(X2, {
|
|
3982
4032
|
className: "w-3 h-3"
|
|
3983
|
-
})))), /* @__PURE__ */
|
|
4033
|
+
})))), /* @__PURE__ */ React19.createElement("button", {
|
|
3984
4034
|
onClick: addPage,
|
|
3985
4035
|
className: "p-1 bg-gray-800 text-gray-300 rounded hover:bg-gray-700",
|
|
3986
4036
|
title: "Add Page"
|
|
3987
|
-
}, /* @__PURE__ */
|
|
4037
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
3988
4038
|
className: "w-4 h-4"
|
|
3989
|
-
})))), /* @__PURE__ */
|
|
4039
|
+
})))), /* @__PURE__ */ React19.createElement(RightSidebar_default, {
|
|
3990
4040
|
currentPageElements: currentPage.elements,
|
|
3991
4041
|
selectedElement,
|
|
3992
4042
|
selectedId,
|
|
@@ -3996,34 +4046,34 @@ var CanvasEditor = forwardRef(({
|
|
|
3996
4046
|
onMoveElementUp: moveElementUp,
|
|
3997
4047
|
onMoveElementDown: moveElementDown,
|
|
3998
4048
|
onDeleteSelected: deleteSelected
|
|
3999
|
-
})), /* @__PURE__ */
|
|
4049
|
+
})), /* @__PURE__ */ React19.createElement("input", {
|
|
4000
4050
|
ref: fileInputRef,
|
|
4001
4051
|
type: "file",
|
|
4002
4052
|
accept: "image/*",
|
|
4003
4053
|
onChange: handleImageUpload,
|
|
4004
4054
|
className: "hidden",
|
|
4005
4055
|
multiple: true
|
|
4006
|
-
}), /* @__PURE__ */
|
|
4056
|
+
}), /* @__PURE__ */ React19.createElement("input", {
|
|
4007
4057
|
ref: jsonInputRef,
|
|
4008
4058
|
type: "file",
|
|
4009
4059
|
accept: ".json",
|
|
4010
4060
|
onChange: handleImportJSON,
|
|
4011
4061
|
className: "hidden"
|
|
4012
|
-
}), showInputModal && /* @__PURE__ */
|
|
4062
|
+
}), showInputModal && /* @__PURE__ */ React19.createElement(TemplateInputModal_default, {
|
|
4013
4063
|
inputs: pendingInputs,
|
|
4014
4064
|
onComplete: handleInputModalComplete,
|
|
4015
4065
|
onCancel: handleInputModalCancel
|
|
4016
|
-
}), showUnsplash && /* @__PURE__ */
|
|
4066
|
+
}), showUnsplash && /* @__PURE__ */ React19.createElement("div", {
|
|
4017
4067
|
className: "fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-8"
|
|
4018
|
-
}, /* @__PURE__ */
|
|
4068
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4019
4069
|
className: "bg-gray-800 rounded-lg w-full max-w-4xl max-h-full overflow-hidden flex flex-col"
|
|
4020
|
-
}, /* @__PURE__ */
|
|
4070
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4021
4071
|
className: "p-6 border-b border-gray-700"
|
|
4022
|
-
}, /* @__PURE__ */
|
|
4072
|
+
}, /* @__PURE__ */ React19.createElement("h3", {
|
|
4023
4073
|
className: "text-xl font-semibold text-white mb-4"
|
|
4024
|
-
}, "Search Unsplash"), /* @__PURE__ */
|
|
4074
|
+
}, "Search Unsplash"), /* @__PURE__ */ React19.createElement("div", {
|
|
4025
4075
|
className: "flex space-x-4"
|
|
4026
|
-
}, /* @__PURE__ */
|
|
4076
|
+
}, /* @__PURE__ */ React19.createElement("input", {
|
|
4027
4077
|
type: "text",
|
|
4028
4078
|
value: unsplashQuery,
|
|
4029
4079
|
onChange: (e) => setUnsplashQuery(e.target.value),
|
|
@@ -4031,59 +4081,59 @@ var CanvasEditor = forwardRef(({
|
|
|
4031
4081
|
placeholder: "Search for images...",
|
|
4032
4082
|
className: "flex-1 bg-gray-700 text-white border border-gray-600 rounded px-4 py-2 focus:border-blue-500 focus:outline-none",
|
|
4033
4083
|
autoFocus: true
|
|
4034
|
-
}), /* @__PURE__ */
|
|
4084
|
+
}), /* @__PURE__ */ React19.createElement("button", {
|
|
4035
4085
|
onClick: searchUnsplash,
|
|
4036
4086
|
className: "px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
|
4037
|
-
}, "Search"), /* @__PURE__ */
|
|
4087
|
+
}, "Search"), /* @__PURE__ */ React19.createElement("button", {
|
|
4038
4088
|
onClick: () => {
|
|
4039
4089
|
setShowUnsplash(false);
|
|
4040
4090
|
setUnsplashQuery("");
|
|
4041
4091
|
setUnsplashResults([]);
|
|
4042
4092
|
},
|
|
4043
4093
|
className: "px-6 py-2 bg-gray-700 text-white rounded hover:bg-gray-600"
|
|
4044
|
-
}, "Cancel"))), /* @__PURE__ */
|
|
4094
|
+
}, "Cancel"))), /* @__PURE__ */ React19.createElement("div", {
|
|
4045
4095
|
className: "flex-1 overflow-y-auto p-6"
|
|
4046
|
-
}, unsplashResults.length > 0 ? /* @__PURE__ */
|
|
4096
|
+
}, unsplashResults.length > 0 ? /* @__PURE__ */ React19.createElement("div", {
|
|
4047
4097
|
className: "grid grid-cols-3 gap-4"
|
|
4048
|
-
}, unsplashResults.map((result) => /* @__PURE__ */
|
|
4098
|
+
}, unsplashResults.map((result) => /* @__PURE__ */ React19.createElement("button", {
|
|
4049
4099
|
key: result.id,
|
|
4050
4100
|
onClick: () => addUnsplashImage(result.urls.regular),
|
|
4051
4101
|
className: "relative group overflow-hidden rounded-lg aspect-square"
|
|
4052
|
-
}, /* @__PURE__ */
|
|
4102
|
+
}, /* @__PURE__ */ React19.createElement("img", {
|
|
4053
4103
|
src: result.urls.thumb,
|
|
4054
4104
|
alt: "",
|
|
4055
4105
|
className: "w-full h-full object-cover group-hover:scale-110 transition-transform duration-200"
|
|
4056
|
-
}), /* @__PURE__ */
|
|
4106
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4057
4107
|
className: "absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-50 transition-opacity duration-200 flex items-center justify-center"
|
|
4058
|
-
}, /* @__PURE__ */
|
|
4108
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
4059
4109
|
className: "w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
|
|
4060
|
-
}))))) : /* @__PURE__ */
|
|
4110
|
+
}))))) : /* @__PURE__ */ React19.createElement("div", {
|
|
4061
4111
|
className: "text-center text-gray-400 py-12"
|
|
4062
|
-
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */
|
|
4112
|
+
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React19.createElement("div", {
|
|
4063
4113
|
className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
|
|
4064
|
-
}, /* @__PURE__ */
|
|
4114
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4065
4115
|
className: "bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-auto"
|
|
4066
|
-
}, /* @__PURE__ */
|
|
4116
|
+
}, /* @__PURE__ */ React19.createElement("h2", {
|
|
4067
4117
|
className: "text-white text-xl font-semibold mb-4"
|
|
4068
|
-
}, "Load JSON Data"), /* @__PURE__ */
|
|
4118
|
+
}, "Load JSON Data"), /* @__PURE__ */ React19.createElement("p", {
|
|
4069
4119
|
className: "text-gray-300 mb-4"
|
|
4070
|
-
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */
|
|
4120
|
+
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React19.createElement("textarea", {
|
|
4071
4121
|
value: jsonInputText,
|
|
4072
4122
|
onChange: (e) => setJsonInputText(e.target.value),
|
|
4073
4123
|
className: "w-full h-64 p-3 bg-gray-700 text-white border border-gray-600 rounded font-mono text-sm resize-none",
|
|
4074
4124
|
placeholder: '{"width": 800, "height": 600, "pages": [...]}'
|
|
4075
|
-
}), /* @__PURE__ */
|
|
4125
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4076
4126
|
className: "flex justify-end space-x-3 mt-4"
|
|
4077
|
-
}, /* @__PURE__ */
|
|
4127
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
4078
4128
|
onClick: () => {
|
|
4079
4129
|
setShowJsonModal(false);
|
|
4080
4130
|
setJsonInputText("");
|
|
4081
4131
|
},
|
|
4082
4132
|
className: "px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
|
|
4083
|
-
}, "Cancel"), /* @__PURE__ */
|
|
4133
|
+
}, "Cancel"), /* @__PURE__ */ React19.createElement("button", {
|
|
4084
4134
|
onClick: handleImportJSONData,
|
|
4085
4135
|
className: "px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
|
|
4086
|
-
}, "Load JSON")))));
|
|
4136
|
+
}, "Load JSON"))))));
|
|
4087
4137
|
});
|
|
4088
4138
|
var CanvasEditor_default = CanvasEditor;
|
|
4089
4139
|
// src/lib/index.ts
|
|
@@ -4141,6 +4191,7 @@ function initWordPressCanvasEditor(containerId, props) {
|
|
|
4141
4191
|
return false;
|
|
4142
4192
|
}
|
|
4143
4193
|
export {
|
|
4194
|
+
useCanvasStore,
|
|
4144
4195
|
setUnsplashAccessKey,
|
|
4145
4196
|
replaceUserInputs,
|
|
4146
4197
|
loadTemplateFromJSON,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CanvasEditor.d.ts","sourceRoot":"","sources":["../../src/CanvasEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAGlH,OAAO,KAAK,MAAM,OAAO,CAAC;AA0C1B,OAAO,EAEL,YAAY,EAKb,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"CanvasEditor.d.ts","sourceRoot":"","sources":["../../src/CanvasEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAGlH,OAAO,KAAK,MAAM,OAAO,CAAC;AA0C1B,OAAO,EAEL,YAAY,EAKb,MAAM,SAAS,CAAC;AAkCjB,OAAO,EAA+B,MAAM,EAA0C,MAAM,gBAAgB,CAAC;AAI7G,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,YAAY,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACxD;AAED,QAAA,MAAM,YAAY;UAAuC,MAAM;aAAW,MAAM;yCAw2C9E,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CanvasStore } from "../types/Config";
|
|
3
|
+
declare const CanvasStoreContext: React.Context<CanvasStore>;
|
|
4
|
+
/**
|
|
5
|
+
* Hook to access the CanvasStore from any component inside CanvasEditor
|
|
6
|
+
* @throws Error if used outside CanvasEditor
|
|
7
|
+
*/
|
|
8
|
+
export declare const useCanvasStore: () => CanvasStore;
|
|
9
|
+
export { CanvasStoreContext };
|
|
10
|
+
//# sourceMappingURL=CanvasStoreContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CanvasStoreContext.d.ts","sourceRoot":"","sources":["../../../src/context/CanvasStoreContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,QAAA,MAAM,kBAAkB,4BAA0C,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,WAMjC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -16,6 +16,7 @@ export interface CanvasEditorRef {
|
|
|
16
16
|
export { default as CanvasEditor } from '../CanvasEditor';
|
|
17
17
|
export * from '../types';
|
|
18
18
|
export type { BuiltInPanelId, CanvasStore, CustomPanelDefinition, PanelDefinition, } from '../types/Config';
|
|
19
|
+
export { useCanvasStore } from '../context/CanvasStoreContext';
|
|
19
20
|
export { exportToPNG, exportToJPG, exportToJSON, exportToJSONObject, importFromJSON, importFromJSONData, // Import JSON data directly (no file needed)
|
|
20
21
|
loadTemplateFromJSON, // Simplified template loading utility
|
|
21
22
|
findRequiredInputs, replaceUserInputs, convertTemplateToCanvasDesign, canvasToDataURL, canvasToBlob, } from '../utils/exportImportUtils';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AASxC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,YAAY,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAGD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG1D,cAAc,UAAU,CAAC;AAGzB,YAAY,EACV,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAAE,6CAA6C;AACjE,oBAAoB,EAAE,sCAAsC;AAC5D,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,eAAe,EACf,YAAY,GACb,MAAM,4BAA4B,CAAC;AAGpC,cAAc,aAAa,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG7E,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AASxC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,YAAY,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,UAAU,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAGD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG1D,cAAc,UAAU,CAAC;AAGzB,YAAY,EACV,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAG/D,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAAE,6CAA6C;AACjE,oBAAoB,EAAE,sCAAsC;AAC5D,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,EAC7B,eAAe,EACf,YAAY,GACb,MAAM,4BAA4B,CAAC;AAGpC,cAAc,aAAa,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG7E,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -14,6 +14,7 @@ export interface CustomPanelDefinition {
|
|
|
14
14
|
export type PanelDefinition = BuiltInPanelId | CustomPanelDefinition;
|
|
15
15
|
export interface CanvasStore {
|
|
16
16
|
activePage: {
|
|
17
|
+
id: string;
|
|
17
18
|
addElement: (element: {
|
|
18
19
|
type: string;
|
|
19
20
|
src?: string;
|
|
@@ -26,6 +27,8 @@ export interface CanvasStore {
|
|
|
26
27
|
width: number;
|
|
27
28
|
height: number;
|
|
28
29
|
openSidePanel: (panelId: string | null) => void;
|
|
30
|
+
deletePages: (pageIds: string[]) => void;
|
|
31
|
+
loadJSON: (jsonData: any) => Promise<void>;
|
|
29
32
|
}
|
|
30
33
|
export interface NavbarSection {
|
|
31
34
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/types/Config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,QAAQ,GACR,MAAM,GACN,OAAO,GACP,YAAY,GACZ,QAAQ,GACR,WAAW,CAAC;AAEhB,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,GAAG,iBAAiB,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,qBAAqB,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE;QACV,UAAU,EAAE,CAAC,OAAO,EAAE;YACpB,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,CAAC,EAAE,MAAM,CAAC;YACb,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;YACV,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;SAChB,KAAK,IAAI,CAAC;KACZ,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/types/Config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED