Skip to content

Releases: facebook/lexical

v0.42.0

19 Mar 21:07
01abe99

Choose a tag to compare

v0.42.0 is a monthly release with a huge number of fixes and features from a lot of new contributors. The most notable fixes are related to tables, links, extensions, and markdown. @lexical/eslint-plugin is now fully compatible with eslint 9+. The production builds are also now generated in an ascii-only format which may considerably reduce memory usage in some deployment environments.

Breaking Changes

Prism highlighting extracted from @lexical/code #8198

Prism highlighting now lives in @lexical/code-prism and the Prism related functionality in @lexical/code is now deprecated. Transitionally, there is a @lexical/code-core package which has the implementation of Lexical's code functionality without a Prism dependency.

Experimental hasFitNestedTables has been moved to the playground #8210

Due to its experimental nature and incomplete implementation, the in-progress hasFitNestedTables functionality has been moved to the playground

New APIs

lexical - $copyNode + LexicalNode.resetOnCopyNodeFrom & NodeState resetOnCopyNode

After $copyNode is used it now calls copiedNode.resetOnCopyNodeFrom(originalNode) which will reset every NodeState that has resetOnCopyNode: true in its configuration. Subclasses can override this method to reset other "ephemeral" state such as whether a ListNodeItem is checked or not.

Note that this does not influence serialization or copy and paste operations, it only affects calls to $copyNode.

@lexical/utils - $insertNodeIntoLeaf

The current behavior RangeSelection.insertNodes can split an inline ElementNode (e.g. a LinkNode) when inserting content, even if that content is also inline and could be a child of the given node. $insertNodeIntoLeaf is now provided to insert a node without splitting any containing nodes.

Highlights

Core:

  • 🧹 #8190 Change EditorThemeClasses from type to interface
  • #8218 Respect CSS scroll-padding in scrollIntoViewIfNeeded
  • #8220 deleteWord now behaves the same as deleteCharacter when at the edge of an ElementNode
  • 🆕 #8221 resetOnCopyNode configuration to NodeState and LexicalNode.resetOnCopyNodeFrom hook
  • 🆕 #8219 LexicalEditor RootListener and EditableListener can return unregister callbacks
  • #8222 Consecutive Linebreak insertion now preserves selection format

Code:

  • ⚠️ #8198 Extract Prism highlighting code to @lexical/code-prism and add @lexical/code-core to provide a dependency that does not include Prism. @lexical/code remains backwards compatible with Prism included, but you should migrate to using highlighting from @lexical/code-shiki or @lexical/code-prism.

Devtools:

  • #8230 Clean up strict mode useLexicalCommandsLog behavior

Extension:

  • 🆕 #8202 LexicalExtensionEditorComposer, NestedEditorExtension, and fixed SharedHistoryExtension with playground refactor

Markdown:

  • #8170 Enforce CommonMark flanking rules for trailing spaces
  • #8192 Update backslash handling to comply with CommonMark
  • #8211 Convert tabs to TabNode on import

Link:

  • #8165 Enable autolink matching when unlinked
  • 🆕 #8236 Merge adjacent LinkNodes with identical attributes

Eslint Plugin:

  • 🧹 #8227 Add flat configuration and full eslint 9+ support for @lexical/eslint-plugin

List:

  • 🆕 #8213 Create copies of ListNode/ListItemNode in split-like operations

React:

  • 🧹#8199 Remove deprecated ContextMenu, consolidate menu rendering with backward-compatible menuRenderFn

Table:

  • #8187 Use monolithic listener for SELECTION_CHANGE_COMMAND and deselection handler
  • #8193 Improve nested table selection by using monolithic pointer event handling
  • #8195 Prevent single-cell table selection after exiting table selection
  • #8200 Call $handleTableSelectionChangeCommand once instead of per-table
  • 🧹 #8215 Add test for mouse leaving browser window during table selection
  • ⚠️ #8210 hasFitNestedTables functionality moved to the playground
  • #8234 Handle table selections crossing into/out of nested tables

Utils:

  • 🆕 #8206 Add $insertNodeIntoLeaf with example usage in playground DateTimeNode

Misc:

Infrastructure

  • 🧹 #8239 Upgrade rollup packages and configure terser for ascii_only output

Playground:

  • #8186 Add fallback for dimensionless images to prevent collapse
  • 🧹 #8188 Remove legacy events mode
  • 🆕 #8183 Nested tables resize themselves with hasFitNestedTables: true
  • #8214 Use inline style for LayoutContainerNode import
  • #8228 Fix cursor position after EquationNode
  • #8224 make clear formatting work on multiple paragraphs

