Skip to content

feat(extension-table): add markdown table column alignment support#7610

Open
weilinzung wants to merge 9 commits intoueberdosis:mainfrom
weilinzung:table-alignments
Open

feat(extension-table): add markdown table column alignment support#7610
weilinzung wants to merge 9 commits intoueberdosis:mainfrom
weilinzung:table-alignments

Conversation

@weilinzung
Copy link
Contributor

@weilinzung weilinzung commented Mar 16, 2026

Changes Overview

The table extension was not handling Markdown column alignment markers. This adds full parse and serialize support for left (:----), right (----:), and center (:----:) alignment on tableHeader and tableCell nodes.

Implementation Approach

  • Added an align attribute to TableCell and TableHeader, parsed from style="text-align: ..." / legacy align HTML attribute and rendered back to inline style
  • Updated parseMarkdown in Table to read token.align (the column alignment array marked provides) and pass it as { align } attrs when creating header/body cells
  • Updated renderTableToMarkdown to emit alignment markers in the separator row based on per-column align attrs
  • Extracted shared utilities into packages/extension-table/src/utilities/parseAlign.ts:
    • TableCellAlign enum (Left, Right, Center)
    • normalizeTableCellAlign(value) — validates unknown input
    • normalizeTableCellAlignFromAttributes(attrs) — typed extraction from node attrs objects
    • parseAlign(element) — parses alignment from an HTML element
    • createAlignAttribute() — shared Tiptap Attribute config for both cell and header

Before

Screenshot 2026-03-16 at 10 47 09 AM

After

Screenshot 2026-03-16 at 10 48 49 AM

Testing Done

Verification Steps

  1. Start the demo app: pnpm dev
  2. Open http://localhost:3000/src/Markdown/Parse/React/
  3. Click Parse Markdown — the table should render with left, center, and right aligned columns
  4. Run the unit test: pnpm vitest run packages/extension-table/__tests__/tableMarkdown.spec.ts

Additional Notes

Alignment is stored per-cell as a schema attribute (align: 'left' | 'right' | 'center' | null). During serialization, alignment is resolved per column by scanning all rows and using the first non-null value found.

Checklist

  • I have created a changeset for this PR if necessary.
  • My changes do not break the library.
  • I have added tests where applicable.
  • I have followed the project guidelines.
  • I have fixed any lint issues.

Related Issues

Fixes #7502

Copilot AI review requested due to automatic review settings March 16, 2026 14:56
@changeset-bot
Copy link

changeset-bot bot commented Mar 16, 2026

🦋 Changeset detected

Latest commit: fad545f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 72 packages
Name Type
@tiptap/extension-table Major
@tiptap/extension-collaboration-caret Major
@tiptap/extension-table-cell Major
@tiptap/extension-table-header Major
@tiptap/extension-table-row Major
@tiptap/core Major
@tiptap/extension-audio Major
@tiptap/extension-blockquote Major
@tiptap/extension-bold Major
@tiptap/extension-bubble-menu Major
@tiptap/extension-bullet-list Major
@tiptap/extension-code-block-lowlight Major
@tiptap/extension-code-block Major
@tiptap/extension-code Major
@tiptap/extension-collaboration Major
@tiptap/extension-color Major
@tiptap/extension-details Major
@tiptap/extension-document Major
@tiptap/extension-drag-handle-react Major
@tiptap/extension-drag-handle-vue-2 Major
@tiptap/extension-drag-handle-vue-3 Major
@tiptap/extension-drag-handle Major
@tiptap/extension-emoji Major
@tiptap/extension-file-handler Major
@tiptap/extension-floating-menu Major
@tiptap/extension-font-family Major
@tiptap/extension-hard-break Major
@tiptap/extension-heading Major
@tiptap/extension-highlight Major
@tiptap/extension-horizontal-rule Major
@tiptap/extension-image Major
@tiptap/extension-invisible-characters Major
@tiptap/extension-italic Major
@tiptap/extension-link Major
@tiptap/extension-list Major
@tiptap/extension-mathematics Major
@tiptap/extension-mention Major
@tiptap/extension-node-range Major
@tiptap/extension-ordered-list Major
@tiptap/extension-paragraph Major
@tiptap/extension-strike Major
@tiptap/extension-subscript Major
@tiptap/extension-superscript Major
@tiptap/extension-table-of-contents Major
@tiptap/extension-text-align Major
@tiptap/extension-text-style Major
@tiptap/extension-text Major
@tiptap/extension-twitch Major
@tiptap/extension-typography Major
@tiptap/extension-underline Major
@tiptap/extension-unique-id Major
@tiptap/extension-youtube Major
@tiptap/extensions Major
@tiptap/html Major
@tiptap/markdown Major
@tiptap/pm Major
@tiptap/react Major
@tiptap/starter-kit Major
@tiptap/static-renderer Major
@tiptap/suggestion Major
@tiptap/vue-2 Major
@tiptap/vue-3 Major
@tiptap/extension-character-count Major
@tiptap/extension-dropcursor Major
@tiptap/extension-focus Major
@tiptap/extension-gapcursor Major
@tiptap/extension-history Major
@tiptap/extension-list-item Major
@tiptap/extension-list-keymap Major
@tiptap/extension-placeholder Major
@tiptap/extension-task-item Major
@tiptap/extension-task-list Major

