@pantheon-systems/p1-media 0.4.2 → 0.4.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 +56 -0
- package/dist/index.d.mts +16 -6
- package/dist/index.d.ts +16 -6
- package/dist/index.js +136 -113
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +136 -113
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +13 -3
- package/dist/server.d.ts +13 -3
- package/dist/server.js +25 -6
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +25 -6
- package/dist/server.mjs.map +1 -1
- package/package.json +16 -11
package/dist/index.mjs
CHANGED
|
@@ -17,6 +17,46 @@ var DEFAULT_MEDIA_PATTERNS = [
|
|
|
17
17
|
// src/components/media-field.tsx
|
|
18
18
|
import { useState as useState5 } from "react";
|
|
19
19
|
|
|
20
|
+
// src/crop.ts
|
|
21
|
+
function getBaseUrl(value) {
|
|
22
|
+
return value ? value.split("?")[0] : "";
|
|
23
|
+
}
|
|
24
|
+
function getParams(value) {
|
|
25
|
+
return new URLSearchParams(value.includes("?") ? value.split("?")[1] : "");
|
|
26
|
+
}
|
|
27
|
+
function getCropMode(value) {
|
|
28
|
+
if (!value) return "fit";
|
|
29
|
+
const params = getParams(value);
|
|
30
|
+
if (params.has("trim.left")) return "custom";
|
|
31
|
+
return params.get("fit") === "cover" ? "smart" : "fit";
|
|
32
|
+
}
|
|
33
|
+
function getTrimRect(value) {
|
|
34
|
+
if (!value) return null;
|
|
35
|
+
const params = getParams(value);
|
|
36
|
+
const read = (key) => {
|
|
37
|
+
const raw = params.get(key);
|
|
38
|
+
if (raw === null || raw === "") return null;
|
|
39
|
+
const n2 = Number(raw);
|
|
40
|
+
return Number.isFinite(n2) ? n2 : null;
|
|
41
|
+
};
|
|
42
|
+
const left = read("trim.left");
|
|
43
|
+
const top = read("trim.top");
|
|
44
|
+
const width = read("trim.width");
|
|
45
|
+
const height = read("trim.height");
|
|
46
|
+
if (left === null || top === null || width === null || height === null) return null;
|
|
47
|
+
return { left, top, width, height };
|
|
48
|
+
}
|
|
49
|
+
function buildValueWithCrop(baseUrl, crop) {
|
|
50
|
+
return crop === "smart" ? `${baseUrl}?fit=cover&gravity=auto` : `${baseUrl}?fit=scale-down`;
|
|
51
|
+
}
|
|
52
|
+
function buildValueWithTrim(baseUrl, rect) {
|
|
53
|
+
const left = Math.max(0, Math.round(rect.left));
|
|
54
|
+
const top = Math.max(0, Math.round(rect.top));
|
|
55
|
+
const width = Math.max(1, Math.round(rect.width));
|
|
56
|
+
const height = Math.max(1, Math.round(rect.height));
|
|
57
|
+
return `${baseUrl}?trim.left=${left}&trim.top=${top}&trim.width=${width}&trim.height=${height}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
20
60
|
// src/components/media-library.tsx
|
|
21
61
|
import { useState as useState4, useEffect as useEffect4, useRef as useRef4, useCallback } from "react";
|
|
22
62
|
|
|
@@ -182,6 +222,9 @@ async function runUpload(target, file, metadata, assetId, progress, onStep) {
|
|
|
182
222
|
uploaded = true;
|
|
183
223
|
}
|
|
184
224
|
const nextProgress = { presigned, uploaded };
|
|
225
|
+
if (presigned === void 0) {
|
|
226
|
+
throw new UploadFlowError("Resume state is missing its presign result", nextProgress);
|
|
227
|
+
}
|
|
185
228
|
const presignedResult = presigned;
|
|
186
229
|
onStep("finalizing");
|
|
187
230
|
const finalizePath = assetId ? `/media/${encodeURIComponent(assetId)}/versions/finalize` : "/media/finalize";
|
|
@@ -1284,12 +1327,13 @@ function MediaLibrary({ isOpen, onClose, onSelect, onSelectItem }) {
|
|
|
1284
1327
|
onClose();
|
|
1285
1328
|
};
|
|
1286
1329
|
const deleteItem = (item) => {
|
|
1287
|
-
|
|
1330
|
+
const { assetId } = item;
|
|
1331
|
+
if (!assetId) return;
|
|
1288
1332
|
(async () => {
|
|
1289
1333
|
try {
|
|
1290
1334
|
const params = siteParams(config);
|
|
1291
1335
|
const response = await fetch(
|
|
1292
|
-
config.workerUrl + "/media/" + encodeURIComponent(
|
|
1336
|
+
config.workerUrl + "/media/" + encodeURIComponent(assetId) + "?" + params.toString(),
|
|
1293
1337
|
{
|
|
1294
1338
|
method: "DELETE",
|
|
1295
1339
|
headers: await getAuthHeaders()
|
|
@@ -1427,46 +1471,6 @@ function MediaLibrary({ isOpen, onClose, onSelect, onSelectItem }) {
|
|
|
1427
1471
|
);
|
|
1428
1472
|
}
|
|
1429
1473
|
|
|
1430
|
-
// src/crop.ts
|
|
1431
|
-
function getBaseUrl(value) {
|
|
1432
|
-
return value ? value.split("?")[0] : "";
|
|
1433
|
-
}
|
|
1434
|
-
function getParams(value) {
|
|
1435
|
-
return new URLSearchParams(value.includes("?") ? value.split("?")[1] : "");
|
|
1436
|
-
}
|
|
1437
|
-
function getCropMode(value) {
|
|
1438
|
-
if (!value) return "fit";
|
|
1439
|
-
const params = getParams(value);
|
|
1440
|
-
if (params.has("trim.left")) return "custom";
|
|
1441
|
-
return params.get("fit") === "cover" ? "smart" : "fit";
|
|
1442
|
-
}
|
|
1443
|
-
function getTrimRect(value) {
|
|
1444
|
-
if (!value) return null;
|
|
1445
|
-
const params = getParams(value);
|
|
1446
|
-
const read = (key) => {
|
|
1447
|
-
const raw = params.get(key);
|
|
1448
|
-
if (raw === null || raw === "") return null;
|
|
1449
|
-
const n2 = Number(raw);
|
|
1450
|
-
return Number.isFinite(n2) ? n2 : null;
|
|
1451
|
-
};
|
|
1452
|
-
const left = read("trim.left");
|
|
1453
|
-
const top = read("trim.top");
|
|
1454
|
-
const width = read("trim.width");
|
|
1455
|
-
const height = read("trim.height");
|
|
1456
|
-
if (left === null || top === null || width === null || height === null) return null;
|
|
1457
|
-
return { left, top, width, height };
|
|
1458
|
-
}
|
|
1459
|
-
function buildValueWithCrop(baseUrl, crop) {
|
|
1460
|
-
return crop === "smart" ? `${baseUrl}?fit=cover&gravity=auto` : `${baseUrl}?fit=scale-down`;
|
|
1461
|
-
}
|
|
1462
|
-
function buildValueWithTrim(baseUrl, rect) {
|
|
1463
|
-
const left = Math.max(0, Math.round(rect.left));
|
|
1464
|
-
const top = Math.max(0, Math.round(rect.top));
|
|
1465
|
-
const width = Math.max(1, Math.round(rect.width));
|
|
1466
|
-
const height = Math.max(1, Math.round(rect.height));
|
|
1467
|
-
return `${baseUrl}?trim.left=${left}&trim.top=${top}&trim.width=${width}&trim.height=${height}`;
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1470
1474
|
// src/components/media-field.tsx
|
|
1471
1475
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1472
1476
|
function MediaFieldRender(props) {
|
|
@@ -1621,10 +1625,73 @@ function MediaFieldRender(props) {
|
|
|
1621
1625
|
// src/components/media-object-field.tsx
|
|
1622
1626
|
import { useState as useState7 } from "react";
|
|
1623
1627
|
|
|
1628
|
+
// src/media-value.ts
|
|
1629
|
+
var STRUCTURAL_MEDIA_KEYS = /* @__PURE__ */ new Set([
|
|
1630
|
+
"assetId",
|
|
1631
|
+
"versionId",
|
|
1632
|
+
"url",
|
|
1633
|
+
"metaSchemaVersion"
|
|
1634
|
+
]);
|
|
1635
|
+
function isMediaValue(value) {
|
|
1636
|
+
return typeof value === "object" && value !== null;
|
|
1637
|
+
}
|
|
1638
|
+
function makeMediaValue(input) {
|
|
1639
|
+
if (!input.assetId || !input.versionId) {
|
|
1640
|
+
return input.url;
|
|
1641
|
+
}
|
|
1642
|
+
const value = {
|
|
1643
|
+
assetId: input.assetId,
|
|
1644
|
+
versionId: input.versionId,
|
|
1645
|
+
url: input.url
|
|
1646
|
+
};
|
|
1647
|
+
if (typeof input.metaSchemaVersion === "number") {
|
|
1648
|
+
value.metaSchemaVersion = input.metaSchemaVersion;
|
|
1649
|
+
}
|
|
1650
|
+
if (input.metadata) {
|
|
1651
|
+
for (const [k, v] of Object.entries(input.metadata)) {
|
|
1652
|
+
if (v === void 0 || v === "") continue;
|
|
1653
|
+
if (STRUCTURAL_MEDIA_KEYS.has(k)) continue;
|
|
1654
|
+
value[k] = v;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
return value;
|
|
1658
|
+
}
|
|
1659
|
+
function buildValueFromAsset(asset, crop) {
|
|
1660
|
+
const metadata = { ...asset.metadata ?? {} };
|
|
1661
|
+
if (typeof asset.width === "number") metadata.width = asset.width;
|
|
1662
|
+
if (typeof asset.height === "number") metadata.height = asset.height;
|
|
1663
|
+
return makeMediaValue({
|
|
1664
|
+
assetId: asset.assetId,
|
|
1665
|
+
versionId: asset.versionId,
|
|
1666
|
+
url: buildValueWithCrop(getBaseUrl(asset.url), crop),
|
|
1667
|
+
metaSchemaVersion: asset.metaSchemaVersion,
|
|
1668
|
+
metadata
|
|
1669
|
+
});
|
|
1670
|
+
}
|
|
1671
|
+
function applyCropToValue(value, crop) {
|
|
1672
|
+
const currentUrl = isMediaValue(value) ? value.url : value;
|
|
1673
|
+
const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
|
|
1674
|
+
if (!baseUrl) return value;
|
|
1675
|
+
const url = buildValueWithCrop(baseUrl, crop);
|
|
1676
|
+
return isMediaValue(value) ? { ...value, url } : url;
|
|
1677
|
+
}
|
|
1678
|
+
function applyTrimToValue(value, rect) {
|
|
1679
|
+
const currentUrl = isMediaValue(value) ? value.url : value;
|
|
1680
|
+
const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
|
|
1681
|
+
if (!baseUrl) return value;
|
|
1682
|
+
const url = buildValueWithTrim(baseUrl, rect);
|
|
1683
|
+
return isMediaValue(value) ? { ...value, url } : url;
|
|
1684
|
+
}
|
|
1685
|
+
function setMetaOnValue(value, fieldName, fieldValue) {
|
|
1686
|
+
if (!isMediaValue(value)) return value;
|
|
1687
|
+
if (STRUCTURAL_MEDIA_KEYS.has(fieldName)) return value;
|
|
1688
|
+
return { ...value, [fieldName]: fieldValue };
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1624
1691
|
// src/components/crop-dialog.tsx
|
|
1625
1692
|
import { useEffect as useEffect5, useRef as useRef5, useState as useState6 } from "react";
|
|
1626
1693
|
|
|
1627
|
-
// ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.
|
|
1694
|
+
// ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.7/node_modules/react-image-crop/dist/index.js
|
|
1628
1695
|
import e, { PureComponent as t, createRef as n } from "react";
|
|
1629
1696
|
var r = {
|
|
1630
1697
|
x: 0,
|
|
@@ -2053,7 +2120,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
2053
2120
|
}
|
|
2054
2121
|
}
|
|
2055
2122
|
|
|
2056
|
-
// ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.
|
|
2123
|
+
// ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.7/node_modules/react-image-crop/dist/ReactCrop.css
|
|
2057
2124
|
styleInject('@keyframes marching-ants {\n 0% {\n background-position:\n 0 0,\n 0 100%,\n 0 0,\n 100% 0;\n }\n to {\n background-position:\n 20px 0,\n -20px 100%,\n 0 -20px,\n 100% 20px;\n }\n}\n:root {\n --rc-drag-handle-size:12px;\n --rc-drag-handle-mobile-size:24px;\n --rc-drag-handle-bg-colour:#0003;\n --rc-drag-bar-size:6px;\n --rc-border-color:#ffffffb3;\n --rc-focus-color:#08f;\n}\n.ReactCrop {\n cursor: crosshair;\n max-width: 100%;\n display: inline-block;\n position: relative;\n}\n.ReactCrop *,\n.ReactCrop :before,\n.ReactCrop :after {\n box-sizing: border-box;\n}\n.ReactCrop--disabled,\n.ReactCrop--locked {\n cursor: inherit;\n}\n.ReactCrop__child-wrapper {\n max-height: inherit;\n overflow: hidden;\n}\n.ReactCrop__child-wrapper > img,\n.ReactCrop__child-wrapper > video {\n max-width: 100%;\n max-height: inherit;\n display: block;\n}\n.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__child-wrapper > img,\n.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__child-wrapper > video,\n.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__crop-selection {\n touch-action: none;\n}\n.ReactCrop__crop-mask {\n pointer-events: none;\n width: calc(100% + .5px);\n height: calc(100% + .5px);\n position: absolute;\n inset: 0;\n}\n.ReactCrop__crop-selection {\n cursor: move;\n position: absolute;\n top: 0;\n left: 0;\n transform: translate(0, 0);\n}\n.ReactCrop--disabled .ReactCrop__crop-selection {\n cursor: inherit;\n}\n.ReactCrop--circular-crop .ReactCrop__crop-selection {\n border-radius: 50%;\n}\n.ReactCrop--circular-crop .ReactCrop__crop-selection:after {\n pointer-events: none;\n content: "";\n border: 1px solid var(--rc-border-color);\n opacity: .3;\n position: absolute;\n inset: -1px;\n}\n.ReactCrop--no-animate .ReactCrop__crop-selection {\n outline: 1px dashed #fff;\n}\n.ReactCrop__crop-selection:not(.ReactCrop--no-animate .ReactCrop__crop-selection) {\n color: #fff;\n background-image:\n linear-gradient(\n 90deg,\n #fff 50%,\n #444 50%),\n linear-gradient(\n 90deg,\n #fff 50%,\n #444 50%),\n linear-gradient(#fff 50%, #444 50%),\n linear-gradient(#fff 50%, #444 50%);\n background-position:\n 0 0,\n 0 100%,\n 0 0,\n 100% 0;\n background-repeat:\n repeat-x,\n repeat-x,\n repeat-y,\n repeat-y;\n background-size:\n 10px 1px,\n 10px 1px,\n 1px 10px,\n 1px 10px;\n animation: 1s linear infinite marching-ants;\n}\n.ReactCrop__crop-selection:focus {\n outline: 2px solid var(--rc-focus-color);\n outline-offset: -1px;\n}\n.ReactCrop--invisible-crop .ReactCrop__crop-mask,\n.ReactCrop--invisible-crop .ReactCrop__crop-selection {\n display: none;\n}\n.ReactCrop__rule-of-thirds-vt:before,\n.ReactCrop__rule-of-thirds-vt:after,\n.ReactCrop__rule-of-thirds-hz:before,\n.ReactCrop__rule-of-thirds-hz:after {\n content: "";\n background-color: #fff6;\n display: block;\n position: absolute;\n}\n.ReactCrop__rule-of-thirds-vt:before,\n.ReactCrop__rule-of-thirds-vt:after {\n width: 1px;\n height: 100%;\n}\n.ReactCrop__rule-of-thirds-vt:before {\n left: 33.3333%;\n}\n.ReactCrop__rule-of-thirds-vt:after {\n left: 66.6667%;\n}\n.ReactCrop__rule-of-thirds-hz:before,\n.ReactCrop__rule-of-thirds-hz:after {\n width: 100%;\n height: 1px;\n}\n.ReactCrop__rule-of-thirds-hz:before {\n top: 33.3333%;\n}\n.ReactCrop__rule-of-thirds-hz:after {\n top: 66.6667%;\n}\n.ReactCrop__drag-handle {\n width: var(--rc-drag-handle-size);\n height: var(--rc-drag-handle-size);\n background-color: var(--rc-drag-handle-bg-colour);\n border: 1px solid var(--rc-border-color);\n position: absolute;\n}\n.ReactCrop__drag-handle:focus {\n background: var(--rc-focus-color);\n}\n.ReactCrop .ord-nw {\n cursor: nw-resize;\n top: 0;\n left: 0;\n transform: translate(-50%, -50%);\n}\n.ReactCrop .ord-n {\n cursor: n-resize;\n top: 0;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n.ReactCrop .ord-ne {\n cursor: ne-resize;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n}\n.ReactCrop .ord-e {\n cursor: e-resize;\n top: 50%;\n right: 0;\n transform: translate(50%, -50%);\n}\n.ReactCrop .ord-se {\n cursor: se-resize;\n bottom: 0;\n right: 0;\n transform: translate(50%, 50%);\n}\n.ReactCrop .ord-s {\n cursor: s-resize;\n bottom: 0;\n left: 50%;\n transform: translate(-50%, 50%);\n}\n.ReactCrop .ord-sw {\n cursor: sw-resize;\n bottom: 0;\n left: 0;\n transform: translate(-50%, 50%);\n}\n.ReactCrop .ord-w {\n cursor: w-resize;\n top: 50%;\n left: 0;\n transform: translate(-50%, -50%);\n}\n.ReactCrop__disabled .ReactCrop__drag-handle {\n cursor: inherit;\n}\n.ReactCrop__drag-bar {\n position: absolute;\n}\n.ReactCrop__drag-bar.ord-n {\n width: 100%;\n height: var(--rc-drag-bar-size);\n top: 0;\n left: 0;\n transform: translateY(-50%);\n}\n.ReactCrop__drag-bar.ord-e {\n width: var(--rc-drag-bar-size);\n height: 100%;\n top: 0;\n right: 0;\n transform: translate(50%);\n}\n.ReactCrop__drag-bar.ord-s {\n width: 100%;\n height: var(--rc-drag-bar-size);\n bottom: 0;\n left: 0;\n transform: translateY(50%);\n}\n.ReactCrop__drag-bar.ord-w {\n width: var(--rc-drag-bar-size);\n height: 100%;\n top: 0;\n left: 0;\n transform: translate(-50%);\n}\n.ReactCrop--new-crop .ReactCrop__drag-bar,\n.ReactCrop--new-crop .ReactCrop__drag-handle,\n.ReactCrop--fixed-aspect .ReactCrop__drag-bar,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-n,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-e,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-s,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-w {\n display: none;\n}\n@media (pointer: coarse) {\n .ReactCrop .ord-n,\n .ReactCrop .ord-e,\n .ReactCrop .ord-s,\n .ReactCrop .ord-w {\n display: none;\n }\n .ReactCrop__drag-handle {\n width: var(--rc-drag-handle-mobile-size);\n height: var(--rc-drag-handle-mobile-size);\n }\n}\n');
|
|
2058
2125
|
|
|
2059
2126
|
// src/components/crop-dialog.tsx
|
|
@@ -2300,69 +2367,6 @@ function CropDialog(props) {
|
|
|
2300
2367
|
);
|
|
2301
2368
|
}
|
|
2302
2369
|
|
|
2303
|
-
// src/media-value.ts
|
|
2304
|
-
var STRUCTURAL_MEDIA_KEYS = /* @__PURE__ */ new Set([
|
|
2305
|
-
"assetId",
|
|
2306
|
-
"versionId",
|
|
2307
|
-
"url",
|
|
2308
|
-
"metaSchemaVersion"
|
|
2309
|
-
]);
|
|
2310
|
-
function isMediaValue(value) {
|
|
2311
|
-
return typeof value === "object" && value !== null;
|
|
2312
|
-
}
|
|
2313
|
-
function makeMediaValue(input) {
|
|
2314
|
-
if (!input.assetId || !input.versionId) {
|
|
2315
|
-
return input.url;
|
|
2316
|
-
}
|
|
2317
|
-
const value = {
|
|
2318
|
-
assetId: input.assetId,
|
|
2319
|
-
versionId: input.versionId,
|
|
2320
|
-
url: input.url
|
|
2321
|
-
};
|
|
2322
|
-
if (typeof input.metaSchemaVersion === "number") {
|
|
2323
|
-
value.metaSchemaVersion = input.metaSchemaVersion;
|
|
2324
|
-
}
|
|
2325
|
-
if (input.metadata) {
|
|
2326
|
-
for (const [k, v] of Object.entries(input.metadata)) {
|
|
2327
|
-
if (v === void 0 || v === "") continue;
|
|
2328
|
-
if (STRUCTURAL_MEDIA_KEYS.has(k)) continue;
|
|
2329
|
-
value[k] = v;
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
return value;
|
|
2333
|
-
}
|
|
2334
|
-
function buildValueFromAsset(asset, crop) {
|
|
2335
|
-
const metadata = { ...asset.metadata ?? {} };
|
|
2336
|
-
if (typeof asset.width === "number") metadata.width = asset.width;
|
|
2337
|
-
if (typeof asset.height === "number") metadata.height = asset.height;
|
|
2338
|
-
return makeMediaValue({
|
|
2339
|
-
assetId: asset.assetId,
|
|
2340
|
-
versionId: asset.versionId,
|
|
2341
|
-
url: buildValueWithCrop(getBaseUrl(asset.url), crop),
|
|
2342
|
-
metaSchemaVersion: asset.metaSchemaVersion,
|
|
2343
|
-
metadata
|
|
2344
|
-
});
|
|
2345
|
-
}
|
|
2346
|
-
function applyCropToValue(value, crop) {
|
|
2347
|
-
const currentUrl = isMediaValue(value) ? value.url : value;
|
|
2348
|
-
const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
|
|
2349
|
-
if (!baseUrl) return value;
|
|
2350
|
-
const url = buildValueWithCrop(baseUrl, crop);
|
|
2351
|
-
return isMediaValue(value) ? { ...value, url } : url;
|
|
2352
|
-
}
|
|
2353
|
-
function applyTrimToValue(value, rect) {
|
|
2354
|
-
const currentUrl = isMediaValue(value) ? value.url : value;
|
|
2355
|
-
const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
|
|
2356
|
-
if (!baseUrl) return value;
|
|
2357
|
-
const url = buildValueWithTrim(baseUrl, rect);
|
|
2358
|
-
return isMediaValue(value) ? { ...value, url } : url;
|
|
2359
|
-
}
|
|
2360
|
-
function setMetaOnValue(value, fieldName, fieldValue) {
|
|
2361
|
-
if (!isMediaValue(value)) return value;
|
|
2362
|
-
if (STRUCTURAL_MEDIA_KEYS.has(fieldName)) return value;
|
|
2363
|
-
return { ...value, [fieldName]: fieldValue };
|
|
2364
|
-
}
|
|
2365
|
-
|
|
2366
2370
|
// src/components/media-object-field.tsx
|
|
2367
2371
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2368
2372
|
function MediaObjectFieldRender(props) {
|
|
@@ -2769,6 +2773,8 @@ function MediaImage({
|
|
|
2769
2773
|
mediaBaseUrl,
|
|
2770
2774
|
transform,
|
|
2771
2775
|
alt,
|
|
2776
|
+
loading = "lazy",
|
|
2777
|
+
decoding = "async",
|
|
2772
2778
|
...rest
|
|
2773
2779
|
}) {
|
|
2774
2780
|
const props = getMediaProps(image, { mediaBaseUrl, transform });
|
|
@@ -2778,6 +2784,8 @@ function MediaImage({
|
|
|
2778
2784
|
{
|
|
2779
2785
|
src: props.src,
|
|
2780
2786
|
alt: alt ?? props.alt,
|
|
2787
|
+
loading,
|
|
2788
|
+
decoding,
|
|
2781
2789
|
...props.width !== void 0 ? { width: props.width } : {},
|
|
2782
2790
|
...props.height !== void 0 ? { height: props.height } : {},
|
|
2783
2791
|
...rest
|
|
@@ -2810,7 +2818,9 @@ function MediaFigure({
|
|
|
2810
2818
|
mediaBaseUrl,
|
|
2811
2819
|
transform,
|
|
2812
2820
|
className,
|
|
2813
|
-
captionClassName
|
|
2821
|
+
captionClassName,
|
|
2822
|
+
loading = "lazy",
|
|
2823
|
+
decoding = "async"
|
|
2814
2824
|
}) {
|
|
2815
2825
|
const props = getMediaProps(image, { mediaBaseUrl, transform });
|
|
2816
2826
|
if (!props.src) return null;
|
|
@@ -2821,6 +2831,8 @@ function MediaFigure({
|
|
|
2821
2831
|
{
|
|
2822
2832
|
src: props.src,
|
|
2823
2833
|
alt: props.alt,
|
|
2834
|
+
loading,
|
|
2835
|
+
decoding,
|
|
2824
2836
|
...props.width !== void 0 ? { width: props.width } : {},
|
|
2825
2837
|
...props.height !== void 0 ? { height: props.height } : {}
|
|
2826
2838
|
}
|
|
@@ -2852,19 +2864,29 @@ function createMediaFigureBlock(options) {
|
|
|
2852
2864
|
schema,
|
|
2853
2865
|
className,
|
|
2854
2866
|
captionClassName,
|
|
2855
|
-
placeholder = "Choose a photo from the media library"
|
|
2867
|
+
placeholder = "Choose a photo from the media library",
|
|
2868
|
+
defaultLoading = "lazy"
|
|
2856
2869
|
} = options;
|
|
2857
2870
|
return {
|
|
2858
2871
|
label,
|
|
2859
2872
|
fields: {
|
|
2860
2873
|
// `p1-media` is registered by createMediaPlugin via overrides.fieldTypes,
|
|
2861
2874
|
// so it is not part of Puck's built-in Field union.
|
|
2862
|
-
photo: { type: "p1-media", label: fieldLabel }
|
|
2875
|
+
photo: { type: "p1-media", label: fieldLabel },
|
|
2876
|
+
loading: {
|
|
2877
|
+
type: "radio",
|
|
2878
|
+
label: "Loading",
|
|
2879
|
+
options: [
|
|
2880
|
+
{ label: "Lazy", value: "lazy" },
|
|
2881
|
+
{ label: "Eager", value: "eager" }
|
|
2882
|
+
]
|
|
2883
|
+
}
|
|
2863
2884
|
},
|
|
2864
2885
|
defaultProps: {
|
|
2865
|
-
photo: null
|
|
2886
|
+
photo: null,
|
|
2887
|
+
loading: defaultLoading
|
|
2866
2888
|
},
|
|
2867
|
-
render: ({ photo }) => {
|
|
2889
|
+
render: ({ photo, loading }) => {
|
|
2868
2890
|
const { src } = getMediaProps(photo ?? null, { mediaBaseUrl });
|
|
2869
2891
|
if (!src) {
|
|
2870
2892
|
return /* @__PURE__ */ jsx14("div", { style: placeholderStyle, children: placeholder });
|
|
@@ -2877,7 +2899,8 @@ function createMediaFigureBlock(options) {
|
|
|
2877
2899
|
transform,
|
|
2878
2900
|
schema,
|
|
2879
2901
|
className,
|
|
2880
|
-
captionClassName
|
|
2902
|
+
captionClassName,
|
|
2903
|
+
loading: loading === "eager" ? "eager" : "lazy"
|
|
2881
2904
|
}
|
|
2882
2905
|
);
|
|
2883
2906
|
}
|