labellife-design-tool 1.1.2 → 1.1.4
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 +66 -1
- package/dist/lib/lib/index.js +111 -54
- package/dist/lib/wordpress.js +111 -54
- 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,40 @@ 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
|
+
return (
|
|
171
|
+
<div style={{ color: "white", padding: 16 }}>
|
|
172
|
+
<p>Current page: {store.activePage.id}</p>
|
|
173
|
+
<p>Canvas size: {store.width} × {store.height}</p>
|
|
174
|
+
<button onClick={handleAddImage}>Add Image</button>
|
|
175
|
+
</div>
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Option 2: Panel prop approach**
|
|
181
|
+
|
|
182
|
+
Every panel (built-in or custom) also receives a `store` prop with a Polotno-like API:
|
|
150
183
|
|
|
151
184
|
```tsx
|
|
152
185
|
// Your custom panel component
|
|
@@ -192,6 +225,7 @@ const MyImagesPanel = ({ store }) => {
|
|
|
192
225
|
```typescript
|
|
193
226
|
interface CanvasStore {
|
|
194
227
|
activePage: {
|
|
228
|
+
id: string;
|
|
195
229
|
addElement: (element: {
|
|
196
230
|
type: string;
|
|
197
231
|
src?: string;
|
|
@@ -203,9 +237,40 @@ interface CanvasStore {
|
|
|
203
237
|
};
|
|
204
238
|
width: number;
|
|
205
239
|
height: number;
|
|
240
|
+
openSidePanel: (panelId: string | null) => void;
|
|
241
|
+
deletePages: (pageIds: string[]) => void;
|
|
206
242
|
}
|
|
207
243
|
```
|
|
208
244
|
|
|
245
|
+
**Open panels programmatically**
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
const MyPanel = ({ store }) => {
|
|
249
|
+
const openTextPanel = () => store.openSidePanel("text");
|
|
250
|
+
const openCustomPanel = () => store.openSidePanel("my-custom-panel");
|
|
251
|
+
const closeAllPanels = () => store.openSidePanel(null);
|
|
252
|
+
const tryOpenUnknown = () => store.openSidePanel("nonexistent"); // closes all panels
|
|
253
|
+
|
|
254
|
+
const deletePage1 = () => store.deletePages(["page-1"]);
|
|
255
|
+
const deleteMultiplePages = () => store.deletePages(["page-1", "page-2", "page-3"]);
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<div style={{ color: "white", padding: 16 }}>
|
|
259
|
+
<p>Current page ID: {store.activePage.id}</p>
|
|
260
|
+
<p>Canvas size: {store.width} × {store.height}</p>
|
|
261
|
+
|
|
262
|
+
<button onClick={openTextPanel}>Open Text Panel</button>
|
|
263
|
+
<button onClick={openCustomPanel}>Open Custom Panel</button>
|
|
264
|
+
<button onClick={closeAllPanels}>Close All Panels</button>
|
|
265
|
+
<button onClick={tryOpenUnknown}>Try Unknown Panel (closes all)</button>
|
|
266
|
+
|
|
267
|
+
<button onClick={deletePage1}>Delete Page 1</button>
|
|
268
|
+
<button onClick={deleteMultiplePages}>Delete Multiple Pages</button>
|
|
269
|
+
</div>
|
|
270
|
+
);
|
|
271
|
+
};
|
|
272
|
+
```
|
|
273
|
+
|
|
209
274
|
#### Default Behavior
|
|
210
275
|
|
|
211
276
|
If `config.panels` is **not provided**, the editor shows the default set:
|
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)}`,
|
|
@@ -3635,8 +3647,50 @@ var CanvasEditor = forwardRef(({
|
|
|
3635
3647
|
}
|
|
3636
3648
|
},
|
|
3637
3649
|
width: design.width,
|
|
3638
|
-
height: design.height
|
|
3639
|
-
|
|
3650
|
+
height: design.height,
|
|
3651
|
+
openSidePanel: (panelId) => {
|
|
3652
|
+
if (!panelId) {
|
|
3653
|
+
setActivePanelId(null);
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3656
|
+
const requestedPanels = config?.panels && config.panels.length > 0 ? config.panels : [
|
|
3657
|
+
"text",
|
|
3658
|
+
"elements",
|
|
3659
|
+
"image",
|
|
3660
|
+
"design",
|
|
3661
|
+
"background",
|
|
3662
|
+
...config?.variables ? ["variables"] : [],
|
|
3663
|
+
...config?.export ? ["export"] : []
|
|
3664
|
+
];
|
|
3665
|
+
const panelExists = requestedPanels.some((p) => typeof p === "string" ? p === panelId : p.id === panelId);
|
|
3666
|
+
if (panelExists) {
|
|
3667
|
+
setActivePanelId(panelId);
|
|
3668
|
+
} else {
|
|
3669
|
+
setActivePanelId(null);
|
|
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
|
+
}), [currentPage.id, design.width, design.height, config, setActivePanelId]);
|
|
3640
3694
|
const panelConfigs = useMemo(() => {
|
|
3641
3695
|
const builtInConfigs = {
|
|
3642
3696
|
elements: {
|
|
@@ -3797,12 +3851,12 @@ var CanvasEditor = forwardRef(({
|
|
|
3797
3851
|
const DynamicPanelRenderer = () => {
|
|
3798
3852
|
const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
|
|
3799
3853
|
if (!activePanelConfig) {
|
|
3800
|
-
return /* @__PURE__ */
|
|
3854
|
+
return /* @__PURE__ */ React19.createElement("div", {
|
|
3801
3855
|
className: "text-white"
|
|
3802
3856
|
}, "Panel not found");
|
|
3803
3857
|
}
|
|
3804
3858
|
const PanelComponent = activePanelConfig.component;
|
|
3805
|
-
return /* @__PURE__ */
|
|
3859
|
+
return /* @__PURE__ */ React19.createElement(PanelComponent, {
|
|
3806
3860
|
...activePanelConfig.props
|
|
3807
3861
|
});
|
|
3808
3862
|
};
|
|
@@ -3855,9 +3909,11 @@ var CanvasEditor = forwardRef(({
|
|
|
3855
3909
|
setHistoryIndex(0);
|
|
3856
3910
|
}
|
|
3857
3911
|
}, []);
|
|
3858
|
-
return /* @__PURE__ */
|
|
3912
|
+
return /* @__PURE__ */ React19.createElement(CanvasStoreContext.Provider, {
|
|
3913
|
+
value: store
|
|
3914
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3859
3915
|
className: "h-screen flex flex-col bg-gray-900"
|
|
3860
|
-
}, /* @__PURE__ */
|
|
3916
|
+
}, /* @__PURE__ */ React19.createElement(Header_default, {
|
|
3861
3917
|
name,
|
|
3862
3918
|
zoom,
|
|
3863
3919
|
historyIndex,
|
|
@@ -3869,37 +3925,37 @@ var CanvasEditor = forwardRef(({
|
|
|
3869
3925
|
onZoomReset: () => setZoom(calculateFitToScreenZoom(design.width, design.height)),
|
|
3870
3926
|
onSetActivePanel: setActivePanelId,
|
|
3871
3927
|
navbarConfig: config?.navbar
|
|
3872
|
-
}), /* @__PURE__ */
|
|
3928
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3873
3929
|
className: "flex-1 flex overflow-hidden"
|
|
3874
|
-
}, /* @__PURE__ */
|
|
3930
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3875
3931
|
className: "w-80 bg-gray-800 border-r border-gray-700 flex"
|
|
3876
|
-
}, /* @__PURE__ */
|
|
3932
|
+
}, /* @__PURE__ */ React19.createElement(LeftMenu_default, {
|
|
3877
3933
|
tool,
|
|
3878
3934
|
activePanel: activePanelId,
|
|
3879
3935
|
onSetTool: setTool,
|
|
3880
3936
|
onSetActivePanel: setActivePanelId,
|
|
3881
3937
|
config
|
|
3882
|
-
}), /* @__PURE__ */
|
|
3938
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3883
3939
|
className: "flex-1 p-4 overflow-y-auto"
|
|
3884
|
-
}, /* @__PURE__ */
|
|
3940
|
+
}, /* @__PURE__ */ React19.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React19.createElement("div", {
|
|
3885
3941
|
className: "flex-1 bg-gray-700 overflow-hidden relative",
|
|
3886
3942
|
ref: containerRef
|
|
3887
|
-
}, /* @__PURE__ */
|
|
3943
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3888
3944
|
className: "absolute inset-0 flex items-center justify-center"
|
|
3889
|
-
}, /* @__PURE__ */
|
|
3945
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3890
3946
|
className: "bg-white shadow-2xl",
|
|
3891
3947
|
style: {
|
|
3892
3948
|
transform: `scale(${zoom})`,
|
|
3893
3949
|
transformOrigin: "center center"
|
|
3894
3950
|
}
|
|
3895
|
-
}, /* @__PURE__ */
|
|
3951
|
+
}, /* @__PURE__ */ React19.createElement(Stage, {
|
|
3896
3952
|
key: `canvas-${design.id || design.width}-${design.height}`,
|
|
3897
3953
|
ref: stageRef,
|
|
3898
3954
|
width: design.width,
|
|
3899
3955
|
height: design.height,
|
|
3900
3956
|
onClick: handleStageClick,
|
|
3901
3957
|
onTap: handleStageClick
|
|
3902
|
-
}, /* @__PURE__ */
|
|
3958
|
+
}, /* @__PURE__ */ React19.createElement(Layer, null, /* @__PURE__ */ React19.createElement(Rect2, {
|
|
3903
3959
|
x: 0,
|
|
3904
3960
|
y: 0,
|
|
3905
3961
|
width: design.width,
|
|
@@ -3910,7 +3966,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3910
3966
|
}), currentPage.elements.map((element) => {
|
|
3911
3967
|
switch (element.type) {
|
|
3912
3968
|
case "text":
|
|
3913
|
-
return
|
|
3969
|
+
return React19.createElement(EditableTextElement, {
|
|
3914
3970
|
key: element.id,
|
|
3915
3971
|
element,
|
|
3916
3972
|
isSelected: element.id === selectedId,
|
|
@@ -3921,7 +3977,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3921
3977
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3922
3978
|
});
|
|
3923
3979
|
case "image":
|
|
3924
|
-
return
|
|
3980
|
+
return React19.createElement(UrlImageElement, {
|
|
3925
3981
|
key: element.id,
|
|
3926
3982
|
element,
|
|
3927
3983
|
isSelected: element.id === selectedId,
|
|
@@ -3932,7 +3988,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3932
3988
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3933
3989
|
});
|
|
3934
3990
|
case "shape":
|
|
3935
|
-
return
|
|
3991
|
+
return React19.createElement(ShapeElement, {
|
|
3936
3992
|
key: element.id,
|
|
3937
3993
|
element,
|
|
3938
3994
|
isSelected: element.id === selectedId,
|
|
@@ -3945,27 +4001,27 @@ var CanvasEditor = forwardRef(({
|
|
|
3945
4001
|
default:
|
|
3946
4002
|
return null;
|
|
3947
4003
|
}
|
|
3948
|
-
}))))), config?.multiPage && /* @__PURE__ */
|
|
4004
|
+
}))))), config?.multiPage && /* @__PURE__ */ React19.createElement("div", {
|
|
3949
4005
|
className: "absolute bottom-4 left-4 flex items-center space-x-2"
|
|
3950
|
-
}, design.pages.map((page, index) => /* @__PURE__ */
|
|
4006
|
+
}, design.pages.map((page, index) => /* @__PURE__ */ React19.createElement("div", {
|
|
3951
4007
|
key: page.id,
|
|
3952
4008
|
className: "relative group"
|
|
3953
|
-
}, /* @__PURE__ */
|
|
4009
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
3954
4010
|
onClick: () => setCurrentPageId(page.id),
|
|
3955
4011
|
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"}`
|
|
3956
|
-
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */
|
|
4012
|
+
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React19.createElement("button", {
|
|
3957
4013
|
onClick: () => deletePage(page.id),
|
|
3958
4014
|
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",
|
|
3959
4015
|
title: `Delete Page ${index + 1}`
|
|
3960
|
-
}, /* @__PURE__ */
|
|
4016
|
+
}, /* @__PURE__ */ React19.createElement(X2, {
|
|
3961
4017
|
className: "w-3 h-3"
|
|
3962
|
-
})))), /* @__PURE__ */
|
|
4018
|
+
})))), /* @__PURE__ */ React19.createElement("button", {
|
|
3963
4019
|
onClick: addPage,
|
|
3964
4020
|
className: "p-1 bg-gray-800 text-gray-300 rounded hover:bg-gray-700",
|
|
3965
4021
|
title: "Add Page"
|
|
3966
|
-
}, /* @__PURE__ */
|
|
4022
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
3967
4023
|
className: "w-4 h-4"
|
|
3968
|
-
})))), /* @__PURE__ */
|
|
4024
|
+
})))), /* @__PURE__ */ React19.createElement(RightSidebar_default, {
|
|
3969
4025
|
currentPageElements: currentPage.elements,
|
|
3970
4026
|
selectedElement,
|
|
3971
4027
|
selectedId,
|
|
@@ -3975,34 +4031,34 @@ var CanvasEditor = forwardRef(({
|
|
|
3975
4031
|
onMoveElementUp: moveElementUp,
|
|
3976
4032
|
onMoveElementDown: moveElementDown,
|
|
3977
4033
|
onDeleteSelected: deleteSelected
|
|
3978
|
-
})), /* @__PURE__ */
|
|
4034
|
+
})), /* @__PURE__ */ React19.createElement("input", {
|
|
3979
4035
|
ref: fileInputRef,
|
|
3980
4036
|
type: "file",
|
|
3981
4037
|
accept: "image/*",
|
|
3982
4038
|
onChange: handleImageUpload,
|
|
3983
4039
|
className: "hidden",
|
|
3984
4040
|
multiple: true
|
|
3985
|
-
}), /* @__PURE__ */
|
|
4041
|
+
}), /* @__PURE__ */ React19.createElement("input", {
|
|
3986
4042
|
ref: jsonInputRef,
|
|
3987
4043
|
type: "file",
|
|
3988
4044
|
accept: ".json",
|
|
3989
4045
|
onChange: handleImportJSON,
|
|
3990
4046
|
className: "hidden"
|
|
3991
|
-
}), showInputModal && /* @__PURE__ */
|
|
4047
|
+
}), showInputModal && /* @__PURE__ */ React19.createElement(TemplateInputModal_default, {
|
|
3992
4048
|
inputs: pendingInputs,
|
|
3993
4049
|
onComplete: handleInputModalComplete,
|
|
3994
4050
|
onCancel: handleInputModalCancel
|
|
3995
|
-
}), showUnsplash && /* @__PURE__ */
|
|
4051
|
+
}), showUnsplash && /* @__PURE__ */ React19.createElement("div", {
|
|
3996
4052
|
className: "fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-8"
|
|
3997
|
-
}, /* @__PURE__ */
|
|
4053
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3998
4054
|
className: "bg-gray-800 rounded-lg w-full max-w-4xl max-h-full overflow-hidden flex flex-col"
|
|
3999
|
-
}, /* @__PURE__ */
|
|
4055
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4000
4056
|
className: "p-6 border-b border-gray-700"
|
|
4001
|
-
}, /* @__PURE__ */
|
|
4057
|
+
}, /* @__PURE__ */ React19.createElement("h3", {
|
|
4002
4058
|
className: "text-xl font-semibold text-white mb-4"
|
|
4003
|
-
}, "Search Unsplash"), /* @__PURE__ */
|
|
4059
|
+
}, "Search Unsplash"), /* @__PURE__ */ React19.createElement("div", {
|
|
4004
4060
|
className: "flex space-x-4"
|
|
4005
|
-
}, /* @__PURE__ */
|
|
4061
|
+
}, /* @__PURE__ */ React19.createElement("input", {
|
|
4006
4062
|
type: "text",
|
|
4007
4063
|
value: unsplashQuery,
|
|
4008
4064
|
onChange: (e) => setUnsplashQuery(e.target.value),
|
|
@@ -4010,64 +4066,65 @@ var CanvasEditor = forwardRef(({
|
|
|
4010
4066
|
placeholder: "Search for images...",
|
|
4011
4067
|
className: "flex-1 bg-gray-700 text-white border border-gray-600 rounded px-4 py-2 focus:border-blue-500 focus:outline-none",
|
|
4012
4068
|
autoFocus: true
|
|
4013
|
-
}), /* @__PURE__ */
|
|
4069
|
+
}), /* @__PURE__ */ React19.createElement("button", {
|
|
4014
4070
|
onClick: searchUnsplash,
|
|
4015
4071
|
className: "px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
|
4016
|
-
}, "Search"), /* @__PURE__ */
|
|
4072
|
+
}, "Search"), /* @__PURE__ */ React19.createElement("button", {
|
|
4017
4073
|
onClick: () => {
|
|
4018
4074
|
setShowUnsplash(false);
|
|
4019
4075
|
setUnsplashQuery("");
|
|
4020
4076
|
setUnsplashResults([]);
|
|
4021
4077
|
},
|
|
4022
4078
|
className: "px-6 py-2 bg-gray-700 text-white rounded hover:bg-gray-600"
|
|
4023
|
-
}, "Cancel"))), /* @__PURE__ */
|
|
4079
|
+
}, "Cancel"))), /* @__PURE__ */ React19.createElement("div", {
|
|
4024
4080
|
className: "flex-1 overflow-y-auto p-6"
|
|
4025
|
-
}, unsplashResults.length > 0 ? /* @__PURE__ */
|
|
4081
|
+
}, unsplashResults.length > 0 ? /* @__PURE__ */ React19.createElement("div", {
|
|
4026
4082
|
className: "grid grid-cols-3 gap-4"
|
|
4027
|
-
}, unsplashResults.map((result) => /* @__PURE__ */
|
|
4083
|
+
}, unsplashResults.map((result) => /* @__PURE__ */ React19.createElement("button", {
|
|
4028
4084
|
key: result.id,
|
|
4029
4085
|
onClick: () => addUnsplashImage(result.urls.regular),
|
|
4030
4086
|
className: "relative group overflow-hidden rounded-lg aspect-square"
|
|
4031
|
-
}, /* @__PURE__ */
|
|
4087
|
+
}, /* @__PURE__ */ React19.createElement("img", {
|
|
4032
4088
|
src: result.urls.thumb,
|
|
4033
4089
|
alt: "",
|
|
4034
4090
|
className: "w-full h-full object-cover group-hover:scale-110 transition-transform duration-200"
|
|
4035
|
-
}), /* @__PURE__ */
|
|
4091
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4036
4092
|
className: "absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-50 transition-opacity duration-200 flex items-center justify-center"
|
|
4037
|
-
}, /* @__PURE__ */
|
|
4093
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
4038
4094
|
className: "w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
|
|
4039
|
-
}))))) : /* @__PURE__ */
|
|
4095
|
+
}))))) : /* @__PURE__ */ React19.createElement("div", {
|
|
4040
4096
|
className: "text-center text-gray-400 py-12"
|
|
4041
|
-
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */
|
|
4097
|
+
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React19.createElement("div", {
|
|
4042
4098
|
className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
|
|
4043
|
-
}, /* @__PURE__ */
|
|
4099
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4044
4100
|
className: "bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-auto"
|
|
4045
|
-
}, /* @__PURE__ */
|
|
4101
|
+
}, /* @__PURE__ */ React19.createElement("h2", {
|
|
4046
4102
|
className: "text-white text-xl font-semibold mb-4"
|
|
4047
|
-
}, "Load JSON Data"), /* @__PURE__ */
|
|
4103
|
+
}, "Load JSON Data"), /* @__PURE__ */ React19.createElement("p", {
|
|
4048
4104
|
className: "text-gray-300 mb-4"
|
|
4049
|
-
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */
|
|
4105
|
+
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React19.createElement("textarea", {
|
|
4050
4106
|
value: jsonInputText,
|
|
4051
4107
|
onChange: (e) => setJsonInputText(e.target.value),
|
|
4052
4108
|
className: "w-full h-64 p-3 bg-gray-700 text-white border border-gray-600 rounded font-mono text-sm resize-none",
|
|
4053
4109
|
placeholder: '{"width": 800, "height": 600, "pages": [...]}'
|
|
4054
|
-
}), /* @__PURE__ */
|
|
4110
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4055
4111
|
className: "flex justify-end space-x-3 mt-4"
|
|
4056
|
-
}, /* @__PURE__ */
|
|
4112
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
4057
4113
|
onClick: () => {
|
|
4058
4114
|
setShowJsonModal(false);
|
|
4059
4115
|
setJsonInputText("");
|
|
4060
4116
|
},
|
|
4061
4117
|
className: "px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
|
|
4062
|
-
}, "Cancel"), /* @__PURE__ */
|
|
4118
|
+
}, "Cancel"), /* @__PURE__ */ React19.createElement("button", {
|
|
4063
4119
|
onClick: handleImportJSONData,
|
|
4064
4120
|
className: "px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
|
|
4065
|
-
}, "Load JSON")))));
|
|
4121
|
+
}, "Load JSON"))))));
|
|
4066
4122
|
});
|
|
4067
4123
|
var CanvasEditor_default = CanvasEditor;
|
|
4068
4124
|
// src/lib/index.ts
|
|
4069
4125
|
initJsxCompat();
|
|
4070
4126
|
export {
|
|
4127
|
+
useCanvasStore,
|
|
4071
4128
|
setUnsplashAccessKey,
|
|
4072
4129
|
replaceUserInputs,
|
|
4073
4130
|
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)}`,
|
|
@@ -3635,8 +3647,50 @@ var CanvasEditor = forwardRef(({
|
|
|
3635
3647
|
}
|
|
3636
3648
|
},
|
|
3637
3649
|
width: design.width,
|
|
3638
|
-
height: design.height
|
|
3639
|
-
|
|
3650
|
+
height: design.height,
|
|
3651
|
+
openSidePanel: (panelId) => {
|
|
3652
|
+
if (!panelId) {
|
|
3653
|
+
setActivePanelId(null);
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3656
|
+
const requestedPanels = config?.panels && config.panels.length > 0 ? config.panels : [
|
|
3657
|
+
"text",
|
|
3658
|
+
"elements",
|
|
3659
|
+
"image",
|
|
3660
|
+
"design",
|
|
3661
|
+
"background",
|
|
3662
|
+
...config?.variables ? ["variables"] : [],
|
|
3663
|
+
...config?.export ? ["export"] : []
|
|
3664
|
+
];
|
|
3665
|
+
const panelExists = requestedPanels.some((p) => typeof p === "string" ? p === panelId : p.id === panelId);
|
|
3666
|
+
if (panelExists) {
|
|
3667
|
+
setActivePanelId(panelId);
|
|
3668
|
+
} else {
|
|
3669
|
+
setActivePanelId(null);
|
|
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
|
+
}), [currentPage.id, design.width, design.height, config, setActivePanelId]);
|
|
3640
3694
|
const panelConfigs = useMemo(() => {
|
|
3641
3695
|
const builtInConfigs = {
|
|
3642
3696
|
elements: {
|
|
@@ -3797,12 +3851,12 @@ var CanvasEditor = forwardRef(({
|
|
|
3797
3851
|
const DynamicPanelRenderer = () => {
|
|
3798
3852
|
const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
|
|
3799
3853
|
if (!activePanelConfig) {
|
|
3800
|
-
return /* @__PURE__ */
|
|
3854
|
+
return /* @__PURE__ */ React19.createElement("div", {
|
|
3801
3855
|
className: "text-white"
|
|
3802
3856
|
}, "Panel not found");
|
|
3803
3857
|
}
|
|
3804
3858
|
const PanelComponent = activePanelConfig.component;
|
|
3805
|
-
return /* @__PURE__ */
|
|
3859
|
+
return /* @__PURE__ */ React19.createElement(PanelComponent, {
|
|
3806
3860
|
...activePanelConfig.props
|
|
3807
3861
|
});
|
|
3808
3862
|
};
|
|
@@ -3855,9 +3909,11 @@ var CanvasEditor = forwardRef(({
|
|
|
3855
3909
|
setHistoryIndex(0);
|
|
3856
3910
|
}
|
|
3857
3911
|
}, []);
|
|
3858
|
-
return /* @__PURE__ */
|
|
3912
|
+
return /* @__PURE__ */ React19.createElement(CanvasStoreContext.Provider, {
|
|
3913
|
+
value: store
|
|
3914
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3859
3915
|
className: "h-screen flex flex-col bg-gray-900"
|
|
3860
|
-
}, /* @__PURE__ */
|
|
3916
|
+
}, /* @__PURE__ */ React19.createElement(Header_default, {
|
|
3861
3917
|
name,
|
|
3862
3918
|
zoom,
|
|
3863
3919
|
historyIndex,
|
|
@@ -3869,37 +3925,37 @@ var CanvasEditor = forwardRef(({
|
|
|
3869
3925
|
onZoomReset: () => setZoom(calculateFitToScreenZoom(design.width, design.height)),
|
|
3870
3926
|
onSetActivePanel: setActivePanelId,
|
|
3871
3927
|
navbarConfig: config?.navbar
|
|
3872
|
-
}), /* @__PURE__ */
|
|
3928
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3873
3929
|
className: "flex-1 flex overflow-hidden"
|
|
3874
|
-
}, /* @__PURE__ */
|
|
3930
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3875
3931
|
className: "w-80 bg-gray-800 border-r border-gray-700 flex"
|
|
3876
|
-
}, /* @__PURE__ */
|
|
3932
|
+
}, /* @__PURE__ */ React19.createElement(LeftMenu_default, {
|
|
3877
3933
|
tool,
|
|
3878
3934
|
activePanel: activePanelId,
|
|
3879
3935
|
onSetTool: setTool,
|
|
3880
3936
|
onSetActivePanel: setActivePanelId,
|
|
3881
3937
|
config
|
|
3882
|
-
}), /* @__PURE__ */
|
|
3938
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
3883
3939
|
className: "flex-1 p-4 overflow-y-auto"
|
|
3884
|
-
}, /* @__PURE__ */
|
|
3940
|
+
}, /* @__PURE__ */ React19.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React19.createElement("div", {
|
|
3885
3941
|
className: "flex-1 bg-gray-700 overflow-hidden relative",
|
|
3886
3942
|
ref: containerRef
|
|
3887
|
-
}, /* @__PURE__ */
|
|
3943
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3888
3944
|
className: "absolute inset-0 flex items-center justify-center"
|
|
3889
|
-
}, /* @__PURE__ */
|
|
3945
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3890
3946
|
className: "bg-white shadow-2xl",
|
|
3891
3947
|
style: {
|
|
3892
3948
|
transform: `scale(${zoom})`,
|
|
3893
3949
|
transformOrigin: "center center"
|
|
3894
3950
|
}
|
|
3895
|
-
}, /* @__PURE__ */
|
|
3951
|
+
}, /* @__PURE__ */ React19.createElement(Stage, {
|
|
3896
3952
|
key: `canvas-${design.id || design.width}-${design.height}`,
|
|
3897
3953
|
ref: stageRef,
|
|
3898
3954
|
width: design.width,
|
|
3899
3955
|
height: design.height,
|
|
3900
3956
|
onClick: handleStageClick,
|
|
3901
3957
|
onTap: handleStageClick
|
|
3902
|
-
}, /* @__PURE__ */
|
|
3958
|
+
}, /* @__PURE__ */ React19.createElement(Layer, null, /* @__PURE__ */ React19.createElement(Rect2, {
|
|
3903
3959
|
x: 0,
|
|
3904
3960
|
y: 0,
|
|
3905
3961
|
width: design.width,
|
|
@@ -3910,7 +3966,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3910
3966
|
}), currentPage.elements.map((element) => {
|
|
3911
3967
|
switch (element.type) {
|
|
3912
3968
|
case "text":
|
|
3913
|
-
return
|
|
3969
|
+
return React19.createElement(EditableTextElement, {
|
|
3914
3970
|
key: element.id,
|
|
3915
3971
|
element,
|
|
3916
3972
|
isSelected: element.id === selectedId,
|
|
@@ -3921,7 +3977,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3921
3977
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3922
3978
|
});
|
|
3923
3979
|
case "image":
|
|
3924
|
-
return
|
|
3980
|
+
return React19.createElement(UrlImageElement, {
|
|
3925
3981
|
key: element.id,
|
|
3926
3982
|
element,
|
|
3927
3983
|
isSelected: element.id === selectedId,
|
|
@@ -3932,7 +3988,7 @@ var CanvasEditor = forwardRef(({
|
|
|
3932
3988
|
onChange: (attrs) => updateElement(element.id, attrs)
|
|
3933
3989
|
});
|
|
3934
3990
|
case "shape":
|
|
3935
|
-
return
|
|
3991
|
+
return React19.createElement(ShapeElement, {
|
|
3936
3992
|
key: element.id,
|
|
3937
3993
|
element,
|
|
3938
3994
|
isSelected: element.id === selectedId,
|
|
@@ -3945,27 +4001,27 @@ var CanvasEditor = forwardRef(({
|
|
|
3945
4001
|
default:
|
|
3946
4002
|
return null;
|
|
3947
4003
|
}
|
|
3948
|
-
}))))), config?.multiPage && /* @__PURE__ */
|
|
4004
|
+
}))))), config?.multiPage && /* @__PURE__ */ React19.createElement("div", {
|
|
3949
4005
|
className: "absolute bottom-4 left-4 flex items-center space-x-2"
|
|
3950
|
-
}, design.pages.map((page, index) => /* @__PURE__ */
|
|
4006
|
+
}, design.pages.map((page, index) => /* @__PURE__ */ React19.createElement("div", {
|
|
3951
4007
|
key: page.id,
|
|
3952
4008
|
className: "relative group"
|
|
3953
|
-
}, /* @__PURE__ */
|
|
4009
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
3954
4010
|
onClick: () => setCurrentPageId(page.id),
|
|
3955
4011
|
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"}`
|
|
3956
|
-
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */
|
|
4012
|
+
}, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React19.createElement("button", {
|
|
3957
4013
|
onClick: () => deletePage(page.id),
|
|
3958
4014
|
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",
|
|
3959
4015
|
title: `Delete Page ${index + 1}`
|
|
3960
|
-
}, /* @__PURE__ */
|
|
4016
|
+
}, /* @__PURE__ */ React19.createElement(X2, {
|
|
3961
4017
|
className: "w-3 h-3"
|
|
3962
|
-
})))), /* @__PURE__ */
|
|
4018
|
+
})))), /* @__PURE__ */ React19.createElement("button", {
|
|
3963
4019
|
onClick: addPage,
|
|
3964
4020
|
className: "p-1 bg-gray-800 text-gray-300 rounded hover:bg-gray-700",
|
|
3965
4021
|
title: "Add Page"
|
|
3966
|
-
}, /* @__PURE__ */
|
|
4022
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
3967
4023
|
className: "w-4 h-4"
|
|
3968
|
-
})))), /* @__PURE__ */
|
|
4024
|
+
})))), /* @__PURE__ */ React19.createElement(RightSidebar_default, {
|
|
3969
4025
|
currentPageElements: currentPage.elements,
|
|
3970
4026
|
selectedElement,
|
|
3971
4027
|
selectedId,
|
|
@@ -3975,34 +4031,34 @@ var CanvasEditor = forwardRef(({
|
|
|
3975
4031
|
onMoveElementUp: moveElementUp,
|
|
3976
4032
|
onMoveElementDown: moveElementDown,
|
|
3977
4033
|
onDeleteSelected: deleteSelected
|
|
3978
|
-
})), /* @__PURE__ */
|
|
4034
|
+
})), /* @__PURE__ */ React19.createElement("input", {
|
|
3979
4035
|
ref: fileInputRef,
|
|
3980
4036
|
type: "file",
|
|
3981
4037
|
accept: "image/*",
|
|
3982
4038
|
onChange: handleImageUpload,
|
|
3983
4039
|
className: "hidden",
|
|
3984
4040
|
multiple: true
|
|
3985
|
-
}), /* @__PURE__ */
|
|
4041
|
+
}), /* @__PURE__ */ React19.createElement("input", {
|
|
3986
4042
|
ref: jsonInputRef,
|
|
3987
4043
|
type: "file",
|
|
3988
4044
|
accept: ".json",
|
|
3989
4045
|
onChange: handleImportJSON,
|
|
3990
4046
|
className: "hidden"
|
|
3991
|
-
}), showInputModal && /* @__PURE__ */
|
|
4047
|
+
}), showInputModal && /* @__PURE__ */ React19.createElement(TemplateInputModal_default, {
|
|
3992
4048
|
inputs: pendingInputs,
|
|
3993
4049
|
onComplete: handleInputModalComplete,
|
|
3994
4050
|
onCancel: handleInputModalCancel
|
|
3995
|
-
}), showUnsplash && /* @__PURE__ */
|
|
4051
|
+
}), showUnsplash && /* @__PURE__ */ React19.createElement("div", {
|
|
3996
4052
|
className: "fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-8"
|
|
3997
|
-
}, /* @__PURE__ */
|
|
4053
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
3998
4054
|
className: "bg-gray-800 rounded-lg w-full max-w-4xl max-h-full overflow-hidden flex flex-col"
|
|
3999
|
-
}, /* @__PURE__ */
|
|
4055
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4000
4056
|
className: "p-6 border-b border-gray-700"
|
|
4001
|
-
}, /* @__PURE__ */
|
|
4057
|
+
}, /* @__PURE__ */ React19.createElement("h3", {
|
|
4002
4058
|
className: "text-xl font-semibold text-white mb-4"
|
|
4003
|
-
}, "Search Unsplash"), /* @__PURE__ */
|
|
4059
|
+
}, "Search Unsplash"), /* @__PURE__ */ React19.createElement("div", {
|
|
4004
4060
|
className: "flex space-x-4"
|
|
4005
|
-
}, /* @__PURE__ */
|
|
4061
|
+
}, /* @__PURE__ */ React19.createElement("input", {
|
|
4006
4062
|
type: "text",
|
|
4007
4063
|
value: unsplashQuery,
|
|
4008
4064
|
onChange: (e) => setUnsplashQuery(e.target.value),
|
|
@@ -4010,59 +4066,59 @@ var CanvasEditor = forwardRef(({
|
|
|
4010
4066
|
placeholder: "Search for images...",
|
|
4011
4067
|
className: "flex-1 bg-gray-700 text-white border border-gray-600 rounded px-4 py-2 focus:border-blue-500 focus:outline-none",
|
|
4012
4068
|
autoFocus: true
|
|
4013
|
-
}), /* @__PURE__ */
|
|
4069
|
+
}), /* @__PURE__ */ React19.createElement("button", {
|
|
4014
4070
|
onClick: searchUnsplash,
|
|
4015
4071
|
className: "px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
|
4016
|
-
}, "Search"), /* @__PURE__ */
|
|
4072
|
+
}, "Search"), /* @__PURE__ */ React19.createElement("button", {
|
|
4017
4073
|
onClick: () => {
|
|
4018
4074
|
setShowUnsplash(false);
|
|
4019
4075
|
setUnsplashQuery("");
|
|
4020
4076
|
setUnsplashResults([]);
|
|
4021
4077
|
},
|
|
4022
4078
|
className: "px-6 py-2 bg-gray-700 text-white rounded hover:bg-gray-600"
|
|
4023
|
-
}, "Cancel"))), /* @__PURE__ */
|
|
4079
|
+
}, "Cancel"))), /* @__PURE__ */ React19.createElement("div", {
|
|
4024
4080
|
className: "flex-1 overflow-y-auto p-6"
|
|
4025
|
-
}, unsplashResults.length > 0 ? /* @__PURE__ */
|
|
4081
|
+
}, unsplashResults.length > 0 ? /* @__PURE__ */ React19.createElement("div", {
|
|
4026
4082
|
className: "grid grid-cols-3 gap-4"
|
|
4027
|
-
}, unsplashResults.map((result) => /* @__PURE__ */
|
|
4083
|
+
}, unsplashResults.map((result) => /* @__PURE__ */ React19.createElement("button", {
|
|
4028
4084
|
key: result.id,
|
|
4029
4085
|
onClick: () => addUnsplashImage(result.urls.regular),
|
|
4030
4086
|
className: "relative group overflow-hidden rounded-lg aspect-square"
|
|
4031
|
-
}, /* @__PURE__ */
|
|
4087
|
+
}, /* @__PURE__ */ React19.createElement("img", {
|
|
4032
4088
|
src: result.urls.thumb,
|
|
4033
4089
|
alt: "",
|
|
4034
4090
|
className: "w-full h-full object-cover group-hover:scale-110 transition-transform duration-200"
|
|
4035
|
-
}), /* @__PURE__ */
|
|
4091
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4036
4092
|
className: "absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-50 transition-opacity duration-200 flex items-center justify-center"
|
|
4037
|
-
}, /* @__PURE__ */
|
|
4093
|
+
}, /* @__PURE__ */ React19.createElement(PlusCircle, {
|
|
4038
4094
|
className: "w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
|
|
4039
|
-
}))))) : /* @__PURE__ */
|
|
4095
|
+
}))))) : /* @__PURE__ */ React19.createElement("div", {
|
|
4040
4096
|
className: "text-center text-gray-400 py-12"
|
|
4041
|
-
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */
|
|
4097
|
+
}, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React19.createElement("div", {
|
|
4042
4098
|
className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
|
|
4043
|
-
}, /* @__PURE__ */
|
|
4099
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
4044
4100
|
className: "bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-auto"
|
|
4045
|
-
}, /* @__PURE__ */
|
|
4101
|
+
}, /* @__PURE__ */ React19.createElement("h2", {
|
|
4046
4102
|
className: "text-white text-xl font-semibold mb-4"
|
|
4047
|
-
}, "Load JSON Data"), /* @__PURE__ */
|
|
4103
|
+
}, "Load JSON Data"), /* @__PURE__ */ React19.createElement("p", {
|
|
4048
4104
|
className: "text-gray-300 mb-4"
|
|
4049
|
-
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */
|
|
4105
|
+
}, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React19.createElement("textarea", {
|
|
4050
4106
|
value: jsonInputText,
|
|
4051
4107
|
onChange: (e) => setJsonInputText(e.target.value),
|
|
4052
4108
|
className: "w-full h-64 p-3 bg-gray-700 text-white border border-gray-600 rounded font-mono text-sm resize-none",
|
|
4053
4109
|
placeholder: '{"width": 800, "height": 600, "pages": [...]}'
|
|
4054
|
-
}), /* @__PURE__ */
|
|
4110
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
4055
4111
|
className: "flex justify-end space-x-3 mt-4"
|
|
4056
|
-
}, /* @__PURE__ */
|
|
4112
|
+
}, /* @__PURE__ */ React19.createElement("button", {
|
|
4057
4113
|
onClick: () => {
|
|
4058
4114
|
setShowJsonModal(false);
|
|
4059
4115
|
setJsonInputText("");
|
|
4060
4116
|
},
|
|
4061
4117
|
className: "px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
|
|
4062
|
-
}, "Cancel"), /* @__PURE__ */
|
|
4118
|
+
}, "Cancel"), /* @__PURE__ */ React19.createElement("button", {
|
|
4063
4119
|
onClick: handleImportJSONData,
|
|
4064
4120
|
className: "px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
|
|
4065
|
-
}, "Load JSON")))));
|
|
4121
|
+
}, "Load JSON"))))));
|
|
4066
4122
|
});
|
|
4067
4123
|
var CanvasEditor_default = CanvasEditor;
|
|
4068
4124
|
// src/lib/index.ts
|
|
@@ -4120,6 +4176,7 @@ function initWordPressCanvasEditor(containerId, props) {
|
|
|
4120
4176
|
return false;
|
|
4121
4177
|
}
|
|
4122
4178
|
export {
|
|
4179
|
+
useCanvasStore,
|
|
4123
4180
|
setUnsplashAccessKey,
|
|
4124
4181
|
replaceUserInputs,
|
|
4125
4182
|
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;AAiCjB,OAAO,EAA+B,MAAM,EAA0C,MAAM,gBAAgB,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;AAiCjB,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;yCAo1C9E,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;
|
|
@@ -25,6 +26,8 @@ export interface CanvasStore {
|
|
|
25
26
|
};
|
|
26
27
|
width: number;
|
|
27
28
|
height: number;
|
|
29
|
+
openSidePanel: (panelId: string | null) => void;
|
|
30
|
+
deletePages: (pageIds: string[]) => void;
|
|
28
31
|
}
|
|
29
32
|
export interface NavbarSection {
|
|
30
33
|
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;
|
|
1
|
+
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/types/Config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED