From ed75718de9aff5b59ec4b1f5eadef6ccc21901ce Mon Sep 17 00:00:00 2001 From: Angelo Ashmore Date: Fri, 21 Apr 2023 16:11:50 -1000 Subject: [PATCH] fix(PrismicLink): types for `rel` and internal/external component props --- src/react-server/PrismicLink.tsx | 59 ++++++++++++++------------ test/react-server/PrismicLink.test.tsx | 24 ++++++++++- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/react-server/PrismicLink.tsx b/src/react-server/PrismicLink.tsx index e73e265..723eb98 100644 --- a/src/react-server/PrismicLink.tsx +++ b/src/react-server/PrismicLink.tsx @@ -46,33 +46,37 @@ export interface LinkProps { export type PrismicLinkProps< InternalComponentProps = React.ComponentProps, ExternalComponentProps = React.ComponentProps, -> = Omit & - Omit & { - rel?: string | AsLinkAttrsConfig["rel"]; - - /** - * The Link Resolver used to resolve links. - * - * @remarks - * If your app uses Route Resolvers when querying for your Prismic - * repository's content, a Link Resolver does not need to be provided. - * @see Learn about Link Resolvers and Route Resolvers {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver} - */ - linkResolver?: LinkResolverFunction; - - /** - * The component rendered for internal URLs. Defaults to ``. - * - * If your app uses a client-side router that requires a special Link - * component, provide the Link component to this prop. - */ - internalComponent?: React.ElementType; - - /** - * The component rendered for external URLs. Defaults to ``. - */ - externalComponent?: React.ComponentType; - } & ( +> = Omit & { + /** + * The `rel` attribute for the link. By default, `"noreferrer"` is provided if + * the link's URL is external. This prop can be provided a function to use the + * link's metadata to determine the `rel` value. + */ + rel?: string | AsLinkAttrsConfig["rel"]; + + /** + * The Link Resolver used to resolve links. + * + * @remarks + * If your app uses Route Resolvers when querying for your Prismic + * repository's content, a Link Resolver does not need to be provided. + * @see Learn about Link Resolvers and Route Resolvers {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver} + */ + linkResolver?: LinkResolverFunction; + + /** + * The component rendered for internal URLs. Defaults to ``. + * + * If your app uses a client-side router that requires a special Link + * component, provide the Link component to this prop. + */ + internalComponent?: React.ElementType; + + /** + * The component rendered for external URLs. Defaults to ``. + */ + externalComponent?: React.ComponentType; +} & ( | { document: PrismicDocument | null | undefined; href?: never; @@ -138,6 +142,7 @@ export const PrismicLink = React.forwardRef(function PrismicLink< } } } + const { href: computedHref, rel: computedRel, diff --git a/test/react-server/PrismicLink.test.tsx b/test/react-server/PrismicLink.test.tsx index 210bd0c..bc616cd 100644 --- a/test/react-server/PrismicLink.test.tsx +++ b/test/react-server/PrismicLink.test.tsx @@ -134,6 +134,29 @@ it("allow overriding default rel", async (ctx) => { expect(actual).toStrictEqual(expected); }); +it("allow overriding default rel with a function", async (ctx) => { + const field = ctx.mock.value.link({ + type: "Web", + withTargetBlank: true, + }); + field.url = "https://prismic.io"; + + const rel = vi.fn(() => "foo"); + + const actual = renderJSON(); + const expected = renderJSON( + // eslint-disable-next-line react/jsx-no-target-blank + , + ); + + expect(actual).toStrictEqual(expected); + expect(rel).toHaveBeenCalledWith({ + href: field.url, + target: field.target, + isExternal: true, + }); +}); + it("allow overriding default target", async (ctx) => { const field = ctx.mock.value.link({ type: "Web", @@ -226,7 +249,6 @@ it("forwards ref to internal component", async () => { ref={(el) => (customComponentRef = el)} internalComponent={CustomComponent} href="/" - onClick={() => void 0} /> , {