diff --git a/package.json b/package.json index 973841da8f15a1cc7e3f6657caf11045f44113d7..809302991e0ccc35d57207632a44767dff9a0777 100644 --- a/package.json +++ b/package.json @@ -52,20 +52,22 @@ "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "@types/draft-js": "^0.11.4", + "@types/draftjs-to-html": "^0.8.1", "@types/html-to-draftjs": "^1.4.0", "@types/luxon": "^3.0.0", - "@types/react-draft-wysiwyg": "^1.13.3", + "@types/react-draft-wysiwyg": "^1.13.4", "ag-grid-community": "^27.1.0", "ag-grid-react": "^27.1.0", "axios": "^0.21.1", "dayjs": "^1.10.7", "draft-js": "^0.11.7", "draft-js-export-html": "^1.4.1", + "draftjs-to-html": "^0.9.1", "html-to-draftjs": "^1.5.0", "luxon": "^3.0.1", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-draft-wysiwyg": "^1.14.7", + "react-draft-wysiwyg": "^1.15.0", "react-router-dom": "^5.2.0", "react-scripts": "^5.0.1", "react-toastify": "^7.0.4", diff --git a/src/components/Editing/CustomEditor.tsx b/src/components/Editing/CustomEditor.tsx index 3fae4902f7ef9457baccbedd9812491550e54430..960aa784ee7ae570dc664ea112cd52aae7ae6b0e 100644 --- a/src/components/Editing/CustomEditor.tsx +++ b/src/components/Editing/CustomEditor.tsx @@ -1,5 +1,6 @@ -import { stateToHTML } from 'draft-js-export-html' -import React, { useCallback, useMemo, useState } from 'react' +import { convertToRaw } from 'draft-js' +import draftToHtml from 'draftjs-to-html' +import React, { useCallback, useState } from 'react' import { Editor, EditorState } from 'react-draft-wysiwyg' import './customEditor.scss' import CustomLink from './CustomLink' @@ -20,36 +21,38 @@ const CustomEditor: React.FC<CustomEditorProps> = ({ }: CustomEditorProps) => { const [editorState, setEditorState] = useState<EditorState>(baseState) - const entityStyleFn = useMemo( - () => (entity: any) => { - const entityType = entity.get('type').toLowerCase() - if (entityType === 'link') { - const data = entity.getData() - return { - element: 'a', - attributes: { - title: data.title, - href: data.href ? data.href : data.url, - }, - } + const convertStateToHTML = (state: EditorState) => { + const parseElements = ({ type, data }: { type: string; data: any }) => { + // properly align images (see: https://github.com/jpuri/draftjs-to-html/issues/28#issuecomment-607344551) + if (type === 'IMAGE') { + const alignment = data.alignment || 'none' + const textAlign = alignment === 'none' ? 'center' : alignment + const alt = data.alt ? data.alt : '' + return `<p style="text-align:${textAlign};"><img src="${data.src}" alt="${alt}" style="height: ${data.height};width: ${data.width}"/></p>` } - }, - [] - ) + if (type === 'LINK') { + return `<a href=${data.href ? data.href : data.url} title=${ + data.title + }>${data.title}</a>` + } + } + return state.getCurrentContent().hasText() + ? draftToHtml( + convertToRaw(state.getCurrentContent()), + {}, + false, + parseElements + ) + : '' + } const handleStateChange = useCallback( (state: EditorState) => { setEditorState(state) - if (state.getCurrentContent().hasText()) { - handleChange( - stateToHTML(state.getCurrentContent(), { entityStyleFn }), - editorType - ) - } else { - handleChange('', editorType) - } + const htmlState = convertStateToHTML(state) + handleChange(htmlState, editorType) }, - [editorType, handleChange, entityStyleFn] + [editorType, handleChange] ) return ( diff --git a/src/components/Editing/customEditor.scss b/src/components/Editing/customEditor.scss index 133604b2aaed841161c482d5acad3c7b644495af..74854419c19e8bc81372e8fdcdd60731b2b4243b 100644 --- a/src/components/Editing/customEditor.scss +++ b/src/components/Editing/customEditor.scss @@ -2,15 +2,25 @@ .toolbar-class { span, - li { + li, + input, + button, + div { color: black; + &:disabled { + opacity: 0.3; + } + &.rdw-image-mandatory-sign { + color: red; + } } } .editor-class { background: white; padding: 0rem 1rem; min-height: 100px; - span { + span, + div { color: black; } } diff --git a/src/components/ImagePicker/ImagePicker.tsx b/src/components/ImagePicker/ImagePicker.tsx index cce9b48afe6d38d06a536ec26bfc6963314ce060..705b2dcd48869ec84a8a00d1e5322e03b73f68e0 100644 --- a/src/components/ImagePicker/ImagePicker.tsx +++ b/src/components/ImagePicker/ImagePicker.tsx @@ -102,8 +102,8 @@ const ImagePicker: React.FC<ImagePickerProps> = ({ <> <div className="image-picker"> {imageNames && - imageNames !== [] && - imageNames[currentPage - 1] !== [] && + imageNames.length !== 0 && + imageNames[currentPage - 1].length !== 0 && imageNames[currentPage - 1].map((imageName) => ( <SingleImage imageURL={imageName} diff --git a/src/utils/editorStateManagment.ts b/src/utils/editorStateManagment.ts index dd3ff893cd944156a5bc8945559c27a34d5b2ee1..b37f30ff9efd7be9a9c150aeef6c3dc23c49c250 100644 --- a/src/utils/editorStateManagment.ts +++ b/src/utils/editorStateManagment.ts @@ -1,10 +1,8 @@ -import { EditorState, convertFromHTML, ContentState } from 'draft-js' +import { EditorState, ContentState } from 'draft-js' +import htmlToDraft from 'html-to-draftjs' export const convertStringToEditorState = (string: string): EditorState => { - const blocksFromHTML = convertFromHTML(string) - const state = ContentState.createFromBlockArray( - blocksFromHTML.contentBlocks, - blocksFromHTML.entityMap - ) + const { contentBlocks, entityMap } = htmlToDraft(string) + const state = ContentState.createFromBlockArray(contentBlocks, entityMap) return EditorState.createWithContent(state) } diff --git a/yarn.lock b/yarn.lock index d10f9e6385f406fcde025e8706147969ca552702..7396f1c6ed2534469d876132e6c577477157a4e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2097,6 +2097,13 @@ "@types/react" "*" immutable "~3.7.4" +"@types/draftjs-to-html@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@types/draftjs-to-html/-/draftjs-to-html-0.8.1.tgz#0800a4f6ff19ece49b6a337bfa8b39ed3d08a5fa" + integrity sha512-NBkphQs+qZ/sAz/j1pCUaxkPAOx00LTsE88aMSSfcvK+UfCpjHJDqIMCkm6wKotuJvY5w0BtdRazQ0sAaXzPdg== + dependencies: + "@types/draft-js" "*" + "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -2280,7 +2287,7 @@ dependencies: "@types/react" "^17" -"@types/react-draft-wysiwyg@^1.13.3": +"@types/react-draft-wysiwyg@^1.13.4": version "1.13.4" resolved "https://registry.yarnpkg.com/@types/react-draft-wysiwyg/-/react-draft-wysiwyg-1.13.4.tgz#df951c76afb47e311061d363f41a10c76de04ac8" integrity sha512-wasD1t78JDmQvdPDRPf/mf5FSHMlncunW0F6KMOKB3awzi3Wi21yHMGsRAUOkfTr3R8F+yceG8fSLz0kYWu/QA== @@ -3520,9 +3527,9 @@ cjs-module-lexer@^1.0.0: integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== classnames@^2.2.6: - version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== clean-css@^5.2.2: version "5.3.1" @@ -3723,9 +3730,9 @@ core-js@^3.19.2: integrity sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg== core-js@^3.6.4: - version "3.23.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.23.5.tgz#1f82b0de5eece800827a2f59d597509c67650475" - integrity sha512-7Vh11tujtAZy82da4duVreQysIoO2EvVrur7y6IzZkH1IHPSekuDi8Vuw1+YKjkbfWLRD7Nc9ICQ/sIUDutcyg== + version "3.29.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.29.0.tgz#0273e142b67761058bcde5615c503c7406b572d6" + integrity sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg== core-util-is@~1.0.0: version "1.0.3" @@ -4304,6 +4311,11 @@ draft-js@^0.11.7: immutable "~3.7.4" object-assign "^4.1.1" +draftjs-to-html@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/draftjs-to-html/-/draftjs-to-html-0.9.1.tgz#1c870fbb588d2390204cb4d0ee7e04ad0c709969" + integrity sha512-fFstE6+IayaVFBEvaFt/wN8vdj8FsTRzij7dy7LI9QIwf5LgfHFi9zSpvCg+feJ2tbYVqHxUkjcibwpsTpgFVQ== + draftjs-utils@^0.10.2: version "0.10.2" resolved "https://registry.yarnpkg.com/draftjs-utils/-/draftjs-utils-0.10.2.tgz#a7f16d2c1c174ac38ba3bbf700c256f176b2699c" @@ -8158,7 +8170,7 @@ react-dom@^17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" -react-draft-wysiwyg@^1.14.7: +react-draft-wysiwyg@^1.15.0: version "1.15.0" resolved "https://registry.yarnpkg.com/react-draft-wysiwyg/-/react-draft-wysiwyg-1.15.0.tgz#d5b4173991033859b9e161c883889ddc00909a57" integrity sha512-p1cYZcWc6/ALFBVksbFoCM3b29fGQDlZLIMrXng0TU/UElxIOF2/AWWo4L5auIYVhmqKTZ0NkNjnXOzGGuxyeA== @@ -9400,9 +9412,9 @@ typescript@^4.1.2, typescript@^4.5.4: integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== ua-parser-js@^0.7.18: - version "0.7.31" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" - integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + version "0.7.33" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz#1d04acb4ccef9293df6f70f2c3d22f3030d8b532" + integrity sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw== uc.micro@^1.0.1: version "1.0.6"