@pantheon-systems/p1-media 0.4.3 → 0.4.5
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/index.d.mts +24 -17
- package/dist/index.d.ts +24 -17
- package/dist/index.js +25 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -6
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +21 -14
- package/dist/server.d.ts +21 -14
- 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 +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ImgHTMLAttributes, ReactElement, ReactNode } from 'react';
|
|
3
3
|
import { ComponentConfig } from '@puckeditor/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -58,7 +58,7 @@ interface MediaConfig {
|
|
|
58
58
|
type GetAuthToken = () => Promise<string | null> | string | null;
|
|
59
59
|
|
|
60
60
|
interface MediaPluginOptions {
|
|
61
|
-
/** The base URL of the
|
|
61
|
+
/** The base URL of the media API. Defaults to the production host. */
|
|
62
62
|
workerUrl?: string;
|
|
63
63
|
/**
|
|
64
64
|
* Site identifier used to scope media to a specific site. Defaults to the
|
|
@@ -68,7 +68,7 @@ interface MediaPluginOptions {
|
|
|
68
68
|
siteId?: string;
|
|
69
69
|
/**
|
|
70
70
|
* Workstream (branch) identifier. Currently accepted for forward-compat but not
|
|
71
|
-
* read by the
|
|
71
|
+
* read by the backend for any scoping decision — omit unless a future release
|
|
72
72
|
* documents otherwise.
|
|
73
73
|
*/
|
|
74
74
|
workstreamId?: string;
|
|
@@ -89,7 +89,7 @@ interface MediaPluginOptions {
|
|
|
89
89
|
metadataFields?: MetadataFieldDef[];
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
|
-
* Creates a Puck plugin that adds a media library backed by Cloudflare R2
|
|
92
|
+
* Creates a Puck plugin that adds a media library backed by Cloudflare R2.
|
|
93
93
|
* It supports two field modes:
|
|
94
94
|
* - Basic: text fields matching image/media name patterns are replaced with the
|
|
95
95
|
* picker and store a clean CDN URL string. Render with `buildImageUrl()`.
|
|
@@ -145,7 +145,7 @@ interface ImageTransformParams {
|
|
|
145
145
|
quality?: number;
|
|
146
146
|
}
|
|
147
147
|
/**
|
|
148
|
-
* Merges
|
|
148
|
+
* Merges image transform params onto a CDN image URL.
|
|
149
149
|
* Preserves any existing params in the URL — e.g. the editor's crop intent
|
|
150
150
|
* (`fit=cover&gravity=auto` for smart crop, `trim.*` for a manual crop).
|
|
151
151
|
*
|
|
@@ -158,20 +158,17 @@ interface GetMediaPropsOptions {
|
|
|
158
158
|
/**
|
|
159
159
|
* The CDN image origin that serves media, e.g.
|
|
160
160
|
* "https://staging.media.p1.pantheon.io". This is the public image host —
|
|
161
|
-
* NOT the
|
|
162
|
-
* real image URL.
|
|
161
|
+
* NOT the content API URL, whose origin would reject every real image URL.
|
|
163
162
|
*
|
|
164
|
-
* Security (required): a value's `url` is untrusted document content —
|
|
165
|
-
* who can edit a document
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* server-fetching `next/image`). getMediaProps therefore rejects any url that
|
|
169
|
-
* is not `https` on this exact origin. If `mediaBaseUrl` is omitted it
|
|
163
|
+
* Security (required): a value's `url` is untrusted document content —
|
|
164
|
+
* anyone who can edit a document controls it. getMediaProps rejects any url
|
|
165
|
+
* that is not `https` on this exact origin, so an edited document can't
|
|
166
|
+
* point a render at an arbitrary origin. If `mediaBaseUrl` is omitted it
|
|
170
167
|
* **fails closed** (empty src) rather than degrading to an insecure pass-through.
|
|
171
168
|
*
|
|
172
169
|
* Local dev exception: when the configured base is itself `http` on a
|
|
173
|
-
* loopback host (`localhost`, `127.0.0.1`, `[::1]`
|
|
174
|
-
*
|
|
170
|
+
* loopback host (`localhost`, `127.0.0.1`, `[::1]`), same-origin `http`
|
|
171
|
+
* urls are allowed so rich values render locally.
|
|
175
172
|
*/
|
|
176
173
|
mediaBaseUrl?: string;
|
|
177
174
|
/** Transform params merged onto the validated URL (width, height, format, quality). */
|
|
@@ -188,7 +185,7 @@ declare function getMediaProps(value: MediaFieldValue | null | undefined, option
|
|
|
188
185
|
* (a broken foreign-origin image is never emitted). `alt` may be overridden;
|
|
189
186
|
* otherwise it comes from the value.
|
|
190
187
|
*/
|
|
191
|
-
declare function MediaImage({ image, mediaBaseUrl, transform, alt, ...rest }: {
|
|
188
|
+
declare function MediaImage({ image, mediaBaseUrl, transform, alt, loading, decoding, ...rest }: {
|
|
192
189
|
image: MediaFieldValue | null | undefined;
|
|
193
190
|
mediaBaseUrl?: string;
|
|
194
191
|
transform?: ImageTransformParams;
|
|
@@ -198,17 +195,21 @@ declare function MediaImage({ image, mediaBaseUrl, transform, alt, ...rest }: {
|
|
|
198
195
|
* ESCAPED text (React default escaping — never dangerouslySetInnerHTML, req.
|
|
199
196
|
* R6). Renders nothing when the src is rejected/empty.
|
|
200
197
|
*/
|
|
201
|
-
declare function MediaFigure({ image, schema, mediaBaseUrl, transform, className, captionClassName, }: {
|
|
198
|
+
declare function MediaFigure({ image, schema, mediaBaseUrl, transform, className, captionClassName, loading, decoding, }: {
|
|
202
199
|
image: MediaFieldValue | null | undefined;
|
|
203
200
|
schema?: MetadataFieldDef[];
|
|
204
201
|
mediaBaseUrl?: string;
|
|
205
202
|
transform?: ImageTransformParams;
|
|
206
203
|
className?: string;
|
|
207
204
|
captionClassName?: string;
|
|
205
|
+
/** Defaults to "lazy"; pass "eager" for an above-the-fold figure. */
|
|
206
|
+
loading?: ImgHTMLAttributes<HTMLImageElement>["loading"];
|
|
207
|
+
decoding?: ImgHTMLAttributes<HTMLImageElement>["decoding"];
|
|
208
208
|
}): ReactElement | null;
|
|
209
209
|
|
|
210
210
|
interface MediaFigureBlockProps {
|
|
211
211
|
photo: MediaFieldValue | null;
|
|
212
|
+
loading?: "lazy" | "eager";
|
|
212
213
|
}
|
|
213
214
|
interface MediaFigureBlockOptions {
|
|
214
215
|
/**
|
|
@@ -233,6 +234,12 @@ interface MediaFigureBlockOptions {
|
|
|
233
234
|
captionClassName?: string;
|
|
234
235
|
/** Rendered when no photo is chosen (or its URL fails origin validation). */
|
|
235
236
|
placeholder?: ReactNode;
|
|
237
|
+
/**
|
|
238
|
+
* Default for the block's "Loading" field. "lazy" (the default) keeps
|
|
239
|
+
* off-screen images off the wire on image-heavy pages; use "eager" when the
|
|
240
|
+
* block is reliably above the fold.
|
|
241
|
+
*/
|
|
242
|
+
defaultLoading?: "lazy" | "eager";
|
|
236
243
|
}
|
|
237
244
|
/**
|
|
238
245
|
* Builds a registerable Puck component around the rich `p1-media` field and
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ImgHTMLAttributes, ReactElement, ReactNode } from 'react';
|
|
3
3
|
import { ComponentConfig } from '@puckeditor/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -58,7 +58,7 @@ interface MediaConfig {
|
|
|
58
58
|
type GetAuthToken = () => Promise<string | null> | string | null;
|
|
59
59
|
|
|
60
60
|
interface MediaPluginOptions {
|
|
61
|
-
/** The base URL of the
|
|
61
|
+
/** The base URL of the media API. Defaults to the production host. */
|
|
62
62
|
workerUrl?: string;
|
|
63
63
|
/**
|
|
64
64
|
* Site identifier used to scope media to a specific site. Defaults to the
|
|
@@ -68,7 +68,7 @@ interface MediaPluginOptions {
|
|
|
68
68
|
siteId?: string;
|
|
69
69
|
/**
|
|
70
70
|
* Workstream (branch) identifier. Currently accepted for forward-compat but not
|
|
71
|
-
* read by the
|
|
71
|
+
* read by the backend for any scoping decision — omit unless a future release
|
|
72
72
|
* documents otherwise.
|
|
73
73
|
*/
|
|
74
74
|
workstreamId?: string;
|
|
@@ -89,7 +89,7 @@ interface MediaPluginOptions {
|
|
|
89
89
|
metadataFields?: MetadataFieldDef[];
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
|
-
* Creates a Puck plugin that adds a media library backed by Cloudflare R2
|
|
92
|
+
* Creates a Puck plugin that adds a media library backed by Cloudflare R2.
|
|
93
93
|
* It supports two field modes:
|
|
94
94
|
* - Basic: text fields matching image/media name patterns are replaced with the
|
|
95
95
|
* picker and store a clean CDN URL string. Render with `buildImageUrl()`.
|
|
@@ -145,7 +145,7 @@ interface ImageTransformParams {
|
|
|
145
145
|
quality?: number;
|
|
146
146
|
}
|
|
147
147
|
/**
|
|
148
|
-
* Merges
|
|
148
|
+
* Merges image transform params onto a CDN image URL.
|
|
149
149
|
* Preserves any existing params in the URL — e.g. the editor's crop intent
|
|
150
150
|
* (`fit=cover&gravity=auto` for smart crop, `trim.*` for a manual crop).
|
|
151
151
|
*
|
|
@@ -158,20 +158,17 @@ interface GetMediaPropsOptions {
|
|
|
158
158
|
/**
|
|
159
159
|
* The CDN image origin that serves media, e.g.
|
|
160
160
|
* "https://staging.media.p1.pantheon.io". This is the public image host —
|
|
161
|
-
* NOT the
|
|
162
|
-
* real image URL.
|
|
161
|
+
* NOT the content API URL, whose origin would reject every real image URL.
|
|
163
162
|
*
|
|
164
|
-
* Security (required): a value's `url` is untrusted document content —
|
|
165
|
-
* who can edit a document
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* server-fetching `next/image`). getMediaProps therefore rejects any url that
|
|
169
|
-
* is not `https` on this exact origin. If `mediaBaseUrl` is omitted it
|
|
163
|
+
* Security (required): a value's `url` is untrusted document content —
|
|
164
|
+
* anyone who can edit a document controls it. getMediaProps rejects any url
|
|
165
|
+
* that is not `https` on this exact origin, so an edited document can't
|
|
166
|
+
* point a render at an arbitrary origin. If `mediaBaseUrl` is omitted it
|
|
170
167
|
* **fails closed** (empty src) rather than degrading to an insecure pass-through.
|
|
171
168
|
*
|
|
172
169
|
* Local dev exception: when the configured base is itself `http` on a
|
|
173
|
-
* loopback host (`localhost`, `127.0.0.1`, `[::1]`
|
|
174
|
-
*
|
|
170
|
+
* loopback host (`localhost`, `127.0.0.1`, `[::1]`), same-origin `http`
|
|
171
|
+
* urls are allowed so rich values render locally.
|
|
175
172
|
*/
|
|
176
173
|
mediaBaseUrl?: string;
|
|
177
174
|
/** Transform params merged onto the validated URL (width, height, format, quality). */
|
|
@@ -188,7 +185,7 @@ declare function getMediaProps(value: MediaFieldValue | null | undefined, option
|
|
|
188
185
|
* (a broken foreign-origin image is never emitted). `alt` may be overridden;
|
|
189
186
|
* otherwise it comes from the value.
|
|
190
187
|
*/
|
|
191
|
-
declare function MediaImage({ image, mediaBaseUrl, transform, alt, ...rest }: {
|
|
188
|
+
declare function MediaImage({ image, mediaBaseUrl, transform, alt, loading, decoding, ...rest }: {
|
|
192
189
|
image: MediaFieldValue | null | undefined;
|
|
193
190
|
mediaBaseUrl?: string;
|
|
194
191
|
transform?: ImageTransformParams;
|
|
@@ -198,17 +195,21 @@ declare function MediaImage({ image, mediaBaseUrl, transform, alt, ...rest }: {
|
|
|
198
195
|
* ESCAPED text (React default escaping — never dangerouslySetInnerHTML, req.
|
|
199
196
|
* R6). Renders nothing when the src is rejected/empty.
|
|
200
197
|
*/
|
|
201
|
-
declare function MediaFigure({ image, schema, mediaBaseUrl, transform, className, captionClassName, }: {
|
|
198
|
+
declare function MediaFigure({ image, schema, mediaBaseUrl, transform, className, captionClassName, loading, decoding, }: {
|
|
202
199
|
image: MediaFieldValue | null | undefined;
|
|
203
200
|
schema?: MetadataFieldDef[];
|
|
204
201
|
mediaBaseUrl?: string;
|
|
205
202
|
transform?: ImageTransformParams;
|
|
206
203
|
className?: string;
|
|
207
204
|
captionClassName?: string;
|
|
205
|
+
/** Defaults to "lazy"; pass "eager" for an above-the-fold figure. */
|
|
206
|
+
loading?: ImgHTMLAttributes<HTMLImageElement>["loading"];
|
|
207
|
+
decoding?: ImgHTMLAttributes<HTMLImageElement>["decoding"];
|
|
208
208
|
}): ReactElement | null;
|
|
209
209
|
|
|
210
210
|
interface MediaFigureBlockProps {
|
|
211
211
|
photo: MediaFieldValue | null;
|
|
212
|
+
loading?: "lazy" | "eager";
|
|
212
213
|
}
|
|
213
214
|
interface MediaFigureBlockOptions {
|
|
214
215
|
/**
|
|
@@ -233,6 +234,12 @@ interface MediaFigureBlockOptions {
|
|
|
233
234
|
captionClassName?: string;
|
|
234
235
|
/** Rendered when no photo is chosen (or its URL fails origin validation). */
|
|
235
236
|
placeholder?: ReactNode;
|
|
237
|
+
/**
|
|
238
|
+
* Default for the block's "Loading" field. "lazy" (the default) keeps
|
|
239
|
+
* off-screen images off the wire on image-heavy pages; use "eager" when the
|
|
240
|
+
* block is reliably above the fold.
|
|
241
|
+
*/
|
|
242
|
+
defaultLoading?: "lazy" | "eager";
|
|
236
243
|
}
|
|
237
244
|
/**
|
|
238
245
|
* Builds a registerable Puck component around the rich `p1-media` field and
|
package/dist/index.js
CHANGED
|
@@ -2815,6 +2815,8 @@ function MediaImage({
|
|
|
2815
2815
|
mediaBaseUrl,
|
|
2816
2816
|
transform,
|
|
2817
2817
|
alt,
|
|
2818
|
+
loading = "lazy",
|
|
2819
|
+
decoding = "async",
|
|
2818
2820
|
...rest
|
|
2819
2821
|
}) {
|
|
2820
2822
|
const props = getMediaProps(image, { mediaBaseUrl, transform });
|
|
@@ -2824,6 +2826,8 @@ function MediaImage({
|
|
|
2824
2826
|
{
|
|
2825
2827
|
src: props.src,
|
|
2826
2828
|
alt: alt ?? props.alt,
|
|
2829
|
+
loading,
|
|
2830
|
+
decoding,
|
|
2827
2831
|
...props.width !== void 0 ? { width: props.width } : {},
|
|
2828
2832
|
...props.height !== void 0 ? { height: props.height } : {},
|
|
2829
2833
|
...rest
|
|
@@ -2856,7 +2860,9 @@ function MediaFigure({
|
|
|
2856
2860
|
mediaBaseUrl,
|
|
2857
2861
|
transform,
|
|
2858
2862
|
className,
|
|
2859
|
-
captionClassName
|
|
2863
|
+
captionClassName,
|
|
2864
|
+
loading = "lazy",
|
|
2865
|
+
decoding = "async"
|
|
2860
2866
|
}) {
|
|
2861
2867
|
const props = getMediaProps(image, { mediaBaseUrl, transform });
|
|
2862
2868
|
if (!props.src) return null;
|
|
@@ -2867,6 +2873,8 @@ function MediaFigure({
|
|
|
2867
2873
|
{
|
|
2868
2874
|
src: props.src,
|
|
2869
2875
|
alt: props.alt,
|
|
2876
|
+
loading,
|
|
2877
|
+
decoding,
|
|
2870
2878
|
...props.width !== void 0 ? { width: props.width } : {},
|
|
2871
2879
|
...props.height !== void 0 ? { height: props.height } : {}
|
|
2872
2880
|
}
|
|
@@ -2898,19 +2906,29 @@ function createMediaFigureBlock(options) {
|
|
|
2898
2906
|
schema,
|
|
2899
2907
|
className,
|
|
2900
2908
|
captionClassName,
|
|
2901
|
-
placeholder = "Choose a photo from the media library"
|
|
2909
|
+
placeholder = "Choose a photo from the media library",
|
|
2910
|
+
defaultLoading = "lazy"
|
|
2902
2911
|
} = options;
|
|
2903
2912
|
return {
|
|
2904
2913
|
label,
|
|
2905
2914
|
fields: {
|
|
2906
2915
|
// `p1-media` is registered by createMediaPlugin via overrides.fieldTypes,
|
|
2907
2916
|
// so it is not part of Puck's built-in Field union.
|
|
2908
|
-
photo: { type: "p1-media", label: fieldLabel }
|
|
2917
|
+
photo: { type: "p1-media", label: fieldLabel },
|
|
2918
|
+
loading: {
|
|
2919
|
+
type: "radio",
|
|
2920
|
+
label: "Loading",
|
|
2921
|
+
options: [
|
|
2922
|
+
{ label: "Lazy", value: "lazy" },
|
|
2923
|
+
{ label: "Eager", value: "eager" }
|
|
2924
|
+
]
|
|
2925
|
+
}
|
|
2909
2926
|
},
|
|
2910
2927
|
defaultProps: {
|
|
2911
|
-
photo: null
|
|
2928
|
+
photo: null,
|
|
2929
|
+
loading: defaultLoading
|
|
2912
2930
|
},
|
|
2913
|
-
render: ({ photo }) => {
|
|
2931
|
+
render: ({ photo, loading }) => {
|
|
2914
2932
|
const { src } = getMediaProps(photo ?? null, { mediaBaseUrl });
|
|
2915
2933
|
if (!src) {
|
|
2916
2934
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: placeholderStyle, children: placeholder });
|
|
@@ -2923,7 +2941,8 @@ function createMediaFigureBlock(options) {
|
|
|
2923
2941
|
transform,
|
|
2924
2942
|
schema,
|
|
2925
2943
|
className,
|
|
2926
|
-
captionClassName
|
|
2944
|
+
captionClassName,
|
|
2945
|
+
loading: loading === "eager" ? "eager" : "lazy"
|
|
2927
2946
|
}
|
|
2928
2947
|
);
|
|
2929
2948
|
}
|