Not sure what this means? Click here to learn what changesets are.

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

@netlify
Copy link

netlify bot commented Mar 16, 2026

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit fad545f
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/69b8aca1a3cfe00008e5b0d8
😎 Deploy Preview https://deploy-preview-7610--tiptap-embed.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds end-to-end table column alignment support to @tiptap/extension-table, including parsing alignment from Markdown/HTML and serializing it back to Markdown/HTML.

Changes:

  • Introduces a shared align attribute for TableCell and TableHeader, with HTML parsing/rendering via text-align.
  • Extends Markdown table parsing/serialization to roundtrip column alignment markers (:---, ---:, :---:).
  • Adds coverage via a Vitest spec and updates the Markdown parsing demo + changeset.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/extension-table/src/utilities/parseAlign.ts New utilities for normalizing/parsing alignment and generating a reusable attribute config.
packages/extension-table/src/table/utilities/markdown.ts Emits Markdown alignment markers in the separator row based on cell/header align attrs.
packages/extension-table/src/table/table.ts Reads token.align / per-cell align info from Markdown tokens and stores align on created cells.
packages/extension-table/src/header/table-header.ts Adds align attribute to table header nodes.
packages/extension-table/src/cell/table-cell.ts Adds align attribute to table cell nodes.
packages/extension-table/tests/tableMarkdown.spec.ts New test ensuring parse + serialize roundtrip for left/right/center alignment.
demos/src/Markdown/Parse/React/index.jsx Updates demo markdown table to showcase alignment markers/columns; removes unused React import and tweaks TableKit config.
.changeset/table-cell-alignment.md Declares a minor bump for the new user-facing Markdown/HTML alignment support.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 16, 2026

Open in StackBlitz

@tiptap/core

npm i https://pkg.pr.new/@tiptap/core@7610

@tiptap/extension-audio

npm i https://pkg.pr.new/@tiptap/extension-audio@7610

@tiptap/extension-blockquote

npm i https://pkg.pr.new/@tiptap/extension-blockquote@7610

@tiptap/extension-bold

npm i https://pkg.pr.new/@tiptap/extension-bold@7610

@tiptap/extension-bullet-list

npm i https://pkg.pr.new/@tiptap/extension-bullet-list@7610

@tiptap/extension-bubble-menu

npm i https://pkg.pr.new/@tiptap/extension-bubble-menu@7610

@tiptap/extension-code

npm i https://pkg.pr.new/@tiptap/extension-code@7610

@tiptap/extension-code-block

npm i https://pkg.pr.new/@tiptap/extension-code-block@7610

@tiptap/extension-collaboration

npm i https://pkg.pr.new/@tiptap/extension-collaboration@7610

@tiptap/extension-code-block-lowlight

npm i https://pkg.pr.new/@tiptap/extension-code-block-lowlight@7610

@tiptap/extension-collaboration-caret

npm i https://pkg.pr.new/@tiptap/extension-collaboration-caret@7610

@tiptap/extension-color

npm i https://pkg.pr.new/@tiptap/extension-color@7610

@tiptap/extension-details

npm i https://pkg.pr.new/@tiptap/extension-details@7610

@tiptap/extension-document

npm i https://pkg.pr.new/@tiptap/extension-document@7610

@tiptap/extension-drag-handle

npm i https://pkg.pr.new/@tiptap/extension-drag-handle@7610

@tiptap/extension-drag-handle-react

npm i https://pkg.pr.new/@tiptap/extension-drag-handle-react@7610

@tiptap/extension-drag-handle-vue-2

npm i https://pkg.pr.new/@tiptap/extension-drag-handle-vue-2@7610

@tiptap/extension-drag-handle-vue-3

npm i https://pkg.pr.new/@tiptap/extension-drag-handle-vue-3@7610

@tiptap/extension-emoji

npm i https://pkg.pr.new/@tiptap/extension-emoji@7610

@tiptap/extension-file-handler

npm i https://pkg.pr.new/@tiptap/extension-file-handler@7610

@tiptap/extension-floating-menu

npm i https://pkg.pr.new/@tiptap/extension-floating-menu@7610

@tiptap/extension-hard-break

npm i https://pkg.pr.new/@tiptap/extension-hard-break@7610

@tiptap/extension-font-family

npm i https://pkg.pr.new/@tiptap/extension-font-family@7610

@tiptap/extension-heading

npm i https://pkg.pr.new/@tiptap/extension-heading@7610

@tiptap/extension-highlight

npm i https://pkg.pr.new/@tiptap/extension-highlight@7610

@tiptap/extension-horizontal-rule

