@prismicio/vue 5.3.0-canary.5d9ea4c → 5.3.0-canary.87748cc

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.
Files changed (170) hide show
  1. package/dist/PrismicImage.vue.d.cts +30 -58
  2. package/dist/PrismicImage.vue.d.cts.map +1 -1
  3. package/dist/PrismicLink.vue.d.cts +65 -137
  4. package/dist/PrismicLink.vue.d.cts.map +1 -1
  5. package/dist/PrismicRichText/PrismicRichText.vue.d.cts +25 -53
  6. package/dist/PrismicRichText/PrismicRichText.vue.d.cts.map +1 -1
  7. package/dist/PrismicRichText/types.d.cts +18 -5
  8. package/dist/PrismicRichText/types.d.cts.map +1 -1
  9. package/dist/PrismicTable/PrismicTable.vue.d.cts +10 -10
  10. package/dist/PrismicTable/PrismicTable.vue.d.cts.map +1 -1
  11. package/dist/PrismicTable/types.d.cts +8 -8
  12. package/dist/PrismicTable/types.d.cts.map +1 -1
  13. package/dist/PrismicText.vue.d.cts +3 -13
  14. package/dist/PrismicText.vue.d.cts.map +1 -1
  15. package/dist/SliceZone/SliceZone.vue.d.cts +5 -24
  16. package/dist/SliceZone/SliceZone.vue.d.cts.map +1 -1
  17. package/dist/index.cjs +3 -10
  18. package/dist/index.d.cts +9 -13
  19. package/dist/index.d.ts +11 -15
  20. package/dist/index.js +3 -6
  21. package/dist/package.cjs +1 -1
  22. package/dist/package.cjs.map +1 -1
  23. package/dist/package.js +1 -1
  24. package/dist/package.js.map +1 -1
  25. package/dist/src/PrismicImage.cjs.map +1 -1
  26. package/dist/src/PrismicImage.js.map +1 -1
  27. package/dist/src/PrismicImage.vue.d.ts +26 -54
  28. package/dist/src/PrismicImage.vue.d.ts.map +1 -1
  29. package/dist/src/PrismicImage.vue_vue_type_script_setup_true_lang.cjs +2 -4
  30. package/dist/src/PrismicImage.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  31. package/dist/src/PrismicImage.vue_vue_type_script_setup_true_lang.js +2 -4
  32. package/dist/src/PrismicImage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/src/PrismicLink.cjs.map +1 -1
  34. package/dist/src/PrismicLink.js.map +1 -1
  35. package/dist/src/PrismicLink.vue.d.ts +61 -133
  36. package/dist/src/PrismicLink.vue.d.ts.map +1 -1
  37. package/dist/src/PrismicLink.vue_vue_type_script_setup_true_lang.cjs +3 -6
  38. package/dist/src/PrismicLink.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  39. package/dist/src/PrismicLink.vue_vue_type_script_setup_true_lang.js +3 -6
  40. package/dist/src/PrismicLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/src/PrismicRichText/PrismicRichText.cjs.map +1 -1
  42. package/dist/src/PrismicRichText/PrismicRichText.js.map +1 -1
  43. package/dist/src/PrismicRichText/PrismicRichText.vue.d.ts +25 -53
  44. package/dist/src/PrismicRichText/PrismicRichText.vue.d.ts.map +1 -1
  45. package/dist/src/PrismicRichText/PrismicRichText.vue_vue_type_script_setup_true_lang.cjs +41 -57
  46. package/dist/src/PrismicRichText/PrismicRichText.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  47. package/dist/src/PrismicRichText/PrismicRichText.vue_vue_type_script_setup_true_lang.js +42 -58
  48. package/dist/src/PrismicRichText/PrismicRichText.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/src/PrismicRichText/PrismicRichTextDefaultComponent.cjs.map +1 -1
  50. package/dist/src/PrismicRichText/PrismicRichTextDefaultComponent.js.map +1 -1
  51. package/dist/src/PrismicRichText/PrismicRichTextDefaultComponent.vue_vue_type_script_setup_true_lang.cjs +53 -33
  52. package/dist/src/PrismicRichText/PrismicRichTextDefaultComponent.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  53. package/dist/src/PrismicRichText/PrismicRichTextDefaultComponent.vue_vue_type_script_setup_true_lang.js +54 -34
  54. package/dist/src/PrismicRichText/PrismicRichTextDefaultComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/src/PrismicRichText/PrismicRichTextSerialize.cjs.map +1 -1
  56. package/dist/src/PrismicRichText/PrismicRichTextSerialize.js.map +1 -1
  57. package/dist/src/PrismicRichText/PrismicRichTextSerialize.vue_vue_type_script_setup_true_lang.cjs +9 -29
  58. package/dist/src/PrismicRichText/PrismicRichTextSerialize.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  59. package/dist/src/PrismicRichText/PrismicRichTextSerialize.vue_vue_type_script_setup_true_lang.js +10 -30
  60. package/dist/src/PrismicRichText/PrismicRichTextSerialize.vue_vue_type_script_setup_true_lang.js.map +1 -1
  61. package/dist/src/PrismicRichText/types.d.ts +18 -5
  62. package/dist/src/PrismicRichText/types.d.ts.map +1 -1
  63. package/dist/src/PrismicTable/PrismicTable.cjs.map +1 -1
  64. package/dist/src/PrismicTable/PrismicTable.js.map +1 -1
  65. package/dist/src/PrismicTable/PrismicTable.vue.d.ts +13 -13
  66. package/dist/src/PrismicTable/PrismicTable.vue.d.ts.map +1 -1
  67. package/dist/src/PrismicTable/PrismicTable.vue_vue_type_script_setup_true_lang.cjs +47 -19
  68. package/dist/src/PrismicTable/PrismicTable.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  69. package/dist/src/PrismicTable/PrismicTable.vue_vue_type_script_setup_true_lang.js +48 -20
  70. package/dist/src/PrismicTable/PrismicTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  71. package/dist/src/PrismicTable/PrismicTableDefaultComponents.cjs +36 -18
  72. package/dist/src/PrismicTable/PrismicTableDefaultComponents.cjs.map +1 -1
  73. package/dist/src/PrismicTable/PrismicTableDefaultComponents.js +36 -18
  74. package/dist/src/PrismicTable/PrismicTableDefaultComponents.js.map +1 -1
  75. package/dist/src/PrismicTable/PrismicTableRow.cjs.map +1 -1
  76. package/dist/src/PrismicTable/PrismicTableRow.js.map +1 -1
  77. package/dist/src/PrismicTable/PrismicTableRow.vue_vue_type_script_setup_true_lang.cjs +13 -10
  78. package/dist/src/PrismicTable/PrismicTableRow.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  79. package/dist/src/PrismicTable/PrismicTableRow.vue_vue_type_script_setup_true_lang.js +14 -11
  80. package/dist/src/PrismicTable/PrismicTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  81. package/dist/src/PrismicTable/types.d.ts +8 -8
  82. package/dist/src/PrismicTable/types.d.ts.map +1 -1
  83. package/dist/src/PrismicText.cjs.map +1 -1
  84. package/dist/src/PrismicText.js.map +1 -1
  85. package/dist/src/PrismicText.vue.d.ts +1 -11
  86. package/dist/src/PrismicText.vue.d.ts.map +1 -1
  87. package/dist/src/PrismicText.vue_vue_type_script_setup_true_lang.cjs +1 -12
  88. package/dist/src/PrismicText.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  89. package/dist/src/PrismicText.vue_vue_type_script_setup_true_lang.js +3 -14
  90. package/dist/src/PrismicText.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/src/SliceZone/SliceZone.cjs.map +1 -1
  92. package/dist/src/SliceZone/SliceZone.js.map +1 -1
  93. package/dist/src/SliceZone/SliceZone.vue.d.ts +5 -24
  94. package/dist/src/SliceZone/SliceZone.vue.d.ts.map +1 -1
  95. package/dist/src/SliceZone/SliceZone.vue_vue_type_script_setup_true_lang.cjs +5 -17
  96. package/dist/src/SliceZone/SliceZone.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
  97. package/dist/src/SliceZone/SliceZone.vue_vue_type_script_setup_true_lang.js +6 -18
  98. package/dist/src/SliceZone/SliceZone.vue_vue_type_script_setup_true_lang.js.map +1 -1
  99. package/dist/src/types.cjs +9 -0
  100. package/dist/src/types.cjs.map +1 -0
  101. package/dist/src/types.d.ts +3 -352
  102. package/dist/src/types.d.ts.map +1 -1
  103. package/dist/src/types.js +8 -0
  104. package/dist/src/types.js.map +1 -0
  105. package/dist/types.d.cts +3 -352
  106. package/dist/types.d.cts.map +1 -1
  107. package/package.json +6 -5
  108. package/src/PrismicImage.vue +10 -27
  109. package/src/PrismicLink.vue +18 -43
  110. package/src/PrismicRichText/PrismicRichText.vue +68 -118
  111. package/src/PrismicRichText/PrismicRichTextDefaultComponent.vue +61 -19
  112. package/src/PrismicRichText/PrismicRichTextSerialize.vue +5 -30
  113. package/src/PrismicRichText/types.ts +33 -14
  114. package/src/PrismicTable/PrismicTable.vue +50 -23
  115. package/src/PrismicTable/PrismicTableDefaultComponents.ts +45 -20
  116. package/src/PrismicTable/PrismicTableRow.vue +17 -24
  117. package/src/PrismicTable/types.ts +28 -15
  118. package/src/PrismicText.vue +3 -18
  119. package/src/SliceZone/SliceZone.vue +12 -41
  120. package/src/index.ts +13 -21
  121. package/src/types.ts +30 -438
  122. package/dist/PrismicEmbed.vue.d.cts +0 -25
  123. package/dist/PrismicEmbed.vue.d.cts.map +0 -1
  124. package/dist/createPrismic.d.cts +0 -29
  125. package/dist/createPrismic.d.cts.map +0 -1
  126. package/dist/src/PrismicEmbed.cjs +0 -8
  127. package/dist/src/PrismicEmbed.cjs.map +0 -1
  128. package/dist/src/PrismicEmbed.js +0 -8
  129. package/dist/src/PrismicEmbed.js.map +0 -1
  130. package/dist/src/PrismicEmbed.vue.d.ts +0 -25
  131. package/dist/src/PrismicEmbed.vue.d.ts.map +0 -1
  132. package/dist/src/PrismicEmbed.vue_vue_type_script_setup_true_lang.cjs +0 -42
  133. package/dist/src/PrismicEmbed.vue_vue_type_script_setup_true_lang.cjs.map +0 -1
  134. package/dist/src/PrismicEmbed.vue_vue_type_script_setup_true_lang.js +0 -42
  135. package/dist/src/PrismicEmbed.vue_vue_type_script_setup_true_lang.js.map +0 -1
  136. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.cjs +0 -8
  137. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.cjs.map +0 -1
  138. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.js +0 -8
  139. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.js.map +0 -1
  140. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.vue_vue_type_script_setup_true_lang.cjs +0 -92
  141. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.vue_vue_type_script_setup_true_lang.cjs.map +0 -1
  142. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.vue_vue_type_script_setup_true_lang.js +0 -92
  143. package/dist/src/PrismicRichText/DeprecatedPrismicRichText.vue_vue_type_script_setup_true_lang.js.map +0 -1
  144. package/dist/src/createPrismic.cjs +0 -85
  145. package/dist/src/createPrismic.cjs.map +0 -1
  146. package/dist/src/createPrismic.d.ts +0 -29
  147. package/dist/src/createPrismic.d.ts.map +0 -1
  148. package/dist/src/createPrismic.js +0 -85
  149. package/dist/src/createPrismic.js.map +0 -1
  150. package/dist/src/lib/Wrapper.cjs +0 -8
  151. package/dist/src/lib/Wrapper.cjs.map +0 -1
  152. package/dist/src/lib/Wrapper.js +0 -8
  153. package/dist/src/lib/Wrapper.js.map +0 -1
  154. package/dist/src/lib/Wrapper.vue_vue_type_script_setup_true_lang.cjs +0 -22
  155. package/dist/src/lib/Wrapper.vue_vue_type_script_setup_true_lang.cjs.map +0 -1
  156. package/dist/src/lib/Wrapper.vue_vue_type_script_setup_true_lang.js +0 -22
  157. package/dist/src/lib/Wrapper.vue_vue_type_script_setup_true_lang.js.map +0 -1
  158. package/dist/src/usePrismic.cjs +0 -38
  159. package/dist/src/usePrismic.cjs.map +0 -1
  160. package/dist/src/usePrismic.d.ts +0 -36
  161. package/dist/src/usePrismic.d.ts.map +0 -1
  162. package/dist/src/usePrismic.js +0 -37
  163. package/dist/src/usePrismic.js.map +0 -1
  164. package/dist/usePrismic.d.cts +0 -36
  165. package/dist/usePrismic.d.cts.map +0 -1
  166. package/src/PrismicEmbed.vue +0 -42
  167. package/src/PrismicRichText/DeprecatedPrismicRichText.vue +0 -146
  168. package/src/createPrismic.ts +0 -154
  169. package/src/lib/Wrapper.vue +0 -22
  170. package/src/usePrismic.ts +0 -36
