Giter Club home page Giter Club logo

easy-editor's Introduction

Easy Editor

GitHub
A rich text editor based on slate

easy-editor

Demo

Quick Start

npm

npm install @camol/easy-editor --save

yarn

yarn add @camol/easy-editor -S

Examples

git clone https://github.com/kanweiwei/easy-editor.git
cd easy-editor
yarn && yarn build && yarn example

with React

import * as React from "react";
import ReactDom from "react-dom";
import EasyEditor from "@camol/easy-editor";

class Editor extends React.Component {
  html = "";

  handleChange = (v: any) => {
    console.log("change=>>>", v);
    if (this.editorRef.current) {
      // value to html
      console.log(this.editorRef.current.convertor.serialize(v.change.value));
    }
  };

  render() {
    return <EasyEditor value={"<p>123</p>"} onChange={this.handleChange} />;
  }
}

ReactDom.render(<Editor />, document.getElementById("root"));

Custom toolbar

For convenience, some tools have been built in the toolbar.

tool instructions
fontSize 字号
fontColor 字体颜色
bold 加粗
italic 斜体
u 下划线
sup 上标
sub 下标
left 文字居左
right 文字居右
center 文字居中
justify 两端对齐
image 插入图片
video 插入音频(mp4、webm)
pdf 插入 pdf
math 插入 latex 数学公式

How to add a custom tool ?

import * as React from "react";
import ReactDom from "react-dom";
import EasyEditor from "@camol/easy-editor";

// audio tool
class AudioControl extends React.Component {
  inputRef = React.createRef();

  handleClick = () => {
    if (inputRef.current) {
      inputRef.current.click();
    }
  };

  handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files[0];
    e.target.value = "";
    if (file) {
      if (this.props.beforeUpload) {
        let url = await this.props.beforeUpload(file);
        if (url) {
          let change = this.props.change.focus().insertInline({
            object: "inline",
            type: "audio",
            isVoid: true,
            data: {
              src: url,
            },
          });
          this.props.update(change);
        }
      }
    }
  };

  render() {
    return (
      <span onMouseDown={this.handleClick}>
        <span className="tool-insert-video" />
        <input
          type="file"
          style={{ width: 0, height: 0, opacity: 0 }}
          ref={this.inputRef}
          onChange={this.handleChange}
        />
      </span>
    );
  }
}

class Editor extends React.Component {
  html = "";

  handleChange = (v: any) => {
    console.log("change=>>>", v);
    if (this.editorRef.current) {
      // value to html
      console.log(this.editorRef.current.convertor.serialize(v.change.value));
    }
  };

  render() {
    return (
      <EasyEditor
        value={"<p>123</p>"}
        onChange={this.handleChange}
        controls={[
          ["bold", "u", "image"],
          [
            {
              type: "audio",
              component: AudioControl,
            },
          ],
        ]}
      />
    );
  }
}

Custom Node Plugin

import * as React from "react";
import { AST } from "parse5";

const plugin = {
  type: "node", // node, mark
  object: "inline",
  nodeType: "super-audio",
  importer(el: AST.Default.Element, next: Function): any {
    if (el.tagName.toLowerCase() === "audio") {
      return {
        object: "inline", // block、inline,
        type: "super-audio",
        isVoid: true,
        data: {
          src: el?.attrs?.find((n) => n.name === "src")?.value,
        },
        nodes: next(el.childNodes),
      };
    }
  },
  exporter(node: any, children: any): any {
    let { className, src } = node.data.toJS();
    return <audio src={src} className={className}></audio>;
  },
  render(
    editor: any,
    props: { attributes: any; children: any; node: any; isSelected: any }
  ): any {
    // @ts-ignore
    const { attributes, children, node, isSelected } = props;
    const src = node.data.get("src");
    return (
      <span {...attributes}>
        <audio src={src} controls>
          {children}
        </audio>
      </span>
    );
  },
};

export default plugin;

License

Apache 2.0

easy-editor's People

Contributors

imal1 avatar kanweiwei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

easy-editor's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.