vue-datocms 3.0.3 → 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 +94 -20
- package/dist/index.d.ts +74 -1
- package/dist/index.esm.mjs +94 -20
- package/package.json +10 -1
package/dist/index.cjs.js
CHANGED
|
@@ -190,6 +190,36 @@ const imageShowStrategy = ({ lazyLoad, loaded }) => {
|
|
|
190
190
|
}
|
|
191
191
|
return true;
|
|
192
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
|
+
};
|
|
193
223
|
const Image = vueDemi.defineComponent({
|
|
194
224
|
name: "DatocmsImage",
|
|
195
225
|
props: {
|
|
@@ -239,6 +269,24 @@ const Image = vueDemi.defineComponent({
|
|
|
239
269
|
},
|
|
240
270
|
objectPosition: {
|
|
241
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]
|
|
242
290
|
}
|
|
243
291
|
},
|
|
244
292
|
setup(props) {
|
|
@@ -250,21 +298,33 @@ const Image = vueDemi.defineComponent({
|
|
|
250
298
|
threshold: props.intersectionThreshold || props.intersectionTreshold || 0,
|
|
251
299
|
rootMargin: props.intersectionMargin || "0px 0px 0px 0px"
|
|
252
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
|
+
});
|
|
253
311
|
return {
|
|
254
312
|
inView,
|
|
255
313
|
elRef,
|
|
256
314
|
loaded,
|
|
257
|
-
handleLoad
|
|
315
|
+
handleLoad,
|
|
316
|
+
computedLazyLoad,
|
|
317
|
+
imageRef
|
|
258
318
|
};
|
|
259
319
|
},
|
|
260
320
|
render() {
|
|
261
321
|
const addImage = imageAddStrategy({
|
|
262
|
-
lazyLoad: this.
|
|
322
|
+
lazyLoad: this.computedLazyLoad,
|
|
263
323
|
inView: this.inView,
|
|
264
324
|
loaded: this.loaded
|
|
265
325
|
});
|
|
266
326
|
const showImage = imageShowStrategy({
|
|
267
|
-
lazyLoad: this.
|
|
327
|
+
lazyLoad: this.computedLazyLoad,
|
|
268
328
|
inView: this.inView,
|
|
269
329
|
loaded: this.loaded
|
|
270
330
|
});
|
|
@@ -272,30 +332,30 @@ const Image = vueDemi.defineComponent({
|
|
|
272
332
|
...vueDemi.isVue2 && {
|
|
273
333
|
props: {
|
|
274
334
|
srcset: this.data.webpSrcSet,
|
|
275
|
-
sizes: this.data.sizes,
|
|
335
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
276
336
|
type: "image/webp"
|
|
277
337
|
}
|
|
278
338
|
},
|
|
279
339
|
...vueDemi.isVue3 && {
|
|
280
340
|
srcset: this.data.webpSrcSet,
|
|
281
|
-
sizes: this.data.sizes,
|
|
341
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
282
342
|
type: "image/webp"
|
|
283
343
|
}
|
|
284
344
|
});
|
|
285
345
|
const regularSource = this.data.srcSet && vueDemi.h(Source, {
|
|
286
346
|
...vueDemi.isVue2 && {
|
|
287
347
|
props: {
|
|
288
|
-
srcset: this.data.srcSet,
|
|
289
|
-
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
|
|
290
350
|
}
|
|
291
351
|
},
|
|
292
352
|
...vueDemi.isVue3 && {
|
|
293
|
-
srcset: this.data.srcSet,
|
|
294
|
-
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
|
|
295
355
|
}
|
|
296
356
|
});
|
|
297
357
|
const transition = typeof this.fadeInDuration === "undefined" || this.fadeInDuration > 0 ? `opacity ${this.fadeInDuration || 500}ms ${this.fadeInDuration || 500}ms` : void 0;
|
|
298
|
-
const placeholder = vueDemi.h("div", {
|
|
358
|
+
const placeholder = this.usePlaceholder && (this.data.bgColor || this.data.base64) ? vueDemi.h("div", {
|
|
299
359
|
style: {
|
|
300
360
|
backgroundImage: this.data.base64 ? `url(${this.data.base64})` : null,
|
|
301
361
|
backgroundColor: this.data.bgColor,
|
|
@@ -304,11 +364,15 @@ const Image = vueDemi.defineComponent({
|
|
|
304
364
|
objectFit: this.objectFit,
|
|
305
365
|
objectPosition: this.objectPosition,
|
|
306
366
|
transition,
|
|
307
|
-
|
|
367
|
+
position: "absolute",
|
|
368
|
+
left: "-5%",
|
|
369
|
+
top: "-5%",
|
|
370
|
+
width: "110%",
|
|
371
|
+
height: "110%"
|
|
308
372
|
}
|
|
309
|
-
});
|
|
373
|
+
}) : null;
|
|
310
374
|
const { width, aspectRatio } = this.data;
|
|
311
|
-
const height = this.data.height
|
|
375
|
+
const height = this.data.height ?? (aspectRatio ? width / aspectRatio : 0);
|
|
312
376
|
const sizer = this.layout !== "fill" ? vueDemi.h(Sizer, {
|
|
313
377
|
...vueDemi.isVue2 && {
|
|
314
378
|
props: {
|
|
@@ -349,7 +413,8 @@ const Image = vueDemi.defineComponent({
|
|
|
349
413
|
attrs: {
|
|
350
414
|
src: this.data.src,
|
|
351
415
|
alt: this.data.alt,
|
|
352
|
-
title: this.data.title
|
|
416
|
+
title: this.data.title,
|
|
417
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
353
418
|
},
|
|
354
419
|
on: {
|
|
355
420
|
load: this.handleLoad
|
|
@@ -359,16 +424,18 @@ const Image = vueDemi.defineComponent({
|
|
|
359
424
|
src: this.data.src,
|
|
360
425
|
alt: this.data.alt,
|
|
361
426
|
title: this.data.title,
|
|
427
|
+
fetchpriority: this.priority ? "high" : void 0,
|
|
362
428
|
onLoad: this.handleLoad
|
|
363
429
|
},
|
|
430
|
+
ref: "imageRef",
|
|
364
431
|
class: this.pictureClass,
|
|
365
432
|
style: {
|
|
366
|
-
...absolutePositioning,
|
|
367
|
-
...this.pictureStyle,
|
|
368
433
|
opacity: showImage ? 1 : 0,
|
|
369
434
|
transition,
|
|
435
|
+
...absolutePositioning,
|
|
370
436
|
objectFit: this.objectFit,
|
|
371
|
-
objectPosition: this.objectPosition
|
|
437
|
+
objectPosition: this.objectPosition,
|
|
438
|
+
...this.pictureStyle
|
|
372
439
|
}
|
|
373
440
|
})
|
|
374
441
|
]),
|
|
@@ -390,8 +457,14 @@ const Image = vueDemi.defineComponent({
|
|
|
390
457
|
alt: this.data.alt,
|
|
391
458
|
title: this.data.title,
|
|
392
459
|
class: this.pictureClass,
|
|
393
|
-
style: toCss({
|
|
394
|
-
|
|
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
|
|
395
468
|
})
|
|
396
469
|
])
|
|
397
470
|
}
|
|
@@ -413,7 +486,8 @@ const Image = vueDemi.defineComponent({
|
|
|
413
486
|
title: this.data.title,
|
|
414
487
|
class: this.pictureClass,
|
|
415
488
|
style: toCss({ ...this.pictureStyle, ...absolutePositioning }),
|
|
416
|
-
loading: "lazy"
|
|
489
|
+
loading: this.computedLazyLoad ? "lazy" : void 0,
|
|
490
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
417
491
|
})
|
|
418
492
|
])
|
|
419
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
|
@@ -184,6 +184,36 @@ const imageShowStrategy = ({ lazyLoad, loaded }) => {
|
|
|
184
184
|
}
|
|
185
185
|
return true;
|
|
186
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
|
+
};
|
|
187
217
|
const Image = defineComponent({
|
|
188
218
|
name: "DatocmsImage",
|
|
189
219
|
props: {
|
|
@@ -233,6 +263,24 @@ const Image = defineComponent({
|
|
|
233
263
|
},
|
|
234
264
|
objectPosition: {
|
|
235
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]
|
|
236
284
|
}
|
|
237
285
|
},
|
|
238
286
|
setup(props) {
|
|
@@ -244,21 +292,33 @@ const Image = defineComponent({
|
|
|
244
292
|
threshold: props.intersectionThreshold || props.intersectionTreshold || 0,
|
|
245
293
|
rootMargin: props.intersectionMargin || "0px 0px 0px 0px"
|
|
246
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
|
+
});
|
|
247
305
|
return {
|
|
248
306
|
inView,
|
|
249
307
|
elRef,
|
|
250
308
|
loaded,
|
|
251
|
-
handleLoad
|
|
309
|
+
handleLoad,
|
|
310
|
+
computedLazyLoad,
|
|
311
|
+
imageRef
|
|
252
312
|
};
|
|
253
313
|
},
|
|
254
314
|
render() {
|
|
255
315
|
const addImage = imageAddStrategy({
|
|
256
|
-
lazyLoad: this.
|
|
316
|
+
lazyLoad: this.computedLazyLoad,
|
|
257
317
|
inView: this.inView,
|
|
258
318
|
loaded: this.loaded
|
|
259
319
|
});
|
|
260
320
|
const showImage = imageShowStrategy({
|
|
261
|
-
lazyLoad: this.
|
|
321
|
+
lazyLoad: this.computedLazyLoad,
|
|
262
322
|
inView: this.inView,
|
|
263
323
|
loaded: this.loaded
|
|
264
324
|
});
|
|
@@ -266,30 +326,30 @@ const Image = defineComponent({
|
|
|
266
326
|
...isVue2 && {
|
|
267
327
|
props: {
|
|
268
328
|
srcset: this.data.webpSrcSet,
|
|
269
|
-
sizes: this.data.sizes,
|
|
329
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
270
330
|
type: "image/webp"
|
|
271
331
|
}
|
|
272
332
|
},
|
|
273
333
|
...isVue3 && {
|
|
274
334
|
srcset: this.data.webpSrcSet,
|
|
275
|
-
sizes: this.data.sizes,
|
|
335
|
+
sizes: this.sizes ?? this.data.sizes ?? void 0,
|
|
276
336
|
type: "image/webp"
|
|
277
337
|
}
|
|
278
338
|
});
|
|
279
339
|
const regularSource = this.data.srcSet && h(Source, {
|
|
280
340
|
...isVue2 && {
|
|
281
341
|
props: {
|
|
282
|
-
srcset: this.data.srcSet,
|
|
283
|
-
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
|
|
284
344
|
}
|
|
285
345
|
},
|
|
286
346
|
...isVue3 && {
|
|
287
|
-
srcset: this.data.srcSet,
|
|
288
|
-
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
|
|
289
349
|
}
|
|
290
350
|
});
|
|
291
351
|
const transition = typeof this.fadeInDuration === "undefined" || this.fadeInDuration > 0 ? `opacity ${this.fadeInDuration || 500}ms ${this.fadeInDuration || 500}ms` : void 0;
|
|
292
|
-
const placeholder = h("div", {
|
|
352
|
+
const placeholder = this.usePlaceholder && (this.data.bgColor || this.data.base64) ? h("div", {
|
|
293
353
|
style: {
|
|
294
354
|
backgroundImage: this.data.base64 ? `url(${this.data.base64})` : null,
|
|
295
355
|
backgroundColor: this.data.bgColor,
|
|
@@ -298,11 +358,15 @@ const Image = defineComponent({
|
|
|
298
358
|
objectFit: this.objectFit,
|
|
299
359
|
objectPosition: this.objectPosition,
|
|
300
360
|
transition,
|
|
301
|
-
|
|
361
|
+
position: "absolute",
|
|
362
|
+
left: "-5%",
|
|
363
|
+
top: "-5%",
|
|
364
|
+
width: "110%",
|
|
365
|
+
height: "110%"
|
|
302
366
|
}
|
|
303
|
-
});
|
|
367
|
+
}) : null;
|
|
304
368
|
const { width, aspectRatio } = this.data;
|
|
305
|
-
const height = this.data.height
|
|
369
|
+
const height = this.data.height ?? (aspectRatio ? width / aspectRatio : 0);
|
|
306
370
|
const sizer = this.layout !== "fill" ? h(Sizer, {
|
|
307
371
|
...isVue2 && {
|
|
308
372
|
props: {
|
|
@@ -343,7 +407,8 @@ const Image = defineComponent({
|
|
|
343
407
|
attrs: {
|
|
344
408
|
src: this.data.src,
|
|
345
409
|
alt: this.data.alt,
|
|
346
|
-
title: this.data.title
|
|
410
|
+
title: this.data.title,
|
|
411
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
347
412
|
},
|
|
348
413
|
on: {
|
|
349
414
|
load: this.handleLoad
|
|
@@ -353,16 +418,18 @@ const Image = defineComponent({
|
|
|
353
418
|
src: this.data.src,
|
|
354
419
|
alt: this.data.alt,
|
|
355
420
|
title: this.data.title,
|
|
421
|
+
fetchpriority: this.priority ? "high" : void 0,
|
|
356
422
|
onLoad: this.handleLoad
|
|
357
423
|
},
|
|
424
|
+
ref: "imageRef",
|
|
358
425
|
class: this.pictureClass,
|
|
359
426
|
style: {
|
|
360
|
-
...absolutePositioning,
|
|
361
|
-
...this.pictureStyle,
|
|
362
427
|
opacity: showImage ? 1 : 0,
|
|
363
428
|
transition,
|
|
429
|
+
...absolutePositioning,
|
|
364
430
|
objectFit: this.objectFit,
|
|
365
|
-
objectPosition: this.objectPosition
|
|
431
|
+
objectPosition: this.objectPosition,
|
|
432
|
+
...this.pictureStyle
|
|
366
433
|
}
|
|
367
434
|
})
|
|
368
435
|
]),
|
|
@@ -384,8 +451,14 @@ const Image = defineComponent({
|
|
|
384
451
|
alt: this.data.alt,
|
|
385
452
|
title: this.data.title,
|
|
386
453
|
class: this.pictureClass,
|
|
387
|
-
style: toCss({
|
|
388
|
-
|
|
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
|
|
389
462
|
})
|
|
390
463
|
])
|
|
391
464
|
}
|
|
@@ -407,7 +480,8 @@ const Image = defineComponent({
|
|
|
407
480
|
title: this.data.title,
|
|
408
481
|
class: this.pictureClass,
|
|
409
482
|
style: toCss({ ...this.pictureStyle, ...absolutePositioning }),
|
|
410
|
-
loading: "lazy"
|
|
483
|
+
loading: this.computedLazyLoad ? "lazy" : void 0,
|
|
484
|
+
fetchpriority: this.priority ? "high" : void 0
|
|
411
485
|
})
|
|
412
486
|
])
|
|
413
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",
|