Skip to content

[richtext-lexical] Strikethrough/inline format carries into a manually-typed checklist ([x]) on the next line #18639

Open

Description

@riancintiyo

Describe the Bug

An inline format (strikethrough, and similarly any text format) applied to a line is carried into the next line's manually-typed checklist item ([x] markdown shortcut), even after the format has been toggled off. Inserting the checklist through the / slash menu does not have this problem.

Environment:

  • payload: 3.84.1
  • @payloadcms/richtext-lexical: 3.84.1
  • bundled lexical / @lexical/markdown: 0.41.0
  • BuildChromium (editor in dark theme, default features + FixedToolbarFeature)

Link to the code that reproduces this issue

https://github.com/riancintiyo/payload-strikethrough-repro.git

Reproduction Steps

Steps to reproduce

  1. In a rich-text field, create strikethrough text using the markdown shortcut: strike.
  2. Press Enter to start a new line.
  3. Type a checklist manually with markdown: [x] Some task (space after ] triggers the checklist transform).

Actual: Some task is rendered struck through.
Expected: Some task is normal text.

Variants (help narrow it down)

  • strike + Enter + / menu → Check box: ✅ not affected (expected, clean).
  • Select text → apply strikethrough from the toolbar → Enter → toggle strikethrough off → type [x] Some task: ❌ still struck.
  • So the difference is newline + manual [] checklist conversion vs. the / command. Toggling the format off does not help.

Root cause analysis

  1. On Enter, Lexical copies the current selection's inline format onto the new paragraph — ParagraphNode.insertNewAfter (lexical@0.41.0, Lexical.dev.mjs:10006):
    newElement.setTextFormat(rangeSelection.format); // block.__textFormat = strikethrough
    A block's textFormat re-derives the selection format (Lexical.dev.mjs:7592), so the new line is struck at the block level.
  2. Toggling the toolbar off on a collapsed caret only calls RangeSelection.toggleFormat() (:6502) — it flips selection.format but never clears the paragraph's __textFormat, so the strike returns on the next keystroke.
  3. Payload's checklist markdown transformer re-parents the line's text nodes into a ListItemNode without resetting the format — @payloadcms/richtext-lexical/dist/features/lists/shared/markdown.js:27 (listReplace → listItem.append(...children)).
  4. The / menu path fires INSERT_CHECK_LIST_COMMAND (fresh ListNode/ListItemNode with __textFormat = 0), which is why it's clean.
    Suggested fix
    In the checklist markdown transformer (listReplace), clear the inline format of the appended children (e.g. children.forEach(n => $isTextNode(n) && n.setFormat(0))), or clear the new block's textFormat right after insertNewAfter. Either keeps the fix scoped to the markdown-conversion path while leaving intentional Bold/Italic carry-over intact.
    Notes
  • Likely also affects ordered/unordered lists and any element transformer on a freshly-created line, since the same listReplace path is shared.
  • Possibly also reportable upstream to facebook/lexical (block-textFormat persistence across a format toggle), but the checklist behavior is reproducible from Payload's markdown transformer alone.

Which area(s) are affected?

plugin: richtext-lexical

Environment Info

Binaries:
  Node: 22.14.0
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  payload: 3.84.1
  next: 16.2.4
  @payloadcms/db-vercel-postgres: 3.84.1
  @payloadcms/drizzle: 3.84.1
  @payloadcms/graphql: 3.84.1
  @payloadcms/next/utilities: 3.84.1
  @payloadcms/plugin-cloud-storage: 3.84.1
  @payloadcms/richtext-lexical: 3.84.1
  @payloadcms/storage-s3: 3.84.1
  @payloadcms/translations: 3.84.1
  @payloadcms/ui/shared: 3.84.1
  react: 19.2.4
  react-dom: 19.2.4
Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Home
  Available memory (MB): 16152
  Available CPU cores: 8

Activity

  1. added
    status: needs-triagePossible bug which hasn't been reproduced yet
    validate-reproductionAuto-added tag on create to tell bot to check recreation URL, removed after check.
    on Oct 9, 2026
  2. added and removed
    validate-reproductionAuto-added tag on create to tell bot to check recreation URL, removed after check.
    on Oct 9, 2026
  3. BhavishTrehan77 commented on Oct 10, 2026

    @BhavishTrehan77

    Hi maintainers! I'd like to contribute to this issue.

    I'm comfortable with JavaScript/TypeScript, React, and Node.js, and I'm interested in investigating the Lexical rich-text formatting behavior described here.

    Would you be open to a community contribution for this issue? I'd be happy to investigate the reproduction, verify the behavior against the existing tests, and propose a focused fix with regression coverage if the issue is confirmed.

    I'll wait for your guidance before starting implementation. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions