0.0.10 • Published 3 months ago

codemirror-elements v0.0.10

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

codemirror-elements

A set of HTML custom elements for editing source code with CodeMirror.

Adding a code editor to you page can be as simple as:

<cm-editor></cm-editor>

codemirror-elements can be used anywhere HTML can:

  • Plain HTML
  • Markdown
  • Frameworks like React or Angular
  • Web component libraries like Lit or Stencil
  • Vanilla JavaScript

Install

npm i codemirror-elements

Usage

Import the element

HTML:

<script
  type="module"
  src="./node_modules/codemirror-elements/index.js"
></script>

JavaScript:

import 'codemirror-elements';

Create a <cm-editor> element

HTML:

<cm-editor></cm-editor>

Lit:

html`<cm-editor></cm-editor>`;

Set an initial value

HTML:

<cm-editor value="console.log('Hello');"></cm-editor>

JavaScript:

const editor = document.querySelector('cm-editor');
editor.value = "console.log('Hello');";

Listen for changes

<cm-editor> fires a DOM events for CodeMirror callbacks:

  • codemirror-transaction: a TransactionEvent fired on all CodeMirror transactions.
  • codemirror-document-change: a DocumentChangeEvent fired on CodeMirror transactions that include document changes.
  • codemirror-selection-change: a SelectionChangeEvent fired on CodeMirror transactions that include selection changes.

Example:

const editor = document.querySelector('cm-editor');
editor.addEventListener('codemirror-document-change', (e) => {
  const newValue = e.target.value;
});

Add extensions

Extensions are also HTML elements that you add as children of <cm-editor>:

HTML:

<script
  type="module"
  src="./node_modules/codemirror-elements/lib/cm-lang-javascript.js"
></script>
<script
  type="module"
  src="./node_modules/codemirror-elements/lib/cm-theme-one-dark.js"
></script>

<cm-editor>
  <cm-lang-javascript typescript></cm-lang-javascript>
  <cm-theme-one-dark></cm-theme-one-dark>
</cm-editor>

This package implements a few CodeMirror extensions as elements:

  • <cm-lang-javascript>
  • <cm-lang-html>
  • <cm-lang-css>
  • <cm-lang-lit>
  • <cm-theme-one-dark>

The intention is to add more, either in this package, or as independently installable packages.

Write an extension element

import {customElement} from 'lit/decorators.js';
import {CodeMirrorExtensionElement} from 'codemirror-elements/lib/cm-extension-element.js';
import {someExtension} from 'some-codemirror-extension';

@customElement('cm-lang-css')
export class CodeMirrorLangJavascript extends CodeMirrorExtensionElement {
  constructor() {
    super();
    this.setExtensions([someExtension()]);
  }
}

Extensions can also by dynamically updated with CodeMirrorExtensionElement.addExtensions() and CodeMirrorExtensionElement.removeExtensions(). This can be used to reconfigure extensions based on element properties.

See the <cm-lang-javascript> element for an example:

import {type PropertyValues} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import {javascript} from '@codemirror/lang-javascript';
import {CodeMirrorExtensionElement} from './cm-extension-element.js';

@customElement('cm-lang-javascript')
export class CodeMirrorLangJavascript extends CodeMirrorExtensionElement {
  @property({type: Boolean})
  jsx = false;

  @property({type: Boolean})
  typescript = false;

  override update(changedProperties: PropertyValues<this>) {
    if (changedProperties.has('jsx') || changedProperties.has('typescript')) {
      this.setExtensions([
        javascript({jsx: this.jsx, typescript: this.typescript}),
      ]);
    }
    super.update(changedProperties);
  }
}

Contributing

This is a small side-project of mine. If you can make use of these elements and need some features or bug fixes, please reach out and hopefully we can collaborate!