@dotcms/react 0.0.1-beta.25 → 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 { UVE_MODE, UVEEventType } from '@dotcms/types';
5
- import { getUVEState, initUVE, createUVESubscription } from '@dotcms/uve';
6
- import { DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_REACT, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getContainersData, getContentletsInContainer, getDotContainerAttributes, getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
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.
@@ -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,11 +1,11 @@
1
1
  {
2
2
  "name": "@dotcms/react",
3
- "version": "0.0.1-beta.25",
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.25",
8
- "@dotcms/uve": "0.0.1-beta.25",
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
11
  "devDependencies": {
@@ -1,4 +1,4 @@
1
- import { DotCMSColumnContainer, DotCMSPageAsset, DotPageAssetLayoutColumn } from '@dotcms/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;
@@ -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
+ };
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';