Skip to content

Feat(extension-invisible-characters): show tabs and non-breaking spaces - #8099

Open
devvaannsh wants to merge 5 commits into
ueberdosis:mainfrom
devvaannsh:pluto/invis
Open

Feat(extension-invisible-characters): show tabs and non-breaking spaces#8099
devvaannsh wants to merge 5 commits into
ueberdosis:mainfrom
devvaannsh:pluto/invis

Conversation

@devvaannsh

@devvaannsh devvaannsh commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Fixes #7954

Changes and Review

Currently, the invisible characters extension can show spaces, paragraphs and line breaks, but tabs and non-breaking spaces stay invisible. This PR adds two new builders, TabCharacter and NonBreakingSpaceCharacter, so those show up too ( for tabs and ° for non-breaking spaces).

They are opt-in, so nothing changes for existing setups.


Before
Screenshot 2026-07-20 at 6 25 31 PM

After
Screenshot 2026-07-20 at 6 25 48 PM


Checklist

  • I have added a changeset if necessary.
  • I have added tests if possible.
  • I have made sure to test my changes myself.

Responsibility

  • I have reviewed and understand these changes, and I take responsibility for this PR, even if an AI agent created it.

@devvaannsh
devvaannsh requested a review from a team as a code owner July 20, 2026 13:03
@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d95baef

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

This PR includes changesets to release 74 packages
Name Type
@tiptap/extension-invisible-characters 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-caret 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-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-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/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-table-cell Major
@tiptap/extension-table-header Major
@tiptap/extension-table-row Major
@tiptap/extension-task-item Major
@tiptap/extension-task-list Major
@tiptap/ai-toolkit Major
@tiptap/server-ai-toolkit 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

netlify Bot commented Jul 20, 2026

Copy link
Copy Markdown

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit d95baef
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/6a5e1c89f69a74000882ec2b
😎 Deploy Preview https://deploy-preview-8099--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.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The invisible-characters extension now provides opt-in builders for tab and non-breaking-space characters, renders them with dedicated decorations and styles, and exposes them publicly. Tests cover editor updates and cleanup, while React and Vue demos configure and demonstrate the new builders.

Changes

Invisible character builders

Layer / File(s) Summary
Builder exports and decoration rendering
packages/extension-invisible-characters/src/plugin/invisible-characters/*, packages/extension-invisible-characters/src/plugin/InvisibleCharacter.ts, packages/extension-invisible-characters/src/index.ts, packages/extension-invisible-characters/src/plugin/style.ts
Adds TabCharacter and NonBreakingSpaceCharacter, exports them, prevents duplicate widgets during decoration updates, and adds tab () and non-breaking-space (°) styles.
Builder behavior coverage
packages/extension-invisible-characters/__tests__/invisible-characters.spec.ts
Uses isolated editor factories and tests default versus opt-in behavior across typing, transactions, headings, undo/redo, paragraph boundaries, and visibility toggling.
Demo configuration and controls
demos/src/Extensions/InvisibleCharacters/React/index.jsx, demos/src/Extensions/InvisibleCharacters/Vue/index.vue, .changeset/invisible-characters-tab-nbsp.md
Configures the new builders in both demos, adds non-breaking-space sample content and tab insertion controls, and records a minor package release.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Editor
  participant InvisibleCharacters
  participant DecorationSet
  participant CSS
  Editor->>InvisibleCharacters: configure tab and non-breaking-space builders
  Editor->>InvisibleCharacters: insert or update document content
  InvisibleCharacters->>DecorationSet: create character decorations
  DecorationSet->>CSS: render tab or non-breaking-space glyph
Loading

Suggested labels: area: editor, area: core, complexity: medium, impact: low

Suggested reviewers: bdbch

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly states the main change: showing tabs and non-breaking spaces in the invisible characters extension.
Description check ✅ Passed The description matches the template with Fixes, Changes and Review, Checklist, and Responsibility sections filled in.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added area: core Core editor engine and ProseMirror integration area: editor Editor behavior, commands, and transactions complexity: medium Moderate change, possibly multiple files impact: low No direct user impact labels Jul 20, 2026

@alexvcasillas alexvcasillas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall: Approve. Clean, consistent with existing patterns, well-tested.
The dedup change to InvisibleCharacter.createDecoration is a nice catch —
it also fixes a pre-existing duplicate-widget bug for the space character
on multi-step transactions, not just the new builders.

Nits (none blocking):

  1. Missing JSDoc on the two new classes (TabCharacter,
    NonBreakingSpaceCharacter). The repo's CLAUDE.md asks for JSDoc on every
    class/type. The existing sibling builders (SpaceCharacter, HardBreakNode)
    also lack them, so it's consistent with current code — but a one-line
    JSDoc on each new public export would satisfy the standard.

  2. Docs not updated. Out of scope for this OSS PR (docs live in the separate
    docs repo), but the new builders should be documented on the
    invisible-characters page as a follow-up. Worth noting in the PR description.

  3. The ° (degree sign) glyph for non-breaking space is unconventional —
    most editors use something like , , or a shaded box; ° reads as
    "degree" to many users. Purely cosmetic and CSS-overridable, but worth
    confirming it's the intended symbol.

Non-issue, just flagging:

  • The new find/remove/add runs for every matching character on every update,
    even single-step cases where nothing needs removing. It's bounded by the
    updated range (not the whole doc) and matches the existing InvisibleNode
    approach, so the cost is fine — just slightly more allocation per char.

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

Labels

area: core Core editor engine and ProseMirror integration area: editor Editor behavior, commands, and transactions complexity: medium Moderate change, possibly multiple files impact: low No direct user impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants