@prismicio/react 2.6.2 → 2.7.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/src/SliceZone.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import * as React from "react";
1
+ import { ComponentType } from "react";
2
2
  import * as prismic from "@prismicio/client";
3
3
 
4
4
  import { pascalCase, PascalCase } from "./lib/pascalCase";
@@ -8,55 +8,61 @@ import { pascalCase, PascalCase } from "./lib/pascalCase";
8
8
  *
9
9
  * @typeParam Slice - The Slice from which the type will be extracted.
10
10
  */
11
- type ExtractSliceType<Slice extends SliceLike> = Slice extends SliceLikeRestV2
12
- ? Slice["slice_type"]
13
- : Slice extends SliceLikeGraphQL
14
- ? Slice["type"]
11
+ type ExtractSliceType<TSlice extends SliceLike> = TSlice extends prismic.Slice
12
+ ? TSlice["slice_type"]
13
+ : TSlice extends SliceLikeGraphQL
14
+ ? TSlice["type"]
15
15
  : never;
16
16
 
17
17
  /**
18
18
  * The minimum required properties to represent a Prismic Slice from the Prismic
19
- * Rest API V2 for the `<SliceZone>` component.
20
- *
21
- * If using Prismic's Rest API V2, use the `Slice` export from
22
- * `@prismicio/types` for a full interface.
19
+ * Rest API V2 for the `unstable_mapSliceZone()` helper.
23
20
  *
24
21
  * @typeParam SliceType - Type name of the Slice.
25
22
  */
26
- export type SliceLikeRestV2<SliceType extends string = string> = {
27
- slice_type: prismic.Slice<SliceType>["slice_type"];
28
- id?: string;
29
- };
23
+ export type SliceLikeRestV2<TSliceType extends string = string> = Pick<
24
+ prismic.Slice<TSliceType>,
25
+ "id" | "slice_type"
26
+ >;
30
27
 
31
28
  /**
32
29
  * The minimum required properties to represent a Prismic Slice from the Prismic
33
- * GraphQL API for the `<SliceZone>` component.
30
+ * GraphQL API for the `unstable_mapSliceZone()` helper.
34
31
  *
35
32
  * @typeParam SliceType - Type name of the Slice.
36
33
  */
