labellife-design-tool 1.1.3 → 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 CHANGED
@@ -146,7 +146,40 @@ interface CustomPanelDefinition {
146
146
 
147
147
  #### Add Elements from a Custom Panel
148
148
 
149
- Every panel (built-in or custom) receives a `store` prop with a Polotno-like API:
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;
@@ -204,6 +238,7 @@ interface CanvasStore {
204
238
  width: number;
205
239
  height: number;
206
240
  openSidePanel: (panelId: string | null) => void;
241
+ deletePages: (pageIds: string[]) => void;
207
242
  }
208
243
  ```
209
244
 
@@ -216,12 +251,21 @@ const MyPanel = ({ store }) => {
216
251
  const closeAllPanels = () => store.openSidePanel(null);
217
252
  const tryOpenUnknown = () => store.openSidePanel("nonexistent"); // closes all panels
218
253
 
254
+ const deletePage1 = () => store.deletePages(["page-1"]);
255
+ const deleteMultiplePages = () => store.deletePages(["page-1", "page-2", "page-3"]);
256
+
219
257
  return (
220
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
+
221
262
  <button onClick={openTextPanel}>Open Text Panel</button>
222
263
  <button onClick={openCustomPanel}>Open Custom Panel</button>
223
264
  <button onClick={closeAllPanels}>Close All Panels</button>
224
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>
225
269
  </div>
226
270
  );
227
271
  };
@@ -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, useMemo, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
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,27 @@ 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
+ });
3659
3692
  }
3660
3693
  }), [currentPage.id, design.width, design.height, config, setActivePanelId]);
3661
3694
  const panelConfigs = useMemo(() => {
@@ -3818,12 +3851,12 @@ var CanvasEditor = forwardRef(({
3818
3851
  const DynamicPanelRenderer = () => {
3819
3852
  const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
3820
3853
  if (!activePanelConfig) {
3821
- return /* @__PURE__ */ React18.createElement("div", {
3854
+ return /* @__PURE__ */ React19.createElement("div", {
3822
3855
  className: "text-white"
3823
3856
  }, "Panel not found");
3824
3857
  }
3825
3858
  const PanelComponent = activePanelConfig.component;
3826
- return /* @__PURE__ */ React18.createElement(PanelComponent, {
3859
+ return /* @__PURE__ */ React19.createElement(PanelComponent, {
3827
3860
  ...activePanelConfig.props
3828
3861
  });
3829
3862
  };
@@ -3876,9 +3909,11 @@ var CanvasEditor = forwardRef(({
3876
3909
  setHistoryIndex(0);
3877
3910
  }
3878
3911
  }, []);
3879
- return /* @__PURE__ */ React18.createElement("div", {
3912
+ return /* @__PURE__ */ React19.createElement(CanvasStoreContext.Provider, {
3913
+ value: store
3914
+ }, /* @__PURE__ */ React19.createElement("div", {
3880
3915
  className: "h-screen flex flex-col bg-gray-900"
3881
- }, /* @__PURE__ */ React18.createElement(Header_default, {
3916
+ }, /* @__PURE__ */ React19.createElement(Header_default, {
3882
3917
  name,
3883
3918
  zoom,
3884
3919
  historyIndex,
@@ -3890,37 +3925,37 @@ var CanvasEditor = forwardRef(({
3890
3925
  onZoomReset: () => setZoom(calculateFitToScreenZoom(design.width, design.height)),
3891
3926
  onSetActivePanel: setActivePanelId,
3892
3927
  navbarConfig: config?.navbar
3893
- }), /* @__PURE__ */ React18.createElement("div", {
3928
+ }), /* @__PURE__ */ React19.createElement("div", {
3894
3929
  className: "flex-1 flex overflow-hidden"
3895
- }, /* @__PURE__ */ React18.createElement("div", {
3930
+ }, /* @__PURE__ */ React19.createElement("div", {
3896
3931
  className: "w-80 bg-gray-800 border-r border-gray-700 flex"
3897
- }, /* @__PURE__ */ React18.createElement(LeftMenu_default, {
3932
+ }, /* @__PURE__ */ React19.createElement(LeftMenu_default, {
3898
3933
  tool,
3899
3934
  activePanel: activePanelId,
3900
3935
  onSetTool: setTool,
3901
3936
  onSetActivePanel: setActivePanelId,
3902
3937
  config
3903
- }), /* @__PURE__ */ React18.createElement("div", {
3938
+ }), /* @__PURE__ */ React19.createElement("div", {
3904
3939
  className: "flex-1 p-4 overflow-y-auto"
3905
- }, /* @__PURE__ */ React18.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React18.createElement("div", {
3940
+ }, /* @__PURE__ */ React19.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React19.createElement("div", {
3906
3941
  className: "flex-1 bg-gray-700 overflow-hidden relative",
3907
3942
  ref: containerRef
3908
- }, /* @__PURE__ */ React18.createElement("div", {
3943
+ }, /* @__PURE__ */ React19.createElement("div", {
3909
3944
  className: "absolute inset-0 flex items-center justify-center"
3910
- }, /* @__PURE__ */ React18.createElement("div", {
3945
+ }, /* @__PURE__ */ React19.createElement("div", {
3911
3946
  className: "bg-white shadow-2xl",
3912
3947
  style: {
3913
3948
  transform: `scale(${zoom})`,
3914
3949
  transformOrigin: "center center"
3915
3950
  }
3916
- }, /* @__PURE__ */ React18.createElement(Stage, {
3951
+ }, /* @__PURE__ */ React19.createElement(Stage, {
3917
3952
  key: `canvas-${design.id || design.width}-${design.height}`,
3918
3953
  ref: stageRef,
3919
3954
  width: design.width,
3920
3955
  height: design.height,
3921
3956
  onClick: handleStageClick,
3922
3957
  onTap: handleStageClick
3923
- }, /* @__PURE__ */ React18.createElement(Layer, null, /* @__PURE__ */ React18.createElement(Rect2, {
3958
+ }, /* @__PURE__ */ React19.createElement(Layer, null, /* @__PURE__ */ React19.createElement(Rect2, {
3924
3959
  x: 0,
3925
3960
  y: 0,
3926
3961
  width: design.width,
@@ -3931,7 +3966,7 @@ var CanvasEditor = forwardRef(({
3931
3966
  }), currentPage.elements.map((element) => {
3932
3967
  switch (element.type) {
3933
3968
  case "text":
3934
- return React18.createElement(EditableTextElement, {
3969
+ return React19.createElement(EditableTextElement, {
3935
3970
  key: element.id,
3936
3971
  element,
3937
3972
  isSelected: element.id === selectedId,
@@ -3942,7 +3977,7 @@ var CanvasEditor = forwardRef(({
3942
3977
  onChange: (attrs) => updateElement(element.id, attrs)
3943
3978
  });
3944
3979
  case "image":
3945
- return React18.createElement(UrlImageElement, {
3980
+ return React19.createElement(UrlImageElement, {
3946
3981
  key: element.id,
3947
3982
  element,
3948
3983
  isSelected: element.id === selectedId,
@@ -3953,7 +3988,7 @@ var CanvasEditor = forwardRef(({
3953
3988
  onChange: (attrs) => updateElement(element.id, attrs)
3954
3989
  });
3955
3990
  case "shape":
3956
- return React18.createElement(ShapeElement, {
3991
+ return React19.createElement(ShapeElement, {
3957
3992
  key: element.id,
3958
3993
  element,
3959
3994
  isSelected: element.id === selectedId,
@@ -3966,27 +4001,27 @@ var CanvasEditor = forwardRef(({
3966
4001
  default:
3967
4002
  return null;
3968
4003
  }
3969
- }))))), config?.multiPage && /* @__PURE__ */ React18.createElement("div", {
4004
+ }))))), config?.multiPage && /* @__PURE__ */ React19.createElement("div", {
3970
4005
  className: "absolute bottom-4 left-4 flex items-center space-x-2"
3971
- }, design.pages.map((page, index) => /* @__PURE__ */ React18.createElement("div", {
4006
+ }, design.pages.map((page, index) => /* @__PURE__ */ React19.createElement("div", {
3972
4007
  key: page.id,
3973
4008
  className: "relative group"
3974
- }, /* @__PURE__ */ React18.createElement("button", {
4009
+ }, /* @__PURE__ */ React19.createElement("button", {
3975
4010
  onClick: () => setCurrentPageId(page.id),
3976
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"}`
3977
- }, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React18.createElement("button", {
4012
+ }, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React19.createElement("button", {
3978
4013
  onClick: () => deletePage(page.id),
3979
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",
3980
4015
  title: `Delete Page ${index + 1}`
3981
- }, /* @__PURE__ */ React18.createElement(X2, {
4016
+ }, /* @__PURE__ */ React19.createElement(X2, {
3982
4017
  className: "w-3 h-3"
3983
- })))), /* @__PURE__ */ React18.createElement("button", {
4018
+ })))), /* @__PURE__ */ React19.createElement("button", {
3984
4019
  onClick: addPage,
3985
4020
  className: "p-1 bg-gray-800 text-gray-300 rounded hover:bg-gray-700",
3986
4021
  title: "Add Page"
3987
- }, /* @__PURE__ */ React18.createElement(PlusCircle, {
4022
+ }, /* @__PURE__ */ React19.createElement(PlusCircle, {
3988
4023
  className: "w-4 h-4"
3989
- })))), /* @__PURE__ */ React18.createElement(RightSidebar_default, {
4024
+ })))), /* @__PURE__ */ React19.createElement(RightSidebar_default, {
3990
4025
  currentPageElements: currentPage.elements,
3991
4026
  selectedElement,
3992
4027
  selectedId,
@@ -3996,34 +4031,34 @@ var CanvasEditor = forwardRef(({
3996
4031
  onMoveElementUp: moveElementUp,
3997
4032
  onMoveElementDown: moveElementDown,
3998
4033
  onDeleteSelected: deleteSelected
3999
- })), /* @__PURE__ */ React18.createElement("input", {
4034
+ })), /* @__PURE__ */ React19.createElement("input", {
4000
4035
  ref: fileInputRef,
4001
4036
  type: "file",
4002
4037
  accept: "image/*",
4003
4038
  onChange: handleImageUpload,
4004
4039
  className: "hidden",
4005
4040
  multiple: true
4006
- }), /* @__PURE__ */ React18.createElement("input", {
4041
+ }), /* @__PURE__ */ React19.createElement("input", {
4007
4042
  ref: jsonInputRef,
4008
4043
  type: "file",
4009
4044
  accept: ".json",
4010
4045
  onChange: handleImportJSON,
4011
4046
  className: "hidden"
4012
- }), showInputModal && /* @__PURE__ */ React18.createElement(TemplateInputModal_default, {
4047
+ }), showInputModal && /* @__PURE__ */ React19.createElement(TemplateInputModal_default, {
4013
4048
  inputs: pendingInputs,
4014
4049
  onComplete: handleInputModalComplete,
4015
4050
  onCancel: handleInputModalCancel
4016
- }), showUnsplash && /* @__PURE__ */ React18.createElement("div", {
4051
+ }), showUnsplash && /* @__PURE__ */ React19.createElement("div", {
4017
4052
  className: "fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-8"
4018
- }, /* @__PURE__ */ React18.createElement("div", {
4053
+ }, /* @__PURE__ */ React19.createElement("div", {
4019
4054
  className: "bg-gray-800 rounded-lg w-full max-w-4xl max-h-full overflow-hidden flex flex-col"
4020
- }, /* @__PURE__ */ React18.createElement("div", {
4055
+ }, /* @__PURE__ */ React19.createElement("div", {
4021
4056
  className: "p-6 border-b border-gray-700"
4022
- }, /* @__PURE__ */ React18.createElement("h3", {
4057
+ }, /* @__PURE__ */ React19.createElement("h3", {
4023
4058
  className: "text-xl font-semibold text-white mb-4"
4024
- }, "Search Unsplash"), /* @__PURE__ */ React18.createElement("div", {
4059
+ }, "Search Unsplash"), /* @__PURE__ */ React19.createElement("div", {
4025
4060
  className: "flex space-x-4"
4026
- }, /* @__PURE__ */ React18.createElement("input", {
4061
+ }, /* @__PURE__ */ React19.createElement("input", {
4027
4062
  type: "text",
4028
4063
  value: unsplashQuery,
4029
4064
  onChange: (e) => setUnsplashQuery(e.target.value),
@@ -4031,64 +4066,65 @@ var CanvasEditor = forwardRef(({
4031
4066
  placeholder: "Search for images...",
4032
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",
4033
4068
  autoFocus: true
4034
- }), /* @__PURE__ */ React18.createElement("button", {
4069
+ }), /* @__PURE__ */ React19.createElement("button", {
4035
4070
  onClick: searchUnsplash,
4036
4071
  className: "px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
4037
- }, "Search"), /* @__PURE__ */ React18.createElement("button", {
4072
+ }, "Search"), /* @__PURE__ */ React19.createElement("button", {
4038
4073
  onClick: () => {
4039
4074
  setShowUnsplash(false);
4040
4075
  setUnsplashQuery("");
4041
4076
  setUnsplashResults([]);
4042
4077
  },
4043
4078
  className: "px-6 py-2 bg-gray-700 text-white rounded hover:bg-gray-600"
4044
- }, "Cancel"))), /* @__PURE__ */ React18.createElement("div", {
4079
+ }, "Cancel"))), /* @__PURE__ */ React19.createElement("div", {
4045
4080
  className: "flex-1 overflow-y-auto p-6"
4046
- }, unsplashResults.length > 0 ? /* @__PURE__ */ React18.createElement("div", {
4081
+ }, unsplashResults.length > 0 ? /* @__PURE__ */ React19.createElement("div", {
4047
4082
  className: "grid grid-cols-3 gap-4"
4048
- }, unsplashResults.map((result) => /* @__PURE__ */ React18.createElement("button", {
4083
+ }, unsplashResults.map((result) => /* @__PURE__ */ React19.createElement("button", {
4049
4084
  key: result.id,
4050
4085
  onClick: () => addUnsplashImage(result.urls.regular),
4051
4086
  className: "relative group overflow-hidden rounded-lg aspect-square"
4052
- }, /* @__PURE__ */ React18.createElement("img", {
4087
+ }, /* @__PURE__ */ React19.createElement("img", {
4053
4088
  src: result.urls.thumb,
4054
4089
  alt: "",
4055
4090
  className: "w-full h-full object-cover group-hover:scale-110 transition-transform duration-200"
4056
- }), /* @__PURE__ */ React18.createElement("div", {
4091
+ }), /* @__PURE__ */ React19.createElement("div", {
4057
4092
  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__ */ React18.createElement(PlusCircle, {
4093
+ }, /* @__PURE__ */ React19.createElement(PlusCircle, {
4059
4094
  className: "w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
4060
- }))))) : /* @__PURE__ */ React18.createElement("div", {
4095
+ }))))) : /* @__PURE__ */ React19.createElement("div", {
4061
4096
  className: "text-center text-gray-400 py-12"
4062
- }, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React18.createElement("div", {
4097
+ }, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React19.createElement("div", {
4063
4098
  className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
4064
- }, /* @__PURE__ */ React18.createElement("div", {
4099
+ }, /* @__PURE__ */ React19.createElement("div", {
4065
4100
  className: "bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-auto"
4066
- }, /* @__PURE__ */ React18.createElement("h2", {
4101
+ }, /* @__PURE__ */ React19.createElement("h2", {
4067
4102
  className: "text-white text-xl font-semibold mb-4"
4068
- }, "Load JSON Data"), /* @__PURE__ */ React18.createElement("p", {
4103
+ }, "Load JSON Data"), /* @__PURE__ */ React19.createElement("p", {
4069
4104
  className: "text-gray-300 mb-4"
4070
- }, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React18.createElement("textarea", {
4105
+ }, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React19.createElement("textarea", {
4071
4106
  value: jsonInputText,
4072
4107
  onChange: (e) => setJsonInputText(e.target.value),
4073
4108
  className: "w-full h-64 p-3 bg-gray-700 text-white border border-gray-600 rounded font-mono text-sm resize-none",
4074
4109
  placeholder: '{"width": 800, "height": 600, "pages": [...]}'
4075
- }), /* @__PURE__ */ React18.createElement("div", {
4110
+ }), /* @__PURE__ */ React19.createElement("div", {
4076
4111
  className: "flex justify-end space-x-3 mt-4"
4077
- }, /* @__PURE__ */ React18.createElement("button", {
4112
+ }, /* @__PURE__ */ React19.createElement("button", {
4078
4113
  onClick: () => {
4079
4114
  setShowJsonModal(false);
4080
4115
  setJsonInputText("");
4081
4116
  },
4082
4117
  className: "px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
4083
- }, "Cancel"), /* @__PURE__ */ React18.createElement("button", {
4118
+ }, "Cancel"), /* @__PURE__ */ React19.createElement("button", {
4084
4119
  onClick: handleImportJSONData,
4085
4120
  className: "px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
4086
- }, "Load JSON")))));
4121
+ }, "Load JSON"))))));
4087
4122
  });
4088
4123
  var CanvasEditor_default = CanvasEditor;
4089
4124
  // src/lib/index.ts
4090
4125
  initJsxCompat();
4091
4126
  export {
4127
+ useCanvasStore,
4092
4128
  setUnsplashAccessKey,
4093
4129
  replaceUserInputs,
4094
4130
  loadTemplateFromJSON,
@@ -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, useMemo, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
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,27 @@ 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
+ });
3659
3692
  }
3660
3693
  }), [currentPage.id, design.width, design.height, config, setActivePanelId]);
3661
3694
  const panelConfigs = useMemo(() => {
@@ -3818,12 +3851,12 @@ var CanvasEditor = forwardRef(({
3818
3851
  const DynamicPanelRenderer = () => {
3819
3852
  const activePanelConfig = panelConfigs.find((p) => p.id === activePanelId);
3820
3853
  if (!activePanelConfig) {
3821
- return /* @__PURE__ */ React18.createElement("div", {
3854
+ return /* @__PURE__ */ React19.createElement("div", {
3822
3855
  className: "text-white"
3823
3856
  }, "Panel not found");
3824
3857
  }
3825
3858
  const PanelComponent = activePanelConfig.component;
3826
- return /* @__PURE__ */ React18.createElement(PanelComponent, {
3859
+ return /* @__PURE__ */ React19.createElement(PanelComponent, {
3827
3860
  ...activePanelConfig.props
3828
3861
  });
3829
3862
  };
@@ -3876,9 +3909,11 @@ var CanvasEditor = forwardRef(({
3876
3909
  setHistoryIndex(0);
3877
3910
  }
3878
3911
  }, []);
3879
- return /* @__PURE__ */ React18.createElement("div", {
3912
+ return /* @__PURE__ */ React19.createElement(CanvasStoreContext.Provider, {
3913
+ value: store
3914
+ }, /* @__PURE__ */ React19.createElement("div", {
3880
3915
  className: "h-screen flex flex-col bg-gray-900"
3881
- }, /* @__PURE__ */ React18.createElement(Header_default, {
3916
+ }, /* @__PURE__ */ React19.createElement(Header_default, {
3882
3917
  name,
3883
3918
  zoom,
3884
3919
  historyIndex,
@@ -3890,37 +3925,37 @@ var CanvasEditor = forwardRef(({
3890
3925
  onZoomReset: () => setZoom(calculateFitToScreenZoom(design.width, design.height)),
3891
3926
  onSetActivePanel: setActivePanelId,
3892
3927
  navbarConfig: config?.navbar
3893
- }), /* @__PURE__ */ React18.createElement("div", {
3928
+ }), /* @__PURE__ */ React19.createElement("div", {
3894
3929
  className: "flex-1 flex overflow-hidden"
3895
- }, /* @__PURE__ */ React18.createElement("div", {
3930
+ }, /* @__PURE__ */ React19.createElement("div", {
3896
3931
  className: "w-80 bg-gray-800 border-r border-gray-700 flex"
3897
- }, /* @__PURE__ */ React18.createElement(LeftMenu_default, {
3932
+ }, /* @__PURE__ */ React19.createElement(LeftMenu_default, {
3898
3933
  tool,
3899
3934
  activePanel: activePanelId,
3900
3935
  onSetTool: setTool,
3901
3936
  onSetActivePanel: setActivePanelId,
3902
3937
  config
3903
- }), /* @__PURE__ */ React18.createElement("div", {
3938
+ }), /* @__PURE__ */ React19.createElement("div", {
3904
3939
  className: "flex-1 p-4 overflow-y-auto"
3905
- }, /* @__PURE__ */ React18.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React18.createElement("div", {
3940
+ }, /* @__PURE__ */ React19.createElement(DynamicPanelRenderer, null))), /* @__PURE__ */ React19.createElement("div", {
3906
3941
  className: "flex-1 bg-gray-700 overflow-hidden relative",
3907
3942
  ref: containerRef
3908
- }, /* @__PURE__ */ React18.createElement("div", {
3943
+ }, /* @__PURE__ */ React19.createElement("div", {
3909
3944
  className: "absolute inset-0 flex items-center justify-center"
3910
- }, /* @__PURE__ */ React18.createElement("div", {
3945
+ }, /* @__PURE__ */ React19.createElement("div", {
3911
3946
  className: "bg-white shadow-2xl",
3912
3947
  style: {
3913
3948
  transform: `scale(${zoom})`,
3914
3949
  transformOrigin: "center center"
3915
3950
  }
3916
- }, /* @__PURE__ */ React18.createElement(Stage, {
3951
+ }, /* @__PURE__ */ React19.createElement(Stage, {
3917
3952
  key: `canvas-${design.id || design.width}-${design.height}`,
3918
3953
  ref: stageRef,
3919
3954
  width: design.width,
3920
3955
  height: design.height,
3921
3956
  onClick: handleStageClick,
3922
3957
  onTap: handleStageClick
3923
- }, /* @__PURE__ */ React18.createElement(Layer, null, /* @__PURE__ */ React18.createElement(Rect2, {
3958
+ }, /* @__PURE__ */ React19.createElement(Layer, null, /* @__PURE__ */ React19.createElement(Rect2, {
3924
3959
  x: 0,
3925
3960
  y: 0,
3926
3961
  width: design.width,
@@ -3931,7 +3966,7 @@ var CanvasEditor = forwardRef(({
3931
3966
  }), currentPage.elements.map((element) => {
3932
3967
  switch (element.type) {
3933
3968
  case "text":
3934
- return React18.createElement(EditableTextElement, {
3969
+ return React19.createElement(EditableTextElement, {
3935
3970
  key: element.id,
3936
3971
  element,
3937
3972
  isSelected: element.id === selectedId,
@@ -3942,7 +3977,7 @@ var CanvasEditor = forwardRef(({
3942
3977
  onChange: (attrs) => updateElement(element.id, attrs)
3943
3978
  });
3944
3979
  case "image":
3945
- return React18.createElement(UrlImageElement, {
3980
+ return React19.createElement(UrlImageElement, {
3946
3981
  key: element.id,
3947
3982
  element,
3948
3983
  isSelected: element.id === selectedId,
@@ -3953,7 +3988,7 @@ var CanvasEditor = forwardRef(({
3953
3988
  onChange: (attrs) => updateElement(element.id, attrs)
3954
3989
  });
3955
3990
  case "shape":
3956
- return React18.createElement(ShapeElement, {
3991
+ return React19.createElement(ShapeElement, {
3957
3992
  key: element.id,
3958
3993
  element,
3959
3994
  isSelected: element.id === selectedId,
@@ -3966,27 +4001,27 @@ var CanvasEditor = forwardRef(({
3966
4001
  default:
3967
4002
  return null;
3968
4003
  }
3969
- }))))), config?.multiPage && /* @__PURE__ */ React18.createElement("div", {
4004
+ }))))), config?.multiPage && /* @__PURE__ */ React19.createElement("div", {
3970
4005
  className: "absolute bottom-4 left-4 flex items-center space-x-2"
3971
- }, design.pages.map((page, index) => /* @__PURE__ */ React18.createElement("div", {
4006
+ }, design.pages.map((page, index) => /* @__PURE__ */ React19.createElement("div", {
3972
4007
  key: page.id,
3973
4008
  className: "relative group"
3974
- }, /* @__PURE__ */ React18.createElement("button", {
4009
+ }, /* @__PURE__ */ React19.createElement("button", {
3975
4010
  onClick: () => setCurrentPageId(page.id),
3976
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"}`
3977
- }, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React18.createElement("button", {
4012
+ }, "Page ", index + 1), design.pages.length > 1 && /* @__PURE__ */ React19.createElement("button", {
3978
4013
  onClick: () => deletePage(page.id),
3979
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",
3980
4015
  title: `Delete Page ${index + 1}`
3981
- }, /* @__PURE__ */ React18.createElement(X2, {
4016
+ }, /* @__PURE__ */ React19.createElement(X2, {
3982
4017
  className: "w-3 h-3"
3983
- })))), /* @__PURE__ */ React18.createElement("button", {
4018
+ })))), /* @__PURE__ */ React19.createElement("button", {
3984
4019
  onClick: addPage,
3985
4020
  className: "p-1 bg-gray-800 text-gray-300 rounded hover:bg-gray-700",
3986
4021
  title: "Add Page"
3987
- }, /* @__PURE__ */ React18.createElement(PlusCircle, {
4022
+ }, /* @__PURE__ */ React19.createElement(PlusCircle, {
3988
4023
  className: "w-4 h-4"
3989
- })))), /* @__PURE__ */ React18.createElement(RightSidebar_default, {
4024
+ })))), /* @__PURE__ */ React19.createElement(RightSidebar_default, {
3990
4025
  currentPageElements: currentPage.elements,
3991
4026
  selectedElement,
3992
4027
  selectedId,
@@ -3996,34 +4031,34 @@ var CanvasEditor = forwardRef(({
3996
4031
  onMoveElementUp: moveElementUp,
3997
4032
  onMoveElementDown: moveElementDown,
3998
4033
  onDeleteSelected: deleteSelected
3999
- })), /* @__PURE__ */ React18.createElement("input", {
4034
+ })), /* @__PURE__ */ React19.createElement("input", {
4000
4035
  ref: fileInputRef,
4001
4036
  type: "file",
4002
4037
  accept: "image/*",
4003
4038
  onChange: handleImageUpload,
4004
4039
  className: "hidden",
4005
4040
  multiple: true
4006
- }), /* @__PURE__ */ React18.createElement("input", {
4041
+ }), /* @__PURE__ */ React19.createElement("input", {
4007
4042
  ref: jsonInputRef,
4008
4043
  type: "file",
4009
4044
  accept: ".json",
4010
4045
  onChange: handleImportJSON,
4011
4046
  className: "hidden"
4012
- }), showInputModal && /* @__PURE__ */ React18.createElement(TemplateInputModal_default, {
4047
+ }), showInputModal && /* @__PURE__ */ React19.createElement(TemplateInputModal_default, {
4013
4048
  inputs: pendingInputs,
4014
4049
  onComplete: handleInputModalComplete,
4015
4050
  onCancel: handleInputModalCancel
4016
- }), showUnsplash && /* @__PURE__ */ React18.createElement("div", {
4051
+ }), showUnsplash && /* @__PURE__ */ React19.createElement("div", {
4017
4052
  className: "fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 p-8"
4018
- }, /* @__PURE__ */ React18.createElement("div", {
4053
+ }, /* @__PURE__ */ React19.createElement("div", {
4019
4054
  className: "bg-gray-800 rounded-lg w-full max-w-4xl max-h-full overflow-hidden flex flex-col"
4020
- }, /* @__PURE__ */ React18.createElement("div", {
4055
+ }, /* @__PURE__ */ React19.createElement("div", {
4021
4056
  className: "p-6 border-b border-gray-700"
4022
- }, /* @__PURE__ */ React18.createElement("h3", {
4057
+ }, /* @__PURE__ */ React19.createElement("h3", {
4023
4058
  className: "text-xl font-semibold text-white mb-4"
4024
- }, "Search Unsplash"), /* @__PURE__ */ React18.createElement("div", {
4059
+ }, "Search Unsplash"), /* @__PURE__ */ React19.createElement("div", {
4025
4060
  className: "flex space-x-4"
4026
- }, /* @__PURE__ */ React18.createElement("input", {
4061
+ }, /* @__PURE__ */ React19.createElement("input", {
4027
4062
  type: "text",
4028
4063
  value: unsplashQuery,
4029
4064
  onChange: (e) => setUnsplashQuery(e.target.value),
@@ -4031,59 +4066,59 @@ var CanvasEditor = forwardRef(({
4031
4066
  placeholder: "Search for images...",
4032
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",
4033
4068
  autoFocus: true
4034
- }), /* @__PURE__ */ React18.createElement("button", {
4069
+ }), /* @__PURE__ */ React19.createElement("button", {
4035
4070
  onClick: searchUnsplash,
4036
4071
  className: "px-6 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
4037
- }, "Search"), /* @__PURE__ */ React18.createElement("button", {
4072
+ }, "Search"), /* @__PURE__ */ React19.createElement("button", {
4038
4073
  onClick: () => {
4039
4074
  setShowUnsplash(false);
4040
4075
  setUnsplashQuery("");
4041
4076
  setUnsplashResults([]);
4042
4077
  },
4043
4078
  className: "px-6 py-2 bg-gray-700 text-white rounded hover:bg-gray-600"
4044
- }, "Cancel"))), /* @__PURE__ */ React18.createElement("div", {
4079
+ }, "Cancel"))), /* @__PURE__ */ React19.createElement("div", {
4045
4080
  className: "flex-1 overflow-y-auto p-6"
4046
- }, unsplashResults.length > 0 ? /* @__PURE__ */ React18.createElement("div", {
4081
+ }, unsplashResults.length > 0 ? /* @__PURE__ */ React19.createElement("div", {
4047
4082
  className: "grid grid-cols-3 gap-4"
4048
- }, unsplashResults.map((result) => /* @__PURE__ */ React18.createElement("button", {
4083
+ }, unsplashResults.map((result) => /* @__PURE__ */ React19.createElement("button", {
4049
4084
  key: result.id,
4050
4085
  onClick: () => addUnsplashImage(result.urls.regular),
4051
4086
  className: "relative group overflow-hidden rounded-lg aspect-square"
4052
- }, /* @__PURE__ */ React18.createElement("img", {
4087
+ }, /* @__PURE__ */ React19.createElement("img", {
4053
4088
  src: result.urls.thumb,
4054
4089
  alt: "",
4055
4090
  className: "w-full h-full object-cover group-hover:scale-110 transition-transform duration-200"
4056
- }), /* @__PURE__ */ React18.createElement("div", {
4091
+ }), /* @__PURE__ */ React19.createElement("div", {
4057
4092
  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__ */ React18.createElement(PlusCircle, {
4093
+ }, /* @__PURE__ */ React19.createElement(PlusCircle, {
4059
4094
  className: "w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-200"
4060
- }))))) : /* @__PURE__ */ React18.createElement("div", {
4095
+ }))))) : /* @__PURE__ */ React19.createElement("div", {
4061
4096
  className: "text-center text-gray-400 py-12"
4062
- }, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React18.createElement("div", {
4097
+ }, "Enter a search term to find images")))), showJsonModal && /* @__PURE__ */ React19.createElement("div", {
4063
4098
  className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
4064
- }, /* @__PURE__ */ React18.createElement("div", {
4099
+ }, /* @__PURE__ */ React19.createElement("div", {
4065
4100
  className: "bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-auto"
4066
- }, /* @__PURE__ */ React18.createElement("h2", {
4101
+ }, /* @__PURE__ */ React19.createElement("h2", {
4067
4102
  className: "text-white text-xl font-semibold mb-4"
4068
- }, "Load JSON Data"), /* @__PURE__ */ React18.createElement("p", {
4103
+ }, "Load JSON Data"), /* @__PURE__ */ React19.createElement("p", {
4069
4104
  className: "text-gray-300 mb-4"
4070
- }, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React18.createElement("textarea", {
4105
+ }, 'Paste your JSON template data below and click "Load" to import it into the canvas.'), /* @__PURE__ */ React19.createElement("textarea", {
4071
4106
  value: jsonInputText,
4072
4107
  onChange: (e) => setJsonInputText(e.target.value),
4073
4108
  className: "w-full h-64 p-3 bg-gray-700 text-white border border-gray-600 rounded font-mono text-sm resize-none",
4074
4109
  placeholder: '{"width": 800, "height": 600, "pages": [...]}'
4075
- }), /* @__PURE__ */ React18.createElement("div", {
4110
+ }), /* @__PURE__ */ React19.createElement("div", {
4076
4111
  className: "flex justify-end space-x-3 mt-4"
4077
- }, /* @__PURE__ */ React18.createElement("button", {
4112
+ }, /* @__PURE__ */ React19.createElement("button", {
4078
4113
  onClick: () => {
4079
4114
  setShowJsonModal(false);
4080
4115
  setJsonInputText("");
4081
4116
  },
4082
4117
  className: "px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700"
4083
- }, "Cancel"), /* @__PURE__ */ React18.createElement("button", {
4118
+ }, "Cancel"), /* @__PURE__ */ React19.createElement("button", {
4084
4119
  onClick: handleImportJSONData,
4085
4120
  className: "px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700"
4086
- }, "Load JSON")))));
4121
+ }, "Load JSON"))))));
4087
4122
  });
4088
4123
  var CanvasEditor_default = CanvasEditor;
4089
4124
  // src/lib/index.ts
@@ -4141,6 +4176,7 @@ function initWordPressCanvasEditor(containerId, props) {
4141
4176
  return false;
4142
4177
  }
4143
4178
  export {
4179
+ useCanvasStore,
4144
4180
  setUnsplashAccessKey,
4145
4181
  replaceUserInputs,
4146
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;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;yCA4yC9E,CAAC;AAEH,eAAe,YAAY,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;
@@ -26,6 +27,7 @@ export interface CanvasStore {
26
27
  width: number;
27
28
  height: number;
28
29
  openSidePanel: (panelId: string | null) => void;
30
+ deletePages: (pageIds: string[]) => void;
29
31
  }
30
32
  export interface NavbarSection {
31
33
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/types/Config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../src/types/Config.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "labellife-design-tool",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Professional canvas editor built with React, TypeScript, and Konva",
5
5
  "main": "./dist/lib/lib/index.js",
6
6
  "module": "./dist/lib/lib/index.js",