Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ngx-tiptap

sibiraj-s18.8kMIT12.0.0TypeScript support: included

Angular bindings for tiptap v2

tiptap, angular-tiptap, angular-editor, angular-rich-text-editor, wysiwyg-editor, rich-text-editor

readme

NgxTiptap

Angular bindings for tiptap v2

Tests NPM Version Total Downloads Monthly Downloads License

demo on stackblitz | edit stackblitz

Find a example on how to use the editor here at project/demo directory.

Installation

npm i ngx-tiptap

# or

yarn add ngx-tiptap

[!NOTE] This package just provides the bindings for angular. For configuring/customizing the editor, refer tiptap's official documentation.

For any issues with the editor. You may need to open the issue on tiptap's repository

Usage

All components are now standalone. Import the component you need.

Create an instance of the editor

import { Component, OnDestroy } from '@angular/core';
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import { TiptapEditorDirective } from 'ngx-tiptap';

@Component({
  selector: 'app-root',
  template: './app.component.html',
  imports: [CommonModule, FormsModule, TiptapEditorDirective],
  standalone: true,
})
export class AppComponent implements OnDestroy {
  editor = new Editor({
    extensions: [StarterKit],
  });

  value = '<p>Hello, Tiptap!</p>'; // can be HTML or JSON, see https://www.tiptap.dev/api/editor#content

  ngOnDestroy(): void {
    this.editor.destroy();
  }
}

and in HTML

<tiptap-editor [editor]="editor" [(ngModel)]="value"></tiptap-editor>

[!NOTE] No styling is provided by default. You are in full control of how your editor looks. Refer tiptaps's styling guide for more information.

[!TIP] Since the editor is dynamically created, You may need to set ViewEncapsulation to None or target the class/element via ::ng-deep to apply the styles. See Component Styles docs for more info.

Options

  • outputFormat [json or html] - defaults to html.

You can get the json or html format from the editor directly as well.

Refer https://www.tiptap.dev/guide/output#export

Extensions

Refer: https://www.tiptap.dev/api/extensions

Floating Menu

This will make a contextual menu appear near a selection of text. The markup and styling are totally up to you.

Import the TiptapFloatingMenuDirective to your component and use it. For example:

<tiptap-editor [editor]="editor"></tiptap-editor>
<tiptap-floating-menu [editor]="editor">
  <!-- Anything that should be rendered inside floating menu -->
</tiptap-floating-menu>

Refer: https://www.tiptap.dev/api/extensions/floating-menu

Bubble Menu

This will make a contextual menu appear near a selection of text. Use it to let users apply marks to their text selection. The markup and styling are totally up to you.

Import the TiptapBubbleMenuDirective to your component and use it. For example:

<tiptap-editor [editor]="editor"></tiptap-editor>
<tiptap-bubble-menu [editor]="editor">
  <!-- Anything that should be rendered inside bubble menu -->
</tiptap-bubble-menu>

Refer: https://www.tiptap.dev/api/extensions/bubble-menu

AngularNodeViewRenderer

This enables rendering Angular Components as NodeViews.

Create a Node Extension

import { Injector } from '@angular/core';
import { Node, mergeAttributes } from '@tiptap/core';
import { AngularNodeViewRenderer } from 'ngx-tiptap';

import { NodeviewCounterComponent } from './nodeview-counter/nodeview-counter.component';

const CounterComponentExtension = (injector: Injector): Node => {
  return Node.create({
    // ...other configuration hidden for brevity
    parseHTML() {
      return [{ tag: 'angular-component-counter' }];
    },
    renderHTML({ HTMLAttributes }) {
      return ['angular-component-counter', mergeAttributes(HTMLAttributes)];
    },
    addNodeView() {
      return AngularNodeViewRenderer(NodeviewCounterComponent, { injector });
    },
  });
};

export default CounterComponentExtension;

Refer: https://tiptap.dev/guide/custom-extensions

Create a Component

import { Component } from '@angular/core';
import { AngularNodeViewComponent } from 'ngx-tiptap';

@Component({
  selector: 'app-nodeview-counter',
})
export class NodeviewCounterComponent extends AngularNodeViewComponent {
  increment(): void {
    const updateAttributes = this.updateAttributes();

    updateAttributes({
      count: this.node.attrs.count + 1,
    });
  }
}

Use the extension

import { Component, Injector, OnInit, OnDestroy } from '@angular/core';
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';

import CounterComponentExtension from './CounterComponentExtension';

@Component({
  selector: 'app-root',
  template: './app.component.html',
})
export class AppComponent implements OnInit, OnDestroy {
  editor: Editor;

  constructor(private injector: Injector) {}

  ngOnInit(): void {
    this.editor = new Editor({
      content: `
        <p>This is still the text editor you’re used to, but enriched with node views.</p>
        <angular-component-counter count="0"></angular-component-counter>
      `,
      extensions: [StarterKit, CounterComponentExtension(this.injector)],
      editorProps: {
        attributes: {
          class: 'p-2 border-black focus:border-blue-700 border-2 rounded-md outline-none',
        },
      },
    });
  }

  ngOnDestroy(): void {
    this.editor.destroy();
  }
}

Access/Update Attributes

Refer https://www.tiptap.dev/guide/node-views/react/#all-available-props for the list of all available attributes. You can access them by extending the AngularNodeViewComponent

import { AngularNodeViewComponent } from 'ngx-tiptap';

export class NodeviewCounterComponent extends AngularNodeViewComponent {
  increment(): void {
    const updateAttributes = this.updateAttributes();

    updateAttributes({
      count: this.node.attrs.count + 1,
    });
  }
}

Adding a content editable

There is another directive called tiptapNodeViewContent which helps you adding editable content to your node view. Make sure to import the TiptapNodeViewContentDirective to your component.

Here is an example.

<!-- editable.component.html -->
<div class="angular-component-with-content">
  <p tiptapNodeViewContent></p>
</div>

Refer: https://www.tiptap.dev/guide/node-views/react/#adding-a-content-editable

Dragging

To make your node views draggable, import the TiptapDraggableDirective to your component and set draggable: true in the tiptap extension. Add tiptapDraggable directive to the DOM element inside the component that should function as the drag handle.

AngularRenderer

You can also manually render the angular components using AngularRenderer.

import { AngularRenderer } from 'ngx-tiptap';

const renderer = new AngularRenderer(Component, injector, props);

renderer.instance; // get the instance of the component, can be used to update `@Input` properties
renderer.dom; // get the HTMLElement for the component
renderer.destroy(); // destroy the component and its instance

Contributing

All types of contributions are welcome. See CONTRIBUTING.md to get started.

changelog

CHANGELOG

All notable changes to this project will be documented in this file.

Tags

  • Features
  • Bug Fixes
  • Performance Improvements
  • Dependency Updates
  • Breaking Changes
  • Enhancements
  • Documentation
  • Internal
  • Refactor

v12.0.0 (2024-11-28)

Breaking Changes

  • requires angular 19 or greater (64193b0)
  • internal: refactor inputs and outputs to be signals (8bc30cb)

Migration

  • Everything is now standalone, and NgxTiptapModule is no longer needed and has been removed. Manually import the following components wherever required:

    • TiptapEditorDirective
    • TiptapFloatingMenuDirective
    • TiptapBubbleMenuDirective
    • TiptapDraggableDirective
    • TiptapNodeViewContentDirective
  • AngularNodeViewComponent methods are now signals.

    An example of updating attributes in a custom node view:

    Before

    this.updateAttributes({
      count: this.node.attrs['count'] + 1,
    });

    After

    const updateAttributes = this.updateAttributes();
    updateAttributes({
      count: this.node().attrs['count'] + 1,
    });

For more details, refer to the README.

v11.1.0 (2024-09-17)

Features

  • add support for attrs in AngularNodeViewRenderer (476081e)
  • improve selection behaviour in custom nodes (476081e)

Bug Fixes

  • fix types mismatch with tiptap v2.7 (476081e)

v11.0.0 (2024-06-19)

Breaking Changes

v10.1.0 (2024-03-06)

Features

  • add support for updateDelay prop in bubble menu (0680e39)

v10.0.0 (2024-03-05)

Breaking Changes

v9.1.1 (2023-12-11)

Bug Fixes

  • fix view not updated on selection with ChangeDetectionStrategy#OnPush (681dc85)

v9.1.0 (2023-11-03)

Features

  • enable hierarchical injectors in AngularRenderer (93ec574)

v9.0.2 (2023-07-24)

Bug Fixes

  • update selected input in nodeview with text selection (0ec762d)

v9.0.1 (2023-07-17)

Bug Fixes

  • fix trigger ChangeDetection in custom Nodeviews using updateProps (4213560)

v9.0.0 (2023-07-01)

Breaking Changes

v8.0.0 (2023-04-26)

Features

  • update to tiptap v2 stable (432f4d2)

v7.0.0 (2022-12-22)

Bug Fixes

  • fixes ngModelChange is invoked during render without any changes to the model value (1fcc867)

