libs/core/monaco-editor/src/lib/monaco-editor/diff-editor.component.ts

Extends

BaseEditor

Metadata

Relationships

Depends on

Index

Properties
Inputs
Outputs

Constructor

constructor()

Inputs

modifiedModel
Type : DiffEditorModel | undefined
Default value : undefined
options
Type : any
Default value : {}
originalModel
Type : DiffEditorModel | undefined
Default value : undefined
insideNg
Type : boolean
Default value : false
Inherited from BaseEditor

Outputs

onInit
Type : any
Inherited from BaseEditor

Properties

_modifiedModel
Type : DiffEditorModel | undefined
_originalModel
Type : DiffEditorModel | undefined
Readonly options
Type : unknown
Default value : computed(() => Object.assign({}, this.config.defaultOptions, this.optionsInput()) )
Readonly _editorContainer
Type : unknown
Default value : viewChild.required<ElementRef>('editorContainer')
Inherited from BaseEditor
config
Type : unknown
Default value : inject<NgxMonacoEditorConfig>(NGX_MONACO_EDITOR_CONFIG)
Inherited from BaseEditor
import {
  ChangeDetectionStrategy,
  Component,
  NgZone,
  computed,
  effect,
  inject,
  input,
  untracked
} from '@angular/core';
import { fromEvent } from 'rxjs';

import { BaseEditor } from './base-editor';
import { DiffEditorModel } from './types';

declare let monaco: any;

@Component({
  standalone: true,
  selector: 'taly-monaco-diff-editor',
  template: '<div class="editor-container" #editorContainer></div>',
  styles: [
    `
      :host {
        display: block;
        height: 200px;
      }

      .editor-container {
        width: 100%;
        height: 98%;
      }
    `
  ],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DiffEditorComponent extends BaseEditor {
  private zone = inject(NgZone);

  // eslint-disable-next-line @angular-eslint/no-input-rename
  readonly optionsInput = input<any>({}, { alias: 'options' });

  readonly options = computed(() =>
    Object.assign({}, this.config.defaultOptions, this.optionsInput())
  );
  readonly originalModel = input<DiffEditorModel | undefined>(undefined);
  readonly modifiedModel = input<DiffEditorModel | undefined>(undefined);

  _originalModel: DiffEditorModel | undefined;
  _modifiedModel: DiffEditorModel | undefined;

  constructor() {
    super();
    effect((onCleanup) => {
      this._options = { ...this.options() };
      this._originalModel = this.originalModel();
      this._modifiedModel = this.modifiedModel();
      const insideNg = this.insideNg();
      const monacoLoaded = this.monacoLoaded();
      untracked(() => {
        if (!monacoLoaded || !this._originalModel || !this._modifiedModel) {
          return;
        }
        // `cancelled` guards against the effect re-running (stale models) or the
        // component being destroyed before this microtask gets a turn.
        let cancelled = false;
        onCleanup(() => {
          cancelled = true;
        });
        // Deferred: initMonaco() emits `onInit`, which can trigger change detection —
        // doing that synchronously inside this effect risks NG0100.
        queueMicrotask(() => {
          if (cancelled) {
            return;
          }
          if (this._editor) {
            this._editor.dispose();
          }
          this.initMonaco(this._options, insideNg);
        });
      });
    });
  }

  protected initMonaco(options: any, insideNg: boolean): void {
    if (!this._originalModel || !this._modifiedModel) {
      throw new Error('originalModel or modifiedModel not found for ngx-monaco-diff-editor');
    }

    this._originalModel.language = this._originalModel.language || options.language;
    this._modifiedModel.language = this._modifiedModel.language || options.language;

    const originalModel = monaco.editor.createModel(
      this._originalModel.code,
      this._originalModel.language
    );
    const modifiedModel = monaco.editor.createModel(
      this._modifiedModel.code,
      this._modifiedModel.language
    );

    this._editorContainer().nativeElement.innerHTML = '';
    const theme = options.theme;

    if (insideNg) {
      this._editor = monaco.editor.createDiffEditor(this._editorContainer().nativeElement, options);
    } else {
      this.zone.runOutsideAngular(() => {
        this._editor = monaco.editor.createDiffEditor(
          this._editorContainer().nativeElement,
          options
        );
      });
    }

    options.theme = theme;
    this._editor.setModel({
      original: originalModel,
      modified: modifiedModel
    });

    // refresh layout on resize event.
    if (this._windowResizeSubscription) {
      this._windowResizeSubscription.unsubscribe();
    }
    this._windowResizeSubscription = fromEvent(window, 'resize').subscribe(() =>
      this._editor.layout()
    );
    this.onInit.emit(this._editor);
  }
}

      :host {
        display: block;
        height: 200px;
      }

      .editor-container {
        width: 100%;
        height: 98%;
      }
    
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""