labellife-design-tool 1.1.0 → 1.1.2
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 +159 -0
- package/dist/lib/lib/index.js +276 -146
- package/dist/lib/wordpress.js +276 -146
- package/dist/types/CanvasEditor.d.ts.map +1 -1
- package/dist/types/components/LeftMenu.d.ts.map +1 -1
- 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 +36 -0
- package/dist/types/types/Config.d.ts.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -54,6 +54,165 @@ function App() {
|
|
|
54
54
|
|
|
55
55
|
**Note on CSS**: The CSS is pre-processed and ready to use. Simply import it - no Tailwind configuration needed!
|
|
56
56
|
|
|
57
|
+
### Panel Configuration (Built-in + Custom)
|
|
58
|
+
|
|
59
|
+
Control which panels appear in the left sidebar and their order using a **single list** via `config.panels`. You can mix built-in panel ids and custom panel objects in one array.
|
|
60
|
+
|
|
61
|
+
#### Available Built-in Panels
|
|
62
|
+
|
|
63
|
+
| Panel ID | Description |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `"text"` | Add and edit text elements |
|
|
66
|
+
| `"elements"` | Add shapes (rect, circle, star, polygon, etc.) |
|
|
67
|
+
| `"image"` | Upload images, use Unsplash, crop/mask/filter |
|
|
68
|
+
| `"design"` | Canvas size, presets, design settings |
|
|
69
|
+
| `"background"` | Page background color/image |
|
|
70
|
+
| `"export"` | Export to PNG/JPG/JSON (requires `config.export`) |
|
|
71
|
+
| `"variables"` | Template variables (requires `config.variables`) |
|
|
72
|
+
|
|
73
|
+
#### Show Only Selected Built-in Panels
|
|
74
|
+
|
|
75
|
+
Omit any panel id to hide it. The order you list them is the order they appear:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
<CanvasEditor
|
|
79
|
+
name="Limited Editor"
|
|
80
|
+
config={{
|
|
81
|
+
panels: ["text", "elements", "image", "background"],
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This hides Design, Export, and Variables — only Text, Elements, Images, and Background are shown.
|
|
87
|
+
|
|
88
|
+
#### Add a Custom Panel
|
|
89
|
+
|
|
90
|
+
Create your own panel component and include it in the same list:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { Sparkles } from "lucide-react";
|
|
94
|
+
|
|
95
|
+
// Your custom panel component — receives whatever props you pass
|
|
96
|
+
const MyAssetsPanel = ({ category }: { category: string }) => {
|
|
97
|
+
return (
|
|
98
|
+
<div style={{ padding: 16, color: "white" }}>
|
|
99
|
+
<h3>My Assets</h3>
|
|
100
|
+
<p>Showing assets for: {category}</p>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
function App() {
|
|
106
|
+
return (
|
|
107
|
+
<CanvasEditor
|
|
108
|
+
name="Custom Panel Editor"
|
|
109
|
+
config={{
|
|
110
|
+
export: { png: true, jpg: true, json: true },
|
|
111
|
+
panels: [
|
|
112
|
+
"text",
|
|
113
|
+
"elements",
|
|
114
|
+
{
|
|
115
|
+
id: "my-assets",
|
|
116
|
+
title: "My Assets",
|
|
117
|
+
tooltip: "Browse my assets",
|
|
118
|
+
icon: <Sparkles className="w-5 h-5" />,
|
|
119
|
+
component: MyAssetsPanel,
|
|
120
|
+
props: { category: "stickers" },
|
|
121
|
+
},
|
|
122
|
+
"image",
|
|
123
|
+
"background",
|
|
124
|
+
"export",
|
|
125
|
+
],
|
|
126
|
+
}}
|
|
127
|
+
/>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Custom Panel Definition
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
interface CustomPanelDefinition {
|
|
136
|
+
id: string; // Unique panel id
|
|
137
|
+
title: string; // Panel title
|
|
138
|
+
tooltip?: string; // Tooltip on hover (defaults to title)
|
|
139
|
+
icon: React.ReactElement; // Icon shown in the left sidebar
|
|
140
|
+
component: React.ComponentType<any>; // Your panel React component
|
|
141
|
+
props?: Record<string, any>; // Props passed to your component
|
|
142
|
+
actionType?: "setPanel" | "setToolAndPanel"; // Click behavior (default: "setPanel")
|
|
143
|
+
toolValue?: ToolType; // Tool to activate (if actionType is "setToolAndPanel")
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### Add Elements from a Custom Panel
|
|
148
|
+
|
|
149
|
+
Every panel (built-in or custom) receives a `store` prop with a Polotno-like API:
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
// Your custom panel component
|
|
153
|
+
const MyImagesPanel = ({ store }) => {
|
|
154
|
+
const handleAddImage = (url: string) => {
|
|
155
|
+
store.activePage?.addElement({
|
|
156
|
+
type: "image",
|
|
157
|
+
src: url,
|
|
158
|
+
x: 100,
|
|
159
|
+
y: 100,
|
|
160
|
+
width: 200,
|
|
161
|
+
height: 200,
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<div style={{ color: "white", padding: 16 }}>
|
|
167
|
+
<h3>My Images</h3>
|
|
168
|
+
<button onClick={() => handleAddImage("https://example.com/img.jpg")}>
|
|
169
|
+
Add Image
|
|
170
|
+
</button>
|
|
171
|
+
<p>Canvas size: {store.width} × {store.height}</p>
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// Register the panel
|
|
177
|
+
<CanvasEditor
|
|
178
|
+
config={{
|
|
179
|
+
panels: [
|
|
180
|
+
"text",
|
|
181
|
+
"elements",
|
|
182
|
+
{ id: "my-images", title: "My Images", icon: <MyIcon />, component: MyImagesPanel },
|
|
183
|
+
"image",
|
|
184
|
+
"background",
|
|
185
|
+
],
|
|
186
|
+
}}
|
|
187
|
+
/>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**CanvasStore interface**
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface CanvasStore {
|
|
194
|
+
activePage: {
|
|
195
|
+
addElement: (element: {
|
|
196
|
+
type: string;
|
|
197
|
+
src?: string;
|
|
198
|
+
x: number;
|
|
199
|
+
y: number;
|
|
200
|
+
width: number;
|
|
201
|
+
height: number;
|
|
202
|
+
}) => void;
|
|
203
|
+
};
|
|
204
|
+
width: number;
|
|
205
|
+
height: number;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### Default Behavior
|
|
210
|
+
|
|
211
|
+
If `config.panels` is **not provided**, the editor shows the default set:
|
|
212
|
+
- `text`, `elements`, `image`, `design`, `background`
|
|
213
|
+
- Plus `variables` if `config.variables` is set
|
|
214
|
+
- Plus `export` if `config.export` is set
|
|
215
|
+
|
|
57
216
|
### Configure Unsplash API Key
|
|
58
217
|
|
|
59
218
|
```tsx
|
package/dist/lib/lib/index.js
CHANGED
|
@@ -23,7 +23,7 @@ function initJsxCompat() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// src/CanvasEditor.tsx
|
|
26
|
-
import React18, { useState as useState3, useRef as useRef5, useEffect as useEffect4, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
|
|
26
|
+
import React18, { 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,
|
|
@@ -1092,7 +1092,97 @@ var Header_default = Header;
|
|
|
1092
1092
|
|
|
1093
1093
|
// src/components/LeftMenu.tsx
|
|
1094
1094
|
import React8 from "react";
|
|
1095
|
-
import {
|
|
1095
|
+
import {
|
|
1096
|
+
Type,
|
|
1097
|
+
Square,
|
|
1098
|
+
Image as ImageIcon,
|
|
1099
|
+
Palette,
|
|
1100
|
+
Download,
|
|
1101
|
+
Layers,
|
|
1102
|
+
Variable
|
|
1103
|
+
} from "lucide-react";
|
|
1104
|
+
var BUILT_IN_MENU_ITEMS = {
|
|
1105
|
+
text: {
|
|
1106
|
+
id: "text",
|
|
1107
|
+
tooltip: "Text",
|
|
1108
|
+
icon: /* @__PURE__ */ React8.createElement(Type, {
|
|
1109
|
+
className: "w-5 h-5"
|
|
1110
|
+
}),
|
|
1111
|
+
actionType: "setToolAndPanel",
|
|
1112
|
+
toolValue: "text",
|
|
1113
|
+
panelValue: "text"
|
|
1114
|
+
},
|
|
1115
|
+
elements: {
|
|
1116
|
+
id: "elements",
|
|
1117
|
+
tooltip: "Elements",
|
|
1118
|
+
icon: /* @__PURE__ */ React8.createElement(Square, {
|
|
1119
|
+
className: "w-5 h-5"
|
|
1120
|
+
}),
|
|
1121
|
+
actionType: "setToolAndPanel",
|
|
1122
|
+
panelValue: "elements",
|
|
1123
|
+
toolValue: "shape"
|
|
1124
|
+
},
|
|
1125
|
+
image: {
|
|
1126
|
+
id: "image",
|
|
1127
|
+
tooltip: "Images",
|
|
1128
|
+
icon: /* @__PURE__ */ React8.createElement(ImageIcon, {
|
|
1129
|
+
className: "w-5 h-5"
|
|
1130
|
+
}),
|
|
1131
|
+
actionType: "setPanel",
|
|
1132
|
+
panelValue: "image"
|
|
1133
|
+
},
|
|
1134
|
+
design: {
|
|
1135
|
+
id: "design",
|
|
1136
|
+
tooltip: "Design",
|
|
1137
|
+
icon: /* @__PURE__ */ React8.createElement(Palette, {
|
|
1138
|
+
className: "w-5 h-5"
|
|
1139
|
+
}),
|
|
1140
|
+
actionType: "setPanel",
|
|
1141
|
+
panelValue: "design"
|
|
1142
|
+
},
|
|
1143
|
+
background: {
|
|
1144
|
+
id: "background",
|
|
1145
|
+
tooltip: "Background",
|
|
1146
|
+
icon: /* @__PURE__ */ React8.createElement(Layers, {
|
|
1147
|
+
className: "w-5 h-5"
|
|
1148
|
+
}),
|
|
1149
|
+
actionType: "setPanel",
|
|
1150
|
+
panelValue: "background"
|
|
1151
|
+
},
|
|
1152
|
+
export: {
|
|
1153
|
+
id: "export",
|
|
1154
|
+
tooltip: "Export",
|
|
1155
|
+
icon: /* @__PURE__ */ React8.createElement(Download, {
|
|
1156
|
+
className: "w-5 h-5"
|
|
1157
|
+
}),
|
|
1158
|
+
actionType: "setPanel",
|
|
1159
|
+
panelValue: "export"
|
|
1160
|
+
},
|
|
1161
|
+
variables: {
|
|
1162
|
+
id: "variables",
|
|
1163
|
+
tooltip: "Variables",
|
|
1164
|
+
icon: /* @__PURE__ */ React8.createElement(Variable, {
|
|
1165
|
+
className: "w-5 h-5"
|
|
1166
|
+
}),
|
|
1167
|
+
actionType: "setPanel",
|
|
1168
|
+
panelValue: "variables"
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
var isCustomPanel = (panel) => typeof panel === "object" && panel !== null;
|
|
1172
|
+
var getDefaultPanelOrder = (config) => {
|
|
1173
|
+
const defaults = [
|
|
1174
|
+
"text",
|
|
1175
|
+
"elements",
|
|
1176
|
+
"image",
|
|
1177
|
+
"design",
|
|
1178
|
+
"background"
|
|
1179
|
+
];
|
|
1180
|
+
if (config?.variables)
|
|
1181
|
+
defaults.push("variables");
|
|
1182
|
+
if (config?.export)
|
|
1183
|
+
defaults.push("export");
|
|
1184
|
+
return defaults;
|
|
1185
|
+
};
|
|
1096
1186
|
var LeftMenu = ({
|
|
1097
1187
|
tool,
|
|
1098
1188
|
activePanel,
|
|
@@ -1100,77 +1190,32 @@ var LeftMenu = ({
|
|
|
1100
1190
|
onSetActivePanel,
|
|
1101
1191
|
config
|
|
1102
1192
|
}) => {
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
toolValue: "text",
|
|
1112
|
-
panelValue: "text"
|
|
1113
|
-
},
|
|
1114
|
-
{
|
|
1115
|
-
id: "elements",
|
|
1116
|
-
tooltip: "Elements",
|
|
1117
|
-
icon: /* @__PURE__ */ React8.createElement(Square, {
|
|
1118
|
-
className: "w-5 h-5"
|
|
1119
|
-
}),
|
|
1120
|
-
actionType: "setToolAndPanel",
|
|
1121
|
-
panelValue: "elements",
|
|
1122
|
-
toolValue: "shape"
|
|
1123
|
-
},
|
|
1124
|
-
{
|
|
1125
|
-
id: "image",
|
|
1126
|
-
tooltip: "Images",
|
|
1127
|
-
icon: /* @__PURE__ */ React8.createElement(ImageIcon, {
|
|
1128
|
-
className: "w-5 h-5"
|
|
1129
|
-
}),
|
|
1130
|
-
actionType: "setPanel",
|
|
1131
|
-
panelValue: "image"
|
|
1132
|
-
},
|
|
1133
|
-
{
|
|
1134
|
-
id: "design",
|
|
1135
|
-
tooltip: "Design",
|
|
1136
|
-
icon: /* @__PURE__ */ React8.createElement(Palette, {
|
|
1137
|
-
className: "w-5 h-5"
|
|
1138
|
-
}),
|
|
1139
|
-
actionType: "setPanel",
|
|
1140
|
-
panelValue: "design"
|
|
1193
|
+
const requestedPanels = config?.panels && config.panels.length > 0 ? config.panels : getDefaultPanelOrder(config);
|
|
1194
|
+
const seenIds = new Set;
|
|
1195
|
+
const menuItems = requestedPanels.map((panel) => {
|
|
1196
|
+
if (typeof panel === "string") {
|
|
1197
|
+
if (panel === "variables" && !config?.variables)
|
|
1198
|
+
return null;
|
|
1199
|
+
const builtIn = BUILT_IN_MENU_ITEMS[panel];
|
|
1200
|
+
return builtIn || null;
|
|
1141
1201
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
className: "w-5 h-5"
|
|
1159
|
-
}),
|
|
1160
|
-
actionType: "setPanel",
|
|
1161
|
-
panelValue: "background"
|
|
1202
|
+
if (isCustomPanel(panel)) {
|
|
1203
|
+
return {
|
|
1204
|
+
id: panel.id,
|
|
1205
|
+
tooltip: panel.tooltip || panel.title,
|
|
1206
|
+
icon: panel.icon,
|
|
1207
|
+
actionType: panel.actionType || "setPanel",
|
|
1208
|
+
toolValue: panel.toolValue,
|
|
1209
|
+
panelValue: panel.id
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
return null;
|
|
1213
|
+
}).filter((item) => !!item).filter((item) => {
|
|
1214
|
+
if (seenIds.has(item.id))
|
|
1215
|
+
return false;
|
|
1216
|
+
seenIds.add(item.id);
|
|
1217
|
+
return true;
|
|
1162
1218
|
});
|
|
1163
|
-
if (config?.variables) {
|
|
1164
|
-
menuItems.push({
|
|
1165
|
-
id: "variables",
|
|
1166
|
-
tooltip: "Variables",
|
|
1167
|
-
icon: /* @__PURE__ */ React8.createElement(Variable, {
|
|
1168
|
-
className: "w-5 h-5"
|
|
1169
|
-
}),
|
|
1170
|
-
actionType: "setPanel",
|
|
1171
|
-
panelValue: "variables"
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
1174
1219
|
const handleItemClick = (item) => {
|
|
1175
1220
|
if (item.actionType === "setTool" && item.toolValue) {
|
|
1176
1221
|
onSetTool(item.toolValue);
|
|
@@ -3566,104 +3611,189 @@ var CanvasEditor = forwardRef(({
|
|
|
3566
3611
|
delete window.__pendingImportReject;
|
|
3567
3612
|
}
|
|
3568
3613
|
};
|
|
3569
|
-
const
|
|
3570
|
-
{
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
component: ImagePanel_default,
|
|
3591
|
-
props: {
|
|
3592
|
-
selectedElement,
|
|
3593
|
-
updateElement,
|
|
3594
|
-
onUploadClick: () => fileInputRef.current?.click(),
|
|
3595
|
-
onUnsplashClick: () => {
|
|
3596
|
-
setShowUnsplash(true);
|
|
3597
|
-
setUnsplashMode("element");
|
|
3598
|
-
},
|
|
3599
|
-
canvasWidth: design.width,
|
|
3600
|
-
canvasHeight: design.height
|
|
3601
|
-
}
|
|
3602
|
-
},
|
|
3603
|
-
{
|
|
3604
|
-
id: "design",
|
|
3605
|
-
title: "Design",
|
|
3606
|
-
component: DesignPanel_default,
|
|
3607
|
-
props: {
|
|
3608
|
-
design,
|
|
3609
|
-
currentPage,
|
|
3610
|
-
selectedElement,
|
|
3611
|
-
setDesign,
|
|
3612
|
-
updateElement,
|
|
3613
|
-
onSetUnsplashBackground: () => {
|
|
3614
|
-
setShowUnsplash(true);
|
|
3615
|
-
setUnsplashMode("background");
|
|
3616
|
-
},
|
|
3617
|
-
config
|
|
3614
|
+
const store = useMemo(() => ({
|
|
3615
|
+
activePage: {
|
|
3616
|
+
addElement: (element) => {
|
|
3617
|
+
const newElement = {
|
|
3618
|
+
id: `element-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
3619
|
+
type: element.type,
|
|
3620
|
+
name: `${element.type} element`,
|
|
3621
|
+
x: element.x,
|
|
3622
|
+
y: element.y,
|
|
3623
|
+
width: element.width,
|
|
3624
|
+
height: element.height,
|
|
3625
|
+
rotation: 0,
|
|
3626
|
+
visible: true,
|
|
3627
|
+
locked: false,
|
|
3628
|
+
opacity: 1,
|
|
3629
|
+
...element.src && { src: element.src }
|
|
3630
|
+
};
|
|
3631
|
+
setDesign((prev) => ({
|
|
3632
|
+
...prev,
|
|
3633
|
+
pages: prev.pages.map((page) => page.id === currentPage.id ? { ...page, elements: [...page.elements, newElement] } : page)
|
|
3634
|
+
}));
|
|
3618
3635
|
}
|
|
3619
3636
|
},
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3637
|
+
width: design.width,
|
|
3638
|
+
height: design.height
|
|
3639
|
+
}), [currentPage.id, design.width, design.height]);
|
|
3640
|
+
const panelConfigs = useMemo(() => {
|
|
3641
|
+
const builtInConfigs = {
|
|
3642
|
+
elements: {
|
|
3643
|
+
id: "elements",
|
|
3644
|
+
title: "Elements",
|
|
3645
|
+
component: ElementPanel_default,
|
|
3646
|
+
props: { onAddShape: addShape, store }
|
|
3647
|
+
},
|
|
3648
|
+
text: {
|
|
3649
|
+
id: "text",
|
|
3650
|
+
title: "Text",
|
|
3651
|
+
component: TextPanel_default,
|
|
3652
|
+
props: {
|
|
3653
|
+
selectedElement,
|
|
3654
|
+
updateElement,
|
|
3655
|
+
setTool,
|
|
3656
|
+
onAddText: addText,
|
|
3657
|
+
store
|
|
3631
3658
|
}
|
|
3632
|
-
}
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3659
|
+
},
|
|
3660
|
+
image: {
|
|
3661
|
+
id: "image",
|
|
3662
|
+
title: "Images",
|
|
3663
|
+
component: ImagePanel_default,
|
|
3664
|
+
props: {
|
|
3665
|
+
selectedElement,
|
|
3666
|
+
updateElement,
|
|
3667
|
+
onUploadClick: () => fileInputRef.current?.click(),
|
|
3668
|
+
onUnsplashClick: () => {
|
|
3669
|
+
setShowUnsplash(true);
|
|
3670
|
+
setUnsplashMode("element");
|
|
3671
|
+
},
|
|
3672
|
+
canvasWidth: design.width,
|
|
3673
|
+
canvasHeight: design.height,
|
|
3674
|
+
store
|
|
3675
|
+
}
|
|
3676
|
+
},
|
|
3677
|
+
design: {
|
|
3678
|
+
id: "design",
|
|
3679
|
+
title: "Design",
|
|
3680
|
+
component: DesignPanel_default,
|
|
3681
|
+
props: {
|
|
3682
|
+
design,
|
|
3683
|
+
currentPage,
|
|
3684
|
+
selectedElement,
|
|
3685
|
+
setDesign,
|
|
3686
|
+
updateElement,
|
|
3687
|
+
onSetUnsplashBackground: () => {
|
|
3688
|
+
setShowUnsplash(true);
|
|
3689
|
+
setUnsplashMode("background");
|
|
3690
|
+
},
|
|
3691
|
+
config,
|
|
3692
|
+
store
|
|
3693
|
+
}
|
|
3694
|
+
},
|
|
3695
|
+
background: {
|
|
3696
|
+
id: "background",
|
|
3697
|
+
title: "Background",
|
|
3698
|
+
component: BackgroundPanel_default,
|
|
3699
|
+
props: {
|
|
3700
|
+
design,
|
|
3701
|
+
currentPage,
|
|
3702
|
+
setDesign,
|
|
3703
|
+
onSetUnsplashBackground: () => {
|
|
3704
|
+
setShowUnsplash(true);
|
|
3705
|
+
setUnsplashMode("background");
|
|
3706
|
+
},
|
|
3707
|
+
store
|
|
3708
|
+
}
|
|
3709
|
+
},
|
|
3710
|
+
variables: config?.variables ? {
|
|
3636
3711
|
id: "variables",
|
|
3637
3712
|
title: "Variables",
|
|
3638
3713
|
component: VariablesPanel_default,
|
|
3639
3714
|
props: {
|
|
3640
3715
|
config,
|
|
3641
3716
|
design,
|
|
3642
|
-
setDesign
|
|
3717
|
+
setDesign,
|
|
3718
|
+
store
|
|
3643
3719
|
}
|
|
3644
|
-
}
|
|
3645
|
-
|
|
3646
|
-
...config?.export ? [
|
|
3647
|
-
{
|
|
3720
|
+
} : null,
|
|
3721
|
+
export: {
|
|
3648
3722
|
id: "export",
|
|
3649
3723
|
title: "Export",
|
|
3650
3724
|
component: ExportPanel_default,
|
|
3651
3725
|
props: {
|
|
3652
|
-
onExportToPNG: config
|
|
3726
|
+
onExportToPNG: config?.export?.png ? () => {
|
|
3653
3727
|
if (stageRef.current)
|
|
3654
3728
|
exportToPNG(stageRef.current, design);
|
|
3655
3729
|
} : undefined,
|
|
3656
|
-
onExportToJPG: config
|
|
3730
|
+
onExportToJPG: config?.export?.jpg ? () => {
|
|
3657
3731
|
if (stageRef.current)
|
|
3658
3732
|
exportToJPG(stageRef.current, design);
|
|
3659
3733
|
} : undefined,
|
|
3660
|
-
onExportToJSON: config
|
|
3734
|
+
onExportToJSON: config?.export?.json ? () => exportToJSON(design) : undefined,
|
|
3661
3735
|
onImportJSON: () => jsonInputRef.current?.click(),
|
|
3662
|
-
onLoadJSON: () => setShowJsonModal(true)
|
|
3736
|
+
onLoadJSON: () => setShowJsonModal(true),
|
|
3737
|
+
store
|
|
3663
3738
|
}
|
|
3664
3739
|
}
|
|
3665
|
-
|
|
3666
|
-
|
|
3740
|
+
};
|
|
3741
|
+
const defaultPanels = [
|
|
3742
|
+
"text",
|
|
3743
|
+
"elements",
|
|
3744
|
+
"image",
|
|
3745
|
+
"design",
|
|
3746
|
+
"background",
|
|
3747
|
+
...config?.variables ? ["variables"] : [],
|
|
3748
|
+
...config?.export ? ["export"] : []
|
|
3749
|
+
];
|
|
3750
|
+
const requestedPanels = config?.panels && config.panels.length > 0 ? config.panels : defaultPanels;
|
|
3751
|
+
const seen = new Set;
|
|
3752
|
+
const ordered = [];
|
|
3753
|
+
requestedPanels.forEach((panel) => {
|
|
3754
|
+
if (typeof panel === "string") {
|
|
3755
|
+
const builtIn = builtInConfigs[panel];
|
|
3756
|
+
if (!builtIn)
|
|
3757
|
+
return;
|
|
3758
|
+
if (seen.has(builtIn.id))
|
|
3759
|
+
return;
|
|
3760
|
+
seen.add(builtIn.id);
|
|
3761
|
+
ordered.push(builtIn);
|
|
3762
|
+
return;
|
|
3763
|
+
}
|
|
3764
|
+
const custom = panel;
|
|
3765
|
+
if (!custom?.id || !custom?.component)
|
|
3766
|
+
return;
|
|
3767
|
+
if (seen.has(custom.id))
|
|
3768
|
+
return;
|
|
3769
|
+
seen.add(custom.id);
|
|
3770
|
+
ordered.push({
|
|
3771
|
+
id: custom.id,
|
|
3772
|
+
title: custom.title,
|
|
3773
|
+
component: custom.component,
|
|
3774
|
+
props: { ...custom.props, store }
|
|
3775
|
+
});
|
|
3776
|
+
});
|
|
3777
|
+
return ordered;
|
|
3778
|
+
}, [
|
|
3779
|
+
addShape,
|
|
3780
|
+
addText,
|
|
3781
|
+
config,
|
|
3782
|
+
currentPage,
|
|
3783
|
+
design,
|
|
3784
|
+
selectedElement,
|
|
3785
|
+
setTool,
|
|
3786
|
+
updateElement,
|
|
3787
|
+
store
|
|
3788
|
+
]);
|
|
3789
|
+
useEffect4(() => {
|
|
3790
|
+
if (!panelConfigs.length)
|
|
3791
|
+
return;
|
|
3792
|
+
const exists = panelConfigs.some((panel) => panel.id === activePanelId);
|
|
3793
|
+
if (!exists) {
|
|
3794
|
+
setActivePanelId(panelConfigs[0].id);
|
|
3795
|
+
}
|
|
3796
|
+
}, [panelConfigs, activePanelId]);
|
|
3667
3797
|
const DynamicPanelRenderer = () => {
|
|
3668
3798
|
const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
|
|
3669
3799
|
if (!activePanelConfig) {
|
package/dist/lib/wordpress.js
CHANGED
|
@@ -23,7 +23,7 @@ function initJsxCompat() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// src/CanvasEditor.tsx
|
|
26
|
-
import React18, { useState as useState3, useRef as useRef5, useEffect as useEffect4, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
|
|
26
|
+
import React18, { 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,
|
|
@@ -1092,7 +1092,97 @@ var Header_default = Header;
|
|
|
1092
1092
|
|
|
1093
1093
|
// src/components/LeftMenu.tsx
|
|
1094
1094
|
import React8 from "react";
|
|
1095
|
-
import {
|
|
1095
|
+
import {
|
|
1096
|
+
Type,
|
|
1097
|
+
Square,
|
|
1098
|
+
Image as ImageIcon,
|
|
1099
|
+
Palette,
|
|
1100
|
+
Download,
|
|
1101
|
+
Layers,
|
|
1102
|
+
Variable
|
|
1103
|
+
} from "lucide-react";
|
|
1104
|
+
var BUILT_IN_MENU_ITEMS = {
|
|
1105
|
+
text: {
|
|
1106
|
+
id: "text",
|
|
1107
|
+
tooltip: "Text",
|
|
1108
|
+
icon: /* @__PURE__ */ React8.createElement(Type, {
|
|
1109
|
+
className: "w-5 h-5"
|
|
1110
|
+
}),
|
|
1111
|
+
actionType: "setToolAndPanel",
|
|
1112
|
+
toolValue: "text",
|
|
1113
|
+
panelValue: "text"
|
|
1114
|
+
},
|
|
1115
|
+
elements: {
|
|
1116
|
+
id: "elements",
|
|
1117
|
+
tooltip: "Elements",
|
|
1118
|
+
icon: /* @__PURE__ */ React8.createElement(Square, {
|
|
1119
|
+
className: "w-5 h-5"
|
|
1120
|
+
}),
|
|
1121
|
+
actionType: "setToolAndPanel",
|
|
1122
|
+
panelValue: "elements",
|
|
1123
|
+
toolValue: "shape"
|
|
1124
|
+
},
|
|
1125
|
+
image: {
|
|
1126
|
+
id: "image",
|
|
1127
|
+
tooltip: "Images",
|
|
1128
|
+
icon: /* @__PURE__ */ React8.createElement(ImageIcon, {
|
|
1129
|
+
className: "w-5 h-5"
|
|
1130
|
+
}),
|
|
1131
|
+
actionType: "setPanel",
|
|
1132
|
+
panelValue: "image"
|
|
1133
|
+
},
|
|
1134
|
+
design: {
|
|
1135
|
+
id: "design",
|
|
1136
|
+
tooltip: "Design",
|
|
1137
|
+
icon: /* @__PURE__ */ React8.createElement(Palette, {
|
|
1138
|
+
className: "w-5 h-5"
|
|
1139
|
+
}),
|
|
1140
|
+
actionType: "setPanel",
|
|
1141
|
+
panelValue: "design"
|
|
1142
|
+
},
|
|
1143
|
+
background: {
|
|
1144
|
+
id: "background",
|
|
1145
|
+
tooltip: "Background",
|
|
1146
|
+
icon: /* @__PURE__ */ React8.createElement(Layers, {
|
|
1147
|
+
className: "w-5 h-5"
|
|
1148
|
+
}),
|
|
1149
|
+
actionType: "setPanel",
|
|
1150
|
+
panelValue: "background"
|
|
1151
|
+
},
|
|
1152
|
+
export: {
|
|
1153
|
+
id: "export",
|
|
1154
|
+
tooltip: "Export",
|
|
1155
|
+
icon: /* @__PURE__ */ React8.createElement(Download, {
|
|
1156
|
+
className: "w-5 h-5"
|
|
1157
|
+
}),
|
|
1158
|
+
actionType: "setPanel",
|
|
1159
|
+
panelValue: "export"
|
|
1160
|
+
},
|
|
1161
|
+
variables: {
|
|
1162
|
+
id: "variables",
|
|
1163
|
+
tooltip: "Variables",
|
|
1164
|
+
icon: /* @__PURE__ */ React8.createElement(Variable, {
|
|
1165
|
+
className: "w-5 h-5"
|
|
1166
|
+
}),
|
|
1167
|
+
actionType: "setPanel",
|
|
1168
|
+
panelValue: "variables"
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
var isCustomPanel = (panel) => typeof panel === "object" && panel !== null;
|
|
1172
|
+
var getDefaultPanelOrder = (config) => {
|
|
1173
|
+
const defaults = [
|
|
1174
|
+
"text",
|
|
1175
|
+
"elements",
|
|
1176
|
+
"image",
|
|
1177
|
+
"design",
|
|
1178
|
+
"background"
|
|
1179
|
+
];
|
|
1180
|
+
if (config?.variables)
|
|
1181
|
+
defaults.push("variables");
|
|
1182
|
+
if (config?.export)
|
|
1183
|
+
defaults.push("export");
|
|
1184
|
+
return defaults;
|
|
1185
|
+
};
|
|
1096
1186
|
var LeftMenu = ({
|
|
1097
1187
|
tool,
|
|
1098
1188
|
activePanel,
|
|
@@ -1100,77 +1190,32 @@ var LeftMenu = ({
|
|
|
1100
1190
|
onSetActivePanel,
|
|
1101
1191
|
config
|
|
1102
1192
|
}) => {
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
toolValue: "text",
|
|
1112
|
-
panelValue: "text"
|
|
1113
|
-
},
|
|
1114
|
-
{
|
|
1115
|
-
id: "elements",
|
|
1116
|
-
tooltip: "Elements",
|
|
1117
|
-
icon: /* @__PURE__ */ React8.createElement(Square, {
|
|
1118
|
-
className: "w-5 h-5"
|
|
1119
|
-
}),
|
|
1120
|
-
actionType: "setToolAndPanel",
|
|
1121
|
-
panelValue: "elements",
|
|
1122
|
-
toolValue: "shape"
|
|
1123
|
-
},
|
|
1124
|
-
{
|
|
1125
|
-
id: "image",
|
|
1126
|
-
tooltip: "Images",
|
|
1127
|
-
icon: /* @__PURE__ */ React8.createElement(ImageIcon, {
|
|
1128
|
-
className: "w-5 h-5"
|
|
1129
|
-
}),
|
|
1130
|
-
actionType: "setPanel",
|
|
1131
|
-
panelValue: "image"
|
|
1132
|
-
},
|
|
1133
|
-
{
|
|
1134
|
-
id: "design",
|
|
1135
|
-
tooltip: "Design",
|
|
1136
|
-
icon: /* @__PURE__ */ React8.createElement(Palette, {
|
|
1137
|
-
className: "w-5 h-5"
|
|
1138
|
-
}),
|
|
1139
|
-
actionType: "setPanel",
|
|
1140
|
-
panelValue: "design"
|
|
1193
|
+
const requestedPanels = config?.panels && config.panels.length > 0 ? config.panels : getDefaultPanelOrder(config);
|
|
1194
|
+
const seenIds = new Set;
|
|
1195
|
+
const menuItems = requestedPanels.map((panel) => {
|
|
1196
|
+
if (typeof panel === "string") {
|
|
1197
|
+
if (panel === "variables" && !config?.variables)
|
|
1198
|
+
return null;
|
|
1199
|
+
const builtIn = BUILT_IN_MENU_ITEMS[panel];
|
|
1200
|
+
return builtIn || null;
|
|
1141
1201
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
className: "w-5 h-5"
|
|
1159
|
-
}),
|
|
1160
|
-
actionType: "setPanel",
|
|
1161
|
-
panelValue: "background"
|
|
1202
|
+
if (isCustomPanel(panel)) {
|
|
1203
|
+
return {
|
|
1204
|
+
id: panel.id,
|
|
1205
|
+
tooltip: panel.tooltip || panel.title,
|
|
1206
|
+
icon: panel.icon,
|
|
1207
|
+
actionType: panel.actionType || "setPanel",
|
|
1208
|
+
toolValue: panel.toolValue,
|
|
1209
|
+
panelValue: panel.id
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
return null;
|
|
1213
|
+
}).filter((item) => !!item).filter((item) => {
|
|
1214
|
+
if (seenIds.has(item.id))
|
|
1215
|
+
return false;
|
|
1216
|
+
seenIds.add(item.id);
|
|
1217
|
+
return true;
|
|
1162
1218
|
});
|
|
1163
|
-
if (config?.variables) {
|
|
1164
|
-
menuItems.push({
|
|
1165
|
-
id: "variables",
|
|
1166
|
-
tooltip: "Variables",
|
|
1167
|
-
icon: /* @__PURE__ */ React8.createElement(Variable, {
|
|
1168
|
-
className: "w-5 h-5"
|
|
1169
|
-
}),
|
|
1170
|
-
actionType: "setPanel",
|
|
1171
|
-
panelValue: "variables"
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
1174
1219
|
const handleItemClick = (item) => {
|
|
1175
1220
|
if (item.actionType === "setTool" && item.toolValue) {
|
|
1176
1221
|
onSetTool(item.toolValue);
|
|
@@ -3566,104 +3611,189 @@ var CanvasEditor = forwardRef(({
|
|
|
3566
3611
|
delete window.__pendingImportReject;
|
|
3567
3612
|
}
|
|
3568
3613
|
};
|
|
3569
|
-
const
|
|
3570
|
-
{
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
component: ImagePanel_default,
|
|
3591
|
-
props: {
|
|
3592
|
-
selectedElement,
|
|
3593
|
-
updateElement,
|
|
3594
|
-
onUploadClick: () => fileInputRef.current?.click(),
|
|
3595
|
-
onUnsplashClick: () => {
|
|
3596
|
-
setShowUnsplash(true);
|
|
3597
|
-
setUnsplashMode("element");
|
|
3598
|
-
},
|
|
3599
|
-
canvasWidth: design.width,
|
|
3600
|
-
canvasHeight: design.height
|
|
3601
|
-
}
|
|
3602
|
-
},
|
|
3603
|
-
{
|
|
3604
|
-
id: "design",
|
|
3605
|
-
title: "Design",
|
|
3606
|
-
component: DesignPanel_default,
|
|
3607
|
-
props: {
|
|
3608
|
-
design,
|
|
3609
|
-
currentPage,
|
|
3610
|
-
selectedElement,
|
|
3611
|
-
setDesign,
|
|
3612
|
-
updateElement,
|
|
3613
|
-
onSetUnsplashBackground: () => {
|
|
3614
|
-
setShowUnsplash(true);
|
|
3615
|
-
setUnsplashMode("background");
|
|
3616
|
-
},
|
|
3617
|
-
config
|
|
3614
|
+
const store = useMemo(() => ({
|
|
3615
|
+
activePage: {
|
|
3616
|
+
addElement: (element) => {
|
|
3617
|
+
const newElement = {
|
|
3618
|
+
id: `element-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
3619
|
+
type: element.type,
|
|
3620
|
+
name: `${element.type} element`,
|
|
3621
|
+
x: element.x,
|
|
3622
|
+
y: element.y,
|
|
3623
|
+
width: element.width,
|
|
3624
|
+
height: element.height,
|
|
3625
|
+
rotation: 0,
|
|
3626
|
+
visible: true,
|
|
3627
|
+
locked: false,
|
|
3628
|
+
opacity: 1,
|
|
3629
|
+
...element.src && { src: element.src }
|
|
3630
|
+
};
|
|
3631
|
+
setDesign((prev) => ({
|
|
3632
|
+
...prev,
|
|
3633
|
+
pages: prev.pages.map((page) => page.id === currentPage.id ? { ...page, elements: [...page.elements, newElement] } : page)
|
|
3634
|
+
}));
|
|
3618
3635
|
}
|
|
3619
3636
|
},
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3637
|
+
width: design.width,
|
|
3638
|
+
height: design.height
|
|
3639
|
+
}), [currentPage.id, design.width, design.height]);
|
|
3640
|
+
const panelConfigs = useMemo(() => {
|
|
3641
|
+
const builtInConfigs = {
|
|
3642
|
+
elements: {
|
|
3643
|
+
id: "elements",
|
|
3644
|
+
title: "Elements",
|
|
3645
|
+
component: ElementPanel_default,
|
|
3646
|
+
props: { onAddShape: addShape, store }
|
|
3647
|
+
},
|
|
3648
|
+
text: {
|
|
3649
|
+
id: "text",
|
|
3650
|
+
title: "Text",
|
|
3651
|
+
component: TextPanel_default,
|
|
3652
|
+
props: {
|
|
3653
|
+
selectedElement,
|
|
3654
|
+
updateElement,
|
|
3655
|
+
setTool,
|
|
3656
|
+
onAddText: addText,
|
|
3657
|
+
store
|
|
3631
3658
|
}
|
|
3632
|
-
}
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3659
|
+
},
|
|
3660
|
+
image: {
|
|
3661
|
+
id: "image",
|
|
3662
|
+
title: "Images",
|
|
3663
|
+
component: ImagePanel_default,
|
|
3664
|
+
props: {
|
|
3665
|
+
selectedElement,
|
|
3666
|
+
updateElement,
|
|
3667
|
+
onUploadClick: () => fileInputRef.current?.click(),
|
|
3668
|
+
onUnsplashClick: () => {
|
|
3669
|
+
setShowUnsplash(true);
|
|
3670
|
+
setUnsplashMode("element");
|
|
3671
|
+
},
|
|
3672
|
+
canvasWidth: design.width,
|
|
3673
|
+
canvasHeight: design.height,
|
|
3674
|
+
store
|
|
3675
|
+
}
|
|
3676
|
+
},
|
|
3677
|
+
design: {
|
|
3678
|
+
id: "design",
|
|
3679
|
+
title: "Design",
|
|
3680
|
+
component: DesignPanel_default,
|
|
3681
|
+
props: {
|
|
3682
|
+
design,
|
|
3683
|
+
currentPage,
|
|
3684
|
+
selectedElement,
|
|
3685
|
+
setDesign,
|
|
3686
|
+
updateElement,
|
|
3687
|
+
onSetUnsplashBackground: () => {
|
|
3688
|
+
setShowUnsplash(true);
|
|
3689
|
+
setUnsplashMode("background");
|
|
3690
|
+
},
|
|
3691
|
+
config,
|
|
3692
|
+
store
|
|
3693
|
+
}
|
|
3694
|
+
},
|
|
3695
|
+
background: {
|
|
3696
|
+
id: "background",
|
|
3697
|
+
title: "Background",
|
|
3698
|
+
component: BackgroundPanel_default,
|
|
3699
|
+
props: {
|
|
3700
|
+
design,
|
|
3701
|
+
currentPage,
|
|
3702
|
+
setDesign,
|
|
3703
|
+
onSetUnsplashBackground: () => {
|
|
3704
|
+
setShowUnsplash(true);
|
|
3705
|
+
setUnsplashMode("background");
|
|
3706
|
+
},
|
|
3707
|
+
store
|
|
3708
|
+
}
|
|
3709
|
+
},
|
|
3710
|
+
variables: config?.variables ? {
|
|
3636
3711
|
id: "variables",
|
|
3637
3712
|
title: "Variables",
|
|
3638
3713
|
component: VariablesPanel_default,
|
|
3639
3714
|
props: {
|
|
3640
3715
|
config,
|
|
3641
3716
|
design,
|
|
3642
|
-
setDesign
|
|
3717
|
+
setDesign,
|
|
3718
|
+
store
|
|
3643
3719
|
}
|
|
3644
|
-
}
|
|
3645
|
-
|
|
3646
|
-
...config?.export ? [
|
|
3647
|
-
{
|
|
3720
|
+
} : null,
|
|
3721
|
+
export: {
|
|
3648
3722
|
id: "export",
|
|
3649
3723
|
title: "Export",
|
|
3650
3724
|
component: ExportPanel_default,
|
|
3651
3725
|
props: {
|
|
3652
|
-
onExportToPNG: config
|
|
3726
|
+
onExportToPNG: config?.export?.png ? () => {
|
|
3653
3727
|
if (stageRef.current)
|
|
3654
3728
|
exportToPNG(stageRef.current, design);
|
|
3655
3729
|
} : undefined,
|
|
3656
|
-
onExportToJPG: config
|
|
3730
|
+
onExportToJPG: config?.export?.jpg ? () => {
|
|
3657
3731
|
if (stageRef.current)
|
|
3658
3732
|
exportToJPG(stageRef.current, design);
|
|
3659
3733
|
} : undefined,
|
|
3660
|
-
onExportToJSON: config
|
|
3734
|
+
onExportToJSON: config?.export?.json ? () => exportToJSON(design) : undefined,
|
|
3661
3735
|
onImportJSON: () => jsonInputRef.current?.click(),
|
|
3662
|
-
onLoadJSON: () => setShowJsonModal(true)
|
|
3736
|
+
onLoadJSON: () => setShowJsonModal(true),
|
|
3737
|
+
store
|
|
3663
3738
|
}
|
|
3664
3739
|
}
|
|
3665
|
-
|
|
3666
|
-
|
|
3740
|
+
};
|
|
3741
|
+
const defaultPanels = [
|
|
3742
|
+
"text",
|
|
3743
|
+
"elements",
|
|
3744
|
+
"image",
|
|
3745
|
+
"design",
|
|
3746
|
+
"background",
|
|
3747
|
+
...config?.variables ? ["variables"] : [],
|
|
3748
|
+
...config?.export ? ["export"] : []
|
|
3749
|
+
];
|
|
3750
|
+
const requestedPanels = config?.panels && config.panels.length > 0 ? config.panels : defaultPanels;
|
|
3751
|
+
const seen = new Set;
|
|
3752
|
+
const ordered = [];
|
|
3753
|
+
requestedPanels.forEach((panel) => {
|
|
3754
|
+
if (typeof panel === "string") {
|
|
3755
|
+
const builtIn = builtInConfigs[panel];
|
|
3756
|
+
if (!builtIn)
|
|
3757
|
+
return;
|
|
3758
|
+
if (seen.has(builtIn.id))
|
|
3759
|
+
return;
|
|
3760
|
+
seen.add(builtIn.id);
|
|
3761
|
+
ordered.push(builtIn);
|
|
3762
|
+
return;
|
|
3763
|
+
}
|
|
3764
|
+
const custom = panel;
|
|
3765
|
+
if (!custom?.id || !custom?.component)
|
|
3766
|
+
return;
|
|
3767
|
+
if (seen.has(custom.id))
|
|
3768
|
+
return;
|
|
3769
|
+
seen.add(custom.id);
|
|
3770
|
+
ordered.push({
|
|
3771
|
+
id: custom.id,
|
|
3772
|
+
title: custom.title,
|
|
3773
|
+
component: custom.component,
|
|
3774
|
+
props: { ...custom.props, store }
|
|
3775
|
+
});
|
|
3776
|
+
});
|
|
3777
|
+
return ordered;
|
|
3778
|
+
}, [
|
|
3779
|
+
addShape,
|
|
3780
|
+
addText,
|
|
3781
|
+
config,
|
|
3782
|
+
currentPage,
|
|
3783
|
+
design,
|
|
3784
|
+
selectedElement,
|
|
3785
|
+
setTool,
|
|
3786
|
+
updateElement,
|
|
3787
|
+
store
|
|
3788
|
+
]);
|
|
3789
|
+
useEffect4(() => {
|
|
3790
|
+
if (!panelConfigs.length)
|
|
3791
|
+
return;
|
|
3792
|
+
const exists = panelConfigs.some((panel) => panel.id === activePanelId);
|
|
3793
|
+
if (!exists) {
|
|
3794
|
+
setActivePanelId(panelConfigs[0].id);
|
|
3795
|
+
}
|
|
3796
|
+
}, [panelConfigs, activePanelId]);
|
|
3667
3797
|
const DynamicPanelRenderer = () => {
|
|
3668
3798
|
const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
|
|
3669
3799
|
if (!activePanelConfig) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CanvasEditor.d.ts","sourceRoot":"","sources":["../../src/CanvasEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
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;AAG7G,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;yCA4wC9E,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LeftMenu.d.ts","sourceRoot":"","sources":["../../../src/components/LeftMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"LeftMenu.d.ts","sourceRoot":"","sources":["../../../src/components/LeftMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAEL,MAAM,EAGP,MAAM,iBAAiB,CAAC;AAWzB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,aAAa,CAAC;IAC3B,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA2ED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA2F5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -15,6 +15,7 @@ export interface CanvasEditorRef {
|
|
|
15
15
|
}
|
|
16
16
|
export { default as CanvasEditor } from '../CanvasEditor';
|
|
17
17
|
export * from '../types';
|
|
18
|
+
export type { BuiltInPanelId, CanvasStore, CustomPanelDefinition, PanelDefinition, } from '../types/Config';
|
|
18
19
|
export { exportToPNG, exportToJPG, exportToJSON, exportToJSONObject, importFromJSON, importFromJSONData, // Import JSON data directly (no file needed)
|
|
19
20
|
loadTemplateFromJSON, // Simplified template loading utility
|
|
20
21
|
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,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,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,3 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ToolType } from "./ToolType";
|
|
3
|
+
export type BuiltInPanelId = "elements" | "design" | "text" | "image" | "background" | "export" | "variables";
|
|
4
|
+
export interface CustomPanelDefinition {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
tooltip?: string;
|
|
8
|
+
icon: React.ReactElement<React.ComponentProps<any>>;
|
|
9
|
+
component: React.ComponentType<any>;
|
|
10
|
+
props?: Record<string, any>;
|
|
11
|
+
actionType?: "setPanel" | "setToolAndPanel";
|
|
12
|
+
toolValue?: ToolType;
|
|
13
|
+
}
|
|
14
|
+
export type PanelDefinition = BuiltInPanelId | CustomPanelDefinition;
|
|
15
|
+
export interface CanvasStore {
|
|
16
|
+
activePage: {
|
|
17
|
+
addElement: (element: {
|
|
18
|
+
type: string;
|
|
19
|
+
src?: string;
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
}) => void;
|
|
25
|
+
};
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
}
|
|
1
29
|
export interface NavbarSection {
|
|
2
30
|
id: string;
|
|
3
31
|
type: 'default' | 'custom';
|
|
@@ -36,5 +64,13 @@ export interface Config {
|
|
|
36
64
|
variable: string;
|
|
37
65
|
}[];
|
|
38
66
|
navbar?: NavbarConfig;
|
|
67
|
+
/**
|
|
68
|
+
* Single source of truth for left-panel order/visibility and custom panels.
|
|
69
|
+
*
|
|
70
|
+
* Built-in panel ids: "text", "elements", "image", "design", "background", "export", "variables"
|
|
71
|
+
* Custom panel objects can be mixed in this same list.
|
|
72
|
+
* If not provided, defaults to all built-in panels.
|
|
73
|
+
*/
|
|
74
|
+
panels?: PanelDefinition[];
|
|
39
75
|
}
|
|
40
76
|
//# sourceMappingURL=Config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/types/Config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IAEjC,eAAe,CAAC,EAAE;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;KACvC,CAAC;CACH;AAED,MAAM,WAAW,MAAM;IACrB,MAAM,CAAC,EAAE;QACP,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CAAC;IACJ,MAAM,CAAC,EAAE,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/types/Config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "labellife-design-tool",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Professional canvas editor built with React, TypeScript, and Konva",
|
|
5
|
-
"main": "./dist/lib/index.js",
|
|
6
|
-
"module": "./dist/lib/index.js",
|
|
7
|
-
"types": "./dist/lib/index.d.ts",
|
|
5
|
+
"main": "./dist/lib/lib/index.js",
|
|
6
|
+
"module": "./dist/lib/lib/index.js",
|
|
7
|
+
"types": "./dist/lib/lib/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"import": "./dist/lib/index.js",
|
|
12
|
-
"types": "./dist/lib/index.d.ts"
|
|
11
|
+
"import": "./dist/lib/lib/index.js",
|
|
12
|
+
"types": "./dist/lib/lib/index.d.ts"
|
|
13
13
|
},
|
|
14
14
|
"./wordpress": {
|
|
15
15
|
"import": "./dist/lib/wordpress.js",
|