@dotcms/react 0.0.1-alpha.1 → 0.0.1-alpha.11

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.
Files changed (41) hide show
  1. package/.babelrc +12 -0
  2. package/.eslintrc.json +18 -0
  3. package/README.md +16 -21
  4. package/jest.config.ts +11 -0
  5. package/package.json +27 -31
  6. package/project.json +51 -0
  7. package/src/{index.d.ts → index.ts} +4 -5
  8. package/src/lib/components/Column/Column.module.css +99 -0
  9. package/src/lib/components/Column/Column.spec.tsx +78 -0
  10. package/src/lib/components/Column/Column.tsx +45 -0
  11. package/src/lib/components/Container/Container.module.css +7 -0
  12. package/src/lib/components/Container/Container.spec.tsx +82 -0
  13. package/src/lib/components/Container/Container.tsx +106 -0
  14. package/src/lib/components/DotcmsLayout/DotcmsLayout.module.css +7 -0
  15. package/src/lib/components/DotcmsLayout/DotcmsLayout.spec.tsx +41 -0
  16. package/src/lib/components/DotcmsLayout/{DotcmsLayout.d.ts → DotcmsLayout.tsx} +48 -32
  17. package/src/lib/components/PageProvider/PageProvider.module.css +7 -0
  18. package/src/lib/components/PageProvider/PageProvider.spec.tsx +54 -0
  19. package/src/lib/components/PageProvider/{PageProvider.d.ts → PageProvider.tsx} +95 -81
  20. package/src/lib/components/Row/Row.module.css +5 -0
  21. package/src/lib/components/Row/Row.spec.tsx +92 -0
  22. package/src/lib/components/Row/Row.tsx +51 -0
  23. package/src/lib/contexts/PageContext.tsx +5 -0
  24. package/src/lib/hooks/useDotcmsEditor.spec.ts +56 -0
  25. package/src/lib/hooks/useDotcmsEditor.ts +29 -0
  26. package/src/lib/hooks/useDotcmsPageContext.spec.tsx +43 -0
  27. package/src/lib/hooks/{useDotcmsPageContext.d.ts → useDotcmsPageContext.tsx} +15 -9
  28. package/src/lib/mocks/{index.d.ts → index.ts} +1 -1
  29. package/src/lib/mocks/mockPageContext.tsx +84 -0
  30. package/src/lib/utils/utils.ts +69 -0
  31. package/tsconfig.json +20 -0
  32. package/tsconfig.lib.json +23 -0
  33. package/tsconfig.spec.json +20 -0
  34. package/index.js +0 -2413
  35. package/src/lib/components/Column/Column.d.ts +0 -7
  36. package/src/lib/components/Container/Container.d.ts +0 -6
  37. package/src/lib/components/Row/Row.d.ts +0 -25
  38. package/src/lib/contexts/PageContext.d.ts +0 -3
  39. package/src/lib/hooks/usePageEditor.d.ts +0 -48
  40. package/src/lib/mocks/mockPageContext.d.ts +0 -2
  41. package/src/lib/utils/utils.d.ts +0 -50
package/.babelrc ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "presets": [
3
+ [
4
+ "@nrwl/react/babel",
5
+ {
6
+ "runtime": "automatic",
7
+ "useBuiltIns": "usage"
8
+ }
9
+ ]
10
+ ],
11
+ "plugins": []
12
+ }
package/.eslintrc.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.base.json"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "overrides": [
5
+ {
6
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
+ "rules": {}
8
+ },
9
+ {
10
+ "files": ["*.ts", "*.tsx"],
11
+ "rules": {}
12
+ },
13
+ {
14
+ "files": ["*.js", "*.jsx"],
15
+ "rules": {}
16
+ }
17
+ ]
18
+ }
package/README.md CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  ## Features
6
6
 
7
- - A collection of React components and hooks tailored to render dotCMS pages.
8
- - Streamlined integration with dotCMS page editor.
9
- - Improved development experience with comprehensive TypeScript typings.
7
+ - A collection of React components and hooks tailored to render dotCMS pages.
8
+ - Streamlined integration with dotCMS page editor.
9
+ - Improved development experience with comprehensive TypeScript typings.
10
10
 
11
11
  ## Installation
12
12
 
@@ -30,7 +30,7 @@ A functional component that renders a layout for a dotCMS page.
30
30
 
31
31
  #### Props
32
32
 
33
- - **entity**: The context for a dotCMS page.
33
+ - **entity**: The context for a dotCMS page.
34
34
 
35
35
  #### Usage
36
36
 
