My Design System Lexical Rich Text Editor Implementation

About the Lexical Implementation

Things to note about this implementation of Lexical:

  • An editor instance will be created on any editor that looks like: <div data-rich-text-editor>
  • All editors should be wrapped in an element that looks like <div class="lexical-wrapper">. This is because most of the time you will want a toolbar with buttons that dispatch actions, and these actions should be listened for and dispatched on the wrapper <div>. Each one of these wrapper divs should have a unique id that is a valid javascript variable name. That is how we keep track of different editor instances in the client side javascript.
  • We use the wrapper div to add appropriate event listeners when registering Lexical Update Listeners, and when an ancestor of the editor is about to be removed form the DOM we use the id of the editor to get the editor instance and properly remove the editor.
  • When a LexicalEditor is focused, we get the input in the <main> element that looks like: <input id="LEXICAL_EDITOR_CURRENT" type="text" />, and set the value of the input to be the id of the wrapper div of the focused editor instance so we can include dialogs on the page that have the ability to dispatch actions on the correct editor instance.
    This allows us to have multiple rich text editors on a single page and only one set of dialogs.
  • When an editor is encountered and is in the process of being registered, we first check if the editor has any innerHTML, and id it does, then we try to derive lexical state from the innerHTML and apply that to the editor.
  • I need to look over how the editor nodes implement the exportDOM function because I may need to include the version of the Node in the data-* attributes for each element to prevent any errors when new versions of nodes are added to the editor.

  • There are different kinds of lexical editors that register different Command / Update Listers on the editor. You can specify which kind of editor you want by including different data-* attributes on the data-rich-text-editor element. Here are the ones that have been implemented so far (more will be added in the future):
    • data-rich-text-full
      • Includes all the features that an editor can have - used for the article builder and to test out new features.
    • data-article
      • Includes all the features that an editor can have - used for the article builder and for rendering articles. This kind of editor has its editable feature set to false after the Lexical State is applied to the div because it is meant to be read. I will need to add the ability for users to highlight specific portions of the article later so that they can highlight certain pieces of content they like / dislike and comment on it.
    • data-type="poll-question"
      • Basically the same as the full editor except for different styling.
    • data-poll-response
      • Used to allow users to respond to polls.
    • data-range-description
      • Used to allow users to describe range inputs for poll questions.

TO DO:

  1. There needs to be a way for users to upload .csv or .xlsx information and get a rendered lexical table in return. Need to look into how to append data to the editor like that.
  2. Maybe look into inline-highlighted code.
  3. Need to include the context menu for highlighted text and implement that context menu for highlighted text on mobile. Look into the Context Menu event.

Example Lexical Implementation

Insert the body of the article here...

Insert Math Markup

ESC
About Inserting Math Content
Display Style:

Embed News Content

ESC
About Embedding News Content

Embed Youtube Video

ESC
Embedding Youtube Videos

Embed TikTok Video

ESC
Embedding TikTok Videos

Embed X Post

ESC
Embedding X Posts

Embed Instagram Post

ESC
Embedding Instagram Posts

Insert Details Element

ESC

Example Output:

Summary Title
You will be able to insert content here after confirming the title of the <details> element.

Insert Table

ESC
Customization
Align:
Preview:

Insert Horizontal Rule

#000000

Preview:


Insert Chart

ESC

View Content At Different Sizes

ESC

Edit Style of Block Nodes

ESC

Edit the background color, default text color, margin, padding, and border of block nodes. Editable block nodes include paragraphs, headers, and lists.

#ffffff
#000000

Edit Selected Cells

Change the background color, vertical align, and borders of the cells in the current selection.

#ffffff
Vertical Align:
Border
#000000
Border Style:

Edit Table

ESC
Customization:
Align:

Upload Lexical State

ESC

Upload a .lexical file. If the file type matches the type of the current editor, then a preview will be shown below the file input.

Upload 3D Object

ESC

Upload Jupyter Notebook

ESC

Upload a Jupyter notebook and embed the resulting HTML in the text editor.

Insert Custom HTML

ESC

Edit Image Background Color

ESC
#ffffff

Insert Columns Layout

ESC
Column Type:

Select Code Language

ESC
Select Coding Language

Lexical Output

Submit the Lexical Editor above and the output will be rendered in the div below. Make sure to look out for the CLS when the lexical output is initially shown (which shows the output of exportDOM per-node) vs when the actual node is rendered via JavaScript.