Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sibiraj-s/ngx-tiptap

Angular bindings for tiptap v2
https://github.com/sibiraj-s/ngx-tiptap

angular-tiptap ngx-tiptap tiptap-editor tiptap-v2

Last synced: 3 days ago
JSON representation

Angular bindings for tiptap v2

Awesome Lists containing this project

README

        

# NgxTiptap

> Angular bindings for [tiptap v2](https://www.tiptap.dev/)

[![Tests](https://github.com/sibiraj-s/ngx-tiptap/actions/workflows/tests.yml/badge.svg)](https://github.com/sibiraj-s/ngx-tiptap/actions/workflows/tests.yml)
[![NPM Version](https://badgen.net/npm/v/ngx-tiptap)](https://www.npmjs.com/package/ngx-tiptap)
[![Total Downloads](https://badgen.net/npm/dt/ngx-tiptap)](https://www.npmjs.com/package/ngx-tiptap)
[![Monthly Downloads](https://badgen.net/npm/dm/ngx-tiptap)](https://www.npmjs.com/package/ngx-tiptap)
[![License](https://badgen.net/npm/license/ngx-tiptap)](https://github.com/sibiraj-s/ngx-tiptap/blob/master/LICENSE)

[demo on stackblitz](https://ngx-tiptap.stackblitz.io/) | [edit stackblitz](https://stackblitz.com/edit/ngx-tiptap)

Find a example on how to use the editor [here at project/demo directory](./projects/demo).

## Installation

```bash
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](https://www.tiptap.dev/).

For any issues with the editor. You may need to open the issue on [tiptap's repository](https://github.com/ueberdosis/tiptap/issues)

## Usage

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

Create an instance of the editor

```ts
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],
})
export class AppComponent implements OnDestroy {
editor = new Editor({
extensions: [StarterKit],
});

value = '

Hello, Tiptap!

'; // can be HTML or JSON, see https://www.tiptap.dev/api/editor#content

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

and in HTML

```html

```

> [!NOTE]
> No styling is provided by default. You are in full control of how your editor looks. Refer [tiptaps's styling guide](https://www.tiptap.dev/guide/styling) for more information.

> [!TIP]
> Since the editor is dynamically created, You may need to set [ViewEncapsulation](https://angular.io/guide/view-encapsulation) to `None` or target the class/element via [::ng-deep](https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep) to apply the styles. See [Component Styles docs](https://angular.io/guide/component-styles#component-styles) 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:

```html

```

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:

```html

```

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

## AngularNodeViewRenderer

This enables rendering Angular Components as NodeViews.

### Create a Node Extension

```ts
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

```ts
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

```ts
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: `

This is still the text editor you’re used to, but enriched with node views.



`,
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`

```ts
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.

```html




```

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`.

```ts
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](./.github/CONTRIBUTING.md) to get started.