import {useContent} from '../../hooks/content/useContent' import {Content} from '../../types' import {ContentMonitor} from './content-monitor' interface BaseContentWrapperProps { /** A render function that receives the content data and loading state, and returns a React element. */ children: ({ content, loading, }: { content?: Content loading: boolean }) => React.JSX.Element | null } interface PublicIdContentWrapperProps extends BaseContentWrapperProps { publicId: string externalId?: never } interface ExternalIdContentWrapperProps extends BaseContentWrapperProps { externalId: string publicId?: never } type ContentWrapperProps = | PublicIdContentWrapperProps | ExternalIdContentWrapperProps /** * The `ContentWrapper` component fetches and provides user-generated content data using a render function pattern. It accepts either a `publicId` or `externalId` to identify the content, and passes the resolved content along with loading state to a child render function. * * If `content` is not set (and `loading` is `false`), the ID was either not found or the content has been moderated and will not be shown. Users will always be able to see their own content. * * Use `ContentWrapper` when you need full control over how content is rendered. For a simpler image-specific wrapper, see `ImageContentWrapper`. * * > Note: Content rendered through `ContentWrapper` is wrapped in a `ContentMonitor` that allows users to report it for moderation. * @publicDocs */ // It's too messy in the docs to show the complete types here so we show a simplified version export interface ContentWrapperPropsForDocs extends BaseContentWrapperProps { /** The public ID of the content item (use this OR externalId). */ publicId?: string /** The external ID of the content item (use this OR publicId). */ externalId?: string } export function ContentWrapper({ publicId, externalId, children, }: ContentWrapperProps) { const {content, loading} = useContent({ identifiers: [{publicId, externalId}], skip: !publicId && !externalId, }) const contentItem = content?.[0] if (loading || !contentItem) { return children({loading}) } return ( {children({content: contentItem, loading})} ) }