@orion-studios/payload-studio 0.5.0-beta.65 → 0.5.0-beta.67
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/admin-app/client.js +58 -18
- package/dist/admin-app/client.mjs +1 -1
- package/dist/chunk-ROTPP5CU.mjs +99 -0
- package/dist/index.mjs +3 -3
- package/dist/studio-pages/builder.css +34 -0
- package/dist/studio-pages/client.js +80 -46
- package/dist/studio-pages/client.mjs +23 -29
- package/package.json +1 -1
- package/dist/chunk-I3HYCS77.mjs +0 -59
package/dist/admin-app/client.js
CHANGED
|
@@ -694,6 +694,41 @@ var import_navigation = require("next/navigation");
|
|
|
694
694
|
|
|
695
695
|
// src/shared/clientImageUploadOptimization.ts
|
|
696
696
|
var MAX_DIRECT_UPLOAD_BYTES = 4e6;
|
|
697
|
+
var extensionForMimeType = (mimeType) => {
|
|
698
|
+
switch (mimeType) {
|
|
699
|
+
case "image/webp":
|
|
700
|
+
return ".webp";
|
|
701
|
+
case "image/png":
|
|
702
|
+
return ".png";
|
|
703
|
+
default:
|
|
704
|
+
return ".jpg";
|
|
705
|
+
}
|
|
706
|
+
};
|
|
707
|
+
var detectCanvasTransparency = (context, width, height) => {
|
|
708
|
+
try {
|
|
709
|
+
const { data } = context.getImageData(0, 0, width, height);
|
|
710
|
+
for (let index = 3; index < data.length; index += 4) {
|
|
711
|
+
if (data[index] < 255) {
|
|
712
|
+
return true;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
} catch {
|
|
716
|
+
}
|
|
717
|
+
return false;
|
|
718
|
+
};
|
|
719
|
+
var resolveOutputMimeTypes = (sourceMime, hasTransparency) => {
|
|
720
|
+
const candidates = [];
|
|
721
|
+
if (hasTransparency) {
|
|
722
|
+
candidates.push("image/webp", "image/png");
|
|
723
|
+
} else if (sourceMime === "image/webp") {
|
|
724
|
+
candidates.push("image/webp", "image/jpeg");
|
|
725
|
+
} else if (sourceMime === "image/png") {
|
|
726
|
+
candidates.push("image/webp", "image/jpeg", "image/png");
|
|
727
|
+
} else {
|
|
728
|
+
candidates.push("image/jpeg", "image/webp");
|
|
729
|
+
}
|
|
730
|
+
return [...new Set(candidates)];
|
|
731
|
+
};
|
|
697
732
|
async function optimizeImageForUpload(file) {
|
|
698
733
|
if (!file.type.startsWith("image/")) {
|
|
699
734
|
return file;
|
|
@@ -714,26 +749,31 @@ async function optimizeImageForUpload(file) {
|
|
|
714
749
|
return file;
|
|
715
750
|
}
|
|
716
751
|
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
717
|
-
const
|
|
752
|
+
const sourceMime = file.type.toLowerCase();
|
|
753
|
+
const hasTransparency = detectCanvasTransparency(context, canvas.width, canvas.height);
|
|
754
|
+
const outputMimes = resolveOutputMimeTypes(sourceMime, hasTransparency);
|
|
718
755
|
const qualityPasses = [0.82, 0.74, 0.66, 0.58, 0.5, 0.42, 0.36, 0.3, 0.26];
|
|
719
756
|
let bestFile = null;
|
|
720
|
-
for (const
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
757
|
+
for (const outputMime of outputMimes) {
|
|
758
|
+
const passes = outputMime === "image/png" ? [void 0] : qualityPasses;
|
|
759
|
+
for (const quality of passes) {
|
|
760
|
+
const blob = await new Promise((resolve) => {
|
|
761
|
+
canvas.toBlob((value) => resolve(value), outputMime, quality);
|
|
762
|
+
});
|
|
763
|
+
if (!blob) {
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
const optimizedName = file.name.replace(/\.[^/.]+$/, extensionForMimeType(outputMime));
|
|
767
|
+
const optimized = new File([blob], optimizedName, {
|
|
768
|
+
lastModified: Date.now(),
|
|
769
|
+
type: outputMime
|
|
770
|
+
});
|
|
771
|
+
if (!bestFile || optimized.size < bestFile.size) {
|
|
772
|
+
bestFile = optimized;
|
|
773
|
+
}
|
|
774
|
+
if (optimized.size <= MAX_DIRECT_UPLOAD_BYTES) {
|
|
775
|
+
break;
|
|
776
|
+
}
|
|
737
777
|
}
|
|
738
778
|
}
|
|
739
779
|
if (!bestFile) {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
// src/shared/clientImageUploadOptimization.ts
|
|
4
|
+
var MAX_DIRECT_UPLOAD_BYTES = 4e6;
|
|
5
|
+
var extensionForMimeType = (mimeType) => {
|
|
6
|
+
switch (mimeType) {
|
|
7
|
+
case "image/webp":
|
|
8
|
+
return ".webp";
|
|
9
|
+
case "image/png":
|
|
10
|
+
return ".png";
|
|
11
|
+
default:
|
|
12
|
+
return ".jpg";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var detectCanvasTransparency = (context, width, height) => {
|
|
16
|
+
try {
|
|
17
|
+
const { data } = context.getImageData(0, 0, width, height);
|
|
18
|
+
for (let index = 3; index < data.length; index += 4) {
|
|
19
|
+
if (data[index] < 255) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
};
|
|
27
|
+
var resolveOutputMimeTypes = (sourceMime, hasTransparency) => {
|
|
28
|
+
const candidates = [];
|
|
29
|
+
if (hasTransparency) {
|
|
30
|
+
candidates.push("image/webp", "image/png");
|
|
31
|
+
} else if (sourceMime === "image/webp") {
|
|
32
|
+
candidates.push("image/webp", "image/jpeg");
|
|
33
|
+
} else if (sourceMime === "image/png") {
|
|
34
|
+
candidates.push("image/webp", "image/jpeg", "image/png");
|
|
35
|
+
} else {
|
|
36
|
+
candidates.push("image/jpeg", "image/webp");
|
|
37
|
+
}
|
|
38
|
+
return [...new Set(candidates)];
|
|
39
|
+
};
|
|
40
|
+
async function optimizeImageForUpload(file) {
|
|
41
|
+
if (!file.type.startsWith("image/")) {
|
|
42
|
+
return file;
|
|
43
|
+
}
|
|
44
|
+
const objectURL = URL.createObjectURL(file);
|
|
45
|
+
try {
|
|
46
|
+
const image = await new Promise((resolve, reject) => {
|
|
47
|
+
const nextImage = new Image();
|
|
48
|
+
nextImage.onload = () => resolve(nextImage);
|
|
49
|
+
nextImage.onerror = () => reject(new Error("Could not read image for upload optimization."));
|
|
50
|
+
nextImage.src = objectURL;
|
|
51
|
+
});
|
|
52
|
+
const canvas = document.createElement("canvas");
|
|
53
|
+
canvas.width = Math.max(1, image.width);
|
|
54
|
+
canvas.height = Math.max(1, image.height);
|
|
55
|
+
const context = canvas.getContext("2d");
|
|
56
|
+
if (!context) {
|
|
57
|
+
return file;
|
|
58
|
+
}
|
|
59
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
60
|
+
const sourceMime = file.type.toLowerCase();
|
|
61
|
+
const hasTransparency = detectCanvasTransparency(context, canvas.width, canvas.height);
|
|
62
|
+
const outputMimes = resolveOutputMimeTypes(sourceMime, hasTransparency);
|
|
63
|
+
const qualityPasses = [0.82, 0.74, 0.66, 0.58, 0.5, 0.42, 0.36, 0.3, 0.26];
|
|
64
|
+
let bestFile = null;
|
|
65
|
+
for (const outputMime of outputMimes) {
|
|
66
|
+
const passes = outputMime === "image/png" ? [void 0] : qualityPasses;
|
|
67
|
+
for (const quality of passes) {
|
|
68
|
+
const blob = await new Promise((resolve) => {
|
|
69
|
+
canvas.toBlob((value) => resolve(value), outputMime, quality);
|
|
70
|
+
});
|
|
71
|
+
if (!blob) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const optimizedName = file.name.replace(/\.[^/.]+$/, extensionForMimeType(outputMime));
|
|
75
|
+
const optimized = new File([blob], optimizedName, {
|
|
76
|
+
lastModified: Date.now(),
|
|
77
|
+
type: outputMime
|
|
78
|
+
});
|
|
79
|
+
if (!bestFile || optimized.size < bestFile.size) {
|
|
80
|
+
bestFile = optimized;
|
|
81
|
+
}
|
|
82
|
+
if (optimized.size <= MAX_DIRECT_UPLOAD_BYTES) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!bestFile) {
|
|
88
|
+
return file;
|
|
89
|
+
}
|
|
90
|
+
return bestFile.size < file.size ? bestFile : file;
|
|
91
|
+
} finally {
|
|
92
|
+
URL.revokeObjectURL(objectURL);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
MAX_DIRECT_UPLOAD_BYTES,
|
|
98
|
+
optimizeImageForUpload
|
|
99
|
+
};
|
package/dist/index.mjs
CHANGED
|
@@ -4,9 +4,6 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
admin_app_exports
|
|
6
6
|
} from "./chunk-XVH5SCBD.mjs";
|
|
7
|
-
import {
|
|
8
|
-
blocks_exports
|
|
9
|
-
} from "./chunk-4AOYZGIY.mjs";
|
|
10
7
|
import {
|
|
11
8
|
nextjs_exports
|
|
12
9
|
} from "./chunk-SBJHEKTV.mjs";
|
|
@@ -16,6 +13,9 @@ import {
|
|
|
16
13
|
import {
|
|
17
14
|
studio_pages_exports
|
|
18
15
|
} from "./chunk-OHAGPJBM.mjs";
|
|
16
|
+
import {
|
|
17
|
+
blocks_exports
|
|
18
|
+
} from "./chunk-4AOYZGIY.mjs";
|
|
19
19
|
import "./chunk-SIL2J5MF.mjs";
|
|
20
20
|
import "./chunk-6BWS3CLP.mjs";
|
|
21
21
|
export {
|
|
@@ -389,9 +389,33 @@ h4 {
|
|
|
389
389
|
|
|
390
390
|
.quote {
|
|
391
391
|
font-size: 0.98rem;
|
|
392
|
+
line-height: 1.55;
|
|
392
393
|
color: var(--orion-studio-ink);
|
|
393
394
|
}
|
|
394
395
|
|
|
396
|
+
.testimonial-quote-mark {
|
|
397
|
+
display: block;
|
|
398
|
+
font-size: 2.2rem;
|
|
399
|
+
line-height: 0.8;
|
|
400
|
+
color: #e7b55a;
|
|
401
|
+
margin-bottom: 0.25rem;
|
|
402
|
+
opacity: 0.8;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.testimonial-quote {
|
|
406
|
+
display: -webkit-box;
|
|
407
|
+
-webkit-box-orient: vertical;
|
|
408
|
+
-webkit-line-clamp: 3;
|
|
409
|
+
overflow: hidden;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
@supports not (-webkit-line-clamp: 1) {
|
|
413
|
+
.testimonial-quote {
|
|
414
|
+
display: block;
|
|
415
|
+
max-height: calc((3 * 1.55em) - 0.5px);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
395
419
|
.quote-author {
|
|
396
420
|
margin-top: 0.75rem;
|
|
397
421
|
display: flex;
|
|
@@ -560,6 +584,16 @@ h4 {
|
|
|
560
584
|
grid-template-columns: var(--testimonials-grid-columns, repeat(auto-fit, minmax(260px, 1fr)));
|
|
561
585
|
}
|
|
562
586
|
|
|
587
|
+
.testimonial-quote {
|
|
588
|
+
-webkit-line-clamp: 2;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
@supports not (-webkit-line-clamp: 1) {
|
|
592
|
+
.testimonial-quote {
|
|
593
|
+
max-height: calc((2 * 1.55em) - 0.5px);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
563
597
|
.orion-stats-grid {
|
|
564
598
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
565
599
|
}
|
|
@@ -265,6 +265,41 @@ var layoutToStudioDocument = (layout, title, metadata) => {
|
|
|
265
265
|
|
|
266
266
|
// src/shared/clientImageUploadOptimization.ts
|
|
267
267
|
var MAX_DIRECT_UPLOAD_BYTES = 4e6;
|
|
268
|
+
var extensionForMimeType = (mimeType) => {
|
|
269
|
+
switch (mimeType) {
|
|
270
|
+
case "image/webp":
|
|
271
|
+
return ".webp";
|
|
272
|
+
case "image/png":
|
|
273
|
+
return ".png";
|
|
274
|
+
default:
|
|
275
|
+
return ".jpg";
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var detectCanvasTransparency = (context, width, height) => {
|
|
279
|
+
try {
|
|
280
|
+
const { data } = context.getImageData(0, 0, width, height);
|
|
281
|
+
for (let index = 3; index < data.length; index += 4) {
|
|
282
|
+
if (data[index] < 255) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
} catch {
|
|
287
|
+
}
|
|
288
|
+
return false;
|
|
289
|
+
};
|
|
290
|
+
var resolveOutputMimeTypes = (sourceMime, hasTransparency) => {
|
|
291
|
+
const candidates = [];
|
|
292
|
+
if (hasTransparency) {
|
|
293
|
+
candidates.push("image/webp", "image/png");
|
|
294
|
+
} else if (sourceMime === "image/webp") {
|
|
295
|
+
candidates.push("image/webp", "image/jpeg");
|
|
296
|
+
} else if (sourceMime === "image/png") {
|
|
297
|
+
candidates.push("image/webp", "image/jpeg", "image/png");
|
|
298
|
+
} else {
|
|
299
|
+
candidates.push("image/jpeg", "image/webp");
|
|
300
|
+
}
|
|
301
|
+
return [...new Set(candidates)];
|
|
302
|
+
};
|
|
268
303
|
async function optimizeImageForUpload(file) {
|
|
269
304
|
if (!file.type.startsWith("image/")) {
|
|
270
305
|
return file;
|
|
@@ -285,26 +320,31 @@ async function optimizeImageForUpload(file) {
|
|
|
285
320
|
return file;
|
|
286
321
|
}
|
|
287
322
|
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
288
|
-
const
|
|
323
|
+
const sourceMime = file.type.toLowerCase();
|
|
324
|
+
const hasTransparency = detectCanvasTransparency(context, canvas.width, canvas.height);
|
|
325
|
+
const outputMimes = resolveOutputMimeTypes(sourceMime, hasTransparency);
|
|
289
326
|
const qualityPasses = [0.82, 0.74, 0.66, 0.58, 0.5, 0.42, 0.36, 0.3, 0.26];
|
|
290
327
|
let bestFile = null;
|
|
291
|
-
for (const
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
328
|
+
for (const outputMime of outputMimes) {
|
|
329
|
+
const passes = outputMime === "image/png" ? [void 0] : qualityPasses;
|
|
330
|
+
for (const quality of passes) {
|
|
331
|
+
const blob = await new Promise((resolve) => {
|
|
332
|
+
canvas.toBlob((value) => resolve(value), outputMime, quality);
|
|
333
|
+
});
|
|
334
|
+
if (!blob) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
const optimizedName = file.name.replace(/\.[^/.]+$/, extensionForMimeType(outputMime));
|
|
338
|
+
const optimized = new File([blob], optimizedName, {
|
|
339
|
+
lastModified: Date.now(),
|
|
340
|
+
type: outputMime
|
|
341
|
+
});
|
|
342
|
+
if (!bestFile || optimized.size < bestFile.size) {
|
|
343
|
+
bestFile = optimized;
|
|
344
|
+
}
|
|
345
|
+
if (optimized.size <= MAX_DIRECT_UPLOAD_BYTES) {
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
308
348
|
}
|
|
309
349
|
}
|
|
310
350
|
if (!bestFile) {
|
|
@@ -3130,20 +3170,17 @@ function BuilderPageEditor({ initialDoc, pageID }) {
|
|
|
3130
3170
|
},
|
|
3131
3171
|
style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
|
|
3132
3172
|
children: [
|
|
3133
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
),
|
|
3145
|
-
'"'
|
|
3146
|
-
] }),
|
|
3173
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "testimonial-quote-mark", "aria-hidden": "true", children: "\u201C" }),
|
|
3174
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "quote testimonial-quote", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3175
|
+
InlineText,
|
|
3176
|
+
{
|
|
3177
|
+
as: "span",
|
|
3178
|
+
multiline: true,
|
|
3179
|
+
onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
|
|
3180
|
+
placeholder: "Customer quote",
|
|
3181
|
+
value: normalizeText(item?.quote)
|
|
3182
|
+
}
|
|
3183
|
+
) }),
|
|
3147
3184
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "quote-author", children: [
|
|
3148
3185
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
|
|
3149
3186
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
@@ -3203,20 +3240,17 @@ function BuilderPageEditor({ initialDoc, pageID }) {
|
|
|
3203
3240
|
},
|
|
3204
3241
|
style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
|
|
3205
3242
|
children: [
|
|
3206
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
),
|
|
3218
|
-
'"'
|
|
3219
|
-
] }),
|
|
3243
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "testimonial-quote-mark", "aria-hidden": "true", children: "\u201C" }),
|
|
3244
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "quote testimonial-quote", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3245
|
+
InlineText,
|
|
3246
|
+
{
|
|
3247
|
+
as: "span",
|
|
3248
|
+
multiline: true,
|
|
3249
|
+
onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
|
|
3250
|
+
placeholder: "Customer quote",
|
|
3251
|
+
value: normalizeText(item?.quote)
|
|
3252
|
+
}
|
|
3253
|
+
) }),
|
|
3220
3254
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "quote-author", children: [
|
|
3221
3255
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
|
|
3222
3256
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
MAX_DIRECT_UPLOAD_BYTES,
|
|
5
5
|
optimizeImageForUpload
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-ROTPP5CU.mjs";
|
|
7
7
|
|
|
8
8
|
// src/studio-pages/builder/BuilderPageEditor.tsx
|
|
9
9
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
@@ -3053,20 +3053,17 @@ function BuilderPageEditor({ initialDoc, pageID }) {
|
|
|
3053
3053
|
},
|
|
3054
3054
|
style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
|
|
3055
3055
|
children: [
|
|
3056
|
-
/* @__PURE__ */
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
),
|
|
3068
|
-
'"'
|
|
3069
|
-
] }),
|
|
3056
|
+
/* @__PURE__ */ jsx("span", { className: "testimonial-quote-mark", "aria-hidden": "true", children: "\u201C" }),
|
|
3057
|
+
/* @__PURE__ */ jsx("p", { className: "quote testimonial-quote", children: /* @__PURE__ */ jsx(
|
|
3058
|
+
InlineText,
|
|
3059
|
+
{
|
|
3060
|
+
as: "span",
|
|
3061
|
+
multiline: true,
|
|
3062
|
+
onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
|
|
3063
|
+
placeholder: "Customer quote",
|
|
3064
|
+
value: normalizeText(item?.quote)
|
|
3065
|
+
}
|
|
3066
|
+
) }),
|
|
3070
3067
|
/* @__PURE__ */ jsxs("div", { className: "quote-author", children: [
|
|
3071
3068
|
/* @__PURE__ */ jsx("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
|
|
3072
3069
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -3126,20 +3123,17 @@ function BuilderPageEditor({ initialDoc, pageID }) {
|
|
|
3126
3123
|
},
|
|
3127
3124
|
style: isItemSelected ? { outline: "2px solid rgba(15, 125, 82, 0.55)", outlineOffset: 3 } : void 0,
|
|
3128
3125
|
children: [
|
|
3129
|
-
/* @__PURE__ */
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
),
|
|
3141
|
-
'"'
|
|
3142
|
-
] }),
|
|
3126
|
+
/* @__PURE__ */ jsx("span", { className: "testimonial-quote-mark", "aria-hidden": "true", children: "\u201C" }),
|
|
3127
|
+
/* @__PURE__ */ jsx("p", { className: "quote testimonial-quote", children: /* @__PURE__ */ jsx(
|
|
3128
|
+
InlineText,
|
|
3129
|
+
{
|
|
3130
|
+
as: "span",
|
|
3131
|
+
multiline: true,
|
|
3132
|
+
onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "quote", value),
|
|
3133
|
+
placeholder: "Customer quote",
|
|
3134
|
+
value: normalizeText(item?.quote)
|
|
3135
|
+
}
|
|
3136
|
+
) }),
|
|
3143
3137
|
/* @__PURE__ */ jsxs("div", { className: "quote-author", children: [
|
|
3144
3138
|
/* @__PURE__ */ jsx("div", { className: "quote-avatar", children: normalizeText(item?.name, "C").split(" ").slice(0, 2).map((part) => part[0]).join("").toUpperCase() }),
|
|
3145
3139
|
/* @__PURE__ */ jsxs("div", { children: [
|
package/package.json
CHANGED
package/dist/chunk-I3HYCS77.mjs
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
// src/shared/clientImageUploadOptimization.ts
|
|
4
|
-
var MAX_DIRECT_UPLOAD_BYTES = 4e6;
|
|
5
|
-
async function optimizeImageForUpload(file) {
|
|
6
|
-
if (!file.type.startsWith("image/")) {
|
|
7
|
-
return file;
|
|
8
|
-
}
|
|
9
|
-
const objectURL = URL.createObjectURL(file);
|
|
10
|
-
try {
|
|
11
|
-
const image = await new Promise((resolve, reject) => {
|
|
12
|
-
const nextImage = new Image();
|
|
13
|
-
nextImage.onload = () => resolve(nextImage);
|
|
14
|
-
nextImage.onerror = () => reject(new Error("Could not read image for upload optimization."));
|
|
15
|
-
nextImage.src = objectURL;
|
|
16
|
-
});
|
|
17
|
-
const canvas = document.createElement("canvas");
|
|
18
|
-
canvas.width = Math.max(1, image.width);
|
|
19
|
-
canvas.height = Math.max(1, image.height);
|
|
20
|
-
const context = canvas.getContext("2d");
|
|
21
|
-
if (!context) {
|
|
22
|
-
return file;
|
|
23
|
-
}
|
|
24
|
-
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
25
|
-
const outputMime = file.type === "image/webp" ? "image/webp" : "image/jpeg";
|
|
26
|
-
const qualityPasses = [0.82, 0.74, 0.66, 0.58, 0.5, 0.42, 0.36, 0.3, 0.26];
|
|
27
|
-
let bestFile = null;
|
|
28
|
-
for (const quality of qualityPasses) {
|
|
29
|
-
const blob = await new Promise((resolve) => {
|
|
30
|
-
canvas.toBlob((value) => resolve(value), outputMime, quality);
|
|
31
|
-
});
|
|
32
|
-
if (!blob) {
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
const optimizedName = file.name.replace(/\.[^/.]+$/, outputMime === "image/webp" ? ".webp" : ".jpg");
|
|
36
|
-
const optimized = new File([blob], optimizedName, {
|
|
37
|
-
lastModified: Date.now(),
|
|
38
|
-
type: outputMime
|
|
39
|
-
});
|
|
40
|
-
if (!bestFile || optimized.size < bestFile.size) {
|
|
41
|
-
bestFile = optimized;
|
|
42
|
-
}
|
|
43
|
-
if (optimized.size <= MAX_DIRECT_UPLOAD_BYTES) {
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if (!bestFile) {
|
|
48
|
-
return file;
|
|
49
|
-
}
|
|
50
|
-
return bestFile.size < file.size ? bestFile : file;
|
|
51
|
-
} finally {
|
|
52
|
-
URL.revokeObjectURL(objectURL);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export {
|
|
57
|
-
MAX_DIRECT_UPLOAD_BYTES,
|
|
58
|
-
optimizeImageForUpload
|
|
59
|
-
};
|