What's Changed

  • v0.41.0 by @etrepum in #8166
  • Update examples for v0.41.0 by @etrepum in #8171
  • [lexical] Chore: Fix minimatch CVE-2026-26996 in example projects by @thatmichael85 in #8169
  • Fix cross-spawn vulnerability (CVE-2024-21538) by removing child-process-promise by @thatmichael85 in #8177
  • [lexical] Security: Fix qs vulnerability (CVE-2025-15284) by @thatmichael85 in #8176
  • [lexical-markdown] Fix: enforce CommonMark flanking rules for trailing spaces by @Sa-Te in #8170
  • [lexical] Chore: Fix form-data CVE-2025-7783 in root lockfile by @thatmichael85 in #8174
  • [lexical] Security: Fix @isaacs/brace-expansion vulnerability (CVE-2026-25547) by @thatmichael85 in #8175
  • [lexical] Chore: Fix rollup CVE-2026-27606 across all lockfiles by @thatmichael85 in #8173
  • Fix rollup CVE-2026-27606 in example project lockfiles by @thatmichael85 in #8182
  • [lexical-link] Bug Fix: Enable autolink matching when it unlinked by @levensta in #8165
  • [lexical-playground] Fix: add fallback for dimensionless images to prevent collapse by @Sa-Te in #8186
  • [lexical-playground] Chore: Remove legacy-events mode by @levensta in #8188
  • [lexical] Chore: Change alias from type to interface for EditorThemeClasses by @levensta in #8190
  • [lexical-table] Refactor: use monolithic listener for table SELECTION_CHANGE_COMMAND and deselection handler by @randal-atticus in #8187
  • [lexical-table][lexical-playground] Feature: nested tables resize themselves if hasFitNestedTables: true by @randal-atticus in #8183
  • [lexical-markdown] Bug Fix: update backslash escape handling to align with CommonMark by @kimseongyu in #8192
  • [lexical-table] Bug Fix: Improve nested table selection by using monolithic pointer event handling by @randal-atticus in #8193
  • [lexical-code] Breaking Change: Extract Prism code highlighting to @lexical/code-prism (with internal module @lexical/code-core to avoid circular import) by @etrepum in #8198
  • [lexical-table] Bug Fix: Prevent single-cell table selection after exiting table selection by @randal-atticus in #8195
  • [lexical-react] Revert revert: Remove deprecated ContextMenu, consolidate menu rendering with backward-compatible menuRenderFn by @thatmichael85 in #8199
  • [lexical-table] Refactor: Call $handleTableSelectionChangeCommand once instead of per-table by @randal-atticus in #8200
  • [lexical-website] Bug Fix: Removed blog route from lexical.dev by @m-santanna in #8209
  • [lexical-playground] Fix: use inline style for LayoutContainerNode import by @WhyBusyy in #8214
  • [lexical-table] Chore: add test for mouse leaving browser window during table selection by @takenosuke-code in #8215
  • [lexical-utils][lexical-playground] Feature: Add $insertNodeIntoLeaf and insert deeply DateTimeNode by @levensta in #8206
  • [lexical] Bug Fix: respect CSS scroll-padding in scrollIntoViewIfNeeded by @takenosuke-code in #8218
  • [lexical] Bug Fix: When the editor starts with an empty list item, pressing ctrl+backspace (deleteWord) should replace the list with a paragraph by @Jynx2004 in #8220
  • [lexical][lexical-list][lexical-markdown] Feature: resetOnCopyNode configuration to NodeState and LexicalNode.resetOnCopyNodeFrom hook by @etrepum in #8221
  • [lexical] Feature: LexicalEditor RootListener and EditableListener can return unregister callbacks by @etrepum in #8219
  • [lexical-markdown][lexical-playground] Bug Fix: Convert tabs in TabNode at import by @lytion in #8211
  • [lexical] Fix: Consecutive Linebreak insertion resets selection format by @Jynx2004 in #8222
  • [lexical-table][lexical-playground] Breaking change: Move hasFitNestedTables logic to Playground plugin by @randal-atticus in #8210
  • [lexical-website] Fix: Correct the mistake in the argument in the example on the Updates page by @levensta in #8225
  • [lexical-list] Fix: create copies ListNode/ListItemNode in split-like operations by @levensta in...
Read more

v0.41.0

25 Feb 18:07

Choose a tag to compare

v0.41.0 is a monthly release with a huge number of fixes and features from a lot of new contributors. The most notable fixes are related to IME, non-ascii keyboard layouts, and markdown.

Breaking Changes

--lexical-indent-base-value CSS moved to root element #8132

The --lexical-indent-base-value CSS custom property is now only read from the root element of the editor, so any CSS or code to set this value must target that rather than an indented element in the document. This allows the indent to be computed while the document is being rendered without layout thrashing.

Highlights

