Skip to content

Feat/extend paragraph supported attributes#7715

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

Feat/extend paragraph supported attributes#7715
alexvcasillas wants to merge 4 commits intomainfrom
feat/extend-paragraph-supported-attributes

Conversation

@alexvcasillas
Copy link
Copy Markdown
Contributor

@alexvcasillas alexvcasillas commented Apr 6, 2026

Changes Overview

Adds spacing and indentation attributes to the @tiptap/extension-paragraph and @tiptap/extension-heading extensions: spacingBefore, spacingAfter, lineHeight, indent, and firstLineIndent. These attributes match what the Tiptap Convert DOCX import API returns on paragraph and heading nodes, which were previously dropped by ProseMirror during setContent because the schemas didn't define them.

Implementation Approach

Following the factory pattern established in the table extension (createAlignAttribute, createBorderAttributes), a shared createSpacingAttributes() factory function was created that returns all 5 attribute definitions. Each attribute:

  • Defaults to null
  • Parses from the element's inline style (margin-top, margin-bottom, line-height, padding-left, text-indent)
  • Renders back as the corresponding inline style

Since extension-paragraph and extension-heading are separate packages with no cross-dependency, the factory is duplicated in each package's src/utilities/ directory.

Testing Done

54 new tests across 3 test files:

  • extension-paragraph/__tests__/utilities/create-spacing-attributes.spec.ts (22 tests) — Unit tests for the factory: all 5 attributes created with correct defaults, parse from inline styles, render to inline styles, null handling
  • extension-paragraph/__tests__/paragraphAttributes.spec.ts (16 tests) — Integration tests on <p>: parse, render, default null, and JSON round-trip for all 5 attributes
  • extension-heading/__tests__/headingAttributes.spec.ts (16 tests) — Integration tests on <h1><h6>: parse, render, default null, JSON round-trip, coexistence with level attribute

Updated 9 existing test files to include the new null-default attributes in expected JSON shapes (createNodeFromContent, generateJSON, unmounted, taskItem, inlineMath, trailing-node, generateHTML, server-with-jsdom).

Full test suite: 825 tests passing across 81 test files.

Verification Steps

  1. cd oss && pnpm run test:unit — all 825 tests pass
  2. Run eslint on changed files — no errors
  3. Create an editor with Paragraph extension, call editor.commands.setContent({ type: 'doc', content: [{ type: 'paragraph', attrs: { spacingBefore: 28, spacingAfter: 13, lineHeight: 1.6 }, content: [{ type: 'text', text: 'Hello' }] }] }) — verify the <p> element renders with margin-top: 28px; margin-bottom: 13px; line-height: 1.6 inline styles
  4. Call editor.getJSON() — verify the spacing attributes round-trip correctly

Additional Notes

These attributes are returned by the Tiptap Convert DOCX import API on paragraph and heading nodes (derived from w:spacing and w:ind DOCX XML elements). Previously ProseMirror silently dropped them during setContent because the schema didn't define them. With this change, per-paragraph spacing and indentation from DOCX imports are preserved end-to-end.

Note: ProseMirror requires all defined attributes to have an explicit default value. Using null means these attrs always appear in getJSON() output even when unset — this is a ProseMirror constraint, not a design choice. Using undefined as default would make the attributes required and throw errors when creating nodes without them.

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
Copilot AI review requested due to automatic review settings April 6, 2026 14:35
@alexvcasillas alexvcasillas added the Open Source The issue or pull reuqest is related to the open source packages of Tiptap. label Apr 6, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

🦋 Changeset detected

Latest commit: 7a1d902

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-paragraph Major
@tiptap/extension-heading Major
@tiptap/extension-collaboration-caret Major
@tiptap/starter-kit 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-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-strike Major
@tiptap/extension-subscript Major
@tiptap/extension-superscript Major
@tiptap/extension-table-of-contents Major
@tiptap/extension-table 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/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-table-cell Major
@tiptap/extension-table-header Major
@tiptap/extension-table-row 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
Copy Markdown

netlify bot commented Apr 6, 2026

Deploy Preview for tiptap-embed ready!

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

Adds paragraph/heading spacing + indentation attributes so DOCX-imported layout data isn’t dropped by ProseMirror during parsing/setContent, and updates tests/fixtures to reflect the new null-default attrs in JSON output.

Changes:

  • Add spacingBefore, spacingAfter, lineHeight, indent, firstLineIndent attributes to @tiptap/extension-paragraph and @tiptap/extension-heading via a createSpacingAttributes() factory.
  • Add unit/integration tests for parsing/rendering + JSON round-trip of the new attrs.
  • Update existing JSON/HTML-related tests to include the new null-default attrs; add a changeset for both packages.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/extension-paragraph/src/utilities/create-spacing-attributes.ts Introduces spacing/indent attribute factory for Paragraph (parse from inline styles, render back to style).
packages/extension-paragraph/src/paragraph.ts Wires the new spacing/indent attributes into the Paragraph node schema.
packages/extension-paragraph/tests/utilities/create-spacing-attributes.spec.ts Unit tests for the new spacing/indent attribute factory.
packages/extension-paragraph/tests/paragraphAttributes.spec.ts Editor-level integration tests for Paragraph parse/render/defaults/JSON round-trip.
packages/extension-heading/src/utilities/create-spacing-attributes.ts Introduces spacing/indent attribute factory for Heading (duplicated for package independence).
packages/extension-heading/src/heading.ts Wires the new spacing/indent attributes into the Heading node schema alongside level.
packages/extension-heading/tests/headingAttributes.spec.ts Editor-level integration tests for Heading parse/render/defaults/JSON round-trip + coexistence with level.
packages/html/tests/server-with-jsdom.spec.ts Updates expected JSON to include new null-default paragraph attrs.
packages/html/tests/generateJSON.spec.ts Updates expected JSON to include new null-default paragraph attrs.
packages/html/tests/generateHTML.spec.ts Updates input JSON shapes for HTML generation tests to include new attrs on paragraph/heading nodes.
packages/extensions/tests/trailing-node.spec.ts Updates expected heading/paragraph JSON to include new null-default attrs.
packages/extension-mathematics/tests/inlineMath.spec.ts Updates expected paragraph JSON to include new null-default attrs.
packages/extension-list/tests/taskItem.spec.ts Updates expected paragraph JSON in task item tests to include new null-default attrs.
packages/core/tests/unmounted.spec.ts Updates expected JSON to include new null-default paragraph attrs.
packages/core/tests/generateJSON.spec.ts Updates expected JSON to include new null-default paragraph attrs.
packages/core/tests/createNodeFromContent.spec.ts Updates expected JSON shapes to include new null-default paragraph attrs.
.changeset/breezy-goats-approve.md Adds a minor changeset for both extensions documenting the new attributes.

@alexvcasillas alexvcasillas requested a review from bdbch April 6, 2026 14:43
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.

I went through this and I think it does solve the immediate problem, but I’m not sure base Paragraph and Heading are the right place for these attrs.

Adding them directly to those core extensions exposes them to every user, including people who don’t need this import/export behavior, and it also starts to overlap with other existing concepts like lineHeight.

So the fix itself makes sense, I’m just not convinced the schema change belongs on the default node extensions in this form.
Maybe a better fit would be a separate extension that adds these attributes globally to paragraph and heading only when needed, instead of exposing them by default on the base extensions.


Add support for more attributes across paragraph, and heading extensions

**@tiptap/extension-paragraph**
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 is a format we usually don't do. I think it makes sense to have two separate changeset files per package if the changes are not related to each other.

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