# Angular contenteditable directive for Angular forms and Material Design

## What is this library

This is micro Angular v6+ contenteditable directive for compatibility with Angular forms.
It just implements [ControlValueAccessor](https://angular.io/api/forms/ControlValueAccessor) for this purpose.

### What is this fork

It implements MatFormFieldControl to support Angular Material

### CSS tricks

I found some useful CSS that can be used with this lib

```css
/* mat-editor should be applied to the container of contenteditable (<mat-form-field>)*/
.mat-editor .mat-form-field-wrapper,
.mat-editor .mat-form-field-infix {
  padding-top: 0;
  padding-bottom: 0;
}

.mat-editor .mat-form-field-flex {
  align-items: center;
}

/* https://github.com/angular/material2/issues/13322 */
.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button,
.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button {
  display: inline-block !important;
}
```

### CKEditor5 support

There are 2 directives that can be used with CKEditor5.

`matCkeditor` simply implements `MatFormFieldControl`

```html
<ckeditor matCkeditor [editor]="ckEditor" [(ngModel)]="content"></ckeditor>
```

`matCkeditorBalloon` should be used with `@ckeditor/ckeditor5-build-balloon` and has an extra input to toggle toolbar of ckeditor.

![Screenshot](/sc.gif)

```html
<mat-form-field appearance="outline" class="mat-editor">
  <ckeditor matCkeditorBalloon [toolbar]="toolbarStatus"
    [editor]="ckEditor" (ready)="editorReady($event)" [config]="editorConfig"
    [(ngModel)]="content">
  </ckeditor>
  <button matSuffix mat-icon-button type="button"
    color="{{toolbarStatus && 'primary'}}" (click)="toolbarStatus = !toolbarStatus">
    <mat-icon> tune </mat-icon>
  </button>
</mat-form-field>
```

To remove the border of CKEditor

```css
.mat-editor .ck-content {
  border: none !important;
  box-shadow: none !important;
}
```

To adjust form-field height

```html
<!-- make mat-form-field fill parent height -->
<div fxLayout="column">
  <mat-form-field appearance="outline" fxFlex formFieldSizer></mat-form-field>
</div>
```

## Install

You can just copy and paste this [directive](projects/mat-contenteditable/src/lib/mat-contenteditable.directive.ts) or install it from npm:

```bash
npm install mat-contenteditable --save
```

## Usage

Import and add `MatContenteditableModule` to your project:

```ts
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatContenteditableModule } from 'mat-contenteditable';

// ...

@NgModule({
  // ...
  imports: [
    // Import this module to get available work angular with `contenteditable`
    MatContenteditableModule,
    // Import one or both of this modules
    FormsModule,
    ReactiveFormsModule
  ]

// ...

})
```

And then you can to use it in [template-driven forms](https://angular.io/guide/forms)
or [reactive forms](https://angular.io/guide/reactive-forms) like this:

```ts
// In your component
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';

export class MyComponent implements OnInit {
  templateDrivenForm = 'This is contenteditable text for template-driven form';
  myControl = new FormControl;

  ngOnInit() {
    this.myControl.setValue(`This is contenteditable text for reactive form`);
  }
}
```

```html
<form #testForm="ngForm">
  <p
    contenteditable="true"
    name="myFormName"
    [(ngModel)]="templateDrivenForm"
    ></p>
</form>

<pre>
  {{ testForm.value | json }}
</pre>

<hr>

<p contenteditable="true" [formControl]="myControl"></p>

<pre>
  {{ myControl.value | json }}
</pre>
```

## Options

With `contenteditable` directive you can pass optional `@Input` value for `propValueAccessor`:

```html
<p
  contenteditable="true"
  propValueAccessor="textContent"
  [formControl]="myControl"
  ></p>
```

In `ContenteditableDirective` this value use like this:

```ts
this.elementRef.nativeElement[this.propValueAccessor]
```

By default it using `innerHTML`.
