parent
d95bb4acd6
commit
3cd97a4c23
@ -0,0 +1,50 @@
|
|||||||
|
# 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
|
||||||
|
```
|
||||||
|
|
||||||
|
Import the component in either the `app.module.ts` file or the component:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { CodeMirrorComponent } from 'codemirror6';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
A code editor with JavaScript syntax highlighting:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<codemirror6-editor
|
||||||
|
[(ngModel)]="editorContent"
|
||||||
|
[extensions]="[
|
||||||
|
basicSetup,
|
||||||
|
javascript()
|
||||||
|
]"
|
||||||
|
></codemirror6-editor>
|
||||||
|
```
|
||||||
|
|
||||||
|
A read-only code output:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<codemirror6-editor
|
||||||
|
[(ngModel)]="editorContent"
|
||||||
|
[extensions]="[
|
||||||
|
EditorState.readOnly.of(true)
|
||||||
|
]"
|
||||||
|
></codemirror6-editor>
|
||||||
|
```
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"dest": "../../dist/codemirror6-editor",
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "src/public-api.ts"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@sandkasten/codemirror6-editor",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^17.1.0",
|
||||||
|
"@angular/core": "^17.1.0",
|
||||||
|
"@codemirror/state": "^6.4.0",
|
||||||
|
"@codemirror/view": "^6.23.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AngularCodemirror6Component } from './codemirror6-editor.component';
|
||||||
|
|
||||||
|
describe('AngularCodemirror6Component', () => {
|
||||||
|
let component: AngularCodemirror6Component;
|
||||||
|
let fixture: ComponentFixture<AngularCodemirror6Component>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [AngularCodemirror6Component]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AngularCodemirror6Component);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,77 @@
|
|||||||
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
Component,
|
||||||
|
ElementRef,
|
||||||
|
Input,
|
||||||
|
NgZone,
|
||||||
|
OnDestroy
|
||||||
|
} from '@angular/core';
|
||||||
|
import { EditorState, Extension, StateEffect } from '@codemirror/state';
|
||||||
|
import { EditorView } from '@codemirror/view';
|
||||||
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'codemirror6-editor',
|
||||||
|
standalone: true,
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: CodeMirrorComponent,
|
||||||
|
multi: true
|
||||||
|
},
|
||||||
|
],
|
||||||
|
template: `<div #host></div>`,
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
})
|
||||||
|
export class CodeMirrorComponent implements AfterViewInit, OnDestroy, ControlValueAccessor {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
set extensions(extensions: Extension[]) {
|
||||||
|
this.editor?.dispatch({
|
||||||
|
effects: StateEffect.reconfigure.of(extensions),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private editor: EditorView | null = null;
|
||||||
|
private handleChange: (value: string) => void = () => {};
|
||||||
|
|
||||||
|
constructor(private host: ElementRef<HTMLElement>, private ngZone: NgZone) {}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
const state = EditorState.create({
|
||||||
|
extensions: [
|
||||||
|
EditorView.updateListener.of((update) => {
|
||||||
|
this.ngZone.run(() => {
|
||||||
|
const value = update.state.doc.toString();
|
||||||
|
this.handleChange(value);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
this.editor = new EditorView({
|
||||||
|
state,
|
||||||
|
parent: this.host.nativeElement,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.editor?.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(value: string) {
|
||||||
|
this.editor?.dispatch({
|
||||||
|
changes: {
|
||||||
|
from: 0,
|
||||||
|
to: this.editor.state.doc.length,
|
||||||
|
insert: value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnChange(fn: (value: string) => void) {
|
||||||
|
this.handleChange = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnTouched() {}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
/*
|
||||||
|
* Public API Surface of codemirror6-editor
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './lib/codemirror6-editor.component';
|
@ -0,0 +1,14 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/lib",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.lib.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declarationMap": false
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"compilationMode": "partial"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in new issue