@prismicio/vue 2.0.11 → 2.1.0-alpha.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,51 +1,87 @@
1
- import PrismicDom from 'prismic-dom'
2
-
3
- export default ({
4
- component = 'a'
5
- }) => ({
6
- name: 'PrismicLink',
7
- functional: true,
8
- props: {
9
- field: {
10
- type: Object,
11
- required: true,
12
- },
13
- linkResolver: {
14
- type: Function,
15
- required: false
16
- }
17
- },
18
- render(h, { props, data, children, parent }) {
19
- const { field, linkResolver } = props
20
-
21
- if (!field) {
22
- return null
23
- }
24
-
25
- const url = parent.$prismic
26
- ? parent.$prismic.asLink(field, linkResolver)
27
- : PrismicDom.Link.url(field, linkResolver || function() { return null; })
28
-
29
- if (url.indexOf('/') === 0) {
30
- data.props = data.props || {};
31
- data.props.to = url;
32
-
33
- return h(component, data, children);
34
- }
35
-
36
- data.attrs = {
37
- ...data.attrs,
38
- href: url,
39
- ...field.target && {
40
- target: field.target,
41
- rel: 'noopener',
42
- },
43
- }
44
-
45
- return h(
46
- 'a',
47
- data,
48
- children,
49
- );
50
- }
51
- })
1
+ import PrismicDom from "prismic-dom";
2
+
3
+ const isInternalURL = (url) => {
4
+ /**
5
+ * @see Regex101 expression: {@link https://regex101.com/r/1y7iod/1}
6
+ */
7
+ const isInternal = /^\/(?!\/)/.test(url);
8
+ /**
9
+ * @see Regex101 expression: {@link https://regex101.com/r/RnUseS/1}
10
+ */
11
+ const isSpecialLink = !isInternal && !/^https?:\/\//i.test(url);
12
+
13
+ return isInternal && !isSpecialLink;
14
+ };
15
+
16
+ export default ({ component = "a" }) => ({
17
+ name: "PrismicLink",
18
+ functional: true,
19
+ props: {
20
+ field: {
21
+ type: Object,
22
+ required: true,
23
+ },
24
+ linkResolver: {
25
+ type: Function,
26
+ required: false,
27
+ },
28
+ target: {
29
+ type: String,
30
+ default: undefined,
31
+ required: false,
32
+ },
33
+ rel: {
34
+ type: String,
35
+ default: undefined,
36
+ required: false,
37
+ },
38
+ blankTargetRelAttribute: {
39
+ type: String,
40
+ default: "noopener",
41
+ required: false,
42
+ },
43
+ },
44
+ render(h, { props, data, children, parent }) {
45
+ const { field, linkResolver } = props;
46
+
47
+ if (!field) {
48
+ return null;
49
+ }
50
+
51
+ const url = parent.$prismic
52
+ ? parent.$prismic.asLink(field, linkResolver)
53
+ : PrismicDom.Link.url(
54
+ field,
55
+ linkResolver ||
56
+ function () {
57
+ return null;
58
+ }
59
+ );
60
+
61
+ if (isInternalURL(url) && !props.target) {
62
+ data.props = data.props || {};
63
+ data.props.to = url;
64
+
65
+ return h(component, data, children);
66
+ }
67
+
68
+ data.attrs = {
69
+ ...data.attrs,
70
+ href: url,
71
+ };
72
+
73
+ if (typeof props.target !== "undefined" || field.target) {
74
+ data.attrs.target =
75
+ typeof props.target !== "undefined" ? props.target : field.target;
76
+
77
+ if (data.attrs.target === "_blank") {
78
+ data.attrs.rel =
79
+ typeof props.rel !== "undefined"
80
+ ? props.rel
81
+ : props.blankTargetRelAttribute;
82
+ }
83
+ }
84
+
85
+ return h("a", data, children);
86
+ },
87
+ });
@@ -1,45 +1,44 @@
1
- import { RichText } from 'prismic-dom'
1
+ import { RichText } from "prismic-dom";
2
2
 
