From 5b5c698af705446989b9831e0af57623820caf15 Mon Sep 17 00:00:00 2001
From: Jorge Manrubia <jorge@37signals.com>
Date: Fri, 22 Aug 2025 14:34:30 +0200
Subject: [PATCH] Rename Action Text Lexical => Lexxy

 Conflicts:
	app/assets/stylesheets/terminals.css
---
 Gemfile                                       |  2 +-
 Gemfile.lock                                  | 17 +++----
 app/assets/stylesheets/cards.css              |  2 +-
 .../{actiontext-lexical.css => lexxy.css}     | 48 +++++++++----------
 app/assets/stylesheets/rich-text-content.css  |  4 +-
 app/helpers/rich_text_helper.rb               | 10 ++--
 app/javascript/application.js                 |  2 +-
 .../controllers/hotkey_controller.js          |  2 +-
 .../controllers/local_save_controller.js      |  4 +-
 .../syntax_highlight_controller.js            |  2 +-
 app/views/cards/comments/_new.html.erb        |  2 +-
 app/views/cards/container/_title.html.erb     |  2 +-
 app/views/prompts/cards/_card.html.erb        |  4 +-
 .../prompts/collections/users/_user.html.erb  |  4 +-
 app/views/prompts/commands/_command.html.erb  |  4 +-
 app/views/prompts/tags/_tag.html.erb          |  4 +-
 config/importmap.rb                           |  2 +-
 17 files changed, 58 insertions(+), 57 deletions(-)
 rename app/assets/stylesheets/{actiontext-lexical.css => lexxy.css} (85%)

diff --git a/Gemfile b/Gemfile
index 87a4a1367..d9fd6f1fe 100644
--- a/Gemfile
+++ b/Gemfile
@@ -27,7 +27,7 @@ gem "rqrcode"
 gem "redcarpet"
 gem "rouge"
 gem "jbuilder"
-gem "actiontext-lexical", bc: "actiontext-lexical"
+gem "lexxy", bc: "lexxy", branch: "rename-to-lexxy"
 gem "image_processing", "~> 1.14"
 gem "platform_agent"
 gem "aws-sdk-s3", require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 76292e489..e79ef4ef3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,10 +1,3 @@
-GIT
-  remote: https://github.com/basecamp/actiontext-lexical
-  revision: 36c86dfd59406c853cb791adfd19a650f781d824
-  specs:
-    actiontext-lexical (0.1.0)
-      rails (>= 8.0.2)
-
 GIT
   remote: https://github.com/basecamp/active_record-tenanted
   revision: f7bf7c2ba5602ed6ad842b54da7355d281d52b21
@@ -38,6 +31,14 @@ GIT
       thor (~> 1.3)
       zeitwerk (>= 2.6.18, < 3.0)
 
+GIT
+  remote: https://github.com/basecamp/lexxy
+  revision: 9957a98d2e1e8ee75d7fc9accce16b8e29c3c62d
+  branch: rename-to-lexxy
+  specs:
+    lexxy (0.1.0)
+      rails (>= 8.0.2)
+
 GIT
   remote: https://github.com/basecamp/portfolio
   revision: 86411a53d19a42ce44705a50ebe7c22828597991
@@ -596,7 +597,6 @@ PLATFORMS
   x86_64-mingw32
 
 DEPENDENCIES
-  actiontext-lexical!
   active_record-tenanted!
   activeresource
   aws-sdk-s3
@@ -612,6 +612,7 @@ DEPENDENCIES
   importmap-rails
   jbuilder
   kamal!
+  lexxy!
   mission_control-jobs
   mocha
   mysql2!
diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css
index 7bedc3334..3183168f8 100644
--- a/app/assets/stylesheets/cards.css
+++ b/app/assets/stylesheets/cards.css
@@ -176,7 +176,7 @@
   }
 
   .card-field__description {
-    lexical-toolbar {
+    lexxy-toolbar {
       border-block-start: 1px solid var(--color-ink-light);
       margin-block-start: var(--block-margin) !important;
     }
diff --git a/app/assets/stylesheets/actiontext-lexical.css b/app/assets/stylesheets/lexxy.css
similarity index 85%
rename from app/assets/stylesheets/actiontext-lexical.css
rename to app/assets/stylesheets/lexxy.css
index c6ac46217..eb19c788a 100644
--- a/app/assets/stylesheets/actiontext-lexical.css
+++ b/app/assets/stylesheets/lexxy.css
@@ -1,5 +1,5 @@
 @layer components {
-  lexical-editor {
+  lexxy-editor {
     display: block;
     position: relative;
     overflow: visible;
@@ -18,11 +18,11 @@
       }
     }
 
-    /* Lexical still uses the `lexical-editor--empty` class if you have a list
+    /* Lexical still uses the `lexxy-editor--empty` class if you have a list
        started with no other characters. Here, we won't show the placeholder if
        you've clicked the List button in the toolbar. */
-    &.lexical-editor--empty {
-      .lexical-editor__content:not(:has(ul, ol))::before {
+    &.lexxy-editor--empty {
+      .lexxy-editor__content:not(:has(ul, ol))::before {
         content: attr(placeholder);
         color: currentColor;
         cursor: text;
@@ -40,7 +40,7 @@
     }
   }
 
-  .lexical-dialog-actions {
+  .lexxy-dialog-actions {
     display: flex;
     font-size: var(--text-x-small);
     flex: 1 1 0%;
@@ -65,7 +65,7 @@
     }
   }
 
-  .lexical-editor__content {
+  .lexxy-editor__content {
     margin: var(--block-space-half) 0;
     min-block-size: calc(7lh + var(--block-space));
     outline: 0;
@@ -81,13 +81,13 @@
     }
   }
 
-  .lexical-editor--drag-over {
+  .lexxy-editor--drag-over {
     background-color: var(--color-selected);
     border-radius: 4px;
     outline: 2px dashed var(--color-selected-dark);
   }
 
-  lexical-toolbar {
+  lexxy-toolbar {
     background-color: inherit;
     border-block-end: 1px solid var(--color-ink-light);
     color: currentColor;
@@ -152,7 +152,7 @@
     }
   }
 
-  .lexical-code-language-picker {
+  .lexxy-code-language-picker {
     /* Based on .input, .input--select */
     -webkit-appearance: none;
     appearance: none;
@@ -185,21 +185,21 @@
   /* Prompt
   /* ------------------------------------------------------------------------ */
 
-  .lexical-prompt-menu {
-    --lexical-prompt-avatar-size: 24px;
-    --lexical-prompt-min-width: 20ch;
-    --lexical-prompt-padding: 0.5ch;
+  .lexxy-prompt-menu {
+    --lexxy-prompt-avatar-size: 24px;
+    --lexxy-prompt-min-width: 20ch;
+    --lexxy-prompt-padding: 0.5ch;
 
     background-color: var(--color-canvas);
-    border-radius: calc(var(--lexical-prompt-padding) * 2);
+    border-radius: calc(var(--lexxy-prompt-padding) * 2);
     box-shadow: var(--shadow);
     color: var(--color-ink);
     font-family: var(--font-sans);
     font-size: var(--text-small);
     list-style: none;
     margin: 0;
-    min-inline-size: var(--lexical-prompt-min-width);
-    padding: var(--lexical-prompt-padding);
+    min-inline-size: var(--lexxy-prompt-min-width);
+    padding: var(--lexxy-prompt-padding);
     visibility: hidden;
     z-index: var(--z-popup);
 
@@ -207,17 +207,17 @@
     overflow: scroll;
   }
 
-  .lexical-prompt-menu--visible {
+  .lexxy-prompt-menu--visible {
     visibility: initial;
   }
 
-  .lexical-prompt-menu__item {
+  .lexxy-prompt-menu__item {
     align-items: center;
     border-radius: 0.5ch;
     cursor: pointer;
     display: flex;
-    gap: var(--lexical-prompt-padding);
-    padding: var(--lexical-prompt-padding);
+    gap: var(--lexxy-prompt-padding);
+    padding: var(--lexxy-prompt-padding);
     white-space: nowrap;
 
     &:hover {
@@ -229,10 +229,10 @@
     }
 
     img {
-      block-size: var(--lexical-prompt-avatar-size);
+      block-size: var(--lexxy-prompt-avatar-size);
       border-radius: 50%;
       flex-shrink: 0;
-      inline-size: var(--lexical-prompt-avatar-size);
+      inline-size: var(--lexxy-prompt-avatar-size);
       margin: 0;
     }
 
@@ -249,8 +249,8 @@
   }
 
   /* Empty state */
-  .lexical-prompt-menu__item--empty {
+  .lexxy-prompt-menu__item--empty {
     color: var(--color-ink-medium);
-    padding: var(--lexical-prompt-padding);
+    padding: var(--lexxy-prompt-padding);
   }
 }
diff --git a/app/assets/stylesheets/rich-text-content.css b/app/assets/stylesheets/rich-text-content.css
index b7d525c6d..c758ed5e2 100644
--- a/app/assets/stylesheets/rich-text-content.css
+++ b/app/assets/stylesheets/rich-text-content.css
@@ -23,7 +23,7 @@
     :where(p, ul, ol, dl, blockquote, figure, .attachment) {
       margin-block: var(--block-margin);
 
-      &:not(lexical-editor &) {
+      &:not(lexxy-editor &) {
         overflow-wrap: break-word;
         text-wrap: pretty;
       }
@@ -362,7 +362,7 @@
        0.5ch 0 0 var(--attachment-bg-color);
     border-radius: 99rem;
 
-    lexical-editor & {
+    lexxy-editor & {
       cursor: pointer;
     }
 
diff --git a/app/helpers/rich_text_helper.rb b/app/helpers/rich_text_helper.rb
index 47941a6a7..752af1075 100644
--- a/app/helpers/rich_text_helper.rb
+++ b/app/helpers/rich_text_helper.rb
@@ -1,22 +1,22 @@
 module RichTextHelper
   def mentions_prompt(collection)
-    content_tag "lexical-prompt", "", trigger: "@", src: prompts_collection_users_path(collection), name: "mention"
+    content_tag "lexxy-prompt", "", trigger: "@", src: prompts_collection_users_path(collection), name: "mention"
   end
 
   def global_mentions_prompt
-    content_tag "lexical-prompt", "", trigger: "@", src: prompts_users_path, name: "mention"
+    content_tag "lexxy-prompt", "", trigger: "@", src: prompts_users_path, name: "mention"
   end
 
   def tags_prompt
-    content_tag "lexical-prompt", "", trigger: "#", src: prompts_tags_path, name: "tag"
+    content_tag "lexxy-prompt", "", trigger: "#", src: prompts_tags_path, name: "tag"
   end
 
   def cards_prompt
-    content_tag "lexical-prompt", "", trigger: "#", src: prompts_cards_path, name: "card", "insert-editable-text": true, "remote-filtering": true, "supports-space-in-searches": true
+    content_tag "lexxy-prompt", "", trigger: "#", src: prompts_cards_path, name: "card", "insert-editable-text": true, "remote-filtering": true, "supports-space-in-searches": true
   end
 
   def code_language_picker
-    content_tag "lexical-code-language-picker"
+    content_tag "lexxy-code-language-picker"
   end
 
   def general_prompts(collection)
diff --git a/app/javascript/application.js b/app/javascript/application.js
index 725acdc82..dbac91d0a 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -3,7 +3,7 @@ import "@hotwired/turbo-rails"
 import "initializers"
 import "controllers"
 
-import "actiontext-lexical"
+import "lexxy"
 import "@rails/actiontext"
 
 window.fetch = Turbo.fetch // TODO: We need to make @rails/request.js use Turbo's fetch when it's present.
diff --git a/app/javascript/controllers/hotkey_controller.js b/app/javascript/controllers/hotkey_controller.js
index 1c85d69e8..a6b8192c9 100644
--- a/app/javascript/controllers/hotkey_controller.js
+++ b/app/javascript/controllers/hotkey_controller.js
@@ -9,7 +9,7 @@ export default class extends Controller {
   }
 
   #shouldIgnore(event) {
-    return event.defaultPrevented || event.target.closest("input, textarea, lexical-editor")
+    return event.defaultPrevented || event.target.closest("input, textarea, lexxy-editor")
   }
 
   get #isClickable() {
diff --git a/app/javascript/controllers/local_save_controller.js b/app/javascript/controllers/local_save_controller.js
index 5f9fc83a3..80af8b0bb 100644
--- a/app/javascript/controllers/local_save_controller.js
+++ b/app/javascript/controllers/local_save_controller.js
@@ -46,8 +46,8 @@ export default class extends Controller {
   }
 
   #triggerChangeEvent(newValue) {
-    if (this.inputTarget.tagName === "LEXICAL-EDITOR") {
-      this.inputTarget.dispatchEvent(new CustomEvent('actiontext:change', {
+    if (this.inputTarget.tagName === "LEXXY-EDITOR") {
+      this.inputTarget.dispatchEvent(new CustomEvent('fizzy:change', {
         bubbles: true,
         detail: {
           previousContent: '',
diff --git a/app/javascript/controllers/syntax_highlight_controller.js b/app/javascript/controllers/syntax_highlight_controller.js
index 02b66a0f7..cfaf93ba1 100644
--- a/app/javascript/controllers/syntax_highlight_controller.js
+++ b/app/javascript/controllers/syntax_highlight_controller.js
@@ -1,5 +1,5 @@
 import { Controller } from "@hotwired/stimulus"
-import { highlightAll } from "actiontext-lexical"
+import { highlightAll } from "lexxy"
 
 export default class extends Controller {
   connect() {
diff --git a/app/views/cards/comments/_new.html.erb b/app/views/cards/comments/_new.html.erb
index 14fb50a4a..8d4a6a2d4 100644
--- a/app/views/cards/comments/_new.html.erb
+++ b/app/views/cards/comments/_new.html.erb
@@ -10,7 +10,7 @@
                   local_save_key_value: "comment-#{card.id}",
                   action: "turbo:submit-end->local-save#submit keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop" } do |form| %>
         <%= form.rich_textarea :body, required: true, placeholder: new_comment_placeholder(card),
-              data: { local_save_target: "input", action: "actiontext:change->local-save#save turbo:morph-element->local-save#restoreContent" } do %>
+              data: { local_save_target: "input", action: "fizzy:change->local-save#save turbo:morph-element->local-save#restoreContent" } do %>
           <%= general_prompts(@card.collection) %>
         <% end %>
         <%= form.button class: "comment__submit btn btn--reversed flex-item-justify-start" do %>
diff --git a/app/views/cards/container/_title.html.erb b/app/views/cards/container/_title.html.erb
index 0521f52d0..d349f6631 100644
--- a/app/views/cards/container/_title.html.erb
+++ b/app/views/cards/container/_title.html.erb
@@ -17,7 +17,7 @@
     </h1>
     <%= form.rich_textarea :description, class: "card-field__description margin-block-start-half margin-block-end",
           placeholder: "Add some notes, context, pictures, or video about this…",
-          data: { action: "actiontext:change->auto-save#change focusout->auto-save#submit keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop" } do %>
+          data: { action: "fizzy:change->auto-save#change focusout->auto-save#submit keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop" } do %>
       <%= general_prompts(card.collection) %>
     <% end %>
   <% end %>
diff --git a/app/views/prompts/cards/_card.html.erb b/app/views/prompts/cards/_card.html.erb
index ebecb20a6..3f45c6213 100644
--- a/app/views/prompts/cards/_card.html.erb
+++ b/app/views/prompts/cards/_card.html.erb
@@ -1,8 +1,8 @@
-<lexical-prompt-item>
+<lexxy-prompt-item>
   <template type="menu">
     #<%= card.id %> <%= card.title %>
   </template>
   <template type="editor">
     <%= link_to "##{card.id} #{card.title}", collection_card_url(card.collection, card) %>
   </template>
-</lexical-prompt-item>
+</lexxy-prompt-item>
diff --git a/app/views/prompts/collections/users/_user.html.erb b/app/views/prompts/collections/users/_user.html.erb
index ad4b917b2..3224f30a0 100644
--- a/app/views/prompts/collections/users/_user.html.erb
+++ b/app/views/prompts/collections/users/_user.html.erb
@@ -1,4 +1,4 @@
-<lexical-prompt-item search="<%= "#{user.name} #{user.initials} #{"me" if user == Current.user}" %>" sgid="<%= user.attachable_sgid %>">
+<lexxy-prompt-item search="<%= "#{user.name} #{user.initials} #{"me" if user == Current.user}" %>" sgid="<%= user.attachable_sgid %>">
   <template type="menu">
     <%= avatar_image_tag user %>
     <%= user.name %>
@@ -7,4 +7,4 @@
     <%= avatar_image_tag user %>
     <%= user.first_name %>
   </template>
-</lexical-prompt-item>
+</lexxy-prompt-item>
diff --git a/app/views/prompts/commands/_command.html.erb b/app/views/prompts/commands/_command.html.erb
index d9fc0f799..634483f58 100644
--- a/app/views/prompts/commands/_command.html.erb
+++ b/app/views/prompts/commands/_command.html.erb
@@ -1,10 +1,10 @@
 <% command, description, editor_version = command %>
 
-<lexical-prompt-item search="<%= description %> <%= command %>">
+<lexxy-prompt-item search="<%= description %> <%= command %>">
   <template type="menu">
     <code><%= command %></code> <%= description %>
   </template>
   <template type="editor">
     <%= editor_version.gsub(/ +$/, "&nbsp;").html_safe %>
   </template>
-</lexical-prompt-item>
+</lexxy-prompt-item>
diff --git a/app/views/prompts/tags/_tag.html.erb b/app/views/prompts/tags/_tag.html.erb
index 904484f5d..3be999a8e 100644
--- a/app/views/prompts/tags/_tag.html.erb
+++ b/app/views/prompts/tags/_tag.html.erb
@@ -1,8 +1,8 @@
-<lexical-prompt-item search="<%= tag.title %>" sgid="<%= tag.attachable_sgid %>">
+<lexxy-prompt-item search="<%= tag.title %>" sgid="<%= tag.attachable_sgid %>">
   <template type="menu">
     #<%= tag.title %>
   </template>
   <template type="editor">
     #<%= tag.title %>
   </template>
-</lexical-prompt-item>
+</lexxy-prompt-item>
diff --git a/config/importmap.rb b/config/importmap.rb
index 2abe3a805..f1da52737 100644
--- a/config/importmap.rb
+++ b/config/importmap.rb
@@ -10,6 +10,6 @@ pin_all_from "app/javascript/controllers", under: "controllers"
 pin_all_from "app/javascript/helpers", under: "helpers"
 pin_all_from "app/javascript/initializers", under: "initializers"
 pin "marked" # @15.0.11
-pin "actiontext-lexical"
+pin "lexxy"
 pin "@rails/activestorage", to: "activestorage.esm.js"
 pin "@rails/actiontext", to: "actiontext.esm.js"
