@servicetitan/dte-unlayer 0.89.0 → 0.91.0
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/dist/api-core.js +29 -22
- package/dist/api-core.js.map +1 -1
- package/dist/api-custom-tools.js +35 -42
- package/dist/api-custom-tools.js.map +1 -1
- package/dist/editor-core-source.d.ts +3 -3
- package/dist/editor-core-source.d.ts.map +1 -1
- package/dist/editor-core-source.js +4 -4
- package/dist/editor-core-source.js.map +1 -1
- package/dist/editor-core.js +2 -2
- package/dist/editor-core.js.map +1 -1
- package/dist/editor.d.ts +1 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +80 -34
- package/dist/editor.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/loadScript.d.ts.map +1 -1
- package/dist/loadScript.js +7 -6
- package/dist/loadScript.js.map +1 -1
- package/dist/shared/configs.d.ts +6 -0
- package/dist/shared/configs.d.ts.map +1 -0
- package/dist/shared/configs.js +7 -0
- package/dist/shared/configs.js.map +1 -0
- package/dist/shared/const.js +2 -1
- package/dist/shared/const.js.map +1 -1
- package/dist/shared/edit-icon.js +1 -0
- package/dist/shared/edit-icon.js.map +1 -1
- package/dist/shared/fonts.js +24 -17
- package/dist/shared/fonts.js.map +1 -1
- package/dist/shared/schema.d.ts.map +1 -1
- package/dist/shared/schema.js +91 -49
- package/dist/shared/schema.js.map +1 -1
- package/dist/shared/tools.d.ts.map +1 -1
- package/dist/shared/tools.js +13 -6
- package/dist/shared/tools.js.map +1 -1
- package/dist/store.d.ts +8 -5
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +302 -314
- package/dist/store.js.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +120 -112
- package/dist/tools.js.map +1 -1
- package/dist/unlayer-interface.d.ts +5 -0
- package/dist/unlayer-interface.d.ts.map +1 -1
- package/dist/unlayer-interface.js +2 -1
- package/dist/unlayer-interface.js.map +1 -1
- package/dist/unlayer.d.ts +1 -0
- package/dist/unlayer.d.ts.map +1 -1
- package/dist/unlayer.js +115 -70
- package/dist/unlayer.js.map +1 -1
- package/package.json +1 -1
- package/src/editor-core-source.ts +3 -3
- package/src/editor.tsx +8 -0
- package/src/shared/configs.ts +5 -0
- package/src/store.ts +85 -6
- package/src/unlayer-interface.tsx +5 -0
- package/src/unlayer.tsx +11 -1
package/src/editor.tsx
CHANGED
|
@@ -26,6 +26,8 @@ export interface UnlayerEditorProps {
|
|
|
26
26
|
|
|
27
27
|
onImage?(file: File): Promise<{ url: string }>;
|
|
28
28
|
|
|
29
|
+
onError?(title: string, description?: string): void;
|
|
30
|
+
|
|
29
31
|
onMessage?(type: string, data: any): void;
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -88,6 +90,12 @@ export const UnlayerEditor = forwardRef<UnlayerRef, UnlayerEditorProps>((props,
|
|
|
88
90
|
return () => store.setOnImage();
|
|
89
91
|
}, [props.onImage, store]);
|
|
90
92
|
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
store.setOnError(props.onError);
|
|
95
|
+
|
|
96
|
+
return () => store.setOnError();
|
|
97
|
+
}, [props.onError, store]);
|
|
98
|
+
|
|
91
99
|
useEffect(() => {
|
|
92
100
|
store.setOnMessage(props.onMessage);
|
|
93
101
|
|
package/src/store.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { loadScript } from './loadScript';
|
|
2
|
+
import { defaultImageValidation } from './shared/configs';
|
|
2
3
|
import { UnlayerEditorTwin, UnlayerEventConfig, UnlayerEventRegister } from './shared/const';
|
|
3
4
|
import { unlayerToolsParseTwinKey } from './shared/tools';
|
|
4
5
|
import { unlayerToolsIterate } from './tools';
|
|
@@ -46,6 +47,7 @@ export class UnlayerStore {
|
|
|
46
47
|
private onSnapshotSaveCB?: (snapshot: UnlayerEditorTwin) => void;
|
|
47
48
|
private onReadyCB?: () => void;
|
|
48
49
|
private onImageCB?: (file: File) => Promise<{ url: string }>;
|
|
50
|
+
private onErrorCB?: (title: string, description?: string) => void;
|
|
49
51
|
|
|
50
52
|
constructor(readonly props: CreateUnlayerEditorProps) {
|
|
51
53
|
this.props.eSignFieldTypes = ['Signature', 'Initials', 'Date Signed', 'Full Name'];
|
|
@@ -129,6 +131,10 @@ export class UnlayerStore {
|
|
|
129
131
|
this.onImageCB = onImage;
|
|
130
132
|
};
|
|
131
133
|
|
|
134
|
+
setOnError = (onError?: UnlayerStore['onErrorCB']) => {
|
|
135
|
+
this.onErrorCB = onError;
|
|
136
|
+
};
|
|
137
|
+
|
|
132
138
|
setOnMessage = (onMessage?: UnlayerStore['onMessageCB']) => {
|
|
133
139
|
this.onMessageCB = onMessage;
|
|
134
140
|
};
|
|
@@ -250,22 +256,95 @@ export class UnlayerStore {
|
|
|
250
256
|
data,
|
|
251
257
|
},
|
|
252
258
|
},
|
|
253
|
-
'*'
|
|
259
|
+
'*',
|
|
254
260
|
);
|
|
255
261
|
};
|
|
256
262
|
|
|
257
|
-
private uploadImage =
|
|
263
|
+
private uploadImage = async (
|
|
264
|
+
data: { attachments: File[] },
|
|
265
|
+
done: (result: { progress: number; url?: string }) => void,
|
|
266
|
+
) => {
|
|
258
267
|
if (!this.onImageCB) {
|
|
259
268
|
done({ progress: 100 });
|
|
260
269
|
throw new Error('image upload is not implemented');
|
|
261
270
|
}
|
|
262
271
|
|
|
272
|
+
if (!data.attachments?.length) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const file = data.attachments[0];
|
|
277
|
+
|
|
278
|
+
const res = await this.validateImage(file, {
|
|
279
|
+
...defaultImageValidation,
|
|
280
|
+
...(this.props.imageValidation ?? {}),
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
if (!res.isValid) {
|
|
284
|
+
this.onErrorCB?.(res.title, res.description);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
263
288
|
done({ progress: 0 });
|
|
264
289
|
|
|
265
|
-
|
|
266
|
-
this.onImageCB(
|
|
267
|
-
|
|
268
|
-
|
|
290
|
+
try {
|
|
291
|
+
const { url } = await this.onImageCB(file);
|
|
292
|
+
done({ progress: 100, url });
|
|
293
|
+
} catch {
|
|
294
|
+
this.onErrorCB?.(
|
|
295
|
+
'Image upload failed',
|
|
296
|
+
'Something went wrong while uploading the image. Please try again or select another image.',
|
|
297
|
+
);
|
|
298
|
+
done({ progress: 100 });
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
private validateImage = async (
|
|
303
|
+
file: File,
|
|
304
|
+
imageValidation: { maxFileSize: number; maxWidth: number; maxHeight: number },
|
|
305
|
+
): Promise<{ isValid: boolean; title: string; description: string }> => {
|
|
306
|
+
const { maxFileSize, maxHeight, maxWidth } = imageValidation;
|
|
307
|
+
|
|
308
|
+
if (file.size > maxFileSize) {
|
|
309
|
+
const maxSizeMB = (maxFileSize / 1024 / 1024).toFixed(2);
|
|
310
|
+
const fileSizeMB = (file.size / 1024 / 1024).toFixed(2);
|
|
311
|
+
return {
|
|
312
|
+
isValid: false,
|
|
313
|
+
title: 'Image size limit reached',
|
|
314
|
+
description: `This image is ${fileSizeMB}MB, which is above the ${maxSizeMB}MB limit. Please upload a smaller file to continue.`,
|
|
315
|
+
};
|
|
269
316
|
}
|
|
317
|
+
|
|
318
|
+
return new Promise(resolve => {
|
|
319
|
+
const img = new Image();
|
|
320
|
+
const objectUrl = URL.createObjectURL(file);
|
|
321
|
+
|
|
322
|
+
img.onload = () => {
|
|
323
|
+
URL.revokeObjectURL(objectUrl);
|
|
324
|
+
const { height, width } = img;
|
|
325
|
+
|
|
326
|
+
if (width > maxWidth || height > maxHeight) {
|
|
327
|
+
resolve({
|
|
328
|
+
isValid: false,
|
|
329
|
+
title: 'Dimension limit reached',
|
|
330
|
+
description: `These image dimensions (${width}x${height}px) exceed the ${maxWidth}x${maxHeight}px limit. Please resize the image and try again.`,
|
|
331
|
+
});
|
|
332
|
+
} else {
|
|
333
|
+
resolve({ isValid: true, title: '', description: '' });
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
img.onerror = () => {
|
|
338
|
+
URL.revokeObjectURL(objectUrl);
|
|
339
|
+
resolve({
|
|
340
|
+
isValid: false,
|
|
341
|
+
title: 'The image is broken',
|
|
342
|
+
description:
|
|
343
|
+
'Looks like this image isn’t valid. Please choose another image and try again.',
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
img.src = objectUrl;
|
|
348
|
+
});
|
|
270
349
|
};
|
|
271
350
|
}
|
package/src/unlayer.tsx
CHANGED
|
@@ -94,6 +94,15 @@ export const hideUnlayerBodyMenuItem = () => {
|
|
|
94
94
|
`;
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
export const hideMobileTabletPreview = () => `
|
|
98
|
+
[data-key="preview-tablet"],
|
|
99
|
+
[data-key="resolution"],
|
|
100
|
+
[data-key="dark-mode"],
|
|
101
|
+
[data-key="preview-desktop"],
|
|
102
|
+
[data-key="preview-mobile"] {
|
|
103
|
+
display: none !important;
|
|
104
|
+
}
|
|
105
|
+
`;
|
|
97
106
|
export const hideUnlayerTools = () => {
|
|
98
107
|
return `
|
|
99
108
|
.blockbuilder-content-tools {
|
|
@@ -165,6 +174,7 @@ export const createUnlayerEditor = (
|
|
|
165
174
|
* @TODO this is workaround for hiding all tools from unlayer sidebar.
|
|
166
175
|
* Will be better to use unlayer functionality for this but it is not implemented yet
|
|
167
176
|
*/
|
|
177
|
+
hideMobileTabletPreview(),
|
|
168
178
|
hideAllTools ? hideUnlayerTools() : '',
|
|
169
179
|
hideContentControls ? hideUnlayerContentsControls() : '',
|
|
170
180
|
hideBodyMenuItem ? hideUnlayerBodyMenuItem() : '',
|
|
@@ -239,7 +249,7 @@ export const createUnlayerEditor = (
|
|
|
239
249
|
displayMode: 'web',
|
|
240
250
|
devices: ['desktop'],
|
|
241
251
|
features: {
|
|
242
|
-
preview:
|
|
252
|
+
preview: true,
|
|
243
253
|
userUploads: false,
|
|
244
254
|
stockImages: false,
|
|
245
255
|
},
|