npm i https://pkg.pr.new/@tiptap/extension-horizontal-rule@7610

@tiptap/extension-image

npm i https://pkg.pr.new/@tiptap/extension-image@7610

@tiptap/extension-italic

npm i https://pkg.pr.new/@tiptap/extension-italic@7610

@tiptap/extension-invisible-characters

npm i https://pkg.pr.new/@tiptap/extension-invisible-characters@7610

@tiptap/extension-link

npm i https://pkg.pr.new/@tiptap/extension-link@7610

@tiptap/extension-mathematics

npm i https://pkg.pr.new/@tiptap/extension-mathematics@7610

@tiptap/extension-list

npm i https://pkg.pr.new/@tiptap/extension-list@7610

@tiptap/extension-mention

npm i https://pkg.pr.new/@tiptap/extension-mention@7610

@tiptap/extension-node-range

npm i https://pkg.pr.new/@tiptap/extension-node-range@7610

@tiptap/extension-paragraph

npm i https://pkg.pr.new/@tiptap/extension-paragraph@7610

@tiptap/extension-ordered-list

npm i https://pkg.pr.new/@tiptap/extension-ordered-list@7610

@tiptap/extension-subscript

npm i https://pkg.pr.new/@tiptap/extension-subscript@7610

@tiptap/extension-strike

npm i https://pkg.pr.new/@tiptap/extension-strike@7610

@tiptap/extension-superscript

npm i https://pkg.pr.new/@tiptap/extension-superscript@7610

@tiptap/extension-table-of-contents

npm i https://pkg.pr.new/@tiptap/extension-table-of-contents@7610

@tiptap/extension-table

npm i https://pkg.pr.new/@tiptap/extension-table@7610

@tiptap/extension-text

npm i https://pkg.pr.new/@tiptap/extension-text@7610

@tiptap/extension-text-align

npm i https://pkg.pr.new/@tiptap/extension-text-align@7610

@tiptap/extension-text-style

npm i https://pkg.pr.new/@tiptap/extension-text-style@7610

@tiptap/extension-twitch

npm i https://pkg.pr.new/@tiptap/extension-twitch@7610

@tiptap/extension-typography

npm i https://pkg.pr.new/@tiptap/extension-typography@7610

@tiptap/extension-underline

npm i https://pkg.pr.new/@tiptap/extension-underline@7610

@tiptap/extension-youtube

npm i https://pkg.pr.new/@tiptap/extension-youtube@7610

@tiptap/extensions

npm i https://pkg.pr.new/@tiptap/extensions@7610

@tiptap/extension-unique-id

npm i https://pkg.pr.new/@tiptap/extension-unique-id@7610

@tiptap/html

npm i https://pkg.pr.new/@tiptap/html@7610

@tiptap/markdown

npm i https://pkg.pr.new/@tiptap/markdown@7610

@tiptap/pm

npm i https://pkg.pr.new/@tiptap/pm@7610

@tiptap/starter-kit

npm i https://pkg.pr.new/@tiptap/starter-kit@7610

@tiptap/react

npm i https://pkg.pr.new/@tiptap/react@7610

@tiptap/static-renderer

npm i https://pkg.pr.new/@tiptap/static-renderer@7610

@tiptap/suggestion

npm i https://pkg.pr.new/@tiptap/suggestion@7610

@tiptap/vue-2

npm i https://pkg.pr.new/@tiptap/vue-2@7610

@tiptap/extension-character-count

npm i https://pkg.pr.new/@tiptap/extension-character-count@7610

@tiptap/vue-3

npm i https://pkg.pr.new/@tiptap/vue-3@7610

@tiptap/extension-dropcursor

npm i https://pkg.pr.new/@tiptap/extension-dropcursor@7610

@tiptap/extension-focus

npm i https://pkg.pr.new/@tiptap/extension-focus@7610

@tiptap/extension-gapcursor

npm i https://pkg.pr.new/@tiptap/extension-gapcursor@7610

@tiptap/extension-history

npm i https://pkg.pr.new/@tiptap/extension-history@7610

@tiptap/extension-list-item

npm i https://pkg.pr.new/@tiptap/extension-list-item@7610

@tiptap/extension-placeholder

npm i https://pkg.pr.new/@tiptap/extension-placeholder@7610

@tiptap/extension-list-keymap

npm i https://pkg.pr.new/@tiptap/extension-list-keymap@7610

@tiptap/extension-table-cell

npm i https://pkg.pr.new/@tiptap/extension-table-cell@7610

@tiptap/extension-table-header

npm i https://pkg.pr.new/@tiptap/extension-table-header@7610

@tiptap/extension-table-row

npm i https://pkg.pr.new/@tiptap/extension-table-row@7610

@tiptap/extension-task-item

npm i https://pkg.pr.new/@tiptap/extension-task-item@7610

@tiptap/extension-task-list

npm i https://pkg.pr.new/@tiptap/extension-task-list@7610

commit: 3dc0bfe

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.

[Markdown]: markdown table alignment not working

2 participants