37
- export type SliceLikeGraphQL<SliceType extends string = string> = {
38
- type: prismic.Slice<SliceType>["slice_type"];
34
+ export type SliceLikeGraphQL<TSliceType extends string = string> = {
35
+ type: prismic.Slice<TSliceType>["slice_type"];
39
36
  };
40
37
 
41
38
  /**
42
39
  * The minimum required properties to represent a Prismic Slice for the
43
- * `<SliceZone>` component.
40
+ * `unstable_mapSliceZone()` helper.
44
41
  *
45
42
  * If using Prismic's Rest API V2, use the `Slice` export from
46
- * `@prismicio/types` for a full interface.
43
+ * `@prismicio/client` for a full interface.
47
44
  *
48
45
  * @typeParam SliceType - Type name of the Slice.
49
46
  */
50
- export type SliceLike<SliceType extends string = string> =
51
- | SliceLikeRestV2<SliceType>
52
- | SliceLikeGraphQL<SliceType>;
47
+ export type SliceLike<TSliceType extends string = string> = (
48
+ | SliceLikeRestV2<TSliceType>
49
+ | SliceLikeGraphQL<TSliceType>
50
+ ) & {
51
+ /**
52
+ * If `true`, this Slice has been modified from its original value using a
53
+ * mapper and `@prismicio/client`'s `mapSliceZone()`.
54
+ *
55
+ * @internal
56
+ */
57
+ __mapped?: true;
58
+ };
53
59
 
54
60
  /**
55
- * A looser version of the `SliceZone` type from `@prismicio/types` using
61
+ * A looser version of the `SliceZone` type from `@prismicio/client` using
56
62
  * `SliceLike`.
57
63
  *
58
64
  * If using Prismic's Rest API V2, use the `SliceZone` export from
59
- * `@prismicio/types` for the full type.
65
+ * `@prismicio/client` for the full type.
60
66
  *
61
67
  * @typeParam TSlice - The type(s) of a Slice in the Slice Zone.
62
68
  */
@@ -73,7 +79,7 @@ export type SliceZoneLike<TSlice extends SliceLike = SliceLike> =
73
79
  */
74
80
  export type SliceComponentProps<
75
81
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
- TSlice extends SliceLike = any,
82
+ TSlice extends SliceLike = SliceLike,
77
83
  TContext = unknown,
78
84
  > = {
79
85
  /**
@@ -93,7 +99,9 @@ export type SliceComponentProps<
93
99
  // reference limtiations. If we had another generic to determine the full
94
100
  // union of Slice types, it would include TSlice. This causes TypeScript to
95
101
  // throw a compilation error.
96
- slices: SliceZoneLike<SliceLike>;
102
+ slices: SliceZoneLike<
103
+ TSlice extends SliceLikeGraphQL ? SliceLikeGraphQL : SliceLikeRestV2
104
+ >;
97
105
 
98
106
  /**
99
107
  * Arbitrary data passed to `<SliceZone>` and made available to all Slice
@@ -145,38 +153,6 @@ export type SliceZoneComponents<
145
153
  >;
146
154
  };
147
155
 
148
- /**
149
- * This Slice component can be used as a reminder to provide a proper
150
- * implementation.
151
- *
152
- * This is also the default React component rendered when a component mapping
153
- * cannot be found in `<SliceZone>`.
154
- */
155
- export const TODOSliceComponent = <TSlice extends SliceLike, TContext>({
156
- slice,
157
- }: SliceComponentProps<TSlice, TContext>): JSX.Element | null => {
158
- if (
159
- typeof process !== "undefined" &&
160
- process.env.NODE_ENV === "development"
161
- ) {
162
- const type = "slice_type" in slice ? slice.slice_type : slice.type;
163
-
164
- console.warn(
165
- `[SliceZone] Could not find a component for Slice type "${type}"`,
166
- slice,
167
- );
168
-
169
- return (
170
- <section data-slice-zone-todo-component="" data-slice-type={type}>
171
- Could not find a component for Slice type &ldquo;{type}
172
- &rdquo;
173
- </section>
174
- );
175
- } else {
176
- return null;
177
- }
178
- };
179
-
180
156
  /**
181
157
  * Arguments for a `<SliceZone>` `resolver` function.
182
158
  */
@@ -215,15 +191,10 @@ type SliceZoneResolverArgs<
215
191
  export type SliceZoneResolver<
216
192
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
217
193
  TSlice extends SliceLike = any,
218
- TContext = unknown,
219
- > = (args: SliceZoneResolverArgs<TSlice>) =>
220
- | SliceComponentType<
221
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
222
- any,
223
- TContext
224
- >
225
- | undefined
226
- | null;
194
+ > = (
195
+ args: SliceZoneResolverArgs<TSlice>,
196
+ ) => // eslint-disable-next-line @typescript-eslint/no-explicit-any
197
+ ComponentType<any> | undefined | null;
227
198
 
228
199
  /**
229
200
  * React props for the `<SliceZone>` component.
@@ -241,7 +212,7 @@ export type SliceZoneProps<TContext = unknown> = {
241
212
  * A record mapping Slice types to React components.
242
213
  */
243
214
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
244
- components?: Record<string, SliceComponentType<any, TContext>>;
215
+ components?: Record<string, ComponentType<any>>;
245
216
 
246
217
  /**
247
218
  * A function that determines the rendered React component for each Slice in
@@ -254,14 +225,14 @@ export type SliceZoneProps<TContext = unknown> = {
254
225
  * @returns The React component to render for a Slice.
255
226
  */
256
227
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
257
- resolver?: SliceZoneResolver<any, TContext>;
228
+ resolver?: SliceZoneResolver<any>;
258
229
 
259
230
  /**
260
231
  * The React component rendered if a component mapping from the `components`
261
232
  * prop cannot be found.
262
233
  */
263
234
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
264
- defaultComponent?: SliceComponentType<any, TContext>;
235
+ defaultComponent?: ComponentType<SliceComponentProps<any, TContext>>;
265
236
 
266
237
  /**
267
238
  * Arbitrary data made available to all Slice components.
@@ -269,6 +240,38 @@ export type SliceZoneProps<TContext = unknown> = {
269
240
  context?: TContext;
270
241
  };
271
242
 
243
+ /**
244
+ * This Slice component can be used as a reminder to provide a proper
245
+ * implementation.
246
+ *
247
+ * This is also the default React component rendered when a component mapping
248
+ * cannot be found in `<SliceZone>`.
249
+ */
250
+ export const TODOSliceComponent = <TSlice extends SliceLike, TContext>({
251
+ slice,
252
+ }: SliceComponentProps<TSlice, TContext>): JSX.Element | null => {
253
+ if (
254
+ typeof process !== "undefined" &&
255
+ process.env.NODE_ENV === "development"
256
+ ) {
257
+ const type = "slice_type" in slice ? slice.slice_type : slice.type;
258
+
259
+ console.warn(
260
+ `[SliceZone] Could not find a component for Slice type "${type}"`,
261
+ slice,
262
+ );
263
+
264
+ return (
265
+ <section data-slice-zone-todo-component="" data-slice-type={type}>
266
+ Could not find a component for Slice type &ldquo;{type}
267
+ &rdquo;
268
+ </section>
269
+ );
270
+ } else {
271
+ return null;
272
+ }
273
+ };
274
+
272
275
  /**
273
276
  * Renders content from a Prismic Slice Zone using React components for each
274
277
  * type of Slice.
@@ -284,38 +287,50 @@ export type SliceZoneProps<TContext = unknown> = {
284
287
  *
285
288
  * @see Learn about Prismic Slices and Slice Zones {@link https://prismic.io/docs/core-concepts/slices}
286
289
  */
287
- export const SliceZone = <TContext,>({
290
+ export function SliceZone<TContext>({
288
291
  slices = [],
289
292
  components = {},
290
293
  resolver,
291
294
  defaultComponent = TODOSliceComponent,
292
295
  context = {} as TContext,
293
- }: SliceZoneProps<TContext>): JSX.Element => {
294
- const renderedSlices = React.useMemo(() => {
295
- return slices.map((slice, index) => {
296
- const type = "slice_type" in slice ? slice.slice_type : slice.type;
297
-
298
- let Comp =
299
- components[type as keyof typeof components] || defaultComponent;
300
-
301
- // TODO: Remove `resolver` in v3 in favor of `components`.
302
- if (resolver) {
303
- const resolvedComp = resolver({
304
- slice,
305
- sliceName: pascalCase(type),
306
- i: index,
307
- });
308
-
309
- if (resolvedComp) {
310
- Comp = resolvedComp as typeof Comp;
311
- }
296
+ }: SliceZoneProps<TContext>) {
297
+ // TODO: Remove in v3 when the `resolver` prop is removed.
298
+ if (process.env.NODE_ENV === "development") {
299
+ if (resolver) {
300
+ console.warn(
301
+ "The `resolver` prop is deprecated. Please replace it with a components map using the `components` prop.",
302
+ );
303
+ }
304
+ }
305
+
306
+ const renderedSlices = slices.map((slice, index) => {
307
+ const type = "slice_type" in slice ? slice.slice_type : slice.type;
308
+
309
+ let Comp = components[type as keyof typeof components] || defaultComponent;
310
+
311
+ // TODO: Remove `resolver` in v3 in favor of `components`.
312
+ if (resolver) {
313
+ const resolvedComp = resolver({
314
+ slice,
315
+ sliceName: pascalCase(type),
316
+ i: index,
317
+ });
318
+
319
+ if (resolvedComp) {
320
+ Comp = resolvedComp as typeof Comp;
312
321
  }
322
+ }
313
323
 
314
- const key =
315
- "id" in slice && slice.id
316
- ? slice.id
317
- : `${index}-${JSON.stringify(slice)}`;
324
+ const key =
325
+ "id" in slice && slice.id
326
+ ? slice.id
327
+ : `${index}-${JSON.stringify(slice)}`;
318
328
 
329
+ if (slice.__mapped) {
330
+ const { __mapped, ...mappedProps } = slice;
331
+
332
+ return <Comp key={key} {...mappedProps} />;
333
+ } else {
319
334
  return (
320
335
  <Comp
321
336
  key={key}
@@ -325,8 +340,8 @@ export const SliceZone = <TContext,>({
325
340
  context={context}
326
341
  />
327
342
  );
328
- });
329
- }, [components, context, defaultComponent, slices, resolver]);
343
+ }
344
+ });
330
345
 
331
346
  return <>{renderedSlices}</>;
332
- };
347
+ }
@@ -1,4 +1,4 @@
1
- import type * as prismicT from "@prismicio/types";
1
+ import type * as prismic from "@prismicio/client";
2
2
 
3
3
  import {
4
4
  ClientHookReturnType,
@@ -21,9 +21,9 @@ import {
21
21
  *
22
22
  * @see Underlying `@prismicio/client` method {@link proto.get}
23
23
  */
24
- export const usePrismicDocuments = <TDocument extends prismicT.PrismicDocument>(
24
+ export const usePrismicDocuments = <TDocument extends prismic.PrismicDocument>(
25
25
  ...args: [params?: ClientMethodParameters<"get">[0] & HookOnlyParameters]
26
- ): ClientHookReturnType<prismicT.Query<TDocument>> =>
26
+ ): ClientHookReturnType<prismic.Query<TDocument>> =>
27
27
  useStatefulPrismicClientMethod("get", args);
28
28
 
29
29
  /**
@@ -42,7 +42,7 @@ export const usePrismicDocuments = <TDocument extends prismicT.PrismicDocument>(
42
42
  * @see Underlying `@prismicio/client` method {@link proto.getFirst}
43
43
  */
44
44
  export const useFirstPrismicDocument = <
45
- TDocument extends prismicT.PrismicDocument,
45
+ TDocument extends prismic.PrismicDocument,
46
46
  >(
47
47
  ...args: [params?: ClientMethodParameters<"getFirst">[0] & HookOnlyParameters]
48
48
  ): ClientHookReturnType<TDocument> =>
@@ -65,7 +65,7 @@ export const useFirstPrismicDocument = <
65
65
  * @see Underlying `@prismicio/client` method {@link proto.getAll}
66
66
  */
67
67
  export const useAllPrismicDocumentsDangerously = <
68
- TDocument extends prismicT.PrismicDocument,
68
+ TDocument extends prismic.PrismicDocument,
69
69
  >(
70
70
  ...args: [
71
71
  params?: ClientMethodParameters<"dangerouslyGetAll">[0] &
@@ -91,7 +91,7 @@ export const useAllPrismicDocumentsDangerously = <
91
91
  * @see Underlying `@prismicio/client` method {@link proto.getByID}
92
92
  */
93
93
  export const usePrismicDocumentByID = <
94
- TDocument extends prismicT.PrismicDocument,
94
+ TDocument extends prismic.PrismicDocument,
95
95
  >(
96
96
  ...args: [
97
97
  id: ClientMethodParameters<"getByID">[0],
@@ -116,13 +116,13 @@ export const usePrismicDocumentByID = <
116
116
  * @see Underlying `@prismicio/client` method {@link proto.getByIDs}
117
117
  */
118
118
  export const usePrismicDocumentsByIDs = <
119
- TDocument extends prismicT.PrismicDocument,
119
+ TDocument extends prismic.PrismicDocument,
120
120
  >(
121
121
  ...args: [
122
122
  id: ClientMethodParameters<"getByIDs">[0],
123
123
  params?: ClientMethodParameters<"getByIDs">[1] & HookOnlyParameters,
124
124
  ]
125
- ): ClientHookReturnType<prismicT.Query<TDocument>> =>
125
+ ): ClientHookReturnType<prismic.Query<TDocument>> =>
126
126
  useStatefulPrismicClientMethod("getByIDs", args);
127
127
 
128
128
  /**
@@ -142,7 +142,7 @@ export const usePrismicDocumentsByIDs = <
142
142
  * @see Underlying `@prismicio/client` method {@link proto.getAllByIDs}
143
143
  */
144
144
  export const useAllPrismicDocumentsByIDs = <
145
- TDocument extends prismicT.PrismicDocument,
145
+ TDocument extends prismic.PrismicDocument,
146
146
  >(
147
147
  ...args: [
148
148
  id: ClientMethodParameters<"getAllByIDs">[0],
@@ -169,7 +169,7 @@ export const useAllPrismicDocumentsByIDs = <
169
169
  * @see Underlying `@prismicio/client` method {@link proto.getByUID}
170
170
  */
171
171
  export const usePrismicDocumentByUID = <
172
- TDocument extends prismicT.PrismicDocument,
172
+ TDocument extends prismic.PrismicDocument,
173
173
  >(
174
174
  ...args: [
175
175
  documentType: ClientMethodParameters<"getByUID">[0],
@@ -197,14 +197,14 @@ export const usePrismicDocumentByUID = <
197
197
  * @see Underlying `@prismicio/client` method {@link proto.getByUID}
198
198
  */
199
199
  export const usePrismicDocumentsByUIDs = <
200
- TDocument extends prismicT.PrismicDocument,
200
+ TDocument extends prismic.PrismicDocument,
201
201
  >(
202
202
  ...args: [
203
203
  documentType: ClientMethodParameters<"getByUIDs">[0],
204
204
  uids: ClientMethodParameters<"getByUIDs">[1],
205
205
  params?: ClientMethodParameters<"getByUIDs">[2] & HookOnlyParameters,
206
206
  ]
207
- ): ClientHookReturnType<prismicT.Query<TDocument>> =>
207
+ ): ClientHookReturnType<prismic.Query<TDocument>> =>
208
208
  useStatefulPrismicClientMethod("getByUIDs", args);
209
209
 
210
210
  /**
@@ -225,7 +225,7 @@ export const usePrismicDocumentsByUIDs = <
225
225
  * @see Underlying `@prismicio/client` method {@link proto.getByUID}
226
226
  */
227
227
  export const useAllPrismicDocumentsByUIDs = <
228
- TDocument extends prismicT.PrismicDocument,
228
+ TDocument extends prismic.PrismicDocument,
229
229
  >(
230
230
  ...args: [
231
231
  documentType: ClientMethodParameters<"getByUIDs">[0],
@@ -252,7 +252,7 @@ export const useAllPrismicDocumentsByUIDs = <
252
252
  * @see Underlying `@prismicio/client` method {@link proto.getSingle}
253
253
  */
254
254
  export const useSinglePrismicDocument = <
255
- TDocument extends prismicT.PrismicDocument,
255
+ TDocument extends prismic.PrismicDocument,
256
256
  >(
257
257
  ...args: [
258
258
  documentType: ClientMethodParameters<"getSingle">[0],
@@ -278,13 +278,13 @@ export const useSinglePrismicDocument = <
278
278
  * @see Underlying `@prismicio/client` method {@link proto.getByType}
279
279
  */
280
280
  export const usePrismicDocumentsByType = <
281
- TDocument extends prismicT.PrismicDocument,
281
+ TDocument extends prismic.PrismicDocument,
282
282
  >(
283
283
  ...args: [
284
284
  documentType: ClientMethodParameters<"getByType">[0],
285
285
  params?: ClientMethodParameters<"getByType">[1] & HookOnlyParameters,
286
286
  ]
287
- ): ClientHookReturnType<prismicT.Query<TDocument>> =>
287
+ ): ClientHookReturnType<prismic.Query<TDocument>> =>
288
288
  useStatefulPrismicClientMethod("getByType", args);
289
289
 
290
290
  /**
@@ -304,7 +304,7 @@ export const usePrismicDocumentsByType = <
304
304
  * @see Underlying `@prismicio/client` method {@link proto.getAllByType}
305
305
  */
306
306
  export const useAllPrismicDocumentsByType = <
307
- TDocument extends prismicT.PrismicDocument,
307
+ TDocument extends prismic.PrismicDocument,
308
308
  >(
309
309
  ...args: [
310
310
  documentType: ClientMethodParameters<"getAllByType">[0],
@@ -330,13 +330,13 @@ export const useAllPrismicDocumentsByType = <
330
330
  * @see Underlying `@prismicio/client` method {@link proto.getByTag}
331
331
  */
332
332
  export const usePrismicDocumentsByTag = <
333
- TDocument extends prismicT.PrismicDocument,
333
+ TDocument extends prismic.PrismicDocument,
334
334
  >(
335
335
  ...args: [
336
336
  tag: ClientMethodParameters<"getByTag">[0],
337
337
  params?: ClientMethodParameters<"getByTag">[1] & HookOnlyParameters,
338
338
  ]
339
- ): ClientHookReturnType<prismicT.Query<TDocument>> =>
339
+ ): ClientHookReturnType<prismic.Query<TDocument>> =>
340
340
  useStatefulPrismicClientMethod("getByTag", args);
341
341
 
342
342
  /**
@@ -356,7 +356,7 @@ export const usePrismicDocumentsByTag = <
356
356
  * @see Underlying `@prismicio/client` method {@link proto.getAllByTag}
357
357
  */
358
358
  export const useAllPrismicDocumentsByTag = <
359
- TDocument extends prismicT.PrismicDocument,
359
+ TDocument extends prismic.PrismicDocument,
360
360
  >(
361
361
  ...args: [
362
362
  tag: ClientMethodParameters<"getAllByTag">[0],
@@ -383,13 +383,13 @@ export const useAllPrismicDocumentsByTag = <
383
383
  * @see Underlying `@prismicio/client` method {@link proto.getByTags}
384
384
  */
385
385
  export const usePrismicDocumentsBySomeTags = <
386
- TDocument extends prismicT.PrismicDocument,
386
+ TDocument extends prismic.PrismicDocument,
387
387
  >(
388
388
  ...args: [
389
389
  tag: ClientMethodParameters<"getBySomeTags">[0],
390
390
  params?: ClientMethodParameters<"getBySomeTags">[1] & HookOnlyParameters,
391
391
  ]
392
- ): ClientHookReturnType<prismicT.Query<TDocument>> =>
392
+ ): ClientHookReturnType<prismic.Query<TDocument>> =>
393
393
  useStatefulPrismicClientMethod("getBySomeTags", args);
394
394
 
395
395
  /**
@@ -410,7 +410,7 @@ export const usePrismicDocumentsBySomeTags = <
410
410
  * @see Underlying `@prismicio/client` method {@link proto.getAllByTags}
411
411
  */
412
412
  export const useAllPrismicDocumentsBySomeTags = <
413
- TDocument extends prismicT.PrismicDocument,
413
+ TDocument extends prismic.PrismicDocument,
414
414
  >(
415
415
  ...args: [
416
416
  tag: ClientMethodParameters<"getAllBySomeTags">[0],
@@ -436,13 +436,13 @@ export const useAllPrismicDocumentsBySomeTags = <
436
436
  * @see Underlying `@prismicio/client` method {@link proto.getByTags}
437
437
  */
438
438
  export const usePrismicDocumentsByEveryTag = <
439
- TDocument extends prismicT.PrismicDocument,
439
+ TDocument extends prismic.PrismicDocument,
440
440
  >(
441
441
  ...args: [
442
442
  tag: ClientMethodParameters<"getByEveryTag">[0],
443
443
  params?: ClientMethodParameters<"getByEveryTag">[1] & HookOnlyParameters,
444
444
  ]
445
- ): ClientHookReturnType<prismicT.Query<TDocument>> =>
445
+ ): ClientHookReturnType<prismic.Query<TDocument>> =>
446
446
  useStatefulPrismicClientMethod("getByEveryTag", args);
447
447
 
448
448
  /**
@@ -462,7 +462,7 @@ export const usePrismicDocumentsByEveryTag = <
462
462
  * @see Underlying `@prismicio/client` method {@link proto.getAllByTags}
463
463
  */
464
464
  export const useAllPrismicDocumentsByEveryTag = <
465
- TDocument extends prismicT.PrismicDocument,
465
+ TDocument extends prismic.PrismicDocument,
466
466
  >(
467
467
  ...args: [
468
468
  tag: ClientMethodParameters<"getAllByEveryTag">[0],