Core

  • ⚠️ #8132 Breaking Change: Fix --lexical-indent-base-value CSS variable override
  • #8111 Prevent layout thrashing when setting element indent for no indent case
  • 🆕 #8115 Support legacy 'align' attribute in ParagraphNode importDOM
  • #8121 IME: Do not move anchor when inserting composition start char
  • #8142 IME: Fix history not recording composing character
  • #8148 IME: Do not apply format and style when moving to a different node in composition
  • #8154 IME: Fix selected text not properly deleted after IME input on Safari (macOS)
  • #8162 IME: Maintain format when multiple formatted text nodes are replaced with composition text
  • #8159 Support DOM selection in elements with slots
    Code
  • 🆕 #7918 Allow moving caret outside of code block
  • 🆕 #8155 Trigger keyboard shortcuts by physical key code with non-ascii keyboard layouts

Extension

  • 🆕 #8114 Implement DecoratorTextExtension applying format to DecoratorTextNode

Rich Text

  • 🆕 #8122 Support configuration of indentable nodes
  • #8152 Inherit format and style when inserting tab

Link

  • #8123 Prevent AutoLink from linking URLs inside code blocks without highlighting
  • #8127 Prevent AutoLinkNode from creating extra paragraphs
  • #8137 Add AutoLinkNode to AutoLinkExtension node dependencies
  • #8138 $toggleLink should remove the whole link when selection is collapsed
  • #8164 Prevent creation of nested LinkNode
  • #8158 Transform to move blocks outside of LinkNode
    List
  • 🆕 #8092 Preserve ordered list numbering when split by blocks or paragraphs
  • #8118 Remove empty parent node in nested list
  • 🆕 #8105 Add focus event option for the checklist extension

Table

  • 🆕 #8097 Implement "fit nested tables" for nested table pasting
  • 🆕 #8094 Support 'scope' attribute in HTML import for th tags
  • #8131 Preserve Background Color when pasting table rows inside table

Markdown

  • #8116 Fix nested fenced code blocks parsing and export
  • 🆕 #8140 Support Enter key after ``` to create code block
  • #8161 Prevent markdown shortcut link transformer from being too greedy

Playground

  • 🆕 #8063 Rearrange table columns
  • #8134 Increase toolbar z-index to prevent content overlap
  • #8149 Code block formatting in unintended adjacent lines

