Skip to content

Raise lexical version and use it to improve text selection#949

Closed
doxman wants to merge 3 commits into
mdx-editor:mainfrom
doxman:main
Closed

Raise lexical version and use it to improve text selection#949
doxman wants to merge 3 commits into
mdx-editor:mainfrom
doxman:main

Conversation

@doxman

@doxman doxman commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Upgrades lexical from 0.35.0 to 0.48.0.

This enables the use of $convertSelectionToMarkdownString, which was introduced in 0.45.0. Used this to make getSelectionAsMarkdown much more precise:

  1. Partially selected nodes are now accurately represented
    • Previous implementation treated partial nodes as if they were fully selected
  2. Task list checkboxes are now included in the output
  3. Nested lists are handled more nicely. Example:

Input (select the lines with A and B):

  • A
    • B
    • C

Output (old implementation):

- A
- - B
- C

- B

Output (new implementation):

- A
  - B

There were two common GFM nodes (thematic breaks, and tables) that were omitted by the previous implementation, and not automatically handled by the lexical function (because they are not core lexical functionality).

Solved this by writing custom Transformers for each of these, and feeding them to getSelectionAsMarkdown if the appropriate plugins are turned on.

In the process, gave tablePlugin a name so that we can check whether it's enabled, and a subscription to toMarkdownExtensions$ so that the transformer can pull them out of a cache and feed them to its toMarkdown() call.


Files not directly related to the main change

I did not delve too deeply into these, we can discuss a more proper fix if they are a concern

  • tsconfig.json: The higher version of lexical required a change to moduleResolution ; I went with "bundler" as the smallest change.
  • src/mdastUtilHtmlComment.ts: The stricter TS module resolution caused issues with types and codes due to their weird types; added a typecast to fix this
  • src/plugins/codeblock/CodeBlockNode.tsx: Now clashes with Lexical's types. Used as unknown as casting trick to silence.
  • Files in src/plugins/thematic-break/: Lexical has deprecated the thematic break members in lexical/react and recommends lexical/extension instead. However, they are not interchangeable - for example HorizontalRulePlugin is a component while HorizontalRuleExtension is a config object. I only moved over the objects I could confirm are the same between the two, and left eslint-disable comments on the rest for now.

Additional edge case

There was one edge-case with selection that I found but did not fix. If a link is partially selected without including the first character, and no other lines are selected, then selection is returned as empty (no error logs or anything).

I think this is because the LINK transformer's regex only identifies a link node if the lead character is included; at least, when it's the only selected node. Since this is probably a rare case, I think it's better to wait for lexical to fix it upstream, than make a handrolled solution to patch it.

@petyosi

petyosi commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

@doxman thanks for raising that, it's indeed a meaningful improvement, and keeping up with lexical has been long overdue. It also accumulated a bunch of things that had to be addressed for the upgrade to work properly (and take advantage of some new Lexical features).

I spent some fable/sol tokens on the upgrade specifics, taking your finding into account, and merged #950 . I would appreciate if you give it some testing, let me know if you discover anything.

Regards,

@petyosi petyosi closed this Jul 19, 2026
pull Bot pushed a commit to LeeeeeeM/editor that referenced this pull request Jul 19, 2026
Capture the changelog assessment, PR mdx-editor#949 analysis, bounded child PRPs, spikes, execution notes, and independently verified evidence. Preserve the decision to keep the public MDAST visitor pipeline authoritative and leave lexical/mdast for a separate initiative.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants