Skip to content

Releases: ueberdosis/tiptap

v3.4.2

09 Sep 10:43
ac8f6f2
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Patch Changes

  • 24445c4: Listen to a custom scroll target when positioning the BubbleMenu and
    ensure the scroll listener is cleaned up on destroy.

    The BubbleMenu now accepts an optional scrollTarget option which will be
    used instead of window when listening for scroll events that affect the
    menu positioning. The plugin also removes the scroll listener during
    cleanup.

    No user-facing API changes other than the new optional scrollTarget setting.

v3.4.1

04 Sep 12:38
a51159f
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Patch Changes

  • 46fa8b8: Prefer the raw inline style attribute when parsing color and
    background-color so the original format (hex, rgba/hsla, etc.) is
    preserved instead of falling back to the computed element.style.*
    value (which often resolves to rgb(...)).

    This fixes mismatches where consumers (for example, demo toolbars and
    color pickers) expected the original hex values when initializing the
    editor from HTML.

    • The color and background-color parsers now look for a style
      attribute first and extract the declared value. If no raw style is
      present, they still fall back to element.style.color /
      element.style.backgroundColor.

    MIGRATION NOTES

    • This is a patch-level change. It corrects parsing behavior and is the
      least-disruptive fix for the issue.
    • If your code relied on the parser returning computed rgb(...)
      strings, you may see different string values (for example #958DF1
      instead of rgb(149, 141, 241)) when HTML contained hex values.
    • If you need a stable, normalized format for comparisons, normalize the
      attribute (for example with a color utility like tinycolor2) before
      comparing or use the editor APIs in a way that doesn't depend on the
      exact string representation.
    • @tiptap/[email protected]

@tiptap/[email protected]

Patch Changes

  • 4dd8d58: fix: @types/react version mismatch

@tiptap/[email protected]

Patch Changes

  • 59fb86f: Previously, clientRect was only obtained through decorationNode. If decorationNode could not be obtained, clientRect was set to null, which caused the suggestion not to render in some IME scenarios (notably Chinese IME).

    This change adds a fallback method to compute clientRect from the editor's cursor position when decorationNode is not available. It generates a DOMRect based on the cursor coordinates so the suggestion can render even when the decoration node is missing.

v3.4.0

04 Sep 00:34
fff4619
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Minor Changes

  • ad51daa: Add mount and unmount events to the Editor instance for tracking mounts and unmounts

Patch Changes

  • 895c73f: Fix can().toggleMark() returning incorrect result when cursor is inside nodes that disallow marks

    Fixed an issue where can().toggleMark('bold') incorrectly returned true when the cursor was positioned inside a code block (with no selection), even though marks are not allowed in code blocks. The method now correctly returns false in this scenario by checking if the parent node allows the mark type when the selection is a cursor.

@tiptap/[email protected]

Patch Changes

  • ef909f1: Updated DropcursorOptions.color types to use types defined in prosemirror-dropcursor

@tiptap/[email protected]

Patch Changes

  • 11c8085: Added indentation support for code blocks via Tab. Is deactivated by default.

    New Extension Options:

    • enableTabIndentation: boolean - controls if tab completion should be enabled
    • tabSize: number - controls how many spaces are inserted for a tab

@tiptap/[email protected]

Patch Changes

  • 11c8085: Added indentation support for code blocks via Tab. Is deactivated by default.

    New Extension Options:

    • enableTabIndentation: boolean - controls if tab completion should be enabled
    • tabSize: number - controls how many spaces are inserted for a tab

@tiptap/[email protected]

Patch Changes

  • d3773c7: Fixed an issue where the input method editor (IME) failed to handle Chinese text correctly when entering the first word. Users can now input multiple words as expected.

@tiptap/[email protected]

Patch Changes

  • 2cb08d3: Use factory function for object default value as required by vue 2.
  • 2cb08d3: Fixed a bug that would cause Vue 2 to throw errors in console because Vue 2 expects factory functions for prop defaults

@tiptap/[email protected]

