From ef4879ab42d9aa310cab8c42bc86b9852890baa2 Mon Sep 17 00:00:00 2001 From: sibiraj-s Date: Wed, 9 Dec 2020 10:50:45 +0530 Subject: [PATCH] feat: allow placeholder to be set via component --- src/lib/editor.component.ts | 19 +++++++++++++++++-- src/plugins/placeholder.ts | 15 +++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/lib/editor.component.ts b/src/lib/editor.component.ts index c6eff2bd..ad3ea4dc 100644 --- a/src/lib/editor.component.ts +++ b/src/lib/editor.component.ts @@ -1,7 +1,8 @@ import { Component, ViewChild, ElementRef, forwardRef, OnDestroy, ViewEncapsulation, OnInit, - Output, EventEmitter, Input, TemplateRef + Output, EventEmitter, Input, TemplateRef, + OnChanges, SimpleChanges } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; @@ -23,7 +24,7 @@ import { NgxEditorService, NgxEditorServiceConfig } from './editor.service'; encapsulation: ViewEncapsulation.None }) -export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestroy { +export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestroy, OnChanges { @ViewChild('ngxEditor', { static: true }) ngxEditor: ElementRef; view: EditorView; @@ -33,6 +34,7 @@ export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestr config: NgxEditorServiceConfig; @Input() customMenuRef: TemplateRef; + @Input() placeholder: string; @Output() init = new EventEmitter(); @Output() focusOut = new EventEmitter(); @Output() focusIn = new EventEmitter(); @@ -150,11 +152,24 @@ export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestr this.editorInitialized = true; } + setPlaceholder(newPlaceholder?: string): void { + const { dispatch, state: { tr } } = this.view; + const placeholder = newPlaceholder ?? this.placeholder; + dispatch(tr.setMeta('UPDATE_PLACEHOLDER', placeholder)); + } + ngOnInit(): void { this.createEditor(); + this.setPlaceholder(); } ngOnDestroy(): void { this.view.destroy(); } + + ngOnChanges(changes: SimpleChanges): void { + if (changes?.placeholder && !changes.placeholder.isFirstChange()) { + this.setPlaceholder(changes.placeholder.currentValue); + } + } } diff --git a/src/plugins/placeholder.ts b/src/plugins/placeholder.ts index 67506781..82673731 100644 --- a/src/plugins/placeholder.ts +++ b/src/plugins/placeholder.ts @@ -1,4 +1,4 @@ -import { Plugin, EditorState, PluginKey } from 'prosemirror-state'; +import { Plugin, EditorState, PluginKey, Transaction } from 'prosemirror-state'; import { DecorationSet, Decoration } from 'prosemirror-view'; const DEFAULT_PLACEHOLDER = 'Type Here...'; @@ -7,14 +7,25 @@ const PLACEHOLDER_CLASSNAME = 'NgxEditor__Placeholder'; const placeholderPlugin = (text: string = DEFAULT_PLACEHOLDER): Plugin => { return new Plugin({ key: new PluginKey('placeholder'), + state: { + init(): string { + return text; + }, + apply(tr: Transaction, previousVal: string): string { + const placeholder = tr.getMeta('UPDATE_PLACEHOLDER') ?? previousVal; + return placeholder; + } + }, props: { decorations(state: EditorState): DecorationSet { const doc = state.doc; + const placeholder = this.getState(state); + if (doc.childCount === 1 && doc?.firstChild?.isTextblock && doc.firstChild.content.size === 0) { const placeHolderEl = document.createElement('span'); placeHolderEl.classList.add(PLACEHOLDER_CLASSNAME); - placeHolderEl.textContent = text; + placeHolderEl.textContent = placeholder; return DecorationSet.create(doc, [Decoration.widget(1, placeHolderEl)]); }