@prismicio/react 3.4.1 → 3.4.2-pr.270.b8e16cb
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/README.md +6 -0
- package/dist/PrismicImage.d.ts +1 -1
- package/dist/PrismicImage.js +1 -1
- package/dist/PrismicImage.js.map +1 -1
- package/dist/PrismicLink.d.ts +1 -1
- package/dist/PrismicLink.d.ts.map +1 -1
- package/dist/PrismicLink.js +1 -1
- package/dist/PrismicLink.js.map +1 -1
- package/dist/PrismicRichText.d.ts +1 -1
- package/dist/PrismicRichText.js +1 -1
- package/dist/PrismicRichText.js.map +1 -1
- package/dist/PrismicTable.d.ts +1 -1
- package/dist/PrismicTable.js +1 -1
- package/dist/PrismicTable.js.map +1 -1
- package/dist/PrismicText.d.ts +1 -1
- package/dist/PrismicText.js +1 -1
- package/dist/PrismicText.js.map +1 -1
- package/dist/PrismicToolbar.d.ts +1 -1
- package/dist/PrismicToolbar.js +1 -1
- package/dist/PrismicToolbar.js.map +1 -1
- package/dist/SliceBoundary.js +55 -0
- package/dist/SliceBoundary.js.map +1 -0
- package/dist/SliceZone.d.ts +1 -1
- package/dist/SliceZone.d.ts.map +1 -1
- package/dist/SliceZone.js +15 -8
- package/dist/SliceZone.js.map +1 -1
- package/dist/lib/devMsg.js +1 -1
- package/dist/lib/devMsg.js.map +1 -1
- package/dist/package.js +1 -1
- package/package.json +3 -3
- package/src/PrismicImage.tsx +33 -33
- package/src/PrismicLink.tsx +43 -43
- package/src/PrismicRichText.tsx +43 -43
- package/src/PrismicTable.tsx +29 -29
- package/src/PrismicText.tsx +16 -16
- package/src/PrismicToolbar.tsx +30 -30
- package/src/SliceBoundary.tsx +77 -0
- package/src/SliceZone.tsx +54 -43
- package/src/index.ts +15 -15
- package/src/lib/devMsg.ts +3 -3
package/src/PrismicTable.tsx
CHANGED
|
@@ -7,22 +7,22 @@ import {
|
|
|
7
7
|
type TableFieldBodyRow,
|
|
8
8
|
type TableFieldHeaderCell,
|
|
9
9
|
type TableFieldDataCell,
|
|
10
|
-
} from "@prismicio/client"
|
|
11
|
-
import type { ComponentType, FC, ReactNode } from "react"
|
|
10
|
+
} from "@prismicio/client"
|
|
11
|
+
import type { ComponentType, FC, ReactNode } from "react"
|
|
12
12
|
|
|
13
|
-
import { type JSXMapSerializer, PrismicRichText } from "./PrismicRichText.js"
|
|
13
|
+
import { type JSXMapSerializer, PrismicRichText } from "./PrismicRichText.js"
|
|
14
14
|
|
|
15
15
|
type TableComponents = {
|
|
16
|
-
table?: ComponentType<{ table: TableField<"filled">; children: ReactNode }
|
|
17
|
-
thead?: ComponentType<{ head: TableFieldHead; children: ReactNode }
|
|
18
|
-
tbody?: ComponentType<{ body: TableFieldBody; children: ReactNode }
|
|
16
|
+
table?: ComponentType<{ table: TableField<"filled">; children: ReactNode }>
|
|
17
|
+
thead?: ComponentType<{ head: TableFieldHead; children: ReactNode }>
|
|
18
|
+
tbody?: ComponentType<{ body: TableFieldBody; children: ReactNode }>
|
|
19
19
|
tr?: ComponentType<{
|
|
20
|
-
row: TableFieldHeadRow | TableFieldBodyRow
|
|
21
|
-
children: ReactNode
|
|
22
|
-
}
|
|
23
|
-
th?: ComponentType<{ cell: TableFieldHeaderCell; children: ReactNode }
|
|
24
|
-
td?: ComponentType<{ cell: TableFieldDataCell; children: ReactNode }
|
|
25
|
-
}
|
|
20
|
+
row: TableFieldHeadRow | TableFieldBodyRow
|
|
21
|
+
children: ReactNode
|
|
22
|
+
}>
|
|
23
|
+
th?: ComponentType<{ cell: TableFieldHeaderCell; children: ReactNode }>
|
|
24
|
+
td?: ComponentType<{ cell: TableFieldDataCell; children: ReactNode }>
|
|
25
|
+
}
|
|
26
26
|
|
|
27
27
|
const defaultComponents: Required<TableComponents> = {
|
|
28
28
|
table: ({ children }) => <table>{children}</table>,
|
|
@@ -31,12 +31,12 @@ const defaultComponents: Required<TableComponents> = {
|
|
|
31
31
|
tr: ({ children }) => <tr>{children}</tr>,
|
|
32
32
|
th: ({ children }) => <th>{children}</th>,
|
|
33
33
|
td: ({ children }) => <td>{children}</td>,
|
|
34
|
-
}
|
|
34
|
+
}
|
|
35
35
|
|
|
36
36
|
/** Props for `<PrismicTable>`. */
|
|
37
37
|
export type PrismicTableProps = {
|
|
38
38
|
/** The Prismic table field to render. */
|
|
39
|
-
field: TableField
|
|
39
|
+
field: TableField
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* An object that maps a table block to a React component.
|
|
@@ -51,33 +51,33 @@ export type PrismicTableProps = {
|
|
|
51
51
|
* }
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
|
-
components?: JSXMapSerializer & TableComponents
|
|
54
|
+
components?: JSXMapSerializer & TableComponents
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* The value to be rendered when the field is empty. If a fallback is not given, `null` will be
|
|
58
58
|
* rendered.
|
|
59
59
|
*/
|
|
60
|
-
fallback?: ReactNode
|
|
61
|
-
}
|
|
60
|
+
fallback?: ReactNode
|
|
61
|
+
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Renders content from a Prismic table field as React components.
|
|
65
65
|
*
|
|
66
66
|
* @example
|
|
67
|
-
*
|
|
67
|
+
* ;```tsx
|
|
68
68
|
* <PrismicTable field={slice.primary.pricing_table} />;
|
|
69
69
|
* ```
|
|
70
70
|
*
|
|
71
71
|
* @see Learn how to style tables and customize table element components: {@link https://prismic.io/docs/fields/table}
|
|
72
72
|
*/
|
|
73
73
|
export const PrismicTable: FC<PrismicTableProps> = (props) => {
|
|
74
|
-
const { field, components, fallback = null } = props
|
|
74
|
+
const { field, components, fallback = null } = props
|
|
75
75
|
|
|
76
76
|
if (!isFilled.table(field)) {
|
|
77
|
-
return fallback
|
|
77
|
+
return fallback
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
const { table: Table, thead: Thead, tbody: Tbody } = { ...defaultComponents, ...components }
|
|
80
|
+
const { table: Table, thead: Thead, tbody: Tbody } = { ...defaultComponents, ...components }
|
|
81
81
|
|
|
82
82
|
return (
|
|
83
83
|
<Table table={field}>
|
|
@@ -94,18 +94,18 @@ export const PrismicTable: FC<PrismicTableProps> = (props) => {
|
|
|
94
94
|
))}
|
|
95
95
|
</Tbody>
|
|
96
96
|
</Table>
|
|
97
|
-
)
|
|
98
|
-
}
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
99
|
|
|
100
100
|
type TableRowProps = {
|
|
101
|
-
row: TableFieldHeadRow | TableFieldBodyRow
|
|
102
|
-
components?: JSXMapSerializer & TableComponents
|
|
103
|
-
}
|
|
101
|
+
row: TableFieldHeadRow | TableFieldBodyRow
|
|
102
|
+
components?: JSXMapSerializer & TableComponents
|
|
103
|
+
}
|
|
104
104
|
|
|
105
105
|
function TableRow(props: TableRowProps) {
|
|
106
|
-
const { row, components } = props
|
|
106
|
+
const { row, components } = props
|
|
107
107
|
|
|
108
|
-
const { tr: Tr, th: Th, td: Td } = { ...defaultComponents, ...components }
|
|
108
|
+
const { tr: Tr, th: Th, td: Td } = { ...defaultComponents, ...components }
|
|
109
109
|
|
|
110
110
|
return (
|
|
111
111
|
<Tr row={row}>
|
|
@@ -121,5 +121,5 @@ function TableRow(props: TableRowProps) {
|
|
|
121
121
|
),
|
|
122
122
|
)}
|
|
123
123
|
</Tr>
|
|
124
|
-
)
|
|
124
|
+
)
|
|
125
125
|
}
|
package/src/PrismicText.tsx
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { asText, isFilled, type RichTextField } from "@prismicio/client"
|
|
2
|
-
import { DEV } from "esm-env"
|
|
3
|
-
import type { FC } from "react"
|
|
1
|
+
import { asText, isFilled, type RichTextField } from "@prismicio/client"
|
|
2
|
+
import { DEV } from "esm-env"
|
|
3
|
+
import type { FC } from "react"
|
|
4
4
|
|
|
5
|
-
import { devMsg } from "./lib/devMsg.js"
|
|
5
|
+
import { devMsg } from "./lib/devMsg.js"
|
|
6
6
|
|
|
7
7
|
/** Props for `<PrismicText>`. */
|
|
8
8
|
export type PrismicTextProps = {
|
|
9
9
|
/** The Prismic rich text field to render. */
|
|
10
|
-
field: RichTextField | null | undefined
|
|
10
|
+
field: RichTextField | null | undefined
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* The string rendered when the field is empty. If a fallback is not given, `null` will be
|
|
14
14
|
* rendered.
|
|
15
15
|
*/
|
|
16
|
-
fallback?: string
|
|
16
|
+
fallback?: string
|
|
17
17
|
|
|
18
18
|
/** The separator used between blocks. Defaults to `\n`. */
|
|
19
|
-
separator?: string
|
|
20
|
-
}
|
|
19
|
+
separator?: string
|
|
20
|
+
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Renders content from a Prismic rich text field as plain text (no HTML).
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
26
|
-
*
|
|
26
|
+
* ;```tsx
|
|
27
27
|
* <PrismicText field={slice.primary.text} />;
|
|
28
28
|
* ```
|
|
29
29
|
*
|
|
30
30
|
* @see Learn how to display rich text as plain text or React components: {@link https://prismic.io/docs/fields/rich-text}
|
|
31
31
|
*/
|
|
32
32
|
export const PrismicText: FC<PrismicTextProps> = (props) => {
|
|
33
|
-
const { field, fallback, separator } = props
|
|
33
|
+
const { field, fallback, separator } = props
|
|
34
34
|
|
|
35
35
|
if (DEV) {
|
|
36
36
|
if ("className" in props) {
|
|
@@ -39,7 +39,7 @@ export const PrismicText: FC<PrismicTextProps> = (props) => {
|
|
|
39
39
|
"classname-is-not-a-valid-prop",
|
|
40
40
|
)}.`,
|
|
41
41
|
props.field,
|
|
42
|
-
)
|
|
42
|
+
)
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -50,15 +50,15 @@ export const PrismicText: FC<PrismicTextProps> = (props) => {
|
|
|
50
50
|
"prismictext-works-only-with-rich-text-and-title-fields",
|
|
51
51
|
)}`,
|
|
52
52
|
props.field,
|
|
53
|
-
)
|
|
53
|
+
)
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
return null
|
|
56
|
+
return null
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
if (!isFilled.richText(field)) {
|
|
60
|
-
return fallback != null ? <>{fallback}</> : null
|
|
60
|
+
return fallback != null ? <>{fallback}</> : null
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
return <>{asText(field, { separator })}
|
|
64
|
-
}
|
|
63
|
+
return <>{asText(field, { separator })}</>
|
|
64
|
+
}
|
package/src/PrismicToolbar.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use client"
|
|
1
|
+
"use client"
|
|
2
2
|
|
|
3
|
-
import { getToolbarSrc } from "@prismicio/client"
|
|
4
|
-
import { type FC, useEffect, useRef } from "react"
|
|
3
|
+
import { getToolbarSrc } from "@prismicio/client"
|
|
4
|
+
import { type FC, useEffect, useRef } from "react"
|
|
5
5
|
|
|
6
6
|
/** Props for `<PrismicToolbar>`. */
|
|
7
7
|
export type PrismicToolbarProps = {
|
|
@@ -9,7 +9,7 @@ export type PrismicToolbarProps = {
|
|
|
9
9
|
* The name of the Prismic repository. For example, `"my-repo"` if the repository URL is
|
|
10
10
|
* `my-repo.prismic.io`.
|
|
11
11
|
*/
|
|
12
|
-
repositoryName: string
|
|
12
|
+
repositoryName: string
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Called when the Prismic toolbar triggers a preview update. This happens when the previewed
|
|
@@ -19,7 +19,7 @@ export type PrismicToolbarProps = {
|
|
|
19
19
|
*
|
|
20
20
|
* The default page reload behavior can be cancelled with `event.preventDefault()`.
|
|
21
21
|
*/
|
|
22
|
-
onPreviewUpdate?: (event: CustomEvent<{ ref: string }>) => void
|
|
22
|
+
onPreviewUpdate?: (event: CustomEvent<{ ref: string }>) => void
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Called when the Prismic toolbar triggers a preview end. This happens when a preview session is
|
|
@@ -27,67 +27,67 @@ export type PrismicToolbarProps = {
|
|
|
27
27
|
*
|
|
28
28
|
* The default page reload behavior can be cancelled with `event.preventDefault()`.
|
|
29
29
|
*/
|
|
30
|
-
onPreviewEnd?: (event: CustomEvent<null>) => void
|
|
31
|
-
}
|
|
30
|
+
onPreviewEnd?: (event: CustomEvent<null>) => void
|
|
31
|
+
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Renders the Prismic Toolbar script to support draft previews.
|
|
35
35
|
*
|
|
36
36
|
* @example
|
|
37
|
-
*
|
|
37
|
+
* ;```tsx
|
|
38
38
|
* <PrismicToolbar repositoryName="my-repo" />;
|
|
39
39
|
* ```
|
|
40
40
|
*
|
|
41
41
|
* @see Learn how to set up preview functionality and the toolbar's role in preview sessions: {@link https://prismic.io/docs/previews}
|
|
42
42
|
*/
|
|
43
43
|
export const PrismicToolbar: FC<PrismicToolbarProps> = (props) => {
|
|
44
|
-
const { repositoryName, onPreviewUpdate, onPreviewEnd } = props
|
|
44
|
+
const { repositoryName, onPreviewUpdate, onPreviewEnd } = props
|
|
45
45
|
|
|
46
|
-
const src = getToolbarSrc(repositoryName)
|
|
46
|
+
const src = getToolbarSrc(repositoryName)
|
|
47
47
|
|
|
48
|
-
const onPreviewUpdateRef = useRef(onPreviewUpdate)
|
|
49
|
-
onPreviewUpdateRef.current = onPreviewUpdate
|
|
48
|
+
const onPreviewUpdateRef = useRef(onPreviewUpdate)
|
|
49
|
+
onPreviewUpdateRef.current = onPreviewUpdate
|
|
50
50
|
|
|
51
|
-
const onPreviewEndRef = useRef(onPreviewEnd)
|
|
52
|
-
onPreviewEndRef.current = onPreviewEnd
|
|
51
|
+
const onPreviewEndRef = useRef(onPreviewEnd)
|
|
52
|
+
onPreviewEndRef.current = onPreviewEnd
|
|
53
53
|
|
|
54
54
|
useEffect(() => {
|
|
55
|
-
const existingScript = document.querySelector(`script[src="${src}"]`)
|
|
55
|
+
const existingScript = document.querySelector(`script[src="${src}"]`)
|
|
56
56
|
|
|
57
57
|
if (!existingScript) {
|
|
58
|
-
const script = document.createElement("script")
|
|
59
|
-
script.src = src
|
|
60
|
-
script.defer = true
|
|
58
|
+
const script = document.createElement("script")
|
|
59
|
+
script.src = src
|
|
60
|
+
script.defer = true
|
|
61
61
|
|
|
62
62
|
// Used to distinguish the toolbar element from other elements.
|
|
63
|
-
script.dataset.prismicToolbar = ""
|
|
64
|
-
script.dataset.repositoryName = repositoryName
|
|
63
|
+
script.dataset.prismicToolbar = ""
|
|
64
|
+
script.dataset.repositoryName = repositoryName
|
|
65
65
|
|
|
66
66
|
// Disable Happy DOM `<script>` evaluation during tests.
|
|
67
67
|
// @ts-expect-error - `_evaluateScript` is a Happy DOM-specific property.
|
|
68
|
-
script._evaluateScript = false
|
|
68
|
+
script._evaluateScript = false
|
|
69
69
|
|
|
70
|
-
document.body.appendChild(script)
|
|
70
|
+
document.body.appendChild(script)
|
|
71
71
|
}
|
|
72
|
-
}, [repositoryName, src])
|
|
72
|
+
}, [repositoryName, src])
|
|
73
73
|
|
|
74
74
|
useEffect(() => {
|
|
75
|
-
const controller = new AbortController()
|
|
75
|
+
const controller = new AbortController()
|
|
76
76
|
|
|
77
77
|
window.addEventListener(
|
|
78
78
|
"prismicPreviewUpdate",
|
|
79
79
|
(event) => onPreviewUpdateRef.current?.(event as CustomEvent<{ ref: string }>),
|
|
80
80
|
{ signal: controller.signal },
|
|
81
|
-
)
|
|
81
|
+
)
|
|
82
82
|
|
|
83
83
|
window.addEventListener(
|
|
84
84
|
"prismicPreviewEnd",
|
|
85
85
|
(event) => onPreviewEndRef.current?.(event as CustomEvent<null>),
|
|
86
86
|
{ signal: controller.signal },
|
|
87
|
-
)
|
|
87
|
+
)
|
|
88
88
|
|
|
89
|
-
return () => controller.abort()
|
|
90
|
-
}, [])
|
|
89
|
+
return () => controller.abort()
|
|
90
|
+
}, [])
|
|
91
91
|
|
|
92
|
-
return null
|
|
93
|
-
}
|
|
92
|
+
return null
|
|
93
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { type ReactNode, useId, useLayoutEffect, useRef, useSyncExternalStore } from "react"
|
|
4
|
+
|
|
5
|
+
type SliceBoundaryProps = {
|
|
6
|
+
children: ReactNode
|
|
7
|
+
sliceId: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function SliceBoundary(props: SliceBoundaryProps): ReactNode {
|
|
11
|
+
const { children, sliceId } = props
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
<CommentMarker value={`prismic-slice-start:${sliceId}`} />
|
|
16
|
+
{children}
|
|
17
|
+
<CommentMarker value={`prismic-slice-end:${sliceId}`} />
|
|
18
|
+
</>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type CommentMarkerProps = {
|
|
23
|
+
value: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function CommentMarker(props: CommentMarkerProps) {
|
|
27
|
+
const { value } = props
|
|
28
|
+
const id = useId()
|
|
29
|
+
const isClient = useIsClient()
|
|
30
|
+
const anchorRef = useRef<Text>(null)
|
|
31
|
+
|
|
32
|
+
useLayoutEffect(() => {
|
|
33
|
+
let anchor = anchorRef.current
|
|
34
|
+
|
|
35
|
+
if (!anchor?.isConnected) {
|
|
36
|
+
anchor = findTextNode(id)
|
|
37
|
+
if (!anchor) return
|
|
38
|
+
|
|
39
|
+
anchor.data = ""
|
|
40
|
+
anchorRef.current = anchor
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const comment = document.createComment(value)
|
|
44
|
+
anchor.after(comment)
|
|
45
|
+
|
|
46
|
+
return () => comment.remove()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return isClient ? id : null
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function useIsClient() {
|
|
53
|
+
return useSyncExternalStore(subscribe, getClientSnapshot, getServerSnapshot)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function subscribe() {
|
|
57
|
+
return () => {}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getClientSnapshot() {
|
|
61
|
+
return true
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getServerSnapshot() {
|
|
65
|
+
return false
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function findTextNode(value: string) {
|
|
69
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT)
|
|
70
|
+
|
|
71
|
+
while (walker.nextNode()) {
|
|
72
|
+
const node = walker.currentNode
|
|
73
|
+
if (node instanceof Text && node.data === value) return node
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return null
|
|
77
|
+
}
|
package/src/SliceZone.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { Slice } from "@prismicio/client"
|
|
2
|
-
import { DEV } from "esm-env"
|
|
3
|
-
import type
|
|
1
|
+
import type { Slice } from "@prismicio/client"
|
|
2
|
+
import { DEV } from "esm-env"
|
|
3
|
+
import { Fragment, type ComponentType, type FC, type ReactNode } from "react"
|
|
4
|
+
|
|
5
|
+
import { SliceBoundary } from "./SliceBoundary.js"
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Returns the type of a `SliceLike` type.
|
|
@@ -11,7 +13,7 @@ type ExtractSliceType<TSlice extends SliceLike> = TSlice extends Slice
|
|
|
11
13
|
? TSlice["slice_type"]
|
|
12
14
|
: TSlice extends SliceLikeGraphQL
|
|
13
15
|
? TSlice["type"]
|
|
14
|
-
: never
|
|
16
|
+
: never
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* The minimum required properties to represent a Prismic slice from the Prismic Content API for the
|
|
@@ -22,7 +24,7 @@ type ExtractSliceType<TSlice extends SliceLike> = TSlice extends Slice
|
|
|
22
24
|
export type SliceLikeRestV2<TSliceType extends string = string> = Pick<
|
|
23
25
|
Slice<TSliceType>,
|
|
24
26
|
"id" | "slice_type"
|
|
25
|
-
|
|
27
|
+
>
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
30
|
* The minimum required properties to represent a Prismic slice from the Prismic GraphQL API for the
|
|
@@ -31,8 +33,8 @@ export type SliceLikeRestV2<TSliceType extends string = string> = Pick<
|
|
|
31
33
|
* @typeParam SliceType - Type name of the slice.
|
|
32
34
|
*/
|
|
33
35
|
export type SliceLikeGraphQL<TSliceType extends string = string> = {
|
|
34
|
-
type: Slice<TSliceType>["slice_type"]
|
|
35
|
-
}
|
|
36
|
+
type: Slice<TSliceType>["slice_type"]
|
|
37
|
+
}
|
|
36
38
|
|
|
37
39
|
/**
|
|
38
40
|
* The minimum required properties to represent a Prismic slice for the `mapSliceZone()` helper.
|
|
@@ -52,8 +54,8 @@ export type SliceLike<TSliceType extends string = string> = (
|
|
|
52
54
|
*
|
|
53
55
|
* @internal
|
|
54
56
|
*/
|
|
55
|
-
__mapped?: true
|
|
56
|
-
}
|
|
57
|
+
__mapped?: true
|
|
58
|
+
}
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
61
|
* A looser version of the `SliceZone` type from `@prismicio/client` using `SliceLike`.
|
|
@@ -63,7 +65,7 @@ export type SliceLike<TSliceType extends string = string> = (
|
|
|
63
65
|
*
|
|
64
66
|
* @typeParam TSlice - The type(s) of a slice in the slice zone.
|
|
65
67
|
*/
|
|
66
|
-
export type SliceZoneLike<TSlice extends SliceLike = SliceLike> = readonly TSlice[]
|
|
68
|
+
export type SliceZoneLike<TSlice extends SliceLike = SliceLike> = readonly TSlice[]
|
|
67
69
|
|
|
68
70
|
/**
|
|
69
71
|
* React props for a component rendering content from a Prismic slice using the `<SliceZone>`
|
|
@@ -75,21 +77,21 @@ export type SliceZoneLike<TSlice extends SliceLike = SliceLike> = readonly TSlic
|
|
|
75
77
|
*/
|
|
76
78
|
export type SliceComponentProps<TSlice extends SliceLike = SliceLike, TContext = unknown> = {
|
|
77
79
|
/** Slice data for this component. */
|
|
78
|
-
slice: TSlice
|
|
80
|
+
slice: TSlice
|
|
79
81
|
|
|
80
82
|
/** The index of the slice in the slice zone. */
|
|
81
|
-
index: number
|
|
83
|
+
index: number
|
|
82
84
|
|
|
83
85
|
/** All slices from the slice zone to which the slice belongs. */
|
|
84
86
|
// TODO: We have to keep this list of slices general due to circular
|
|
85
87
|
// reference limtiations. If we had another generic to determine the full
|
|
86
88
|
// union of slice types, it would include TSlice. This causes TypeScript to
|
|
87
89
|
// throw a compilation error.
|
|
88
|
-
slices: SliceZoneLike<TSlice extends SliceLikeGraphQL ? SliceLikeGraphQL : SliceLikeRestV2
|
|
90
|
+
slices: SliceZoneLike<TSlice extends SliceLikeGraphQL ? SliceLikeGraphQL : SliceLikeRestV2>
|
|
89
91
|
|
|
90
92
|
/** Arbitrary data passed to `<SliceZone>` and made available to all slice components. */
|
|
91
|
-
context: TContext
|
|
92
|
-
}
|
|
93
|
+
context: TContext
|
|
94
|
+
}
|
|
93
95
|
|
|
94
96
|
/**
|
|
95
97
|
* A React component to be rendered for each instance of its slice.
|
|
@@ -101,7 +103,7 @@ export type SliceComponentType<
|
|
|
101
103
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
102
104
|
TSlice extends SliceLike = any,
|
|
103
105
|
TContext = unknown,
|
|
104
|
-
> = ComponentType<SliceComponentProps<TSlice, TContext
|
|
106
|
+
> = ComponentType<SliceComponentProps<TSlice, TContext>>
|
|
105
107
|
|
|
106
108
|
/**
|
|
107
109
|
* A record of slice types mapped to a React component. The component will be rendered for each
|
|
@@ -128,8 +130,8 @@ export type SliceZoneComponents<TSlice extends SliceLike = SliceLike, TContext =
|
|
|
128
130
|
? SliceLike
|
|
129
131
|
: Extract<TSlice, SliceLike<SliceType>>,
|
|
130
132
|
TContext
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
+
>
|
|
134
|
+
}
|
|
133
135
|
|
|
134
136
|
/**
|
|
135
137
|
* React props for the `<SliceZone>` component.
|
|
@@ -139,19 +141,19 @@ export type SliceZoneComponents<TSlice extends SliceLike = SliceLike, TContext =
|
|
|
139
141
|
*/
|
|
140
142
|
export type SliceZoneProps<TContext = unknown> = {
|
|
141
143
|
/** List of slice data from the slice zone. */
|
|
142
|
-
slices?: SliceZoneLike
|
|
144
|
+
slices?: SliceZoneLike
|
|
143
145
|
|
|
144
146
|
/** A record mapping slice types to React components. */
|
|
145
147
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
146
|
-
components?: Record<string, ComponentType<any
|
|
148
|
+
components?: Record<string, ComponentType<any>>
|
|
147
149
|
|
|
148
150
|
/** The React component rendered if a component mapping from the `components` prop cannot be found. */
|
|
149
151
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
-
defaultComponent?: ComponentType<SliceComponentProps<any, TContext
|
|
152
|
+
defaultComponent?: ComponentType<SliceComponentProps<any, TContext>>
|
|
151
153
|
|
|
152
154
|
/** Arbitrary data made available to all slice components. */
|
|
153
|
-
context?: TContext
|
|
154
|
-
}
|
|
155
|
+
context?: TContext
|
|
156
|
+
}
|
|
155
157
|
|
|
156
158
|
/**
|
|
157
159
|
* This slice component can be used as a reminder to provide a proper implementation.
|
|
@@ -162,56 +164,65 @@ export type SliceZoneProps<TContext = unknown> = {
|
|
|
162
164
|
export const TODOSliceComponent = <TSlice extends SliceLike>({
|
|
163
165
|
slice,
|
|
164
166
|
}: {
|
|
165
|
-
slice: TSlice
|
|
167
|
+
slice: TSlice
|
|
166
168
|
}): ReactNode => {
|
|
167
169
|
if (!DEV) {
|
|
168
|
-
return null
|
|
170
|
+
return null
|
|
169
171
|
}
|
|
170
172
|
|
|
171
|
-
const type = "slice_type" in slice ? slice.slice_type : slice.type
|
|
173
|
+
const type = "slice_type" in slice ? slice.slice_type : slice.type
|
|
172
174
|
|
|
173
|
-
console.warn(`[SliceZone] Could not find a component for slice type "${type}"`, slice)
|
|
175
|
+
console.warn(`[SliceZone] Could not find a component for slice type "${type}"`, slice)
|
|
174
176
|
|
|
175
177
|
return (
|
|
176
178
|
<section data-slice-zone-todo-component="" data-slice-type={type}>
|
|
177
179
|
Could not find a component for slice type “{type}
|
|
178
180
|
”
|
|
179
181
|
</section>
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
+
)
|
|
183
|
+
}
|
|
182
184
|
|
|
183
185
|
/**
|
|
184
186
|
* Renders slices in a slice zone as React components.
|
|
185
187
|
*
|
|
186
188
|
* @example
|
|
187
|
-
*
|
|
189
|
+
* ;```tsx
|
|
188
190
|
* <SliceZone slices={page.data.slices} components={components} />;
|
|
189
191
|
* ```
|
|
190
192
|
*
|
|
191
193
|
* @see Learn how to create slices, use slice variations, and display slices: {@link https://prismic.io/docs/slices}
|
|
192
194
|
*/
|
|
193
195
|
export const SliceZone: FC<SliceZoneProps> = (props) => {
|
|
194
|
-
const { slices = [], components = {}, defaultComponent, context = {} } = props
|
|
196
|
+
const { slices = [], components = {}, defaultComponent, context = {} } = props
|
|
195
197
|
|
|
196
198
|
const renderedSlices = slices.map((slice, index) => {
|
|
197
|
-
const type = "slice_type" in slice ? slice.slice_type : slice.type
|
|
199
|
+
const type = "slice_type" in slice ? slice.slice_type : slice.type
|
|
198
200
|
|
|
199
|
-
const key = "id" in slice && slice.id ? slice.id : `${index}-${JSON.stringify(slice)}
|
|
201
|
+
const key = "id" in slice && slice.id ? slice.id : `${index}-${JSON.stringify(slice)}`
|
|
200
202
|
|
|
201
|
-
const Comp = components[type as keyof typeof components] || defaultComponent
|
|
203
|
+
const Comp = components[type as keyof typeof components] || defaultComponent
|
|
204
|
+
let renderedSlice: ReactNode
|
|
202
205
|
|
|
203
206
|
if (!Comp) {
|
|
204
|
-
|
|
205
|
-
}
|
|
207
|
+
renderedSlice = <TODOSliceComponent slice={slice} />
|
|
208
|
+
} else if (slice.__mapped) {
|
|
209
|
+
const { __mapped, ...mappedProps } = slice
|
|
206
210
|
|
|
207
|
-
|
|
208
|
-
|
|
211
|
+
renderedSlice = <Comp {...mappedProps} />
|
|
212
|
+
} else {
|
|
213
|
+
renderedSlice = <Comp slice={slice} index={index} slices={slices} context={context} />
|
|
214
|
+
}
|
|
209
215
|
|
|
210
|
-
|
|
216
|
+
if ("id" in slice && slice.id) {
|
|
217
|
+
return (
|
|
218
|
+
<SliceBoundary key={key} sliceId={slice.id}>
|
|
219
|
+
{renderedSlice}
|
|
220
|
+
</SliceBoundary>
|
|
221
|
+
)
|
|
211
222
|
}
|
|
212
223
|
|
|
213
|
-
return <
|
|
214
|
-
})
|
|
224
|
+
return <Fragment key={key}>{renderedSlice}</Fragment>
|
|
225
|
+
})
|
|
215
226
|
|
|
216
|
-
return <>{renderedSlices}
|
|
217
|
-
}
|
|
227
|
+
return <>{renderedSlices}</>
|
|
228
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
export { PrismicLink } from "./PrismicLink.js"
|
|
2
|
-
export type { PrismicLinkProps, LinkProps } from "./PrismicLink.js"
|
|
1
|
+
export { PrismicLink } from "./PrismicLink.js"
|
|
2
|
+
export type { PrismicLinkProps, LinkProps } from "./PrismicLink.js"
|
|
3
3
|
|
|
4
|
-
export { PrismicTable } from "./PrismicTable.js"
|
|
5
|
-
export type { PrismicTableProps } from "./PrismicTable.js"
|
|
4
|
+
export { PrismicTable } from "./PrismicTable.js"
|
|
5
|
+
export type { PrismicTableProps } from "./PrismicTable.js"
|
|
6
6
|
|
|
7
|
-
export { PrismicText } from "./PrismicText.js"
|
|
8
|
-
export type { PrismicTextProps } from "./PrismicText.js"
|
|
7
|
+
export { PrismicText } from "./PrismicText.js"
|
|
8
|
+
export type { PrismicTextProps } from "./PrismicText.js"
|
|
9
9
|
|
|
10
|
-
export { PrismicRichText } from "./PrismicRichText.js"
|
|
10
|
+
export { PrismicRichText } from "./PrismicRichText.js"
|
|
11
11
|
export type {
|
|
12
12
|
PrismicRichTextProps,
|
|
13
13
|
RichTextComponents,
|
|
14
14
|
JSXMapSerializer,
|
|
15
15
|
JSXFunctionSerializer,
|
|
16
|
-
} from "./PrismicRichText.js"
|
|
16
|
+
} from "./PrismicRichText.js"
|
|
17
17
|
|
|
18
|
-
export { Element } from "@prismicio/client/richtext"
|
|
18
|
+
export { Element } from "@prismicio/client/richtext"
|
|
19
19
|
|
|
20
|
-
export { PrismicImage } from "./PrismicImage.js"
|
|
21
|
-
export type { PrismicImageProps } from "./PrismicImage.js"
|
|
20
|
+
export { PrismicImage } from "./PrismicImage.js"
|
|
21
|
+
export type { PrismicImageProps } from "./PrismicImage.js"
|
|
22
22
|
|
|
23
|
-
export { SliceZone, TODOSliceComponent } from "./SliceZone.js"
|
|
23
|
+
export { SliceZone, TODOSliceComponent } from "./SliceZone.js"
|
|
24
24
|
export type {
|
|
25
25
|
SliceComponentProps,
|
|
26
26
|
SliceComponentType,
|
|
@@ -30,7 +30,7 @@ export type {
|
|
|
30
30
|
SliceZoneComponents,
|
|
31
31
|
SliceZoneLike,
|
|
32
32
|
SliceZoneProps,
|
|
33
|
-
} from "./SliceZone.js"
|
|
33
|
+
} from "./SliceZone.js"
|
|
34
34
|
|
|
35
|
-
export { PrismicToolbar } from "./PrismicToolbar.js"
|
|
36
|
-
export type { PrismicToolbarProps } from "./PrismicToolbar.js"
|
|
35
|
+
export { PrismicToolbar } from "./PrismicToolbar.js"
|
|
36
|
+
export type { PrismicToolbarProps } from "./PrismicToolbar.js"
|
package/src/lib/devMsg.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { version } from "../../package.json"
|
|
1
|
+
import { version } from "../../package.json"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns a `prismic.dev/msg` URL for a given message slug.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
|
-
*
|
|
7
|
+
* ;```ts
|
|
8
8
|
* devMsg("missing-param");
|
|
9
9
|
* // => "https://prismic.dev/msg/react/v1.2.3/missing-param"
|
|
10
10
|
* ```
|
|
@@ -14,5 +14,5 @@ import { version } from "../../package.json";
|
|
|
14
14
|
* @returns The `prismic.dev/msg` URL for the given slug.
|
|
15
15
|
*/
|
|
16
16
|
export function devMsg(slug: string): string {
|
|
17
|
-
return `https://prismic.dev/msg/react/v${version}/${slug}
|
|
17
|
+
return `https://prismic.dev/msg/react/v${version}/${slug}`
|
|
18
18
|
}
|