Dependency Updates

  • update prosemirror-* peerDependencies (733aa55)
  • update @tiptap/* peerDependencies (03d738f)
  • update devDependencies (b8b1733)

Breaking Changes

  • requires angular 15 or greater (ea34042)
  • titap commands like setContent, clearContent requires emitUpdate flag to be passed (1fcc867)

For Example,

Before

editor.commands.setContent('Hello World!');

After

editor.commands.setContent('Hello World!', true);

v6.0.0 (2022-06-27)

Breaking Changes

  • requires angular 14 or greater (e7f43bf)

v5.0.0 (2022-05-07)

Bug Fixes

  • don't destroy editor from the directive (c165cc6)
  • run changeDetection manually after view init (65f5c1e)

Breaking Changes

  • Editor should be destroyed manually
import { Component, OnDestroy } from '@angular/core';
import { Editor } from '@tiptap/core';

@Component({
  selector: 'app-root',
})
export class AppComponent implements OnDestroy {
  editor = new Editor();

  ngOnDestroy(): void {
    this.editor.destroy();
  }
}

v4.0.4 (2022-01-18)

Bug Fixes

  • render json inputs correctly (3848f59)

Dependency Updates

v4.0.3 (2022-01-13)

Bug Fixes

  • revert using viewContainerRef instead of applicationRef to create components (bb34ce7)

Dependency Updates

v4.0.2 (2022-01-11)

Refactor

  • use viewContainerRef instead of applicationRef to create components (454be3e)

Dependency Updates

Internal

  • replace chalk with picocolors (be8b0f8)
  • remove unused imports (b73aa97)

v4.0.1 (2021-12-08)

Bug Fixes

  • allow setting empty string to ngModel (89c510e)

Dependency Updates

  • update peerDependencies (1489f44)

Internal

v4.0.0 (2021-11-24)

Breaking Changes

v3.0.4 (2021-09-28)

Bug Fixes

  • destory component when nodeview is removed (8ed4db8)

Dependency Updates

  • update peerDependencies (bdc9db7)

v3.0.3 (2021-08-13)

Dependency Updates

  • update tiptap dependencies (19366aa)
  • update angular dependencies (a1832b4)

v3.0.2 (2021-07-31)

Dependency Updates

  • update tiptap dependencies (94f02da)

v3.0.1 (2021-07-18)

Bug Fixes

  • make AngularRenderer more generic (34d5c70)

v3.0.0 (2021-07-17)

Breaking Changes

  • update Input decorators for AngularNodeViewComponent component (8b9bed1)

Before

this.props.selected;
this.props.updatedAttributes;

After

this.selected;
this.updateAttributes;

v2.1.2 (2021-07-14)

Bug Fixes

  • set correct styles for editable component (2b53819)

v2.1.1 (2021-07-13)

Bug Fixes

  • use correct peerDependencies (e48cf70)

v2.1.0 (2021-05-30)

Features

  • add deleteNode method to component prop (7a170a0)

Bug Fixes

  • set correct semver for tiptap packages (5b08331)
  • move contentDOM on editor update (c5f71d9)
  • move all child nodes within EditorContent (883798e)
  • add missing @angular/forms peerDependency (467619e)

Dependency Updates

  • update peerDependencies (52307d4)

v2.0.0 (2021-05-17)

Breaking Changes

v1.4.1 (2021-05-16)

Bug Fixes

  • detectChanges after mounting contentDOMElement (cc1f8da)

Dependency Updates

  • update tiptap dependencies (54ef857)

v1.4.0 (2021-05-13)

Features

  • add AngularRenderer to render custom components (feaa118), (8ec978b)
  • add tiptapNodeViewContent to add contenteditable element inside node views (8d45055)

v1.3.0 (2021-05-11)

Features

  • support dragging nodeviews (55c70c0)

v1.2.3 (2021-05-10)

Bug Fixes

Dependency Updates

  • update dependencies and devDependencies (cfb68de)

Documentation

  • update examples to use StarterKit instead of defaultExtensions (92c93c9)

v1.2.2 (2021-05-04)

Bug Fixes

  • attach stopEvent only if provided (d385e10)

Internal

v1.2.1 (2021-05-04)

Bug Fixes

  • fix typo in floating-menu directive selector (99775a0)

v1.2.0 (2021-05-03)

Features

  • add AngularNodeViewRenderer to render angular components as nodeViews (ebb7851), (4e9911f)

v1.1.0 (2021-05-03)

Features

  • add support for floating menu and bubble menu (1a7eded)

v1.0.1 (2021-05-02)

Documentation

  • add stackblitz demo link (ae836fe)
  • update usage guide, install instruction

Internal

  • enable prod mode for builds (ed30e81)

v1.0.0 (2021-05-02)

Initial Release: Angular bindings for Tiptap v2