@dotcms/react
Version:
Official React Components library to render a dotCMS page.
88 lines (85 loc) • 2.92 kB
JavaScript
"use client";
import { jsx, Fragment } from 'react/jsx-runtime';
import { useRef, useMemo, useContext } from 'react';
import { getDotContentletAttributes, CUSTOM_NO_COMPONENT } from '@dotcms/uve/internal';
import { DotCMSPageContext } from '../../contexts/DotCMSPageContext.esm.js';
import { useCheckVisibleContent } from '../../hooks/useCheckVisibleContent.esm.js';
import { useIsDevMode } from '../../hooks/useIsDevMode.esm.js';
import { FallbackComponent } from '../FallbackComponent/FallbackComponent.esm.js';
/**
* CSS class name for contentlet elements
*/
const CONTENTLET_CLASS = 'dotcms-contentlet';
/**
* Contentlet component that renders DotCMS content with development mode support
*
* @component
* @param {DotCMSContentletRendererProps} props - Component properties
* @param {DotCMSContentlet} props.contentlet - The contentlet to be rendered
* @param {string} props.container - The container identifier
* @returns {JSX.Element} Rendered contentlet with appropriate wrapper and attributes
*
* @example
* ```tsx
* <Contentlet
* contentlet={myContentlet}
* container="container-1"
* />
* ```
*/
function Contentlet({
contentlet,
container
}) {
const ref = useRef(null);
const isDevMode = useIsDevMode();
const haveContent = useCheckVisibleContent(ref);
const style = useMemo(() => isDevMode ? {
minHeight: haveContent ? undefined : '4rem'
} : {}, [isDevMode, haveContent]);
// UVE attributes - always applied
const dotAttributes = useMemo(() => getDotContentletAttributes(contentlet, container), [contentlet, container]);
return jsx("div", Object.assign({}, dotAttributes, {
"data-dot-object": "contentlet",
className: CONTENTLET_CLASS,
ref: ref,
style: style,
children: jsx(CustomComponent, {
contentlet: contentlet
})
}));
}
/**
* Renders a custom component based on the contentlet type or falls back to a default component
*
* @component
* @param {CustomComponentProps} props - Component properties
* @param {DotCMSContentlet} props.contentlet - The contentlet data to render
* @returns {JSX.Element} The rendered custom component or fallback component
*
* @internal
*/
function CustomComponent({
contentlet
}) {
const {
userComponents,
slots
} = useContext(DotCMSPageContext);
const slotNode = contentlet != null && contentlet.identifier ? slots == null ? void 0 : slots[contentlet.identifier] : undefined;
if (slotNode !== undefined) {
return jsx(Fragment, {
children: slotNode
});
}
const UserComponent = userComponents[contentlet == null ? void 0 : contentlet.contentType];
if (UserComponent) {
return jsx(UserComponent, Object.assign({}, contentlet));
}
const UserNoComponent = userComponents[CUSTOM_NO_COMPONENT];
return jsx(FallbackComponent, {
UserNoComponent: UserNoComponent,
contentlet: contentlet
});
}
export { CONTENTLET_CLASS, Contentlet };