Skip to content

Getting started

Quick start with npm

Lake is available on npm as the lakelib package. Install the latest version using the following command:

bash
npm install lakelib

Place the editor placeholders within your HTML:

html
<div class="my-editor">
  <div class="my-toolbar"></div>
  <div class="my-content"></div>
</div>

Import the required CSS and JavaScript modules, then initialize and render the editor. You can customize the toolbar and editor config as needed.

js
import 'lakelib/lib/lake.css';
import { Editor, Toolbar } from 'lakelib';

const toolbar = new Toolbar({
  root: '.my-toolbar',
});
const editor = new Editor({
  root: '.my-content',
  toolbar,
});
editor.render();

Note

Ensure lake.css is loaded before rendering the editor.

For a live demonstration, check out the npm example on CodeSandbox.

Quick start with CDN

If you prefer to use plain JavaScript without any build steps, you can load the bundled files directly from a CDN like jsDelivr or UNPKG. You can also download and host the files yourself.

Include the following lines in the <head> section of your HTML page:

html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/lake.min.css" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lake.min.js"></script>

Place the editor placeholders within your HTML:

html
<div class="my-editor">
  <div class="my-toolbar"></div>
  <div class="my-content"></div>
</div>

Use the following JavaScript to initialize and render the editor. You can customize the toolbar and editor config as needed.

js
const { Editor, Toolbar } = Lake;

const toolbar = new Toolbar({
  root: '.my-toolbar',
});
const editor = new Editor({
  root: '.my-content',
  toolbar,
});
editor.render();

For a live demonstration, visit the CDN example on this website or try it on CodeSandbox.

Integrating with frameworks

Lake is a plain JavaScript library, which means you can integrate it into any other frameworks, such as React, Vue, Svelte, and Angular.

js
import 'lakelib/lib/lake.css';
import { Editor, Toolbar } from 'lakelib';
import { useRef, useEffect } from 'react';

export default function Lake({ defaultValue }) {
  const toolbarRef = useRef(null);
  const contentRef = useRef(null);

  useEffect(() => {
    const toolbar = new Toolbar({
      root: toolbarRef.current,
    });
    const editor = new Editor({
      root: contentRef.current,
      toolbar,
      value: defaultValue,
    });
    editor.render();
    editor.event.on('change', (value) => {
      console.log(value);
    });
    return () => editor.unmount();
  }, []);

  return (
    <div className="my-editor">
      <div className="my-toolbar" ref={toolbarRef}></div>
      <div className="my-content" ref={contentRef}></div>
    </div>
  );
}
vue
<script setup>
import 'lakelib/lib/lake.css';
import { Editor, Toolbar } from 'lakelib';
import { useTemplateRef, onMounted, onUnmounted } from 'vue';

const toolbarRef = useTemplateRef('toolbarRef');
const contentRef = useTemplateRef('contentRef');

let editor = null;

onMounted(() => {
  const toolbar = new Toolbar({
    root: toolbarRef.value,
  });
  editor = new Editor({
    root: contentRef.value,
    toolbar,
  });
  editor.render();
  editor.event.on('change', (value) => {
    console.log(value);
  });
});

onUnmounted(() => {
  if (editor) {
    editor.unmount();
    editor = null;
  }
});
</script>

<template>
  <div class="my-editor">
    <div class="my-toolbar" ref="toolbarRef"></div>
    <div class="my-content" ref="contentRef"></div>
  </div>
</template>
svelte
<script lang="ts">
  import 'lakelib/lib/lake.css';
  import { Editor, Toolbar } from 'lakelib';
  import { onMount, onDestroy } from 'svelte';

  let toolbarNode;
  let contentNode;
  let editor;

  onMount(() => {
    const toolbar = new Toolbar({
      root: toolbarNode,
    });
    editor = new Editor({
      root: contentNode,
      toolbar,
      value: '<p>Hello World!</p>',
    });
    editor.render();
    editor.event.on('change', (value) => {
      console.log(value);
    });
  });

  onDestroy(() => {
    if (editor) {
      editor.unmount();
    }
  });
</script>

<div class="my-editor">
  <div class="my-toolbar" bind:this={toolbarNode}></div>
  <div class="my-content" bind:this={contentNode}></div>
</div>
ts
import 'lakelib/lib/lake.css';
import { Editor, Toolbar } from 'lakelib';
import { Component, ElementRef, afterRender } from '@angular/core';

@Component({
  selector: 'lake-root',
  standalone: true,
  template: `
    <div class="my-editor">
      <div class="my-toolbar"></div>
      <div class="my-content"></div>
    </div>
  `,
})
export class Lake {
  private editor: Editor | null = null;

  constructor(elementRef: ElementRef) {
    const nativeElement = elementRef.nativeElement;

    afterRender(() => {
      if (this.editor) {
        this.editor.unmount();
      }
      const toolbar = new Toolbar({
        root: nativeElement.querySelector('.my-toolbar'),
      });
      const editor = new Editor({
        root: nativeElement.querySelector('.my-content'),
        toolbar,
        value: '<p>Hello World!</p>',
      });
      editor.render();
      editor.event.on('change', (value) => {
        console.log(value);
      });
      this.editor = editor;
    });
  }
}

You can visit the following sandboxes to try these examples in your browser:

Getting and setting value

Lake provides the following methods to get and set the editor's content.

Initializing the editor with a provided value

Use the value config to set the initial content:

js
const defaultValue = `
  <h1>Title</h1>
  <p>Content<focus /></p>
`;
new Editor({
  root: '.my-content',
  value: defaultValue,
});

Getting value

Get the current content using the getValue() method:

js
const content = editor.getValue();

Setting value

Replace the existing content with a new value using the setValue() method:

js
editor.setValue('<p>New content</p>');

Binding events

Lake supports event binding through the editor.event.on() method.

change event

Fired when the editor's content is changed. The value parameter is the current content, which conforms to LML format.

js
editor.event.on('change', value => {
  console.log(value);
});

statechange event

Fired when the current selection is changed. The state parameter is a SelectionState object representing the state of the current selection.

js
editor.event.on('statechange', state => {
  console.log(state);
});

For all event names, refer to the Editor class.

Customizing toolbar

Lake allows you to make your own toolbar by setting the items config.

js
const toolbarItems = [
  'undo',
  'redo',
  '|',
  'bold',
];
new Toolbar({
  root: '.my-toolbar',
  items: toolbarItems,
});

Uploading images

Before using image uploads, you need to set the image config.

js
new Editor({
  root: '.my-content',
  image: {
    requestMethod: 'POST',
    requestAction: '/upload',
    requestTypes: ['image/gif', 'image/jpeg', 'image/png'],
  },
});

Uploading files

Similarly, before using file uploads, you need to set the file config.

js
new Editor({
  root: '.my-content',
  file: {
    requestMethod: 'POST',
    requestAction: '/upload',
    requestTypes: ['application/zip', 'application/pdf'],
  },
});

Code block

This feature is powered by CodeMirror. Since CodeMirror is a quite large library and not all users require it, it is disabled by default. To enable it, include CodeMirror for Lake in your project:

js
import * as CodeMirror from 'lake-codemirror';
window.LakeCodeMirror = CodeMirror;
html
<script src="https://cdn.jsdelivr.net/npm/lake-codemirror@2/dist/codemirror.min.js"></script>

Mathematical formula

Similarly, the formula feature is disabled by default. Enable it by adding KaTeX:

js
import 'katex/dist/katex.css';
import katex from 'katex';
window.katex = katex;
html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>

Released under the MIT License.