You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
3.7 KiB
144 lines
3.7 KiB
# CodeMirror 6 editor for Angular
|
|
|
|
## Installation
|
|
|
|
Use the CodeFirst NPM registry for `@sandkasten` packages in your `~/.npmrc` file:
|
|
|
|
```env
|
|
@sandkasten:registry=https://codefirst.iut.uca.fr/git/api/packages/sandkasten/npm/
|
|
```
|
|
|
|
```bash
|
|
npm install @sandkasten/codemirror6-editor codemirror @codemirror/state @codemirror/view
|
|
```
|
|
|
|
Install the language support you need, for example with JavaScript:
|
|
|
|
```bash
|
|
npm install @codemirror/lang-javascript
|
|
```
|
|
|
|
Don't forget to import the standalone component in either the `app.module.ts` file or in the component file.
|
|
|
|
## Simple examples
|
|
|
|
Those examples use [Angular's standalone API](https://angular.io/guide/standalone-migration).
|
|
|
|
### Editor with JavaScript syntax highlighting
|
|
|
|
```html
|
|
<codemirror6-editor
|
|
[(ngModel)]="editorContent"
|
|
[extensions]="[
|
|
basicSetup,
|
|
javascript
|
|
]"
|
|
></codemirror6-editor>
|
|
```
|
|
|
|
```ts
|
|
import { Component } from '@angular/core';
|
|
import { basicSetup } from 'codemirror';
|
|
import { javascript } from '@codemirror/lang-javascript';
|
|
import { CodeMirrorComponent } from '@sandkasten/codemirror6-editor';
|
|
|
|
@Component({
|
|
selector: 'code-editor',
|
|
standalone: true,
|
|
templateUrl: './code-editor.component.html',
|
|
imports: [CodeMirrorComponent],
|
|
})
|
|
export class CodeEditorComponent {
|
|
protected readonly basicSetup = basicSetup;
|
|
protected readonly javascript = javascript();
|
|
editorContent: string = '';
|
|
}
|
|
```
|
|
|
|
### Read-only editor
|
|
|
|
```html
|
|
<codemirror6-editor
|
|
[(ngModel)]="outputContent"
|
|
[extensions]="[
|
|
readOnlyState
|
|
]"
|
|
></codemirror6-editor>
|
|
```
|
|
|
|
```ts
|
|
import { Component } from '@angular/core';
|
|
import { EditorState } from '@codemirror/state';
|
|
import { CodeMirrorComponent } from '@sandkasten/codemirror6-editor';
|
|
|
|
@Component({
|
|
selector: 'code-output',
|
|
standalone: true,
|
|
templateUrl: './code-output.component.html',
|
|
imports: [CodeMirrorComponent],
|
|
})
|
|
export class CodeOutputComponent {
|
|
protected readonly readOnlyState = EditorState.readOnly.of(true);
|
|
outputContent: string = '';
|
|
}
|
|
```
|
|
|
|
## Dynamic configuration
|
|
|
|
CodeMirror 6 uses a transaction-based API to update the editor state.
|
|
See the [CodeMirror 6 documentation](https://codemirror.net/examples/config/#dynamic-configuration) for more information.
|
|
|
|
To access it programmatically, you can use the `editor` property of the component. Coupled with a CodeMirror's `Compartment`,
|
|
you can dynamically replace the language extension used in the editor for example.
|
|
|
|
```html
|
|
<codemirror6-editor
|
|
[extensions]="extensions"
|
|
></codemirror6-editor>
|
|
```
|
|
|
|
```ts
|
|
import { Component } from '@angular/core';
|
|
import { javascript } from '@codemirror/lang-javascript';
|
|
import { CodeMirrorComponent } from '@sandkasten/codemirror6-editor';
|
|
|
|
type JavaScriptConfig = {
|
|
jsx: boolean;
|
|
typescript: boolean;
|
|
};
|
|
|
|
@Component({
|
|
selector: 'code-editor',
|
|
standalone: true,
|
|
templateUrl: './code-editor.component.html',
|
|
imports: [CodeMirrorComponent],
|
|
})
|
|
export class CodeEditorComponent {
|
|
// Access the CodeMirror Angular component
|
|
@ViewChild(CodeMirrorComponent) codemirror!: CodeMirrorComponent;
|
|
// Create a new dynamic configuration compartment
|
|
private readonly languageCompartment = new Compartment();
|
|
|
|
// Represent the editor configuration for the UI
|
|
private _config: JavaScriptConfig = {
|
|
jsx: false,
|
|
typescript: false,
|
|
};
|
|
get config(): JavaScriptConfig {
|
|
return this._config;
|
|
}
|
|
set config(value: JavaScriptConfig) {
|
|
this._config = value;
|
|
// Update the editor according to the new configuration
|
|
this.codemirror.editor?.dispatch({
|
|
effects: this.languageCompartment.reconfigure(javascript(value))
|
|
});
|
|
}
|
|
// Create the initial extensions array
|
|
protected readonly extensions: Extension[] = [
|
|
basicSetup,
|
|
this.languageCompartment.of(javascript(this.config))
|
|
];
|
|
}
|
|
```
|