diff --git a/package-lock.json b/package-lock.json index 538e2ea..1ff1aac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,13 +13,14 @@ "e2e-projects/*" ], "dependencies": { + "@prismicio/react": "^3.3.0", "@prismicio/simulator": "^0.2.0", "imgix-url-builder": "^0.0.5", "lz-string": "^1.5.0" }, "devDependencies": { "@playwright/test": "^1.49.1", - "@prismicio/client": "^7.12.0", + "@prismicio/client": "^7.21.3", "@trivago/prettier-plugin-sort-imports": "^6.0.2", "@types/node": "^22.10.2", "@types/react": "^19.2.3", @@ -1351,20 +1352,50 @@ } }, "node_modules/@prismicio/client": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@prismicio/client/-/client-7.13.1.tgz", - "integrity": "sha512-E+XdBYFXldTNENkkQpnuLKAliWSMTYwyoSlzNsQU+TtCXrasxFFYe/IESeTnI5VYYKAgT5wNSnHufempW+AXlw==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@prismicio/client/-/client-7.21.3.tgz", + "integrity": "sha512-OQ/c+dfUcexYFEAhrN+0DrrKwEF5nHabOMJxAPXACpaVg9+itX2PX7YCqUXYEj7DTfOVTRbxyCyKqWprVtMi/w==", + "license": "Apache-2.0", "dependencies": { - "imgix-url-builder": "^0.0.5" + "imgix-url-builder": "^0.0.6" }, "engines": { "node": ">=14.15.0" } }, + "node_modules/@prismicio/client/node_modules/imgix-url-builder": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/imgix-url-builder/-/imgix-url-builder-0.0.6.tgz", + "integrity": "sha512-lFVbvaE9vMck8qz9j+y6o7vsyc1vZhdqzWu+Wp/nlnOCi9zAErc31QMkZKYUGMNLLzxOO4YIBAUPndTPah8HFg==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.7.0" + } + }, "node_modules/@prismicio/next": { "resolved": "", "link": true }, + "node_modules/@prismicio/react": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@prismicio/react/-/react-3.3.0.tgz", + "integrity": "sha512-M9u0iKkU/Ir1JCmEhTLYcUf86n6+o3fTWw74CGW91E+cPwJZ5UZDqqwWSSUU++ByaEfbjoYOhvvaxlPlBzuicg==", + "license": "Apache-2.0", + "workspaces": [ + ".", + "e2e-projects/*" + ], + "dependencies": { + "esm-env": "^1.2.2" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@prismicio/client": "^7", + "react": "^18 || ^19" + } + }, "node_modules/@prismicio/simulator": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@prismicio/simulator/-/simulator-0.2.0.tgz", @@ -3681,6 +3712,12 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT" + }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", @@ -3899,6 +3936,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ diff --git a/package.json b/package.json index 2f0f126..736d712 100644 --- a/package.json +++ b/package.json @@ -55,13 +55,14 @@ "types": "tsc --noEmit" }, "dependencies": { + "@prismicio/react": "^3.3.0", "@prismicio/simulator": "^0.2.0", "imgix-url-builder": "^0.0.5", "lz-string": "^1.5.0" }, "devDependencies": { "@playwright/test": "^1.49.1", - "@prismicio/client": "^7.12.0", + "@prismicio/client": "^7.21.3", "@trivago/prettier-plugin-sort-imports": "^6.0.2", "@types/node": "^22.10.2", "@types/react": "^19.2.3", diff --git a/src/PrismicImage.tsx b/src/PrismicImage.tsx new file mode 100644 index 0000000..50e7d68 --- /dev/null +++ b/src/PrismicImage.tsx @@ -0,0 +1,187 @@ +"use client"; + +import { imgixLoader } from "./imgixLoader"; +import { devMsg } from "./lib/devMsg"; +import { resolveDefaultExport } from "./lib/resolveDefaultExport"; +import type { ImageFieldImage } from "@prismicio/client"; +import { isFilled } from "@prismicio/client"; +import type { ImgixURLParams } from "imgix-url-builder"; +import { buildURL } from "imgix-url-builder"; +import type { ImageProps } from "next/image"; +import Image from "next/image"; +import type { + ForwardRefExoticComponent, + PropsWithoutRef, + RefAttributes, +} from "react"; +import { forwardRef } from "react"; + +/** + * @deprecated Use `PrismicImage` instead. + */ +export { PrismicImage as PrismicNextImage }; + +/** + * @deprecated Use `PrismicImageProps` instead. + */ +export type { PrismicImageProps as PrismicNextImageProps }; + +const castInt = (input: string | number | undefined): number | undefined => { + if (typeof input === "number" || typeof input === "undefined") { + return input; + } else { + const parsed = Number.parseInt(input); + + if (Number.isNaN(parsed)) { + return undefined; + } else { + return parsed; + } + } +}; + +export type PrismicImageProps = Omit & { + /** The Prismic Image field or thumbnail to render. */ + field: ImageFieldImage | null | undefined; + + /** + * An object of Imgix URL API parameters to transform the image. + * + * @see https://docs.imgix.com/apis/rendering + */ + imgixParams?: { [P in keyof ImgixURLParams]: ImgixURLParams[P] | null }; + + /** + * Declare an image as decorative by providing `alt=""`. + * + * See: + * https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/alt#decorative_images + */ + alt?: ""; + + /** + * Declare an image as decorative only if the Image field does not have + * alternative text by providing `fallbackAlt=""`. + * + * See: + * https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/alt#decorative_images + */ + fallbackAlt?: ""; + + /** + * Rendered when the field is empty. If a fallback is not given, `null` will + * be rendered. + */ + fallback?: React.ReactNode; + + loader?: ImageProps["loader"] | null; +}; + +/** + * React component that renders an image from a Prismic Image field or one of + * its thumbnails using `next/image`. It will automatically set the `alt` + * attribute using the Image field's `alt` property. + * + * It uses an Imgix URL-based loader by default. A custom loader can be provided + * with the `loader` prop. If you would like to use the Next.js Image + * Optimization API instead, set `loader={undefined}`. + * + * @param props - Props for the component. + * + * @returns A responsive image component using `next/image` for the given Image + * field. + * + * @see To learn more about `next/image`, see: https://nextjs.org/docs/api-reference/next/image + */ +// The type annotation is necessary to avoid a type reference issue. +export const PrismicImage: ForwardRefExoticComponent< + PropsWithoutRef & RefAttributes +> = forwardRef(function PrismicImage( + { + field, + imgixParams = {}, + alt, + fallbackAlt, + fill, + width, + height, + fallback = null, + loader = imgixLoader, + ...restProps + }, + ref, +) { + if (process.env.NODE_ENV === "development") { + if (typeof alt === "string" && alt !== "") { + console.warn( + `[PrismicImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg( + "alt-must-be-an-empty-string", + )}`, + ); + } + + if (typeof fallbackAlt === "string" && fallbackAlt !== "") { + console.warn( + `[PrismicImage] The "fallbackAlt" prop can only be used to declare an image as decorative by passing an empty string (fallbackAlt="") but was provided a non-empty string. You can resolve this warning by removing the "fallbackAlt" prop or changing it to fallbackAlt="". For more details, see ${devMsg( + "alt-must-be-an-empty-string", + )}`, + ); + } + } + + if (!isFilled.imageThumbnail(field)) { + return <>{fallback}; + } + + const resolvedImgixParams = imgixParams; + for (const x in imgixParams) { + if (resolvedImgixParams[x as keyof typeof resolvedImgixParams] === null) { + resolvedImgixParams[x as keyof typeof resolvedImgixParams] = undefined; + } + } + + const src = buildURL(field.url, imgixParams as ImgixURLParams); + + const ar = field.dimensions.width / field.dimensions.height; + + const castedWidth = castInt(width); + const castedHeight = castInt(height); + + let resolvedWidth = castedWidth ?? field.dimensions.width; + let resolvedHeight = castedHeight ?? field.dimensions.height; + + if (castedWidth != null && castedHeight == null) { + resolvedHeight = castedWidth / ar; + } else if (castedWidth == null && castedHeight != null) { + resolvedWidth = castedHeight * ar; + } + + // A non-null assertion is required since we can't statically + // know if an alt attribute is available. + const resolvedAlt = (alt ?? (field.alt || fallbackAlt))!; + + if ( + process.env.NODE_ENV === "development" && + typeof resolvedAlt !== "string" + ) { + console.error( + `[PrismicImage] The following image is missing an "alt" property. Please add Alternative Text to the image in Prismic. To mark the image as decorative instead, add one of \`alt=""\` or \`fallbackAlt=""\`.`, + src, + ); + } + + const ResolvedImage = resolveDefaultExport(Image); + + return ( + + ); +}); diff --git a/src/PrismicLink.tsx b/src/PrismicLink.tsx new file mode 100644 index 0000000..b084c85 --- /dev/null +++ b/src/PrismicLink.tsx @@ -0,0 +1,74 @@ +import { resolveDefaultExport } from "./lib/resolveDefaultExport"; +import type { + AsLinkAttrsConfig, + LinkField, + LinkResolverFunction, + PrismicDocument, +} from "@prismicio/client"; +import { asLinkAttrs } from "@prismicio/client"; +import Link from "next/link"; +import type { ComponentProps } from "react"; +import { forwardRef } from "react"; + +/** + * @deprecated Use `PrismicLink` instead. + */ +export { PrismicLink as PrismicNextLink } from "./PrismicLink"; + +/** + * @deprecated Use `PrismicLinkProps` instead. + */ +export type { PrismicLinkProps as PrismicNextLinkProps } from "./PrismicLink"; + +export type PrismicLinkProps = Omit< + ComponentProps, + "field" | "document" | "href" | "rel" +> & { + linkResolver?: LinkResolverFunction; + rel?: string | AsLinkAttrsConfig["rel"]; +} & ( + | { + field: LinkField | null | undefined; + document?: never; + href?: never; + } + | { + field?: never; + document: PrismicDocument | null | undefined; + href?: never; + } + | { + field?: never; + document?: never; + href: ComponentProps["href"]; + } + ); + +export const PrismicLink = forwardRef( + function PrismicLink(props, ref) { + const { field, document, linkResolver, children, ...restProps } = props; + const { + href: computedHref, + rel: computedRel, + ...attrs + } = asLinkAttrs(field ?? document, { + linkResolver, + rel: typeof restProps.rel === "function" ? restProps.rel : undefined, + }); + + const href = ("href" in restProps ? restProps.href : computedHref) || ""; + + let rel = computedRel; + if ("rel" in restProps && typeof restProps.rel !== "function") { + rel = restProps.rel; + } + + const ResolvedLink = resolveDefaultExport(Link); + + return ( + + {"children" in props ? children : field?.text} + + ); + }, +); diff --git a/src/PrismicNextImage.tsx b/src/PrismicNextImage.tsx deleted file mode 100644 index 7ada3d7..0000000 --- a/src/PrismicNextImage.tsx +++ /dev/null @@ -1,185 +0,0 @@ -"use client"; - -import type { - ForwardRefExoticComponent, - PropsWithoutRef, - RefAttributes} from "react"; -import { - forwardRef -} from "react"; -import type { ImageProps } from "next/image"; -import Image from "next/image"; -import type { ImgixURLParams } from "imgix-url-builder"; -import { buildURL } from "imgix-url-builder"; -import type { ImageFieldImage} from "@prismicio/client"; -import { isFilled } from "@prismicio/client"; - -import { devMsg } from "./lib/devMsg"; -import { resolveDefaultExport } from "./lib/resolveDefaultExport"; - -import { imgixLoader } from "./imgixLoader"; - -const castInt = (input: string | number | undefined): number | undefined => { - if (typeof input === "number" || typeof input === "undefined") { - return input; - } else { - const parsed = Number.parseInt(input); - - if (Number.isNaN(parsed)) { - return undefined; - } else { - return parsed; - } - } -}; - -export type PrismicNextImageProps = Omit< - ImageProps, - "src" | "alt" | "loader" -> & { - /** The Prismic Image field or thumbnail to render. */ - field: ImageFieldImage | null | undefined; - - /** - * An object of Imgix URL API parameters to transform the image. - * - * @see https://docs.imgix.com/apis/rendering - */ - imgixParams?: { [P in keyof ImgixURLParams]: ImgixURLParams[P] | null }; - - /** - * Declare an image as decorative by providing `alt=""`. - * - * See: - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/alt#decorative_images - */ - alt?: ""; - - /** - * Declare an image as decorative only if the Image field does not have - * alternative text by providing `fallbackAlt=""`. - * - * See: - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/alt#decorative_images - */ - fallbackAlt?: ""; - - /** - * Rendered when the field is empty. If a fallback is not given, `null` will - * be rendered. - */ - fallback?: React.ReactNode; - - loader?: ImageProps["loader"] | null; -}; - -/** - * React component that renders an image from a Prismic Image field or one of - * its thumbnails using `next/image`. It will automatically set the `alt` - * attribute using the Image field's `alt` property. - * - * It uses an Imgix URL-based loader by default. A custom loader can be provided - * with the `loader` prop. If you would like to use the Next.js Image - * Optimization API instead, set `loader={undefined}`. - * - * @param props - Props for the component. - * - * @returns A responsive image component using `next/image` for the given Image - * field. - * - * @see To learn more about `next/image`, see: https://nextjs.org/docs/api-reference/next/image - */ -// The type annotation is necessary to avoid a type reference issue. -export const PrismicNextImage: ForwardRefExoticComponent< - PropsWithoutRef & RefAttributes -> = forwardRef( - function PrismicNextImage( - { - field, - imgixParams = {}, - alt, - fallbackAlt, - fill, - width, - height, - fallback = null, - loader = imgixLoader, - ...restProps - }, - ref, - ) { - if (process.env.NODE_ENV === "development") { - if (typeof alt === "string" && alt !== "") { - console.warn( - `[PrismicNextImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg( - "alt-must-be-an-empty-string", - )}`, - ); - } - - if (typeof fallbackAlt === "string" && fallbackAlt !== "") { - console.warn( - `[PrismicNextImage] The "fallbackAlt" prop can only be used to declare an image as decorative by passing an empty string (fallbackAlt="") but was provided a non-empty string. You can resolve this warning by removing the "fallbackAlt" prop or changing it to fallbackAlt="". For more details, see ${devMsg( - "alt-must-be-an-empty-string", - )}`, - ); - } - } - - if (!isFilled.imageThumbnail(field)) { - return <>{fallback}; - } - - const resolvedImgixParams = imgixParams; - for (const x in imgixParams) { - if (resolvedImgixParams[x as keyof typeof resolvedImgixParams] === null) { - resolvedImgixParams[x as keyof typeof resolvedImgixParams] = undefined; - } - } - - const src = buildURL(field.url, imgixParams as ImgixURLParams); - - const ar = field.dimensions.width / field.dimensions.height; - - const castedWidth = castInt(width); - const castedHeight = castInt(height); - - let resolvedWidth = castedWidth ?? field.dimensions.width; - let resolvedHeight = castedHeight ?? field.dimensions.height; - - if (castedWidth != null && castedHeight == null) { - resolvedHeight = castedWidth / ar; - } else if (castedWidth == null && castedHeight != null) { - resolvedWidth = castedHeight * ar; - } - - // A non-null assertion is required since we can't statically - // know if an alt attribute is available. - const resolvedAlt = (alt ?? (field.alt || fallbackAlt))!; - - if ( - process.env.NODE_ENV === "development" && - typeof resolvedAlt !== "string" - ) { - console.error( - `[PrismicNextImage] The following image is missing an "alt" property. Please add Alternative Text to the image in Prismic. To mark the image as decorative instead, add one of \`alt=""\` or \`fallbackAlt=""\`.`, - src, - ); - } - - const ResolvedImage = resolveDefaultExport(Image); - - return ( - - ); - }, -); diff --git a/src/PrismicNextLink.tsx b/src/PrismicNextLink.tsx deleted file mode 100644 index c5d081d..0000000 --- a/src/PrismicNextLink.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import type { ComponentProps} from "react"; -import { forwardRef } from "react"; -import Link from "next/link"; -import type { - AsLinkAttrsConfig, - LinkField, - LinkResolverFunction, - PrismicDocument} from "@prismicio/client"; -import { - asLinkAttrs, -} from "@prismicio/client"; - -import { resolveDefaultExport } from "./lib/resolveDefaultExport"; - -export type PrismicNextLinkProps = Omit< - ComponentProps, - "field" | "document" | "href" | "rel" -> & { - linkResolver?: LinkResolverFunction; - rel?: string | AsLinkAttrsConfig["rel"]; -} & ( - | { - field: LinkField | null | undefined; - document?: never; - href?: never; - } - | { - field?: never; - document: PrismicDocument | null | undefined; - href?: never; - } - | { - field?: never; - document?: never; - href: ComponentProps["href"]; - } - ); - -export const PrismicNextLink = forwardRef< - HTMLAnchorElement, - PrismicNextLinkProps ->(function PrismicNextLink(props, ref) { - const { field, document, linkResolver, children, ...restProps } = props; - const { - href: computedHref, - rel: computedRel, - ...attrs - } = asLinkAttrs(field ?? document, { - linkResolver, - rel: typeof restProps.rel === "function" ? restProps.rel : undefined, - }); - - const href = ("href" in restProps ? restProps.href : computedHref) || ""; - - let rel = computedRel; - if ("rel" in restProps && typeof restProps.rel !== "function") { - rel = restProps.rel; - } - - const ResolvedLink = resolveDefaultExport(Link); - - return ( - - {"children" in props ? children : field?.text} - - ); -}); diff --git a/src/PrismicRichText.tsx b/src/PrismicRichText.tsx new file mode 100644 index 0000000..a9b50d0 --- /dev/null +++ b/src/PrismicRichText.tsx @@ -0,0 +1,63 @@ +"use client"; + +import { PrismicImage } from "./PrismicImage"; +import { PrismicLink } from "./PrismicLink"; +import { + PrismicRichText as BasePrismicRichText, + type PrismicRichTextProps as BasePrismicRichTextProps, + type RichTextComponents, +} from "@prismicio/react"; +import type { FC } from "react"; + +/** + * Props for ``. + */ +export type PrismicRichTextProps = Omit< + BasePrismicRichTextProps, + "components" +> & { + components?: RichTextComponents; +}; + +export const defaultComponents: RichTextComponents = { + image: ({ node, key }) => { + return ( +

+ {node.linkTo ? ( + + + + ) : ( + + )} +

+ ); + }, + hyperlink: ({ node, children }) => ( + {children} + ), +}; + +/** + * Renders content from a Prismic rich text field as React components with + * Next.js-optimized defaults for images and links. + * + * @example + * + * ```tsx + * ; + * ``` + * + * @see {@link https://prismic.io/docs/fields/rich-text} + */ +export const PrismicRichText: FC = ({ + components, + ...restProps +}) => { + return ( + + ); +}; diff --git a/src/PrismicTable.tsx b/src/PrismicTable.tsx new file mode 100644 index 0000000..b19ae49 --- /dev/null +++ b/src/PrismicTable.tsx @@ -0,0 +1,33 @@ +"use client"; + +import { defaultComponents } from "./PrismicRichText"; +import { + PrismicTable as BasePrismicTable, + type PrismicTableProps, +} from "@prismicio/react"; +import type { FC } from "react"; + +/** + * Renders content from a Prismic table field as React components with + * Next.js-optimized defaults for images and links in cell content. + * + * @example + * + * ```tsx + * ; + * ``` + * + * @see Learn how to style tables and customize table element components: + * {@link https://prismic.io/docs/fields/table} + */ +export const PrismicTable: FC = ({ + components, + ...restProps +}) => { + return ( + + ); +}; diff --git a/src/index.ts b/src/index.ts index 2dfcddb..92d869d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,8 +3,17 @@ export { exitPreview } from "./exitPreview"; export { PrismicPreview } from "./PrismicPreview"; export type { PrismicPreviewProps } from "./PrismicPreview"; -export { PrismicNextLink } from "./PrismicNextLink"; -export type { PrismicNextLinkProps } from "./PrismicNextLink"; +export { PrismicImage, PrismicNextImage } from "./PrismicImage"; +export type { PrismicImageProps, PrismicNextImageProps } from "./PrismicImage"; + +export { PrismicLink, PrismicNextLink } from "./PrismicLink"; +export type { PrismicLinkProps, PrismicNextLinkProps } from "./PrismicLink"; + +export { PrismicRichText } from "./PrismicRichText"; +export type { PrismicRichTextProps } from "./PrismicRichText"; + +export { PrismicTable } from "./PrismicTable"; +export type { PrismicTableProps } from "@prismicio/react"; export { enableAutoPreviews } from "./enableAutoPreviews"; export type { EnableAutoPreviewsConfig } from "./enableAutoPreviews"; @@ -12,9 +21,6 @@ export type { EnableAutoPreviewsConfig } from "./enableAutoPreviews"; export { redirectToPreviewURL } from "./redirectToPreviewURL"; export type { RedirectToPreviewURLConfig } from "./redirectToPreviewURL"; -export { PrismicNextImage } from "./PrismicNextImage"; -export type { PrismicNextImageProps } from "./PrismicNextImage"; - export { SliceSimulator } from "./SliceSimulator"; export type { SliceSimulatorProps, @@ -29,3 +35,13 @@ export type { CreateClientConfig } from "./types"; export { createLocaleRedirect } from "./createLocaleRedirect"; export type { CreateLocaleRedirectConfig } from "./createLocaleRedirect"; + +// Re-exports from @prismicio/react +export { PrismicText, SliceZone, TODOSliceComponent } from "@prismicio/react"; +export type { + SliceComponentProps, + SliceComponentType, + SliceZoneProps, + RichTextComponents, + PrismicTextProps, +} from "@prismicio/react"; diff --git a/src/pages/index.ts b/src/pages/index.ts index 22a344f..0c838b5 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -1,8 +1,14 @@ -export { PrismicNextLink } from "../PrismicNextLink"; -export { type PrismicNextLinkProps } from "../PrismicNextLink"; +export { PrismicImage, PrismicNextImage } from "../PrismicImage"; +export type { PrismicImageProps, PrismicNextImageProps } from "../PrismicImage"; -export { PrismicNextImage } from "../PrismicNextImage"; -export { type PrismicNextImageProps } from "../PrismicNextImage"; +export { PrismicLink, PrismicNextLink } from "../PrismicLink"; +export type { PrismicLinkProps, PrismicNextLinkProps } from "../PrismicLink"; + +export { PrismicRichText } from "../PrismicRichText"; +export type { PrismicRichTextProps } from "../PrismicRichText"; + +export { PrismicTable } from "../PrismicTable"; +export type { PrismicTableProps } from "@prismicio/react"; export { SliceSimulator } from "./SliceSimulator"; export type { @@ -31,3 +37,13 @@ export type { CreateClientConfig } from "./types"; export { createLocaleRedirect } from "../createLocaleRedirect"; export type { CreateLocaleRedirectConfig } from "../createLocaleRedirect"; + +// Re-exports from @prismicio/react +export { PrismicText, SliceZone, TODOSliceComponent } from "@prismicio/react"; +export type { + SliceComponentProps, + SliceComponentType, + SliceZoneProps, + RichTextComponents, + PrismicTextProps, +} from "@prismicio/react";