@@ -38,7 +38,7 @@ A functional component that renders a layout for a dotCMS page.
38
38
  import { DotcmsLayout } from '@dotcms/react';
39
39
 
40
40
  const MyPage = ({ entity }) => {
41
- return <DotcmsLayout entity={entity} />;
41
+ return <DotcmsLayout entity={entity} />;
42
42
  };
43
43
  ```
44
44
 
@@ -50,7 +50,7 @@ A custom React hook that provides access to the `PageProviderContext`.
50
50
 
51
51
  #### Returns
52
52
 
53
- - `PageProviderContext | null`: The context value or `null` if it's not available.
53
+ - `PageProviderContext | null`: The context value or `null` if it's not available.
54
54
 
55
55
  #### Usage
56
56
 
@@ -58,8 +58,8 @@ A custom React hook that provides access to the `PageProviderContext`.
58
58
  import { useDotcmsPageContext } from '@dotcms/react';
59
59
 
60
60
  const MyComponent = () => {
61
- const context = useDotcmsPageContext();
62
- // Use the context
61
+ const context = useDotcmsPageContext();
62
+ // Use the context
63
63
  };
64
64
  ```
65
65
 
@@ -69,11 +69,11 @@ A custom React hook that sets up the page editor for a dotCMS page.
69
69
 
70
70
  #### Parameters
71
71
 
72
- - **props**: `PageEditorOptions` - The options for the page editor. Includes a `reloadFunction` and a `pathname`.
72
+ - **props**: `PageEditorOptions` - The options for the page editor. Includes a `reloadFunction` and a `pathname`.
73
73
 
74
74
  #### Returns
75
75
 
76
- - `React.RefObject<HTMLDivElement>[]`: A reference to the rows of the page.
76
+ - `React.RefObject<HTMLDivElement>[]`: A reference to the rows of the page.
77
77
 
78
78
  #### Usage
79
79
 
@@ -81,8 +81,8 @@ A custom React hook that sets up the page editor for a dotCMS page.
81
81
  import { usePageEditor } from '@dotcms/react';
82
82
 
83
83
  const MyEditor = () => {
84
- const rowsRef = usePageEditor({ pathname: '/my-page' });
85
- // Use the rowsRef
84
+ const rowsRef = usePageEditor({ pathname: '/my-page' });
85
+ // Use the rowsRef
86
86
  };
87
87
  ```
88
88
 
@@ -94,8 +94,8 @@ A functional component that provides a context for a dotCMS page.
94
94
 
95
95
  #### Props
96
96
 
97
- - **entity**: The entity representing the page's data.
98
- - **children**: The children components.
97
+ - **entity**: The entity representing the page's data.
98
+ - **children**: The children components.
99
99
 
100
100
  #### Usage
101
101
 
@@ -103,11 +103,7 @@ A functional component that provides a context for a dotCMS page.
103
103
  import { PageProvider } from '@dotcms/react';
104
104
 
105
105
  const MyApp = ({ entity }) => {
106
- return (
107
- <PageProvider entity={entity}>
108
- {/* children */}
109
- </PageProvider>
110
- );
106
+ return <PageProvider entity={entity}>{/* children */}</PageProvider>;
111
107
  };
112
108
  ```
113
109
 
