mirror of https://github.com/abpframework/abp.git
4 changed files with 159 additions and 1 deletions
@ -0,0 +1,70 @@ |
|||
import { Component, ElementRef, AfterViewInit, ViewChild, forwardRef } from '@angular/core'; |
|||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; |
|||
import { EditorState } from '@codemirror/state'; |
|||
import { EditorView, lineNumbers } from '@codemirror/view'; |
|||
import { basicSetup } from 'codemirror'; |
|||
|
|||
@Component({ |
|||
selector: 'abp-codemirror-editor', |
|||
template: `<div #cmHost class="codemirror-container"></div>`, |
|||
providers: [ |
|||
{ |
|||
provide: NG_VALUE_ACCESSOR, |
|||
useExisting: forwardRef(() => CodeMirrorEditorComponent), |
|||
multi: true, |
|||
}, |
|||
], |
|||
}) |
|||
export class CodeMirrorEditorComponent implements AfterViewInit, ControlValueAccessor { |
|||
@ViewChild('cmHost', { static: true }) |
|||
host!: ElementRef; |
|||
|
|||
private view!: EditorView; |
|||
private value = ''; |
|||
|
|||
private onChange = (value: string) => {}; |
|||
private onTouched = () => {}; |
|||
|
|||
writeValue(value: string): void { |
|||
this.value = value || ''; |
|||
|
|||
if (this.view) { |
|||
this.view.dispatch({ |
|||
changes: { |
|||
from: 0, |
|||
to: this.view.state.doc.length, |
|||
insert: this.value, |
|||
}, |
|||
}); |
|||
} |
|||
} |
|||
|
|||
registerOnChange(fn: any): void { |
|||
this.onChange = fn; |
|||
} |
|||
|
|||
registerOnTouched(fn: any): void { |
|||
this.onTouched = fn; |
|||
} |
|||
|
|||
ngAfterViewInit(): void { |
|||
const startState = EditorState.create({ |
|||
doc: this.value, |
|||
extensions: [ |
|||
basicSetup, |
|||
EditorView.updateListener.of(update => { |
|||
if (update.docChanged) { |
|||
const text = update.state.doc.toString(); |
|||
this.onChange(text); |
|||
} |
|||
}), |
|||
lineNumbers(), |
|||
], |
|||
}); |
|||
|
|||
this.view = new EditorView({ |
|||
state: startState, |
|||
parent: this.host.nativeElement, |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
export * from './code-mirror-editor/code-mirror-editor.component'; |
|||
export * from './toast-ui/toastui-editor.component'; |
|||
@ -0,0 +1,86 @@ |
|||
import { AbpLocalStorageService } from '@abp/ng.core'; |
|||
import { isPlatformBrowser } from '@angular/common'; |
|||
import { |
|||
Component, |
|||
AfterViewInit, |
|||
ViewChild, |
|||
ElementRef, |
|||
forwardRef, |
|||
inject, |
|||
DOCUMENT, |
|||
PLATFORM_ID, |
|||
} from '@angular/core'; |
|||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; |
|||
import Editor from '@toast-ui/editor'; |
|||
|
|||
@Component({ |
|||
selector: 'abp-toastui-editor', |
|||
template: `<div #editorContainer></div>`, |
|||
providers: [ |
|||
{ |
|||
provide: NG_VALUE_ACCESSOR, |
|||
useExisting: forwardRef(() => ToastuiEditorComponent), |
|||
multi: true, |
|||
}, |
|||
], |
|||
}) |
|||
export class ToastuiEditorComponent implements AfterViewInit, ControlValueAccessor { |
|||
@ViewChild('editorContainer', { static: true }) |
|||
editorContainer!: ElementRef<HTMLDivElement>; |
|||
|
|||
private editor!: Editor; |
|||
private value = ''; |
|||
|
|||
private document = inject(DOCUMENT); |
|||
private platformId = inject(PLATFORM_ID); |
|||
private localStorageService = inject(AbpLocalStorageService); |
|||
|
|||
private onChange: (value: string) => void = () => {}; |
|||
private onTouched: () => void = () => {}; |
|||
|
|||
writeValue(value: string): void { |
|||
this.value = value || ''; |
|||
if (this.editor) { |
|||
this.editor.setMarkdown(this.value); |
|||
} |
|||
} |
|||
|
|||
registerOnChange(fn: any): void { |
|||
this.onChange = fn; |
|||
} |
|||
|
|||
registerOnTouched(fn: any): void { |
|||
this.onTouched = fn; |
|||
} |
|||
|
|||
ngAfterViewInit(): void { |
|||
if (!isPlatformBrowser(this.platformId)) { |
|||
return; |
|||
} |
|||
|
|||
this.initializeEditor(); |
|||
// TODO: Revise this approach on lepton side :: Service injection through DI
|
|||
// this.setupThemeListener();
|
|||
} |
|||
|
|||
private getTheme(): string { |
|||
return this.localStorageService.getItem('LPX_THEME') || 'light'; |
|||
} |
|||
|
|||
private initializeEditor(): void { |
|||
const theme = this.getTheme(); |
|||
this.editor = new Editor({ |
|||
el: this.editorContainer.nativeElement, |
|||
previewStyle: 'tab', |
|||
height: '500px', |
|||
autofocus: true, |
|||
theme: theme, |
|||
initialValue: this.value, |
|||
}); |
|||
|
|||
this.editor.addHook('change', () => { |
|||
const value = this.editor.getMarkdown(); |
|||
this.onChange(value); |
|||
}); |
|||
} |
|||
} |
|||
@ -1,3 +1,3 @@ |
|||
// Main package entry point
|
|||
// Use @abp/ng.cms-kit/admin or @abp/ng.cms-kit/public for specific functionality
|
|||
export {}; |
|||
export * from './components'; |
|||
|
|||
Loading…
Reference in new issue