3
3
  export default {
4
- name: 'PrismicRichText',
5
- functional: true,
6
- props: {
7
- field: {
8
- type: Array,
9
- required: true,
10
- },
11
- htmlSerializer: {
12
- type: Function,
13
- required: false,
14
- },
15
- wrapper: {
16
- type: String,
17
- required: false,
18
- default: 'div',
19
- }
20
- },
21
- render(h, {
22
- props, data, children, parent
23
- }) {
24
- const { field, htmlSerializer, wrapper } = props
4
+ name: "PrismicRichText",
5
+ functional: true,
6
+ props: {
7
+ field: {
8
+ type: Array,
9
+ required: true,
10
+ },
11
+ linkResolver: {
12
+ type: Function,
13
+ required: false,
14
+ },
15
+ htmlSerializer: {
16
+ type: Function,
17
+ required: false,
18
+ },
19
+ wrapper: {
20
+ type: String,
21
+ required: false,
22
+ default: "div",
23
+ },
24
+ },
25
+ render(h, { props, data, parent }) {
26
+ const { field, linkResolver, htmlSerializer, wrapper } = props;
25
27
 
26
- if (!field) {
27
- return null
28
- }
29
- const innerHTML = RichText.asHtml(
30
- field,
31
- parent.$prismic.linkResolver,
32
- htmlSerializer || parent.$prismic.htmlSerializer
33
- )
28
+ if (!field) {
29
+ return null;
30
+ }
31
+ const innerHTML = RichText.asHtml(
32
+ field,
33
+ linkResolver || parent.$prismic.linkResolver,
34
+ htmlSerializer || parent.$prismic.htmlSerializer
35
+ );
34
36
 
35
- return h(
36
- wrapper,
37
- {
38
- ...data,
39
- domProps: {
40
- innerHTML
41
- },
42
- },
43
- )
44
- }
45
- }
37
+ return h(wrapper, {
38
+ ...data,
39
+ domProps: {
40
+ innerHTML,
41
+ },
42
+ });
43
+ },
44
+ };
@@ -0,0 +1,144 @@
1
+ // We need to polyfill process if it doesn't exist, such as in the browser.
2
+ if (typeof process === "undefined") {
3
+ globalThis.process = { env: {} };
4
+ }
5
+
6
+ /**
7
+ * `true` if in the production environment, `false` otherwise.
8
+ *
9
+ * This boolean can be used to perform actions only in development environments,
10
+ * such as logging.
11
+ */
12
+ const __PRODUCTION__ = process.env.NODE_ENV === "production";
13
+
14
+ export const getSliceComponentProps = (propsHint) => ({
15
+ slice: {
16
+ type: Object,
17
+ required: true,
18
+ },
19
+ index: {
20
+ type: Number,
21
+ required: true,
22
+ },
23
+ slices: {
24
+ type: Array,
25
+ required: true,
26
+ },
27
+ context: {
28
+ type: null,
29
+ required: true,
30
+ },
31
+ });
32
+
33
+ export const TODOSliceComponent = __PRODUCTION__
34
+ ? () => null
35
+ : {
36
+ name: "TODOSliceCOmponent",
37
+ functional: true,
38
+ props: getSliceComponentProps(),
39
+ renfer(h, { props, data }) {
40
+ console.warn(
41
+ `[SliceZone] Could not find a component for Slice type "${props.slice.slice_type}"`,
42
+ props.slice
43
+ );
44
+
45
+ return () => {
46
+ return h(
47
+ "section",
48
+ {
49
+ ...data,
50
+ "data-slice-zone-todo-component": "",
51
+ "data-slice-type": props.slice.slice_type,
52
+ },
53
+ [
54
+ `Could not find a component for Slice type "${props.slice.slice_type}"`,
55
+ ]
56
+ );
57
+ };
58
+ },
59
+ };
60
+
61
+ // Just mimiced to prevent confusion but doesn't provide any value with version 2 of this kit
62
+ export const defineSliceZoneComponents = (components) => components;
63
+
64
+ export const SliceZone = {
65
+ name: "SliceZone",
66
+ functional: true,
67
+ props: {
68
+ slices: {
69
+ type: Array,
70
+ required: true,
71
+ },
72
+ components: {
73
+ type: Object,
74
+ default: undefined,
75
+ required: false,
76
+ },
77
+ resolver: {
78
+ type: Function,
79
+ default: undefined,
80
+ required: false,
81
+ },
82
+ context: {
83
+ type: null,
84
+ default: undefined,
85
+ required: false,
86
+ },
87
+ defaultComponent: {
88
+ type: Object,
89
+ default: undefined,
90
+ required: false,
91
+ },
92
+ wrapper: {
93
+ type: [String, Object, Function],
94
+ default: "div",
95
+ required: false,
96
+ },
97
+ },
98
+ render(h, { props, data }) {
99
+ // Prevent fatal if user didn't check for field, throws `Invalid prop` warn
100
+ if (!props.slices) {
101
+ return () => null;
102
+ }
103
+
104
+ const renderedSlices = computed(() => {
105
+ return props.slices.map((slice, index) => {
106
+ let component =
107
+ props.components && slice.slice_type in props.components
108
+ ? props.components[slice.slice_type]
109
+ : props.defaultComponent || TODOSliceComponent;
110
+
111
+ // TODO: Remove `resolver` in v3 in favor of `components`.
112
+ if (props.resolver) {
113
+ const resolvedComponent = props.resolver({
114
+ slice,
115
+ sliceName: slice.slice_type,
116
+ i: index,
117
+ });
118
+
119
+ if (resolvedComponent) {
120
+ component = resolvedComponent;
121
+ }
122
+ }
123
+
124
+ const p = {
125
+ key: `${slice.slice_type}-${index}`,
126
+ slice,
127
+ index,
128
+ context: props.context,
129
+ slices: props.slices,
130
+ };
131
+
132
+ return h(component, p);
133
+ });
134
+ });
135
+
136
+ const parent = props.wrapper;
137
+
138
+ if (typeof parent === "string") {
139
+ return h(parent, data, renderedSlices.value);
140
+ } else {
141
+ return h(parent, data, { default: () => renderedSlices.value });
142
+ }
143
+ },
144
+ };
@@ -0,0 +1,37 @@
1
+ import { RichText } from "prismic-dom";
2
+
3
+ export default {
4
+ name: "PrismicText",
5
+ functional: true,
6
+ props: {
7
+ field: {
8
+ type: Array,
9
+ required: true,
10
+ },
11
+ separator: {
12
+ type: String,
13
+ default: undefined,
14
+ required: false,
15
+ },
16
+ wrapper: {
17
+ type: String,
18
+ required: false,
19
+ default: "div",
20
+ },
21
+ },
22
+ render(h, { props, data, children, parent }) {
23
+ const { field, separator, wrapper } = props;
24
+
25
+ if (!field) {
26
+ return null;
27
+ }
28
+ const innerHTML = RichText.asText(field, separator);
29
+
30
+ return h(wrapper, {
31
+ ...data,
32
+ domProps: {
33
+ innerHTML,
34
+ },
35
+ });
36
+ },
37
+ };
@@ -1,27 +1,31 @@
1
- import Embed from './Embed'
2
- import Image from './Image'
3
- import Link from './Link'
4
- import RichText from './RichText'
1
+ import Embed from "./Embed";
2
+ import Image from "./Image";
3
+ import Link from "./Link";
4
+ import RichText from "./RichText";
5
+ import Text from "./Text";
6
+ import { SliceZone } from "./SliceZone";
5
7
 