Patch Changes

  • 3733bb9: Allow consumers to handle the Escape key via render().onKeyDown before the suggestion plugin auto-exits.

    Previously the suggestion plugin intercepted Escape internally and immediately called onExit, preventing render().onKeyDown from receiving the event and stopping propagation. Now render().onKeyDown is invoked first for Escape; if it returns true the plugin assumes the consumer handled the event (so they can call event.preventDefault() / event.stopPropagation() and optionally call exitSuggestion(view) themselves). If it returns false (or is absent), the plugin will continue to call onExit and close the suggestion as before.

    This change enables scenarios where the editor is inside a modal/drawer and the consumer needs to prevent the outer UI from reacting to Escape while still controlling the suggestion's lifecycle.

  • 90cbed5: Remove the global document mousedown handler that closed suggestion popups when clicking outside.

    Previously the suggestion plugin listened for document mousedown events and closed suggestion UIs when the user clicked outside the editor or suggestion portal. That behavior has been removed to avoid framework-specific coupling (for example reliance on .react-renderer) and related compatibility issues.

    Now suggestions are closed via other signals:

    • pressing Escape (unchanged)
    • selection/cursor changes
    • renderer.onExit (renderers can call this)
    • programmatic calls to exitSuggestion(view)

v3.3.1

02 Sep 13:22
d019c84
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Patch Changes

  • 9e02c12: Prevent incorrect insertion of code marks when a space immediately follows backticks.

@tiptap/[email protected]

Patch Changes

  • 02eae08: Fixed outdated warning message to reference @tiptap/extension-undo-redo instead of @tiptap/extension-history.

@tiptap/[email protected]

Patch Changes

  • 8eff69a: Improve drag handle node lookup by scanning element bounding rects inside the editor instead of performing per-pixel elementsFromPoint loops, and throttle mouse handling to a single update per animation frame to reduce CPU usage and improve stability.

    This should make drag handle positioning and node detection significantly faster and more robust.

@tiptap/[email protected]

Patch Changes

  • 03bf0ea: Preserve prefixes when replacing emoji shortcodes to avoid unintended conversions.

    Previously, shortcodes such as :x: could be converted into emoji nodes even when part of a larger string (e.g., in URLs or other text). The paste handler now preserves prefixes, which helps prevent unwanted conversions in such cases, but does not specifically target URLs.

Patch Changes

  • 96a34a0: Fix collaboration extension selection to use the extension with a provider instead of the first registered extension

v3.3.0