What's Changed

  • v0.40.0 by @etrepum in #8104
  • [lexical] Bug Fix: Prevent layout thrashing when setting element indent for no indent case by @InanBerkin in #8111
  • Update examples for v0.40.0 and pnpm by @etrepum in #8110
  • [lexical-table][lexical-playground] Feature: Implement "fit nested tables" for nested table pasting by @randal-atticus in #8097
  • [lexical] Chore: Stabilize playground collab WebKit E2E test waits by @screenfluent in #8113
  • Fix(table): Support 'scope' attribute in HTML import. by @Sa-Te in #8094
  • [lexical] Feature: Support legacy 'align' attribute in ParagraphNode importDOM by @Sa-Te in #8115
  • [lexical-list] Feature: Preserve ordered list numbering when split by blocks or paragraphs by @Sa-Te in #8092
  • [lexical-markdown] Bug Fix: Fix nested fenced code blocks parsing and export by @abdulalim110 in #8116
  • [lexical-playground] tests for ComponentPickerMenuPlugin by @umaranis in #8128
  • [lexical] Bug Fix: Remove empty parent node in nested list by @Senasiko in #8118
  • [lexical-extension][lexical-rich-text][lexical-react] Feature: Support configuration of indentable nodes by @levensta in #8122
  • [lexical-link] Bug Fix: Prevent AutoLink from linking URLs inside code blocks by @achaljhawar in #8123
  • [lexical-playground]: Rearrange table columns by @ivailop7 in #8063
  • [lexical-playground][lexical-link] Bug Fix: Prevent AutoLinkNode from creating extra paragraphs by @polyrainbow in #8127
  • [lexical-react] Annotate @deprecated to menuRenderFn with NodeContext… by @thatmichael85 in #8001
  • [lexical] Bug Fix: Do not move anchor when inserting composition start char by @kimseongyu in #8121
  • [lexical-table] Fix: Preserve Background Color when pasting table rows inside table. by @Sa-Te in #8131
  • [lexical-code] Bug Fix: Allow moving caret outside code block by @lytion in #7918
  • [Breaking Change][lexical] Bug Fix: Fix --lexical-indent-base-value CSS variable override by @achaljhawar in #8132
  • [lexical-playground] Fix: Increase toolbar z-index to prevent content overlap by @Sa-Te in #8134
  • [lexical-link] Bug Fix: Add AutoLinkNode to AutoLinkExtension node dependencies by @etrepum in #8137
  • [lexical-playground]: Clean up old Table Hover Actions by @ivailop7 in #8139
  • [lexical-website] Chore: Update supported browsers list to Safari 15+, Chrome 86+, Firefox 115+ by @etrepum in #8141
  • [lexical-link] Bug Fix: $toggleLink removes link when selection is collapsed by @Senasiko in #8138
  • [lexical-markdown] Feature: Support Enter key after ``` to create code block by @achaljhawar in #8140
  • [lexical-extension] Feature: Implement DecoratorTextExtension applying format to DecoratorTextNode by @levensta in #8114
  • docs: fix formatting and update browser support table by @IkyssOffc in #8144
  • [lexical-website] Chore: Add a website build step to Github Actions in CI by @etrepum in #8146
  • [lexical-history] Bug Fix: History not record composing character by @Senasiko in #8142
  • [lexical] Bug Fix: Do not apply format and style when moving to different node in composition by @kimseongyu in #8148
  • [lexical-playground] Bug Fix: Code block formatting in unintended adjacent lines by @achaljhawar in #8149
  • [lexical-rich-text] Bug Fix: Inherit format and style when inserting tab by @kimseongyu in #8152
  • [lexical-core] Bug fix: support dom selection for elements with slots by @fantactuka in #8159
  • [lexical] Bug Fix: Fix selected text not properly deleted after IME input on Safari (macOS) by @sKawashima in #8154
  • feat: add focus event option for the checklist extension by @rayterion in #8105
  • [lexical-markdown] Fix: Prevent markdown shortcut link transformer from being too greedy by @etrepum in #8161
  • [lexical] Bug Fix: Maintain format when replace multiple formatted text nodes with composition text by @kimseongyu in #8162
  • [tests] Chore: Update yaml-language-server in lexical-esm-astro-react integration fixture by @PikkaPikkachu in #8163
  • [lexical-markdown] Bug Fix: Prevent nesting links creation by @levensta in #8164
  • [lexical] Bug Fix: Move new paragraph outside inline element in insertParagraph by @achaljhawar in #8158
  • [lexical] Bug Fix: REDO_COMMAND not triggered with non-English keyboard layouts (Ctrl+Y / Ctrl+Shift+Z) by @kenclaron in #8155

New Contributors

Full Changelog: v0.40.0...v0.41.0

v0.40.0

02 Feb 17:34

Choose a tag to compare

v0.40.0 is a monthly release primarily focusing on bug fixes and infrastructure such as the move from npm to pnpm.

Some very notable changes include:

  • Some major fixes and refactoring to markdown parsing #8093 #8085
  • Several of the most common utilities were moved from @lexical/utils to lexical (mergeRegister, addClassNames, removeClassNames) #8106
  • A cache coherency bug in RootNode.getTextContent() was fixed #8099

Highlights

Monorepo:

Link:

  • #8070 Fix: Fix infinite transform loop in AutoLinkPlugin
  • #8078 Fix: Toggle links with nested children

List:

  • #8049 Fix: fix selection issue from list transform on linebreak
  • #8068 Fix: Treat whitespace-only list items as empty when pressing Enter

Markdown:

  • #8085 Fix: Fix incorrect format tag placement at link boundaries
  • #8093 Fix: Replace regex-based format matching

Core:

  • #8069 Fix: format removed on multi selection after replace
  • #8099 Fix: Refactor RootNode.__cachedText computation for coherency

Table:

  • #8076 Fix: Fix Ctrl+A to select all cells in table with merged cells
  • #8081 Fix: Fix inconsistent multi-cell selection in 2x2 tables
  • 🧹 #8088 Chore: Fix test for nested table pasting

Utils:

  • 🧹 #8106 Chore: Move functions mergeRegister, addClassNames, removeClassNames to lexical package

React:

  • #8062 Fix: Clear remote cursor immediately on collaborator refresh
  • #8065 Fix: Fix cursor disappearing in Firefox when dragging blocks
  • #8071 Chore: Expose onReposition prop on SelectionAlwaysOnDisplay

Playground:

  • 🆕 #8043 Feature: Color table resize handle
  • 🆕 #8042 Feature: Draggable block handle gliding effect
  • #8052 Fix: Draggable handle and dropdown CSS zoom fix
  • 🆕 #8057 Feature: New Table Hover Actions Plugin
  • 🆕 #8060 Feature: Column Sort for Basic Table
  • 🆕 #8066 Feature: Add button shows the component picker
  • #8087 Fix: Prevent code block line wrapping to keep line number

What's Changed

  • v0.39.0 by @etrepum in #8021
  • Chore: Add an ignore-previously-published arg to the publish action by @etrepum in #8023
  • Chore: Update examples for v0.39.0 by @etrepum in #8024
  • Agent documentation by @zurfyx in #8031
  • README tweaks by @zurfyx in #8033
  • npm -> pnpm by @zurfyx in #8035
  • Nightlies publish param by @zurfyx in #8045
  • Nightlies fix frozen lockfile by @zurfyx in #8048
  • [lexical-playground]: Color table resize handle by @ivailop7 in #8043
  • Use PNPM workspace feature for publish by @zurfyx in #8050
  • Override workspace with actual version on npm/ bundle by @zurfyx in #8051
  • [lexical-playground]: Draggable block handle gliding effect by @ivailop7 in #8042
  • Allow publish to run on detached head by @zurfyx in #8054
  • [lexical-list] Bug Fix: fix selection issue from list transform on linebreak by @dizsmek in #8049
  • [docs] Documentation Update: Fix incorrect and broken links in README by @h8f1z in #8055
  • [lexical-playground]: Draggable handle and dropdown CSS zoom fix by @ivailop7 in #8052
  • [lexical-playground]: New Table Hover Actions Plugin by @ivailop7 in #8057
  • [lexical-playground]: Column Sort for Basic Table by @ivailop7 in #8060
  • [lexical-react] Bug Fix: Clear remote cursor immediately on collaborator refresh by @aldoprogrammer in #8062
  • [lexical-playground] Add button shows the Component Picker by @ivailop7 in #8066
  • [lexical][@lexical/react] Bug Fix: Fix cursor disappearing in Firefox when dragging blocks by @aldoprogrammer in #8065
  • [lexical] Bug Fix: format removed on multi selection after replace by @kimseongyu in #8069
  • [lexical-list] Bug Fix: Treat whitespace-only list items as empty when pressing Enter by @mike-atticus in #8068
  • [lexical][@lexical/link] Bug Fix: Fix infinite transform loop in AutoLinkPlugin by @aldoprogrammer in #8070
  • [lexical][@lexical/table] Fix Ctrl+A to select all cells in table with merged cells #8074 by @aldoprogrammer in #8076
  • [lexical-react] Chore: Expose onReposition prop on SelectionAlwaysOnDisplay by @takuyakanbr in #8071
  • [lexical-link] Bug Fix: Toggle links with nested children by @patrick-atticus in #8078
  • [lexical-markdown] Bug Fix: Fix incorrect format tag placement at link boundaries by @kimseongyu in #8085
  • [lexical][@lexical/table] Bug Fix: Fix inconsistent multi-cell selection in 2x2 tables by @aldoprogrammer in #8081
  • [lexical-table] Chore: Fix test for nested table pasting by @randal-atticus in #8088
  • Fix(Playground): Prevent code block line wrapping to keep line number… by @Sa-Te in #8087
  • [lexical-markdown] Bug Fix: Replace regex-based format matching with … by @kimseongyu in #8093
  • [lexical] Bug Fix: Refactor RootNode.__cachedText computation for coherency by @etrepum in #8099
  • [lexical][lexical-utils] Chore: Use workspace:* for monorepo versions and fix some cyclic dependencies by @etrepum in #8106

New Contributors

Full Changelog: v0.39.0...v0.40.0

v0.39.0

10 Dec 20:17

Choose a tag to compare

v0.39.0 is a monthly release primarily focusing on bug fixes

Breaking Changes

JSON serialization for ElementNode only includes textFormat and textStyle when necessary #7971

Previously the derived properties textFormat and textStyle would always be serialized to JSON if not set to the default values. These should only be useful when the ElementNode does not currently have any TextNode children, to preserve formatting choices, and will be recomputed when reconciled. Now they are only reconciled when they are determined to be useful (in an ElementNode with no direct TextNode children that is not a root or shadow root).

Highlights

Code:

  • #7970 Fix: Scope highlight cache by editor

Core:

  • #7971 Fix: Only serialize ElementNode textFormat and textStyle when necessary
  • 🆕 #7964 Feature: Add commands for beforeinput, input, compositionstart/end events
  • #7978 Fix: $dfsCaretIterator should be able to stop at its last descendant

Selection:

  • #8003 Fix: Text styles are now applied to empty ElementNodes in a selection (typically the empty paragraphs contained in empty table cells)

Extension:

  • #7961 Fix: Defer node class references to potentially work around webpack issues

Table:

  • 🧪 #7983 Experiment: add config for opting in to nested tables (note that this does not fix their behavior)
  • #7986 Fix: Ensure colWidths has length equal to number of columns
  • #7998 Fix: Include first cell contents in partial backwards table selection

React:

  • #7987 Prevent typeahead menu from closing during IME composition

Collab:

  • #7990 Fix: Don't rewrite unchanged non-primitive property/state values to yjs in collab v2

Playground:

  • 🆕 #8002 Feature: Shadows when table is scrollable
  • #8015 Fix: Show draggable block target line when dragging images

What's Changed

  • v0.38.2 by @etrepum in #7962
  • [scripts] Allow export-froms in Flow files to be transformed for www build by @takuyakanbr in #7967
  • [examples] Chore: Update examples for v0.38.2 by @etrepum in #7963
  • [lexical-code] Bug fix: Add editor key in highlighted nodes cache by @takuyakanbr in #7970
  • [lexical] Feature: Only serialize ElementNode textFormat and textStyle when necessary by @etrepum in #7971
  • [lexical-extension][lexical-*] Bug Fix: Defer node class references to potentially work around webpack issues by @etrepum in #7961
  • [lexical] Chore: Update flow-bin (to 0.289.0) and LexicalLink Flow types by @takuyakanbr in #7973
  • [lexical] Feature: add commands for beforeinput, input, compositionstart/end events by @james-atticus in #7964
  • [lexical] Chore: Update flow-bin (to 0.290.0) and fix incompatible-variance issues by @takuyakanbr in #7975
  • [lexical] Bug fix: $dfsCaretIterator should be able to stop at its last descendant by @nigelgutzmann in #7978
  • [lexical-table] Feature: add config for opting in to nested tables by @james-atticus in #7983
  • [lexical-react] [lexical-playground] Bug Fix: Prevent typeahead menu from closing during IME composition (#7985) by @kykim00 in #7987
  • [lexical-table] Bug Fix: ensure colWidths has length equal to number of columns by @james-atticus in #7986
  • [lexical-react] [lexical-playground] Remove old ContextMenu, consolidate LexicalMenu render by @ivailop7 in #7984
  • [lexical-yjs] Bug fix: don't rewrite unchanged non-primitive property/state values to yjs in collab v2 by @james-atticus in #7990
  • [lexical-website] Documentation Update: Add @y/websocket-server package dependency by @mattcline in #7996
  • Revert "[lexical-react] [lexical-playground] Remove old ContextMenu, consolidate LexicalMenu render" by @ivailop7 in #7997
  • [lexical-website] Documentation Update: Add missing getDocFromMap fn to docs by @mattcline in #8000
  • [lexical-table] Bug Fix: include first cell contents in partial backwards table selection by @patrick-atticus in #7998
  • Doc nit by @zurfyx in #8010
  • [lexical-mark][flow][chore] Add flowfix me after flow 0.292.0 was deployed to www. This fixes the sync between github and www by @thatmichael85 in #8019
  • [lexical-playground]: Shadows when table is scrollable by @ivailop7 in #8002
  • [lexical-selection]: Fix applying styles for empty table cells by @ivailop7 in #8003
  • [lexical-playground] Bug Fix: Show draggable block target line when dragging images by @paigekim29 in #8015

New Contributors

Full Changelog: v0.38.2...v0.39.0

v0.38.2

31 Oct 00:49

Choose a tag to compare

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: v0.38.1...v0.38.2

v0.38.1

27 Oct 20:22

Choose a tag to compare

v0.38.1 is a 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

  • v0.37.0 by @etrepum in #7910
  • Update examples for v0.37.0 by @etrepum in #7911
  • [Documentation] Chore: Update bounty program link in CONTRIBUTING.md by @mustkem in #7915
  • [lexical-yjs] Fix: skip elements that were added and removed between snapshots by @james-atticus in #7922
  • [lexical-code] Bug Fix: Respect RTL when moving to line start/end in code blocks by @ashmod in #7921
  • [lexical-markdown] Fix: bugs in normalizeMarkdown by @GermanJablo in #7812
  • [lexical-playground] Bug Fix: Fix image caption overflow issue by @ritoban23 in #7920
  • [lexical-markdown] Bug Fix: Prevent Markdown links with empty string link text from being automatically removed by @adambolcsfoldi in #7923
  • [lexical-website] Chore: Update docusuarus and add contributing docs by @etrepum in #7931
  • [lexical-markdown] Bug Fix: Fix implicit checklist marker export regression by @etrepum in #7928
  • [lexical][lexical-list] Bug Fix: Apply static transform and $config $transform from all superclasses by @etrepum in #7926
  • [lexical-extension] Feature: Allow nodes config to be deferred for circular dependency reasons by @etrepum in #7930
  • [lexical-website] Documentation Update: change setText to setTextContent by @bbertold in #7932
  • [lexical-react] Bug Fix: Add getServerSnapshot for RSC compatibility by @nestarz in #7935
  • [lexical-link][lexical-code-shiki][examples] Feature: Implement mergeConfig for LinkExtension and flatten config for CodeHighlighterShikiExtension by @etrepum in #7936
  • [lexical-table] Chore: Lower table handler command priority by @patrick-atticus in #7933
  • [lexical] Bug Fix: retain selection during updates on unfocused editor by @fantactuka in #7941
  • [lexical-clipboard] Bug Fix: Log exceptions in clipboard paste handler by @niikkhilsharma in #7942
  • [lexical-link] Feature: Enable Selective Removal Within Linked Text by @normtronics in #7944
  • [lexical] Bug Fix: update block cursor if selection has changed by @fantactuka in #7947
  • [lexical-list] Bug Fix: fix pasting checklist from joplin by @antsgar in #7946
  • [examples] Chore: Remove #7859 workaround from svelte example by @etrepum in #7939

New Contributors

Full Changelog: v0.37.0...v0.38.1

v0.37.0

11 Oct 22:43

Choose a tag to compare

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:

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

  • v0.36.2 by @etrepum in #7894
  • Update examples for v0.36.2 by @etrepum in #7896
  • [examples] Feature: sveltekit ssr example by @etrepum in #7879
  • [lexical-react] Bug Fix: LexicalMenu guard against undefined option when list shrinks by @MRADULTRIPATHI in #7899
  • [lexical-yjs][lexical-react] Feature: initial implementation of collab v2 by @james-atticus in #7616
  • [lexical-list][lexical-markdown] Feature: Keep list marker for markdown round-trip by @lytion in #7892
  • [lexical-rich-text] Bug fix: up/down arrows for node selection by @fantactuka in #7902
  • [lexical][lexical-clipboard][lexical-playground] Feature: ImageNode caption support for exportDOM and importDOM by @Kepron in #7900
  • [lexical-yjs][lexical-react] Feature: commands for diffing two yjs snapshots in collab v2 by @james-atticus in #7903
  • [lexical][lexical-clipboard][lexical-html][lexical-selection] Feature: Add an internal ephemeral node concept by @etrepum in #7904
  • [lexical-playground] Bug Fix: Export ParagraphNode as div role="paragraph" when it contains block DOM by @etrepum in #7906
  • [lexical-react] Chore: make __shouldBootstrapUnsafe prop optional by @james-atticus in #7907
  • [lexical-yjs] Chore: fix imports of Yjs XML types by @james-atticus in #7908
  • [lexical-headless] Chore: Update to happy-dom v20 by @etrepum in #7909

New Contributors

Full Changelog: v0.36.2...v0.37.0

v0.36.2

01 Oct 14:27

Choose a tag to compare

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

  • v0.36.1 by @etrepum in #7871
  • [*] Bug Fix: devInvariant should warn in prod even if not in codes.json by @etrepum in #7870
  • [lexical-website] Chore: add example for how to bootstrap collab ydoc on the server by @james-atticus in #7830
  • [lexical-playground] Bug Fix: Table add-row button no longer hides horizontal scroll by @niikkhilsharma in #7847
  • Update examples for v0.36.1 by @etrepum in #7872
  • [lexical-headless] Bug Fix: Fix types for @lexical/headless/dom and simplify npmToWwwName workaround by @etrepum in #7873
  • [lexical-table] Bug Fix: Handle accessing table selection following table deletion by @patrick-atticus in #7864
  • [lexical-headless][lexical-html] Bug Fix: Fix entrypoint for @lexical/headless/dom and generalize $generateNodesFromDOM by @etrepum in #7859
  • [lexical-website] Chore: Update to docusaurus v3.9.1 by @etrepum in #7881
  • [lexical-clipboard] Preventing copying empty string by @niikkhilsharma in #7880
  • [lexical-react] Fix: ensure selection listeners cleaned up from original owner document by @james-atticus in #7843
  • [lexical-markdown] Bug Fix: Ensure First Match is Used in importTextMatchTransformer by @jkjk822 in #7890
  • [docs] Chore: Export DOMConversion* types so that they are in the docs by @etrepum in #7893
  • [lexical][lexical-playground] Feature: Improve focus management in Toolbar and adds SKIP_SELECTION_FOCUS_TAG by @KaiPrince in #7804

New Contributors

Full Changelog: v0.36.1...v0.36.2

v0.36.1

25 Sep 16:16

Choose a tag to compare

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

  • v0.35.0 by @etrepum in #7797
  • [lexical-website] Chore: Update docusaurus-plugin-typedoc by @etrepum in #7766
  • [examples] Chore: Update examples for v0.35.0 by @etrepum in #7799
  • [lexical-playground] DatetimeNode DOM updates by @ivailop7 in #7786
  • [lexical-list] Fix: updating list type to/from check type updates child DOM elements by @james-atticus in #7800
  • [lexical-react] Fix: Use explicit key attr in NodeContextMenuPlugin by @etrepum in #7803
  • [lexical-list] Fix: clear li checklist attributes when inserting nested list by @james-atticus in #7805
  • [*] Chore: Port scripts unit tests to vitest and fix test include match pattern by @etrepum in #7807
  • [lexical-website] Bug Fix: Replace broken algolia search with @easyops-cn/docusaurus-search-local by @etrepum in #7810
  • [lexical-markdown] Update Flow types to match TypeScript by @takuyakanbr in #7813
  • [lexical][lexical-selection][lexical-utils] Refactor: Consolidate ancestor lookup via findMatchingParent by @cnaples79 in #7814
  • [lexical] Chore: Improve error message when a node is registered from a foreign lexical module by @etrepum in #7821
  • [lexical-clipboard] Fix: copy correct selection when editor in different window/document by @james-atticus in #7822
  • [lexical-yjs][lexical-playground] Breaking change: remove clientID from collab context by @james-atticus in #7816
  • [lexical-react] Breaking change: enforce use of collab context provider by @james-atticus in #7818
  • [lexical-markdown] Refactor: Remove MarkdownShortcuts.ts Dependency on index.ts by @jkjk822 in #7832
  • [lexical-clipboard] Bug Fix: Update Lexical Clipboard with Empty Selection by @jkjk822 in #7835
  • [*] Bug Fix: Relocate internal eslint plugin to packages/lexical-eslint-plugin-internal by @etrepum in #7834
  • [lexical] Bug Fix: Fix cache coherency issue with RangeSelection#extract by @jkjk822 in #7836
  • [lexical-playground] Chore: remove InlineImageNode and InlineImagePlugun by @etrepum in #7839
  • [lexical][lexical-react][lexical-playground] Chore: Update from React 18 to React 19 by @etrepum in #7802
  • [lexical-react] Bug Fix: Add visibility margin to isTriggerVisibleInNearestScrollContainer to prevent popover from wrongfully closing by @dwrth in #7844
  • [lexical-react] Bug Fix: Include react-error-boundary and @floating-ui/react in WWW bundle by @etrepum in #7852
  • [lexical][lexical-extension][*] Feature: Lexical Extension by @etrepum in #7706
  • [lexical-extension][docs] Chore: Add @experimental to extension functions by @etrepum in #7853
  • [lexical] Chore: Change TabNode.setTextContent invariant to devInvariant by @amanharwara in #7855
  • [lexical-headless] Feature: @lexical/headless/dom module for easier SSR by @etrepum in #7833
  • [*] Bug Fix: npmToWwwName ensures lexical prefix by @etrepum in #7857
  • [lexical-headless] Bug Fix: Replace happy-dom with jsdom in www and map react-dom/client by @etrepum in #7858
  • [lexical] Bug Fix: account for Apple WebView in setManagedLineBreak by @elpnt in #7854
  • v0.36.0 by @etrepum in #7861
  • Make ref optional in ContentEditable flow by @zurfyx in #7866
  • [*] Bug Fix: Update examples and fix package.json for v0.36.0 (will need a patch release) by @etrepum in #7867
  • Expose LexicalCollaboration Context to flow by @zurfyx in #7868

New Contributors

Full Changelog: v0.35.0...v0.36.1

v0.35.0

05 Sep 01:57

Choose a tag to compare

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

  • v0.34.0 monthly release by @etrepum in #7746
  • Update examples for v0.34.0 by @etrepum in #7747
  • [lexical-playground][examples] Refactor: remove redundant fragment by @noritaka1166 in #7755
  • [lexical-react] Bug Fix: Add $config $transform inheritance to LexicalNestedComposer by @etrepum in #7757
  • [lexical-playground] Refactor: remove unnecessary await in e2e test by @noritaka1166 in #7759
  • [lexical-code-shiki] Refactor: remove unnecessary assertion by @noritaka1166 in #7762
  • [lexical-playground][lexical-react][lexical-table] Refactor: remove unnecessary assertion by @noritaka1166 in #7761
  • [lexical][lexical-code] Refactor: remove unnecessary assertion by @noritaka1166 in #7760
  • [lexical] Feature: allow ElementNode direction to be overridden by @james-atticus in #7727
  • [lexical-markdown] Formatted textmatch fix by @MarekKuncik in #7769
  • [Chore] Update flow suppressions to use error code by @SamChou19815 in #7770
  • [lexical-react] Fix the context menu event listener element by @ivailop7 in #7778
  • [lexical] Bug Fix: Correct exit direction from decorator nodes in RTL by @noamzaks in #7772
  • [lexical] Chore: Update flow-bin to 0.280.0 by @takuyakanbr in #7785
  • [lexical] Fix: insert into existing paragraph node if selection is on parent element by @james-atticus in #7794
  • [lexical-markdown] Bug Fix: Allow any characters in markdown link text by @lytion in #7735
  • [lexical-history] Add Missing Argument for DispatchCommand in Undo/Redo Docs Example by @lithika-damnod in #7795
  • [*] Chore: Replace jest with vitest for unit tests by @etrepum in #7796

New Contributors

Full Changelog: v0.34.0...v0.35.0