@dotcms/react 0.0.1-beta.24 → 0.0.1-beta.26

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/next.esm.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { createContext, useContext, useState, useEffect, useLayoutEffect, useRef, useMemo } from 'react';
3
- import { s as styleInject } from './es.json.stringify.esm.js';
4
- import { getUVEState, initUVE, createUVESubscription } from '@dotcms/uve';
5
- import { DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_REACT, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getContainersData, getContentletsInContainer, getDotContainerAttributes, getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
6
- import { UVE_MODE, UVEEventType } from '@dotcms/uve/types';
3
+ import { s as styleInject } from './web.url-search-params.size.esm.js';
4
+ import { UVE_MODE, UVEEventType, DotCMSUVEAction } from '@dotcms/types';
5
+ import { getUVEState, initUVE, createUVESubscription, sendMessageToUVE } from '@dotcms/uve';
6
+ import { DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_REACT, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getContainersData, getContentletsInContainer, getDotContainerAttributes, getColumnPositionClasses, combineClasses, __DEFAULT_TINYMCE_CONFIG__, __BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__, __TINYMCE_PATH_ON_DOTCMS__ } from '@dotcms/uve/internal';
7
7
  import { updateNavigation } from '@dotcms/client';
8
+ import { Editor } from '@tinymce/tinymce-react';
9
+ import { __DOTCMS_UVE_EVENT__ } from '@dotcms/types/internal';
8
10
 
9
11
  /**
10
12
  * The `PageContext` is a React context that provides access to the DotCMS page context.
@@ -214,7 +216,7 @@ function FallbackComponent({
214
216
  *
215
217
  * Component to render when there is no component for the content type.
216
218
  *
217
- * @param {DotCMSContentlet} contentType - The content type that couldn't be rendered
219
+ * @param {DotCMSBasicContentlet} contentType - The content type that couldn't be rendered
218
220
  * @return {*}
219
221
  */
220
222
  function NoComponent({
@@ -640,4 +642,176 @@ const useEditableDotCMSPage = editablePage => {
640
642
  return updatedEditablePage;
641
643
  };
642
644
 
643
- export { DotCMSLayoutBody, DotCMSShow, useDotCMSShowWhen, useEditableDotCMSPage };
645
+ const DEFAULT_TINYMCE_CONFIG = Object.assign({}, __DEFAULT_TINYMCE_CONFIG__, {
646
+ licenseKey: 'gpl' // Using self-hosted license key
647
+ });
648
+ const TINYMCE_CONFIG = {
649
+ full: Object.assign({}, DEFAULT_TINYMCE_CONFIG, __BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.full),
650
+ plain: Object.assign({}, DEFAULT_TINYMCE_CONFIG, __BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.plain),
651
+ minimal: Object.assign({}, DEFAULT_TINYMCE_CONFIG, __BASE_TINYMCE_CONFIG_WITH_NO_DEFAULT__.minimal)
652
+ };
653
+
654
+ /**
655
+ * Allows inline edit content pulled from dotCMS API using TinyMCE editor
656
+ *
657
+ * @export
658
+ * @component
659
+ * @param {Readonly<DotCMSEditableTextProps>} props {
660
+ * mode = 'plain',
661
+ * format = 'text',
662
+ * contentlet,
663
+ * fieldName = ''
664
+ * }
665
+ * @example
666
+ * ```javascript
667
+ * import { DotCMSEditableText } from '@dotcms/react';
668
+ *
669
+ * const MyContentletWithTitle = ({ contentlet }) => (
670
+ * <h2>
671
+ * <DotCMSEditableText
672
+ * contentlet={contentlet}
673
+ * fieldName="title"
674
+ * mode='full'
675
+ * format='text'/>
676
+ * </h2>
677
+ * );
678
+ * ```
679
+ * @returns {JSX.Element} A component to edit content inline
680
+ */
681
+ function DotCMSEditableText({
682
+ mode = 'plain',
683
+ format = 'text',
684
+ contentlet,
685
+ fieldName = ''
686
+ }) {
687
+ const editorRef = useRef(null);
688
+ const [scriptSrc, setScriptSrc] = useState('');
689
+ const [initEditor, setInitEditor] = useState(false);
690
+ const [content, setContent] = useState((contentlet == null ? void 0 : contentlet[fieldName]) || '');
691
+ useEffect(() => {
692
+ var _state$dotCMSHost, _editorRef$current;
693
+ const state = getUVEState();
694
+ setInitEditor((state == null ? void 0 : state.mode) === UVE_MODE.EDIT && !!(state != null && (_state$dotCMSHost = state.dotCMSHost) != null && _state$dotCMSHost.length));
695
+ if (!contentlet || !fieldName) {
696
+ console.error('DotCMSEditableText: contentlet or fieldName is missing', 'Ensure that all needed props are passed to view and edit the content');
697
+ return;
698
+ }
699
+ if (state && state.mode !== UVE_MODE.EDIT) {
700
+ console.warn('DotCMSEditableText: TinyMCE is not available in the current mode');
701
+ return;
702
+ }
703
+ if (!(state != null && state.dotCMSHost)) {
704
+ console.warn('The `dotCMSHost` parameter is not defined. Check that the UVE is sending the correct parameters.');
705
+ return;
706
+ }
707
+ const createURL = new URL(__TINYMCE_PATH_ON_DOTCMS__, state.dotCMSHost);
708
+ setScriptSrc(createURL.toString());
709
+ const content = (contentlet == null ? void 0 : contentlet[fieldName]) || '';
710
+ (_editorRef$current = editorRef.current) == null || _editorRef$current.setContent(content, {
711
+ format
712
+ });
713
+ setContent(content);
714
+ }, [format, fieldName, contentlet]);
715
+ useEffect(() => {
716
+ var _getUVEState;
717
+ if (((_getUVEState = getUVEState()) == null ? void 0 : _getUVEState.mode) !== UVE_MODE.EDIT) {
718
+ return;
719
+ }
720
+ const onMessage = ({
721
+ data
722
+ }) => {
723
+ const {
724
+ name,
725
+ payload
726
+ } = data;
727
+ if (name !== __DOTCMS_UVE_EVENT__.UVE_COPY_CONTENTLET_INLINE_EDITING_SUCCESS) {
728
+ return;
729
+ }
730
+ const {
731
+ oldInode,
732
+ inode
733
+ } = payload;
734
+ const currentInode = contentlet.inode;
735
+ const shouldFocus = currentInode === oldInode || currentInode === inode;
736
+ if (shouldFocus) {
737
+ var _editorRef$current2;
738
+ (_editorRef$current2 = editorRef.current) == null || _editorRef$current2.focus();
739
+ }
740
+ };
741
+ window.addEventListener('message', onMessage);
742
+ return () => {
743
+ window.removeEventListener('message', onMessage);
744
+ };
745
+ }, [contentlet == null ? void 0 : contentlet.inode]);
746
+ const onMouseDown = event => {
747
+ var _editorRef$current3;
748
+ const {
749
+ onNumberOfPages = 1
750
+ } = contentlet;
751
+ const {
752
+ inode,
753
+ languageId: language
754
+ } = contentlet;
755
+ if (Number(onNumberOfPages) <= 1 || (_editorRef$current3 = editorRef.current) != null && _editorRef$current3.hasFocus()) {
756
+ return;
757
+ }
758
+ event.stopPropagation();
759
+ event.preventDefault();
760
+ sendMessageToUVE({
761
+ action: DotCMSUVEAction.COPY_CONTENTLET_INLINE_EDITING,
762
+ payload: {
763
+ dataset: {
764
+ inode,
765
+ language,
766
+ fieldName
767
+ }
768
+ }
769
+ });
770
+ };
771
+ const onFocusOut = () => {
772
+ var _editorRef$current4, _editorRef$current5;
773
+ const editedContent = ((_editorRef$current4 = editorRef.current) == null ? void 0 : _editorRef$current4.getContent({
774
+ format: format
775
+ })) || '';
776
+ const {
777
+ inode,
778
+ languageId: langId
779
+ } = contentlet;
780
+ if (!((_editorRef$current5 = editorRef.current) != null && _editorRef$current5.isDirty()) || !didContentChange(editedContent)) {
781
+ return;
782
+ }
783
+ sendMessageToUVE({
784
+ action: DotCMSUVEAction.UPDATE_CONTENTLET_INLINE_EDITING,
785
+ payload: {
786
+ content: editedContent,
787
+ dataset: {
788
+ inode,
789
+ langId,
790
+ fieldName
791
+ }
792
+ }
793
+ });
794
+ };
795
+ const didContentChange = editedContent => {
796
+ return content !== editedContent;
797
+ };
798
+ if (!initEditor) {
799
+ // We can let the user pass the Child Component and create a root to get the HTML for the editor
800
+ return jsx("span", {
801
+ dangerouslySetInnerHTML: {
802
+ __html: content
803
+ }
804
+ });
805
+ }
806
+ return jsx(Editor, {
807
+ tinymceScriptSrc: scriptSrc,
808
+ inline: true,
809
+ onInit: (_, editor) => editorRef.current = editor,
810
+ init: TINYMCE_CONFIG[mode],
811
+ initialValue: content,
812
+ onMouseDown: onMouseDown,
813
+ onFocusOut: onFocusOut
814
+ });
815
+ }
816
+
817
+ export { DotCMSEditableText, DotCMSLayoutBody, DotCMSShow, useDotCMSShowWhen, useEditableDotCMSPage };
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@dotcms/react",
3
- "version": "0.0.1-beta.24",
3
+ "version": "0.0.1-beta.26",
4
4
  "peerDependencies": {
5
5
  "react": ">=18",
6
6
  "react-dom": ">=18",
7
- "@dotcms/client": "0.0.1-beta.24",
8
- "@dotcms/uve": "0.0.1-beta.24",
7
+ "@dotcms/client": "0.0.1-beta.26",
8
+ "@dotcms/uve": "0.0.1-beta.26",
9
9
  "@tinymce/tinymce-react": "^6.0.0"
10
10
  },
11
+ "devDependencies": {
12
+ "@dotcms/types": "next"
13
+ },
11
14
  "description": "Official React Components library to render a dotCMS page.",
12
15
  "repository": {
13
16
  "type": "git",
@@ -1,4 +1,4 @@
1
- import { DotCMSColumnContainer, DotCMSPageAsset, DotPageAssetLayoutColumn } from '@dotcms/uve/types';
1
+ import { DotCMSColumnContainer, DotCMSPageAsset, DotPageAssetLayoutColumn, DotCMSBasicContentlet } from '@dotcms/types';
2
2
  export declare const MOCK_COLUMN: DotPageAssetLayoutColumn;
3
3
  export declare const MOCK_CONTAINER: DotCMSColumnContainer;
4
4
  export declare const MOCK_PAGE_ASSET: DotCMSPageAsset;
@@ -9,3 +9,4 @@ export declare const MOCK_CONTAINER_DATA: {
9
9
  acceptTypes: string;
10
10
  maxContentlets: number;
11
11
  };
12
+ export declare const MOCK_CONTENTLET: DotCMSBasicContentlet;
@@ -1,4 +1,4 @@
1
- import { DotPageAssetLayoutColumn } from '@dotcms/uve/types';
1
+ import { DotPageAssetLayoutColumn } from '@dotcms/types';
2
2
  /**
3
3
  * @internal
4
4
  *
@@ -1,4 +1,4 @@
1
- import { DotCMSColumnContainer } from '@dotcms/uve/types';
1
+ import { DotCMSColumnContainer } from '@dotcms/types';
2
2
  /**
3
3
  * @internal
4
4
  *
@@ -1,4 +1,4 @@
1
- import { DotContainerAttributes } from '@dotcms/uve/types';
1
+ import { DotContainerAttributes } from '@dotcms/types/internal';
2
2
  /**
3
3
  * @internal
4
4
  *
@@ -1,4 +1,4 @@
1
- import { DotCMSContentlet } from '@dotcms/uve/types';
1
+ import { DotCMSBasicContentlet } from '@dotcms/types';
2
2
  /**
3
3
  * @internal
4
4
  *
@@ -8,7 +8,7 @@ import { DotCMSContentlet } from '@dotcms/uve/types';
8
8
  * @property {string} container - The container identifier where the contentlet is placed
9
9
  */
10
10
  interface DotCMSContentletRendererProps {
11
- contentlet: DotCMSContentlet;
11
+ contentlet: DotCMSBasicContentlet;
12
12
  container: string;
13
13
  }
14
14
  /**
@@ -0,0 +1,30 @@
1
+ import { DotCMSEditableTextProps } from './utils';
2
+ /**
3
+ * Allows inline edit content pulled from dotCMS API using TinyMCE editor
4
+ *
5
+ * @export
6
+ * @component
7
+ * @param {Readonly<DotCMSEditableTextProps>} props {
8
+ * mode = 'plain',
9
+ * format = 'text',
10
+ * contentlet,
11
+ * fieldName = ''
12
+ * }
13
+ * @example
14
+ * ```javascript
15
+ * import { DotCMSEditableText } from '@dotcms/react';
16
+ *
17
+ * const MyContentletWithTitle = ({ contentlet }) => (
18
+ * <h2>
19
+ * <DotCMSEditableText
20
+ * contentlet={contentlet}
21
+ * fieldName="title"
22
+ * mode='full'
23
+ * format='text'/>
24
+ * </h2>
25
+ * );
26
+ * ```
27
+ * @returns {JSX.Element} A component to edit content inline
28
+ */
29
+ export declare function DotCMSEditableText({ mode, format, contentlet, fieldName }: Readonly<DotCMSEditableTextProps>): JSX.Element;
30
+ export default DotCMSEditableText;
@@ -0,0 +1,36 @@
1
+ import { IAllProps } from '@tinymce/tinymce-react';
2
+ import { DotCMSBasicContentlet } from '@dotcms/types';
3
+ export type DOT_EDITABLE_TEXT_FORMAT = 'html' | 'text';
4
+ export type DOT_EDITABLE_TEXT_MODE = 'minimal' | 'full' | 'plain';
5
+ export interface DotCMSEditableTextProps {
6
+ /**
7
+ * Represents the field name of the `contentlet` that can be edited
8
+ *
9
+ * @memberof DotCMSEditableTextProps
10
+ */
11
+ fieldName: string;
12
+ /**
13
+ * Represents the format of the editor which can be `text` or `html`
14
+ *
15
+ * @type {DOT_EDITABLE_TEXT_FORMAT}
16
+ * @memberof DotCMSEditableTextProps
17
+ */
18
+ format?: DOT_EDITABLE_TEXT_FORMAT;
19
+ /**
20
+ * Represents the mode of the editor which can be `plain`, `minimal`, or `full`
21
+ *
22
+ * @type {DOT_EDITABLE_TEXT_MODE}
23
+ * @memberof DotCMSEditableTextProps
24
+ */
25
+ mode?: DOT_EDITABLE_TEXT_MODE;
26
+ /**
27
+ * Represents the `contentlet` that can be inline edited
28
+ *
29
+ * @type {DotCMSBasicContentlet}
30
+ * @memberof DotCMSEditableTextProps
31
+ */
32
+ contentlet: DotCMSBasicContentlet;
33
+ }
34
+ export declare const TINYMCE_CONFIG: {
35
+ [key in DOT_EDITABLE_TEXT_MODE]: IAllProps['init'];
36
+ };
@@ -1,8 +1,10 @@
1
1
  /// <reference types="react" />
2
- import { DotCMSContentlet, DotCMSPageAsset, DotCMSPageRendererMode } from '@dotcms/uve/types';
3
- interface DotCMSLayoutBodyProps {
2
+ import { DotCMSBasicContentlet, DotCMSPageAsset, DotCMSPageRendererMode } from '@dotcms/types';
3
+ interface DotCMSLayoutBodyProps<TContentlet extends DotCMSBasicContentlet = DotCMSBasicContentlet> {
4
4
  page: DotCMSPageAsset;
5
- components: Record<string, React.ComponentType<DotCMSContentlet>>;
5
+ components: {
6
+ [key: string]: React.ComponentType<TContentlet> | React.ComponentType<any>;
7
+ };
6
8
  mode?: DotCMSPageRendererMode;
7
9
  }
8
10
  /**
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { UVE_MODE } from '@dotcms/uve/types';
2
+ import { UVE_MODE } from '@dotcms/types';
3
3
  /**
4
4
  * Props for the DotCMSShow component.
5
5
  *
@@ -1,22 +1,22 @@
1
1
  /// <reference types="react" />
2
- import { DotCMSContentlet } from '@dotcms/uve/types';
2
+ import { DotCMSBasicContentlet } from '@dotcms/types';
3
3
  /**
4
4
  * @internal
5
5
  *
6
6
  * Type definition for components that can be used as fallback when no matching component is found
7
7
  */
8
- export type NoComponentType = React.ComponentType<DotCMSContentlet>;
8
+ export type NoComponentType = React.ComponentType<DotCMSBasicContentlet>;
9
9
  /**
10
10
  * @internal
11
11
  *
12
12
  * Props for the FallbackComponent
13
13
  * @interface DotCMSFallbackComponentProps
14
- * @property {React.ComponentType<DotCMSContentlet>} [UserNoComponent] - Optional custom component to render when no matching component is found
15
- * @property {DotCMSContentlet} [contentlet] - The contentlet that couldn't be rendered
14
+ * @property {React.ComponentType<DotCMSBasicContentlet>} [UserNoComponent] - Optional custom component to render when no matching component is found
15
+ * @property {DotCMSBasicContentlet} [contentlet] - The contentlet that couldn't be rendered
16
16
  */
17
17
  interface DotCMSFallbackComponentProps {
18
- contentlet: DotCMSContentlet;
19
- UserNoComponent?: React.ComponentType<DotCMSContentlet>;
18
+ contentlet: DotCMSBasicContentlet;
19
+ UserNoComponent?: React.ComponentType<DotCMSBasicContentlet>;
20
20
  }
21
21
  /**
22
22
  * @internal
@@ -1,4 +1,4 @@
1
- import { DotPageAssetLayoutRow } from '@dotcms/uve/types';
1
+ import { DotPageAssetLayoutRow } from '@dotcms/types';
2
2
  /**
3
3
  * @internal
4
4
  *
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { DotCMSContentlet, DotCMSPageAsset, DotCMSPageRendererMode } from '@dotcms/uve/types';
2
+ import { DotCMSBasicContentlet, DotCMSPageAsset, DotCMSPageRendererMode } from '@dotcms/types';
3
3
  /**
4
4
  * @internal
5
5
  *
@@ -12,7 +12,7 @@ import { DotCMSContentlet, DotCMSPageAsset, DotCMSPageRendererMode } from '@dotc
12
12
  export interface DotCMSPageContextProps {
13
13
  pageAsset: DotCMSPageAsset;
14
14
  mode: DotCMSPageRendererMode;
15
- userComponents: Record<string, React.ComponentType<DotCMSContentlet>>;
15
+ userComponents: Record<string, React.ComponentType<DotCMSBasicContentlet>>;
16
16
  }
17
17
  /**
18
18
  * The `PageContext` is a React context that provides access to the DotCMS page context.
@@ -1,4 +1,4 @@
1
- import { UVE_MODE } from '@dotcms/uve/types';
1
+ import { UVE_MODE } from '@dotcms/types';
2
2
  /**
3
3
  * Custom hook to determine if the current UVE (Universal Visual Editor) mode
4
4
  * matches the specified mode. This hook is useful for conditionally rendering
@@ -1,4 +1,4 @@
1
- import { DotCMSEditablePage } from '@dotcms/uve/types';
1
+ import { DotCMSEditablePage } from '@dotcms/types';
2
2
  /**
3
3
  * Custom hook to manage the editable state of a DotCMS page.
4
4
  *
package/src/next.d.ts CHANGED
@@ -2,3 +2,4 @@ export { DotCMSLayoutBody } from './lib/next/components/DotCMSLayoutBody/DotCMSL
2
2
  export { DotCMSShow } from './lib/next/components/DotCMSShow/DotCMSShow';
3
3
  export { useDotCMSShowWhen } from './lib/next/hooks/useDotCMSShowWhen';
4
4
  export { useEditableDotCMSPage } from './lib/next/hooks/useEditableDotCMSPage';
5
+ export { DotCMSEditableText } from './lib/next/components/DotCMSEditableText/DotCMSEditableText';