@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 @@
1
+ {"version":3,"file":"notectl-angular.mjs","sources":["../../src/lib/notectl-editor.component.ts","../../src/lib/notectl-editor.module.ts","../../src/lib/notectl-editor.directive.ts","../../src/public-api.ts","../../src/index.ts","../../src/notectl-angular.ts"],"sourcesContent":["/**\n * Angular component wrapper for NotectlEditor\n */\n\nimport {\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n ViewEncapsulation,\n forwardRef,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { NotectlEditor as NotectlEditorCore } from '@notectl/core';\nimport type { EditorConfig, EditorAPI } from '@notectl/core';\n\n/**\n * NotectlEditor Angular component\n */\n@Component({\n selector: 'notectl-editor',\n template: '<div #container [attr.data-notectl-angular-wrapper]=\"true\"></div>',\n styles: [':host { display: block; }'],\n encapsulation: ViewEncapsulation.None,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NotectlEditorComponent),\n multi: true,\n },\n ],\n})\nexport class NotectlEditorComponent implements OnInit, OnDestroy, ControlValueAccessor {\n @ViewChild('container', { static: true }) containerRef!: ElementRef<HTMLDivElement>;\n\n /** Debug mode */\n @Input() debug?: boolean;\n\n /** Initial content */\n @Input() content?: string | object;\n\n /** Placeholder text */\n @Input() placeholder?: string;\n\n /** Read-only mode */\n @Input() readOnly?: boolean;\n\n /** Accessibility configuration */\n @Input() accessibility?: EditorConfig['accessibility'];\n\n /** Internationalization configuration */\n @Input() i18n?: EditorConfig['i18n'];\n\n /** Theme configuration */\n @Input() theme?: EditorConfig['theme'];\n\n /** Custom class name */\n @Input() className?: string;\n\n /** Emitted when content changes */\n @Output() contentChange = new EventEmitter<unknown>();\n\n /** Emitted when selection changes */\n @Output() selectionChange = new EventEmitter<unknown>();\n\n /** Emitted when editor gains focus */\n @Output() editorFocus = new EventEmitter<void>();\n\n /** Emitted when editor loses focus */\n @Output() editorBlur = new EventEmitter<void>();\n\n /** Emitted when editor is ready */\n @Output() ready = new EventEmitter<EditorAPI>();\n\n /** Emitted when an error occurs */\n @Output() error = new EventEmitter<Error>();\n\n private editor: NotectlEditorCore | null = null;\n private onChange: (value: unknown) => void = () => {};\n private onTouched: () => void = () => {};\n\n ngOnInit(): void {\n this.initEditor();\n }\n\n ngOnDestroy(): void {\n this.destroyEditor();\n }\n\n /**\n * Initialize the editor instance\n */\n private initEditor(): void {\n if (!this.containerRef?.nativeElement) {\n console.error('NotectlEditor: Container element not found');\n return;\n }\n\n // Create editor instance\n this.editor = document.createElement('notectl-editor') as NotectlEditorCore;\n\n // Configure editor\n const config: EditorConfig = {\n debug: this.debug,\n content: this.content,\n placeholder: this.placeholder,\n readOnly: this.readOnly,\n accessibility: this.accessibility,\n i18n: this.i18n,\n theme: this.theme,\n };\n this.editor.configure(config);\n\n // Attach event listeners\n this.editor.on('content-change', (data) => {\n const eventData = data as { content?: unknown };\n const content = eventData.content;\n this.contentChange.emit(content);\n this.onChange(content);\n });\n\n this.editor.on('selection-change', (data) => {\n const eventData = data as { selection?: unknown };\n this.selectionChange.emit(eventData.selection);\n });\n\n this.editor.on('focus', () => {\n this.editorFocus.emit();\n this.onTouched();\n });\n\n this.editor.on('blur', () => {\n this.editorBlur.emit();\n });\n\n this.editor.on('ready', () => {\n this.ready.emit(this.getEditorAPI());\n });\n\n this.editor.on('error', (data) => {\n const eventData = data as { error?: Error };\n if (eventData.error) {\n this.error.emit(eventData.error);\n }\n });\n\n // Mount editor\n this.containerRef.nativeElement.appendChild(this.editor);\n }\n\n /**\n * Destroy the editor instance\n */\n private destroyEditor(): void {\n if (this.editor) {\n this.editor.destroy();\n if (this.containerRef?.nativeElement?.contains(this.editor)) {\n this.containerRef.nativeElement.removeChild(this.editor);\n }\n this.editor = null;\n }\n }\n\n /**\n * Update editor configuration\n */\n private updateConfig(): void {\n if (!this.editor) return;\n\n const config: EditorConfig = {\n debug: this.debug,\n content: this.content,\n placeholder: this.placeholder,\n readOnly: this.readOnly,\n accessibility: this.accessibility,\n i18n: this.i18n,\n theme: this.theme,\n };\n this.editor.configure(config);\n }\n\n /**\n * Get editor API\n */\n private getEditorAPI(): EditorAPI {\n if (!this.editor) {\n throw new Error('Editor not initialized');\n }\n return this.editor as EditorAPI;\n }\n\n // ControlValueAccessor implementation\n writeValue(value: unknown): void {\n if (this.editor && typeof value === 'string') {\n this.editor.setContent(value);\n }\n }\n\n registerOnChange(fn: (value: unknown) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this.editor) {\n this.editor.configure({ readOnly: isDisabled });\n }\n }\n\n // Public API methods\n /**\n * Get current editor content\n */\n public getContent(): unknown {\n return this.editor?.getContent();\n }\n\n /**\n * Set editor content\n */\n public setContent(content: unknown): void {\n if (this.editor && typeof content === 'string') {\n this.editor.setContent(content);\n }\n }\n\n /**\n * Get current editor state\n */\n public getState(): unknown {\n return this.editor?.getState();\n }\n\n /**\n * Execute an editor command\n */\n public executeCommand(command: string, ...args: unknown[]): void {\n this.editor?.executeCommand(command, ...args);\n }\n\n /**\n * Register a plugin\n */\n public registerPlugin(plugin: unknown): void {\n this.editor?.registerPlugin(plugin as any);\n }\n\n /**\n * Unregister a plugin\n */\n public unregisterPlugin(pluginId: string): void {\n this.editor?.unregisterPlugin(pluginId);\n }\n}\n","/**\n * Angular module for NotectlEditor\n */\n\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { NotectlEditorComponent } from './notectl-editor.component';\n\n@NgModule({\n declarations: [NotectlEditorComponent],\n imports: [CommonModule],\n exports: [NotectlEditorComponent],\n})\nexport class NotectlEditorModule {}\n","/**\n * Angular directive for NotectlEditor (optional alternative to component)\n */\n\nimport {\n Directive,\n ElementRef,\n EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n forwardRef,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { NotectlEditor as NotectlEditorCore } from '@notectl/core';\nimport type { EditorConfig, EditorAPI } from '@notectl/core';\n\n/**\n * Directive to use NotectlEditor on any element\n * Usage: <div notectl-editor [content]=\"content\"></div>\n */\n@Directive({\n selector: '[notectl-editor]',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NotectlEditorDirective),\n multi: true,\n },\n ],\n})\nexport class NotectlEditorDirective implements OnInit, OnDestroy, ControlValueAccessor {\n @Input() debug?: boolean;\n @Input() content?: string | object;\n @Input() placeholder?: string;\n @Input() readOnly?: boolean;\n @Input() accessibility?: EditorConfig['accessibility'];\n @Input() i18n?: EditorConfig['i18n'];\n @Input() theme?: EditorConfig['theme'];\n\n @Output() contentChange = new EventEmitter<unknown>();\n @Output() selectionChange = new EventEmitter<unknown>();\n @Output() editorFocus = new EventEmitter<void>();\n @Output() editorBlur = new EventEmitter<void>();\n @Output() ready = new EventEmitter<EditorAPI>();\n @Output() error = new EventEmitter<Error>();\n\n private editor: NotectlEditorCore | null = null;\n private onChange: (value: unknown) => void = () => {};\n private onTouched: () => void = () => {};\n\n constructor(private elementRef: ElementRef<HTMLElement>) {}\n\n ngOnInit(): void {\n this.initEditor();\n }\n\n ngOnDestroy(): void {\n this.destroyEditor();\n }\n\n private initEditor(): void {\n const hostElement = this.elementRef.nativeElement;\n\n // Create editor instance\n this.editor = document.createElement('notectl-editor') as NotectlEditorCore;\n\n // Configure editor\n const config: EditorConfig = {\n debug: this.debug,\n content: this.content,\n placeholder: this.placeholder,\n readOnly: this.readOnly,\n accessibility: this.accessibility,\n i18n: this.i18n,\n theme: this.theme,\n };\n this.editor.configure(config);\n\n // Attach event listeners\n this.editor.on('content-change', (data) => {\n const eventData = data as { content?: unknown };\n const content = eventData.content;\n this.contentChange.emit(content);\n this.onChange(content);\n });\n\n this.editor.on('selection-change', (data) => {\n const eventData = data as { selection?: unknown };\n this.selectionChange.emit(eventData.selection);\n });\n\n this.editor.on('focus', () => {\n this.editorFocus.emit();\n this.onTouched();\n });\n\n this.editor.on('blur', () => {\n this.editorBlur.emit();\n });\n\n this.editor.on('ready', () => {\n this.ready.emit(this.getEditorAPI());\n });\n\n this.editor.on('error', (data) => {\n const eventData = data as { error?: Error };\n if (eventData.error) {\n this.error.emit(eventData.error);\n }\n });\n\n // Mount editor\n hostElement.appendChild(this.editor);\n }\n\n private destroyEditor(): void {\n if (this.editor) {\n this.editor.destroy();\n const hostElement = this.elementRef.nativeElement;\n if (hostElement.contains(this.editor)) {\n hostElement.removeChild(this.editor);\n }\n this.editor = null;\n }\n }\n\n private getEditorAPI(): EditorAPI {\n if (!this.editor) {\n throw new Error('Editor not initialized');\n }\n return this.editor as EditorAPI;\n }\n\n // ControlValueAccessor implementation\n writeValue(value: unknown): void {\n if (this.editor && typeof value === 'string') {\n this.editor.setContent(value);\n }\n }\n\n registerOnChange(fn: (value: unknown) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (this.editor) {\n this.editor.configure({ readOnly: isDisabled });\n }\n }\n}\n","/**\n * Public API surface of @notectl/angular\n */\n\nexport * from './lib/notectl-editor.component';\nexport * from './lib/notectl-editor.module';\nexport * from './lib/notectl-editor.directive';\n","/**\n * @notectl/angular - Angular adapter for NotectlEditor\n * @packageDocumentation\n */\n\nexport * from './public-api';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @notectl/angular - Angular adapter for NotectlEditor
3
+ * @packageDocumentation
4
+ */
5
+ export * from './public-api';
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Angular component wrapper for NotectlEditor
3
+ */
4
+ import { ElementRef, EventEmitter, OnDestroy, OnInit } from '@angular/core';
5
+ import { ControlValueAccessor } from '@angular/forms';
6
+ import type { EditorConfig, EditorAPI } from '@notectl/core';
7
+ import * as i0 from "@angular/core";
8
+ /**
9
+ * NotectlEditor Angular component
10
+ */
11
+ export declare class NotectlEditorComponent implements OnInit, OnDestroy, ControlValueAccessor {
12
+ containerRef: ElementRef<HTMLDivElement>;
13
+ /** Debug mode */
14
+ debug?: boolean;
15
+ /** Initial content */
16
+ content?: string | object;
17
+ /** Placeholder text */
18
+ placeholder?: string;
19
+ /** Read-only mode */
20
+ readOnly?: boolean;
21
+ /** Accessibility configuration */
22
+ accessibility?: EditorConfig['accessibility'];
23
+ /** Internationalization configuration */
24
+ i18n?: EditorConfig['i18n'];
25
+ /** Theme configuration */
26
+ theme?: EditorConfig['theme'];
27
+ /** Custom class name */
28
+ className?: string;
29
+ /** Emitted when content changes */
30
+ contentChange: EventEmitter<unknown>;
31
+ /** Emitted when selection changes */
32
+ selectionChange: EventEmitter<unknown>;
33
+ /** Emitted when editor gains focus */
34
+ editorFocus: EventEmitter<void>;
35
+ /** Emitted when editor loses focus */
36
+ editorBlur: EventEmitter<void>;
37
+ /** Emitted when editor is ready */
38
+ ready: EventEmitter<EditorAPI>;
39
+ /** Emitted when an error occurs */
40
+ error: EventEmitter<Error>;
41
+ private editor;
42
+ private onChange;
43
+ private onTouched;
44
+ ngOnInit(): void;
45
+ ngOnDestroy(): void;
46
+ /**
47
+ * Initialize the editor instance
48
+ */
49
+ private initEditor;
50
+ /**
51
+ * Destroy the editor instance
52
+ */
53
+ private destroyEditor;
54
+ /**
55
+ * Update editor configuration
56
+ */
57
+ private updateConfig;
58
+ /**
59
+ * Get editor API
60
+ */
61
+ private getEditorAPI;
62
+ writeValue(value: unknown): void;
63
+ registerOnChange(fn: (value: unknown) => void): void;
64
+ registerOnTouched(fn: () => void): void;
65
+ setDisabledState(isDisabled: boolean): void;
66
+ /**
67
+ * Get current editor content
68
+ */
69
+ getContent(): unknown;
70
+ /**
71
+ * Set editor content
72
+ */
73
+ setContent(content: unknown): void;
74
+ /**
75
+ * Get current editor state
76
+ */
77
+ getState(): unknown;
78
+ /**
79
+ * Execute an editor command
80
+ */
81
+ executeCommand(command: string, ...args: unknown[]): void;
82
+ /**
83
+ * Register a plugin
84
+ */
85
+ registerPlugin(plugin: unknown): void;
86
+ /**
87
+ * Unregister a plugin
88
+ */
89
+ unregisterPlugin(pluginId: string): void;
90
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotectlEditorComponent, never>;
91
+ static ɵcmp: i0.ɵɵComponentDeclaration<NotectlEditorComponent, "notectl-editor", never, { "debug": { "alias": "debug"; "required": false; }; "content": { "alias": "content"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "accessibility": { "alias": "accessibility"; "required": false; }; "i18n": { "alias": "i18n"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; "className": { "alias": "className"; "required": false; }; }, { "contentChange": "contentChange"; "selectionChange": "selectionChange"; "editorFocus": "editorFocus"; "editorBlur": "editorBlur"; "ready": "ready"; "error": "error"; }, never, never, false, never>;
92
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Angular directive for NotectlEditor (optional alternative to component)
3
+ */
4
+ import { ElementRef, EventEmitter, OnDestroy, OnInit } from '@angular/core';
5
+ import { ControlValueAccessor } from '@angular/forms';
6
+ import type { EditorConfig, EditorAPI } from '@notectl/core';
7
+ import * as i0 from "@angular/core";
8
+ /**
9
+ * Directive to use NotectlEditor on any element
10
+ * Usage: <div notectl-editor [content]="content"></div>
11
+ */
12
+ export declare class NotectlEditorDirective implements OnInit, OnDestroy, ControlValueAccessor {
13
+ private elementRef;
14
+ debug?: boolean;
15
+ content?: string | object;
16
+ placeholder?: string;
17
+ readOnly?: boolean;
18
+ accessibility?: EditorConfig['accessibility'];
19
+ i18n?: EditorConfig['i18n'];
20
+ theme?: EditorConfig['theme'];
21
+ contentChange: EventEmitter<unknown>;
22
+ selectionChange: EventEmitter<unknown>;
23
+ editorFocus: EventEmitter<void>;
24
+ editorBlur: EventEmitter<void>;
25
+ ready: EventEmitter<EditorAPI>;
26
+ error: EventEmitter<Error>;
27
+ private editor;
28
+ private onChange;
29
+ private onTouched;
30
+ constructor(elementRef: ElementRef<HTMLElement>);
31
+ ngOnInit(): void;
32
+ ngOnDestroy(): void;
33
+ private initEditor;
34
+ private destroyEditor;
35
+ private getEditorAPI;
36
+ writeValue(value: unknown): void;
37
+ registerOnChange(fn: (value: unknown) => void): void;
38
+ registerOnTouched(fn: () => void): void;
39
+ setDisabledState(isDisabled: boolean): void;
40
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotectlEditorDirective, never>;
41
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NotectlEditorDirective, "[notectl-editor]", never, { "debug": { "alias": "debug"; "required": false; }; "content": { "alias": "content"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "readOnly": { "alias": "readOnly"; "required": false; }; "accessibility": { "alias": "accessibility"; "required": false; }; "i18n": { "alias": "i18n"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; }, { "contentChange": "contentChange"; "selectionChange": "selectionChange"; "editorFocus": "editorFocus"; "editorBlur": "editorBlur"; "ready": "ready"; "error": "error"; }, never, never, false, never>;
42
+ }
@@ -0,0 +1,8 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "./notectl-editor.component";
3
+ import * as i2 from "@angular/common";
4
+ export declare class NotectlEditorModule {
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotectlEditorModule, never>;
6
+ static ɵmod: i0.ɵɵNgModuleDeclaration<NotectlEditorModule, [typeof i1.NotectlEditorComponent], [typeof i2.CommonModule], [typeof i1.NotectlEditorComponent]>;
7
+ static ɵinj: i0.ɵɵInjectorDeclaration<NotectlEditorModule>;
8
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Public API surface of @notectl/angular
3
+ */
4
+ export * from './lib/notectl-editor.component';
5
+ export * from './lib/notectl-editor.module';
6
+ export * from './lib/notectl-editor.directive';
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@notectl/angular",
3
+ "version": "0.0.2",
4
+ "description": "Angular adapter for NotectlEditor",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "src",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "ng-packagr -p ng-package.json",
22
+ "test": "echo \"No tests yet\"",
23
+ "lint": "eslint src --ext .ts",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "keywords": [
27
+ "notectl",
28
+ "editor",
29
+ "angular",
30
+ "rich-text",
31
+ "wysiwyg"
32
+ ],
33
+ "author": "Samuel Abramov",
34
+ "license": "MIT",
35
+ "peerDependencies": {
36
+ "@angular/common": ">=14.0.0",
37
+ "@angular/core": ">=14.0.0",
38
+ "@angular/forms": ">=14.0.0",
39
+ "@notectl/core": "*"
40
+ },
41
+ "devDependencies": {
42
+ "@angular/common": "^17.0.0",
43
+ "@angular/compiler": "^17.0.0",
44
+ "@angular/compiler-cli": "^17.0.0",
45
+ "@angular/core": "^17.0.0",
46
+ "@angular/forms": "^17.0.0",
47
+ "ng-packagr": "^17.0.0",
48
+ "typescript": "^5.3.0"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/neuravision-io/notectl.git",
53
+ "directory": "packages/adapters/angular"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ }
58
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @notectl/angular - Angular adapter for NotectlEditor
3
+ * @packageDocumentation
4
+ */
5
+
6
+ export * from './public-api';
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Angular component wrapper for NotectlEditor
3
+ */
4
+
5
+ import {
6
+ Component,
7
+ ElementRef,
8
+ EventEmitter,
9
+ Input,
10
+ OnDestroy,
11
+ OnInit,
12
+ Output,
13
+ ViewChild,
14
+ ViewEncapsulation,
15
+ forwardRef,
16
+ } from '@angular/core';
17
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
18
+ import { NotectlEditor as NotectlEditorCore } from '@notectl/core';
19
+ import type { EditorConfig, EditorAPI } from '@notectl/core';
20
+
21
+ /**
22
+ * NotectlEditor Angular component
23
+ */
24
+ @Component({
25
+ selector: 'notectl-editor',
26
+ template: '<div #container [attr.data-notectl-angular-wrapper]="true"></div>',
27
+ styles: [':host { display: block; }'],
28
+ encapsulation: ViewEncapsulation.None,
29
+ providers: [
30
+ {
31
+ provide: NG_VALUE_ACCESSOR,
32
+ useExisting: forwardRef(() => NotectlEditorComponent),
33
+ multi: true,
34
+ },
35
+ ],
36
+ })
37
+ export class NotectlEditorComponent implements OnInit, OnDestroy, ControlValueAccessor {
38
+ @ViewChild('container', { static: true }) containerRef!: ElementRef<HTMLDivElement>;
39
+
40
+ /** Debug mode */
41
+ @Input() debug?: boolean;
42
+
43
+ /** Initial content */
44
+ @Input() content?: string | object;
45
+
46
+ /** Placeholder text */
47
+ @Input() placeholder?: string;
48
+
49
+ /** Read-only mode */
50
+ @Input() readOnly?: boolean;
51
+
52
+ /** Accessibility configuration */
53
+ @Input() accessibility?: EditorConfig['accessibility'];
54
+
55
+ /** Internationalization configuration */
56
+ @Input() i18n?: EditorConfig['i18n'];
57
+
58
+ /** Theme configuration */
59
+ @Input() theme?: EditorConfig['theme'];
60
+
61
+ /** Custom class name */
62
+ @Input() className?: string;
63
+
64
+ /** Emitted when content changes */
65
+ @Output() contentChange = new EventEmitter<unknown>();
66
+
67
+ /** Emitted when selection changes */
68
+ @Output() selectionChange = new EventEmitter<unknown>();
69
+
70
+ /** Emitted when editor gains focus */
71
+ @Output() editorFocus = new EventEmitter<void>();
72
+
73
+ /** Emitted when editor loses focus */
74
+ @Output() editorBlur = new EventEmitter<void>();
75
+
76
+ /** Emitted when editor is ready */
77
+ @Output() ready = new EventEmitter<EditorAPI>();
78
+
79
+ /** Emitted when an error occurs */
80
+ @Output() error = new EventEmitter<Error>();
81
+
82
+ private editor: NotectlEditorCore | null = null;
83
+ private onChange: (value: unknown) => void = () => {};
84
+ private onTouched: () => void = () => {};
85
+
86
+ ngOnInit(): void {
87
+ this.initEditor();
88
+ }
89
+
90
+ ngOnDestroy(): void {
91
+ this.destroyEditor();
92
+ }
93
+
94
+ /**
95
+ * Initialize the editor instance
96
+ */
97
+ private initEditor(): void {
98
+ if (!this.containerRef?.nativeElement) {
99
+ console.error('NotectlEditor: Container element not found');
100
+ return;
101
+ }
102
+
103
+ // Create editor instance
104
+ this.editor = document.createElement('notectl-editor') as NotectlEditorCore;
105
+
106
+ // Configure editor
107
+ const config: EditorConfig = {
108
+ debug: this.debug,
109
+ content: this.content,
110
+ placeholder: this.placeholder,
111
+ readOnly: this.readOnly,
112
+ accessibility: this.accessibility,
113
+ i18n: this.i18n,
114
+ theme: this.theme,
115
+ };
116
+ this.editor.configure(config);
117
+
118
+ // Attach event listeners
119
+ this.editor.on('content-change', (data) => {
120
+ const eventData = data as { content?: unknown };
121
+ const content = eventData.content;
122
+ this.contentChange.emit(content);
123
+ this.onChange(content);
124
+ });
125
+
126
+ this.editor.on('selection-change', (data) => {
127
+ const eventData = data as { selection?: unknown };
128
+ this.selectionChange.emit(eventData.selection);
129
+ });
130
+
131
+ this.editor.on('focus', () => {
132
+ this.editorFocus.emit();
133
+ this.onTouched();
134
+ });
135
+
136
+ this.editor.on('blur', () => {
137
+ this.editorBlur.emit();
138
+ });
139
+
140
+ this.editor.on('ready', () => {
141
+ this.ready.emit(this.getEditorAPI());
142
+ });
143
+
144
+ this.editor.on('error', (data) => {
145
+ const eventData = data as { error?: Error };
146
+ if (eventData.error) {
147
+ this.error.emit(eventData.error);
148
+ }
149
+ });
150
+
151
+ // Mount editor
152
+ this.containerRef.nativeElement.appendChild(this.editor);
153
+ }
154
+
155
+ /**
156
+ * Destroy the editor instance
157
+ */
158
+ private destroyEditor(): void {
159
+ if (this.editor) {
160
+ this.editor.destroy();
161
+ if (this.containerRef?.nativeElement?.contains(this.editor)) {
162
+ this.containerRef.nativeElement.removeChild(this.editor);
163
+ }
164
+ this.editor = null;
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Update editor configuration
170
+ */
171
+ private updateConfig(): void {
172
+ if (!this.editor) return;
173
+
174
+ const config: EditorConfig = {
175
+ debug: this.debug,
176
+ content: this.content,
177
+ placeholder: this.placeholder,
178
+ readOnly: this.readOnly,
179
+ accessibility: this.accessibility,
180
+ i18n: this.i18n,
181
+ theme: this.theme,
182
+ };
183
+ this.editor.configure(config);
184
+ }
185
+
186
+ /**
187
+ * Get editor API
188
+ */
189
+ private getEditorAPI(): EditorAPI {
190
+ if (!this.editor) {
191
+ throw new Error('Editor not initialized');
192
+ }
193
+ return this.editor as EditorAPI;
194
+ }
195
+
196
+ // ControlValueAccessor implementation
197
+ writeValue(value: unknown): void {
198
+ if (this.editor && typeof value === 'string') {
199
+ this.editor.setContent(value);
200
+ }
201
+ }
202
+
203
+ registerOnChange(fn: (value: unknown) => void): void {
204
+ this.onChange = fn;
205
+ }
206
+
207
+ registerOnTouched(fn: () => void): void {
208
+ this.onTouched = fn;
209
+ }
210
+
211
+ setDisabledState(isDisabled: boolean): void {
212
+ if (this.editor) {
213
+ this.editor.configure({ readOnly: isDisabled });
214
+ }
215
+ }
216
+
217
+ // Public API methods
218
+ /**
219
+ * Get current editor content
220
+ */
221
+ public getContent(): unknown {
222
+ return this.editor?.getContent();
223
+ }
224
+
225
+ /**
226
+ * Set editor content
227
+ */
228
+ public setContent(content: unknown): void {
229
+ if (this.editor && typeof content === 'string') {
230
+ this.editor.setContent(content);
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Get current editor state
236
+ */
237
+ public getState(): unknown {
238
+ return this.editor?.getState();
239
+ }
240
+
241
+ /**
242
+ * Execute an editor command
243
+ */
244
+ public executeCommand(command: string, ...args: unknown[]): void {
245
+ this.editor?.executeCommand(command, ...args);
246
+ }
247
+
248
+ /**
249
+ * Register a plugin
250
+ */
251
+ public registerPlugin(plugin: unknown): void {
252
+ this.editor?.registerPlugin(plugin as any);
253
+ }
254
+
255
+ /**
256
+ * Unregister a plugin
257
+ */
258
+ public unregisterPlugin(pluginId: string): void {
259
+ this.editor?.unregisterPlugin(pluginId);
260
+ }
261
+ }