UNPKG

@prismicio/react

Version:

React components and hooks to fetch and present Prismic content

63 lines (62 loc) 2.93 kB
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