@merchi/product-editor 0.1.9

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.
Files changed (123) hide show
  1. package/.turbo/turbo-build.log +1 -0
  2. package/README.md +174 -0
  3. package/dist/components/AlignMenu.d.ts +3 -0
  4. package/dist/components/AlignMenu.js +61 -0
  5. package/dist/components/FloatingToolbar.d.ts +4 -0
  6. package/dist/components/FloatingToolbar.js +97 -0
  7. package/dist/components/FormatButtons.d.ts +2 -0
  8. package/dist/components/FormatButtons.js +22 -0
  9. package/dist/components/ImageNavButton.d.ts +7 -0
  10. package/dist/components/ImageNavButton.js +14 -0
  11. package/dist/components/ImageZoomModal.d.ts +12 -0
  12. package/dist/components/ImageZoomModal.js +129 -0
  13. package/dist/components/LayerPanel.d.ts +4 -0
  14. package/dist/components/LayerPanel.js +223 -0
  15. package/dist/components/LoadingOverlay.d.ts +9 -0
  16. package/dist/components/LoadingOverlay.js +17 -0
  17. package/dist/components/ProductEditor.d.ts +4 -0
  18. package/dist/components/ProductEditor.js +67 -0
  19. package/dist/components/ProductImageGallery.d.ts +6 -0
  20. package/dist/components/ProductImageGallery.js +148 -0
  21. package/dist/components/ProductPreviews.d.ts +7 -0
  22. package/dist/components/ProductPreviews.js +281 -0
  23. package/dist/components/TextToolbar.d.ts +4 -0
  24. package/dist/components/TextToolbar.js +117 -0
  25. package/dist/components/Toolbar.d.ts +3 -0
  26. package/dist/components/Toolbar.js +47 -0
  27. package/dist/config/colorConfig.d.ts +1 -0
  28. package/dist/config/colorConfig.js +10 -0
  29. package/dist/config/fontConfig.d.ts +5 -0
  30. package/dist/config/fontConfig.js +21 -0
  31. package/dist/context/ProductEditorContext.d.ts +60 -0
  32. package/dist/context/ProductEditorContext.js +743 -0
  33. package/dist/hooks/useSwipeNavigate.d.ts +11 -0
  34. package/dist/hooks/useSwipeNavigate.js +35 -0
  35. package/dist/index.d.ts +6 -0
  36. package/dist/index.js +30 -0
  37. package/dist/styles/BottomPreviewDisplay.css +65 -0
  38. package/dist/styles/FloatingToolbar.css +41 -0
  39. package/dist/styles/ImageGallery.css +147 -0
  40. package/dist/styles/ImageNavButton.css +35 -0
  41. package/dist/styles/ImageZoomModal.css +101 -0
  42. package/dist/styles/LayerPanel.css +179 -0
  43. package/dist/styles/LoadingOverlay.css +48 -0
  44. package/dist/styles/ProductEditor.css +192 -0
  45. package/dist/styles/TextToolbar.css +327 -0
  46. package/dist/styles/Toolbar.css +125 -0
  47. package/dist/styles/index.css +5 -0
  48. package/dist/styles/textToolbarSelectStyles.d.ts +3 -0
  49. package/dist/styles/textToolbarSelectStyles.js +30 -0
  50. package/dist/types.d.ts +228 -0
  51. package/dist/types.js +17 -0
  52. package/dist/utils/canvasAddText.d.ts +11 -0
  53. package/dist/utils/canvasAddText.js +66 -0
  54. package/dist/utils/canvasUtils.d.ts +37 -0
  55. package/dist/utils/canvasUtils.js +342 -0
  56. package/dist/utils/deviceUtils.d.ts +5 -0
  57. package/dist/utils/deviceUtils.js +33 -0
  58. package/dist/utils/draftTemplateUtils.d.ts +23 -0
  59. package/dist/utils/draftTemplateUtils.js +66 -0
  60. package/dist/utils/grid.d.ts +32 -0
  61. package/dist/utils/grid.js +151 -0
  62. package/dist/utils/imageUtils.d.ts +12 -0
  63. package/dist/utils/imageUtils.js +178 -0
  64. package/dist/utils/job.d.ts +40 -0
  65. package/dist/utils/job.js +115 -0
  66. package/dist/utils/keyboard.d.ts +1 -0
  67. package/dist/utils/keyboard.js +26 -0
  68. package/dist/utils/previewUtils.d.ts +9 -0
  69. package/dist/utils/previewUtils.js +39 -0
  70. package/dist/utils/psdConverter.d.ts +40 -0
  71. package/dist/utils/psdConverter.js +516 -0
  72. package/dist/utils/psdRenderUtils.d.ts +12 -0
  73. package/dist/utils/psdRenderUtils.js +465 -0
  74. package/dist/utils/renderUtils.d.ts +2 -0
  75. package/dist/utils/renderUtils.js +85 -0
  76. package/package.json +66 -0
  77. package/src/components/AlignMenu.tsx +49 -0
  78. package/src/components/FloatingToolbar.tsx +83 -0
  79. package/src/components/FormatButtons.tsx +31 -0
  80. package/src/components/ImageNavButton.tsx +23 -0
  81. package/src/components/ImageZoomModal.tsx +163 -0
  82. package/src/components/LayerPanel.tsx +256 -0
  83. package/src/components/LoadingOverlay.tsx +27 -0
  84. package/src/components/ProductEditor.tsx +104 -0
  85. package/src/components/ProductImageGallery.tsx +181 -0
  86. package/src/components/ProductPreviews.tsx +243 -0
  87. package/src/components/TextToolbar.tsx +164 -0
  88. package/src/components/Toolbar.tsx +86 -0
  89. package/src/config/colorConfig.ts +7 -0
  90. package/src/config/fontConfig.ts +23 -0
  91. package/src/context/ProductEditorContext.tsx +829 -0
  92. package/src/hooks/useSwipeNavigate.ts +40 -0
  93. package/src/index.ts +6 -0
  94. package/src/styles/BottomPreviewDisplay.css +65 -0
  95. package/src/styles/FloatingToolbar.css +41 -0
  96. package/src/styles/ImageGallery.css +147 -0
  97. package/src/styles/ImageNavButton.css +35 -0
  98. package/src/styles/ImageZoomModal.css +101 -0
  99. package/src/styles/LayerPanel.css +179 -0
  100. package/src/styles/LoadingOverlay.css +48 -0
  101. package/src/styles/ProductEditor.css +192 -0
  102. package/src/styles/TextToolbar.css +327 -0
  103. package/src/styles/Toolbar.css +125 -0
  104. package/src/styles/index.css +5 -0
  105. package/src/styles/textToolbarSelectStyles.ts +60 -0
  106. package/src/types/ag-psd/index.d.ts +1 -0
  107. package/src/types/fabric.d.ts +14 -0
  108. package/src/types/lodash/index.d.ts +1 -0
  109. package/src/types/psd.d.ts +53 -0
  110. package/src/types.ts +247 -0
  111. package/src/utils/canvasAddText.ts +72 -0
  112. package/src/utils/canvasUtils.ts +406 -0
  113. package/src/utils/deviceUtils.ts +31 -0
  114. package/src/utils/draftTemplateUtils.ts +70 -0
  115. package/src/utils/grid.ts +154 -0
  116. package/src/utils/imageUtils.ts +218 -0
  117. package/src/utils/job.ts +128 -0
  118. package/src/utils/keyboard.ts +28 -0
  119. package/src/utils/previewUtils.ts +43 -0
  120. package/src/utils/psdConverter.ts +595 -0
  121. package/src/utils/psdRenderUtils.ts +453 -0
  122. package/src/utils/renderUtils.ts +44 -0
  123. package/tsconfig.json +17 -0
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
37
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
38
+ return new (P || (P = Promise))(function (resolve, reject) {
39
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
40
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
41
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
42
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
43
+ });
44
+ };
45
+ var __generator = (this && this.__generator) || function (thisArg, body) {
46
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
47
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
48
+ function verb(n) { return function (v) { return step([n, v]); }; }
49
+ function step(op) {
50
+ if (f) throw new TypeError("Generator is already executing.");
51
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
52
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
53
+ if (y = 0, t) op = [op[0] & 2, t.value];
54
+ switch (op[0]) {
55
+ case 0: case 1: t = op; break;
56
+ case 4: _.label++; return { value: op[1], done: false };
57
+ case 5: _.label++; y = op[1]; op = [0]; continue;
58
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
59
+ default:
60
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
61
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
62
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
63
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
64
+ if (t[2]) _.ops.pop();
65
+ _.trys.pop(); continue;
66
+ }
67
+ op = body.call(thisArg, _);
68
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
69
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
70
+ }
71
+ };
72
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
73
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
74
+ if (ar || !(i in from)) {
75
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
76
+ ar[i] = from[i];
77
+ }
78
+ }
79
+ return to.concat(ar || Array.prototype.slice.call(from));
80
+ };
81
+ var __importDefault = (this && this.__importDefault) || function (mod) {
82
+ return (mod && mod.__esModule) ? mod : { "default": mod };
83
+ };
84
+ Object.defineProperty(exports, "__esModule", { value: true });
85
+ var react_1 = __importStar(require("react"));
86
+ var ImageZoomModal_1 = __importDefault(require("./ImageZoomModal"));
87
+ require("../styles/ProductEditor.css");
88
+ require("../styles/BottomPreviewDisplay.css");
89
+ var ProductEditorContext_1 = require("../context/ProductEditorContext");
90
+ var draftTemplateUtils_1 = require("../utils/draftTemplateUtils");
91
+ var psdRenderUtils_1 = require("../utils/psdRenderUtils");
92
+ var ProductPreviews = function () {
93
+ var _a, _b;
94
+ var _c = (0, ProductEditorContext_1.useProductEditor)(), draftTemplates = _c.draftTemplates, draftPreviews = _c.draftPreviews, loadingPreviews = _c.loadingPreviews, renderedDraftPreviews = _c.renderedDraftPreviews;
95
+ var _d = (0, react_1.useState)(false), isModalOpen = _d[0], setIsModalOpen = _d[1];
96
+ var _e = (0, react_1.useState)(0), selectedPreviewIndex = _e[0], setSelectedPreviewIndex = _e[1];
97
+ var _f = (0, react_1.useState)([]), renderedPreviews = _f[0], setRenderedPreviews = _f[1];
98
+ var _g = (0, react_1.useState)(false), isProcessing = _g[0], setIsProcessing = _g[1];
99
+ // Use refs instead of state to track processed data without causing re-renders
100
+ var processedPreviewIdsRef = (0, react_1.useRef)(new Set());
101
+ // Track which template versions we've already processed
102
+ var processedTemplateVersionsRef = (0, react_1.useRef)(new Map());
103
+ // For debugging
104
+ var renderCountRef = (0, react_1.useRef)(0);
105
+ // Track if this is first mount
106
+ var isFirstMountRef = (0, react_1.useRef)(true);
107
+ // When mappedPreviews or renderedDraftPreviews changes, update our rendered PNGs
108
+ (0, react_1.useEffect)(function () {
109
+ // Skip first render to avoid processing before renderedDraftPreviews are available
110
+ if (isFirstMountRef.current) {
111
+ isFirstMountRef.current = false;
112
+ return;
113
+ }
114
+ renderCountRef.current++;
115
+ var processPreviewsWithLayers = function () { return __awaiter(void 0, void 0, void 0, function () {
116
+ var mappedPreviews, changedTemplateIds, previewsToProcess, processedResults_1, error_1;
117
+ return __generator(this, function (_a) {
118
+ switch (_a.label) {
119
+ case 0:
120
+ // Skip if we're already processing or if we don't have previews
121
+ if (isProcessing || !draftPreviews || draftPreviews.length === 0) {
122
+ return [2 /*return*/];
123
+ }
124
+ mappedPreviews = (0, draftTemplateUtils_1.mapPreviewsWithRendered)(draftTemplates, draftPreviews, renderedDraftPreviews);
125
+ // Skip if there are no mappedPreviews to process
126
+ if (!mappedPreviews || mappedPreviews.length === 0) {
127
+ return [2 /*return*/];
128
+ }
129
+ changedTemplateIds = new Set();
130
+ renderedDraftPreviews.forEach(function (rdp) {
131
+ var templateId = rdp.templateId;
132
+ var templateVersion = rdp.draft; // Use the image data URL as a version identifier
133
+ var previousVersion = processedTemplateVersionsRef.current.get(templateId);
134
+ if (previousVersion !== templateVersion) {
135
+ changedTemplateIds.add(templateId);
136
+ // Update the stored version
137
+ processedTemplateVersionsRef.current.set(templateId, templateVersion);
138
+ }
139
+ });
140
+ previewsToProcess = mappedPreviews.filter(function (mp) {
141
+ var previewId = mp.draftPreview.id;
142
+ // Always process if we haven't processed this preview yet
143
+ if (!processedPreviewIdsRef.current.has(previewId)) {
144
+ return true;
145
+ }
146
+ // If no templates have changed, skip reprocessing
147
+ if (changedTemplateIds.size === 0) {
148
+ return false;
149
+ }
150
+ // Check if this preview uses any templates that have changed
151
+ var shouldProcess = mp.draftPreviewLayers.some(function (layer) {
152
+ return layer.renderedLayer && changedTemplateIds.has(layer.renderedLayer.templateId);
153
+ });
154
+ return shouldProcess;
155
+ });
156
+ // Skip if there's nothing new to process
157
+ if (previewsToProcess.length === 0) {
158
+ return [2 /*return*/];
159
+ }
160
+ setIsProcessing(true);
161
+ _a.label = 1;
162
+ case 1:
163
+ _a.trys.push([1, 3, 4, 5]);
164
+ return [4 /*yield*/, (0, psdRenderUtils_1.renderDraftPreviewsWithLayers)(previewsToProcess)];
165
+ case 2:
166
+ processedResults_1 = _a.sent();
167
+ // Update our rendered previews state
168
+ setRenderedPreviews(function (prevRendered) {
169
+ var newRendered = __spreadArray([], prevRendered, true);
170
+ processedResults_1.forEach(function (result) {
171
+ var existingIndex = newRendered.findIndex(function (r) { return r.draftPreviewId === result.draftPreviewId; });
172
+ if (existingIndex !== -1) {
173
+ // Update existing preview
174
+ newRendered[existingIndex] = result;
175
+ }
176
+ else {
177
+ // Add new preview
178
+ newRendered.push(result);
179
+ }
180
+ });
181
+ return newRendered;
182
+ });
183
+ // Update our processed IDs ref (not state)
184
+ processedResults_1.forEach(function (result) {
185
+ if (result.draftPreviewId !== undefined) {
186
+ processedPreviewIdsRef.current.add(result.draftPreviewId);
187
+ }
188
+ });
189
+ return [3 /*break*/, 5];
190
+ case 3:
191
+ error_1 = _a.sent();
192
+ console.error('Failed to process previews with layers:', error_1);
193
+ return [3 /*break*/, 5];
194
+ case 4:
195
+ setIsProcessing(false);
196
+ return [7 /*endfinally*/];
197
+ case 5: return [2 /*return*/];
198
+ }
199
+ });
200
+ }); };
201
+ processPreviewsWithLayers();
202
+ }, [draftTemplates, draftPreviews, renderedDraftPreviews, isProcessing]);
203
+ // One-time initialization to handle initial rendering of previews
204
+ // when component mounts and renderedDraftPreviews are available
205
+ (0, react_1.useEffect)(function () {
206
+ if ((draftPreviews === null || draftPreviews === void 0 ? void 0 : draftPreviews.length) > 0 && (renderedDraftPreviews === null || renderedDraftPreviews === void 0 ? void 0 : renderedDraftPreviews.length) > 0 && renderedPreviews.length === 0) {
207
+ var mappedPreviews_1 = (0, draftTemplateUtils_1.mapPreviewsWithRendered)(draftTemplates, draftPreviews, renderedDraftPreviews);
208
+ if ((mappedPreviews_1 === null || mappedPreviews_1 === void 0 ? void 0 : mappedPreviews_1.length) > 0) {
209
+ (function () { return __awaiter(void 0, void 0, void 0, function () {
210
+ var processedResults, error_2;
211
+ return __generator(this, function (_a) {
212
+ switch (_a.label) {
213
+ case 0:
214
+ setIsProcessing(true);
215
+ _a.label = 1;
216
+ case 1:
217
+ _a.trys.push([1, 3, 4, 5]);
218
+ return [4 /*yield*/, (0, psdRenderUtils_1.renderDraftPreviewsWithLayers)(mappedPreviews_1)];
219
+ case 2:
220
+ processedResults = _a.sent();
221
+ // Store initial results
222
+ setRenderedPreviews(processedResults);
223
+ // Mark these previews as processed
224
+ processedResults.forEach(function (result) {
225
+ if (result.draftPreviewId !== undefined) {
226
+ processedPreviewIdsRef.current.add(result.draftPreviewId);
227
+ }
228
+ });
229
+ // Store initial template versions
230
+ renderedDraftPreviews.forEach(function (rdp) {
231
+ processedTemplateVersionsRef.current.set(rdp.templateId, rdp.draft);
232
+ });
233
+ return [3 /*break*/, 5];
234
+ case 3:
235
+ error_2 = _a.sent();
236
+ console.error('[Initialization] Error processing previews:', error_2);
237
+ return [3 /*break*/, 5];
238
+ case 4:
239
+ setIsProcessing(false);
240
+ return [7 /*endfinally*/];
241
+ case 5: return [2 /*return*/];
242
+ }
243
+ });
244
+ }); })();
245
+ }
246
+ }
247
+ }, [draftPreviews, renderedDraftPreviews, draftTemplates, renderedPreviews.length]);
248
+ var openModal = function (index) {
249
+ setSelectedPreviewIndex(index);
250
+ setIsModalOpen(true);
251
+ };
252
+ var closeModal = function () {
253
+ setIsModalOpen(false);
254
+ };
255
+ // Determine the URL to display for each preview
256
+ var previewUrlsForDisplay = draftPreviews.length > 0
257
+ ? draftPreviews.map(function (preview) {
258
+ // If we have a rendered PNG for this preview, use it
259
+ var renderedPreview = renderedPreviews.find(function (rp) { return rp.draftPreviewId === preview.id; });
260
+ return (renderedPreview === null || renderedPreview === void 0 ? void 0 : renderedPreview.pngDataUrl) || '';
261
+ })
262
+ : renderedDraftPreviews.map(function (preview) {
263
+ // If we have a rendered PNG for this preview, use it
264
+ return preview.canvasPreview;
265
+ });
266
+ var previews = (draftPreviews === null || draftPreviews === void 0 ? void 0 : draftPreviews.length) > 0 ? draftPreviews : renderedDraftPreviews;
267
+ return (react_1.default.createElement(react_1.default.Fragment, null,
268
+ !isModalOpen && (react_1.default.createElement("div", { className: "bottom-preview-section" },
269
+ react_1.default.createElement("div", { className: "preview-images" }, previews.map(function (preview, index) {
270
+ var _a;
271
+ return loadingPreviews || isProcessing ? (react_1.default.createElement("div", { key: "loading-".concat(preview.id || index), className: 'preview-image-box' },
272
+ react_1.default.createElement("div", { className: "preview-image-box-loading-spinner" }))) : (react_1.default.createElement("div", { key: preview.id || "preview-".concat(index), className: "preview-image-box", onClick: function () { return openModal(index); }, style: {
273
+ backgroundImage: "url(".concat(previewUrlsForDisplay[index] || ((_a = preview.file) === null || _a === void 0 ? void 0 : _a.viewUrl) || '', ")"),
274
+ backgroundSize: 'contain',
275
+ backgroundRepeat: 'no-repeat',
276
+ backgroundPosition: 'center center'
277
+ }, title: "Preview ".concat(index + 1) }));
278
+ })))),
279
+ react_1.default.createElement(ImageZoomModal_1.default, { isOpen: isModalOpen, onClose: closeModal, imageUrl: previewUrlsForDisplay[selectedPreviewIndex] || ((_b = (_a = previews[selectedPreviewIndex]) === null || _a === void 0 ? void 0 : _a.file) === null || _b === void 0 ? void 0 : _b.viewUrl) || '', productName: "Preview", totalImages: previews.length, currentIndex: selectedPreviewIndex, allImages: previews.map(function (preview, index) { return (__assign(__assign({}, preview), { key: preview.id || "modal-preview-".concat(index) })); }) })));
280
+ };
281
+ exports.default = ProductPreviews;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import '../styles/TextToolbar.css';
3
+ declare const TextToolbar: React.FC;
4
+ export default TextToolbar;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ var react_1 = __importStar(require("react"));
30
+ var react_select_1 = __importDefault(require("react-select"));
31
+ var react_color_1 = require("react-color");
32
+ var ProductEditorContext_1 = require("../context/ProductEditorContext");
33
+ var textToolbarSelectStyles_1 = require("../styles/textToolbarSelectStyles");
34
+ require("../styles/TextToolbar.css");
35
+ var FormatButtons_1 = require("./FormatButtons");
36
+ var AlignMenu_1 = require("./AlignMenu");
37
+ var TextToolbar = function () {
38
+ var _a = (0, ProductEditorContext_1.useProductEditor)(), selectedTextObject = _a.selectedTextObject, updateSelectedText = _a.updateSelectedText, fontOptions = _a.fontOptions, colorPalette = _a.colorPalette;
39
+ var _b = (0, react_1.useState)(false), displayColorPicker = _b[0], setDisplayColorPicker = _b[1];
40
+ var _c = (0, react_1.useState)('palette'), pickerMode = _c[0], setPickerMode = _c[1];
41
+ var colorPickerRef = (0, react_1.useRef)(null);
42
+ (0, react_1.useEffect)(function () {
43
+ var handleClickOutside = function (event) {
44
+ if (colorPickerRef.current && !colorPickerRef.current.contains(event.target)) {
45
+ setDisplayColorPicker(false);
46
+ }
47
+ };
48
+ document.addEventListener('mousedown', handleClickOutside);
49
+ return function () {
50
+ document.removeEventListener('mousedown', handleClickOutside);
51
+ };
52
+ }, []);
53
+ if (!selectedTextObject || !updateSelectedText) {
54
+ return null;
55
+ }
56
+ var currentFontValue = selectedTextObject.fontFamily || 'Nunito';
57
+ var currentColor = typeof selectedTextObject.fill === 'string' ? selectedTextObject.fill : '#000000';
58
+ var handleFontChange = function (selectedOption) {
59
+ if (selectedOption) {
60
+ updateSelectedText({ fontFamily: selectedOption.value });
61
+ }
62
+ };
63
+ var handlePaletteColorClick = function (color) {
64
+ updateSelectedText({ fill: color });
65
+ setDisplayColorPicker(false);
66
+ setPickerMode('palette');
67
+ };
68
+ var handleCustomColorChange = function (color) {
69
+ updateSelectedText({ fill: color.hex });
70
+ };
71
+ var handleSwatchClick = function () {
72
+ var currentlyVisible = displayColorPicker;
73
+ setDisplayColorPicker(!currentlyVisible);
74
+ if (!currentlyVisible) {
75
+ setPickerMode('palette');
76
+ }
77
+ };
78
+ var handleCustomTriggerClick = function () {
79
+ setPickerMode('custom');
80
+ setDisplayColorPicker(true);
81
+ };
82
+ var currentFontOption = fontOptions.find(function (option) { return option.value === currentFontValue; }) || fontOptions[0];
83
+ return (react_1.default.createElement("div", { className: "text-toolbar" },
84
+ react_1.default.createElement(react_select_1.default, { options: fontOptions, styles: textToolbarSelectStyles_1.customStyles, value: currentFontOption, onChange: handleFontChange, isSearchable: true, placeholder: "Select or search font...", className: "react-select-container", classNamePrefix: "react-select" }),
85
+ react_1.default.createElement("div", { className: "color-picker-trigger", onClick: handleSwatchClick, title: "Change text color" },
86
+ react_1.default.createElement("div", { className: "color-picker-swatch", style: {
87
+ backgroundColor: currentColor,
88
+ borderRadius: '50%',
89
+ width: '28px',
90
+ height: '28px',
91
+ minWidth: '28px',
92
+ minHeight: '28px',
93
+ flexShrink: 0
94
+ } }),
95
+ react_1.default.createElement("span", { className: "color-picker-label" }, "Color")),
96
+ displayColorPicker && (react_1.default.createElement("div", { className: "color-picker-container", ref: colorPickerRef },
97
+ react_1.default.createElement("div", { className: "color-picker-popover" }, pickerMode === 'palette' ? (react_1.default.createElement("div", { className: "palette-grid" }, colorPalette.flat().map(function (color, index) {
98
+ if (color === null) {
99
+ return (react_1.default.createElement("button", { key: "custom-trigger", className: "palette-trigger-swatch", onClick: handleCustomTriggerClick, title: "Choose custom color" }, "+"));
100
+ }
101
+ else {
102
+ return (react_1.default.createElement("button", { key: "".concat(color, "-").concat(index), className: "palette-swatch", style: { backgroundColor: color }, onClick: function () { return handlePaletteColorClick(color); }, title: color }));
103
+ }
104
+ }))) : (react_1.default.createElement(react_1.default.Fragment, null,
105
+ react_1.default.createElement(react_color_1.ChromePicker, { color: currentColor, onChange: handleCustomColorChange, disableAlpha: true, styles: {
106
+ default: {
107
+ picker: {
108
+ boxShadow: 'none',
109
+ width: '250px'
110
+ }
111
+ }
112
+ } }),
113
+ react_1.default.createElement("button", { className: "color-picker-back-btn", onClick: function () { return setPickerMode('palette'); } }, "Back to Palette")))))),
114
+ react_1.default.createElement(FormatButtons_1.FormatButtons, null),
115
+ react_1.default.createElement(AlignMenu_1.AlignMenu, null)));
116
+ };
117
+ exports.default = TextToolbar;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import '../styles/Toolbar.css';
3
+ export default function Toolbar(): React.JSX.Element;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var react_1 = __importDefault(require("react"));
7
+ var grommet_icons_1 = require("grommet-icons");
8
+ var ProductEditorContext_1 = require("../context/ProductEditorContext");
9
+ var canvasUtils_1 = require("../utils/canvasUtils");
10
+ require("../styles/Toolbar.css");
11
+ function Toolbar() {
12
+ var _a = (0, ProductEditorContext_1.useProductEditor)(), canvas = _a.canvas, width = _a.width, setShowGrid = _a.setShowGrid, showGrid = _a.showGrid, height = _a.height, showPreview = _a.showPreview, togglePreview = _a.togglePreview, showLayerPanel = _a.showLayerPanel, toggleLayerPanel = _a.toggleLayerPanel, deleteObject = _a.deleteObject, selectedObjectId = _a.selectedObjectId, renderedDraftPreviews = _a.renderedDraftPreviews;
13
+ // Add handleAddText function before the return statement
14
+ var handleAddText = function () {
15
+ if (!canvas)
16
+ return;
17
+ (0, canvasUtils_1.addTextToCanvas)(canvas, width, height);
18
+ };
19
+ var toggleGrid = function () { return setShowGrid(!showGrid); };
20
+ // Handle delete button click
21
+ var handleDelete = function () {
22
+ if (!canvas)
23
+ return;
24
+ var activeObject = canvas.getActiveObject();
25
+ if (activeObject) {
26
+ deleteObject(activeObject);
27
+ }
28
+ };
29
+ // Check if previews are available
30
+ var hasPreview = renderedDraftPreviews && renderedDraftPreviews.length > 0;
31
+ return (react_1.default.createElement(react_1.default.Fragment, null,
32
+ react_1.default.createElement("div", { className: "grid-toggle" },
33
+ react_1.default.createElement("div", { className: "toolbar-button ".concat(showGrid ? 'active' : ''), onClick: toggleGrid },
34
+ react_1.default.createElement(grommet_icons_1.Apps, { width: 24, height: 24 }),
35
+ react_1.default.createElement("span", null, showGrid ? 'Hide Grid' : 'Show Grid'))),
36
+ react_1.default.createElement("div", { className: "preview-toggle" },
37
+ react_1.default.createElement("div", { className: "toolbar-button ".concat(showPreview && hasPreview ? 'active' : '', " ").concat(!hasPreview ? 'disabled' : ''), onClick: hasPreview ? togglePreview : undefined },
38
+ react_1.default.createElement(grommet_icons_1.View, { width: 24, height: 24 }),
39
+ react_1.default.createElement("span", null, hasPreview && showPreview ? 'Hide Preview' : 'Show Preview'))),
40
+ react_1.default.createElement("div", { className: "toolbar-button ".concat(showLayerPanel ? 'active' : ''), onClick: toggleLayerPanel },
41
+ react_1.default.createElement(grommet_icons_1.Layer, { width: 24, height: 24 }),
42
+ react_1.default.createElement("span", null, "Layer")),
43
+ react_1.default.createElement("div", { className: "toolbar-button ".concat(!selectedObjectId ? 'disabled' : ''), onClick: handleDelete },
44
+ react_1.default.createElement(grommet_icons_1.Trash, { width: 24, height: 24 }),
45
+ react_1.default.createElement("span", null, "Delete"))));
46
+ }
47
+ exports.default = Toolbar;
@@ -0,0 +1 @@
1
+ export declare const defaultPalette: (string | null)[][];
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultPalette = void 0;
4
+ exports.defaultPalette = [
5
+ [null, '#000000', '#434343', '#666666', '#999999', '#CCCCCC', '#D9D9D9', '#EFEFEF'],
6
+ ['#FFFFFF', '#F44E3B', '#FE9200', '#FCDC00', '#DBDF00', '#A4DD00', '#68CCCA', '#73D8FF'],
7
+ ['#AEA1FF', '#FDA1FF', '#CF329A', '#FF6900', '#FCB900', '#7BDCB5', '#00D084', '#8ED1FC'],
8
+ ['#0693E3', '#EB144C', '#F78DA7', '#9900EF', '#B80000', '#DB3E00', '#FCC400', '#27724D'],
9
+ ['#607D8B', '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800', '#FF5722', '#795548']
10
+ ];
@@ -0,0 +1,5 @@
1
+ export interface FontOption {
2
+ value: string;
3
+ label: string;
4
+ }
5
+ export declare const defaultFontOptions: FontOption[];
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultFontOptions = void 0;
4
+ exports.defaultFontOptions = [
5
+ { value: 'Arial', label: 'Arial' },
6
+ { value: 'Brush Script MT', label: 'Brush Script MT' },
7
+ { value: 'Courier New', label: 'Courier New' },
8
+ { value: 'Garamond', label: 'Garamond' },
9
+ { value: 'Georgia', label: 'Georgia' },
10
+ { value: 'Lato', label: 'Lato' },
11
+ { value: 'Montserrat', label: 'Montserrat' },
12
+ { value: 'Nunito', label: 'Nunito' },
13
+ { value: 'Open Sans', label: 'Open Sans' },
14
+ { value: 'Oswald', label: 'Oswald' },
15
+ { value: 'Playfair Display', label: 'Playfair Display' },
16
+ { value: 'Roboto', label: 'Roboto' },
17
+ { value: 'Tahoma', label: 'Tahoma' },
18
+ { value: 'Times New Roman', label: 'Times New Roman' },
19
+ { value: 'Trebuchet MS', label: 'Trebuchet MS' },
20
+ { value: 'Verdana', label: 'Verdana' },
21
+ ];
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+ import { fabric } from 'fabric';
3
+ import { Product, Job, DraftTemplate, DraftTemplateData, DraftPreview, SavedCanvasObject, RenderedDraftPreview } from '../types';
4
+ import { FontOption } from '../config/fontConfig';
5
+ import { UseFormReturn } from 'react-hook-form';
6
+ interface ProductEditorContextType {
7
+ canvas: fabric.Canvas | null;
8
+ draftPreviews: DraftPreview[];
9
+ draftTemplates: DraftTemplateData[];
10
+ isCanvasLoading: boolean;
11
+ isMobileView: boolean;
12
+ loadingPreviews: boolean;
13
+ renderedDraftPreviews: RenderedDraftPreview[];
14
+ savedObjects: SavedCanvasObject[];
15
+ selectedTemplate: number | null;
16
+ selectedTextObject: fabric.IText | null;
17
+ showGrid: boolean;
18
+ showPreview: boolean;
19
+ setCanvas: (canvas: fabric.Canvas) => void;
20
+ setSelectedTemplate: (templateId: number) => void;
21
+ setShowGrid: (show: boolean) => void;
22
+ handleCancel: () => void;
23
+ handleSave: () => void;
24
+ handleTemplateChange: (draftTemplate: DraftTemplate) => void;
25
+ recordVariationFieldObjectsOnCanvas: () => void;
26
+ togglePreview: () => void;
27
+ updateSelectedText: (props: Partial<fabric.IText>) => void;
28
+ fontOptions: FontOption[];
29
+ colorPalette: (string | null)[][];
30
+ showLayerPanel: boolean;
31
+ toggleLayerPanel: () => void;
32
+ selectedObjectId: string | null;
33
+ setSelectedObjectId: (id: string | null) => void;
34
+ selectObject: (obj: fabric.Object | null) => void;
35
+ deleteObject: (obj: fabric.Object) => void;
36
+ canvasRef: React.RefObject<HTMLCanvasElement | null>;
37
+ groupIndex: number;
38
+ height: number;
39
+ inputName: string;
40
+ job: Job;
41
+ product: Product;
42
+ width: number;
43
+ hookForm: UseFormReturn<any> | null;
44
+ }
45
+ interface ProductEditorProviderProps {
46
+ children: React.ReactNode;
47
+ groupIndex?: number;
48
+ product: Product;
49
+ width?: number;
50
+ height?: number;
51
+ job: Job;
52
+ onSave: () => void;
53
+ onCancel: () => void;
54
+ hookForm?: UseFormReturn<any> | null;
55
+ fontOptions?: FontOption[];
56
+ colorPalette?: (string | null)[][];
57
+ }
58
+ export declare const ProductEditorProvider: React.FC<ProductEditorProviderProps>;
59
+ export declare const useProductEditor: () => ProductEditorContextType;
60
+ export {};