@notectl/angular 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Angular directive for NotectlEditor (optional alternative to component)
3
+ */
4
+
5
+ import {
6
+ Directive,
7
+ ElementRef,
8
+ EventEmitter,
9
+ Input,
10
+ OnDestroy,
11
+ OnInit,
12
+ Output,
13
+ forwardRef,
14
+ } from '@angular/core';
15
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
16
+ import { NotectlEditor as NotectlEditorCore } from '@notectl/core';
17
+ import type { EditorConfig, EditorAPI } from '@notectl/core';
18
+
19
+ /**
20
+ * Directive to use NotectlEditor on any element
21
+ * Usage: <div notectl-editor [content]="content"></div>
22
+ */
23
+ @Directive({
24
+ selector: '[notectl-editor]',
25
+ providers: [
26
+ {
27
+ provide: NG_VALUE_ACCESSOR,
28
+ useExisting: forwardRef(() => NotectlEditorDirective),
29
+ multi: true,
30
+ },
31
+ ],
32
+ })
33
+ export class NotectlEditorDirective implements OnInit, OnDestroy, ControlValueAccessor {
34
+ @Input() debug?: boolean;
35
+ @Input() content?: string | object;
36
+ @Input() placeholder?: string;
37
+ @Input() readOnly?: boolean;
38
+ @Input() accessibility?: EditorConfig['accessibility'];
39
+ @Input() i18n?: EditorConfig['i18n'];
40
+ @Input() theme?: EditorConfig['theme'];
41
+
42
+ @Output() contentChange = new EventEmitter<unknown>();
43
+ @Output() selectionChange = new EventEmitter<unknown>();
44
+ @Output() editorFocus = new EventEmitter<void>();
45
+ @Output() editorBlur = new EventEmitter<void>();
46
+ @Output() ready = new EventEmitter<EditorAPI>();
47
+ @Output() error = new EventEmitter<Error>();
48
+
49
+ private editor: NotectlEditorCore | null = null;
50
+ private onChange: (value: unknown) => void = () => {};
51
+ private onTouched: () => void = () => {};
52
+
53
+ constructor(private elementRef: ElementRef<HTMLElement>) {}
54
+
55
+ ngOnInit(): void {
56
+ this.initEditor();
57
+ }
58
+
59
+ ngOnDestroy(): void {
60
+ this.destroyEditor();
61
+ }
62
+
63
+ private initEditor(): void {
64
+ const hostElement = this.elementRef.nativeElement;
65
+
66
+ // Create editor instance
67
+ this.editor = document.createElement('notectl-editor') as NotectlEditorCore;
68
+
69
+ // Configure editor
70
+ const config: EditorConfig = {
71
+ debug: this.debug,
72
+ content: this.content,
73
+ placeholder: this.placeholder,
74
+ readOnly: this.readOnly,
75
+ accessibility: this.accessibility,
76
+ i18n: this.i18n,
77
+ theme: this.theme,
78
+ };
79
+ this.editor.configure(config);
80
+
81
+ // Attach event listeners
82
+ this.editor.on('content-change', (data) => {
83
+ const eventData = data as { content?: unknown };
84
+ const content = eventData.content;
85
+ this.contentChange.emit(content);
86
+ this.onChange(content);
87
+ });
88
+
89
+ this.editor.on('selection-change', (data) => {
90
+ const eventData = data as { selection?: unknown };
91
+ this.selectionChange.emit(eventData.selection);
92
+ });
93
+
94
+ this.editor.on('focus', () => {
95
+ this.editorFocus.emit();
96
+ this.onTouched();
97
+ });
98
+
99
+ this.editor.on('blur', () => {
100
+ this.editorBlur.emit();
101
+ });
102
+
103
+ this.editor.on('ready', () => {
104
+ this.ready.emit(this.getEditorAPI());
105
+ });
106
+
107
+ this.editor.on('error', (data) => {
108
+ const eventData = data as { error?: Error };
109
+ if (eventData.error) {
110
+ this.error.emit(eventData.error);
111
+ }
112
+ });
113
+
114
+ // Mount editor
115
+ hostElement.appendChild(this.editor);
116
+ }
117
+
118
+ private destroyEditor(): void {
119
+ if (this.editor) {
120
+ this.editor.destroy();
121
+ const hostElement = this.elementRef.nativeElement;
122
+ if (hostElement.contains(this.editor)) {
123
+ hostElement.removeChild(this.editor);
124
+ }
125
+ this.editor = null;
126
+ }
127
+ }
128
+
129
+ private getEditorAPI(): EditorAPI {
130
+ if (!this.editor) {
131
+ throw new Error('Editor not initialized');
132
+ }
133
+ return this.editor as EditorAPI;
134
+ }
135
+
136
+ // ControlValueAccessor implementation
137
+ writeValue(value: unknown): void {
138
+ if (this.editor && typeof value === 'string') {
139
+ this.editor.setContent(value);
140
+ }
141
+ }
142
+
143
+ registerOnChange(fn: (value: unknown) => void): void {
144
+ this.onChange = fn;
145
+ }
146
+
147
+ registerOnTouched(fn: () => void): void {
148
+ this.onTouched = fn;
149
+ }
150
+
151
+ setDisabledState(isDisabled: boolean): void {
152
+ if (this.editor) {
153
+ this.editor.configure({ readOnly: isDisabled });
154
+ }
155
+ }
156
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Angular module for NotectlEditor
3
+ */
4
+
5
+ import { NgModule } from '@angular/core';
6
+ import { CommonModule } from '@angular/common';
7
+ import { NotectlEditorComponent } from './notectl-editor.component';
8
+
9
+ @NgModule({
10
+ declarations: [NotectlEditorComponent],
11
+ imports: [CommonModule],
12
+ exports: [NotectlEditorComponent],
13
+ })
14
+ export class NotectlEditorModule {}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Public API surface of @notectl/angular
3
+ */
4
+
5
+ export * from './lib/notectl-editor.component';
6
+ export * from './lib/notectl-editor.module';
7
+ export * from './lib/notectl-editor.directive';