From 0d5cb898d53e1cb2e169b1c0cfac8937664cba33 Mon Sep 17 00:00:00 2001 From: Alexander Don Date: Sun, 15 Mar 2026 23:47:54 +0200 Subject: [PATCH] Integrate Leaf editor into PhoenixKit Bundle leaf.js into phoenix_kit.js and register the Leaf hook globally. Switch Posts editor from MarkdownEditor to Leaf with visual mode default. Update media insertion JS and add Leaf message handlers in the edit LiveView. Co-Authored-By: Claude Opus 4.6 --- lib/modules/posts/web/edit.ex | 20 +- lib/modules/posts/web/edit.html.heex | 27 +- mix.exs | 3 + mix.lock | 1 + priv/static/assets/phoenix_kit.js | 2033 ++++++++++++++++++++++++++ 5 files changed, 2070 insertions(+), 14 deletions(-) diff --git a/lib/modules/posts/web/edit.ex b/lib/modules/posts/web/edit.ex index 21acdb1cb..ee68caa19 100644 --- a/lib/modules/posts/web/edit.ex +++ b/lib/modules/posts/web/edit.ex @@ -110,7 +110,7 @@ defmodule PhoenixKitWeb.Live.Modules.Posts.Edit do @impl true def handle_event("save", %{"post" => post_params}, socket) do # Merge content from assigns (stored separately from form) - content = socket.assigns.content + content = socket.assigns[:live_content] || socket.assigns.content post_params = Map.put(post_params, "content", content) # Parse tags from content if auto-tagging is enabled @@ -215,14 +215,13 @@ defmodule PhoenixKitWeb.Live.Modules.Posts.Edit do end end - # Handle content changes from MarkdownEditor component + # Handle content changes from MarkdownEditor/Leaf component @impl true def handle_info( - {:editor_content_changed, %{content: content, editor_id: "post-content-editor"}}, + {:editor_content_changed, %{content: content, editor_id: "post-content-editor" <> _}}, socket ) do - # Store content as a separate assign (like Publishing editor does) - {:noreply, assign(socket, :content, content)} + {:noreply, assign(socket, :live_content, content)} end # Handle image/video insert from MarkdownEditor toolbar @@ -324,6 +323,17 @@ defmodule PhoenixKitWeb.Live.Modules.Posts.Edit do |> assign(:selecting_featured_image, false)} end + # Handle Leaf editor messages + def handle_info({:leaf_changed, %{markdown: content}}, socket) do + {:noreply, assign(socket, :live_content, content)} + end + + def handle_info({:leaf_insert_request, %{type: type}}, socket) do + handle_info({:editor_insert_component, %{type: type}}, socket) + end + + def handle_info({:leaf_mode_changed, _}, socket), do: {:noreply, socket} + # Catch-all for other editor events def handle_info({:editor_insert_component, _}, socket), do: {:noreply, socket} def handle_info({:editor_save_requested, _}, socket), do: {:noreply, socket} diff --git a/lib/modules/posts/web/edit.html.heex b/lib/modules/posts/web/edit.html.heex index 1c521e880..41eba85d9 100644 --- a/lib/modules/posts/web/edit.html.heex +++ b/lib/modules/posts/web/edit.html.heex @@ -143,15 +143,14 @@ <.live_component - module={PhoenixKitWeb.Components.Core.MarkdownEditor} + module={Leaf} id="post-content-editor" content={@content} + mode={:visual} placeholder="Write your post content here... Use #hashtags for auto-tagging" height="400px" debounce={400} toolbar={[:image, :video]} - protect_navigation={false} - script_nonce={assigns[:csp_nonce] || ""} />