vue-datocms 8.1.4 → 8.1.5-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.
@@ -1,4 +1,6 @@
1
- import { ref, onMounted, onBeforeUnmount, defineComponent, h, watchEffect, unref, reactive, computed, toRaw } from 'vue';
1
+ import { ref, watch, onMounted, onUnmounted, defineComponent, onBeforeUnmount, h, watchEffect, unref, reactive, computed, toRaw } from 'vue';
2
+ import { createController } from '@datocms/content-link';
3
+ export { decodeStega, stripStega } from '@datocms/content-link';
2
4
  import hypenateStyleName from 'hyphenate-style-name';
3
5
  import { render, renderNodeRule, defaultMetaTransformer } from 'datocms-structured-text-generic-html-renderer';
4
6
  export { renderMarkRule, renderNodeRule, renderNodeRule as renderRule } from 'datocms-structured-text-generic-html-renderer';
@@ -6,6 +8,172 @@ import { isRoot, isInlineItem, RenderError, isStructuredText, isItemLink, isBloc
6
8
  export { RenderError } from 'datocms-structured-text-utils';
7
9
  import { subscribeToQuery } from 'datocms-listen';
8
10
 
11
+ function useContentLink(options = {}) {
12
+ const { enabled = true, onNavigateTo, root } = options;
13
+ const controller = ref(null);
14
+ const onNavigateToRef = ref(onNavigateTo);
15
+ watch(
16
+ () => onNavigateTo,
17
+ (newCallback) => {
18
+ onNavigateToRef.value = newCallback;
19
+ }
20
+ );
21
+ const initializeController = () => {
22
+ const isEnabled = enabled === true || typeof enabled === "object" && enabled !== null;
23
+ if (!isEnabled) return;
24
+ if (controller.value) {
25
+ controller.value.dispose();
26
+ }
27
+ const controllerOptions = {};
28
+ if (typeof enabled === "object") {
29
+ controllerOptions.stripStega = enabled.stripStega;
30
+ }
31
+ if (onNavigateToRef.value) {
32
+ controllerOptions.onNavigateTo = (path) => {
33
+ var _a;
34
+ return (_a = onNavigateToRef.value) == null ? void 0 : _a.call(onNavigateToRef, path);
35
+ };
36
+ }
37
+ if (root == null ? void 0 : root.value) {
38
+ controllerOptions.root = root.value;
39
+ }
40
+ controller.value = createController(controllerOptions);
41
+ };
42
+ onMounted(() => {
43
+ initializeController();
44
+ });
45
+ onUnmounted(() => {
46
+ if (controller.value) {
47
+ controller.value.dispose();
48
+ controller.value = null;
49
+ }
50
+ });
51
+ if (root) {
52
+ watch(
53
+ root,
54
+ () => {
55
+ if (enabled) {
56
+ initializeController();
57
+ }
58
+ },
59
+ { flush: "post" }
60
+ );
61
+ }
62
+ const enableClickToEdit = (opts) => {
63
+ var _a;
64
+ (_a = controller.value) == null ? void 0 : _a.enableClickToEdit(opts);
65
+ };
66
+ const disableClickToEdit = () => {
67
+ var _a;
68
+ (_a = controller.value) == null ? void 0 : _a.disableClickToEdit();
69
+ };
70
+ const isClickToEditEnabled = () => {
71
+ var _a, _b;
72
+ return (_b = (_a = controller.value) == null ? void 0 : _a.isClickToEditEnabled()) != null ? _b : false;
73
+ };
74
+ const flashAll = (scrollToNearestTarget) => {
75
+ var _a;
76
+ (_a = controller.value) == null ? void 0 : _a.flashAll(scrollToNearestTarget);
77
+ };
78
+ const setCurrentPath = (path) => {
79
+ var _a;
80
+ (_a = controller.value) == null ? void 0 : _a.setCurrentPath(path);
81
+ };
82
+ return {
83
+ controller,
84
+ enableClickToEdit,
85
+ disableClickToEdit,
86
+ isClickToEditEnabled,
87
+ flashAll,
88
+ setCurrentPath
89
+ };
90
+ }
91
+
92
+ const ContentLink = defineComponent({
93
+ name: "DatocmsContentLink",
94
+ props: {
95
+ /**
96
+ * Callback when Web Previews plugin requests navigation.
97
+ * Use this to integrate with your router.
98
+ *
99
+ * @example
100
+ * With Vue Router: `(path) => router.push(path)`
101
+ * With Nuxt: `(path) => navigateTo(path)`
102
+ */
103
+ onNavigateTo: {
104
+ type: Function,
105
+ required: false
106
+ },
107
+ /**
108
+ * Root element to limit scanning to (instead of document).
109
+ * Pass a ref to a parent element to limit the scope of content link scanning.
110
+ */
111
+ root: {
112
+ type: Object,
113
+ required: false
114
+ },
115
+ /**
116
+ * Current pathname to sync with Web Previews plugin.
117
+ * This keeps the plugin in sync with the current page being previewed.
118
+ *
119
+ * @example
120
+ * With Vue Router: `route.path`
121
+ * With Nuxt: `route.path`
122
+ */
123
+ currentPath: {
124
+ type: String,
125
+ required: false
126
+ },
127
+ /**
128
+ * Enable click-to-edit on mount. Pass true for default behavior or an object with scrollToNearestTarget.
129
+ * If undefined, click-to-edit is disabled and editors can use Alt/Option key for temporary activation.
130
+ */
131
+ enableClickToEdit: {
132
+ type: [Boolean, Object],
133
+ required: false
134
+ },
135
+ /**
136
+ * Whether to strip stega encoding from text nodes after stamping.
137
+ */
138
+ stripStega: {
139
+ type: Boolean,
140
+ required: false
141
+ }
142
+ },
143
+ setup(props) {
144
+ const {
145
+ enableClickToEdit: enableClickToEditFn,
146
+ setCurrentPath
147
+ } = useContentLink({
148
+ enabled: props.stripStega !== void 0 ? { stripStega: props.stripStega } : true,
149
+ onNavigateTo: props.onNavigateTo,
150
+ root: props.root
151
+ });
152
+ onMounted(() => {
153
+ if (props.enableClickToEdit !== void 0) {
154
+ enableClickToEditFn(
155
+ props.enableClickToEdit === true ? void 0 : props.enableClickToEdit
156
+ );
157
+ }
158
+ });
159
+ watch(
160
+ () => props.currentPath,
161
+ (newPath) => {
162
+ if (newPath !== void 0) {
163
+ setCurrentPath(newPath);
164
+ }
165
+ },
166
+ { immediate: true }
167
+ );
168
+ return () => null;
169
+ }
170
+ });
171
+ const DatocmsContentLinkPlugin = {
172
+ install: (Vue) => {
173
+ Vue.component("DatocmsContentLink", ContentLink);
174
+ }
175
+ };
176
+
9
177
  const isSsr = () => {
10
178
  return typeof window === "undefined";
11
179
  };
@@ -255,67 +423,108 @@ const Image$1 = defineComponent({
255
423
  inheritAttrs: false,
256
424
  emits: ["load"],
257
425
  props: {
426
+ /** The actual response you get from a DatoCMS `responsiveImage` GraphQL query */
258
427
  data: {
259
428
  type: Object,
260
429
  required: true
261
430
  },
431
+ /** Additional CSS class for the `<picture />` tag */
262
432
  pictureClass: {
263
433
  type: String
264
434
  },
435
+ /** Additional CSS class for the image inside the `<picture />` tag */
265
436
  imgClass: {
266
437
  type: String
267
438
  },
439
+ /** Additional CSS class for the placeholder image */
268
440
  placeholderClass: {
269
441
  type: String
270
442
  },
443
+ /** Duration (in ms) of the fade-in transition effect upoad image loading */
271
444
  fadeInDuration: {
272
445
  type: Number
273
446
  },
447
+ /** @deprecated Use the intersectionThreshold prop */
274
448
  intersectionTreshold: {
275
449
  type: Number,
276
450
  default: 0
277
451
  },
452
+ /** Indicate at what percentage of the placeholder visibility the loading of the image should be triggered. A value of 0 means that as soon as even one pixel is visible, the callback will be run. A value of 1.0 means that the threshold isn't considered passed until every pixel is visible */
278
453
  intersectionThreshold: {
279
454
  type: Number
280
455
  },
456
+ /** Margin around the placeholder. Can have values similar to the CSS margin property (top, right, bottom, left). The values can be percentages. This set of values serves to grow or shrink each side of the placeholder element's bounding box before computing intersections */
281
457
  intersectionMargin: {
282
458
  type: String,
283
459
  default: "0px 0px 0px 0px"
284
460
  },
461
+ /** Additional CSS rules to add to the `<picture />` tag */
285
462
  pictureStyle: {
286
463
  type: Object,
287
464
  default: () => ({})
288
465
  },
466
+ /** Additional CSS rules to add to the image inside the `<picture />` tag */
289
467
  imgStyle: {
290
468
  type: Object,
291
469
  default: () => ({})
292
470
  },
471
+ /** Additional CSS rules to add to the placeholder image */
293
472
  placeholderStyle: {
294
473
  type: Object,
295
474
  default: () => ({})
296
475
  },
476
+ /**
477
+ * The layout behavior of the image as the viewport changes size
478
+ *
479
+ * Possible values:
480
+ *
481
+ * * `intrinsic`: the image will scale the dimensions down for smaller viewports, but maintain the original dimensions for larger viewports
482
+ * * `fixed`: the image dimensions will not change as the viewport changes (no responsiveness) similar to the native img element
483
+ * * `responsive` (default): the image will scale the dimensions down for smaller viewports and scale up for larger viewports
484
+ * * `fill`: image will stretch both width and height to the dimensions of the parent element, provided the parent element is `relative`
485
+ **/
297
486
  layout: {
298
487
  type: String,
299
488
  default: () => "intrinsic",
300
489
  validator: (value) => ["intrinsic", "fixed", "responsive", "fill"].includes(value)
301
490
  },
491
+ /** Defines how the image will fit into its parent container when using layout="fill" */
302
492
  objectFit: {
303
493
  type: String
304
494
  },
495
+ /** Defines how the image is positioned within its parent element when using layout="fill". */
305
496
  objectPosition: {
306
497
  type: String
307
498
  },
499
+ /** Whether the component should use a blurred image placeholder */
308
500
  usePlaceholder: {
309
501
  type: Boolean,
310
502
  default: true
311
503
  },
504
+ /**
505
+ * The HTML5 `sizes` attribute for the image
506
+ *
507
+ * Learn more about srcset and sizes:
508
+ * -> https://web.dev/learn/design/responsive-images/#sizes
509
+ * -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
510
+ **/
312
511
  sizes: {
313
512
  type: String
314
513
  },
514
+ /**
515
+ * When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
516
+ * 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.
517
+ * Should only be used when the image is visible above the fold.
518
+ **/
315
519
  priority: {
316
520
  type: Boolean,
317
521
  default: false
318
522
  },
523
+ /**
524
+ * If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
525
+ *
526
+ * Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
527
+ **/
319
528
  srcSetCandidates: {
320
529
  type: Array,
321
530
  validator: (values) => values.every((value) => {
@@ -323,6 +532,12 @@ const Image$1 = defineComponent({
323
532
  }),
324
533
  default: () => [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
325
534
  },
535
+ /**
536
+ * Defines which referrer is sent when fetching the image
537
+ * Read more: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#referrerpolicy
538
+ *
539
+ * Defaults to `no-referrer-when-downgrade` to give more useful stats in DatoCMS Project Usages
540
+ **/
326
541
  referrerPolicy: {
327
542
  type: String,
328
543
  default: "no-referrer-when-downgrade"
@@ -381,6 +596,10 @@ const Image$1 = defineComponent({
381
596
  const basePlaceholderStyle = __spreadValues$5({
382
597
  transition,
383
598
  opacity: showImage ? 0 : 1,
599
+ // During the opacity transition of the placeholder to the definitive version,
600
+ // hardware acceleration is triggered. This results in the browser trying to render the
601
+ // placeholder with your GPU, causing blurred edges. Solution: style the placeholder
602
+ // so the edges overflow the container
384
603
  position: "absolute",
385
604
  left: "-5%",
386
605
  top: "-5%",
@@ -508,21 +727,40 @@ const NakedImage = defineComponent({
508
727
  name: "DatocmsNakedImage",
509
728
  inheritAttrs: false,
510
729
  props: {
730
+ /** The actual response you get from a DatoCMS `responsiveImage` GraphQL query */
511
731
  data: {
512
732
  type: Object,
513
733
  required: true
514
734
  },
735
+ /** Whether the component should use a blurred image placeholder */
515
736
  usePlaceholder: {
516
737
  type: Boolean,
517
738
  default: true
518
739
  },
740
+ /**
741
+ * The HTML5 `sizes` attribute for the image
742
+ *
743
+ * Learn more about srcset and sizes:
744
+ * -> https://web.dev/learn/design/responsive-images/#sizes
745
+ * -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
746
+ **/
519
747
  sizes: {
520
748
  type: String
521
749
  },
750
+ /**
751
+ * When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
752
+ * 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.
753
+ * Should only be used when the image is visible above the fold.
754
+ **/
522
755
  priority: {
523
756
  type: Boolean,
524
757
  default: false
525
758
  },
759
+ /**
760
+ * If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
761
+ *
762
+ * Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
763
+ **/
526
764
  srcSetCandidates: {
527
765
  type: Array,
528
766
  validator: (values) => values.every((value) => {
@@ -530,20 +768,30 @@ const NakedImage = defineComponent({
530
768
  }),
531
769
  default: () => [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
532
770
  },
771
+ /** Additional CSS class for the root `<picture />` tag */
533
772
  pictureClass: {
534
773
  type: String
535
774
  },
775
+ /** Additional CSS rules to add to the root `<picture />` tag */
536
776
  pictureStyle: {
537
777
  type: Object,
538
778
  default: () => ({})
539
779
  },
780
+ /** Additional CSS class for the `<img />` tag */
540
781
  imgClass: {
541
782
  type: String
542
783
  },
784
+ /** Additional CSS rules to add to the `<img />` tag */
543
785
  imgStyle: {
544
786
  type: Object,
545
787
  default: () => ({})
546
788
  },
789
+ /**
790
+ * Defines which referrer is sent when fetching the image
791
+ * Read more: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#referrerpolicy
792
+ *
793
+ * Defaults to `no-referrer-when-downgrade` to give more useful stats in DatoCMS Project Usages
794
+ **/
547
795
  referrerPolicy: {
548
796
  type: String,
549
797
  default: "no-referrer-when-downgrade"
@@ -645,33 +893,45 @@ function appendKeyToValidElement(element, key) {
645
893
  const StructuredText = defineComponent({
646
894
  name: "DatocmsStructuredText",
647
895
  props: {
896
+ /** The actual field value you get from DatoCMS **/
648
897
  data: {
649
898
  type: Object
650
899
  },
900
+ /** @deprecated use customNodeRules **/
651
901
  customRules: {
652
902
  type: Array
653
903
  },
904
+ /** A set of additional rules to convert the document to JSX **/
654
905
  customNodeRules: {
655
906
  type: Array
656
907
  },
908
+ /** A set of additional rules to convert the document to JSX **/
657
909
  customMarkRules: {
658
910
  type: Array
659
911
  },
912
+ /** Fuction that converts an 'inlineItem' node into a Vue component **/
660
913
  renderInlineRecord: {
661
914
  type: Function
662
915
  },
916
+ /** Fuction that converts an 'itemLink' node into a Vue component **/
663
917
  renderLinkToRecord: {
664
918
  type: Function
665
919
  },
920
+ /** Fuction that converts a 'block' node into a Vue component **/
666
921
  renderBlock: {
667
922
  type: Function
668
923
  },
924
+ /** Fuction that converts an 'inlineBlock' node into a Vue component **/
669
925
  renderInlineBlock: {
670
926
  type: Function
671
927
  },
928
+ /** Function that converts 'link' and 'itemLink' `meta` into HTML props */
672
929
  metaTransformer: { type: Function },
930
+ /** Fuction that converts a simple string text into a Vue component **/
673
931
  renderText: { type: Function },
932
+ /** React.createElement-like function to use to convert a node into a Vue component **/
674
933
  renderNode: { type: Function },
934
+ /** Function to use to generate a Vue.Fragment **/
675
935
  renderFragment: { type: Function }
676
936
  },
677
937
  setup(props) {
@@ -834,13 +1094,11 @@ const computedTitle = (title) => {
834
1094
  return title ? { title } : void 0;
835
1095
  };
836
1096
  const computedPlaybackId = (muxPlaybackId, playbackId) => {
837
- if (!(muxPlaybackId || playbackId))
838
- return void 0;
1097
+ if (!(muxPlaybackId || playbackId)) return void 0;
839
1098
  return { playbackId: `${muxPlaybackId || playbackId}` };
840
1099
  };
841
1100
  const computedStyle = (width, height) => {
842
- if (!(width && height))
843
- return void 0;
1101
+ if (!(width && height)) return void 0;
844
1102
  return {
845
1103
  style: {
846
1104
  aspectRatio: `${width} / ${height}`
@@ -854,8 +1112,7 @@ const useVideoPlayer = ({
854
1112
  data
855
1113
  }) => {
856
1114
  const { title, width, height, playbackId, muxPlaybackId, blurUpThumb } = data || {};
857
- if (data === void 0)
858
- return {};
1115
+ if (data === void 0) return {};
859
1116
  return __spreadValues$3(__spreadValues$3(__spreadValues$3(__spreadValues$3({}, computedTitle(title) || {}), computedPlaybackId(muxPlaybackId, playbackId) || {}), computedStyle(width, height) || {}), computedPlaceholder(blurUpThumb) || {});
860
1117
  };
861
1118
 
@@ -892,8 +1149,7 @@ var __objRest$1 = (source, exclude) => {
892
1149
  };
893
1150
  const isNil = (x) => x == void 0;
894
1151
  const isKeyOf = (k, o) => {
895
- if (isNil(o))
896
- return false;
1152
+ if (isNil(o)) return false;
897
1153
  return k in o;
898
1154
  };
899
1155
  const PropToAttrNameMap = {
@@ -906,21 +1162,15 @@ const PropToAttrNameMap = {
906
1162
  };
907
1163
  const toKebabCase = (string) => string.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
908
1164
  const toNativeAttrName = (propName, propValue) => {
909
- if (typeof propValue === "boolean" && !propValue)
910
- return void 0;
911
- if (isKeyOf(propName, PropToAttrNameMap))
912
- return PropToAttrNameMap[propName];
913
- if (typeof propValue == void 0)
914
- return void 0;
915
- if (/[A-Z]/.test(propName))
916
- return toKebabCase(propName);
1165
+ if (typeof propValue === "boolean" && !propValue) return void 0;
1166
+ if (isKeyOf(propName, PropToAttrNameMap)) return PropToAttrNameMap[propName];
1167
+ if (typeof propValue == void 0) return void 0;
1168
+ if (/[A-Z]/.test(propName)) return toKebabCase(propName);
917
1169
  return propName;
918
1170
  };
919
1171
  const toNativeAttrValue = (propValue, propName) => {
920
- if (Array.isArray(propValue))
921
- return propValue.join(" ");
922
- if (typeof propValue === "boolean")
923
- return propValue;
1172
+ if (Array.isArray(propValue)) return propValue.join(" ");
1173
+ if (typeof propValue === "boolean") return propValue;
924
1174
  return propValue;
925
1175
  };
926
1176
  const toHTMLAttrs = (props = {}) => {
@@ -1568,4 +1818,4 @@ const toHead = (...args) => {
1568
1818
  };
1569
1819
  };
1570
1820
 
1571
- export { DatocmsImagePlugin, DatocmsNakedImagePlugin, DatocmsStructuredTextPlugin, DatocmsVideoPlayerPlugin, Image$1 as Image, NakedImage, StructuredText, VideoPlayer, appendKeyToValidElement, defaultAdapter, isKeyOf, isNil, toHead, toNativeAttrName, toNativeAttrValue, useQuerySubscription, useSiteSearch, useVideoPlayer };
1821
+ export { ContentLink, DatocmsContentLinkPlugin, DatocmsImagePlugin, DatocmsNakedImagePlugin, DatocmsStructuredTextPlugin, DatocmsVideoPlayerPlugin, Image$1 as Image, NakedImage, StructuredText, VideoPlayer, appendKeyToValidElement, defaultAdapter, isKeyOf, isNil, toHead, toNativeAttrName, toNativeAttrValue, useContentLink, useQuerySubscription, useSiteSearch, useVideoPlayer };
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "vue-datocms",
3
- "version": "8.1.4",
3
+ "version": "8.1.5-0",
4
+ "type": "module",
4
5
  "description": "A set of components and utilities to work faster with DatoCMS in Vue.js environments",
5
6
  "keywords": [
6
7
  "datocms",
@@ -41,7 +42,8 @@
41
42
  "toc": "doctoc --github src/components src/lib"
42
43
  },
43
44
  "dependencies": {
44
- "datocms-listen": "^0.1.15",
45
+ "@datocms/content-link": "^0.3.7",
46
+ "datocms-listen": "^1.0.2",
45
47
  "hls.js": "^1.5.17",
46
48
  "datocms-structured-text-generic-html-renderer": "^5.0.0",
47
49
  "datocms-structured-text-utils": "^5.1.6",
@@ -62,11 +64,11 @@
62
64
  "@mux/playback-core": "^0.22.1",
63
65
  "@types/hyphenate-style-name": "^1.0.2",
64
66
  "@types/jest": "^29.5.11",
65
- "@types/node": "^14.18.63",
67
+ "@types/node": "^25.0.10",
66
68
  "@vue/test-utils": "^2.4.3",
67
69
  "@vuedx/typescript-plugin-vue": "^0.7.6",
68
70
  "doctoc": "^2.0.0",
69
- "esbuild": "^0.15.18",
71
+ "esbuild": "^0.24.2",
70
72
  "jest": "^29.7.0",
71
73
  "jest-environment-jsdom": "^29.7.0",
72
74
  "jest-serializer-vue": "^2.0.2",
@@ -74,12 +76,12 @@
74
76
  "matchmedia-polyfill": "^0.3.2",
75
77
  "np": "^9.2.0",
76
78
  "resize-observer-polyfill": "^1.5.1",
77
- "rollup": "^2.79.1",
78
- "rollup-plugin-dts": "^4.2.3",
79
- "rollup-plugin-esbuild": "^4.10.3",
79
+ "rollup": "^3.29.5",
80
+ "rollup-plugin-dts": "^5.3.1",
81
+ "rollup-plugin-esbuild": "^6.1.1",
80
82
  "ts-jest": "^29.1.1",
81
83
  "tslib": "^2.6.2",
82
- "typescript": "^4.9.5",
84
+ "typescript": "^5.9.3",
83
85
  "vue-tsc": "^0.37.9"
84
86
  }
85
87
  }