@@ -115,7 +111,6 @@ const MyApp = ({ entity }) => {
115
111
 
116
112
  GitHub pull requests are the preferred method to contribute code to dotCMS. Before any pull requests can be accepted, an automated tool will ask you to agree to the [dotCMS Contributor's Agreement](https://gist.github.com/wezell/85ef45298c48494b90d92755b583acb3).
117
113
 
118
-
119
114
  ## Licensing
120
115
 
121
116
  dotCMS comes in multiple editions and as such is dual licensed. The dotCMS Community Edition is licensed under the GPL 3.0 and is freely available for download, customization and deployment for use within organizations of all stripes. dotCMS Enterprise Editions (EE) adds a number of enterprise features and is available via a supported, indemnified commercial license from dotCMS. For the differences between the editions, see [the feature page](http://dotcms.com/cms-platform/features).
@@ -138,4 +133,4 @@ Always refer to the official [DotCMS documentation](https://www.dotcms.com/docs/
138
133
  | Code Examples | [Codeshare](https://dotcms.com/codeshare/) |
139
134
  | Forums/Listserv | [via Google Groups](https://groups.google.com/forum/#!forum/dotCMS) |
140
135
  | Twitter | @dotCMS |
141
- | Main Site | [dotCMS.com](https://dotcms.com/) |
136
+ | Main Site | [dotCMS.com](https://dotcms.com/) |
package/jest.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ /* eslint-disable */
2
+ export default {
3
+ displayName: 'sdk-react',
4
+ preset: '../../../jest.preset.js',
5
+ transform: {
6
+ '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
7
+ '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }]
8
+ },
9
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
10
+ coverageDirectory: '../../../coverage/libs/sdk/react'
11
+ };
package/package.json CHANGED
@@ -1,33 +1,29 @@
1
1
  {
2
- "name": "@dotcms/react",
3
- "version": "0.0.1-alpha.1",
4
- "peerDependencies": {
5
- "react": "^18",
6
- "react-dom": "^18",
7
- "@dotcms/client": "latest"
8
- },
9
- "description": "Official React Components library to render a dotCMS page.",
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/dotCMS/core.git#master"
13
- },
14
- "keywords": [
15
- "dotCMS",
16
- "CMS",
17
- "Content Management",
18
- "API Client",
19
- "REST API",
20
- "React",
21
- "Components"
22
- ],
23
- "author": "dotcms <dev@dotcms.com>",
24
- "license": "MIT",
25
- "bugs": {
26
- "url": "https://github.com/dotCMS/core/issues"
27
- },
28
- "homepage": "https://github.com/dotCMS/core/tree/master/core-web/libs/sdk/react/README.md",
29
- "module": "./index.js",
30
- "main": "./index.js",
31
- "type": "module",
32
- "types": "./src/index.d.ts"
2
+ "name": "@dotcms/react",
3
+ "version": "0.0.1-alpha.11",
4
+ "peerDependencies": {
5
+ "react": ">=18",
6
+ "react-dom": ">=18",
7
+ "@dotcms/client": "0.0.1-alpha.11"
8
+ },
9
+ "description": "Official React Components library to render a dotCMS page.",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/dotCMS/core.git#master"
13
+ },
14
+ "keywords": [
15
+ "dotCMS",
16
+ "CMS",
17
+ "Content Management",
18
+ "API Client",
19
+ "REST API",
20
+ "React",
21
+ "Components"
22
+ ],
23
+ "author": "dotcms <dev@dotcms.com>",
24
+ "license": "MIT",
25
+ "bugs": {
26
+ "url": "https://github.com/dotCMS/core/issues"
27
+ },
28
+ "homepage": "https://github.com/dotCMS/core/tree/master/core-web/libs/sdk/react/README.md"
33
29
  }
package/project.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "sdk-react",
3
+ "$schema": "../../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "libs/sdk/react/src",
5
+ "projectType": "library",
6
+ "tags": [],
7
+ "targets": {
8
+ "lint": {
9
+ "executor": "@nrwl/linter:eslint",
10
+ "outputs": ["{options.outputFile}"],
11
+ "options": {
12
+ "lintFilePatterns": ["libs/sdk/react/**/*.{ts,tsx,js,jsx}"]
13
+ }
14
+ },
15
+ "build": {
16
+ "executor": "@nrwl/rollup:rollup",
17
+ "outputs": ["{options.outputPath}"],
18
+ "options": {
19
+ "outputPath": "dist/libs/sdk/react",
20
+ "tsConfig": "libs/sdk/react/tsconfig.lib.json",
21
+ "project": "libs/sdk/react/package.json",
22
+ "entryFile": "libs/sdk/react/src/index.ts",
23
+ "external": ["react/jsx-runtime"],
24
+ "rollupConfig": "@nrwl/react/plugins/bundle-rollup",
25
+ "compiler": "babel",
26
+ "extractCss": false,
27
+ "assets": [
28
+ {
29
+ "glob": "libs/sdk/react/README.md",
30
+ "input": ".",
31
+ "output": "."
32
+ }
33
+ ]
34
+ }
35
+ },
36
+ "test": {
37
+ "executor": "@nrwl/jest:jest",
38
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
39
+ "options": {
40
+ "jestConfig": "libs/sdk/react/jest.config.ts",
41
+ "passWithNoTests": true
42
+ },
43
+ "configurations": {
44
+ "ci": {
45
+ "ci": true,
46
+ "codeCoverage": true
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
@@ -1,5 +1,4 @@
1
- export * from './lib/components/DotcmsLayout/DotcmsLayout';
2
- export * from './lib/components/PageProvider/PageProvider';
3
- export * from './lib/components/Row/Row';
4
- export * from './lib/hooks/useDotcmsPageContext';
5
- export * from './lib/hooks/usePageEditor';
1
+ export * from './lib/components/DotcmsLayout/DotcmsLayout';
2
+ export * from './lib/components/PageProvider/PageProvider';
3
+ export * from './lib/components/Row/Row';
4
+ export * from './lib/hooks/useDotcmsPageContext';
@@ -0,0 +1,99 @@
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
+ }
@@ -0,0 +1,78 @@
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
+ });
@@ -0,0 +1,45 @@
1
+ import { useContext } from 'react';
2
+
3
+ import styles from './column.module.css';
4
+
5
+ import { PageContext } from '../../contexts/PageContext';
6
+ import { combineClasses, getPositionStyleClasses } from '../../utils/utils';
7
+ import { Container } from '../Container/Container';
8
+ import { PageProviderContext } from '../PageProvider/PageProvider';
9
+
10
+ export interface ColumnProps {
11
+ readonly column: PageProviderContext['layout']['body']['rows'][0]['columns'][0];
12
+ }
13
+
14
+ export function Column({ column }: ColumnProps) {
15
+ const { isInsideEditor } = useContext(PageContext) as PageProviderContext;
16
+
17
+ const { startClass, endClass } = getPositionStyleClasses(
18
+ column.leftOffset,
19
+ column.width + column.leftOffset
20
+ );
21
+
22
+ const combinedClasses = combineClasses([
23
+ styles[endClass],
24
+ styles[startClass],
25
+ column.styleClass
26
+ ]);
27
+
28
+ const columnProps = isInsideEditor
29
+ ? {
30
+ 'data-dot': 'column',
31
+ 'data-testid': 'column'
32
+ }
33
+ : {};
34
+
35
+ return (
36
+ <div {...columnProps} className={combinedClasses}>
37
+ {column.containers.map((container) => (
38
+ <Container
39
+ key={`${container.identifier}-${container.uuid}`}
40
+ containerRef={container}
41
+ />
42
+ ))}
43
+ </div>
44
+ );
45
+ }
@@ -0,0 +1,7 @@
1
+ /*
2
+ * Replace this with your own classes
3
+ *
4
+ * e.g.
5
+ * .container {
6
+ * }
7
+ */
@@ -0,0 +1,82 @@
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
+
11
+ describe('Container', () => {
12
+ // Mock data for your context and container
13
+ jest.spyOn(dotcmsClient, 'isInsideEditor').mockReturnValue(true);
14
+
15
+ describe('with contentlets', () => {
16
+ const mockContainerRef = {
17
+ identifier: 'container-1',
18
+ uuid: '1',
19
+ containers: []
20
+ };
21
+
22
+ it('renders NoContent component for unsupported content types', () => {
23
+ const updatedContext = {
24
+ ...mockPageContext,
25
+ components: {}
26
+ };
27
+
28
+ render(
29
+ <MockContextRender mockContext={updatedContext}>
30
+ <Container containerRef={mockContainerRef} />
31
+ </MockContextRender>
32
+ );
33
+
34
+ expect(screen.getByTestId('no-component')).toHaveTextContent(
35
+ 'No Component for content-type-1'
36
+ );
37
+ });
38
+
39
+ describe('without contentlets', () => {
40
+ const mockContainerRef = {
41
+ identifier: 'container-2',
42
+ uuid: '2',
43
+ containers: []
44
+ };
45
+ it('renders EmptyContainer component in editor mode', () => {
46
+ const updatedContext = {
47
+ ...mockPageContext,
48
+ components: {},
49
+ isInsideEditor: true
50
+ };
51
+ render(
52
+ <MockContextRender mockContext={updatedContext}>
53
+ <Container containerRef={mockContainerRef} />
54
+ </MockContextRender>
55
+ );
56
+
57
+ expect(screen.getByTestId('empty-container')).toHaveTextContent(
58
+ 'This container is empty.'
59
+ );
60
+ });
61
+
62
+ it('dont render EmptyContainer component outside editor mode', () => {
63
+ jest.spyOn(dotcmsClient, 'isInsideEditor').mockReturnValue(false);
64
+
65
+ const updatedContext = {
66
+ ...mockPageContext,
67
+ components: {},
68
+ isInsideEditor: false
69
+ };
70
+ render(
71
+ <MockContextRender mockContext={updatedContext}>
72
+ <Container containerRef={mockContainerRef} />
73
+ </MockContextRender>
74
+ );
75
+
76
+ expect(screen.queryByTestId('empty-container')).toBeNull();
77
+ });
78
+ });
79
+ });
80
+
81
+ // Add tests for pointer events, dynamic component rendering, and other scenarios...
82
+ });