Skip to content

developius/lexical-actiontext

Repository files navigation

README

This is a bare Rails 7 app with esbuild.

It includes an example controller which can be used to replace Trix with Lexical for an ActionText rich text field.

The HTML generated by Lexical is stored in a hidden input field (same approach as Trix). We then persist this to the database and render it when we show the article. This part works without any changes.

View controller & form partial.

Live demo or see video.

Intentions

I wanted to package this Stimulus controller up into a more reusable format and share make it available on NPM. Something like this which could then be extended by a subclass like that. So, imagine for this that the LexicalBaseController is a package bundled up nicely. Our app would implement the subclass.

This would make it super easy to extend without the Stimulus package needing to include all of the plugins and setup, which might not be needed for all consumers.

Sadly I ran into some issues. My knowledge of the internals of JS, bundles and other such things is limited, but hopefully I can convey the primary issues properly:

  1. Lexical uses a Map for storing event listeners (click, cut, copy, etc). This is fine, but the keys of the map are objects. This means we can't register plugins from the subclass as our copy of registerRichText doesn't have access to the same objects that the bundled version in the LexicalBaseController has. This means the calls to map.get() won't find the correct event listeners. This could be patched by using the strings instead of the objects.
  2. There are a few globals baked into the Lexical package itself. This makes it impossible to interact with the Lexical methods from outside of the bundle it's included in. Our subclass is in a different bundle, so we can't. Particularly, editorState is a global and $getSelection() depends on it. This means that even after (1) is resolved, an exception is raised when triggering the command (click, cut, paste, etc) as the editorState global is defined in the other bundle.

For now, the included Stimulus controller can be copied into your own application.

See blog post for more info.