From ece3da0eff0647781eae6b8f6a4897c94dae5bd5 Mon Sep 17 00:00:00 2001 From: thecodrr Date: Fri, 24 Dec 2021 12:32:58 +0500 Subject: [PATCH] feat: add scrollable column resizing for tables --- apps/web/package.json | 2 +- apps/web/patches/tinymce+5.10.2.patch | 33 ++++++ apps/web/src/components/editor/editor.css | 135 +++++++++++++++++++--- apps/web/src/components/editor/index.js | 1 - apps/web/src/components/editor/tinymce.js | 7 +- apps/web/src/theme/colorscheme/dark.js | 2 +- apps/web/src/theme/colorscheme/light.js | 2 +- 7 files changed, 161 insertions(+), 21 deletions(-) create mode 100644 apps/web/patches/tinymce+5.10.2.patch diff --git a/apps/web/package.json b/apps/web/package.json index 3b85f12bb..8242778e7 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -11,7 +11,7 @@ "@mdi/react": "^1.4.0", "@notesnook/desktop": "file:desktop", "@rebass/forms": "^4.0.6", - "@streetwritersco/tinymce-plugins": "^1.4.15", + "@streetwritersco/tinymce-plugins": "^1.5.0", "@tinymce/tinymce-react": "^3.13.0", "async-mutex": "^0.3.2", "axios": "^0.21.4", diff --git a/apps/web/patches/tinymce+5.10.2.patch b/apps/web/patches/tinymce+5.10.2.patch new file mode 100644 index 000000000..380fe7ca2 --- /dev/null +++ b/apps/web/patches/tinymce+5.10.2.patch @@ -0,0 +1,33 @@ +diff --git a/node_modules/tinymce/plugins/table/plugin.js b/node_modules/tinymce/plugins/table/plugin.js +index e41249b..fb25fc5 100644 +--- a/node_modules/tinymce/plugins/table/plugin.js ++++ b/node_modules/tinymce/plugins/table/plugin.js +@@ -1875,7 +1875,8 @@ + var remove$5 = function (element) { + var dom = element.dom; + if (dom.parentNode !== null) { +- dom.parentNode.removeChild(dom); ++ if (dom.parentNode.classList.contains("table-container")) dom.parentNode.remove(); ++ else dom.parentNode.removeChild(dom); + } + }; + var unwrap = function (wrapper) { +@@ -7259,7 +7260,9 @@ + editor.undoManager.ignore(function () { + var table = render(rows, columns, rowHeaders, colHeaders, getTableHeaderType(editor), options); + set$2(table, 'data-mce-id', '__mce'); ++ set$2(table, "contenteditable", "true"); + var html = getOuter(table); ++ html = `
${html}


`; + editor.insertContent(html); + editor.addVisual(); + }); +@@ -9575,7 +9578,7 @@ + var rootElements = [ + 'table', + 'li', +- 'dl' ++ 'dl', + ]; + var handle$1 = function (event, editor, cellSelection) { + if (event.keyCode === global$1.TAB) { diff --git a/apps/web/src/components/editor/editor.css b/apps/web/src/components/editor/editor.css index b14729132..755a292b1 100644 --- a/apps/web/src/components/editor/editor.css +++ b/apps/web/src/components/editor/editor.css @@ -112,19 +112,6 @@ max-width: 100% !important; } -.mce-content-body table { - display: block !important; - overflow-x: auto !important; - white-space: nowrap !important; - max-width: 100% !important; - width: 100% !important; - height: auto !important; -} - -.mce-content-body td { - min-width: 20vw !important; -} - .mce-content-body [data-mce-selected] { outline: none !important; box-shadow: 0px 0px 0px 2px var(--primary); @@ -169,7 +156,10 @@ background-color: var(--shade) !important; } -.mce-content-body a[data-mce-selected] { +a[data-mce-selected], +td[data-mce-selected], +th[data-mce-selected], +table[data-mce-selected] { box-shadow: none !important; } @@ -207,3 +197,120 @@ margin-left: 0; margin-right: -1.5em; } + +/* TABLE */ + +.mce-content-body table { + table-layout: fixed; + border-collapse: separate !important; + border-spacing: 0px; + border: none !important; + border-radius: 5px; + font-size: 14px; + min-width: 100% !important; +} + +.mce-content-body td, +.mce-content-body th { + padding: 5px !important; + border: 1px solid var(--border) !important; + border-left: none !important; + border-top: none !important; +} + +.mce-content-body td:last-child { + border-right: none !important; +} + +.mce-content-body tr:last-child td { + border-bottom: none !important; +} + +.mce-content-body tr:nth-child(even) { + background-color: var(--bgSecondary); +} + +.mce-content-body .table-container { + border: 1px solid var(--border); + border-radius: 5px; + overflow-x: auto; + max-width: 100%; +} + +.mce-content-body td > *, +.mce-content-body th > * { + margin: 0 !important; +} + +.mce-content-body td > * + *, +.mce-content-body th > * + * { + margin-top: 0.75em !important; +} + +.mce-content-body td[data-mce-selected]::after, +.mce-content-body th[data-mce-selected]::after { + background-color: var(--shade) !important; + border: 1px solid var(--shade) !important; + bottom: -1px; + content: ""; + left: -1px; + mix-blend-mode: multiply; + position: absolute; + right: -1px; + top: -1px; +} + +.mce-content-body table td:hover { + background-color: var(--shade); +} + +.mce-content-body table[data-mce-selected] tbody tr[data-mce-active] { + background-color: var(--shade); + /* color: var(--static); */ +} + +.mce-content-body + table[data-mce-selected] + tbody + tr[data-mce-active] + td:not([data-mce-active]), +.mce-content-body + table[data-mce-selected] + tbody + tr[data-mce-active] + th:not([data-mce-active]) { + border-bottom: 1px solid var(--dimPrimary) !important; + border-top: 1px solid var(--dimPrimary) !important; +} + +.mce-content-body + table[data-mce-selected] + tbody + tr[data-mce-active] + td:not([data-mce-active]):first-child, +.mce-content-body + table[data-mce-selected] + tbody + tr[data-mce-active] + th:not([data-mce-active]):first-child { + border-left: 1px solid var(--dimPrimary) !important; +} + +.mce-content-body + table[data-mce-selected] + tbody + tr[data-mce-active] + td:not([data-mce-active]):last-child, +.mce-content-body + table[data-mce-selected] + tbody + tr[data-mce-active] + th:not([data-mce-active]):last-child { + border-right: 1px solid var(--dimPrimary) !important; +} + +.mce-content-body table[data-mce-selected] tbody td[data-mce-active], +.mce-content-body table[data-mce-selected] tbody th[data-mce-active] { + border: 2px solid var(--dimPrimary) !important; + background-color: var(--shade); +} diff --git a/apps/web/src/components/editor/index.js b/apps/web/src/components/editor/index.js index 31052440c..04880a313 100644 --- a/apps/web/src/components/editor/index.js +++ b/apps/web/src/components/editor/index.js @@ -67,7 +67,6 @@ function Editor({ noteId, nonce }) { const startSession = useCallback( async function startSession(noteId) { - console.log("starting session"); if (noteId === 0) newSession(nonce); else if (noteId) { await openSession(noteId); diff --git a/apps/web/src/components/editor/tinymce.js b/apps/web/src/components/editor/tinymce.js index ac1285698..1a18c6957 100644 --- a/apps/web/src/components/editor/tinymce.js +++ b/apps/web/src/components/editor/tinymce.js @@ -32,6 +32,7 @@ import "@streetwritersco/tinymce-plugins/shortcuts"; import "@streetwritersco/tinymce-plugins/keyboardquirks"; import "@streetwritersco/tinymce-plugins/attachmentshandler"; import "@streetwritersco/tinymce-plugins/contenthandler"; +import "@streetwritersco/tinymce-plugins/bettertable"; import "./plugins/picker"; import "./plugins/icons"; import "./plugins/attachmentshandler.css"; @@ -120,7 +121,7 @@ const plugins = { default: "importcss searchreplace autolink directionality media table hr advlist lists imagetools noneditable autoresize", custom: - "contenthandler icons blockescape keyboardquirks collapsibleheaders shortlink paste codeblock inlinecode checklist attachmentshandler", + "bettertable contenthandler icons blockescape keyboardquirks collapsibleheaders shortlink paste codeblock inlinecode checklist attachmentshandler", pro: "textpattern picker", }; @@ -139,7 +140,7 @@ const plugins = { */ const changeEvents = "input paste ExecCommand ObjectResized cut Redo Undo NewBlock ListMutation"; -const ignoredCommand = ["mcerepaint", "mcefocus"]; +const ignoredCommand = ["mcerepaint", "mcefocus", "selectall"]; function TinyMCE(props) { const { @@ -251,7 +252,6 @@ function TinyMCE(props) { } const onEditorChange = debounce((e) => { - console.log(e); if ( e.type === "execcommand" && ignoredCommand.includes(e.command.toLowerCase()) @@ -308,6 +308,7 @@ function TinyMCE(props) { attachmenthandler_download_attachment: async (hash) => { await downloadAttachment(hash); }, + table_tab_navigation: true, }} onBeforeExecCommand={async (command) => { const isPremiumCommand = premiumCommands.some((cmd) => { diff --git a/apps/web/src/theme/colorscheme/dark.js b/apps/web/src/theme/colorscheme/dark.js index f271880af..6ef8379c9 100644 --- a/apps/web/src/theme/colorscheme/dark.js +++ b/apps/web/src/theme/colorscheme/dark.js @@ -11,7 +11,7 @@ class DarkColorSchemeFactory { accent: "#000", bgSecondary: "#2b2b2b", bgSecondaryText: "#A1A1A1", - border: "#2b2b2b", + border: "#3b3b3b", hover: "#3b3b3b", fontSecondary: "#000", fontTertiary: "#A1A1A1", diff --git a/apps/web/src/theme/colorscheme/light.js b/apps/web/src/theme/colorscheme/light.js index 736a59996..88622f1f8 100644 --- a/apps/web/src/theme/colorscheme/light.js +++ b/apps/web/src/theme/colorscheme/light.js @@ -10,7 +10,7 @@ class LightColorSchemeFactory { accent: "white", bgSecondary: "#f7f7f7", bgSecondaryText: "#5E5E5E", - border: "#e7e7e7", + border: "#e5e5e5", hover: "#f0f0f0", fontSecondary: "white", fontTertiary: "#656565",