@prismicio/react
Version:
React components and hooks to fetch and present Prismic content
63 lines (62 loc) • 2.93 kB
JavaScript
import { devMsg } from "./lib/devMsg.js";
import { asLinkAttrs } from "@prismicio/client";
import { DEV } from "esm-env";
import { forwardRef } from "react";
import { jsx } from "react/jsx-runtime";
//#region src/PrismicLink.tsx
/** The default component rendered for internal and external links. */
const defaultComponent = "a";
/**
* Renders a link from a Prismic link field or page.
*
* @example
* ```tsx
* <PrismicLink field={slice.primary.link}>Click here</PrismicLink>;
* ```
*
* @see Learn how to display links and use variants for styling: {@link https://prismic.io/docs/fields/link}
*/
const PrismicLink = forwardRef(function PrismicLink(props, ref) {
const { field, document: doc, linkResolver, internalComponent, externalComponent, children, ...restProps } = props;
if (DEV) {
if (field) {
if (!field.link_type) {
console.error(`[PrismicLink] This "field" prop value caused an error to be thrown.\n`, field);
throw new Error(`[PrismicLink] The provided field is missing required properties to properly render a link. The link will not render. For more details, see ${devMsg("missing-link-properties")}`);
} else if (("text" in field ? Object.keys(field).length > 2 : Object.keys(field).length > 1) && !("url" in field || "uid" in field || "id" in field)) console.warn(`[PrismicLink] The provided field is missing required properties to properly render a link. The link may not render correctly. For more details, see ${devMsg("missing-link-properties")}`, field);
} else if (doc) {
if (!("url" in doc || "id" in doc)) console.warn(`[PrismicLink] The provided document is missing required properties to properly render a link. The link may not render correctly. For more details, see ${devMsg("missing-link-properties")}`, doc);
}
}
const { href: computedHref, rel: computedRel, ...attrs } = asLinkAttrs(field ?? doc, {
linkResolver,
rel: typeof restProps.rel === "function" ? restProps.rel : void 0
});
let rel = computedRel;
if ("rel" in restProps && typeof restProps.rel !== "function") rel = restProps.rel;
const href = ("href" in restProps ? restProps.href : computedHref) || "";
const InternalComponent = internalComponent || defaultComponent;
const ExternalComponent = externalComponent || defaultComponent;
return /* @__PURE__ */ jsx(href ? isInternalURL(href) ? InternalComponent : ExternalComponent : InternalComponent, {
ref,
...attrs,
...restProps,
href,
rel,
children: "children" in props ? children : field?.text
});
});
/**
* Determines if a URL is internal or external.
*
* @param url - The URL to check if internal or external.
* @returns `true` if `url` is internal, `false` otherwise.
*/
function isInternalURL(url) {
const isInternal = /^(\/(?!\/)|#)/.test(url);
const isSpecialLink = !isInternal && !/^https?:\/\//.test(url);
return isInternal && !isSpecialLink;
}
//#endregion
export { PrismicLink };
//# sourceMappingURL=PrismicLink.js.map