diff --git a/packages/core/src/canvas/view/CanvasView.ts b/packages/core/src/canvas/view/CanvasView.ts index dc0e0ce63..57490fe52 100644 --- a/packages/core/src/canvas/view/CanvasView.ts +++ b/packages/core/src/canvas/view/CanvasView.ts @@ -322,7 +322,7 @@ export default class CanvasView extends ModuleView { const canvasWorldHeight = canvasHeight * zoomMltp; const canvasHeightDiff = canvasWorldHeight - canvasHeight; const yDelta = canvasHeightDiff / 2; - coords.y = (-boxRect.y + gapY) * zoomRatio - yDelta / zoomMltp; + coords.y = (-boxRect.y + gapY) * zoomMltp - yDelta / zoomMltp; } module.setCoords(coords.x, coords.y); @@ -619,10 +619,10 @@ export default class CanvasView extends ModuleView { // #873 Adding setTimeout will make js components work on init of the editor setTimeout(() => { - component.emitWithEitor(ComponentsEvents.scriptMountBefore, dataToEmit); + component.emitWithEditor(ComponentsEvents.scriptMountBefore, dataToEmit); const scr = view.scriptContainer; scr?.appendChild(script); - component.emitWithEitor(ComponentsEvents.scriptMount, dataToEmit); + component.emitWithEditor(ComponentsEvents.scriptMount, dataToEmit); }, 0); } diff --git a/packages/core/src/dom_components/model/Component.ts b/packages/core/src/dom_components/model/Component.ts index c16b96b68..62eb0f5e3 100644 --- a/packages/core/src/dom_components/model/Component.ts +++ b/packages/core/src/dom_components/model/Component.ts @@ -1770,8 +1770,8 @@ export default class Component extends StyleableModel { }); } - emitWithEitor(event: string, data?: Record) { - [this.em, this].forEach((item) => item?.trigger(event, data)); + emitWithEditor(event: string, data?: Record, extra?: Record) { + [this.em, this].forEach((item) => item?.trigger(event, data, extra)); } /** diff --git a/packages/core/src/dom_components/model/Components.ts b/packages/core/src/dom_components/model/Components.ts index 892b1d6c2..932e78fc8 100644 --- a/packages/core/src/dom_components/model/Components.ts +++ b/packages/core/src/dom_components/model/Components.ts @@ -202,7 +202,7 @@ Component> { em.Commands.run('core:component-style-clear', { target: removed }); removed.views.forEach((view) => { view.scriptContainer && - removed.emitWithEitor(ComponentsEvents.scriptUnmount, { component: removed, view, el: view.el }); + removed.emitWithEditor(ComponentsEvents.scriptUnmount, { component: removed, view, el: view.el }); }); removed.removed(); removed.trigger('removed'); @@ -226,6 +226,14 @@ Component> { em.stopListening(removed); em.stopListening(removed.get('classes')); removed.__postRemove(); + + if (!removed.opt.temporary) { + const triggerRemoved = (cmp: Component) => { + cmp.emitWithEditor(ComponentsEvents.removed, cmp, { removeOptions: opts }); + cmp.components().forEach((cmp) => triggerRemoved(cmp)); + }; + triggerRemoved(removed); + } } /** @ts-ignore */ diff --git a/packages/core/src/dom_components/types.ts b/packages/core/src/dom_components/types.ts index 2af662023..e3b87a563 100644 --- a/packages/core/src/dom_components/types.ts +++ b/packages/core/src/dom_components/types.ts @@ -36,6 +36,7 @@ export enum ComponentsEvents { */ remove = 'component:remove', removeBefore = 'component:remove:before', + removed = 'component:removed', /** * @event `component:create` Component created. @@ -75,6 +76,13 @@ export enum ComponentsEvents { */ scriptUnmount = 'component:script:unmount', + /** + * @event `component:render` Component rendered in the canvas. This event could be triggered multiple times for the same component (eg. undo/redo, explicit rerender). + * @example + * editor.on('component:render', ({ component, view, el }) => { ... }); + */ + render = 'component:render', + /** * @event `symbol:main:add` Added new main symbol. * @example diff --git a/packages/core/src/dom_components/view/ComponentView.ts b/packages/core/src/dom_components/view/ComponentView.ts index d524f1ee5..c374f6a1c 100644 --- a/packages/core/src/dom_components/view/ComponentView.ts +++ b/packages/core/src/dom_components/view/ComponentView.ts @@ -518,7 +518,7 @@ TComp> { reset() { const view = this; const { el, model } = view; - view.scriptContainer && model.emitWithEitor(ComponentsEvents.scriptUnmount, { component: model, view, el }); + view.scriptContainer && model.emitWithEditor(ComponentsEvents.scriptUnmount, { component: model, view, el }); // @ts-ignore this.el = ''; this._ensureElement(); @@ -583,7 +583,13 @@ TComp> { postRender() { if (!this.modelOpt.temporary) { + const { model, el } = this; this.onRender(this._clbObj()); + model.emitWithEditor(ComponentsEvents.render, { + component: model, + view: this, + el, + }); } }