@prismicio/react 2.5.2 → 2.6.0-alpha.1

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 (82) hide show
  1. package/dist/PrismicImage.cjs +7 -11
  2. package/dist/PrismicImage.cjs.map +1 -1
  3. package/dist/PrismicImage.d.ts +14 -15
  4. package/dist/PrismicImage.js +6 -10
  5. package/dist/PrismicImage.js.map +1 -1
  6. package/dist/PrismicLink.cjs +4 -66
  7. package/dist/PrismicLink.cjs.map +1 -1
  8. package/dist/PrismicLink.d.ts +5 -104
  9. package/dist/PrismicLink.js +4 -65
  10. package/dist/PrismicLink.js.map +1 -1
  11. package/dist/PrismicProvider.cjs.map +1 -1
  12. package/dist/PrismicProvider.d.ts +8 -9
  13. package/dist/PrismicProvider.js.map +1 -1
  14. package/dist/PrismicRichText.cjs +4 -71
  15. package/dist/PrismicRichText.cjs.map +1 -1
  16. package/dist/PrismicRichText.d.ts +4 -116
  17. package/dist/PrismicRichText.js +5 -70
  18. package/dist/PrismicRichText.js.map +1 -1
  19. package/dist/PrismicText.cjs +4 -4
  20. package/dist/PrismicText.cjs.map +1 -1
  21. package/dist/PrismicText.d.ts +2 -2
  22. package/dist/PrismicText.js +3 -3
  23. package/dist/PrismicText.js.map +1 -1
  24. package/dist/PrismicToolbar.cjs +6 -4
  25. package/dist/PrismicToolbar.cjs.map +1 -1
  26. package/dist/PrismicToolbar.d.ts +3 -1
  27. package/dist/PrismicToolbar.js +6 -4
  28. package/dist/PrismicToolbar.js.map +1 -1
  29. package/dist/SliceZone.cjs +4 -17
  30. package/dist/SliceZone.cjs.map +1 -1
  31. package/dist/SliceZone.d.ts +4 -65
  32. package/dist/SliceZone.js +4 -17
  33. package/dist/SliceZone.js.map +1 -1
  34. package/dist/index.cjs +0 -2
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.ts +2 -27
  37. package/dist/index.js +1 -4
  38. package/dist/index.js.map +1 -1
  39. package/dist/package.json.cjs +1 -1
  40. package/dist/package.json.js +1 -1
  41. package/dist/react-server/PrismicLink.cjs +59 -0
  42. package/dist/react-server/PrismicLink.cjs.map +1 -0
  43. package/dist/react-server/PrismicLink.d.ts +72 -0
  44. package/dist/react-server/PrismicLink.js +42 -0
  45. package/dist/react-server/PrismicLink.js.map +1 -0
  46. package/dist/react-server/PrismicRichText.cjs +92 -0
  47. package/dist/react-server/PrismicRichText.cjs.map +1 -0
  48. package/dist/react-server/PrismicRichText.d.ts +104 -0
  49. package/dist/react-server/PrismicRichText.js +73 -0
  50. package/dist/react-server/PrismicRichText.js.map +1 -0
  51. package/dist/react-server/index.d.ts +4 -0
  52. package/dist/react-server/unsupported.cjs +97 -0
  53. package/dist/react-server/unsupported.cjs.map +1 -0
  54. package/dist/react-server/unsupported.d.ts +22 -0
  55. package/dist/react-server/unsupported.js +97 -0
  56. package/dist/react-server/unsupported.js.map +1 -0
  57. package/dist/react-server.cjs +44 -0
  58. package/dist/react-server.cjs.map +1 -0
  59. package/dist/react-server.js +41 -0
  60. package/dist/react-server.js.map +1 -0
  61. package/dist/useStatefulPrismicClientMethod.cjs +6 -0
  62. package/dist/useStatefulPrismicClientMethod.cjs.map +1 -1
  63. package/dist/useStatefulPrismicClientMethod.d.ts +1 -1
  64. package/dist/useStatefulPrismicClientMethod.js +6 -0
  65. package/dist/useStatefulPrismicClientMethod.js.map +1 -1
  66. package/package.json +42 -47
  67. package/src/PrismicImage.tsx +30 -37
  68. package/src/PrismicLink.tsx +29 -258
  69. package/src/PrismicProvider.tsx +9 -8
  70. package/src/PrismicRichText.tsx +28 -275
  71. package/src/PrismicText.tsx +4 -5
  72. package/src/PrismicToolbar.tsx +7 -6
  73. package/src/SliceZone.tsx +8 -129
  74. package/src/index.ts +1 -9
  75. package/src/react-server/PrismicLink.tsx +179 -0
  76. package/src/react-server/PrismicRichText.tsx +267 -0
  77. package/src/react-server/index.ts +38 -0
  78. package/src/react-server/unsupported.ts +98 -0
  79. package/dist/lib/pascalCase.cjs +0 -10
  80. package/dist/lib/pascalCase.cjs.map +0 -1
  81. package/dist/lib/pascalCase.js +0 -10
  82. package/dist/lib/pascalCase.js.map +0 -1
