diff --git a/assets/js/app.js b/assets/js/app.js index c44b1b544..dcbcb8e4a 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -4,6 +4,11 @@ import "phoenix_html"; import { Socket } from "phoenix"; import NProgress from "nprogress"; import { LiveSocket } from "phoenix_live_view"; +import ContentEditable from "./content_editable"; + +const Hooks = { + ContentEditable, +}; const csrfToken = document .querySelector("meta[name='csrf-token']") @@ -11,6 +16,7 @@ const csrfToken = document const liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken }, + hooks: Hooks, }); // Show progress bar on live navigation and form submits diff --git a/assets/js/content_editable.js b/assets/js/content_editable.js new file mode 100644 index 000000000..ad91c39b2 --- /dev/null +++ b/assets/js/content_editable.js @@ -0,0 +1,39 @@ +/** + * A hook used on [contenteditable] elements to update the specified + * attribute with the element text. + * + * Configuration: + * + * * `data-update-attribute` - the name of the attribute to update when content changes + */ +const ContentEditable = { + mounted() { + this.attribute = this.el.dataset.updateAttribute; + + this.__updateAttribute(); + + // Set the specified attribute on every content change + this.el.addEventListener("input", (event) => { + this.__updateAttribute(); + }); + + // Make sure only plain text is pasted + this.el.addEventListener("paste", (event) => { + event.preventDefault(); + const text = event.clipboardData.getData("text/plain"); + document.execCommand("insertText", false, text); + }); + }, + + updated() { + // The element has been re-rendered so we have to add the attribute back + this.__updateAttribute(); + }, + + __updateAttribute() { + const value = this.el.innerText.trim(); + this.el.setAttribute(this.attribute, value); + }, +}; + +export default ContentEditable; diff --git a/lib/live_book_web/live/section.ex b/lib/live_book_web/live/section.ex index 337db6822..0636beaaa 100644 --- a/lib/live_book_web/live/section.ex +++ b/lib/live_book_web/live/section.ex @@ -7,7 +7,14 @@ defmodule LiveBookWeb.Section do
<%= Icons.svg(:chevron_right, class: "h-8") %> -

<%= @section.name %>

+

<%= @section.name %>