facebook/lexical
 Watch   
 Star   
 Fork   
4 days ago
lexical

v0.38.2

v0.38.2 is a patch release to fix a regression in yjs cursor position awareness (#7960). It also includes another fix for a Markdown issue.

Highlights

React:

  • ✅ #7960 Fix: update cursor positions on awareness update in collab v1

Markdown:

  • ✅ #7958 Fix markdown formatting when a backslash is before or after a closing backtick

What's Changed

Full Changelog: https://github.com/facebook/lexical/compare/v0.38.1...v0.38.2

7 days ago
lexical

v0.38.1

v0.38.1 is an monthly release with a lot of fixes and a few potentially breaking changes (this is a re-publish of v0.38.0, which had problems during initial npm publish).

Breaking Changes

#7926 Static transforms from superclasses are always applied

Before $config there was a limited amount of "automatic" re-use of the static transform by subclasses, because class inheritance also inherits static methods, so you get the implementation of whatever static transform method was in the superclass if it wasn't overridden.

Now the application of these static transforms (whether by method or $config) is implicit. There is no need to call super if adding an additional transform. The implementation walks up the inheritance tree by $config extends or Object.getPrototypeOf and will register all transforms it finds.

#7936 Extension configuration for CodeHighlighterShikiExtension has been flattened

If you are using CodeHighlighterShikiExtension the configuration has changed.

Before:

configExtension(CodeHighlighterShikiExtension, {tokenizer: {...ShikiTokenizer, defaultTheme: })

After:

configExtension(CodeHighlighterShikiExtension, {defaultTheme: })

#7933 LexicalTableSelectionHelpers listener priorities lowered to HIGH from CRITICAL

This is unlikely to break most applications but the priority of these command listeners has been lowered to allow them to be overridden.

Highlights

Core:

  • ✅ #7926 Apply static transform and $config $transform from all superclasses (fixes ListNode/ListItemNode subclassing)
  • ✅ #7941 Retain lexical selection during updates on unfocused editors
  • ✅ #7947 Update block cursor if selection has changed

Extension:

  • 🆕 #7930 Allow nodes config to be deferred for circular dependency reasons
  • ⚠️ #7936 Implement mergeConfig for LinkExtension and flatten config for CodeHighlighterShikiExtension

List:

  • 🆕 #7946 importDOM support for joplin checklists

Table:

  • ⚠️ #7933 Lower table handler command priority

Clipboard:

  • ✅ #7942 Log exceptions in clipboard paste handlers

Link:

  • 🆕 #7944 Enable Selective Removal Within Linked Text

React:

  • ✅ #7935 Add getServerSnapshot for improved RSC compatibility

Collab v2:

  • ✅ #7922 Skip elements that were added and removed between snapshots

Code:

  • ✅ #7921 Respect RTL when moving to line start/end in code blocks

Markdown:

  • ✅ #7812 Fix bugs in normalizeMarkdown when using shouldMergeAdjacentLines
  • ✅ #7923 Prevent markdown links with empty strings from being automatically removed
  • ✅ #7928 Fix implicit checklist marker export regression

Playground:

  • ✅ #7920 Fix image caption overflow

Examples:

  • 🧹 #7939 Remove workaround from svelte example

Documentation:

  • 🧹 #7931 Update docusaurus and contributing docs

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.37.0...v0.38.1

23 days ago
lexical

v0.37.0

v0.37.0 is an ad-hoc release, primarily to update the happy-dom dependency to address a CVE (#7909 - lexical's usage of this package was not susceptible) but also includes several bug fixes. This was marked as a minor release because it includes an experimental collab v2 implementation which is not yet ready for use (see #7616 #7903)

Highlights

Core:

  • #7900 ✅ Fix $cloneWithProperties so that it doesn't throw an exception when used in read-only mode
  • #7904 🆕 Add new (internal) ephemeral node concept for situations where a cloned node is intentionally decoupled from the editor state for mutations that will only have a local effect

Examples:

  • 🆕 #7879 New sveltekit ssr example demonstrating the use of @lexical/headless/dom

React:

  • ✅ #7899 LexicalMenu guard against undefined option when list shrinks

Collab:

  • 🆕 #7616 #7903 #7907 #7908 Initial implementation of collab v2

List

  • 🆕 #7892 Keep list marker for markdown round-trip

Rich Text:

  • ✅ #7902 Fix up/down arrows for node selection

Clipboard/Playground:

  • ✅ #7900 ImageNode caption support for exportDOM and importDOM
  • ✅ #7906 Export ParagraphNode as div role="paragraph" when it contains block DOM (such as the <figure> from ImageNode captions)

Headless

  • 🧹 #7909 Update to happy-dom v20 to address CVE reports (lexical's usage was not susceptible)

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.36.2...v0.37.0

2025-10-01 10:14:42
lexical

v0.36.2

v0.36.2 is a bug fix release, primarily to fix a problem with the @lexical/headless package.json that prevented the new @lexical/headless/dom from being used as designed. It also includes several improvements and bug fixes such as the new SKIP_SELECTION_FOCUS_TAG.

Highlights

Core:

  • 🆕 #7804 New SKIP_SELECTION_FOCUS_TAG to allow the update to set the DOM selection but not automatically ensure that the root element is focused
  • 🧹 #7870 devInvariant should warn in prod even if not in codes.json (only relevant for unreleased versions, npm releases, even nightly ones, have an up to date codes.json)

Clipboard:

  • ✅ #7880 Copying from a collapsed selection no longer updates the clipboard (consistent with the browser's default behavior and other applications)

Markdown:

  • ✅ #7890 Ensure First Match is Used in importTextMatchTransformer Table:
  • ✅ #7864 Handle accessing table selection following table deletion Playground:
  • ✅ #7804 Improve focus management in toolbar DOM
  • ✅ #7847 Table add-row button no longer hides horizontal scroll

React:

  • ✅ #7843 Ensure selection listeners cleaned up from original owner document

HTML:

  • 🆕 #7859 $generateNodesFromDOM now accepts any ParentNode (not just Document) as input

Headless:

  • 🆕 #7873 #7859 @lexical/headless/dom should be usable now

Docs:

  • 🆕 #7830 Add example for how to bootstrap collab ydoc on the server
  • 🆕 #7893 Export DOMConversion* types so that they are in the docs
  • 🧹 #7881 Update to docusaurus v3.9.1

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.36.1...v0.36.2

2025-09-25 23:27:05
lexical

v0.36.1

v0.36.1 is a major feature release with a new Lexical Extension API (#7706), some needed breaking changes to @lexical/yjs (#7816, #7818) and a bunch of bug fixes. We've also moved to React 19 (#7802) for all examples, tests, etc. although it should all still remain compatible with React 18 for now.

Breaking Changes

#7706 DecoratorNode

  • Removed type requirement & warning for DecoratorNode to implement decorate()
  • Widens type for decorate(): T to be decorate(): null | T as that's always how it worked in practice - the generic type here is unsafe and wrong anyway (e.g. $isDecoratorNode is a cast to any type T)

#7818 useCollaborationContext now requires that a context provider is used

Users of the CollaborationPlugin or useCollaborationContext must wrap the top-level LexicalComposer with a LexicalCollaboration component. For example:

<LexicalCollaboration>
  <LexicalComposer initialConfig={initialConfig}>
    <RichTextPlugin ... />
    <CollaborationPlugin id="lexical-editor" ... />
  </LexicalComposer>
<LexicalCollaboration>

The collaboration context is shared for nested editors, so the provider must only be used on the top-level editor.

#7818 useCollaborationContext no longer has clientID

clientID has been removed from the collaboration context. This ID was unreliable as it could be updated by nested collab editors. Consumers should retrieve the client ID by looking up the correct document in the context's yjsDocMap, or switch to using a different ID.

Highlights

Extension:

Core:

  • ✅ #7836 Fix cache coherency issue with RangeSelection#extract
  • ✅ #7854 Account for Apple WebView in setManagedLineBreak
  • 🧹 #7855 TabNode.setTextContent uses devInvariant instead of invariant for a warning in prod
  • 🧹 #7821 Improve error message when a node is registered from a foreign lexical module
  • 🧹 #7814 Consolidate ancestor lookup via findMatchingParent

Clipboard:

  • ✅ #7835 Update Lexical Clipboard with Empty Selection
  • ✅ #7822 Copy correct selection when editor in different window/document

List:

  • ✅ #7805 Clear li checklist attributes when inserting nested list

Markdown:

  • 🧹 #7832 Remove MarkdownShortcuts.ts dependency on index.ts

React:

  • ⚠️ #7816 Breaking change: remove clientID from collab context
  • ⚠️ #7818 Breaking change: enforce use of collab context provider
  • ✅ #7844 Add visibility margin to isTriggerVisibleInNearestScrollContainer to prevent popover from wrongfully closing
  • 🧹 #7802 #7803 Update from React 18 to React 19

Headless:

  • 🧪 #7833 @lexical/headless/dom module featuring withDOM function to make SSR easier

Playground:

  • ✅ #7786 DatetimeNode DOM updates
  • 🗑️ #7839 Remove mostly redundant InlineImageNode and InlineImageNodePlugin

Internal:

  • 🧹 #7766 #7810 Updated docusaurus and added local search index
  • 🧹 #7834 Relocate internal eslint plugin to packages/lexical-eslint-plugin-internal
  • 🧹 #7807 Port scripts unit tests to vitest and fix test include match pattern

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.35.0...v0.36.1

2025-09-05 08:32:32
lexical

v0.35.0

v0.35.0 is a monthly release with much improved RTL bidirectional text support (#7727) and several bug fixes

Breaking Changes

All of the breaking changes in this release are related to the improved RTL bidirectional text support in #7727

ltr and rtl theme CSS classes removed

ltr and rtl theme CSS classes are no longer added to DOM elements. If you have custom CSS to set text-align (or any other properties) for bidirectional text, this can be removed. You can target elements that have customized their dir by targeting the attr in CSS, for example:

[dir=rtl] { text-align: right; }

$isParentElementRTL requires an active editor

$isParentElementRTL now relies on accessing the DOM to determine element direction, meaning there must be an active editor when calling the function. If you have code that calls $isParentElementRTL inside editorState.read(), you will need to pass in an editor argument. For example:

const isRTL = editorState.read(
  () => {
    const selection = $getSelection();
    return $isRangeSelection(selection) && $isParentElementRTL(selection);
  },
  {editor}
);

__dir property is synced to/from Yjs (again)

Prior to #7330, the text direction of nodes (as determined by the reconciler) was synced to Yjs, even though this value was ignored on other clients. This property is now used for any manually-set direction attribute on ElementNode.

If you have documents that were created prior to v0.30.0, the previously-reconciled direction will now be read and applied to nodes in the editor. This may lead to unexpected behaviour if, for example, your document contains a paragraph that contained RTL text but content changed to LTR in >= v0.30.0.

Highlights

Core:

  • 🆕 #7727 Allow ElementNode direction to be overridden (RTL)
  • ✅ #7772 Correct exit direction from decorator nodes in RTL
  • ✅ #7794 Fix insert into existing paragraph node if selection is on parent element

Markdown:

  • ✅ #7769 Formatted textmatch fix
  • 🆕 #7735 Allow any characters in markdown link text

React:

  • ✅ #7757 Add $config $transform inheritance to LexicalNestedComposer
  • ✅ #7778 Fix the context menu event listener element

Internal:

  • 🧹 #7770 Update flow suppressions to use error code
  • 🧹 #7785 flow-bin updated to 0.280.0
  • 🧹 #7796 Replace jest with vitest for unit tests

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.34.0...v0.35.0

2025-08-08 04:55:33
lexical

v0.34.0

v0.34.0 is a monthly release with several bug fixes and a new experimental Shiki based code highlighter engine for @lexical/code (the existing prismjs highlighter is still the default)

Highlights

Core:

  • ✅ #7724 Fix trigger of reconciliation on nested editor.read
  • ✅ #7725 Clamp DOM selection offsets to valid lexical TextNode offsets in $internalResolveSelectionPoint

Code:

  • 🆕 #7662 Experimental Shiki support for code highlighting

Selection:

  • ✅ #7686 Correct backward inversion for RTL

Utils:

  • ✅ #7737 Backwards selection was not being retained

React:

  • ✅ #7705 Clean up old mouseup events from context menu
  • 🆕 #7697 Context Menu icons
  • ✅ #7723 Prevent race condition in CollaborationPlugin during rapid mount/unmount cycles

Playground:

  • ✅ #7693 Image links lose link state when dragged
  • 🆕 #7719 Parse font sizes in pt as well as px in parseAllowedFontSize
  • ✅ #7707 DateTime plugin

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.33.1...v0.34.0

2025-07-11 03:49:24
lexical

v0.33.1

This is a patch release with a fix for the new $config flat NodeState API

Highlights

Core

  • ✅ #7683 Implement missing updateJSON support for $config flat NodeState
  • 🆕 #5829 RangeSelection.setFormat setter

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.33.0...v0.33.1

2025-07-04 05:42:19
lexical

v0.33.0

This is a monthly release with some major new features and lots of bug fixes

Breaking Changes

$copyNode(prevNode) now calls node.afterCloneFrom(prevNode) #7609

If you have code that assumes that newNode.afterCloneFrom(prevNode) will not be called as a result of $copyNode(prevNode), and would no longer work if it was, then it will need some refactoring. This is a very unlikely scenario.

role no longer removed from readonly LexicalContentEditableElement #7647

The role attribute is no longer removed from readonly LexicalContentEditableElement for better accessibility compliance. This may require application and/or CSS changes in rare cases.

New APIs

$config protocol #7258

There's a new protocol for creating new node classes, that's more concise, automatically generates the boilerplate for the static methods (getType, clone, importJSON) and has additional features for NodeState.

See the Creating custom nodes with $config and NodeState documentation.

Highlights

Core

  • 🆕 #7258 $config protocol + NodeState registration/flattening (also #7659 #7661 #7667 #7671)
  • ✅ #7641 Copy NodeState in TextNode.splitText
  • ✅ #7654 Allow the same mutation listener function to be registered to multiple nodes

Clipboard

  • 🆕 #7657 Inherit the style of the last pasted TextNode in the block after pasting rich text

Code

  • 🆕 #7613 Code diff highlighting

Devtools

  • 🆕 #7642 Add NodeState to TreeView

List

  • 🆕 #7638 Add a command to change an ordered list's start number
  • ✅ #7655 Make tap target for checklists bugger for touch input

React

  • ✅ #7633 Make ref types mutable
  • ✅ #7644 Handle DraggableBlockPlugin in scrollable editors
  • ✅ #7647 Do not remove role from read-only LexicalContentEditableElement
  • ✅ #7669 Fix an issue with dangling div portals with non-empty style in LexicalMenu (regressed in v0.25)

Table

  • ✅ #7637 Ignore SELECTION_INSERT_CLIPBOARD_NODES_COMMAND dispatched from child editors
  • ✅ #7656 Table selection now only occurs when dragging on touch devices

Playground

  • ✅ #7627 Update alignment state for image selection
  • ✅ #7636 Allow deleting an empty column layout via backspace
  • ✅ #7670 Close FloatingLinkEditor popup when user clicks out of it

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.32.1...v0.33.0

2025-06-05 05:17:13
lexical

v0.32.1

This is an ad-hoc patch release to include #7602 - which fixes an issue that could corrupt a document if a TabNode was at the anchor or focus of a selection when text is inserted under certain circumstances.

Highlights

Core

  • ✅ #7602 Treat all TabNode as if they are in token mode
  • ✅ #7579 Firefox now handles Select All (Ctrl+A) the same way as other browsers

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.32.0...v0.32.1