@@ -1,4 +1,7 @@
1
+ "use client";
2
+
1
3
  import * as React from "react";
4
+ import { getToolbarSrc } from "@prismicio/client";
2
5
 
3
6
  /**
4
7
  * Props for `<PrismicToolbar>`.
@@ -13,6 +16,8 @@ export type PrismicToolbarProps = {
13
16
  /**
14
17
  * The type of toolbar needed for the repository. Defaults to `"new"`.
15
18
  *
19
+ * @deprecated All repositories use the "new"-type toolbar. This option can be
20
+ * removed.
16
21
  * @see To check which version you need, view the Prismic Toolbar documentation {@link https://prismic.io/docs/technologies/previews-and-the-prismic-toolbar-reactjs}
17
22
  */
18
23
  type?: "new" | "legacy";
@@ -24,11 +29,8 @@ export type PrismicToolbarProps = {
24
29
  */
25
30
  export const PrismicToolbar = ({
26
31
  repositoryName,
27
- type = "new",
28
32
  }: PrismicToolbarProps): null => {
29
- const src = `https://static.cdn.prismic.io/prismic.js?repo=${repositoryName}${
30
- type === "new" ? "&new=true" : ""
31
- }`;
33
+ const src = getToolbarSrc(repositoryName);
32
34
 
33
35
  React.useEffect(() => {
34
36
  const existingScript = document.querySelector(`script[src="${src}"]`);
@@ -41,7 +43,6 @@ export const PrismicToolbar = ({
41
43
  // Used to distinguish the toolbar element from other elements.
42
44
  script.dataset.prismicToolbar = "";
43
45
  script.dataset.repositoryName = repositoryName;
44
- script.dataset.type = type;
45
46
 
46
47
  // Disable Happy DOM `<script>` evaluation during
47
48
  // tests.
@@ -58,7 +59,7 @@ export const PrismicToolbar = ({
58
59
 
59
60
  document.body.appendChild(script);
60
61
  }
61
- }, [repositoryName, type, src]);
62
+ }, [repositoryName, src]);
62
63
 
63
64
  return null;
64
65
  };
package/src/SliceZone.tsx CHANGED
@@ -1,19 +1,7 @@
1
1
  import * as React from "react";
2
- import * as prismicT from "@prismicio/types";
2
+ import * as prismic from "@prismicio/client";
3
3
 
4
4
  import { __PRODUCTION__ } from "./lib/__PRODUCTION__";
5
- import { pascalCase, PascalCase } from "./lib/pascalCase";
6
-
7
- /**
8
- * Returns the type of a `SliceLike` type.
9
- *
10
- * @typeParam Slice - The Slice from which the type will be extracted.
11
- */
12
- type ExtractSliceType<Slice extends SliceLike> = Slice extends SliceLikeRestV2
13
- ? Slice["slice_type"]
14
- : Slice extends SliceLikeGraphQL
15
- ? Slice["type"]
16
- : never;
17
5
 
18
6
  /**
19
7
  * The minimum required properties to represent a Prismic Slice from the Prismic
@@ -25,7 +13,7 @@ type ExtractSliceType<Slice extends SliceLike> = Slice extends SliceLikeRestV2
25
13
  * @typeParam SliceType - Type name of the Slice.
26
14
  */
27
15
  export type SliceLikeRestV2<SliceType extends string = string> = {
28
- slice_type: prismicT.Slice<SliceType>["slice_type"];
16
+ slice_type: prismic.Slice<SliceType>["slice_type"];
29
17
  id?: string;
30
18
  };
31
19
 
@@ -36,7 +24,7 @@ export type SliceLikeRestV2<SliceType extends string = string> = {
36
24
  * @typeParam SliceType - Type name of the Slice.
37
25
  */
38
26
  export type SliceLikeGraphQL<SliceType extends string = string> = {
39
- type: prismicT.Slice<SliceType>["slice_type"];
27
+ type: prismic.Slice<SliceType>["slice_type"];
40
28
  };
41
29
 
42
30
  /**
@@ -115,37 +103,6 @@ export type SliceComponentType<
115
103
  TContext = unknown,
116
104
  > = React.ComponentType<SliceComponentProps<TSlice, TContext>>;
117
105
 
118
- /**
119
- * A record of Slice types mapped to a React component. The component will be
120
- * rendered for each instance of its Slice.
121
- *
122
- * @deprecated This type is no longer used by `@prismicio/react`. Prefer using
123
- * `Record<string, SliceComponentType<any>>` instead.
124
- * @typeParam TSlice - The type(s) of a Slice in the Slice Zone.
125
- * @typeParam TContext - Arbitrary data made available to all Slice components.
126
- */
127
- export type SliceZoneComponents<
128
- TSlice extends SliceLike = SliceLike,
129
- TContext = unknown,
130
- > =
131
- // This is purposely not wrapped in Partial to ensure a component is provided
132
- // for all Slice types. <SliceZone> will render a default component if one is
133
- // not provided, but it *should* be a type error if an explicit component is
134
- // missing.
135
- //
136
- // If a developer purposely does not want to provide a component, they can
137
- // assign it to the TODOSliceComponent exported from this package. This
138
- // signals to future developers that it is a placeholder and should be
139
- // implemented.
140
- {
141
- [SliceType in ExtractSliceType<TSlice>]: SliceComponentType<
142
- Extract<TSlice, SliceLike<SliceType>> extends never
143
- ? SliceLike
144
- : Extract<TSlice, SliceLike<SliceType>>,
145
- TContext
146
- >;
147
- };
148
-
149
106
  /**
150
107
  * This Slice component can be used as a reminder to provide a proper
151
108
  * implementation.
@@ -160,12 +117,9 @@ export const TODOSliceComponent = __PRODUCTION__
160
117
  }: SliceComponentProps<TSlice, TContext>): JSX.Element | null => {
161
118
  const type = "slice_type" in slice ? slice.slice_type : slice.type;
162
119
 
163
- React.useEffect(() => {
164
- console.warn(
165
- `[SliceZone] Could not find a component for Slice type "${type}"`,
166
- slice,
167
- );
168
- }, [slice, type]);
120
+ console.warn(
121
+ `[SliceZone] Could not find a component for Slice type "${type}"`,
122
+ );
169
123
 
170
124
  return (
171
125
  <section data-slice-zone-todo-component="" data-slice-type={type}>
@@ -175,54 +129,6 @@ export const TODOSliceComponent = __PRODUCTION__
175
129
  );
176
130
  };
177
131
 
178
- /**
179
- * Arguments for a `<SliceZone>` `resolver` function.
180
- */
181
- type SliceZoneResolverArgs<
182
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
- TSlice extends SliceLike = any,
184
- > = {
185
- /**
186
- * The Slice to resolve to a React component.
187
- */
188
- slice: TSlice;
189
-
190
- /**
191
- * The name of the Slice.
192
- */
193
- sliceName: PascalCase<ExtractSliceType<TSlice>>;
194
-
195
- /**
196
- * The index of the Slice in the Slice Zone.
197
- */
198
- i: number;
199
- };
200
-
201
- /**
202
- * A function that determines the rendered React component for each Slice in the
203
- * Slice Zone. If a nullish value is returned, the component will fallback to
204
- * the `components` or `defaultComponent` props to determine the rendered
205
- * component.
206
- *
207
- * @deprecated Use the `components` prop instead.
208
- *
209
- * @param args - Arguments for the resolver function.
210
- *
211
- * @returns The React component to render for a Slice.
212
- */
213
- export type SliceZoneResolver<
214
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
215
- TSlice extends SliceLike = any,
216
- TContext = unknown,
217
- > = (args: SliceZoneResolverArgs<TSlice>) =>
218
- | SliceComponentType<
219
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
220
- any,
221
- TContext
222
- >
223
- | undefined
224
- | null;
225
-
226
132
  /**
227
133
  * React props for the `<SliceZone>` component.
228
134
  *
@@ -241,19 +147,6 @@ export type SliceZoneProps<TContext = unknown> = {
241
147
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
242
148
  components?: Record<string, SliceComponentType<any, TContext>>;
243
149
 
244
- /**
245
- * A function that determines the rendered React component for each Slice in
246
- * the Slice Zone.
247
- *
248
- * @deprecated Use the `components` prop instead.
249
- *
250
- * @param args - Arguments for the resolver function.
251
- *
252
- * @returns The React component to render for a Slice.
253
- */
254
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
255
- resolver?: SliceZoneResolver<any, TContext>;
256
-
257
150
  /**
258
151
  * The React component rendered if a component mapping from the `components`
259
152
  * prop cannot be found.
@@ -285,7 +178,6 @@ export type SliceZoneProps<TContext = unknown> = {
285
178
  export const SliceZone = <TContext,>({
286
179
  slices = [],
287
180
  components = {},
288
- resolver,
289
181
  defaultComponent = TODOSliceComponent,
290
182
  context = {} as TContext,
291
183
  }: SliceZoneProps<TContext>): JSX.Element => {
@@ -293,22 +185,9 @@ export const SliceZone = <TContext,>({
293
185
  return slices.map((slice, index) => {
294
186
  const type = "slice_type" in slice ? slice.slice_type : slice.type;
295
187
 
296
- let Comp =
188
+ const Comp =
297
189
  components[type as keyof typeof components] || defaultComponent;
298
190
 
299
- // TODO: Remove `resolver` in v3 in favor of `components`.
300
- if (resolver) {
301
- const resolvedComp = resolver({
302
- slice,
303
- sliceName: pascalCase(type),
304
- i: index,
305
- });
306
-
307
- if (resolvedComp) {
308
- Comp = resolvedComp as typeof Comp;
309
- }
310
- }
311
-
312
191
  const key =
313
192
  "id" in slice && slice.id
314
193
  ? slice.id
@@ -324,7 +203,7 @@ export const SliceZone = <TContext,>({
324
203
  />
325
204
  );
326
205
  });
327
- }, [components, context, defaultComponent, slices, resolver]);
206
+ }, [components, context, defaultComponent, slices]);
328
207
 
329
208
  return <>{renderedSlices}</>;
330
209
  };
package/src/index.ts CHANGED
@@ -17,13 +17,7 @@ export type { PrismicTextProps } from "./PrismicText";
17
17
  export { PrismicRichText } from "./PrismicRichText";
18
18
  export type { PrismicRichTextProps } from "./PrismicRichText";
19
19
 
20
- import { Element } from "@prismicio/richtext";
21
- export { Element };
22
- /**
23
- * @deprecated Renamed to `Element` (without an "s").
24
- */
25
- // TODO: Remove in v3.
26
- export const Elements = Element;
20
+ export { Element } from "@prismicio/richtext";
27
21
 
28
22
  export { PrismicImage } from "./PrismicImage";
29
23
  export type { PrismicImageProps } from "./PrismicImage";
@@ -35,10 +29,8 @@ export type {
35
29
  SliceLikeRestV2,
36
30
  SliceLikeGraphQL,
37
31
  SliceLike,
38
- SliceZoneComponents,
39
32
  SliceZoneLike,
40
33
  SliceZoneProps,
41
- SliceZoneResolver,
42
34
  } from "./SliceZone";
43
35
 
44
36
  export { PrismicToolbar } from "./PrismicToolbar";
@@ -0,0 +1,179 @@
1
+ import * as React from "react";
2
+ import {
3
+ LinkField,
4
+ LinkResolverFunction,
5
+ PrismicDocument,
6
+ asLinkAttrs,
7
+ AsLinkAttrsConfig,
8
+ } from "@prismicio/client";
9
+
10
+ import { __PRODUCTION__ } from "../lib/__PRODUCTION__";
11
+ import { devMsg } from "../lib/devMsg";
12
+ import { isInternalURL } from "../lib/isInternalURL";
13
+
14
+ /**
15
+ * The default component rendered for internal and external links.
16
+ */
17
+ export const defaultComponent = "a";
18
+
19
+ /**
20
+ * Props provided to a component when rendered with `<PrismicLink>`.
21
+ */
22
+ export interface LinkProps {
23
+ /**
24
+ * The URL to link.
25
+ */
26
+ href: string;
27
+
28
+ /**
29
+ * The `target` attribute for anchor elements. If the Prismic field is
30
+ * configured to open in a new window, this prop defaults to `_blank`.
31
+ */
32
+ target?: React.HTMLAttributeAnchorTarget;
33
+
34
+ /**
35
+ * The `rel` attribute for anchor elements. If the `target` prop is set to
36
+ * `"_blank"`, this prop defaults to `"noopener noreferrer"`.
37
+ */
38
+ rel?: string;
39
+
40
+ /**
41
+ * Children for the component. *
42
+ */
43
+ children?: React.ReactNode;
44
+ }
45
+
46
+ export type PrismicLinkProps<
47
+ InternalComponentProps = React.ComponentProps<typeof defaultComponent>,
48
+ ExternalComponentProps = React.ComponentProps<typeof defaultComponent>,
49
+ > = Omit<InternalComponentProps & ExternalComponentProps, "rel" | "href"> & {
50
+ /**
51
+ * The `rel` attribute for the link. By default, `"noreferrer"` is provided if
52
+ * the link's URL is external. This prop can be provided a function to use the
53
+ * link's metadata to determine the `rel` value.
54
+ */
55
+ rel?: string | AsLinkAttrsConfig["rel"];
56
+
57
+ /**
58
+ * The Link Resolver used to resolve links.
59
+ *
60
+ * @remarks
61
+ * If your app uses Route Resolvers when querying for your Prismic
62
+ * repository's content, a Link Resolver does not need to be provided.
63
+ * @see Learn about Link Resolvers and Route Resolvers {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver}
64
+ */
65
+ linkResolver?: LinkResolverFunction;
66
+
67
+ /**
68
+ * The component rendered for internal URLs. Defaults to `<a>`.
69
+ *
70
+ * If your app uses a client-side router that requires a special Link
71
+ * component, provide the Link component to this prop.
72
+ */
73
+ internalComponent?: React.ElementType<InternalComponentProps>;
74
+
75
+ /**
76
+ * The component rendered for external URLs. Defaults to `<a>`.
77
+ */
78
+ externalComponent?: React.ComponentType<ExternalComponentProps>;
79
+ } & (
80
+ | {
81
+ document: PrismicDocument | null | undefined;
82
+ href?: never;
83
+ field?: never;
84
+ }
85
+ | {
86
+ field: LinkField | null | undefined;
87
+ href?: never;
88
+ document?: never;
89
+ }
90
+ | {
91
+ href: LinkProps["href"];
92
+ field?: LinkField | null | undefined;
93
+ document?: never;
94
+ }
95
+ );
96
+
97
+ export const PrismicLink = React.forwardRef(function PrismicLink<
98
+ InternalComponentProps = React.ComponentProps<typeof defaultComponent>,
99
+ ExternalComponentProps = React.ComponentProps<typeof defaultComponent>,
100
+ >(
101
+ {
102
+ field,
103
+ document: doc,
104
+ linkResolver,
105
+ internalComponent,
106
+ externalComponent,
107
+ ...restProps
108
+ }: PrismicLinkProps<InternalComponentProps, ExternalComponentProps>,
109
+ ref: React.ForwardedRef<Element>,
110
+ ): JSX.Element {
111
+ if (!__PRODUCTION__) {
112
+ if (field) {
113
+ if (!field.link_type) {
114
+ console.error(
115
+ `[PrismicLink] This "field" prop value caused an error to be thrown.\n`,
116
+ field,
117
+ );
118
+ throw new Error(
119
+ `[PrismicLink] The provided field is missing required properties to properly render a link. The link will not render. For more details, see ${devMsg(
120
+ "missing-link-properties",
121
+ )}`,
122
+ );
123
+ } else if (
124
+ Object.keys(field).length > 1 &&
125
+ !("url" in field || "uid" in field || "id" in field)
126
+ ) {
127
+ console.warn(
128
+ `[PrismicLink] The provided field is missing required properties to properly render a link. The link may not render correctly. For more details, see ${devMsg(
129
+ "missing-link-properties",
130
+ )}`,
131
+ field,
132
+ );
133
+ }
134
+ } else if (doc) {
135
+ if (!("url" in doc || "id" in doc)) {
136
+ console.warn(
137
+ `[PrismicLink] The provided document is missing required properties to properly render a link. The link may not render correctly. For more details, see ${devMsg(
138
+ "missing-link-properties",
139
+ )}`,
140
+ doc,
141
+ );
142
+ }
143
+ }
144
+ }
145
+
146
+ const {
147
+ href: computedHref,
148
+ rel: computedRel,
149
+ ...attrs
150
+ } = asLinkAttrs(field ?? doc, {
151
+ linkResolver,
152
+ rel: typeof restProps.rel === "function" ? restProps.rel : undefined,
153
+ });
154
+
155
+ let rel: string | undefined = computedRel;
156
+ if ("rel" in restProps && typeof restProps.rel !== "function") {
157
+ rel = restProps.rel;
158
+ }
159
+
160
+ const href = ("href" in restProps ? restProps.href : computedHref) || "";
161
+
162
+ const InternalComponent = (internalComponent ||
163
+ defaultComponent) as React.ComponentType<LinkProps>;
164
+ const ExternalComponent = (externalComponent ||
165
+ defaultComponent) as React.ComponentType<LinkProps>;
166
+ const Component =
167
+ href && isInternalURL(href) ? InternalComponent : ExternalComponent;
168
+
169
+ return (
170
+ <Component ref={ref} {...attrs} {...restProps} href={href} rel={rel} />
171
+ );
172
+ }) as <
173
+ InternalComponentProps = React.ComponentProps<typeof defaultComponent>,
174
+ ExternalComponentProps = React.ComponentProps<typeof defaultComponent>,
175
+ >(
176
+ props: PrismicLinkProps<InternalComponentProps, ExternalComponentProps> & {
177
+ ref?: React.ForwardedRef<Element>;
178
+ },
179
+ ) => JSX.Element;