0.0.3 • Published 2 years ago

pure-editor v0.0.3

Weekly downloads
-
License
-
Repository
-
Last release
2 years ago

PureEditor | 中文文档

example

PureEditor is pure text editor, 'pure' means the childNodes of the editor are only pure text and buildin components. so it is used for chat box, comment box or something like that.

  • light-weight, only 200 lines code, without any dependences .

  • fully featured, support @, user fuzzy finding, emoji, picture, file, link...

  • 100% customizable, every parts of ui accept a render function.

  • 0 constraints, PureEditor has no contraints for data format, you can use it in any system without adaptation codes.

this result of PureEditor is structured, fully-messaged array, you can translate it to anything you want(html, template string), this is a standard example:

[
  'I send a',
  {type: 'emoji', name: 'smile'},
  'and will',
  {type: 'at', name: 'lucy'}
]

the data format of the item(except text) is upto you, ervey entity's data format will be consistent with the incoming(it's recommanded every entity include a type propertity for distinguish them). the machanism is simple, PureEditor just set the element's dataset with the data you give, and return the dataset of it to you when submit:

// render flow
render(data) --> element -> element.dataset = data --> append(element)

// parse flow
element --> element.nodeName === '#text' ? element.textContent : element.dataset

Install

npm i 'pure-editor'

there are only three files in the src, so you can copy them either for free modification .

Use

import Editor from 'pure-editor'

const editor =  new PureEditor(target, config)

target

target should be html pre element to make \n and series blank spaceies rendered normally.

why not generate it internally ? to leave the full ability for you to control it, for example, you can offer extra features directly:

colorBtn.onclick = color => pre.style.color = color
fontBtn.onclick = fontFamily => pre.style.fontFamily = fontFamily

config

export interface Config {
  submit?: {
    will(e: KeyboardEvent): boolean
    done(values: Array<string | object>): void
  }
  at: {
    find(keyword: string): Promise<object[]>
    render: {
      list(): HTMLElement
      item(user: object): HTMLElement
    }
  }
  emoji: {
    render(emoji: object): HTMLElement
  }
  file: {
    upload(file: File): Promise<object>
    render(fileResult: object): HTMLElement
  }
  reply: {
    render(reply: object): HTMLElement
  }
}

submit

this submit trigger setting, if you needn't this, just ignore it and get the result by the instance method submit

  • will(e: KeyboardEvent): boolean: if it return true, PureEditor will trigger submit immediately. example: will: e => e.key === 'Enter'

  • done(values: Array<string | object>): void: the submit callback function. example: done: console.log.

at

  • find(keyword: string): Promise<object[]>: the fuzzy finding function of users, will be triggered when people input @. why is it aync? for users may be thousands. if you needn't this, just return a sync list. for example: async find: () => [user1, user2].

  • render.list(): HTMLElement: the float user list , PureEditor will set it's position be fixed, all you need is set it's style, be sure to give it a specific width, example: width: 120px.

  • render.item(user):HTMLElement: then render function of user, then element will be appended to the list, you should set it's innerText to be the user's name .

PureEditor does not care what the user's format is, it just return the same format as it is. for example, if the find function return the value [{type:'user',id:'1', name: 'Susan'}], the item in the result will be {type:'user',id:'1', name: 'Susan'} if people @ Susan. other entities follow the same pattern.

emoji

  • render(emoji: object): HTMLElement: the render function of emoji. PureEditor will insert the return element to the box.

file

  • upload(file: File): Promise<object>: when paste a picture, or when the instance method insertFile be called, PureEditor will call this function to upload the file.

  • render(fileResult: object): HTMLElement: after upload, PureEditor will call this function with the upload result, and then insert the return element to end of the box .

reply

  • render(reply: object): HTMLElement: the render function of reply data, PureEditor will insert the return Element to the start of the box. one message can have only one reply, if you insert another, it will repalce the old one.

Instance Methods

  • insertEmoji(emoji): insert emoji
  • insertFile(file): insert file
  • insertReply(reply): insert replay
  • submit: return the values and clear the box
  • getValues: submit will clear the box ,whitch behaver is not suitable for debug, this method only return the values.

Full Example

const editor = new Editor(document.getElementById('app'), {
  at: {
    async find(keyword) {
      return [
        { type: 'user', id: 1, name: `${keyword}Susan` },
        { type: 'user', id: 2, name: `${keyword}Catherine` },
      ]
    },
    render: {
      list() {
        const el = document.createElement('div')
        el.className = 'at-list'
        return el
      },
      item(user) {
        const item = document.createElement('div')
        item.className = 'at-item'
        item.innerText = user.name
        return item
      },
    },
  },
  emoji: {
    render(emoji) {
      const img = document.createElement('img')
      img.className = 'emoji'
      img.src = '/smile.png'
      return img
    },
  },
  reply: {
    render(reply) {
      const div = document.createElement('div')
      div.innerText = 'reply to...'
      div.className = 'block'
      return div
    },
  },
  file: {
    async upload(file) {
      return {
        type: 'file',
        contentType: 'zip',
      }
    },
    render(fileResult) {
      const div = document.createElement('div')
      div.innerText = 'a file...'
      div.className = 'block'
      return div
    },
  },
  submit: {
    will: e => e.key === 'Enter' && e.ctrlKey,
    done: console.log,
  },
})

emoji.onclick = () => editor.insertEmoji({ type: 'emoji', name: 'smile' })
reply.onclick = () => editor.insertReply({ type: 'reply', to: 'foo' })
file.onclick = () => editor.insertFile({name: 'file.zip'})
submit.onclick = () => console.log(editor.submit())

Attention

PureEditor has no toolbar and any default ui, you should give it every render function, this is for leave the full ability to you to controll them(or just because I'm lazy?). any thing I may help, submit an issue.