@dotcms/react 0.0.1-alpha.40 → 0.0.1-alpha.41
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/index.esm.d.ts +1 -0
- package/index.esm.js +5204 -0
- package/package.json +9 -5
- package/src/lib/components/BlockEditorRenderer/{BlockEditorRenderer.tsx → BlockEditorRenderer.d.ts} +2 -16
- package/src/lib/components/BlockEditorRenderer/blocks/{Code.tsx → Code.d.ts} +2 -14
- package/src/lib/components/BlockEditorRenderer/blocks/{Contentlet.tsx → Contentlet.d.ts} +1 -21
- package/src/lib/components/BlockEditorRenderer/blocks/Image.d.ts +8 -0
- package/src/lib/components/BlockEditorRenderer/blocks/{Lists.tsx → Lists.d.ts} +3 -12
- package/src/lib/components/BlockEditorRenderer/blocks/Table.d.ts +16 -0
- package/src/lib/components/BlockEditorRenderer/blocks/Texts.d.ts +71 -0
- package/src/lib/components/BlockEditorRenderer/blocks/Video.d.ts +8 -0
- package/src/lib/components/BlockEditorRenderer/item/BlockEditorBlock.d.ts +12 -0
- package/src/lib/components/Column/Column.d.ts +19 -0
- package/src/lib/components/Container/Container.d.ts +19 -0
- package/src/lib/components/DotEditableText/DotEditableText.d.ts +31 -0
- package/src/lib/components/DotEditableText/utils.d.ts +36 -0
- package/src/lib/components/DotcmsLayout/{DotcmsLayout.tsx → DotcmsLayout.d.ts} +2 -18
- package/src/lib/components/PageProvider/{PageProvider.tsx → PageProvider.d.ts} +1 -10
- package/src/lib/components/Row/Row.d.ts +26 -0
- package/src/lib/contexts/{PageContext.tsx → PageContext.d.ts} +2 -4
- package/src/lib/hooks/useCheckHaveContent.d.ts +5 -0
- package/src/lib/hooks/useDotcmsEditor.d.ts +13 -0
- package/src/lib/hooks/{useDotcmsPageContext.tsx → useDotcmsPageContext.d.ts} +1 -7
- package/src/lib/mocks/mockPageContext.d.ts +8 -0
- package/src/lib/models/{blocks.interface.ts → blocks.interface.d.ts} +16 -19
- package/src/lib/models/{content-node.interface.ts → content-node.interface.d.ts} +4 -12
- package/src/lib/models/{index.ts → index.d.ts} +2 -5
- package/src/lib/utils/utils.d.ts +43 -0
- package/.babelrc +0 -12
- package/.eslintrc.json +0 -18
- package/jest.config.ts +0 -11
- package/project.json +0 -56
- package/src/lib/components/BlockEditorRenderer/BlockEditorRenderer.spec.tsx +0 -51
- package/src/lib/components/BlockEditorRenderer/blocks/Image.tsx +0 -18
- package/src/lib/components/BlockEditorRenderer/blocks/Table.tsx +0 -60
- package/src/lib/components/BlockEditorRenderer/blocks/Texts.tsx +0 -126
- package/src/lib/components/BlockEditorRenderer/blocks/Video.tsx +0 -26
- package/src/lib/components/BlockEditorRenderer/item/BlockEditorBlock.spec.tsx +0 -634
- package/src/lib/components/BlockEditorRenderer/item/BlockEditorBlock.tsx +0 -146
- package/src/lib/components/Column/Column.module.css +0 -99
- package/src/lib/components/Column/Column.spec.tsx +0 -78
- package/src/lib/components/Column/Column.tsx +0 -59
- package/src/lib/components/Container/Container.module.css +0 -7
- package/src/lib/components/Container/Container.spec.tsx +0 -155
- package/src/lib/components/Container/Container.tsx +0 -122
- package/src/lib/components/DotEditableText/DotEditableText.spec.tsx +0 -232
- package/src/lib/components/DotEditableText/DotEditableText.tsx +0 -168
- package/src/lib/components/DotEditableText/utils.ts +0 -82
- package/src/lib/components/DotcmsLayout/DotcmsLayout.module.css +0 -7
- package/src/lib/components/DotcmsLayout/DotcmsLayout.spec.tsx +0 -46
- package/src/lib/components/PageProvider/PageProvider.module.css +0 -7
- package/src/lib/components/PageProvider/PageProvider.spec.tsx +0 -59
- package/src/lib/components/Row/Row.module.css +0 -5
- package/src/lib/components/Row/Row.spec.tsx +0 -92
- package/src/lib/components/Row/Row.tsx +0 -52
- package/src/lib/hooks/useDotcmsEditor.spec.ts +0 -176
- package/src/lib/hooks/useDotcmsEditor.ts +0 -94
- package/src/lib/hooks/useDotcmsPageContext.spec.tsx +0 -47
- package/src/lib/mocks/mockPageContext.tsx +0 -113
- package/src/lib/utils/utils.ts +0 -89
- package/tsconfig.json +0 -20
- package/tsconfig.lib.json +0 -23
- package/tsconfig.spec.json +0 -20
- /package/src/{index.ts → index.d.ts} +0 -0
- /package/src/lib/mocks/{index.ts → index.d.ts} +0 -0
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { Blocks } from '../../../models/blocks.interface';
|
|
2
|
-
import { ContentNode, CustomRenderer } from '../../../models/content-node.interface';
|
|
3
|
-
import { BlockQuote, CodeBlock } from '../blocks/Code';
|
|
4
|
-
import { DotContent } from '../blocks/Contentlet';
|
|
5
|
-
import { DotCMSImage } from '../blocks/Image';
|
|
6
|
-
import { BulletList, ListItem, OrderedList } from '../blocks/Lists';
|
|
7
|
-
import { TableRenderer } from '../blocks/Table';
|
|
8
|
-
import { Heading, Paragraph, TextBlock } from '../blocks/Texts';
|
|
9
|
-
import { DotCMSVideo } from '../blocks/Video';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Renders a block editor item based on the provided content and custom renderers.
|
|
13
|
-
*
|
|
14
|
-
* @param content - The content nodes to render.
|
|
15
|
-
* @param customRenderers - Optional custom renderers for specific node types.
|
|
16
|
-
* @returns The rendered block editor item.
|
|
17
|
-
*/
|
|
18
|
-
export const BlockEditorBlock = ({
|
|
19
|
-
content,
|
|
20
|
-
customRenderers
|
|
21
|
-
}: {
|
|
22
|
-
content: ContentNode[];
|
|
23
|
-
customRenderers?: CustomRenderer;
|
|
24
|
-
}) => {
|
|
25
|
-
return content?.map((node: ContentNode, index) => {
|
|
26
|
-
const CustomRendererComponent = customRenderers?.[node.type];
|
|
27
|
-
if (CustomRendererComponent) {
|
|
28
|
-
return (
|
|
29
|
-
<CustomRendererComponent
|
|
30
|
-
key={`${node.type}-${index}`}
|
|
31
|
-
{...node}
|
|
32
|
-
content={node.content}>
|
|
33
|
-
<BlockEditorBlock content={node.content} customRenderers={customRenderers} />
|
|
34
|
-
</CustomRendererComponent>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
switch (node.type) {
|
|
39
|
-
case Blocks.PARAGRAPH:
|
|
40
|
-
return (
|
|
41
|
-
<Paragraph key={`${node.type}-${index}`} {...node}>
|
|
42
|
-
<BlockEditorBlock
|
|
43
|
-
content={node.content}
|
|
44
|
-
customRenderers={customRenderers}
|
|
45
|
-
/>
|
|
46
|
-
</Paragraph>
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
case Blocks.HEADING:
|
|
50
|
-
return (
|
|
51
|
-
<Heading key={`${node.type}-${index}`} {...node}>
|
|
52
|
-
<BlockEditorBlock
|
|
53
|
-
content={node.content}
|
|
54
|
-
customRenderers={customRenderers}
|
|
55
|
-
/>
|
|
56
|
-
</Heading>
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
case Blocks.TEXT:
|
|
60
|
-
return <TextBlock key={`${node.type}-${index}`} {...node} />;
|
|
61
|
-
|
|
62
|
-
case Blocks.BULLET_LIST:
|
|
63
|
-
return (
|
|
64
|
-
<BulletList key={`${node.type}-${index}`}>
|
|
65
|
-
<BlockEditorBlock
|
|
66
|
-
content={node.content}
|
|
67
|
-
customRenderers={customRenderers}
|
|
68
|
-
/>
|
|
69
|
-
</BulletList>
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
case Blocks.ORDERED_LIST:
|
|
73
|
-
return (
|
|
74
|
-
<OrderedList key={`${node.type}-${index}`}>
|
|
75
|
-
<BlockEditorBlock
|
|
76
|
-
content={node.content}
|
|
77
|
-
customRenderers={customRenderers}
|
|
78
|
-
/>
|
|
79
|
-
</OrderedList>
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
case Blocks.LIST_ITEM:
|
|
83
|
-
return (
|
|
84
|
-
<ListItem key={`${node.type}-${index}`}>
|
|
85
|
-
<BlockEditorBlock
|
|
86
|
-
content={node.content}
|
|
87
|
-
customRenderers={customRenderers}
|
|
88
|
-
/>
|
|
89
|
-
</ListItem>
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
case Blocks.BLOCK_QUOTE:
|
|
93
|
-
return (
|
|
94
|
-
<BlockQuote key={`${node.type}-${index}`}>
|
|
95
|
-
<BlockEditorBlock
|
|
96
|
-
content={node.content}
|
|
97
|
-
customRenderers={customRenderers}
|
|
98
|
-
/>
|
|
99
|
-
</BlockQuote>
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
case Blocks.CODE_BLOCK:
|
|
103
|
-
return (
|
|
104
|
-
<CodeBlock key={`${node.type}-${index}`} {...node}>
|
|
105
|
-
<BlockEditorBlock
|
|
106
|
-
content={node.content}
|
|
107
|
-
customRenderers={customRenderers}
|
|
108
|
-
/>
|
|
109
|
-
</CodeBlock>
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
case Blocks.HARDBREAK:
|
|
113
|
-
return <br key={`${node.type}-${index}`} />;
|
|
114
|
-
|
|
115
|
-
case Blocks.HORIZONTAL_RULE:
|
|
116
|
-
return <hr key={`${node.type}-${index}`} />;
|
|
117
|
-
|
|
118
|
-
case Blocks.DOT_IMAGE:
|
|
119
|
-
return <DotCMSImage key={`${node.type}-${index}`} {...node} />;
|
|
120
|
-
|
|
121
|
-
case Blocks.DOT_VIDEO:
|
|
122
|
-
return <DotCMSVideo key={`${node.type}-${index}`} {...node} />;
|
|
123
|
-
|
|
124
|
-
case Blocks.TABLE:
|
|
125
|
-
return (
|
|
126
|
-
<TableRenderer
|
|
127
|
-
key={`${node.type}-${index}`}
|
|
128
|
-
content={node.content}
|
|
129
|
-
blockEditorItem={BlockEditorBlock}
|
|
130
|
-
/>
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
case Blocks.DOT_CONTENT:
|
|
134
|
-
return (
|
|
135
|
-
<DotContent
|
|
136
|
-
key={`${node.type}-${index}`}
|
|
137
|
-
{...node}
|
|
138
|
-
customRenderers={customRenderers}
|
|
139
|
-
/>
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
default:
|
|
143
|
-
return <div key={`${node.type}-${index}`}>Unknown Block Type {node.type}</div>;
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
.col-start-1 {
|
|
2
|
-
grid-column-start: 1;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.col-start-2 {
|
|
6
|
-
grid-column-start: 2;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.col-start-3 {
|
|
10
|
-
grid-column-start: 3;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.col-start-4 {
|
|
14
|
-
grid-column-start: 4;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.col-start-5 {
|
|
18
|
-
grid-column-start: 5;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.col-start-6 {
|
|
22
|
-
grid-column-start: 6;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.col-start-7 {
|
|
26
|
-
grid-column-start: 7;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.col-start-8 {
|
|
30
|
-
grid-column-start: 8;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.col-start-9 {
|
|
34
|
-
grid-column-start: 9;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.col-start-10 {
|
|
38
|
-
grid-column-start: 10;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.col-start-11 {
|
|
42
|
-
grid-column-start: 11;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.col-start-12 {
|
|
46
|
-
grid-column-start: 12;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.col-end-1 {
|
|
50
|
-
grid-column-end: 1;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.col-end-2 {
|
|
54
|
-
grid-column-end: 2;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.col-end-3 {
|
|
58
|
-
grid-column-end: 3;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.col-end-4 {
|
|
62
|
-
grid-column-end: 4;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.col-end-5 {
|
|
66
|
-
grid-column-end: 5;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.col-end-6 {
|
|
70
|
-
grid-column-end: 6;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.col-end-7 {
|
|
74
|
-
grid-column-end: 7;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.col-end-8 {
|
|
78
|
-
grid-column-end: 8;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.col-end-9 {
|
|
82
|
-
grid-column-end: 9;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.col-end-10 {
|
|
86
|
-
grid-column-end: 10;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.col-end-11 {
|
|
90
|
-
grid-column-end: 11;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.col-end-12 {
|
|
94
|
-
grid-column-end: 12;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.col-end-13 {
|
|
98
|
-
grid-column-end: 13;
|
|
99
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import '@testing-library/jest-dom';
|
|
3
|
-
|
|
4
|
-
import * as dotcmsClient from '@dotcms/client';
|
|
5
|
-
|
|
6
|
-
import { Column } from './Column';
|
|
7
|
-
|
|
8
|
-
import { MockContextRender } from '../../mocks/mockPageContext';
|
|
9
|
-
import { ContainerProps } from '../Container/Container';
|
|
10
|
-
|
|
11
|
-
jest.mock('../Container/Container', () => {
|
|
12
|
-
return {
|
|
13
|
-
Container: ({ containerRef }: Partial<ContainerProps>) => (
|
|
14
|
-
<div data-testid="mockContainer">{containerRef?.identifier}</div>
|
|
15
|
-
)
|
|
16
|
-
};
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe('Column', () => {
|
|
20
|
-
const mockColumnData = {
|
|
21
|
-
width: 6, // Adjust as needed
|
|
22
|
-
leftOffset: 3, // Adjust as needed
|
|
23
|
-
containers: [
|
|
24
|
-
{ identifier: 'Container1', uuid: 'unique-id-1' },
|
|
25
|
-
{ identifier: 'Container2', uuid: 'unique-id-2' }
|
|
26
|
-
// Add more containers as needed for your test
|
|
27
|
-
],
|
|
28
|
-
styleClass: ''
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
describe('Column is inside editor', () => {
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
jest.spyOn(dotcmsClient, 'isInsideEditor').mockReturnValue(true);
|
|
34
|
-
render(
|
|
35
|
-
<MockContextRender mockContext={{ isInsideEditor: true }}>
|
|
36
|
-
<Column column={mockColumnData} />
|
|
37
|
-
</MockContextRender>
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('applies the correct width and start classes based on props', () => {
|
|
42
|
-
const columnElement = screen.getByTestId('column');
|
|
43
|
-
expect(columnElement).toHaveClass('col-end-9');
|
|
44
|
-
expect(columnElement).toHaveClass('col-start-3');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('applies the correct data attr', () => {
|
|
48
|
-
expect(screen.getByTestId('column')).toHaveAttribute('data-dot', 'column');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('renders the correct number of containers', () => {
|
|
52
|
-
const containers = screen.getAllByTestId('mockContainer');
|
|
53
|
-
expect(containers.length).toBe(mockColumnData.containers.length);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('passes the correct props to each Container', () => {
|
|
57
|
-
mockColumnData.containers.forEach((container) => {
|
|
58
|
-
expect(screen.getByText(container.identifier)).toBeInTheDocument();
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('Column is not inside editor', () => {
|
|
64
|
-
beforeEach(() => {
|
|
65
|
-
jest.spyOn(dotcmsClient, 'isInsideEditor').mockReturnValue(false);
|
|
66
|
-
render(
|
|
67
|
-
<MockContextRender mockContext={{ isInsideEditor: false }}>
|
|
68
|
-
<Column column={mockColumnData} />
|
|
69
|
-
</MockContextRender>
|
|
70
|
-
);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should not have dot attrs', () => {
|
|
74
|
-
const columnElement = screen.queryByTestId('column');
|
|
75
|
-
expect(columnElement).toBeNull();
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
});
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
|
|
3
|
-
import styles from './column.module.css';
|
|
4
|
-
|
|
5
|
-
import { PageContext } from '../../contexts/PageContext';
|
|
6
|
-
import { DotCMSPageContext } from '../../models';
|
|
7
|
-
import { combineClasses, getPositionStyleClasses } from '../../utils/utils';
|
|
8
|
-
import { Container } from '../Container/Container';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Props for Column component to render a column with its containers.
|
|
12
|
-
*
|
|
13
|
-
* @export
|
|
14
|
-
* @interface ColumnProps
|
|
15
|
-
*/
|
|
16
|
-
export interface ColumnProps {
|
|
17
|
-
readonly column: DotCMSPageContext['pageAsset']['layout']['body']['rows'][0]['columns'][0];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Renders a Column with its containers using information provided by dotCMS Page API.
|
|
22
|
-
*
|
|
23
|
-
* @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
|
|
24
|
-
* @export
|
|
25
|
-
* @param {ColumnProps} { column }
|
|
26
|
-
* @return {JSX.Element} Rendered column with containers
|
|
27
|
-
*/
|
|
28
|
-
export function Column({ column }: ColumnProps) {
|
|
29
|
-
const { isInsideEditor } = useContext(PageContext) as DotCMSPageContext;
|
|
30
|
-
|
|
31
|
-
const { startClass, endClass } = getPositionStyleClasses(
|
|
32
|
-
column.leftOffset,
|
|
33
|
-
column.width + column.leftOffset
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const combinedClasses = combineClasses([
|
|
37
|
-
styles[endClass],
|
|
38
|
-
styles[startClass],
|
|
39
|
-
column.styleClass
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
const columnProps = isInsideEditor
|
|
43
|
-
? {
|
|
44
|
-
'data-dot': 'column',
|
|
45
|
-
'data-testid': 'column'
|
|
46
|
-
}
|
|
47
|
-
: {};
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<div {...columnProps} className={combinedClasses}>
|
|
51
|
-
{column.containers.map((container) => (
|
|
52
|
-
<Container
|
|
53
|
-
key={`${container.identifier}-${container.uuid}`}
|
|
54
|
-
containerRef={container}
|
|
55
|
-
/>
|
|
56
|
-
))}
|
|
57
|
-
</div>
|
|
58
|
-
);
|
|
59
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import '@testing-library/jest-dom';
|
|
2
|
-
|
|
3
|
-
import { render, screen } from '@testing-library/react';
|
|
4
|
-
|
|
5
|
-
import * as dotcmsClient from '@dotcms/client';
|
|
6
|
-
|
|
7
|
-
import { Container } from './Container';
|
|
8
|
-
|
|
9
|
-
import { MockContextRender, mockPageContext } from '../../mocks/mockPageContext';
|
|
10
|
-
import { getContainersData } from '../../utils/utils';
|
|
11
|
-
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
-
const getContainer = ({ containerRef, containers }: { containerRef: any; containers: any }) => {
|
|
14
|
-
const { acceptTypes, maxContentlets, variantId, path } = getContainersData(
|
|
15
|
-
containers,
|
|
16
|
-
containerRef
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
acceptTypes,
|
|
21
|
-
identifier: path ?? containerRef.identifier,
|
|
22
|
-
maxContentlets,
|
|
23
|
-
variantId,
|
|
24
|
-
uuid: containerRef.uuid
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
describe('Container', () => {
|
|
29
|
-
// Mock data for your context and container
|
|
30
|
-
jest.spyOn(dotcmsClient, 'isInsideEditor').mockReturnValue(true);
|
|
31
|
-
|
|
32
|
-
describe('with contentlets', () => {
|
|
33
|
-
const mockContainerRef = {
|
|
34
|
-
identifier: 'container-1',
|
|
35
|
-
uuid: '1',
|
|
36
|
-
containers: []
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
it('renders NoComponent component for unsupported content types', () => {
|
|
40
|
-
const updatedContext = {
|
|
41
|
-
...mockPageContext,
|
|
42
|
-
isInsideEditor: true,
|
|
43
|
-
components: {}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
render(
|
|
47
|
-
<MockContextRender mockContext={updatedContext}>
|
|
48
|
-
<Container containerRef={mockContainerRef} />
|
|
49
|
-
</MockContextRender>
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
expect(screen.getByTestId('no-component')).toHaveTextContent(
|
|
53
|
-
'No Component for content-type-1'
|
|
54
|
-
);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('render custom NoComponent component for unsetted content types', () => {
|
|
58
|
-
const updatedContext = {
|
|
59
|
-
...mockPageContext,
|
|
60
|
-
isInsideEditor: true,
|
|
61
|
-
components: {
|
|
62
|
-
CustomNoComponent: () => (
|
|
63
|
-
<div data-testid="custom-no-component">Custom No Component</div>
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
render(
|
|
69
|
-
<MockContextRender mockContext={updatedContext}>
|
|
70
|
-
<Container containerRef={mockContainerRef} />
|
|
71
|
-
</MockContextRender>
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
expect(screen.getByTestId('custom-no-component')).toHaveTextContent(
|
|
75
|
-
'Custom No Component'
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should render contentlets with the right attributes', () => {
|
|
80
|
-
const mockContainer = {
|
|
81
|
-
identifier: 'container-1',
|
|
82
|
-
uuid: '1',
|
|
83
|
-
containers: []
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const updatedContext = {
|
|
87
|
-
...mockPageContext,
|
|
88
|
-
components: {},
|
|
89
|
-
isInsideEditor: true
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
render(
|
|
93
|
-
<MockContextRender mockContext={updatedContext}>
|
|
94
|
-
<Container containerRef={mockContainer} />
|
|
95
|
-
</MockContextRender>
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
const container = getContainer({
|
|
99
|
-
containerRef: mockContainer,
|
|
100
|
-
containers: updatedContext.pageAsset.containers
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const contentlet = screen.getByTestId('dot-contentlet');
|
|
104
|
-
expect(contentlet).toHaveAttribute('data-dot-identifier', 'contentlet-1');
|
|
105
|
-
expect(contentlet).toHaveAttribute('data-dot-title', 'Contentlet 1');
|
|
106
|
-
expect(contentlet).toHaveAttribute('data-dot-inode', 'inode-1');
|
|
107
|
-
expect(contentlet).toHaveAttribute('data-dot-on-number-of-pages', '1');
|
|
108
|
-
expect(contentlet).toHaveAttribute('data-dot-basetype', 'base-type-1');
|
|
109
|
-
expect(contentlet).toHaveAttribute('data-dot-container', JSON.stringify(container));
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('without contentlets', () => {
|
|
113
|
-
const mockContainerRef = {
|
|
114
|
-
identifier: 'container-2',
|
|
115
|
-
uuid: '2',
|
|
116
|
-
containers: []
|
|
117
|
-
};
|
|
118
|
-
it('renders EmptyContainer component in editor mode', () => {
|
|
119
|
-
const updatedContext = {
|
|
120
|
-
...mockPageContext,
|
|
121
|
-
components: {},
|
|
122
|
-
isInsideEditor: true
|
|
123
|
-
};
|
|
124
|
-
render(
|
|
125
|
-
<MockContextRender mockContext={updatedContext}>
|
|
126
|
-
<Container containerRef={mockContainerRef} />
|
|
127
|
-
</MockContextRender>
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
expect(screen.getByTestId('dot-container')).toHaveTextContent(
|
|
131
|
-
'This container is empty.'
|
|
132
|
-
);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('dont render EmptyContainer component outside editor mode', () => {
|
|
136
|
-
jest.spyOn(dotcmsClient, 'isInsideEditor').mockReturnValue(false);
|
|
137
|
-
|
|
138
|
-
const updatedContext = {
|
|
139
|
-
...mockPageContext,
|
|
140
|
-
components: {},
|
|
141
|
-
isInsideEditor: false
|
|
142
|
-
};
|
|
143
|
-
render(
|
|
144
|
-
<MockContextRender mockContext={updatedContext}>
|
|
145
|
-
<Container containerRef={mockContainerRef} />
|
|
146
|
-
</MockContextRender>
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
expect(screen.queryByTestId('dot-container')).toBeNull();
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
// Add tests for pointer events, dynamic component rendering, and other scenarios...
|
|
155
|
-
});
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
|
|
3
|
-
import { PageContext } from '../../contexts/PageContext';
|
|
4
|
-
import { DotCMSPageContext } from '../../models';
|
|
5
|
-
import { getContainersData } from '../../utils/utils';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Component to render when there is no component for the content type.
|
|
9
|
-
*
|
|
10
|
-
* @param {{ readonly contentType: string }} { contentType }
|
|
11
|
-
* @return {*}
|
|
12
|
-
*/
|
|
13
|
-
function NoComponent({ contentType }: { readonly contentType: string }) {
|
|
14
|
-
return <div data-testid="no-component">No Component for {contentType}</div>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Component to render when there is no content in the container.
|
|
19
|
-
*
|
|
20
|
-
* @return {*}
|
|
21
|
-
*/
|
|
22
|
-
function EmptyContent() {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Props for the Container component.
|
|
28
|
-
*
|
|
29
|
-
* @export
|
|
30
|
-
* @interface ContainerProps
|
|
31
|
-
*/
|
|
32
|
-
export interface ContainerProps {
|
|
33
|
-
readonly containerRef: DotCMSPageContext['pageAsset']['layout']['body']['rows'][0]['columns'][0]['containers'][0];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Renders a Container with its content using information provided by dotCMS Page API.
|
|
38
|
-
*
|
|
39
|
-
* @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
|
|
40
|
-
* @export
|
|
41
|
-
* @param {ContainerProps} { containerRef }
|
|
42
|
-
* @return {JSX.Element} Rendered container with content
|
|
43
|
-
*/
|
|
44
|
-
export function Container({ containerRef }: ContainerProps) {
|
|
45
|
-
const { isInsideEditor } = useContext(PageContext) as DotCMSPageContext;
|
|
46
|
-
|
|
47
|
-
const { identifier, uuid } = containerRef;
|
|
48
|
-
|
|
49
|
-
// Get the containers from the global context
|
|
50
|
-
const {
|
|
51
|
-
pageAsset: { containers },
|
|
52
|
-
components
|
|
53
|
-
} = useContext<DotCMSPageContext | null>(PageContext) as DotCMSPageContext;
|
|
54
|
-
|
|
55
|
-
const { acceptTypes, contentlets, maxContentlets, variantId, path } = getContainersData(
|
|
56
|
-
containers,
|
|
57
|
-
containerRef
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const container = {
|
|
61
|
-
acceptTypes,
|
|
62
|
-
identifier: path ?? identifier,
|
|
63
|
-
maxContentlets,
|
|
64
|
-
variantId,
|
|
65
|
-
uuid
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const containerStyles = contentlets.length
|
|
69
|
-
? undefined
|
|
70
|
-
: {
|
|
71
|
-
width: '100%',
|
|
72
|
-
backgroundColor: '#ECF0FD',
|
|
73
|
-
display: 'flex',
|
|
74
|
-
justifyContent: 'center',
|
|
75
|
-
alignItems: 'center',
|
|
76
|
-
color: '#030E32',
|
|
77
|
-
height: '10rem'
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const ContainerChildren = contentlets.map((contentlet) => {
|
|
81
|
-
const ContentTypeComponent = components[contentlet.contentType];
|
|
82
|
-
const DefaultComponent = components['CustomNoComponent'] || NoComponent;
|
|
83
|
-
|
|
84
|
-
const Component = isInsideEditor
|
|
85
|
-
? ContentTypeComponent || DefaultComponent
|
|
86
|
-
: ContentTypeComponent || EmptyContent;
|
|
87
|
-
|
|
88
|
-
return isInsideEditor ? (
|
|
89
|
-
<div
|
|
90
|
-
data-testid="dot-contentlet"
|
|
91
|
-
data-dot-object="contentlet"
|
|
92
|
-
data-dot-identifier={contentlet.identifier}
|
|
93
|
-
data-dot-basetype={contentlet.baseType}
|
|
94
|
-
data-dot-title={contentlet.widgetTitle || contentlet.title}
|
|
95
|
-
data-dot-inode={contentlet.inode}
|
|
96
|
-
data-dot-type={contentlet.contentType}
|
|
97
|
-
data-dot-container={JSON.stringify(container)}
|
|
98
|
-
data-dot-on-number-of-pages={contentlet.onNumberOfPages}
|
|
99
|
-
key={contentlet.identifier}>
|
|
100
|
-
<Component {...contentlet} />
|
|
101
|
-
</div>
|
|
102
|
-
) : (
|
|
103
|
-
<Component {...contentlet} key={contentlet.identifier} />
|
|
104
|
-
);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
return isInsideEditor ? (
|
|
108
|
-
<div
|
|
109
|
-
data-testid="dot-container"
|
|
110
|
-
data-dot-object="container"
|
|
111
|
-
data-dot-accept-types={acceptTypes}
|
|
112
|
-
data-dot-identifier={path ?? identifier}
|
|
113
|
-
data-max-contentlets={maxContentlets}
|
|
114
|
-
data-dot-uuid={uuid}
|
|
115
|
-
style={containerStyles}>
|
|
116
|
-
{ContainerChildren.length ? ContainerChildren : 'This container is empty.'}
|
|
117
|
-
</div>
|
|
118
|
-
) : (
|
|
119
|
-
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
120
|
-
<>{ContainerChildren}</>
|
|
121
|
-
);
|
|
122
|
-
}
|