/solid-codemirror

CodeMirror 6 component for SolidJS

Primary LanguageTypeScriptMIT LicenseMIT

solid-codemirror

solid-codemirror

A set of libraries to integrate CodeMirror to any SolidJS app. This repository contains two packages:

Demo

https://solid-codemirror.vercel.app/

Installation

yarn add @solid-codemirror/codemirror
# or
npm i @solid-codemirror/codemirror

Note The @codemirror/state and @codemirror/view libraries are flagged as peer dependencies and are recommeneded to be installed alongside this package.

Known issue with Vite

Warning You may encounter the following error if you're using Vite as your bundling tool:

Error: Unrecognized extension value in extension set ([object Object]). This sometimes happens because multipleinstances of @codemirror/state are loaded, breaking instanceof checks.

This error can be fixed by adding the following configuration option to your vite.config.{js,ts} file.

export default defineConfig({
  // Your configuration
  optimizeDeps: {
    // Add both @codemirror/state and @codemirror/view to included deps for optimization
    include: ["@codemirror/state", "@codemirror/view"],
  },
});

Basic Usage

import { CodeMirror } from "@solid-codemirror/codemirror";

export default function App() {
  return <CodeMirror />;
}

Configure Line Numbers / Read Only / Line Wrapping

import { CodeMirror } from "@solid-codemirror/codemirror";

export default function App() {
  return <CodeMirror showLineNumbers={true} readOnly={false} wrapLine={true} />;
}

Configure theme

import { CodeMirror } from "@solid-codemirror/codemirror";
import { oneDark } from "@codemirror/theme-one-dark";

export default function App() {
  return <CodeMirror theme={oneDark} />;
}

Configure Extensions

import { CodeMirror } from "@solid-codemirror/codemirror";
import { basicSetup } from "codemirror";
import { python } from "@codemirror/lang-python";
import { oneDark } from "@codemirror/theme-one-dark";

export default function App() {
  return <CodeMirror extensions={[basicSetup, python()]} />;
}

Register callbacks on editor value change or editor mount

import { CodeMirror } from "@solid-codemirror/codemirror";
import type { EditorView } from "@codemirror/view";

export default function App() {
  const onValueChange = (value: string) => {
    console.log(value);
  };

  const onEditorMount = (view: EditorView) => {
    console.log(view);
  };

  return (
    <CodeMirror onEditorMount={onEditorMount} onValueChange={onValueChange} />
  );
}

Controlling the CodeMirror component

You can control the CodeMirror component through the following props. All props are optional.

Prop Type Description
value string The initial value of the editor
onValueChange (value: string) => void Called whenever the editor code value changes
onEditorMount (editor: EditorView) => void Called when the editor first mounts, receiving the current EditorView instance
showLineNumbers boolean Whether to display line numbers
wrapLine boolean Whether to wrap lines
readOnly boolean Whether to set the editor to read-only
theme Extension The CodeMirror theme extension to use
extensions Extension[] An array of CodeMirror extensions to use

For more information on the usage of the CodeMirror component, check out @solid-codemirror/codemirror.
 
 

Advanced usage

Want more control over your CodeMirror component? Create your custom component using the createCodeMirror function.

Installation

yarn add @solid-codemirror/core @codemirror/state @codemirror/view
# or
npm i @solid-codemirror/core @codemirror/state @codemirror/view

createCodeMirror

Attaches a CodeMirror view to the specified ref object and returns a object with a createExtension method to add extension compartments to the codemirror state instance.

Basic Usage

import { CodeMirrorProps, createCodeMirror } from "@solid-codemirror/core";

export default function CodeMirror(props: CodeMirrorProps) {
  let ref: HTMLDivElement | undefined;

  createCodeMirror(props, () => ref);

  return <div ref={ref} />;
}

Add Extension

import { CodeMirrorProps, createCodeMirror } from "@solid-codemirror/core";
import { lineNumbers } from "@codemirror/view";

export default function App(props: CodeMirrorProps) {
  let ref: HTMLDivElement | undefined;

  const { createExtension } = createCodeMirror(props, () => ref);

  createExtension(lineNumbers());

  return <div ref={ref} />;
}

Reconfigure Extension

import { CodeMirrorProps, createCodeMirror } from "@solid-codemirror/core";
import { lineNumbers } from "@codemirror/view";

export default function App(props: CodeMirrorProps) {
  let ref: HTMLDivElement | undefined;

  const { createExtension } = createCodeMirror(props, () => ref);

  const reconfigureLineNumbers = createExtension(lineNumbers());

  return (
    <div>
      <div ref={ref} />

      {/* Buttons to show/hide line numbers */}
      <div>
        <button onClick={() => reconfigureLineNumbers([])}>
          Hide line numbers
        </button>
        <button onClick={() => reconfigureLineNumbers(lineNumbers())}>
          Show line numbers
        </button>
      </div>
    </div>
  );
}

Note Extensions in @codemirror/core are wrapped inside an editor Comparment. Compartments enable dynamic reconfiguration (partially reconfigure a tree of extensions) of the editor.

Note The @solid-codemirror/codemirror package is based on @codemirror/core. You can view the source code of the library here.

For more information on the usage of the createCodeMirror function, check out @solid-codemirror/core.

License

This project is licensed under MIT.

Author