diff --git a/README.md b/README.md
index d753626ec..a26029252 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
[](https://cdnjs.com/libraries/grapesjs)
[](https://www.npmjs.com/package/grapesjs)
+> If you looking to embed the [Studio](https://app.grapesjs.com/studio) editor in your application, we now offer the [Studio SDK](https://app.grapesjs.com/dashboard/sdk/licenses?ref=repo-readme), a ready-to-use visual builder that's easy to embed in external applications, with GrapesJS team support included.

diff --git a/src/dom_components/model/types.ts b/src/dom_components/model/types.ts
index 860d886f3..4a603f125 100644
--- a/src/dom_components/model/types.ts
+++ b/src/dom_components/model/types.ts
@@ -18,12 +18,12 @@ export type DraggableDroppableFn = (source: Component, target: Component, index?
export interface AddComponentsOption extends AddOptions, OptionAsDocument {}
-interface ComponentWithCheck{
+interface ComponentWithCheck {
new (props: any, opt: ComponentOptions): C;
- isComponent(node: HTMLElement, opts?: ParseNodeOptions): ComponentDefinitionDefined|undefined|boolean;
+ isComponent(node: HTMLElement, opts?: ParseNodeOptions): ComponentDefinitionDefined | undefined | boolean;
}
-export interface ComponentStackItem = ComponentView>{
+export interface ComponentStackItem = ComponentView> {
id: string;
model: ComponentWithCheck;
view: new (opt: any) => CV;
@@ -65,6 +65,14 @@ export interface ComponentDelegateProps {
* }
*/
select?: (cmp: Component) => Component | Nullable;
+ /**
+ * Delegate another component as a layer in the LayerManager.
+ * @example
+ * delegate: {
+ * layer: (cmp) => cmp.findType('other-type')[0],
+ * }
+ */
+ layer?: (cmp: Component) => Component | Nullable;
}
export interface ComponentProperties {
diff --git a/src/navigator/index.ts b/src/navigator/index.ts
index 38ffa2d5a..38b557291 100644
--- a/src/navigator/index.ts
+++ b/src/navigator/index.ts
@@ -127,9 +127,10 @@ export default class LayerManager extends Module {
root = wrapper.find(component)[0] || wrapper;
}
- this.model.set('root', root);
+ const result = this.__getLayerFromComponent(root);
+ this.model.set('root', result);
- return root;
+ return result;
}
/**
@@ -152,7 +153,10 @@ export default class LayerManager extends Module {
* console.log(components);
*/
getComponents(component: Component): Component[] {
- return component.components().filter((cmp: any) => this.__isLayerable(cmp));
+ return component
+ .components()
+ .map(cmp => this.__getLayerFromComponent(cmp))
+ .filter((cmp: any) => this.__isLayerable(cmp));
}
/**
@@ -360,12 +364,16 @@ export default class LayerManager extends Module {
this.__trgCustom();
}
+ __getLayerFromComponent(cmp: Component) {
+ return cmp.delegate?.layer?.(cmp) || cmp;
+ }
+
__onComponent(component: Component) {
this.updateLayer(component);
}
__isLayerable(cmp: Component): boolean {
- const tag = cmp.get('tagName');
+ const tag = cmp.tagName;
const hideText = this.config.hideTextnode;
const isValid = !hideText || (!cmp.isInstanceOf('textnode') && tag !== 'br');
diff --git a/src/navigator/view/ItemsView.ts b/src/navigator/view/ItemsView.ts
index ed1a28148..de2fc400f 100644
--- a/src/navigator/view/ItemsView.ts
+++ b/src/navigator/view/ItemsView.ts
@@ -4,12 +4,14 @@ import Component from '../../dom_components/model/Component';
import EditorModel from '../../editor/model/Editor';
import ItemView from './ItemView';
import Components from '../../dom_components/model/Components';
+import LayerManager from '..';
export default class ItemsView extends View {
items: ItemView[];
opt: any;
config: any;
parentView: ItemView;
+ module: LayerManager;
/** @ts-ignore */
collection!: Components;
@@ -19,6 +21,7 @@ export default class ItemsView extends View {
this.opt = opt;
const config = opt.config || {};
this.config = config;
+ this.module = opt.module;
this.parentView = opt.parentView;
const pfx = config.stylePrefix || '';
const ppfx = config.pStylePrefix || '';
@@ -128,10 +131,10 @@ export default class ItemsView extends View {
}
render() {
+ const { el, module } = this;
const frag = document.createDocumentFragment();
- const el = this.el;
el.innerHTML = '';
- this.collection.each(model => this.addToCollection(model, frag));
+ this.collection.map(cmp => module.__getLayerFromComponent(cmp)).forEach(model => this.addToCollection(model, frag));
el.appendChild(frag);
el.className = this.className!;
return this;