vue-datocms 3.0.2 → 4.0.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/index.cjs.js +95 -22
- package/dist/index.d.ts +74 -1
- package/dist/index.esm.mjs +95 -22
- package/package.json +10 -1
package/dist/index.cjs.js
CHANGED
|
@@ -27,8 +27,7 @@ const useInView = ({ threshold, rootMargin }) => {
|
|
|
27
27
|
if (isIntersectionObserverAvailable()) {
|
|
28
28
|
observer.value = new IntersectionObserver(
|
|
29
29
|
(entries) => {
|
|
30
|
-
|
|
31
|
-
if (image.isIntersecting && observer.value) {
|
|
30
|
+
if (entries.some(({ isIntersecting }) => isIntersecting) && observer.value) {
|
|
32
31
|
inView.value = true;
|
|
33
32
|
observer.value.disconnect();
|
|
34
33
|
}
|
|
@@ -191,6 +190,36 @@ const imageShowStrategy = ({ lazyLoad, loaded }) => {
|
|
|
191
190
|
}
|
|
192
191
|
return true;
|
|
193
192
|
};
|
|
193
|
+
const buildSrcSet = (src, width, candidateMultipliers) => {
|
|
194
|
+
if (!src || !width) {
|
|
195
|
+
return void 0;
|
|
196
|
+
}
|
|
197
|
+
return candidateMultipliers.map((multiplier) => {
|
|
198
|
+
const url = new URL(src);
|
|
199
|
+
if (multiplier !== 1) {
|
|
200
|
+
url.searchParams.set("dpr", `${multiplier}`);
|
|
201
|
+
const maxH = url.searchParams.get("max-h");
|
|
202
|
+
const maxW = url.searchParams.get("max-w");
|
|
203
|
+
if (maxH) {
|
|
204
|
+
url.searchParams.set(
|
|
205
|
+
"max-h",
|
|
206
|
+
`${Math.floor(parseInt(maxH) * multiplier)}`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
if (maxW) {
|
|
210
|
+
url.searchParams.set(
|
|
211
|
+
"max-w",
|
|
212
|
+
`${Math.floor(parseInt(maxW) * multiplier)}`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const finalWidth = Math.floor(width * multiplier);
|
|
217
|
+
if (finalWidth < 50) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
return `${url.toString()} ${finalWidth}w`;
|
|
221
|
+
}).filter(Boolean).join(",");
|
|
222
|
+
};
|
|
194
223
|
const Image = vueDemi.defineComponent({
|
|
195
224
|
name: "DatocmsImage",
|
|
196
225
|
props: {
|
|
@@ -240,6 +269,24 @@ const Image = vueDemi.defineComponent({
|
|
|
240
269
|
},
|
|
241
270
|
objectPosition: {
|
|
242
271
|
type: String
|
|
272
|
+
},
|
|
273
|
+
usePlaceholder: {
|
|
274
|
+
type: Boolean,
|
|
275
|
+
default: true
|
|
276
|
+
},
|
|
277
|
+
sizes: {
|
|
278
|
+
type: String
|
|
279
|
+
},
|
|
280
|
+
priority: {
|
|
281
|
+
type: Boolean,
|
|
282
|
+
default: false
|
|
283
|
+
},
|
|
284
|
+
srcSetCandidates: {
|
|
285
|
+
type: Array,
|
|
286
|
+
validator: (values) => values.every((value) => {
|
|
287
|
+
return typeof value === "number";
|
|
288
|
+
}),
|
|
289
|
+
default: () => [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
|
|
243
290
|
}
|
|
244
291
|
},
|
|
245
292
|
setup(props) {
|
|
@@ -251,21 +298,33 @@ const Image = vueDemi.defineComponent({
|
|
|
251
298
|
threshold: props.intersectionThreshold || props.intersectionTreshold || 0,
|
|
252
299
|
rootMargin: props.intersectionMargin || "0px 0px 0px 0px"
|
|
253
300
|
});
|
|
301
|
+
const computedLazyLoad = vueDemi.ref(props.priority ? false : props.lazyLoad);
|
|
302
|
+
const imageRef = vueDemi.ref();
|
|
303
|
+
vueDemi.watchEffect(() => {
|
|
304
|
+
if (!imageRef.value) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (imageRef.value.complete && imageRef.value.naturalWidth) {
|
|
308
|
+
handleLoad();
|
|
309
|
+
}
|
|
310
|
+
});
|
|
254
311
|
return {
|
|
255
312
|
inView,
|
|
256
313
|
elRef,
|
|
257
314
|
loaded,
|
|
258
|
-
handleLoad
|
|
315
|
+
handleLoad,
|
|
316
|
+
computedLazyLoad,
|
|
317
|
+
imageRef
|
|
259
318
|
};
|
|
260
319
|
},
|
|
261
320
|
render() {
|
|
262
321
|
const addImage = imageAddStrategy({
|
|
263
|
-
lazyLoad: this.
|
|
322
|
+
lazyLoad: this.computedLazyLoad,
|
|
264
323
|
inView: this.inView,
|
|
265
324
|
loaded: this.loaded
|
|
266
325
|
});
|
|
267
326
|
const showImage = imageShowStrategy({
|
|
268
|
-
lazyLoad: this.
|
|
327
|
+
lazyLoad: this.computedLazyLoad,
|
|
269
328
|
inView: this.inView,
|
|
270
329
|
loaded: this.loaded
|
|
271
330
|
});
|
|
@@ -273,30 +332,30 @@ const Image = vueDemi.defineComponent({
|
|
|
273
332
|
...vueDemi.isVue2 && {
|
|
274
333
|
props: {
|
|
275
334
|
srcset: this.data.webpSrcSet,
|
|
276
|
-
sizes: this.data.sizes,
|
|
335
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
277
336
|
type: "image/webp"
|
|
278
337
|
}
|
|
279
338
|
},
|
|
280
339
|
...vueDemi.isVue3 && {
|
|
281
340
|
srcset: this.data.webpSrcSet,
|
|
282
|
-
sizes: this.data.sizes,
|
|
341
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
283
342
|
type: "image/webp"
|
|
284
343
|
}
|
|
285
344
|
});
|
|
286
345
|
const regularSource = this.data.srcSet && vueDemi.h(Source, {
|
|
287
346
|
...vueDemi.isVue2 && {
|
|
288
347
|
props: {
|
|
289
|
-
srcset: this.data.srcSet,
|
|
290
|
-
sizes: this.data.sizes
|
|
348
|
+
srcset: this.data.srcSet ?? buildSrcSet(this.data.src, this.data.width, this.srcSetCandidates),
|
|
349
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0
|
|
291
350
|
}
|
|
292
351
|
},
|
|
293
352
|
...vueDemi.isVue3 && {
|
|
294
|
-
srcset: this.data.srcSet,
|
|
295
|
-
sizes: this.data.sizes
|
|
353
|
+
srcset: this.data.srcSet ?? buildSrcSet(this.data.src, this.data.width, this.srcSetCandidates),
|
|
354
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0
|
|
296
355
|
}
|
|
297
356
|
});
|
|
298
357
|
const transition = typeof this.fadeInDuration === "undefined" || this.fadeInDuration > 0 ? `opacity ${this.fadeInDuration || 500}ms ${this.fadeInDuration || 500}ms` : void 0;
|
|
299
|
-
const placeholder = vueDemi.h("div", {
|
|
358
|
+
const placeholder = this.usePlaceholder && (this.data.bgColor || this.data.base64) ? vueDemi.h("div", {
|
|
300
359
|
style: {
|
|
301
360
|
backgroundImage: this.data.base64 ? `url(${this.data.base64})` : null,
|
|
302
361
|
backgroundColor: this.data.bgColor,
|
|
@@ -305,11 +364,15 @@ const Image = vueDemi.defineComponent({
|
|
|
305
364
|
objectFit: this.objectFit,
|
|
306
365
|
objectPosition: this.objectPosition,
|
|
307
366
|
transition,
|
|
308
|
-
|
|
367
|
+
position: "absolute",
|
|
368
|
+
left: "-5%",
|
|
369
|
+
top: "-5%",
|
|
370
|
+
width: "110%",
|
|
371
|
+
height: "110%"
|
|
309
372
|
}
|
|
310
|
-
});
|
|
373
|
+
}) : null;
|
|
311
374
|
const { width, aspectRatio } = this.data;
|
|
312
|
-
const height = this.data.height
|
|
375
|
+
const height = this.data.height ?? (aspectRatio ? width / aspectRatio : 0);
|
|
313
376
|
const sizer = this.layout !== "fill" ? vueDemi.h(Sizer, {
|
|
314
377
|
...vueDemi.isVue2 && {
|
|
315
378
|
props: {
|
|
@@ -350,7 +413,8 @@ const Image = vueDemi.defineComponent({
|
|
|
350
413
|
attrs: {
|
|
351
414
|
src: this.data.src,
|
|
352
415
|
alt: this.data.alt,
|
|
353
|
-
title: this.data.title
|
|
416
|
+
title: this.data.title,
|
|
417
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
354
418
|
},
|
|
355
419
|
on: {
|
|
356
420
|
load: this.handleLoad
|
|
@@ -360,16 +424,18 @@ const Image = vueDemi.defineComponent({
|
|
|
360
424
|
src: this.data.src,
|
|
361
425
|
alt: this.data.alt,
|
|
362
426
|
title: this.data.title,
|
|
427
|
+
fetchpriority: this.priority ? "high" : void 0,
|
|
363
428
|
onLoad: this.handleLoad
|
|
364
429
|
},
|
|
430
|
+
ref: "imageRef",
|
|
365
431
|
class: this.pictureClass,
|
|
366
432
|
style: {
|
|
367
|
-
...absolutePositioning,
|
|
368
|
-
...this.pictureStyle,
|
|
369
433
|
opacity: showImage ? 1 : 0,
|
|
370
434
|
transition,
|
|
435
|
+
...absolutePositioning,
|
|
371
436
|
objectFit: this.objectFit,
|
|
372
|
-
objectPosition: this.objectPosition
|
|
437
|
+
objectPosition: this.objectPosition,
|
|
438
|
+
...this.pictureStyle
|
|
373
439
|
}
|
|
374
440
|
})
|
|
375
441
|
]),
|
|
@@ -391,8 +457,14 @@ const Image = vueDemi.defineComponent({
|
|
|
391
457
|
alt: this.data.alt,
|
|
392
458
|
title: this.data.title,
|
|
393
459
|
class: this.pictureClass,
|
|
394
|
-
style: toCss({
|
|
395
|
-
|
|
460
|
+
style: toCss({
|
|
461
|
+
...absolutePositioning,
|
|
462
|
+
objectFit: this.objectFit,
|
|
463
|
+
objectPosition: this.objectPosition,
|
|
464
|
+
...this.pictureStyle
|
|
465
|
+
}),
|
|
466
|
+
loading: this.computedLazyLoad ? "lazy" : void 0,
|
|
467
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
396
468
|
})
|
|
397
469
|
])
|
|
398
470
|
}
|
|
@@ -414,7 +486,8 @@ const Image = vueDemi.defineComponent({
|
|
|
414
486
|
title: this.data.title,
|
|
415
487
|
class: this.pictureClass,
|
|
416
488
|
style: toCss({ ...this.pictureStyle, ...absolutePositioning }),
|
|
417
|
-
loading: "lazy"
|
|
489
|
+
loading: this.computedLazyLoad ? "lazy" : void 0,
|
|
490
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
418
491
|
})
|
|
419
492
|
])
|
|
420
493
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { Options, ConnectionStatus } from 'datocms-listen';
|
|
|
8
8
|
|
|
9
9
|
declare type ResponsiveImageType = {
|
|
10
10
|
/** The aspect ratio (width/height) of the image */
|
|
11
|
-
aspectRatio
|
|
11
|
+
aspectRatio?: number;
|
|
12
12
|
/** A base64-encoded thumbnail to offer during image loading */
|
|
13
13
|
base64?: string;
|
|
14
14
|
/** The height of the image */
|
|
@@ -100,11 +100,47 @@ declare const Image: vue_demi.DefineComponent<{
|
|
|
100
100
|
objectPosition: {
|
|
101
101
|
type: StringConstructor;
|
|
102
102
|
};
|
|
103
|
+
/** Whether the component should use a blurred image placeholder */
|
|
104
|
+
usePlaceholder: {
|
|
105
|
+
type: BooleanConstructor;
|
|
106
|
+
default: boolean;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* The HTML5 `sizes` attribute for the image
|
|
110
|
+
*
|
|
111
|
+
* Learn more about srcset and sizes:
|
|
112
|
+
* -> https://web.dev/learn/design/responsive-images/#sizes
|
|
113
|
+
* -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
|
|
114
|
+
**/
|
|
115
|
+
sizes: {
|
|
116
|
+
type: StringConstructor;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
|
|
120
|
+
* You should use the priority property on any image detected as the Largest Contentful Paint (LCP) element. It may be appropriate to have multiple priority images, as different images may be the LCP element for different viewport sizes.
|
|
121
|
+
* Should only be used when the image is visible above the fold.
|
|
122
|
+
**/
|
|
123
|
+
priority: {
|
|
124
|
+
type: BooleanConstructor;
|
|
125
|
+
default: boolean;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
|
|
129
|
+
*
|
|
130
|
+
* Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
|
|
131
|
+
**/
|
|
132
|
+
srcSetCandidates: {
|
|
133
|
+
type: ArrayConstructor;
|
|
134
|
+
validator: (values: any[]) => values is number[];
|
|
135
|
+
default: () => number[];
|
|
136
|
+
};
|
|
103
137
|
}, {
|
|
104
138
|
inView: vue_demi.Ref<boolean>;
|
|
105
139
|
elRef: vue_demi.Ref<HTMLElement | null>;
|
|
106
140
|
loaded: vue_demi.Ref<boolean>;
|
|
107
141
|
handleLoad: () => void;
|
|
142
|
+
computedLazyLoad: vue_demi.Ref<boolean>;
|
|
143
|
+
imageRef: vue_demi.Ref<HTMLImageElement | undefined>;
|
|
108
144
|
}, unknown, {}, {}, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, {}, string, vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<vue_demi.ExtractPropTypes<{
|
|
109
145
|
/** The actual response you get from a DatoCMS `responsiveImage` GraphQL query */
|
|
110
146
|
data: {
|
|
@@ -175,6 +211,40 @@ declare const Image: vue_demi.DefineComponent<{
|
|
|
175
211
|
objectPosition: {
|
|
176
212
|
type: StringConstructor;
|
|
177
213
|
};
|
|
214
|
+
/** Whether the component should use a blurred image placeholder */
|
|
215
|
+
usePlaceholder: {
|
|
216
|
+
type: BooleanConstructor;
|
|
217
|
+
default: boolean;
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* The HTML5 `sizes` attribute for the image
|
|
221
|
+
*
|
|
222
|
+
* Learn more about srcset and sizes:
|
|
223
|
+
* -> https://web.dev/learn/design/responsive-images/#sizes
|
|
224
|
+
* -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
|
|
225
|
+
**/
|
|
226
|
+
sizes: {
|
|
227
|
+
type: StringConstructor;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
|
|
231
|
+
* You should use the priority property on any image detected as the Largest Contentful Paint (LCP) element. It may be appropriate to have multiple priority images, as different images may be the LCP element for different viewport sizes.
|
|
232
|
+
* Should only be used when the image is visible above the fold.
|
|
233
|
+
**/
|
|
234
|
+
priority: {
|
|
235
|
+
type: BooleanConstructor;
|
|
236
|
+
default: boolean;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
|
|
240
|
+
*
|
|
241
|
+
* Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
|
|
242
|
+
**/
|
|
243
|
+
srcSetCandidates: {
|
|
244
|
+
type: ArrayConstructor;
|
|
245
|
+
validator: (values: any[]) => values is number[];
|
|
246
|
+
default: () => number[];
|
|
247
|
+
};
|
|
178
248
|
}>>, {
|
|
179
249
|
explicitWidth: boolean;
|
|
180
250
|
lazyLoad: boolean;
|
|
@@ -183,6 +253,9 @@ declare const Image: vue_demi.DefineComponent<{
|
|
|
183
253
|
rootStyle: Record<string, any>;
|
|
184
254
|
pictureStyle: Record<string, any>;
|
|
185
255
|
layout: string;
|
|
256
|
+
usePlaceholder: boolean;
|
|
257
|
+
priority: boolean;
|
|
258
|
+
srcSetCandidates: unknown[];
|
|
186
259
|
}>;
|
|
187
260
|
declare const DatocmsImagePlugin: {
|
|
188
261
|
install: (Vue: any) => void;
|
package/dist/index.esm.mjs
CHANGED
|
@@ -21,8 +21,7 @@ const useInView = ({ threshold, rootMargin }) => {
|
|
|
21
21
|
if (isIntersectionObserverAvailable()) {
|
|
22
22
|
observer.value = new IntersectionObserver(
|
|
23
23
|
(entries) => {
|
|
24
|
-
|
|
25
|
-
if (image.isIntersecting && observer.value) {
|
|
24
|
+
if (entries.some(({ isIntersecting }) => isIntersecting) && observer.value) {
|
|
26
25
|
inView.value = true;
|
|
27
26
|
observer.value.disconnect();
|
|
28
27
|
}
|
|
@@ -185,6 +184,36 @@ const imageShowStrategy = ({ lazyLoad, loaded }) => {
|
|
|
185
184
|
}
|
|
186
185
|
return true;
|
|
187
186
|
};
|
|
187
|
+
const buildSrcSet = (src, width, candidateMultipliers) => {
|
|
188
|
+
if (!src || !width) {
|
|
189
|
+
return void 0;
|
|
190
|
+
}
|
|
191
|
+
return candidateMultipliers.map((multiplier) => {
|
|
192
|
+
const url = new URL(src);
|
|
193
|
+
if (multiplier !== 1) {
|
|
194
|
+
url.searchParams.set("dpr", `${multiplier}`);
|
|
195
|
+
const maxH = url.searchParams.get("max-h");
|
|
196
|
+
const maxW = url.searchParams.get("max-w");
|
|
197
|
+
if (maxH) {
|
|
198
|
+
url.searchParams.set(
|
|
199
|
+
"max-h",
|
|
200
|
+
`${Math.floor(parseInt(maxH) * multiplier)}`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (maxW) {
|
|
204
|
+
url.searchParams.set(
|
|
205
|
+
"max-w",
|
|
206
|
+
`${Math.floor(parseInt(maxW) * multiplier)}`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const finalWidth = Math.floor(width * multiplier);
|
|
211
|
+
if (finalWidth < 50) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
return `${url.toString()} ${finalWidth}w`;
|
|
215
|
+
}).filter(Boolean).join(",");
|
|
216
|
+
};
|
|
188
217
|
const Image = defineComponent({
|
|
189
218
|
name: "DatocmsImage",
|
|
190
219
|
props: {
|
|
@@ -234,6 +263,24 @@ const Image = defineComponent({
|
|
|
234
263
|
},
|
|
235
264
|
objectPosition: {
|
|
236
265
|
type: String
|
|
266
|
+
},
|
|
267
|
+
usePlaceholder: {
|
|
268
|
+
type: Boolean,
|
|
269
|
+
default: true
|
|
270
|
+
},
|
|
271
|
+
sizes: {
|
|
272
|
+
type: String
|
|
273
|
+
},
|
|
274
|
+
priority: {
|
|
275
|
+
type: Boolean,
|
|
276
|
+
default: false
|
|
277
|
+
},
|
|
278
|
+
srcSetCandidates: {
|
|
279
|
+
type: Array,
|
|
280
|
+
validator: (values) => values.every((value) => {
|
|
281
|
+
return typeof value === "number";
|
|
282
|
+
}),
|
|
283
|
+
default: () => [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
|
|
237
284
|
}
|
|
238
285
|
},
|
|
239
286
|
setup(props) {
|
|
@@ -245,21 +292,33 @@ const Image = defineComponent({
|
|
|
245
292
|
threshold: props.intersectionThreshold || props.intersectionTreshold || 0,
|
|
246
293
|
rootMargin: props.intersectionMargin || "0px 0px 0px 0px"
|
|
247
294
|
});
|
|
295
|
+
const computedLazyLoad = ref(props.priority ? false : props.lazyLoad);
|
|
296
|
+
const imageRef = ref();
|
|
297
|
+
watchEffect(() => {
|
|
298
|
+
if (!imageRef.value) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (imageRef.value.complete && imageRef.value.naturalWidth) {
|
|
302
|
+
handleLoad();
|
|
303
|
+
}
|
|
304
|
+
});
|
|
248
305
|
return {
|
|
249
306
|
inView,
|
|
250
307
|
elRef,
|
|
251
308
|
loaded,
|
|
252
|
-
handleLoad
|
|
309
|
+
handleLoad,
|
|
310
|
+
computedLazyLoad,
|
|
311
|
+
imageRef
|
|
253
312
|
};
|
|
254
313
|
},
|
|
255
314
|
render() {
|
|
256
315
|
const addImage = imageAddStrategy({
|
|
257
|
-
lazyLoad: this.
|
|
316
|
+
lazyLoad: this.computedLazyLoad,
|
|
258
317
|
inView: this.inView,
|
|
259
318
|
loaded: this.loaded
|
|
260
319
|
});
|
|
261
320
|
const showImage = imageShowStrategy({
|
|
262
|
-
lazyLoad: this.
|
|
321
|
+
lazyLoad: this.computedLazyLoad,
|
|
263
322
|
inView: this.inView,
|
|
264
323
|
loaded: this.loaded
|
|
265
324
|
});
|
|
@@ -267,30 +326,30 @@ const Image = defineComponent({
|
|
|
267
326
|
...isVue2 && {
|
|
268
327
|
props: {
|
|
269
328
|
srcset: this.data.webpSrcSet,
|
|
270
|
-
sizes: this.data.sizes,
|
|
329
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
271
330
|
type: "image/webp"
|
|
272
331
|
}
|
|
273
332
|
},
|
|
274
333
|
...isVue3 && {
|
|
275
334
|
srcset: this.data.webpSrcSet,
|
|
276
|
-
sizes: this.data.sizes,
|
|
335
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
277
336
|
type: "image/webp"
|
|
278
337
|
}
|
|
279
338
|
});
|
|
280
339
|
const regularSource = this.data.srcSet && h(Source, {
|
|
281
340
|
...isVue2 && {
|
|
282
341
|
props: {
|
|
283
|
-
srcset: this.data.srcSet,
|
|
284
|
-
sizes: this.data.sizes
|
|
342
|
+
srcset: this.data.srcSet ?? buildSrcSet(this.data.src, this.data.width, this.srcSetCandidates),
|
|
343
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0
|
|
285
344
|
}
|
|
286
345
|
},
|
|
287
346
|
...isVue3 && {
|
|
288
|
-
srcset: this.data.srcSet,
|
|
289
|
-
sizes: this.data.sizes
|
|
347
|
+
srcset: this.data.srcSet ?? buildSrcSet(this.data.src, this.data.width, this.srcSetCandidates),
|
|
348
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0
|
|
290
349
|
}
|
|
291
350
|
});
|
|
292
351
|
const transition = typeof this.fadeInDuration === "undefined" || this.fadeInDuration > 0 ? `opacity ${this.fadeInDuration || 500}ms ${this.fadeInDuration || 500}ms` : void 0;
|
|
293
|
-
const placeholder = h("div", {
|
|
352
|
+
const placeholder = this.usePlaceholder && (this.data.bgColor || this.data.base64) ? h("div", {
|
|
294
353
|
style: {
|
|
295
354
|
backgroundImage: this.data.base64 ? `url(${this.data.base64})` : null,
|
|
296
355
|
backgroundColor: this.data.bgColor,
|
|
@@ -299,11 +358,15 @@ const Image = defineComponent({
|
|
|
299
358
|
objectFit: this.objectFit,
|
|
300
359
|
objectPosition: this.objectPosition,
|
|
301
360
|
transition,
|
|
302
|
-
|
|
361
|
+
position: "absolute",
|
|
362
|
+
left: "-5%",
|
|
363
|
+
top: "-5%",
|
|
364
|
+
width: "110%",
|
|
365
|
+
height: "110%"
|
|
303
366
|
}
|
|
304
|
-
});
|
|
367
|
+
}) : null;
|
|
305
368
|
const { width, aspectRatio } = this.data;
|
|
306
|
-
const height = this.data.height
|
|
369
|
+
const height = this.data.height ?? (aspectRatio ? width / aspectRatio : 0);
|
|
307
370
|
const sizer = this.layout !== "fill" ? h(Sizer, {
|
|
308
371
|
...isVue2 && {
|
|
309
372
|
props: {
|
|
@@ -344,7 +407,8 @@ const Image = defineComponent({
|
|
|
344
407
|
attrs: {
|
|
345
408
|
src: this.data.src,
|
|
346
409
|
alt: this.data.alt,
|
|
347
|
-
title: this.data.title
|
|
410
|
+
title: this.data.title,
|
|
411
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
348
412
|
},
|
|
349
413
|
on: {
|
|
350
414
|
load: this.handleLoad
|
|
@@ -354,16 +418,18 @@ const Image = defineComponent({
|
|
|
354
418
|
src: this.data.src,
|
|
355
419
|
alt: this.data.alt,
|
|
356
420
|
title: this.data.title,
|
|
421
|
+
fetchpriority: this.priority ? "high" : void 0,
|
|
357
422
|
onLoad: this.handleLoad
|
|
358
423
|
},
|
|
424
|
+
ref: "imageRef",
|
|
359
425
|
class: this.pictureClass,
|
|
360
426
|
style: {
|
|
361
|
-
...absolutePositioning,
|
|
362
|
-
...this.pictureStyle,
|
|
363
427
|
opacity: showImage ? 1 : 0,
|
|
364
428
|
transition,
|
|
429
|
+
...absolutePositioning,
|
|
365
430
|
objectFit: this.objectFit,
|
|
366
|
-
objectPosition: this.objectPosition
|
|
431
|
+
objectPosition: this.objectPosition,
|
|
432
|
+
...this.pictureStyle
|
|
367
433
|
}
|
|
368
434
|
})
|
|
369
435
|
]),
|
|
@@ -385,8 +451,14 @@ const Image = defineComponent({
|
|
|
385
451
|
alt: this.data.alt,
|
|
386
452
|
title: this.data.title,
|
|
387
453
|
class: this.pictureClass,
|
|
388
|
-
style: toCss({
|
|
389
|
-
|
|
454
|
+
style: toCss({
|
|
455
|
+
...absolutePositioning,
|
|
456
|
+
objectFit: this.objectFit,
|
|
457
|
+
objectPosition: this.objectPosition,
|
|
458
|
+
...this.pictureStyle
|
|
459
|
+
}),
|
|
460
|
+
loading: this.computedLazyLoad ? "lazy" : void 0,
|
|
461
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
390
462
|
})
|
|
391
463
|
])
|
|
392
464
|
}
|
|
@@ -408,7 +480,8 @@ const Image = defineComponent({
|
|
|
408
480
|
title: this.data.title,
|
|
409
481
|
class: this.pictureClass,
|
|
410
482
|
style: toCss({ ...this.pictureStyle, ...absolutePositioning }),
|
|
411
|
-
loading: "lazy"
|
|
483
|
+
loading: this.computedLazyLoad ? "lazy" : void 0,
|
|
484
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
412
485
|
})
|
|
413
486
|
])
|
|
414
487
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-datocms",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "A set of components and utilities to work faster with DatoCMS in Vue.js environments",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"datocms",
|
|
@@ -11,7 +11,16 @@
|
|
|
11
11
|
"main": "./dist/index.cjs.js",
|
|
12
12
|
"module": "./dist/index.esm.mjs",
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git://github.com/datocms/vue-datocms.git"
|
|
17
|
+
},
|
|
14
18
|
"license": "MIT",
|
|
19
|
+
"author": "Stefano Verna <s.verna@datocms.com>",
|
|
20
|
+
"contributors": [
|
|
21
|
+
"Silvano Stralla <silvano@datocms.com>"
|
|
22
|
+
],
|
|
23
|
+
"homepage": "https://github.com/datocms/vue-datocms",
|
|
15
24
|
"exports": {
|
|
16
25
|
".": {
|
|
17
26
|
"import": "./dist/index.esm.mjs",
|