6
- const NuxtLink = Link({ component: 'nuxt-link' })
7
- const VueRouterLink = Link({ component: 'router-link' })
8
+ const NuxtLink = Link({ component: "nuxt-link" });
9
+ const VueRouterLink = Link({ component: "router-link" });
8
10
 
9
11
  const exp = {
10
- common: {
11
- Embed,
12
- Image,
13
- RichText,
14
- },
15
- nuxt: {
16
- Link: NuxtLink,
17
- },
18
- vueRouter: {
19
- Link: VueRouterLink,
20
- }
21
- }
12
+ common: {
13
+ Embed,
14
+ Image,
15
+ RichText,
16
+ Text,
17
+ SliceZone,
18
+ },
19
+ nuxt: {
20
+ Link: NuxtLink,
21
+ },
22
+ vueRouter: {
23
+ Link: VueRouterLink,
24
+ },
25
+ };
22
26
 
23
- export const common = exp.common
24
- export const nuxt = exp.nuxt
25
- export const vueRouter = exp.vueRouter
27
+ export const common = exp.common;
28
+ export const nuxt = exp.nuxt;
29
+ export const vueRouter = exp.vueRouter;
26
30
 
27
- export default exp
31
+ export default exp;
@@ -1,7 +1,12 @@
1
- import exp from './components'
1
+ import exp from "./components";
2
2
 
3
- export const common = exp.common
4
- export const nuxt = exp.nuxt
5
- export const vueRouter = exp.vueRouter
3
+ export {
4
+ getSliceComponentProps,
5
+ defineSliceZoneComponents,
6
+ } from "./components/SliceZone";
6
7
 