23 Aug 14:30
ba8d13f
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Minor Changes

  • 5423726: Make input rules and paste rules respect extension priority by registering
    them per-extension instead of aggregating them into a single global plugin.

    Why

    Previously all addInputRules() and addPasteRules() were gathered into one
    global plugin which ran before the other plugins. That caused conflicts where
    some extensions (for example mention/suggestion with #) could not preempt the
    built-in heading input rule.

    What changed

    • Input and paste rules are now created and registered at the position of the
      owning extension. This makes their execution order follow the extension
      sorting/priority mechanism.
    • Behavior is more predictable: extensions with higher priority can now take
      precedence over lower priority extensions' input/paste rules.

    Migration & compatibility

    • This is a behavioral change. If you relied on the old global ordering (input
      rules always running before other plugins), you may observe different
      outcomes. In most cases this is desirable and fixes conflicts (like the
      # mention vs. heading shortcut), but be aware of the change.
    • If you need to force the previous behavior for a specific rule, you can:
      • Register the rule as a ProseMirror plugin via addProseMirrorPlugins() on
        the extension and place it where you want it to run.
      • Adjust the extension priority value so the extension sits earlier or
        later in the ordering.

    If you have any questions or see regressions after upgrading, please open an
    issue with a small repro and we'll help triage.

Patch Changes

  • 5423726: Fix paste rule handling for node views and defensively guard empty ranges.

    This patch ensures paste rules can correctly inspect node content when
    node-specific size metadata (nodeSize) is present, falling back to
    node.content.size when needed. It also skips empty or invalid node ranges
    before calling textBetween, preventing runtime errors originating from
    internal Fragment/Node traversals (for example: "Cannot read properties of
    undefined (reading 'nodeSize')").

@tiptap/[email protected]

Patch Changes

  • 5423726: Change the generateID option to accept a context object: { node, pos }.

    This lets ID generators access both the ProseMirror node and its pos within the document when creating IDs, enabling logic that depends on node content, type, or position.

    The change is backwards-compatible: existing generateID functions that ignore the new context will continue to work. Example usage:

    editor.use(UniqueID, {
      generateID: ({ node, pos }) => `${node.type.name}-${pos}-${uuidv4()}`,
    })
    

@tiptap/[email protected]

Patch Changes

  • 5423726: Ensure ReactRenderer.destroy() removes the renderer DOM element when present.

    • When consumers append a ReactRenderer's .element to the DOM (for example many demos append it to document.body), previously calling destroy() removed the portal renderer but left the DOM node in place which could lead to accumulating .react-renderer elements.
    • destroy() now also removes the element from its parent node if present, preventing leaked DOM nodes / React roots.

@tiptap/[email protected]

Patch Changes

  • 5423726: Add a safe API to exit suggestions and remove decorations.

    • Dispatching a metadata-only transaction with { exit: true } will now reliably deactivate the suggestion plugin and remove inline decorations.
    • Pressing Escape now triggers renderer.onExit and dispatches the exit meta, so suggestions close immediately without needing document edits.
    • Clicking outside the editor will also close active suggestions.
    • Exported exitSuggestion(view, pluginKey?) helper to programmatically close suggestions safely.

v3.2.2

22 Aug 12:05
1a23204
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Patch Changes

  • 1cab7ff: Change the generateID option to accept a context object: { node, pos }.

    This lets ID generators access both the ProseMirror node and its pos within the document when creating IDs, enabling logic that depends on node content, type, or position.

v3.2.1

21 Aug 09:55
11d430c
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Patch Changes

  • 6a2873f: Ensure drag previews for node views work correctly in Safari by attaching
    an offscreen clone of the node to the DOM while calling
    setDragImage, and by preserving the original element's pixel
    width/height so the preview matches the original. This prevents
    Safari from immediately cancelling the drag when a detached element is
    used as the drag image.

v3.1.0

10 Aug 12:38
03cfa84
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Minor Changes

  • 978c548: Expose onDragStart and onDragEnd callbacks to improve custom drag behavior. This allows better UI control compared to relying on editor.view.dragging, especially when using absolute-positioned drag handles.

@tiptap/[email protected]

Minor Changes

  • 978c548: Expose onDragStart and onDragEnd callbacks to improve custom drag behavior. This allows better UI control compared to relying on editor.view.dragging, especially when using absolute-positioned drag handles.

@tiptap/[email protected]

Patch Changes

  • 2718eea: Fixed bubble menus having invalid positions on node selections

@tiptap/[email protected]

Patch Changes

  • 43747ce: Fixed a problem where the emoji extension would interfer with editor's in composing mode (for example in IME conversion)

@tiptap/[email protected]

Patch Changes

  • c868252: Fixed an issue with the mathematics regex using modern negative lookups causing crashes in older Safari versions.

@tiptap/[email protected]

Patch Changes

  • c0d33fd: Fixed a bug causing invalid number of columns being created while converting tables to Markdown
  • 0943a52: Fixed an issue preventing overriding the default options of the static renderer's renderToMarkdown function.

v3.0.9

01 Aug 16:02
224cb2c
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Patch Changes

  • 072b110: Fixed the Vue 3 Drag Handle so it only appears when the user starts interacting with the text editor.

@tiptap/[email protected]

Patch Changes

  • 22fcc31: Update TaskItem aria-label when node changes

@tiptap/[email protected]

Patch Changes

  • 22d6050: fix renderToMarkdown rendering a link href's as undefined

v3.0.8

01 Aug 12:00
ed0dd52
Compare
Choose a tag to compare

Releases

@tiptap/[email protected]

Patch Changes