Skip to content

feat: extend table supported attributes#7713

Open
alexvcasillas wants to merge 4 commits intomainfrom
feat/extend-table-supported-attributes
Open

feat: extend table supported attributes#7713
alexvcasillas wants to merge 4 commits intomainfrom
feat/extend-table-supported-attributes

Conversation

@alexvcasillas
Copy link
Copy Markdown
Contributor

Changes Overview

Extends the tableCell and tableHeader node schemas in @tiptap/extension-table with 14 new attributes to support cell-level styling: background, verticalAlign, and all 12 border properties
(borderTopWidth, borderTopStyle, borderTopColor, borderBottomWidth, borderBottomStyle, borderBottomColor, borderLeftWidth, borderLeftStyle, borderLeftColor, borderRightWidth,
borderRightStyle, borderRightColor).

Implementation Approach

Following the existing createAlignAttribute() factory pattern, three new shared utility factories were created:

  • createBorderAttributes() — Returns all 12 border attribute definitions. Each parses from the element's computed inline style (e.g. element.style.borderTopWidth) and renders back as individual inline
    style properties.
  • createBackgroundAttribute() — Parses background-color from inline styles and renders as background-color: <value>.
  • createVerticalAlignAttribute() — Parses vertical-align from inline styles, normalizes to top | middle | bottom (rejects invalid values), and renders as vertical-align: <value>.

Both tableCell and tableHeader spread these factories into their addAttributes() alongside the existing colspan, rowspan, colwidth, and align attributes. All new attributes default to null and
are enabled by default — no configuration needed.

Testing Done

79 tests across 8 test files (72 new, 7 existing):

  • tableCellAttributes.spec.ts (21 tests) — Full integration tests for <td>: parse, render, default null, JSON round-trip, and coexistence with existing attrs for background, verticalAlign, and all
    borders.
  • tableHeaderAttributes.spec.ts (21 tests) — Same coverage for <th>.
  • utilities/create-border-attributes.spec.ts (18 tests) — Unit tests for the factory: creates 12 attrs, correct defaults, parse/render for width (numeric), style (string), and color (string) on all
    sides.
  • utilities/create-background-attribute.spec.ts (7 tests) — Unit tests: default, parse hex/rgb/empty, render value/null/undefined.
  • utilities/create-vertical-align-attribute.spec.ts (10 tests) — Unit tests: default, parse all valid values/invalid/empty, render all values/null/undefined.

Verification Steps

  1. cd oss && pnpm vitest run packages/extension-table — all 79 tests pass
  2. Run eslint on changed files — no errors
  3. Create an editor with TableKit, call editor.commands.setContent(json) with a JSON doc containing tableCell nodes that have borderTopWidth: 1, borderTopStyle: "solid", background: "#ECF0E9" — verify
    the <td> elements render with the corresponding inline styles
  4. Call editor.getJSON() — verify the border/background/verticalAlign attributes round-trip correctly

Additional Notes

These attributes match what the Tiptap Convert DOCX import API returns on tableCell nodes (borderTopWidth, borderTopStyle, borderTopColor, background, verticalAlign, etc.). Previously ProseMirror
silently dropped these attrs during setContent because the schema didn't define them. With this change, DOCX table borders and cell styling are preserved end-to-end.

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

N/A — Part of the experimental CSS export style mapping feature (feat/experimental-css-export-style-mapping).

@alexvcasillas alexvcasillas self-assigned this Apr 6, 2026
@alexvcasillas alexvcasillas added the Open Source The issue or pull reuqest is related to the open source packages of Tiptap. label Apr 6, 2026
Copilot AI review requested due to automatic review settings April 6, 2026 12:59
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 6, 2026

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit eaccb2f
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/69d3c5e76c7b5c0008a1c838
😎 Deploy Preview https://deploy-preview-7713--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.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

🦋 Changeset detected

Latest commit: eaccb2f

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

@alexvcasillas
Copy link
Copy Markdown
Contributor Author

@bdbch I think the changeset bot went crazy because it says it's a mayor change on the comment but the changeset is actually a minor bump 🤔

Copy link
Copy Markdown
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

Extends @tiptap/extension-table’s tableCell and tableHeader node schemas to preserve cell-level styling (background, vertical alignment, and per-side border width/style/color) through HTML parsing and JSON round-trips.

Changes:

  • Added shared attribute factories for background color, vertical-align, and 12 border properties.
  • Registered the new attributes on TableCell and TableHeader.
  • Added Vitest coverage (unit tests for factories + integration tests for <td>/<th>) and a changeset.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/extension-table/src/utilities/create-vertical-align-attribute.ts Adds a vertical-align attribute factory with value normalization.
packages/extension-table/src/utilities/create-border-attributes.ts Adds a border attribute factory generating 12 per-side border attrs.
packages/extension-table/src/utilities/create-background-attribute.ts Adds a background-color attribute factory.
packages/extension-table/src/header/table-header.ts Registers new styling attributes on tableHeader.
packages/extension-table/src/cell/table-cell.ts Registers new styling attributes on tableCell.
packages/extension-table/tests/utilities/create-vertical-align-attribute.spec.ts Unit tests for vertical-align attribute parsing/rendering.
packages/extension-table/tests/utilities/create-border-attributes.spec.ts Unit tests for border attribute generation and parse/render behavior.
packages/extension-table/tests/utilities/create-background-attribute.spec.ts Unit tests for background attribute parsing/rendering.
packages/extension-table/tests/tableHeaderAttributes.spec.ts Integration tests ensuring <th> attrs parse/render/round-trip.
packages/extension-table/tests/tableCellAttributes.spec.ts Integration tests ensuring <td> attrs parse/render/round-trip.
.zed/settings.json Adds Zed editor settings (currently invalid JSON due to trailing commas).
.changeset/shy-queens-itch.md Declares a minor bump for the new user-facing table cell/header attributes.

Copy link
Copy Markdown
Member

@bdbch bdbch left a comment

Choose a reason for hiding this comment

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

Nice direction overall, but I think there are still a couple of preservation issues in the HTML path and one stray editor file in the PR.

*
* @param value - A CSS length string (e.g. "1px", "2")
* @return The numeric pixel value, or null if unparseable
*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This feels a bit too lossy for imported HTML. parseFloat() drops the original unit, and then renderHTML() always writes back px, so something like 0.5rem, 1em, or thin either changes meaning or gets dropped. If the goal here is preserving cell styling end to end, I think width probably needs to keep the original CSS token instead of normalizing everything into a number.

}
return { style: `border-${cssSide}-style: ${attributes[styleKey]}` }
},
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this has the same round-trip problem the background helper already avoids. Reading color from element.style will usually normalize #000000 into rgb(0, 0, 0), so HTML import/export is still lossy here. I'd probably parse the raw style attribute first, same as createBackgroundAttribute(), and only fall back to the CSSOM value if needed.

@@ -0,0 +1,23 @@
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like this is just a local editor config file. Can we drop it from the PR? It doesn't seem related to the feature and it'll just add noise/churn for everyone else.

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

Labels

Open Source The issue or pull reuqest is related to the open source packages of Tiptap.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants