@fsegurai/ngx-codemirror
Version:
Angular library that uses codemirror to create a code editor
579 lines (572 loc) • 29.6 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, ElementRef, input, booleanAttribute, output, forwardRef, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { MergeView } from '@codemirror/merge';
import { Compartment, StateEffect, Annotation, EditorState } from '@codemirror/state';
import { EditorView, placeholder, keymap, highlightWhitespace } from '@codemirror/view';
import { basicSetup, minimalSetup } from 'codemirror';
import { External as External$1 } from 'ngx-codemirror';
import { indentWithTab } from '@codemirror/commands';
import { indentUnit } from '@codemirror/language';
class CodeDiffEditorComponent {
constructor() {
this._elementRef = inject(ElementRef);
/** The editor's theme. */
this.theme = input('light');
/**
* The editor's built-in setup. The value can be set to
* [`basic`](https://codemirror.net/docs/ref/#codemirror.basicSetup),
* [`minimal`](https://codemirror.net/docs/ref/#codemirror.minimalSetup) or `null`.
*
* Don't support change dynamically!
*/
this.setup = input('basic');
/** The diff-editor's original value. */
this.originalValue = '';
/**
* The MergeView original config's
* [extensions](https://codemirror.net/docs/ref/#state.EditorStateConfig.extensions).
*
* Don't support change dynamically!
*/
this.originalExtensions = input([]);
/** The diff-editor's modified value. */
this.modifiedValue = '';
/**
* The MergeView modified config's
* [extensions](https://codemirror.net/docs/ref/#state.EditorStateConfig.extensions).
*/
this.modifiedExtensions = input([]);
/** Controls whether editor A or editor B is shown first. Defaults to `"a-b"`. */
this.orientation = input();
/** Controls whether revert controls are shown between changed chunks. */
this.revertControls = input();
/** When given, this function is called to render the button to revert a chunk. */
this.renderRevertControl = input();
/**
* By default, the merge view will mark inserted and deleted text
* in changed chunks. Set this to false in order to turn that off.
*/
this.highlightChanges = input(true, { transform: booleanAttribute });
/** Controls whether a gutter marker is shown next to changed lines. */
this.gutter = input(true, { transform: booleanAttribute });
/** Whether the diff-editor is disabled. */
this.disabled = false;
/**
* When given, long stretches of unchanged text are collapsed.
* `margin` gives the number of lines to leave visible after/before
* a change (default is 3), and `minSize` gives the minimum amount
* of collapsible lines that need to be present (defaults to 4).
*/
this.collapseUnchanged = input();
/** Pass options to the diff algorithm. */
this.diffConfig = input();
/** Event emitted when the editor's original value changes. */
this.originalValueChange = output();
/** Event emitted when focus on the original editor. */
this.originalFocus = output();
/** Event emitted when blur on the original editor. */
this.originalBlur = output();
/** Event emitted when the editor's modified value changes. */
this.modifiedValueChange = output();
/** Event emitted when focus on the modified editor. */
this.modifiedFocus = output();
/** Event emitted when blur on the modified editor. */
this.modifiedBlur = output();
this._onChange = () => {
// Intentionally left blank
};
this._onTouched = () => {
// Intentionally left blank
};
this._updateListener = (editor) => {
return EditorView.updateListener.of(vu => {
if (vu.docChanged && !vu.transactions.some(tr => tr.annotation(External$1))) {
const value = vu.state.doc.toString();
if (editor == 'a') {
this._onChange({ original: value, modified: this.modifiedValue });
this.originalValue = value;
this.originalValueChange.emit(value);
}
else {
this._onChange({ original: this.originalValue, modified: value });
this.modifiedValue = value;
this.modifiedValueChange.emit(value);
}
}
});
};
this._editableConf = new Compartment();
this._themeConf = new Compartment();
}
_getAllExtensions(editor) {
const setup = this.setup();
return [
this._editableConf.of([]),
this._themeConf.of([]),
this._updateListener(editor),
setup === 'basic' ? basicSetup : setup === 'minimal' ? minimalSetup : [],
...(editor === 'a' ? this.originalExtensions() : this.modifiedExtensions()),
];
}
ngOnChanges(changes) {
if (changes['originalValue']) {
this.setValue('a', this.originalValue);
}
if (changes['modifiedValue']) {
this.setValue('b', this.modifiedValue);
}
if (changes['disabled']) {
this.setEditable(!this.disabled);
}
if (changes['theme']) {
this.setTheme(this.theme());
}
this.reconfigureMergeView(changes);
}
ngOnInit() {
this.initializeMergeView();
this.addEventListeners();
this.setEditable(!this.disabled);
this.setTheme(this.theme());
}
ngOnDestroy() {
this.mergeView?.destroy();
}
writeValue(value) {
if (this.mergeView && value != null && typeof value === 'object') {
this.originalValue = value.original;
this.modifiedValue = value.modified;
this.setValue('a', value.original);
this.setValue('b', value.modified);
}
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
this.setEditable(!isDisabled);
}
/** Sets diff-editor's value. */
setValue(editor, value) {
this.mergeView?.[editor].dispatch({
changes: { from: 0, to: this.mergeView[editor].state.doc.length, insert: value },
});
}
/** Sets editor's editable state. */
setEditable(value) {
this._dispatchEffects(this._editableConf.reconfigure(EditorView.editable.of(value)));
}
/** Sets editor's theme. */
setTheme(value) {
this._dispatchEffects(this._themeConf.reconfigure(value === 'light' ? [] : value));
}
/** Sets the root extensions of the editor state. */
setExtensions(editor, value) {
this.mergeView?.[editor].dispatch({
effects: StateEffect.reconfigure.of(value),
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_dispatchEffects(effects) {
this.mergeView?.a.dispatch({ effects });
this.mergeView?.b.dispatch({ effects });
}
initializeMergeView() {
this.mergeView = new MergeView({
parent: this._elementRef.nativeElement,
a: {
doc: this.originalValue,
extensions: this._getAllExtensions('a'),
},
b: {
doc: this.modifiedValue,
extensions: this._getAllExtensions('b'),
},
orientation: this.orientation(),
revertControls: this.revertControls(),
renderRevertControl: this.renderRevertControl(),
highlightChanges: this.highlightChanges(),
gutter: this.gutter(),
collapseUnchanged: this.collapseUnchanged(),
diffConfig: this.diffConfig(),
});
}
addEventListeners() {
this.mergeView?.a.contentDOM.addEventListener('focus', () => {
this._onTouched();
this.originalFocus.emit();
});
this.mergeView?.a.contentDOM.addEventListener('blur', () => {
this._onTouched();
this.originalBlur.emit();
});
this.mergeView?.b.contentDOM.addEventListener('focus', () => {
this._onTouched();
this.modifiedFocus.emit();
});
this.mergeView?.b.contentDOM.addEventListener('blur', () => {
this._onTouched();
this.modifiedBlur.emit();
});
}
reconfigureMergeView(changes) {
if (changes['orientation']) {
this.mergeView?.reconfigure({ orientation: this.orientation() });
}
if (changes['revertControls']) {
this.mergeView?.reconfigure({ revertControls: this.revertControls() });
}
if (changes['renderRevertControl']) {
this.mergeView?.reconfigure({ renderRevertControl: this.renderRevertControl() });
}
if (changes['highlightChanges']) {
this.mergeView?.reconfigure({ highlightChanges: this.highlightChanges() });
}
if (changes['gutter']) {
this.mergeView?.reconfigure({ gutter: this.gutter() });
}
if (changes['collapseUnchanged']) {
this.mergeView?.reconfigure({ collapseUnchanged: this.collapseUnchanged() });
}
if (changes['diffConfig']) {
this.mergeView?.reconfigure({ diffConfig: this.diffConfig() });
}
if (changes['setup'] || changes['originalExtensions'] || changes['modifiedExtensions']) {
this.setExtensions('a', this._getAllExtensions('a'));
this.setExtensions('b', this._getAllExtensions('b'));
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: CodeDiffEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.0", type: CodeDiffEditorComponent, isStandalone: true, selector: "ngx-code-diff-editor, code-diff-editor, [diff-editor]", inputs: { theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, setup: { classPropertyName: "setup", publicName: "setup", isSignal: true, isRequired: false, transformFunction: null }, originalValue: { classPropertyName: "originalValue", publicName: "originalValue", isSignal: false, isRequired: false, transformFunction: null }, originalExtensions: { classPropertyName: "originalExtensions", publicName: "originalExtensions", isSignal: true, isRequired: false, transformFunction: null }, modifiedValue: { classPropertyName: "modifiedValue", publicName: "modifiedValue", isSignal: false, isRequired: false, transformFunction: null }, modifiedExtensions: { classPropertyName: "modifiedExtensions", publicName: "modifiedExtensions", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, revertControls: { classPropertyName: "revertControls", publicName: "revertControls", isSignal: true, isRequired: false, transformFunction: null }, renderRevertControl: { classPropertyName: "renderRevertControl", publicName: "renderRevertControl", isSignal: true, isRequired: false, transformFunction: null }, highlightChanges: { classPropertyName: "highlightChanges", publicName: "highlightChanges", isSignal: true, isRequired: false, transformFunction: null }, gutter: { classPropertyName: "gutter", publicName: "gutter", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, collapseUnchanged: { classPropertyName: "collapseUnchanged", publicName: "collapseUnchanged", isSignal: true, isRequired: false, transformFunction: null }, diffConfig: { classPropertyName: "diffConfig", publicName: "diffConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { originalValueChange: "originalValueChange", originalFocus: "originalFocus", originalBlur: "originalBlur", modifiedValueChange: "modifiedValueChange", modifiedFocus: "modifiedFocus", modifiedBlur: "modifiedBlur" }, host: { classAttribute: "diff-editor" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CodeDiffEditorComponent),
multi: true,
},
], usesOnChanges: true, ngImport: i0, template: '', isInline: true, styles: [".diff-editor{display:block}.diff-editor .cm-mergeView,.diff-editor .cm-mergeViewEditors{height:100%}.diff-editor .cm-mergeView .cm-editor,.diff-editor .cm-mergeView .cm-scroller{height:100%!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: CodeDiffEditorComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-code-diff-editor, code-diff-editor, [diff-editor]', imports: [], template: '', host: {
class: 'diff-editor',
}, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CodeDiffEditorComponent),
multi: true,
},
], styles: [".diff-editor{display:block}.diff-editor .cm-mergeView,.diff-editor .cm-mergeViewEditors{height:100%}.diff-editor .cm-mergeView .cm-editor,.diff-editor .cm-mergeView .cm-scroller{height:100%!important}\n"] }]
}], propDecorators: { originalValue: [{
type: Input
}], modifiedValue: [{
type: Input
}], disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}] } });
const External = Annotation.define();
class CodeEditorComponent {
constructor() {
this._elementRef = inject(ElementRef);
/**
* EditorView's [root](https://codemirror.net/docs/ref/#view.EditorView.root).
*
* Don't support change dynamically!
*/
this.root = input();
/**
* Whether focus on the editor after init.
*
* Don't support change dynamically!
*/
this.autoFocus = input(false, { transform: booleanAttribute });
/** The editor's value. */
this.value = input('');
/** Whether the editor is disabled. */
this.disabled = false;
/** Whether the editor is readonly. */
this.readonly = input(false, { transform: booleanAttribute });
/** The editor's theme. */
this.theme = input('light');
/** The editor's placeholder. */
this.placeholder = input('');
/** Whether indent with Tab key. */
this.indentWithTab = input(false, { transform: booleanAttribute });
/** Should be a string consisting either entirely of the same whitespace character. */
this.indentUnit = input(0);
/** Whether the editor wraps lines. */
this.lineWrapping = input(false, { transform: booleanAttribute });
/** Whether highlight the whitespace. */
this.highlightWhitespace = input(false, { transform: booleanAttribute });
/**
* An array of language descriptions for known
* [language-data](https://github.com/codemirror/language-data/blob/main/src/language-data.ts).
*
* Don't support change dynamically!
*/
this.languages = input([]);
/** The editor's language. You should set the `languages` prop at first. */
this.language = input('');
/**
* The editor's built-in setup. The value can be set to
* [`basic`](https://codemirror.net/docs/ref/#codemirror.basicSetup),
* [`minimal`](https://codemirror.net/docs/ref/#codemirror.minimalSetup) or `null`.
*/
this.setup = input('basic');
/**
* It will be appended to the root
* [extensions](https://codemirror.net/docs/ref/#state.EditorStateConfig.extensions).
*/
this.extensions = input([]);
/** Event emitted when the editor's value changes. */
this.change = output();
/** Event emitted when focus on the editor. */
this.focus = output();
/** Event emitted when the editor has lost focus. */
this.blur = output();
this._onChange = () => {
// Intentionally left blank
};
this._onTouched = () => {
// Intentionally left blank
};
this._updateListener = EditorView.updateListener.of(vu => {
if (vu.docChanged && !vu.transactions.some(tr => tr.annotation(External))) {
const value = vu.state.doc.toString();
this._onChange(value);
this.change.emit(value);
}
});
// Extension compartments can be used to make a configuration dynamic.
// https://codemirror.net/docs/ref/#state.Compartment
this._editableConf = new Compartment();
this._readonlyConf = new Compartment();
this._themeConf = new Compartment();
this._placeholderConf = new Compartment();
this._indentWithTabConf = new Compartment();
this._indentUnitConf = new Compartment();
this._lineWrappingConf = new Compartment();
this._highlightWhitespaceConf = new Compartment();
this._languageConf = new Compartment();
}
_getAllExtensions() {
const setup = this.setup();
return [
this._updateListener,
this._editableConf.of([]),
this._readonlyConf.of([]),
this._themeConf.of([]),
this._placeholderConf.of([]),
this._indentWithTabConf.of([]),
this._indentUnitConf.of([]),
this._lineWrappingConf.of([]),
this._highlightWhitespaceConf.of([]),
this._languageConf.of([]),
setup === 'basic' ? basicSetup : setup === 'minimal' ? minimalSetup : [],
...this.extensions(),
];
}
ngOnChanges(changes) {
if (changes['value'])
this.setValue(this.value());
if (changes['disabled'])
this.setEditable(!this.disabled);
if (changes['readonly'])
this.setReadonly(this.readonly());
if (changes['theme'])
this.setTheme(this.theme());
if (changes['placeholder'])
this.setPlaceholder(this.placeholder());
if (changes['indentWithTab'])
this.setIndentWithTab(this.indentWithTab());
if (changes['indentUnit'])
this.setIndentUnit(this.indentUnit());
if (changes['lineWrapping'])
this.setLineWrapping(this.lineWrapping());
if (changes['highlightWhitespace'])
this.setHighlightWhitespace(this.highlightWhitespace());
if (changes['language'])
this.setLanguage(this.language());
if (changes['setup'] || changes['extensions'])
this.setExtensions(this._getAllExtensions());
}
ngOnInit() {
this.view = new EditorView({
root: this.root(),
parent: this._elementRef.nativeElement,
state: EditorState.create({
doc: this.value(),
extensions: this._getAllExtensions(),
}),
});
if (this.autoFocus())
this.view?.focus();
this.addEventListeners();
this.setEditable(!this.disabled);
this.setReadonly(this.readonly());
this.setTheme(this.theme());
this.setPlaceholder(this.placeholder());
this.setIndentWithTab(this.indentWithTab());
this.setIndentUnit(this.indentUnit());
this.setLineWrapping(this.lineWrapping());
this.setHighlightWhitespace(this.highlightWhitespace());
this.setLanguage(this.language());
}
ngOnDestroy() {
this.view?.destroy();
}
writeValue(value) {
if (this.view)
this.setValue(value);
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
this.setEditable(!isDisabled);
}
/** Sets editor's value. */
setValue(value) {
this.view?.dispatch({
changes: { from: 0, to: this.view.state.doc.length, insert: value },
});
}
/** Sets editor's editable state. */
setEditable(value) {
this._dispatchEffects(this._editableConf.reconfigure(EditorView.editable.of(value)));
}
/** Sets editor's readonly state. */
setReadonly(value) {
this._dispatchEffects(this._readonlyConf.reconfigure(EditorState.readOnly.of(value)));
}
/** Sets editor's theme. */
setTheme(value) {
this._dispatchEffects(this._themeConf.reconfigure(value === 'light' ? [] : value));
}
/** Sets editor's placeholder. */
setPlaceholder(value) {
this._dispatchEffects(this._placeholderConf.reconfigure(value ? placeholder(value) : []));
}
/** Sets editor' indentWithTab. */
setIndentWithTab(value) {
this._dispatchEffects(this._indentWithTabConf.reconfigure(value ? keymap.of([indentWithTab]) : []));
}
/** Sets editor's indentUnit. */
setIndentUnit(value) {
const spaceCount = Array.from({ length: value }).map(() => ' ').join('');
this._dispatchEffects(this._indentUnitConf.reconfigure(value ? indentUnit.of(spaceCount) : []));
}
/** Sets editor's lineWrapping. */
setLineWrapping(value) {
this._dispatchEffects(this._lineWrappingConf.reconfigure(value ? EditorView.lineWrapping : []));
}
/** Sets editor's highlightWhitespace. */
setHighlightWhitespace(value) {
this._dispatchEffects(this._highlightWhitespaceConf.reconfigure(value ? highlightWhitespace() : []));
}
/** Sets the root extensions of the editor. */
setExtensions(value) {
this._dispatchEffects(StateEffect.reconfigure.of(value));
}
/** Sets editor's language dynamically. */
setLanguage(lang) {
if (!lang || lang === 'Plain Text') {
this._dispatchEffects(this._languageConf.reconfigure([]));
return;
}
if (this.languages().length === 0) {
if (this.view)
console.error('No supported languages. Please set the `languages` prop at first.');
return;
}
const langDesc = this._findLanguage(lang);
if (langDesc) {
langDesc.load().then(lang => {
this._dispatchEffects(this._languageConf.reconfigure([lang]));
});
}
}
/** Find the language's extension by its name. Case-insensitive. */
_findLanguage(name) {
const normalizedInput = name.toLowerCase();
const lang = this.languages().find(lang => [lang.name, ...lang.alias].some(alias => normalizedInput === alias.toLowerCase()));
if (!lang) {
console.error('Language not found:', name);
console.info('Supported language names:', this.languages().map(lang => lang.name).join(', '));
return null;
}
return lang;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_dispatchEffects(effects) {
return this.view?.dispatch({ effects });
}
addEventListeners() {
this.view?.contentDOM.addEventListener('focus', () => {
this._onTouched();
this.focus.emit();
});
this.view?.contentDOM.addEventListener('blur', () => {
this._onTouched();
this.blur.emit();
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: CodeEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.0", type: CodeEditorComponent, isStandalone: true, selector: "ngx-code-editor, code-editor, [code-editor]", inputs: { root: { classPropertyName: "root", publicName: "root", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, indentWithTab: { classPropertyName: "indentWithTab", publicName: "indentWithTab", isSignal: true, isRequired: false, transformFunction: null }, indentUnit: { classPropertyName: "indentUnit", publicName: "indentUnit", isSignal: true, isRequired: false, transformFunction: null }, lineWrapping: { classPropertyName: "lineWrapping", publicName: "lineWrapping", isSignal: true, isRequired: false, transformFunction: null }, highlightWhitespace: { classPropertyName: "highlightWhitespace", publicName: "highlightWhitespace", isSignal: true, isRequired: false, transformFunction: null }, languages: { classPropertyName: "languages", publicName: "languages", isSignal: true, isRequired: false, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, setup: { classPropertyName: "setup", publicName: "setup", isSignal: true, isRequired: false, transformFunction: null }, extensions: { classPropertyName: "extensions", publicName: "extensions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change", focus: "focus", blur: "blur" }, host: { classAttribute: "code-editor" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CodeEditorComponent),
multi: true,
},
], usesOnChanges: true, ngImport: i0, template: '', isInline: true, styles: [".code-editor{display:block}.code-editor .cm-editor{height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: CodeEditorComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-code-editor, code-editor, [code-editor]', imports: [], template: '', host: {
class: 'code-editor',
}, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CodeEditorComponent),
multi: true,
},
], styles: [".code-editor{display:block}.code-editor .cm-editor{height:100%}\n"] }]
}], propDecorators: { disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}] } });
const sharedDeclarations = [
CodeEditorComponent,
CodeDiffEditorComponent,
];
class CodeEditorModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: CodeEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.0", ngImport: i0, type: CodeEditorModule, imports: [CodeEditorComponent,
CodeDiffEditorComponent], exports: [CodeEditorComponent,
CodeDiffEditorComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: CodeEditorModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: CodeEditorModule, decorators: [{
type: NgModule,
args: [{
imports: [...sharedDeclarations],
exports: sharedDeclarations,
}]
}] });
/*
* Public API Surface of code-editor
*/
/**
* Generated bundle index. Do not edit.
*/
export { CodeDiffEditorComponent, CodeEditorComponent, CodeEditorModule, External };
//# sourceMappingURL=fsegurai-ngx-codemirror.mjs.map