@dotcms/react 1.2.5-next.7 → 1.2.6-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -17
- package/_virtual/_commonjsHelpers.esm.js +3 -0
- package/_virtual/_style-inject.esm.js +30 -0
- package/_virtual/make-built-in.esm.js +3 -0
- package/_virtual/new-promise-capability.esm.js +3 -0
- package/_virtual/object-define-properties.esm.js +3 -0
- package/_virtual/object-define-property.esm.js +3 -0
- package/_virtual/object-get-own-property-descriptor.esm.js +3 -0
- package/_virtual/object-get-own-property-names.esm.js +3 -0
- package/_virtual/object-get-own-property-symbols.esm.js +3 -0
- package/_virtual/object-property-is-enumerable.esm.js +3 -0
- package/_virtual/shared-store.esm.js +3 -0
- package/index.esm.js +9 -7168
- package/index.server.d.ts +1 -0
- package/index.server.esm.js +8 -0
- package/libs/sdk/react/src/lib/next/components/Column/Column.esm.js +50 -0
- package/libs/sdk/react/src/lib/next/components/Column/Column.module.css.esm.js +8 -0
- package/libs/sdk/react/src/lib/next/components/Container/Container.esm.js +58 -0
- package/libs/sdk/react/src/lib/next/components/Container/ContainerFallbacks.esm.js +61 -0
- package/libs/sdk/react/src/lib/next/components/Contentlet/Contentlet.esm.js +88 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/DotCMSBlockEditorRenderer.esm.js +46 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/BlockEditorBlock.esm.js +182 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/Code.esm.js +37 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/DotContent.esm.js +47 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/GridBlock.esm.js +47 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/Image.esm.js +22 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/Lists.esm.js +43 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/NoComponentProvided.esm.js +40 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/Table.esm.js +55 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/Texts.esm.js +158 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/Video.esm.js +43 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSEditableText/DotCMSEditableText.esm.js +190 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSEditableText/utils.esm.js +13 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSLayoutBody/DotCMSLayoutBody.esm.js +44 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSLayoutBody/DotCMSPageProvider.esm.js +30 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSLayoutBody/components/ErrorMessage.esm.js +43 -0
- package/libs/sdk/react/src/lib/next/components/DotCMSShow/DotCMSShow.esm.js +49 -0
- package/libs/sdk/react/src/lib/next/components/FallbackComponent/FallbackComponent.esm.js +55 -0
- package/libs/sdk/react/src/lib/next/components/Row/Row.esm.js +32 -0
- package/libs/sdk/react/src/lib/next/components/Row/Row.module.css.esm.js +8 -0
- package/libs/sdk/react/src/lib/next/contexts/DotCMSPageContext.esm.js +16 -0
- package/libs/sdk/react/src/lib/next/hooks/useAISearch.esm.js +131 -0
- package/libs/sdk/react/src/lib/next/hooks/useCheckVisibleContent.esm.js +42 -0
- package/libs/sdk/react/src/lib/next/hooks/useDotCMSShowWhen.esm.js +44 -0
- package/libs/sdk/react/src/lib/next/hooks/useEditableDotCMSPage.esm.js +133 -0
- package/libs/sdk/react/src/lib/next/hooks/useIsDevMode.esm.js +37 -0
- package/libs/sdk/react/src/lib/next/hooks/useStyleEditorSchemas.esm.js +15 -0
- package/libs/sdk/react/src/lib/next/utils/buildSlots.esm.js +46 -0
- package/package.json +2 -1
- package/src/index.d.ts +1 -0
- package/src/index.server.d.ts +11 -0
- package/src/lib/next/components/DotCMSBlockEditorRenderer/DotCMSBlockEditorRenderer.d.ts +2 -1
- package/src/lib/next/components/DotCMSBlockEditorRenderer/components/BlockEditorBlock.d.ts +2 -1
- package/src/lib/next/components/DotCMSBlockEditorRenderer/components/blocks/DotContent.d.ts +2 -1
- package/src/lib/next/components/DotCMSLayoutBody/DotCMSLayoutBody.d.ts +20 -1
- package/src/lib/next/components/DotCMSLayoutBody/DotCMSPageProvider.d.ts +18 -0
- package/src/lib/next/contexts/DotCMSPageContext.d.ts +3 -0
- package/src/lib/next/utils/buildSlots.d.ts +24 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index.server";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { DotCMSLayoutBody } from './libs/sdk/react/src/lib/next/components/DotCMSLayoutBody/DotCMSLayoutBody.esm.js';
|
|
2
|
+
export { DotCMSShow } from './libs/sdk/react/src/lib/next/components/DotCMSShow/DotCMSShow.esm.js';
|
|
3
|
+
export { useDotCMSShowWhen } from './libs/sdk/react/src/lib/next/hooks/useDotCMSShowWhen.esm.js';
|
|
4
|
+
export { useEditableDotCMSPage } from './libs/sdk/react/src/lib/next/hooks/useEditableDotCMSPage.esm.js';
|
|
5
|
+
export { DotCMSBlockEditorRenderer } from './libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer/DotCMSBlockEditorRenderer.esm.js';
|
|
6
|
+
export { useAISearch } from './libs/sdk/react/src/lib/next/hooks/useAISearch.esm.js';
|
|
7
|
+
export { useStyleEditorSchemas } from './libs/sdk/react/src/lib/next/hooks/useStyleEditorSchemas.esm.js';
|
|
8
|
+
export { buildSlots } from './libs/sdk/react/src/lib/next/utils/buildSlots.esm.js';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import '../../../../../../../../node_modules/core-js/modules/esnext.iterator.constructor.esm.js';
|
|
2
|
+
import '../../../../../../../../node_modules/core-js/modules/esnext.iterator.map.esm.js';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
|
|
5
|
+
import styles from './Column.module.css.esm.js';
|
|
6
|
+
import { Container } from '../Container/Container.esm.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
*
|
|
11
|
+
* Renders a Column component that represents a single column in a 12-column grid system.
|
|
12
|
+
* The column's position and width are determined by the leftOffset and width properties
|
|
13
|
+
* from the dotCMS Page API. Uses CSS Grid classes for positioning.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <Column column={{
|
|
18
|
+
* leftOffset: 0,
|
|
19
|
+
* width: 6,
|
|
20
|
+
* styleClass: "custom-class",
|
|
21
|
+
* containers: []
|
|
22
|
+
* }} />
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
|
|
26
|
+
* @export
|
|
27
|
+
* @param {ColumnProps} { column } - Column configuration object
|
|
28
|
+
* @return {JSX.Element} Rendered column with its containers positioned in the grid
|
|
29
|
+
*/
|
|
30
|
+
function Column({
|
|
31
|
+
column
|
|
32
|
+
}) {
|
|
33
|
+
const {
|
|
34
|
+
startClass,
|
|
35
|
+
endClass
|
|
36
|
+
} = getColumnPositionClasses(column);
|
|
37
|
+
const combinedClasses = combineClasses([styles[endClass], styles[startClass]]);
|
|
38
|
+
return jsx("div", {
|
|
39
|
+
"data-dot": "column",
|
|
40
|
+
className: combinedClasses,
|
|
41
|
+
children: jsx("div", {
|
|
42
|
+
className: column.styleClass,
|
|
43
|
+
children: column.containers.map(container => jsx(Container, {
|
|
44
|
+
container: container
|
|
45
|
+
}, `${container.identifier}-${container.uuid}`))
|
|
46
|
+
})
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { Column };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import styleInject from '../../../../../../../../_virtual/_style-inject.esm.js';
|
|
2
|
+
|
|
3
|
+
var css = "._col-start-1_1myqa_1 {\n grid-column-start: 1;\n}\n\n._col-start-2_1myqa_5 {\n grid-column-start: 2;\n}\n\n._col-start-3_1myqa_9 {\n grid-column-start: 3;\n}\n\n._col-start-4_1myqa_13 {\n grid-column-start: 4;\n}\n\n._col-start-5_1myqa_17 {\n grid-column-start: 5;\n}\n\n._col-start-6_1myqa_21 {\n grid-column-start: 6;\n}\n\n._col-start-7_1myqa_25 {\n grid-column-start: 7;\n}\n\n._col-start-8_1myqa_29 {\n grid-column-start: 8;\n}\n\n._col-start-9_1myqa_33 {\n grid-column-start: 9;\n}\n\n._col-start-10_1myqa_37 {\n grid-column-start: 10;\n}\n\n._col-start-11_1myqa_41 {\n grid-column-start: 11;\n}\n\n._col-start-12_1myqa_45 {\n grid-column-start: 12;\n}\n\n._col-end-1_1myqa_49 {\n grid-column-end: 1;\n}\n\n._col-end-2_1myqa_53 {\n grid-column-end: 2;\n}\n\n._col-end-3_1myqa_57 {\n grid-column-end: 3;\n}\n\n._col-end-4_1myqa_61 {\n grid-column-end: 4;\n}\n\n._col-end-5_1myqa_65 {\n grid-column-end: 5;\n}\n\n._col-end-6_1myqa_69 {\n grid-column-end: 6;\n}\n\n._col-end-7_1myqa_73 {\n grid-column-end: 7;\n}\n\n._col-end-8_1myqa_77 {\n grid-column-end: 8;\n}\n\n._col-end-9_1myqa_81 {\n grid-column-end: 9;\n}\n\n._col-end-10_1myqa_85 {\n grid-column-end: 10;\n}\n\n._col-end-11_1myqa_89 {\n grid-column-end: 11;\n}\n\n._col-end-12_1myqa_93 {\n grid-column-end: 12;\n}\n\n._col-end-13_1myqa_97 {\n grid-column-end: 13;\n}\n";
|
|
4
|
+
|
|
5
|
+
styleInject(css);
|
|
6
|
+
var styles = {"col-start-1":"_col-start-1_1myqa_1","col-start-2":"_col-start-2_1myqa_5","col-start-3":"_col-start-3_1myqa_9","col-start-4":"_col-start-4_1myqa_13","col-start-5":"_col-start-5_1myqa_17","col-start-6":"_col-start-6_1myqa_21","col-start-7":"_col-start-7_1myqa_25","col-start-8":"_col-start-8_1myqa_29","col-start-9":"_col-start-9_1myqa_33","col-start-10":"_col-start-10_1myqa_37","col-start-11":"_col-start-11_1myqa_41","col-start-12":"_col-start-12_1myqa_45","col-end-1":"_col-end-1_1myqa_49","col-end-2":"_col-end-2_1myqa_53","col-end-3":"_col-end-3_1myqa_57","col-end-4":"_col-end-4_1myqa_61","col-end-5":"_col-end-5_1myqa_65","col-end-6":"_col-end-6_1myqa_69","col-end-7":"_col-end-7_1myqa_73","col-end-8":"_col-end-8_1myqa_77","col-end-9":"_col-end-9_1myqa_81","col-end-10":"_col-end-10_1myqa_85","col-end-11":"_col-end-11_1myqa_89","col-end-12":"_col-end-12_1myqa_93","col-end-13":"_col-end-13_1myqa_97"};
|
|
7
|
+
|
|
8
|
+
export { styles as default };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import '../../../../../../../../node_modules/core-js/modules/es.json.stringify.esm.js';
|
|
3
|
+
import '../../../../../../../../node_modules/core-js/modules/es.object.assign.esm.js';
|
|
4
|
+
import '../../../../../../../../node_modules/core-js/modules/esnext.iterator.constructor.esm.js';
|
|
5
|
+
import '../../../../../../../../node_modules/core-js/modules/esnext.iterator.map.esm.js';
|
|
6
|
+
import { jsx } from 'react/jsx-runtime';
|
|
7
|
+
import { useContext, useMemo } from 'react';
|
|
8
|
+
import { getContainersData, getContentletsInContainer, getDotContainerAttributes } from '@dotcms/uve/internal';
|
|
9
|
+
import { ContainerNotFound, EmptyContainer } from './ContainerFallbacks.esm.js';
|
|
10
|
+
import { DotCMSPageContext } from '../../contexts/DotCMSPageContext.esm.js';
|
|
11
|
+
import { Contentlet } from '../Contentlet/Contentlet.esm.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
*
|
|
16
|
+
* Container component that renders DotCMS containers and their contentlets.
|
|
17
|
+
* This component is responsible for:
|
|
18
|
+
* - Rendering container content based on DotCMS Page API data
|
|
19
|
+
* - Handling empty container states
|
|
20
|
+
* - Providing proper data attributes for DotCMS functionality
|
|
21
|
+
* - Managing container contentlets rendering
|
|
22
|
+
*
|
|
23
|
+
* @component
|
|
24
|
+
* @param {DotCMSContainerRendererProps} props - Component properties
|
|
25
|
+
* @returns {JSX.Element} Rendered container with its contentlets or empty state message
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* <Container container={containerData} />
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function Container({
|
|
33
|
+
container
|
|
34
|
+
}) {
|
|
35
|
+
const {
|
|
36
|
+
pageAsset
|
|
37
|
+
} = useContext(DotCMSPageContext);
|
|
38
|
+
const containerData = useMemo(() => getContainersData(pageAsset, container), [pageAsset, container]);
|
|
39
|
+
const contentlets = useMemo(() => getContentletsInContainer(pageAsset, container), [pageAsset, container]);
|
|
40
|
+
if (!containerData) {
|
|
41
|
+
return jsx(ContainerNotFound, {
|
|
42
|
+
identifier: container.identifier
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const isEmpty = contentlets.length === 0;
|
|
46
|
+
const dotAttributes = getDotContainerAttributes(containerData);
|
|
47
|
+
if (isEmpty) {
|
|
48
|
+
return jsx(EmptyContainer, Object.assign({}, dotAttributes));
|
|
49
|
+
}
|
|
50
|
+
return jsx("div", Object.assign({}, dotAttributes, {
|
|
51
|
+
children: contentlets.map(contentlet => jsx(Contentlet, {
|
|
52
|
+
contentlet: contentlet,
|
|
53
|
+
container: JSON.stringify(containerData)
|
|
54
|
+
}, contentlet.identifier))
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { Container };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import '../../../../../../../../node_modules/core-js/modules/es.object.assign.esm.js';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
import { EMPTY_CONTAINER_STYLE_REACT } from '@dotcms/uve/internal';
|
|
6
|
+
import { useIsDevMode } from '../../hooks/useIsDevMode.esm.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
*
|
|
11
|
+
* Component to display when a container is not found in the system.
|
|
12
|
+
* Only renders in development mode for debugging purposes.
|
|
13
|
+
*
|
|
14
|
+
* @component
|
|
15
|
+
* @param {Object} props - Component properties
|
|
16
|
+
* @param {string} props.identifier - Container identifier
|
|
17
|
+
* @returns {JSX.Element | null} Message about missing container or null in production
|
|
18
|
+
*/
|
|
19
|
+
const ContainerNotFound = ({
|
|
20
|
+
identifier
|
|
21
|
+
}) => {
|
|
22
|
+
const isDevMode = useIsDevMode();
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!isDevMode) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
console.error(`Container with identifier ${identifier} not found`);
|
|
28
|
+
}, [identifier, isDevMode]);
|
|
29
|
+
if (!isDevMode) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return jsxs("div", {
|
|
33
|
+
"data-testid": "container-not-found",
|
|
34
|
+
style: EMPTY_CONTAINER_STYLE_REACT,
|
|
35
|
+
children: ["This container with identifier ", identifier, " was not found."]
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*
|
|
41
|
+
* Component to display when a container is empty.
|
|
42
|
+
*
|
|
43
|
+
* @param {DotContainerAttributes} dotAttributes
|
|
44
|
+
* @return {*}
|
|
45
|
+
*/
|
|
46
|
+
const EmptyContainer = dotAttributes => {
|
|
47
|
+
const isDevMode = useIsDevMode();
|
|
48
|
+
if (!isDevMode) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return jsx("div", Object.assign({}, dotAttributes, {
|
|
52
|
+
style: EMPTY_CONTAINER_STYLE_REACT,
|
|
53
|
+
children: jsx("span", {
|
|
54
|
+
"data-testid": "empty-container-message",
|
|
55
|
+
"data-dot-object": "empty-content",
|
|
56
|
+
children: "This container is empty."
|
|
57
|
+
})
|
|
58
|
+
}));
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export { ContainerNotFound, EmptyContainer };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import '../../../../../../../../node_modules/core-js/modules/es.object.assign.esm.js';
|
|
3
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import { useRef, useMemo, useContext } from 'react';
|
|
5
|
+
import { getDotContentletAttributes, CUSTOM_NO_COMPONENT } from '@dotcms/uve/internal';
|
|
6
|
+
import { DotCMSPageContext } from '../../contexts/DotCMSPageContext.esm.js';
|
|
7
|
+
import { useCheckVisibleContent } from '../../hooks/useCheckVisibleContent.esm.js';
|
|
8
|
+
import { useIsDevMode } from '../../hooks/useIsDevMode.esm.js';
|
|
9
|
+
import { FallbackComponent } from '../FallbackComponent/FallbackComponent.esm.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* CSS class name for contentlet elements
|
|
13
|
+
*/
|
|
14
|
+
const CONTENTLET_CLASS = 'dotcms-contentlet';
|
|
15
|
+
/**
|
|
16
|
+
* Contentlet component that renders DotCMS content with development mode support
|
|
17
|
+
*
|
|
18
|
+
* @component
|
|
19
|
+
* @param {DotCMSContentletRendererProps} props - Component properties
|
|
20
|
+
* @param {DotCMSContentlet} props.contentlet - The contentlet to be rendered
|
|
21
|
+
* @param {string} props.container - The container identifier
|
|
22
|
+
* @returns {JSX.Element} Rendered contentlet with appropriate wrapper and attributes
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <Contentlet
|
|
27
|
+
* contentlet={myContentlet}
|
|
28
|
+
* container="container-1"
|
|
29
|
+
* />
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function Contentlet({
|
|
33
|
+
contentlet,
|
|
34
|
+
container
|
|
35
|
+
}) {
|
|
36
|
+
const ref = useRef(null);
|
|
37
|
+
const isDevMode = useIsDevMode();
|
|
38
|
+
const haveContent = useCheckVisibleContent(ref);
|
|
39
|
+
const style = useMemo(() => isDevMode ? {
|
|
40
|
+
minHeight: haveContent ? undefined : '4rem'
|
|
41
|
+
} : {}, [isDevMode, haveContent]);
|
|
42
|
+
// UVE attributes - always applied
|
|
43
|
+
const dotAttributes = useMemo(() => getDotContentletAttributes(contentlet, container), [contentlet, container]);
|
|
44
|
+
return jsx("div", Object.assign({}, dotAttributes, {
|
|
45
|
+
"data-dot-object": "contentlet",
|
|
46
|
+
className: CONTENTLET_CLASS,
|
|
47
|
+
ref: ref,
|
|
48
|
+
style: style,
|
|
49
|
+
children: jsx(CustomComponent, {
|
|
50
|
+
contentlet: contentlet
|
|
51
|
+
})
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Renders a custom component based on the contentlet type or falls back to a default component
|
|
56
|
+
*
|
|
57
|
+
* @component
|
|
58
|
+
* @param {CustomComponentProps} props - Component properties
|
|
59
|
+
* @param {DotCMSContentlet} props.contentlet - The contentlet data to render
|
|
60
|
+
* @returns {JSX.Element} The rendered custom component or fallback component
|
|
61
|
+
*
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
function CustomComponent({
|
|
65
|
+
contentlet
|
|
66
|
+
}) {
|
|
67
|
+
const {
|
|
68
|
+
userComponents,
|
|
69
|
+
slots
|
|
70
|
+
} = useContext(DotCMSPageContext);
|
|
71
|
+
const slotNode = slots == null ? void 0 : slots[contentlet == null ? void 0 : contentlet.identifier];
|
|
72
|
+
if (slotNode !== undefined) {
|
|
73
|
+
return jsx(Fragment, {
|
|
74
|
+
children: slotNode
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const UserComponent = userComponents[contentlet == null ? void 0 : contentlet.contentType];
|
|
78
|
+
if (UserComponent) {
|
|
79
|
+
return jsx(UserComponent, Object.assign({}, contentlet));
|
|
80
|
+
}
|
|
81
|
+
const UserNoComponent = userComponents[CUSTOM_NO_COMPONENT];
|
|
82
|
+
return jsx(FallbackComponent, {
|
|
83
|
+
UserNoComponent: UserNoComponent,
|
|
84
|
+
contentlet: contentlet
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { CONTENTLET_CLASS, Contentlet };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { isValidBlocks } from '@dotcms/uve/internal';
|
|
3
|
+
import { BlockEditorBlock } from './components/BlockEditorBlock.esm.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* BlockEditorRenderer component for rendering block editor field.
|
|
7
|
+
*
|
|
8
|
+
* @component
|
|
9
|
+
* @param {Object} props - The component props.
|
|
10
|
+
* @param {BlockEditorNode} props.blocks - The blocks of content to render.
|
|
11
|
+
* @param {CustomRenderer} [props.customRenderers] - Optional custom renderers for specific block types.
|
|
12
|
+
* @param {string} [props.className] - Optional CSS class name for the container div.
|
|
13
|
+
* @param {React.CSSProperties} [props.style] - Optional inline styles for the container div.
|
|
14
|
+
* @returns {JSX.Element} A div containing the rendered blocks of content.
|
|
15
|
+
*/
|
|
16
|
+
const DotCMSBlockEditorRenderer = ({
|
|
17
|
+
blocks,
|
|
18
|
+
style,
|
|
19
|
+
className,
|
|
20
|
+
customRenderers,
|
|
21
|
+
isDevMode: _isDevMode = false
|
|
22
|
+
}) => {
|
|
23
|
+
const validationResult = isValidBlocks(blocks);
|
|
24
|
+
if (validationResult.error) {
|
|
25
|
+
console.error(validationResult.error);
|
|
26
|
+
if (_isDevMode) {
|
|
27
|
+
return jsx("div", {
|
|
28
|
+
"data-testid": "invalid-blocks-message",
|
|
29
|
+
children: validationResult.error
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return jsx("div", {
|
|
35
|
+
className: className,
|
|
36
|
+
style: style,
|
|
37
|
+
"data-testid": "dot-block-editor-container",
|
|
38
|
+
children: jsx(BlockEditorBlock, {
|
|
39
|
+
content: blocks == null ? void 0 : blocks.content,
|
|
40
|
+
customRenderers: customRenderers,
|
|
41
|
+
isDevMode: _isDevMode
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { DotCMSBlockEditorRenderer };
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import '../../../../../../../../../node_modules/core-js/modules/es.object.assign.esm.js';
|
|
2
|
+
import '../../../../../../../../../node_modules/core-js/modules/esnext.iterator.constructor.esm.js';
|
|
3
|
+
import '../../../../../../../../../node_modules/core-js/modules/esnext.iterator.map.esm.js';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
import { BlockEditorDefaultBlocks } from '@dotcms/types/internal';
|
|
6
|
+
import { getUVEState } from '@dotcms/uve';
|
|
7
|
+
import { CodeBlock, BlockQuote } from './blocks/Code.esm.js';
|
|
8
|
+
import { DotContent } from './blocks/DotContent.esm.js';
|
|
9
|
+
import { GridBlock } from './blocks/GridBlock.esm.js';
|
|
10
|
+
import { DotCMSImage } from './blocks/Image.esm.js';
|
|
11
|
+
import { ListItem, OrderedList, BulletList } from './blocks/Lists.esm.js';
|
|
12
|
+
import { TableRenderer } from './blocks/Table.esm.js';
|
|
13
|
+
import { TextBlock, Heading, Paragraph } from './blocks/Texts.esm.js';
|
|
14
|
+
import { DotCMSVideo } from './blocks/Video.esm.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Renders a block editor item based on the provided content and custom renderers.
|
|
18
|
+
*
|
|
19
|
+
* @param content - The content nodes to render.
|
|
20
|
+
* @param customRenderers - Optional custom renderers for specific node types.
|
|
21
|
+
* @returns The rendered block editor item.
|
|
22
|
+
*/
|
|
23
|
+
const BlockEditorBlock = ({
|
|
24
|
+
content,
|
|
25
|
+
customRenderers,
|
|
26
|
+
isDevMode
|
|
27
|
+
}) => {
|
|
28
|
+
if (!content) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return content == null ? void 0 : content.map((node, index) => {
|
|
32
|
+
var _node$content;
|
|
33
|
+
const CustomRendererComponent = customRenderers == null ? void 0 : customRenderers[node.type];
|
|
34
|
+
const key = `${node.type}-${index}`;
|
|
35
|
+
if (CustomRendererComponent) {
|
|
36
|
+
return jsx(CustomRendererComponent, {
|
|
37
|
+
node: node,
|
|
38
|
+
children: jsx(BlockEditorBlock, {
|
|
39
|
+
content: node.content,
|
|
40
|
+
customRenderers: customRenderers,
|
|
41
|
+
isDevMode: isDevMode
|
|
42
|
+
})
|
|
43
|
+
}, key);
|
|
44
|
+
}
|
|
45
|
+
switch (node.type) {
|
|
46
|
+
case BlockEditorDefaultBlocks.PARAGRAPH:
|
|
47
|
+
return jsx(Paragraph, {
|
|
48
|
+
node: node,
|
|
49
|
+
children: jsx(BlockEditorBlock, {
|
|
50
|
+
content: node.content,
|
|
51
|
+
customRenderers: customRenderers,
|
|
52
|
+
isDevMode: isDevMode
|
|
53
|
+
})
|
|
54
|
+
}, key);
|
|
55
|
+
case BlockEditorDefaultBlocks.HEADING:
|
|
56
|
+
return jsx(Heading, {
|
|
57
|
+
node: node,
|
|
58
|
+
children: jsx(BlockEditorBlock, {
|
|
59
|
+
content: node.content,
|
|
60
|
+
customRenderers: customRenderers,
|
|
61
|
+
isDevMode: isDevMode
|
|
62
|
+
})
|
|
63
|
+
}, key);
|
|
64
|
+
case BlockEditorDefaultBlocks.TEXT:
|
|
65
|
+
return jsx(TextBlock, Object.assign({}, node), key);
|
|
66
|
+
case BlockEditorDefaultBlocks.BULLET_LIST:
|
|
67
|
+
return jsx(BulletList, {
|
|
68
|
+
children: jsx(BlockEditorBlock, {
|
|
69
|
+
content: node.content,
|
|
70
|
+
customRenderers: customRenderers,
|
|
71
|
+
isDevMode: isDevMode
|
|
72
|
+
})
|
|
73
|
+
}, key);
|
|
74
|
+
case BlockEditorDefaultBlocks.ORDERED_LIST:
|
|
75
|
+
return jsx(OrderedList, {
|
|
76
|
+
children: jsx(BlockEditorBlock, {
|
|
77
|
+
content: node.content,
|
|
78
|
+
customRenderers: customRenderers,
|
|
79
|
+
isDevMode: isDevMode
|
|
80
|
+
})
|
|
81
|
+
}, key);
|
|
82
|
+
case BlockEditorDefaultBlocks.LIST_ITEM:
|
|
83
|
+
return jsx(ListItem, {
|
|
84
|
+
children: jsx(BlockEditorBlock, {
|
|
85
|
+
content: node.content,
|
|
86
|
+
customRenderers: customRenderers,
|
|
87
|
+
isDevMode: isDevMode
|
|
88
|
+
})
|
|
89
|
+
}, key);
|
|
90
|
+
case BlockEditorDefaultBlocks.BLOCK_QUOTE:
|
|
91
|
+
return jsx(BlockQuote, {
|
|
92
|
+
children: jsx(BlockEditorBlock, {
|
|
93
|
+
content: node.content,
|
|
94
|
+
customRenderers: customRenderers,
|
|
95
|
+
isDevMode: isDevMode
|
|
96
|
+
})
|
|
97
|
+
}, key);
|
|
98
|
+
case BlockEditorDefaultBlocks.CODE_BLOCK:
|
|
99
|
+
return jsx(CodeBlock, {
|
|
100
|
+
node: node,
|
|
101
|
+
children: jsx(BlockEditorBlock, {
|
|
102
|
+
content: node.content,
|
|
103
|
+
customRenderers: customRenderers,
|
|
104
|
+
isDevMode: isDevMode
|
|
105
|
+
})
|
|
106
|
+
}, key);
|
|
107
|
+
case BlockEditorDefaultBlocks.HARDBREAK:
|
|
108
|
+
return jsx("br", {}, key);
|
|
109
|
+
case BlockEditorDefaultBlocks.HORIZONTAL_RULE:
|
|
110
|
+
return jsx("hr", {}, key);
|
|
111
|
+
case BlockEditorDefaultBlocks.DOT_IMAGE:
|
|
112
|
+
return jsx(DotCMSImage, {
|
|
113
|
+
node: node
|
|
114
|
+
}, key);
|
|
115
|
+
case BlockEditorDefaultBlocks.DOT_VIDEO:
|
|
116
|
+
return jsx(DotCMSVideo, {
|
|
117
|
+
node: node
|
|
118
|
+
}, key);
|
|
119
|
+
case BlockEditorDefaultBlocks.TABLE:
|
|
120
|
+
return jsx(TableRenderer, {
|
|
121
|
+
content: (_node$content = node.content) != null ? _node$content : [],
|
|
122
|
+
blockEditorItem: BlockEditorBlock
|
|
123
|
+
}, key);
|
|
124
|
+
case BlockEditorDefaultBlocks.GRID_BLOCK:
|
|
125
|
+
return jsx(GridBlock, {
|
|
126
|
+
node: node,
|
|
127
|
+
blockEditorBlock: BlockEditorBlock,
|
|
128
|
+
customRenderers: customRenderers
|
|
129
|
+
}, key);
|
|
130
|
+
case BlockEditorDefaultBlocks.DOT_CONTENT:
|
|
131
|
+
return jsx(DotContent, {
|
|
132
|
+
customRenderers: customRenderers,
|
|
133
|
+
node: node,
|
|
134
|
+
isDevMode: isDevMode
|
|
135
|
+
}, key);
|
|
136
|
+
default:
|
|
137
|
+
return jsx(UnknownBlock, {
|
|
138
|
+
node: node
|
|
139
|
+
}, key);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Renders an unknown block type with a warning message in development mode.
|
|
145
|
+
*
|
|
146
|
+
* @param node - The block editor node to render.
|
|
147
|
+
* @returns The rendered block or null if in production mode.
|
|
148
|
+
*/
|
|
149
|
+
const UnknownBlock = ({
|
|
150
|
+
node
|
|
151
|
+
}) => {
|
|
152
|
+
const style = {
|
|
153
|
+
backgroundColor: '#fff5f5',
|
|
154
|
+
color: '#333',
|
|
155
|
+
padding: '1rem',
|
|
156
|
+
borderRadius: '0.5rem',
|
|
157
|
+
marginBottom: '1rem',
|
|
158
|
+
marginTop: '1rem',
|
|
159
|
+
border: '1px solid #fc8181'
|
|
160
|
+
};
|
|
161
|
+
if (getUVEState()) {
|
|
162
|
+
return jsxs("div", {
|
|
163
|
+
style: style,
|
|
164
|
+
children: [jsx("strong", {
|
|
165
|
+
style: {
|
|
166
|
+
color: '#c53030'
|
|
167
|
+
},
|
|
168
|
+
children: "Warning:"
|
|
169
|
+
}), " The block type", ' ', jsx("strong", {
|
|
170
|
+
children: node.type
|
|
171
|
+
}), " is not recognized. Please check your", ' ', jsx("a", {
|
|
172
|
+
href: "https://dev.dotcms.com/docs/block-editor",
|
|
173
|
+
target: "_blank",
|
|
174
|
+
rel: "noopener noreferrer",
|
|
175
|
+
children: "configuration"
|
|
176
|
+
}), ' ', "or contact support for assistance."]
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export { BlockEditorBlock };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Renders a code block component.
|
|
5
|
+
*
|
|
6
|
+
* @param attrs - The attributes of the code block.
|
|
7
|
+
* @param children - The content of the code block.
|
|
8
|
+
* @returns The rendered code block component.
|
|
9
|
+
*/
|
|
10
|
+
const CodeBlock = ({
|
|
11
|
+
node,
|
|
12
|
+
children
|
|
13
|
+
}) => {
|
|
14
|
+
var _node$attrs;
|
|
15
|
+
const language = (node == null || (_node$attrs = node.attrs) == null ? void 0 : _node$attrs.language) || '';
|
|
16
|
+
return jsx("pre", {
|
|
17
|
+
"data-language": language,
|
|
18
|
+
children: jsx("code", {
|
|
19
|
+
children: children
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Renders a blockquote component.
|
|
25
|
+
*
|
|
26
|
+
* @param children - The content to be rendered inside the blockquote.
|
|
27
|
+
* @returns The rendered blockquote component.
|
|
28
|
+
*/
|
|
29
|
+
const BlockQuote = ({
|
|
30
|
+
children
|
|
31
|
+
}) => {
|
|
32
|
+
return jsx("blockquote", {
|
|
33
|
+
children: children
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export { BlockQuote, CodeBlock };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { NoComponentProvided } from './NoComponentProvided.esm.js';
|
|
3
|
+
|
|
4
|
+
const DOT_CONTENT_NO_DATA_MESSAGE = '[DotCMSBlockEditorRenderer]: No data provided for Contentlet Block. Try to add a contentlet to the block editor. If the error persists, please contact the DotCMS support team.';
|
|
5
|
+
const DOT_CONTENT_NO_MATCHING_COMPONENT_MESSAGE = contentType => `[DotCMSBlockEditorRenderer]: No matching component found for content type: ${contentType}. Provide a custom renderer for this content type to fix this error.`;
|
|
6
|
+
/**
|
|
7
|
+
* Renders a DotContent component.
|
|
8
|
+
*
|
|
9
|
+
* @param {DotContentProps} props - The props for the DotContent component.
|
|
10
|
+
* @returns {JSX.Element} The rendered DotContent component.
|
|
11
|
+
*/
|
|
12
|
+
const DotContent = ({
|
|
13
|
+
customRenderers,
|
|
14
|
+
node,
|
|
15
|
+
isDevMode: _isDevMode = false
|
|
16
|
+
}) => {
|
|
17
|
+
const {
|
|
18
|
+
attrs = {}
|
|
19
|
+
} = node;
|
|
20
|
+
const {
|
|
21
|
+
data
|
|
22
|
+
} = attrs;
|
|
23
|
+
if (!data) {
|
|
24
|
+
console.error(DOT_CONTENT_NO_DATA_MESSAGE);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const {
|
|
28
|
+
contentType = 'Unknown Content Type'
|
|
29
|
+
} = data;
|
|
30
|
+
const Component = customRenderers == null ? void 0 : customRenderers[contentType];
|
|
31
|
+
/* In dev mode, show a helpful message for unknown content types */
|
|
32
|
+
if (_isDevMode && !Component) {
|
|
33
|
+
return jsx(NoComponentProvided, {
|
|
34
|
+
contentType: contentType
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/* In production, use default component if no matching component found */
|
|
38
|
+
if (!Component) {
|
|
39
|
+
console.warn(DOT_CONTENT_NO_MATCHING_COMPONENT_MESSAGE(contentType));
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return jsx(Component, {
|
|
43
|
+
node: node
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export { DotContent };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import '../../../../../../../../../../node_modules/core-js/modules/esnext.iterator.constructor.esm.js';
|
|
2
|
+
import '../../../../../../../../../../node_modules/core-js/modules/esnext.iterator.every.esm.js';
|
|
3
|
+
import '../../../../../../../../../../node_modules/core-js/modules/esnext.iterator.map.esm.js';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Renders a grid block with two columns using a 12-column grid system.
|
|
8
|
+
*
|
|
9
|
+
* @param node - The grid block node containing column configuration.
|
|
10
|
+
* @param blockEditorBlock - The block editor component for rendering nested content.
|
|
11
|
+
* @param customRenderers - Optional custom renderers for nested blocks.
|
|
12
|
+
*/
|
|
13
|
+
const GridBlock = ({
|
|
14
|
+
node,
|
|
15
|
+
blockEditorBlock,
|
|
16
|
+
customRenderers
|
|
17
|
+
}) => {
|
|
18
|
+
var _node$attrs, _node$content;
|
|
19
|
+
const BlockEditorBlockComponent = blockEditorBlock;
|
|
20
|
+
const rawCols = Array.isArray((_node$attrs = node.attrs) == null ? void 0 : _node$attrs.columns) ? node.attrs.columns : [6, 6];
|
|
21
|
+
const cols = rawCols.length === 2 && rawCols.every(v => typeof v === 'number' && Number.isFinite(v)) ? rawCols : [6, 6];
|
|
22
|
+
return jsx("div", {
|
|
23
|
+
"data-type": "gridBlock",
|
|
24
|
+
className: "grid-block",
|
|
25
|
+
style: {
|
|
26
|
+
display: 'grid',
|
|
27
|
+
gridTemplateColumns: 'repeat(12, 1fr)',
|
|
28
|
+
gap: '1rem'
|
|
29
|
+
},
|
|
30
|
+
children: (_node$content = node.content) == null ? void 0 : _node$content.map((column, index) => {
|
|
31
|
+
var _cols$index;
|
|
32
|
+
return jsx("div", {
|
|
33
|
+
"data-type": "gridColumn",
|
|
34
|
+
className: "grid-block__column",
|
|
35
|
+
style: {
|
|
36
|
+
gridColumn: `span ${(_cols$index = cols[index]) != null ? _cols$index : 6}`
|
|
37
|
+
},
|
|
38
|
+
children: jsx(BlockEditorBlockComponent, {
|
|
39
|
+
content: column.content,
|
|
40
|
+
customRenderers: customRenderers
|
|
41
|
+
})
|
|
42
|
+
}, `gridColumn-${index}`);
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export { GridBlock };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Renders an image component for dotCMS.
|
|
5
|
+
*
|
|
6
|
+
* @param node - The node for the DotCMSImage component.
|
|
7
|
+
* @returns The rendered image component.
|
|
8
|
+
*/
|
|
9
|
+
const DotCMSImage = ({
|
|
10
|
+
node
|
|
11
|
+
}) => {
|
|
12
|
+
const {
|
|
13
|
+
src,
|
|
14
|
+
alt
|
|
15
|
+
} = node.attrs;
|
|
16
|
+
return jsx("img", {
|
|
17
|
+
alt: alt,
|
|
18
|
+
src: src
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { DotCMSImage };
|