codex-team / editor.js

A block-style editor with clean JSON output
https://editorjs.io
Apache License 2.0
28.45k stars 2.07k forks source link

Divide blocks into container blocks and leaf blocks #803

Closed LinFeng1997 closed 4 years ago

LinFeng1997 commented 5 years ago

Editor.js is an awesome project, both in design and implementation.

But I need to nesting a block in other block.

So I hope that you can divide blocks into container blocks and leaf blocks.

emredipi commented 5 years ago

Exactly, that's what I need too. The editor needs to have bootstrap "row" and "col" structure. (This is just example of course. In fact, it will be children-parent-sibling relationship in json)

LinFeng1997 commented 5 years ago

@emredipi Yes!Such as Insert a Image to a paragraph.

n0str commented 5 years ago

You can create your own tool for a paragraph with a nested image. EditorJS allows that

tom-sherman commented 5 years ago

I'm trying to create a general nested block plugin, would the best way to this be to nest instances of Editor instances?

So if I wanted a two column layout block for example, my tool could spawn two new Editor instances and place them side by side?

enes-sahin commented 5 years ago

So if I wanted a two column layout block for example, my tool could spawn two new Editor instances and place them side by side?

@tom-sherman I think multiple Editor instances is not very effective for two column layout. Maybe you could try column-count property in CSS.

column-count

tom-sherman commented 5 years ago

@enes-sahin This doesn't support the experience I'm after. I'm building a Squarespace-like layout builder, where I can configure rows and columns.

Is there some other solution I'm missing?

enes-sahin commented 5 years ago

@tom-sherman What i undestand from your comment is that you try to create page builder/layout builder like popular layout plugins used especially in wordpress.

First thing that comes to mind is that create your own tool and create new type field in Block data

const editor = new EditorJs({ 
  tools: { 
   row: Row, 
   column: Column 
  }, 
})

Output will be like :

{
   "time": 1550476186479,
   "blocks": [
      {
         "type": "row",
         "data": {
            "text": "",
         }
      },
      {
         "type": "column",
         "data": {
            "text": "Some text"
         }
      },
      {
         "type": "column",
         "data": {
            "text": "Some text",
         }
      }
   ],
   "version": "2.8.1"
}

But the problem is that there is no unique id for blocks, so It is very difficult to determine which column/row is related to another column/row.

Issues about unique id for blocks https://github.com/codex-team/editor.js/issues/727 and https://github.com/codex-team/editor.js/issues/873

As for nesting, i am not sure if it is allowed in Editor.js or not. Maybe you can use multiple instances but for every row/column/etc, but it would be difficult to maintain.

tom-sherman commented 5 years ago

I think my issue is that you can't nest editors I think. I've tried to instantiate new editors inside of a blocks render method but I run into issues. While the nested editors seem to render correctly, as soon as you interact with them there are all kinds of errors thrown in the console.

Here's my attempt at creating a block that contains two editors inside. My hopes were to allow adding more columns/editors by using +/- buttons in the block settings.

export class Row {
  static get toolbox() {
    return {
    title: 'Row',
      icon: '<svg width="17" height="15" viewBox="0 0 336 276" xmlns="http://www.w3.org/2000/svg"><path d="M291 150V79c0-19-15-34-34-34H79c-19 0-34 15-34 34v42l67-44 81 72 56-29 42 30zm0 52l-43-30-56 30-81-67-66 39v23c0 19 15 34 34 34h178c17 0 31-13 34-29zM79 0h178c44 0 79 35 79 79v118c0 44-35 79-79 79H79c-44 0-79-35-79-79V79C0 35 35 0 79 0z"/></svg>'
    }
  }

  renderSettings () {
    const wrapper = document.createElement('div')

    const addButton = document.createElement('button')
    addButton.classList.add('cds-settings-button')
    addButton.innerText = '+'
    wrapper.appendChild(addButton)

    const removeButton = document.createElement('button')
    removeButton.classList.add('cds-settings-button')
    removeButton.innerText = '-'
    wrapper.appendChild(removeButton)

    addButton.addEventListener('click', () => this.api.insert(''))

    return wrapper
  }

  render () {
    const wrapper = document.createElement('div')
    const editorEl1 = document.createElement('div')
    editorEl1.className = 'inner-editor'
    wrapper.appendChild(editorEl1)

    new EditorJS({
      holder: editorEl1
    })
    return wrapper
  }

  save () {
    return {}
  }
}

It would be great to get some thoughts from the Codex Team as to whether this feature is something they think would add value, I would like to help implement it if so.

It feels like allowing nested Editors would be the easiest thing to do and would offer the greatest flexibility.

matias-miranda commented 5 years ago

hey @tom-sherman were you able to do it, I'm facing the exactly same scenario

tom-sherman commented 5 years ago

@matias-miranda unfortunately not, I ended up going with a different library (GrapesJS) as the base for the application I'm building.

hata6502 commented 4 years ago

I want to nest EditorJS, too. I developed editor-js-grid to resolve it.

https://www.npmjs.com/package/editor-js-grid

But EditorJS can't be nested in EditorJS. Because operations don't work correctly.

gohabereg commented 4 years ago

https://github.com/codex-team/editor.js/pull/1055#issuecomment-664018031

hata6502 commented 3 years ago

editor-js-grid is revived as editorjs-layout! See: https://github.com/hata6502/editorjs-layout