7
- export default exp
8
+ export const common = exp.common;
9
+ export const nuxt = exp.nuxt;
10
+ export const vueRouter = exp.vueRouter;
11
+
12
+ export default exp;
package/src/index.js CHANGED
@@ -1,49 +1,56 @@
1
- import prismicJS from '@prismicio/client'
1
+ import prismicJS from "@prismicio/client";
2
2
 
3
- import Components from './components'
4
- import { asHtml, asText, asDate, asLink } from './methods'
3
+ import Components from "./components";
4
+ import { asHtml, asText, asDate, asLink } from "./methods";
5
5
 
6
6
  function attachMethods(Vue, options) {
7
- Vue.prototype.$prismic.asHtml = function(richText, linkResolver, htmlSerializer) {
8
- return asHtml(
9
- richText,
10
- linkResolver || options.linkResolver,
11
- htmlSerializer || options.htmlSerializer
12
- )
13
- }
14
- Vue.prototype.$prismic.asText = asText
15
- Vue.prototype.$prismic.richTextAsPlain = asText
16
- Vue.prototype.$prismic.asDate = asDate
17
- Vue.prototype.$prismic.asLink = function(link, linkResolver) {
18
- return asLink(link, linkResolver || options.linkResolver)
19
- }
7
+ Vue.prototype.$prismic.asHtml = function(
8
+ richText,
9
+ linkResolver,
10
+ htmlSerializer
11
+ ) {
12
+ return asHtml(
13
+ richText,
14
+ linkResolver || options.linkResolver,
15
+ htmlSerializer || options.htmlSerializer
16
+ );
17
+ };
18
+ Vue.prototype.$prismic.asHTML = Vue.prototype.$prismic.asHtml;
19
+ Vue.prototype.$prismic.asText = asText;
20
+ Vue.prototype.$prismic.richTextAsPlain = asText;
21
+ Vue.prototype.$prismic.asDate = asDate;
22
+ Vue.prototype.$prismic.asLink = function(link, linkResolver) {
23
+ return asLink(link, linkResolver || options.linkResolver);
24
+ };
20
25
  }
21
26
 
22
27
  const PrismicVue = {
23
- install: function (Vue, options) {
24
- const { linkType = 'vueRouter' } = options
25
- Vue.prototype.$prismic = prismicJS
26
- Vue.prototype.$prismic.endpoint = options.endpoint
27
- Vue.prototype.$prismic.linkResolver = options.linkResolver
28
- Vue.prototype.$prismic.htmlSerializer = options.htmlSerializer
29
- Vue.prototype.$prismic.client = prismicJS.client(options.endpoint, options.apiOptions)
28
+ install: function(Vue, options) {
29
+ const { linkType = "vueRouter" } = options;
30
+ Vue.prototype.$prismic = prismicJS;
31
+ Vue.prototype.$prismic.endpoint = options.endpoint;
32
+ Vue.prototype.$prismic.linkResolver = options.linkResolver;
33
+ Vue.prototype.$prismic.htmlSerializer = options.htmlSerializer;
34
+ Vue.prototype.$prismic.client = prismicJS.client(
35
+ options.endpoint,
36
+ options.apiOptions
37
+ );
30
38
 
31
- attachMethods(Vue, options)
39
+ attachMethods(Vue, options);
32
40
 
33
- const components = {
34
- ...Components.common,
35
- ...Components[linkType]
36
- }
41
+ const components = {
42
+ ...Components.common,
43
+ ...Components[linkType]
44
+ };
37
45
 
38
- /**
39
- * Global registration of common components + stack specific components.
40
- * Currently, only Nuxt links differ though. Use `linkType: 'nuxt'` in that case.
41
- */
42
- Object.entries(components)
43
- .forEach(([_, c]) => {
44
- Vue.component(c.name, c)
45
- })
46
- }
47
- }
46
+ /**
47
+ * Global registration of common components + stack specific components.
48
+ * Currently, only Nuxt links differ though. Use `linkType: 'nuxt'` in that case.
49
+ */
50
+ Object.entries(components).forEach(([_, c]) => {
51
+ Vue.component(c.name, c);
52
+ });
53
+ }
54
+ };
48
55
 
49
- export default PrismicVue
56
+ export default PrismicVue;