From 976153efaae1bbefd5006a334ce6b4c9f1cab174 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Mon, 27 Sep 2021 12:15:26 +0200 Subject: [PATCH] Refactor blocks open --- docs/modules/Blocks.md | 30 ++++++++++++++++++++ src/block_manager/config/config.js | 6 +++- src/block_manager/index.js | 34 +++++++++++++++++----- src/commands/view/OpenBlocks.js | 45 ++++++++++++++++++++++-------- 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/docs/modules/Blocks.md b/docs/modules/Blocks.md index 6b59e5b64..8cbe28008 100644 --- a/docs/modules/Blocks.md +++ b/docs/modules/Blocks.md @@ -299,6 +299,36 @@ To know more about the available block properties, check the [Block API Referenc +## Customization +The default Block Manager UI is great for simple things, but except the possibility to tweak some CSS style, adding more complex elements requires a replace of the defualt UI. + +All you have to do is to indicate the editor your intent to use a custom UI and then subscribe to the `block:custom` event that will give you all the information on any requested change. + +```js +const editor = grapesjs.init({ + // ... + blockManager: { + // ... + custom: true, + }, +}); + +editor.on('block:custom', props => { + // The `props` will contain all the information you need in order to update your UI. + // props.open (boolean) - Indicates if the Asset Manager is open + // props.assets (Array) - Array of all assets + // props.types (Array) - Array of asset types requested, eg. ['image'], + // props.close (Function) - A callback to close the Asset Manager + // props.remove (Function) - A callback to remove an asset + // props.select (Function) - A callback to select an asset + // props.container (HTMLElement) - The element where you should append your UI + + // Here you would put the logic to render/update your UI. +}); +``` + + + ## Events For a complete list of available events, you can check it [here](/api/block_manager.html#available-events). diff --git a/src/block_manager/config/config.js b/src/block_manager/config/config.js index 2c96bb49e..c88adb5e7 100644 --- a/src/block_manager/config/config.js +++ b/src/block_manager/config/config.js @@ -16,5 +16,9 @@ export default { // } appendOnClick: false, - blocks: [] + // Default blocks + blocks: [], + + // Avoid rendering the default block manager. + custom: false }; diff --git a/src/block_manager/index.js b/src/block_manager/index.js index 8382b25ee..1d529b318 100644 --- a/src/block_manager/index.js +++ b/src/block_manager/index.js @@ -57,9 +57,7 @@ export const evAdd = `${evPfx}add`; export const evUpdate = `${evPfx}update`; export const evRemove = `${evPfx}remove`; export const evRemoveBefore = `${evRemove}:before`; -// export const evCustom = `${evPfx}custom`; -// export const evOpen = `${evPfx}open`; -// export const evClose = `${evPfx}close`; +export const evCustom = `${evPfx}custom`; export default () => { var c = {}; @@ -84,10 +82,8 @@ export default () => { update: evUpdate, add: evAdd, remove: evRemove, - removeBefore: evRemoveBefore - // custom: evCustom, - // open: evOpen, - // close: evClose + removeBefore: evRemoveBefore, + custom: evCustom }, init(config = {}) { @@ -110,6 +106,30 @@ export default () => { return this; }, + __trgCustom() { + this.em.trigger(this.events.custom, this.__customData()); + }, + + __customData() { + const bhv = this.__getBehaviour(); + return { + bm: this, + blocks: this.getAll().models, + container: bhv.container + }; + }, + + __behaviour(opts = {}) { + return (this._bhv = { + ...(this._bhv || {}), + ...opts + }); + }, + + __getBehaviour() { + return this._bhv || {}; + }, + /** * Get configuration object * @return {Object} diff --git a/src/commands/view/OpenBlocks.js b/src/commands/view/OpenBlocks.js index a1758c64b..f1a049030 100644 --- a/src/commands/view/OpenBlocks.js +++ b/src/commands/view/OpenBlocks.js @@ -1,23 +1,44 @@ +import { createEl } from '../../utils/dom'; + export default { - run(editor, sender) { - const bm = editor.BlockManager; - const pn = editor.Panels; + open() { + const { container, editor, bm } = this; - if (!this.blocks) { - bm.render(); + if (this.firstRender) { const id = 'views-container'; - const blocks = document.createElement('div'); + const pn = editor.Panels; const panels = pn.getPanel(id) || pn.addPanel({ id }); - blocks.appendChild(bm.getContainer()); - panels.set('appendContent', blocks).trigger('change:appendContent'); - this.blocks = blocks; + panels.set('appendContent', container).trigger('change:appendContent'); + if (!bm.getConfig().custom) container.appendChild(bm.render()); + } + + if (container) container.style.display = 'block'; + }, + + close() { + const { container } = this; + if (container) container.style.display = 'none'; + }, + + run(editor, sender) { + const bm = editor.Blocks; + this.firstRender = !this.container; + this.container = this.container || createEl('div'); + this.editor = editor; + this.bm = bm; + const { container } = this; + bm.__behaviour({ + container + }); + + if (bm.getConfig().custom) { + bm.__trgCustom(); } - this.blocks.style.display = 'block'; + this.open(); }, stop() { - const blocks = this.blocks; - blocks && (blocks.style.display = 'none'); + this.close(); } };