diff --git a/src/PrismicRichText.tsx b/src/PrismicRichText.tsx index ec3bcdb..f761731 100644 --- a/src/PrismicRichText.tsx +++ b/src/PrismicRichText.tsx @@ -224,21 +224,25 @@ export const PrismicRichText = ( return null; } else { const linkResolver = props.linkResolver || context.linkResolver; - const components = props.components || context.richTextComponents; const defaultSerializer = createDefaultSerializer({ linkResolver, internalLinkComponent: props.internalLinkComponent, externalLinkComponent: props.externalLinkComponent, }); - const serializer = components - ? prismicR.composeSerializers( - typeof components === "object" - ? prismicR.wrapMapSerializer(components) - : components, - defaultSerializer, - ) - : defaultSerializer; + const serializers = [ + typeof props.components === "object" + ? prismicR.wrapMapSerializer(props.components) + : props.components, + typeof context.richTextComponents === "object" + ? prismicR.wrapMapSerializer(context.richTextComponents) + : context.richTextComponents, + defaultSerializer, + ].filter((x): x is JSXFunctionSerializer => Boolean(x)); + const serializer = prismicR.composeSerializers( + serializers[0], + ...serializers.slice(1), + ); const serialized = prismicR.serialize(props.field, serializer); diff --git a/test/PrismicRichText.test.tsx b/test/PrismicRichText.test.tsx index ba716b1..8a10c03 100644 --- a/test/PrismicRichText.test.tsx +++ b/test/PrismicRichText.test.tsx @@ -2,10 +2,10 @@ import test from "ava"; import * as prismicT from "@prismicio/types"; import * as React from "react"; -import { PrismicRichText, PrismicLink } from "../src"; - import { renderJSON } from "./__testutils__/renderJSON"; +import { PrismicRichText, PrismicLink, PrismicProvider } from "../src"; + type LinkProps = { href: string; rel?: string; @@ -348,9 +348,9 @@ test("returns wrapped in ", (t) => { }); test("returns
with embedded html if type is embed", (t) => { - const oembed = { + const oembed: prismicT.EmbedField = { embed_url: "https://example.com", - type: "modern html elements", + type: "rich", provider_name: "Prismic", html: "Prismic is fun", }; @@ -367,7 +367,7 @@ test("returns
with embedded html if type is embed", (t) => { data-oembed={oembed.embed_url} data-oembed-type={oembed.type} data-oembed-provider={oembed.provider_name} - dangerouslySetInnerHTML={{ __html: oembed.html }} + dangerouslySetInnerHTML={{ __html: oembed.html as string }} />, ); @@ -501,3 +501,85 @@ test("renders line breaks as
", (t) => { t.deepEqual(actual, expected); }); + +test("renders components from components prop", (t) => { + const field: prismicT.RichTextField = [ + { + type: prismicT.RichTextNodeType.paragraph, + text: "paragraph", + spans: [], + }, + ]; + + const actual = renderJSON( +

paragraph

}} + />, + ); + const expected = renderJSON(

paragraph

); + + t.deepEqual(actual, expected); +}); + +test("renders components given to PrismicProvider", (t) => { + const field: prismicT.RichTextField = [ + { + type: prismicT.RichTextNodeType.paragraph, + text: "paragraph", + spans: [], + }, + ]; + + const actual = renderJSON( +

paragraph

, + }} + > + +
, + ); + const expected = renderJSON(

paragraph

); + + t.deepEqual(actual, expected); +}); + +test("components given to components prop overrides components given to PrismicProvider", (t) => { + const field: prismicT.RichTextField = [ + { + type: prismicT.RichTextNodeType.heading1, + text: "heading", + spans: [], + }, + { + type: prismicT.RichTextNodeType.paragraph, + text: "paragraph", + spans: [], + }, + ]; + + const actual = renderJSON( +

PrismicProvider heading1

, + paragraph: () =>

PrismicProvider paragraph

, + }} + > +

overridden paragraph

, + }} + /> +
, + ); + const expected = renderJSON( + <> +

PrismicProvider heading1

+

overridden paragraph

+ , + ); + + t.deepEqual(actual, expected); +});