From 749074fec03cefa8fe920b42be8c26bb1147ed02 Mon Sep 17 00:00:00 2001 From: Julia Casamitjana <62883011+JuliaCasamitjana@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:23:00 +0200 Subject: [PATCH] Add functionality to expand the markdown editor The editor will now have a default height of 300px but a button will let the user expand the editor. It will expand it to fit all content (or up to 400px if the content was not exceeding 300px). In the expanded mode the editor will keep growing as the user types more content. --- app/assets/javascripts/markdown_editor.js | 48 ++++++++++++++++++++++- app/helpers/markdown_form_builder.rb | 14 ++++++- app/javascript/toast-ui.scss | 30 ++++++++++++++ config/locales/de.yml | 3 ++ config/locales/en.yml | 3 ++ 5 files changed, 95 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/markdown_editor.js b/app/assets/javascripts/markdown_editor.js index e44f93f0..d8950ae6 100644 --- a/app/assets/javascripts/markdown_editor.js +++ b/app/assets/javascripts/markdown_editor.js @@ -1,7 +1,7 @@ /** * ToastUi editor initializer * - * This script transforms form textareas created with + * This script transforms form textareas created with * "MarkdownFormBuilder" into ToastUi markdown editors. * */ @@ -25,7 +25,7 @@ const initializeMarkdownEditors = () => { target: "_blank", }, previewHighlight: false, - height: "400px", + height: "300px", autofocus: false, usageStatistics: false, language: I18n.locale, @@ -45,6 +45,8 @@ const initializeMarkdownEditors = () => { }, }); + setResizeBtn(formInput, toastEditor); + // Prevent user from drag'n'dropping images in the editor toastEditor.removeHook("addImageBlobHook"); @@ -82,6 +84,48 @@ const setMarkdownEditorTheme = (theme) => { }); }; +const hasScrollBar = (el) => el.scrollHeight > el.clientHeight; +const toggleScrollbarModifier = (btn, el) => { + if (el.clientHeight === 0) return; + btn.classList.toggle( + "markdown-editor__resize-btn--with-scrollbar", + hasScrollBar(el) + ); +}; +const setResizeBtn = (formInput, editor) => { + const resizeBtn = document.querySelector(`#${formInput.id}-resize`); + if (!resizeBtn) return; + + const editorTextArea = editor + .getEditorElements() + .mdEditor.querySelector('[contenteditable="true"]'); + + toggleScrollbarModifier(resizeBtn, editorTextArea); + new MutationObserver(() => { + toggleScrollbarModifier(resizeBtn, editorTextArea); + }).observe(editorTextArea, { + attributes: true, + }); + + resizeBtn.addEventListener("click", () => { + const height = editor.getHeight(); + + if (height && height === "300px") { + editor.setHeight("auto"); + editor.setMinHeight("400px"); + resizeBtn.classList.add("markdown-editor__resize-btn--collapse"); + resizeBtn.title = I18n.t("markdown_editor.collapse"); + resizeBtn.ariaLabel = I18n.t("markdown_editor.collapse"); + } else { + editor.setHeight("300px"); + editor.setMinHeight("300px"); + resizeBtn.classList.remove("markdown-editor__resize-btn--collapse"); + resizeBtn.title = I18n.t("markdown_editor.expand"); + resizeBtn.ariaLabel = I18n.t("markdown_editor.expand"); + } + }); +}; + $(document).on("turbolinks:load", function () { initializeMarkdownEditors(); disableImageUpload(); diff --git a/app/helpers/markdown_form_builder.rb b/app/helpers/markdown_form_builder.rb index ca067ee0..b24bf30b 100644 --- a/app/helpers/markdown_form_builder.rb +++ b/app/helpers/markdown_form_builder.rb @@ -8,7 +8,7 @@ class MarkdownFormBuilder < ActionView::Helpers::FormBuilder @template.capture do @template.concat form_textarea - @template.concat @template.tag.div(class: 'markdown-editor', data: {behavior: 'markdown-editor-widget', id: label_target}) + @template.concat toast_ui_editor end end @@ -21,6 +21,18 @@ class MarkdownFormBuilder < ActionView::Helpers::FormBuilder class: 'd-none' end + def toast_ui_editor + @template.tag.div(class: 'markdown-editor__wrapper') do + @template.concat @template.tag.div(class: 'markdown-editor', data: {behavior: 'markdown-editor-widget', id: label_target}) + @template.concat resize_btn + end + end + + def resize_btn + @template.tag.button(class: 'markdown-editor__resize-btn fa-solid', type: 'button', id: "#{label_target}-resize", + title: I18n.t(:'markdown_editor.expand'), aria_label: I18n.t(:'markdown_editor.expand')) + end + def base_id options[:markdown_id_suffix] || @attribute_name end diff --git a/app/javascript/toast-ui.scss b/app/javascript/toast-ui.scss index 101a2093..cb43a999 100644 --- a/app/javascript/toast-ui.scss +++ b/app/javascript/toast-ui.scss @@ -5,6 +5,36 @@ * { box-sizing: content-box; } + + &__wrapper { + position: relative; + } + + &__resize-btn { + box-sizing: border-box; + position: absolute; + bottom: 30px; + right: 0; + background: transparent; + border: 1px solid transparent; + color: var(--bs-secondary-text-emphasis); + z-index: 100; + &::after { + content: "\f065"; + } + &--with-scrollbar { + right: 18px; + } + &--collapse { + right: 0; + &::after { + content: "\f066"; + } + } + &:hover { + background: var(--bs-secondary-bg); + } + } } // /*------------------------------------*\ diff --git a/config/locales/de.yml b/config/locales/de.yml index f5f1fac6..9b28e681 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -835,6 +835,9 @@ de:
This mail was automatically sent by CodeOcean.
subject: "Eine Aufgabe auf CodeOcean benötigt Ihr Feedback" + markdown_editor: + expand: Editor aufklappen + collapse: Editor zuklappen request_for_comments: click_here: Zum Kommentieren auf die Seitenleiste klicken! comments: Kommentare diff --git a/config/locales/en.yml b/config/locales/en.yml index fd902ca6..288b83f9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -835,6 +835,9 @@ en:
This mail was automatically sent by CodeOcean.
subject: "An exercise on CodeOcean needs your feedback" + markdown_editor: + expand: Expand editor + collapse: Collapse editor request_for_comments: click_here: Click on this sidebar to comment! comments: Comments