Skip to content

fix(list): keep lists through Word, HTML and Markdown import and export - #5160

Merged
zbeyens merged 3 commits into
nextfrom
fix/list-import-export
Oct 12, 2026
Merged

zbeyens merged 3 commits into
nextfrom
fix/list-import-export

Conversation

@natamox

@natamox natamox commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator
  • Auto release

Plan: docs/plans/2026-10-12-list-import-export-fixes.md

Why

A browser regression of the list refactor found lists losing their structure or content when a document goes through Word, HTML or Markdown, plus import and export warnings for losses that never happen. Each fix sits in the code that owns the behavior.

What changed

  • Word export converts table cells like the body, so lists, to-dos, code, equations, images and nested tables inside cells survive, and a listed heading or quote keeps its text, style and number.
  • The static list kit draws bullets as real lists, HTML import reads a list drawn inside a block back onto that block, and Markdown export keeps an item's later paragraphs inside the item.
  • Word import opens files whose notes are only Word's separators and reads checkbox bullet levels back as to-dos; list-start warns only for a start Word would change, and the import button shows one warning summary.

Scope

  • Leaves toolbar and block menu Outdent on a top-level list item as it is, for the list plan's owner.
  • Leaves the remaining Markdown-to-Word list warnings, a start other than 1 and a to-do inside a numbered list, as they are.
  • Word export does not warn when a list starts with a bullet whose level settings differ from a later numbered item's.

Where to start

  • Word export: render-document-file.ts and xml-builder.ts (table cells and listed headings), exportDocx.tsx (list warnings) and docx-document.ts (the Word level reader that the warnings and the writer share).
  • Word import: importDocx.ts and readDocxNumbering.ts.
  • HTML and Markdown: BaseListPlugin.ts, listToMdastTree.ts and convertNodesSerialize.ts.
  • Registry UI: block-list-static.tsx, list-static.tsx and import-toolbar-button.tsx.
  • Generated, skim only: apps/www/public/r/**, apps/www/src/__registry__/** and the registry changelog JSON.

Blast Radius

Touches DOCX export and import, HTML list import, Markdown list export and the copied static list kit. Numbered and to-do output stays byte-identical in static HTML and Word; bulleted quotes and code blocks now draw their bullet inside the block, as numbered ones already do.

Verification

  • List, Markdown and DOCX specs pass in platejs and www; each fix has a test that failed first, and mutation runs revert each fix.
  • The list regression suite passes every case this PR fixes in Chromium, twice.
  • LibreOffice opens the exported Word file with bullets, numbered headings and cell content in place.
  • CI fails only where next fails at 6fa1169c5e: the same check steps, failing tests and browser cases.

Word export lost bullets, numbered headings and anything but plain
paragraphs inside table cells, and Word import refused files whose
footnote parts hold only Word's separators. Table cells now convert
through the same path as the body, and the registry static kit draws
bullets as real lists, so Word and HTML keep them. A listed heading or
quote keeps its text, style and number in Word.

Import opens files whose notes are only separators or an empty
continuation notice, and reads checkbox bullet levels back as to-dos.
HTML import reads a list drawn inside its block back onto that block,
Markdown export keeps an item's later paragraphs inside it, list-start
warns only for a start Word would show differently, and the import
button shows one warning summary.
@natamox
natamox requested a review from a team October 12, 2026 10:10
@codesandbox

codesandbox Bot commented Oct 12, 2026

Copy link
Copy Markdown

Review or Edit in CodeSandbox

Open the branch in Web Editor • VS Code • Insiders

Open Preview

@changeset-bot

changeset-bot Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: bffa6f5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 1 package
Name Type
platejs Major

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Word export's start warning parsed listLevels through its own guard. It now
reads a level's start through the writer's toWordLevelRules, so the warning
and the Word writer cannot disagree. The Markdown list builder opens a nested
list through one openNestedList helper instead of two copies, and the
continuation check calls getListIndent. The plan and its decision log record
the babysit pass.
…ort plan

CI on both pushed heads fails only where next fails at 6fa1169, apart from
one heavy test per run that times out on the runner and passes locally well
under its limit. The plan and its decision log now say so for the second head.
@zbeyens
zbeyens merged commit ca301fa into next Oct 12, 2026
9 of 16 checks passed
@zbeyens
zbeyens deleted the fix/list-import-export branch October 12, 2026 22:45
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