From e92c843852a643fd57d9541f5b4311391d9ad9e4 Mon Sep 17 00:00:00 2001 From: Anang Yusman Date: Tue, 10 Feb 2026 15:23:55 +0800 Subject: [PATCH] update ckeditor --- components/details/details-content.tsx | 20 +++- components/editor/custom-editor.js | 100 +------------------ components/editor/view-editor.js | 3 +- components/table/article-table.tsx | 31 +++++- package-lock.json | 129 +++---------------------- package.json | 2 +- styles/custom-editor.css | 121 +++++++++++++++++++++++ 7 files changed, 181 insertions(+), 225 deletions(-) create mode 100644 styles/custom-editor.css diff --git a/components/details/details-content.tsx b/components/details/details-content.tsx index 49e3617..dd6a790 100644 --- a/components/details/details-content.tsx +++ b/components/details/details-content.tsx @@ -21,6 +21,7 @@ import { import { saveActivity } from "@/service/activity-log"; import { useForm } from "react-hook-form"; import { Badge } from "../ui/badge"; +import { formatTextToHtmlTag } from "@/utils/global"; type TabKey = "trending" | "comments" | "latest"; @@ -320,6 +321,16 @@ export default function DetailContent() { ); } + function removeImgTags(htmlString?: { __html: string }) { + const parser = new DOMParser(); + const doc = parser.parseFromString(String(htmlString?.__html), "text/html"); + + const images = doc.querySelectorAll("img"); + images.forEach((img) => img.remove()); + + return { __html: doc.body.innerHTML }; + } + function decodeHtmlString(raw: string = "") { if (!raw) return ""; @@ -497,11 +508,10 @@ export default function DetailContent() {
{/* */} diff --git a/components/editor/custom-editor.js b/components/editor/custom-editor.js index 95886a7..cee120f 100644 --- a/components/editor/custom-editor.js +++ b/components/editor/custom-editor.js @@ -1,7 +1,7 @@ -// components/custom-editor.js - -import React from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import { CKEditor } from "@ckeditor/ckeditor5-react"; + +import "@/styles/custom-editor.css"; import Editor from "@/vendor/ckeditor5/build/ckeditor"; function CustomEditor(props) { @@ -47,7 +47,7 @@ function CustomEditor(props) { padding: 1rem; } p { - margin: 0.5em 0; + margin: 0.5em 0 !important; } h1, h2, h3, h4, h5, h6 { margin: 1em 0 0.5em 0; @@ -72,98 +72,6 @@ function CustomEditor(props) { }, }} /> -
); } diff --git a/components/editor/view-editor.js b/components/editor/view-editor.js index 31e7db9..1e579b0 100644 --- a/components/editor/view-editor.js +++ b/components/editor/view-editor.js @@ -48,7 +48,8 @@ function ViewEditor(props) { .ckeditor-view-wrapper { border-radius: 6px; overflow: hidden; - box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), + box-shadow: + 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); } diff --git a/components/table/article-table.tsx b/components/table/article-table.tsx index 3a50853..919c99d 100644 --- a/components/table/article-table.tsx +++ b/components/table/article-table.tsx @@ -316,7 +316,7 @@ export default function ArticleTable() { return cellValue; } }, - [article, page] + [article, page], ); let typingTimer: NodeJS.Timeout; @@ -445,8 +445,8 @@ export default function ArticleTable() {
-
- +
+
{(username === "admin-mabes" @@ -455,7 +455,18 @@ export default function ArticleTable() { ).map((column) => ( {column.name} @@ -472,7 +483,17 @@ export default function ArticleTable() { ).map((column) => ( {renderCell(item, column.uid)} diff --git a/package-lock.json b/package-lock.json index 0db3818..2101675 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "react-apexcharts": "^1.7.0", "react-datepicker": "^8.4.0", "react-day-picker": "^9.7.0", - "react-dom": "^19.0.0", + "react-dom": "^19.2.4", "react-dropzone": "^14.3.8", "react-hook-form": "^7.59.0", "react-password-checklist": "^1.8.1", @@ -1521,111 +1521,6 @@ "fast-glob": "3.3.1" } }, - "node_modules/@next/swc-darwin-arm64": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.4.tgz", - "integrity": "sha512-z0qIYTONmPRbwHWvpyrFXJd5F9YWLCsw3Sjrzj2ZvMYy9NPQMPZ1NjOJh4ojr4oQzcGYwgJKfidzehaNa1BpEg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.4.tgz", - "integrity": "sha512-Z0FYJM8lritw5Wq+vpHYuCIzIlEMjewG2aRkc3Hi2rcbULknYL/xqfpBL23jQnCSrDUGAo/AEv0Z+s2bff9Zkw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.4.tgz", - "integrity": "sha512-l8ZQOCCg7adwmsnFm8m5q9eIPAHdaB2F3cxhufYtVo84pymwKuWfpYTKcUiFcutJdp9xGHC+F1Uq3xnFU1B/7g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.4.tgz", - "integrity": "sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.4.tgz", - "integrity": "sha512-gEbH9rv9o7I12qPyvZNVTyP/PWKqOp8clvnoYZQiX800KkqsaJZuOXkWgMa7ANCCh/oEN2ZQheh3yH8/kWPSEg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.4.tgz", - "integrity": "sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.3.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.4.tgz", - "integrity": "sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@next/swc-win32-x64-msvc": { "version": "15.3.4", "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.4.tgz", @@ -6375,9 +6270,9 @@ ] }, "node_modules/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "engines": { "node": ">=0.10.0" } @@ -6429,14 +6324,14 @@ } }, "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "dependencies": { - "scheduler": "^0.26.0" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19.2.4" } }, "node_modules/react-dropzone": { @@ -6748,9 +6643,9 @@ } }, "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==" }, "node_modules/semver": { "version": "7.7.2", diff --git a/package.json b/package.json index 57a2716..15769bc 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "react-apexcharts": "^1.7.0", "react-datepicker": "^8.4.0", "react-day-picker": "^9.7.0", - "react-dom": "^19.0.0", + "react-dom": "^19.2.4", "react-dropzone": "^14.3.8", "react-hook-form": "^7.59.0", "react-password-checklist": "^1.8.1", diff --git a/styles/custom-editor.css b/styles/custom-editor.css new file mode 100644 index 0000000..d203c3d --- /dev/null +++ b/styles/custom-editor.css @@ -0,0 +1,121 @@ +/* ========== CKEditor Wrapper ========== */ +.ckeditor-wrapper { + border-radius: 6px; + overflow: hidden; + box-shadow: + 0 1px 3px 0 rgba(0, 0, 0, 0.1), + 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} + +/* ========== Main Editor Container ========== */ +.ckeditor-wrapper .ck.ck-editor__main { + min-height: var(--editor-min-height, 400px); + max-height: var(--editor-max-height, 600px); +} + +/* ========== Editable Content Area (ClassicEditor) ========== */ +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline { + min-height: calc(var(--editor-min-height, 400px) - 50px); + max-height: calc(var(--editor-max-height, 600px) - 50px); + overflow-y: auto !important; + scrollbar-width: thin; + scrollbar-color: #cbd5e1 #f1f5f9; + background: #fff !important; + color: #111 !important; + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-size: 14px; + line-height: 1.6; + padding: 1rem; + border: none !important; +} + +/* ========== Headings and Text Formatting ========== */ +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h1, +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h2, +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h3, +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h4, +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h5, +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h6 { + margin: 1em 0 0.5em 0; + color: inherit !important; +} + +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline p { + margin: 0.5em 0 !important; +} + +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline ul, +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline ol { + margin: 0.5em 0; + padding-left: 2em; +} + +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline blockquote { + margin: 1em 0; + padding: 0.5em 1em; + border-left: 4px solid #d1d5db; + background-color: #f9fafb; + color: inherit !important; +} + +/* ========== Dark Mode Support ========== */ +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline { + background: #111 !important; + color: #f9fafb !important; +} + +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h1, +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h2, +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h3, +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h4, +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h5, +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline h6 { + color: #f9fafb !important; +} + +.dark .ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline blockquote { + background-color: #1f2937 !important; + border-left-color: #374151 !important; + color: #f3f4f6 !important; +} + +/* ========== Custom Scrollbars (Light & Dark) ========== */ +.ckeditor-wrapper .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar { + width: 8px; +} + +.ckeditor-wrapper + .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-track { + background: #f1f5f9; + border-radius: 4px; +} + +.ckeditor-wrapper + .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb { + background: #cbd5e1; + border-radius: 4px; +} + +.ckeditor-wrapper + .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb:hover { + background: #94a3b8; +} + +.dark + .ckeditor-wrapper + .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-track { + background: #1f2937; +} + +.dark + .ckeditor-wrapper + .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb { + background: #4b5563; +} + +.dark + .ckeditor-wrapper + .ck.ck-content.ck-editor__editable_inline::-webkit-scrollbar-thumb:hover { + background: #6b7280; +}