@@ -1,83 +1,61 @@
1
1
  <script lang="ts" setup>
2
- import {
3
- type HTMLRichTextFunctionSerializer,
4
- type HTMLRichTextMapSerializer,
5
- type LinkResolverFunction,
6
- type RichTextField,
7
- isFilled,
2
+ import type {
3
+ LinkResolverFunction,
4
+ RichTextField,
5
+ RichTextNodeType,
8
6
  } from "@prismicio/client"
9
7
  import { asTree } from "@prismicio/client/richtext"
10
- import { DEV } from "esm-env"
11
8
  import type { PropType } from "vue"
12
- import { computed, watchEffect } from "vue"
9
+ import { computed } from "vue"
13
10
 
14
- import Wrapper from "../lib/Wrapper.vue"
11
+ import { type ComponentOrTagName, isVueComponent } from "../types"
12
+ import type {
13
+ InternalVueRichTextComponent,
14
+ VueRichTextSerializer,
15
+ VueShorthand,
16
+ } from "./types"
15
17
 
16
- import type { ComponentOrTagName } from "../types"
17
- import type { VueRichTextSerializer } from "./types"
18
-
19
- import { usePrismic } from "../usePrismic"
20
-
21
- import DeprecatedPrismicRichText from "./DeprecatedPrismicRichText.vue"
18
+ import PrismicRichTextDefaultComponent from "./PrismicRichTextDefaultComponent.vue"
22
19
  import PrismicRichTextSerialize from "./PrismicRichTextSerialize.vue"
23
20
 
24
21
  /**
25
22
  * Props for `<PrismicRichText />`.
26
23
  */
27
24
  export type PrismicRichTextProps = {
28
- /**
29
- * The Prismic rich text or title field to render.
30
- */
25
+ /** The Prismic rich text field to render. */
31
26
  field: RichTextField | null | undefined
32
27
 
33
28
  /**
34
- * The value to be rendered when the field is empty. If a fallback is not
35
- * given, `null` (nothing) will be rendered.
29
+ * The link resolver used to resolve links.
30
+ *
31
+ * @remarks
32
+ * If your app uses route resolvers when querying for your Prismic
33
+ * repository's content, a link resolver does not need to be provided.
34
+ *
35
+ * @see Learn about link resolvers and route resolvers {@link https://prismic.io/docs/routes}
36
36
  */
37
- fallback?: ComponentOrTagName
37
+ linkResolver?: LinkResolverFunction
38
38
 
39
39
  /**
40
- * An object that maps a rich text block type to a Vue component.
40
+ * An object that maps a rich text block type to a Vue component or a shorthand definition.
41
41
  *
42
42
  * @example
43
43
  *
44
44
  * ```javascript
45
45
  * {
46
46
  * heading1: Heading1,
47
+ * paragraph: { class: 'prose'},
48
+ * strong: { as: 'em', class: 'font-bold' },
47
49
  * }
48
50
  * ```
49
51
  */
50
52
  components?: VueRichTextSerializer
51
53
 
52
54
  /**
53
- * A link resolver function used to resolve link when not using the route
54
- * resolver parameter with `@prismicio/client`.
55
- *
56
- * @defaultValue The link resolver provided to `@prismicio/vue` plugin if configured.
57
- *
58
- * @see Link resolver documentation {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver#link-resolver}
59
- */
60
- linkResolver?: LinkResolverFunction
61
-
62
- /**
63
- * An HTML serializer to customize the way rich text fields are rendered.
64
- *
65
- * @deprecated Use `components` instead.
66
- *
67
- * @defaultValue The HTML serializer provided to `@prismicio/vue` plugin if configured.
68
- *
69
- * @see HTML serializer documentation {@link https://prismic.io/docs/core-concepts/html-serializer}
70
- */
71
- // TODO: Remove in v6
72
- serializer?: HTMLRichTextFunctionSerializer | HTMLRichTextMapSerializer
73
-
74
- /**
75
- * An HTML tag name or a component used to wrap the output. `<PrismicText />`
76
- * is not wrapped by default.
77
- *
78
- * @defaultValue `"template"` (no wrapper)
55
+ * The value to be rendered when the field is empty. If a fallback is not
56
+ * given, `null` will be rendered.
79
57
  */
80
- wrapper?: ComponentOrTagName
58
+ fallback?: ComponentOrTagName
81
59
  }
82
60
 
83
61
  // We're forced to declare props using the JavaScript syntax because `@vue/compiler-sfc`
@@ -86,98 +64,70 @@ const props = defineProps({
86
64
  field: {
87
65
  type: Array as unknown as PropType<PrismicRichTextProps["field"]>,
88
66
  },
89
- fallback: {
90
- type: [String, Object, Function] as PropType<
91
- PrismicRichTextProps["fallback"]
92
- >,
93
- },
94
- components: {
95
- type: Object as PropType<PrismicRichTextProps["components"]>,
96
- },
97
67
  linkResolver: {
98
68
  type: Function as PropType<PrismicRichTextProps["linkResolver"]>,
99
69
  },
100
- serializer: {
101
- type: [Object, Function] as PropType<PrismicRichTextProps["serializer"]>,
70
+ components: {
71
+ type: Object as PropType<PrismicRichTextProps["components"]>,
102
72
  },
103
- wrapper: {
73
+ fallback: {
104
74
  type: [String, Object, Function] as PropType<
105
- PrismicRichTextProps["wrapper"]
75
+ PrismicRichTextProps["fallback"]
106
76
  >,
107
77
  },
108
78
  })
109
79
  defineOptions({ name: "PrismicRichText" })
110
80
 
111
- const { options } = usePrismic()
112
-
113
- const resolvedComponents = computed(() => {
114
- return props.components || options.components?.richTextComponents
115
- })
116
-
117
- const resolvedLinkResolver = computed(() => {
118
- return props.linkResolver || options.linkResolver
119
- })
120
-
121
81
  const children = computed(() => {
122
82
  return asTree(props.field || []).children
123
83
  })
124
84
 
125
- const isModern = computed(() => {
126
- // Explicit components prop
127
- if (props.components) {
128
- return true
129
- }
85
+ function getInternalComponent(type: keyof typeof RichTextNodeType) {
86
+ const maybeComponentOrShorthand = props.components?.[type]
130
87
 
131
- // Explicit serializer prop
132
- if (props.serializer) {
133
- return false
88
+ if (isVueComponent(maybeComponentOrShorthand)) {
89
+ return { is: maybeComponentOrShorthand }
134
90
  }
135
91
 
136
- // Global components option
137
- if (options.components?.richTextComponents) {
138
- return true
92
+ return {
93
+ is: PrismicRichTextDefaultComponent,
94
+ props: {
95
+ linkResolver: props.linkResolver,
96
+ shorthand: maybeComponentOrShorthand as VueShorthand,
97
+ },
139
98
  }
99
+ }
140
100
 
141
- // Global serializer option
142
- if (options.richTextSerializer) {
143
- return false
101
+ const internalComponents = computed<InternalVueRichTextComponent>(() => {
102
+ return {
103
+ heading1: getInternalComponent("heading1"),
104
+ heading2: getInternalComponent("heading2"),
105
+ heading3: getInternalComponent("heading3"),
106
+ heading4: getInternalComponent("heading4"),
107
+ heading5: getInternalComponent("heading5"),
108
+ heading6: getInternalComponent("heading6"),
109
+ paragraph: getInternalComponent("paragraph"),
110
+ preformatted: getInternalComponent("preformatted"),
111
+ strong: getInternalComponent("strong"),
112
+ em: getInternalComponent("em"),
113
+ "list-item": getInternalComponent("listItem"),
114
+ "o-list-item": getInternalComponent("oListItem"),
115
+ "group-list-item": getInternalComponent("list"),
116
+ "group-o-list-item": getInternalComponent("oList"),
117
+ image: getInternalComponent("image"),
118
+ embed: getInternalComponent("embed"),
119
+ hyperlink: getInternalComponent("hyperlink"),
120
+ label: getInternalComponent("label"),
121
+ span: getInternalComponent("span"),
144
122
  }
145
-
146
- // Default to modern
147
- return true
148
123
  })
149
-
150
- if (DEV) {
151
- watchEffect(() => {
152
- // TODO: Remove in v6
153
- if (props.components && props.serializer) {
154
- console.warn(
155
- `[PrismicRichText] Only one of "components" or "serializer" (deprecated) props can be provided. You can resolve this warning by removing either the "components" or "serializer" prop. "components" will be used in this case.`,
156
- )
157
- }
158
- })
159
- }
160
124
  </script>
161
125
 
162
126
  <template>
163
- <Wrapper
164
- v-if="isModern && (isFilled.richText(field) || fallback)"
165
- :wrapper="wrapper"
166
- >
167
- <PrismicRichTextSerialize
168
- v-if="children.length"
169
- :children="children"
170
- :components="resolvedComponents"
171
- :link-resolver="resolvedLinkResolver"
172
- />
173
- <component v-else :is="fallback" />
174
- </Wrapper>
175
- <DeprecatedPrismicRichText
176
- v-else-if="!isModern"
177
- :field="field"
178
- :fallback="typeof fallback === 'string' ? fallback : undefined"
179
- :link-resolver="linkResolver"
180
- :serializer="serializer"
181
- :wrapper="wrapper"
127
+ <PrismicRichTextSerialize
128
+ v-if="children.length"
129
+ :children="children"
130
+ :internal-components="internalComponents"
182
131
  />
132
+ <component v-else-if="fallback" :is="fallback" />
183
133
  </template>
@@ -2,19 +2,31 @@
2
2
  import type { LinkResolverFunction } from "@prismicio/client"
3
3
  import { computed } from "vue"
4
4
 
5
- import type { RichTextComponentProps } from "./types"
5
+ import type { RichTextComponentProps, VueShorthand } from "./types"
6
6
 
7
- import PrismicEmbed from "../PrismicEmbed.vue"
8
7
  import PrismicImage from "../PrismicImage.vue"
9
8
  import PrismicLink from "../PrismicLink.vue"
10
9
 
11
10
  const props = defineProps<
12
11
  RichTextComponentProps & {
13
12
  linkResolver?: LinkResolverFunction
13
+ shorthand?: VueShorthand
14
14
  }
15
15
  >()
16
16
  defineOptions({ name: "PrismicRichTextDefaultComponent" })
17
17
 
18
+ const as = computed(() => {
19
+ return props.node.type !== "image" && props.node.type !== "span"
20
+ ? props.shorthand?.as
21
+ : undefined
22
+ })
23
+
24
+ const attrs = computed(() => {
25
+ const { as, ...attrs } = props.shorthand ?? {}
26
+
27
+ return attrs
28
+ })
29
+
18
30
  const dir = computed(() => {
19
31
  return "direction" in props.node && props.node.direction === "rtl"
20
32
  ? "rtl"
@@ -23,38 +35,68 @@ const dir = computed(() => {
23
35
  </script>
24
36
 
25
37
  <template>
26
- <h1 v-if="node.type === 'heading1'" :dir="dir"><slot /></h1>
27
- <h2 v-else-if="node.type === 'heading2'" :dir="dir"><slot /></h2>
28
- <h3 v-else-if="node.type === 'heading3'" :dir="dir"><slot /></h3>
29
- <h4 v-else-if="node.type === 'heading4'" :dir="dir"><slot /></h4>
30
- <h5 v-else-if="node.type === 'heading5'" :dir="dir"><slot /></h5>
31
- <h6 v-else-if="node.type === 'heading6'" :dir="dir"><slot /></h6>
32
- <p v-else-if="node.type === 'paragraph'" :dir="dir"><slot /></p>
33
- <pre v-else-if="node.type === 'preformatted'"><slot /></pre>
34
- <strong v-else-if="node.type === 'strong'"><slot /></strong>
35
- <em v-else-if="node.type === 'em'"><slot /></em>
36
- <li v-else-if="node.type === 'list-item'" :dir="dir"><slot /></li>
37
- <li v-else-if="node.type === 'o-list-item'" :dir="dir"><slot /></li>
38
- <ul v-else-if="node.type === 'group-list-item'">
38
+ <component v-if="as" :is="as" :dir="dir" v-bind="attrs"><slot /></component>
39
+ <h1 v-else-if="node.type === 'heading1'" :dir="dir" v-bind="attrs">
40
+ <slot />
41
+ </h1>
42
+ <h2 v-else-if="node.type === 'heading2'" :dir="dir" v-bind="attrs">
43
+ <slot />
44
+ </h2>
45
+ <h3 v-else-if="node.type === 'heading3'" :dir="dir" v-bind="attrs">
46
+ <slot />
47
+ </h3>
48
+ <h4 v-else-if="node.type === 'heading4'" :dir="dir" v-bind="attrs">
49
+ <slot />
50
+ </h4>
51
+ <h5 v-else-if="node.type === 'heading5'" :dir="dir" v-bind="attrs">
52
+ <slot />
53
+ </h5>
54
+ <h6 v-else-if="node.type === 'heading6'" :dir="dir" v-bind="attrs">
55
+ <slot />
56
+ </h6>
57
+ <p v-else-if="node.type === 'paragraph'" :dir="dir" v-bind="attrs">
58
+ <slot />
59
+ </p>
60
+ <pre v-else-if="node.type === 'preformatted'" v-bind="attrs"><slot /></pre>
61
+ <strong v-else-if="node.type === 'strong'" v-bind="attrs"><slot /></strong>
62
+ <em v-else-if="node.type === 'em'" v-bind="attrs"><slot /></em>
63
+ <li v-else-if="node.type === 'list-item'" :dir="dir" v-bind="attrs">
64
+ <slot />
65
+ </li>
66
+ <li v-else-if="node.type === 'o-list-item'" :dir="dir" v-bind="attrs">
67
+ <slot />
68
+ </li>
69
+ <ul v-else-if="node.type === 'group-list-item'" v-bind="attrs">
39
70
  <slot />
40
71
  </ul>
41
- <ol v-else-if="node.type === 'group-o-list-item'">
72
+ <ol v-else-if="node.type === 'group-o-list-item'" v-bind="attrs">
42
73
  <slot />
43
74
  </ol>
44
75
  <p class="block-img" v-else-if="node.type === 'image'">
45
76
  <PrismicLink v-if="node.linkTo" :field="node.linkTo"
46
77
  ><PrismicImage :field="node"
47
78
  /></PrismicLink>
48
- <PrismicImage v-else :field="node" />
79
+ <PrismicImage v-else :field="node" v-bind="attrs" />
49
80
  </p>
50
- <PrismicEmbed v-else-if="node.type === 'embed'" :field="node.oembed" />
81
+ <div
82
+ v-else-if="node.type === 'embed'"
83
+ :data-oembed="node.oembed.embed_url"
84
+ :data-oembed-type="node.oembed.type"
85
+ :data-oembed-provider="node.oembed.provider_name"
86
+ v-html="node.oembed.html"
87
+ v-bind="attrs"
88
+ />
51
89
  <PrismicLink
52
90
  v-else-if="node.type === 'hyperlink'"
53
91
  :field="node.data"
54
92
  :link-resolver="linkResolver"
93
+ v-bind="attrs"
55
94
  ><slot
56
95
  /></PrismicLink>
57
- <span v-else-if="node.type === 'label'" :class="node.data.label"
96
+ <span
97
+ v-else-if="node.type === 'label'"
98
+ :class="node.data.label"
99
+ v-bind="attrs"
58
100
  ><slot
59
101
  /></span>
60
102
  <template v-else v-for="(line, index) in node.text.split('\n')" :key="line"
@@ -1,52 +1,27 @@
1
1
  <script lang="ts" setup>
2
- import type { LinkResolverFunction } from "@prismicio/client"
3
2
  import type { asTree } from "@prismicio/client/richtext"
4
3
 
5
- import type { VueRichTextSerializer } from "./types"
6
-
7
- import PrismicRichTextDefaultComponent from "./PrismicRichTextDefaultComponent.vue"
8
-
9
- const CHILD_TYPE_RENAMES = {
10
- "list-item": "listItem",
11
- "o-list-item": "oListItem",
12
- "group-list-item": "list",
13
- "group-o-list-item": "oList",
14
- } as const
4
+ import type { InternalVueRichTextComponent } from "./types"
15
5
 
16
6
  type PrismicRichTextSerializeProps = {
17
- components?: VueRichTextSerializer
18
7
  children: ReturnType<typeof asTree>["children"]
19
- linkResolver?: LinkResolverFunction
8
+ internalComponents: InternalVueRichTextComponent
20
9
  }
21
10
 
22
11
  const props = defineProps<PrismicRichTextSerializeProps>()
23
12
  defineOptions({ name: "PrismicRichTextSerialize" })
24
-
25
- function getComponent(child: ReturnType<typeof asTree>["children"][number]) {
26
- return (
27
- props.components?.[
28
- CHILD_TYPE_RENAMES[child.type as keyof typeof CHILD_TYPE_RENAMES] ||
29
- (child.type as keyof typeof props.components)
30
- ] || PrismicRichTextDefaultComponent
31
- )
32
- }
33
13
  </script>
34
14
 
35
15
  <template>
36
16
  <component
37
17
  v-for="child in props.children"
38
18
  :key="JSON.stringify(child)"
39
- :is="getComponent(child)"
19
+ :is="internalComponents[child.type].is"
40
20
  :node="child.node"
41
- :link-resolver="
42
- getComponent(child) === PrismicRichTextDefaultComponent
43
- ? props.linkResolver
44
- : undefined
45
- "
21
+ v-bind="internalComponents[child.type].props"
46
22
  ><PrismicRichTextSerialize
47
23
  v-if="child.children.length"
48
24
  :children="child.children"
49
- :components="components"
50
- :link-resolver="linkResolver"
25
+ :internal-components="internalComponents"
51
26
  /></component>
52
27
  </template>
@@ -1,9 +1,10 @@
1
- import type { RTAnyNode, RichTextNodeType } from "@prismicio/client"
2
1
  import type {
3
- DefineComponent,
4
- FunctionalComponent,
5
- defineAsyncComponent,
6
- } from "vue"
2
+ LinkResolverFunction,
3
+ RTAnyNode,
4
+ RichTextNodeType,
5
+ } from "@prismicio/client"
6
+
7
+ import type { VueComponent } from "../types"
7
8
 
8
9
  /**
9
10
  * A map of Rich Text block types to Vue Components. It is used to render Rich
@@ -12,7 +13,7 @@ import type {
12
13
  * @see Templating Rich Text and title fields from Prismic {@link https://prismic.io/docs/rich-text}
13
14
  */
14
15
  export type VueRichTextSerializer = Partial<
15
- Record<keyof typeof RichTextNodeType, VueRichTextComponent>
16
+ Record<keyof typeof RichTextNodeType, VueRichTextComponent | VueShorthand>
16
17
  >
17
18
 
18
19
  /**
@@ -27,11 +28,29 @@ export type RichTextComponentProps<TRTNode extends RTAnyNode = RTAnyNode> = {
27
28
  *
28
29
  * @typeParam TRTNode - The type of rich text node(s) this component handles
29
30
  */
30
- type VueRichTextComponent<TRTNode extends RTAnyNode = RTAnyNode> =
31
- // For reference within TypeScript files when `*.vue` type cannot be inferred
32
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-explicit-any
33
- | DefineComponent<{}, {}, any>
34
- // Likewise, for reference with TypeScript files.
35
- | ReturnType<typeof defineAsyncComponent>
36
- | DefineComponent<RichTextComponentProps<TRTNode>>
37
- | FunctionalComponent<RichTextComponentProps<TRTNode>>
31
+ type VueRichTextComponent<TRTNode extends RTAnyNode = RTAnyNode> = VueComponent<
32
+ RichTextComponentProps<TRTNode>
33
+ >
34
+
35
+ /**
36
+ * A shorthand definition for {@link VueRichTextSerializer} component types.
37
+ */
38
+ export type VueShorthand = {
39
+ /**
40
+ * The HTML element type rendered for this node type.
41
+ */
42
+ as?: string
43
+
44
+ /**
45
+ * Other attributes to apply to the element type.
46
+ */
47
+ [Attribute: string]: string | boolean | null | undefined
48
+ }
49
+
50
+ export type InternalVueRichTextComponent = Record<
51
+ (typeof RichTextNodeType)[keyof typeof RichTextNodeType],
52
+ {
53
+ is: VueRichTextComponent
54
+ props?: { linkResolver?: LinkResolverFunction; shorthand?: VueShorthand }
55
+ }
56
+ >
@@ -2,8 +2,9 @@
2
2
  import { type TableField, isFilled } from "@prismicio/client"
3
3
  import { computed } from "vue"
4
4
 
5
- import type { ComponentOrTagName } from "../types"
6
- import type { VueTableComponents } from "./types"
5
+ import type { VueShorthand } from "../PrismicRichText/types"
6
+ import { type ComponentOrTagName, isVueComponent } from "../types"
7
+ import type { InternalVueTableComponents, VueTableComponents } from "./types"
7
8
 
8
9
  import type { VueRichTextSerializer } from "../PrismicRichText"
9
10
 
@@ -14,67 +15,93 @@ import PrismicTableRow from "./PrismicTableRow.vue"
14
15
  * Props for `<PrismicTable />`.
15
16
  */
16
17
  export type PrismicTableProps = {
17
- /**
18
- * The Prismic table field to render.
19
- */
18
+ /** The Prismic table field to render. */
20
19
  field: TableField | undefined
21
20
 
22
21
  /**
23
- * The value to be rendered when the field is empty. If a fallback is not
24
- * given, `null` (nothing) will be rendered.
25
- */
26
- fallback?: ComponentOrTagName
27
-
28
- /**
29
- * An object that maps a table block type to a Vue component.
22
+ * An object that maps a table block type to a Vue component or a shorthand definition.
30
23
  *
31
24
  * @example
32
25
  *
33
26
  * ```javascript
34
27
  * {
35
28
  * table: Table,
29
+ * thead: { class: 'bg-black text-white' },
30
+ * th: { as: 'td', class: 'font-bold' },
36
31
  * }
37
32
  * ```
38
33
  */
39
34
  components?: VueTableComponents & VueRichTextSerializer
35
+
36
+ /**
37
+ * The value to be rendered when the field is empty. If a fallback is not
38
+ * given, `null` (nothing) will be rendered.
39
+ */
40
+ fallback?: ComponentOrTagName
40
41
  }
41
42
 
42
43
  const props = defineProps<PrismicTableProps>()
43
44
  defineOptions({ name: "PrismicTable" })
44
45
 
45
- const mergedComponents = computed(() => ({
46
- ...defaultTableComponents,
47
- ...props.components,
48
- }))
46
+ function getInternalComponent(type: keyof VueTableComponents) {
47
+ const maybeComponentOrShorthand = props.components?.[type]
48
+
49
+ if (isVueComponent(maybeComponentOrShorthand)) {
50
+ return { is: maybeComponentOrShorthand }
51
+ }
52
+
53
+ return {
54
+ is: defaultTableComponents[type],
55
+ shorthand: maybeComponentOrShorthand as VueShorthand,
56
+ }
57
+ }
58
+
59
+ const tableComponents = computed<InternalVueTableComponents>(() => {
60
+ return {
61
+ table: getInternalComponent("table"),
62
+ thead: getInternalComponent("thead"),
63
+ tbody: getInternalComponent("tbody"),
64
+ tr: getInternalComponent("tr"),
65
+ th: getInternalComponent("th"),
66
+ td: getInternalComponent("td"),
67
+ }
68
+ })
49
69
  </script>
50
70
 
51
71
  <template>
52
72
  <component
53
73
  v-if="isFilled.table(field)"
54
- :is="mergedComponents.table"
74
+ :is="tableComponents.table.is"
55
75
  :table="field"
56
- v-bind="$attrs"
76
+ v-bind="{ ...$attrs, ...tableComponents.table.shorthand }"
57
77
  >
58
78
  <component
59
79
  v-if="field.head"
60
- :is="mergedComponents.thead"
80
+ :is="tableComponents.thead.is"
61
81
  :head="field.head"
82
+ v-bind="tableComponents.thead.shorthand"
62
83
  >
63
84
  <PrismicTableRow
64
85
  v-for="row in field.head.rows"
65
86
  :key="row.key"
66
87
  :row="row"
67
- :components="mergedComponents"
88
+ :internalTableComponents="tableComponents"
89
+ :components="components"
68
90
  />
69
91
  </component>
70
- <component :is="mergedComponents.tbody" :body="field.body">
92
+ <component
93
+ :is="tableComponents.tbody.is"
94
+ :body="field.body"
95
+ v-bind="tableComponents.tbody.shorthand"
96
+ >
71
97
  <PrismicTableRow
72
98
  v-for="row in field.body.rows"
73
99
  :key="row.key"
74
100
  :row="row"
75
- :components="mergedComponents"
101
+ :internalTableComponents="tableComponents"
102
+ :components="components"
76
103
  />
77
104
  </component>
78
105
  </component>
79
- <component v-else :is="fallback" />
106
+ <component v-else-if="fallback" :is="fallback" v-bind="$attrs" />
80
107
  </template>