diff --git a/src/commands/view/ComponentDelete.ts b/src/commands/view/ComponentDelete.ts index 46233f73b..a8d9cff6c 100644 --- a/src/commands/view/ComponentDelete.ts +++ b/src/commands/view/ComponentDelete.ts @@ -15,7 +15,8 @@ const command: CommandObject<{ component?: Component }> = { component, }); } - component.remove(); + const cmp = component.delegate?.remove?.(component) || component; + cmp.remove(); }); ed.select(toSelect); diff --git a/src/commands/view/DeleteComponent.ts b/src/commands/view/DeleteComponent.ts deleted file mode 100644 index 3497fa92b..000000000 --- a/src/commands/view/DeleteComponent.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { bindAll, extend } from 'underscore'; -import { $ } from '../../common'; -import Component from '../../dom_components/model/Component'; -import { CommandObject } from './CommandAbstract'; -import SelectComponent from './SelectComponent'; - -export default extend({}, SelectComponent, { - init() { - bindAll(this, 'startDelete', 'stopDelete', 'onDelete'); - this.hoverClass = this.pfx + 'hover-delete'; - this.badgeClass = this.pfx + 'badge-red'; - }, - - enable() { - var that = this; - this.$el.find('*').mouseover(this.startDelete).mouseout(this.stopDelete).click(this.onDelete); - }, - - /** - * Start command - * @param {Object} e - * @private - */ - startDelete(e: any) { - e.stopPropagation(); - var $this = $(e.target); - - // Show badge if possible - if ($this.data('model').get('removable')) { - $this.addClass(this.hoverClass); - this.attachBadge($this.get(0)); - } - }, - - /** - * Stop command - * @param {Object} e - * @private - */ - stopDelete(e: any) { - e.stopPropagation(); - var $this = $(e.target); - $this.removeClass(this.hoverClass); - - // Hide badge if possible - if (this.badge) this.badge.css({ left: -1000, top: -1000 }); - }, - - /** - * Delete command - * @param {Object} e - * @private - */ - onDelete(e: any) { - e.stopPropagation(); - var $this = $(e.target); - - // Do nothing in case can't remove - if (!$this.data('model').get('removable')) return; - - $this.data('model').destroy(); - this.removeBadge(); - this.clean(); - }, - - /** - * Updates badge label - * @param {Object} model - * @private - * */ - updateBadgeLabel(model: Component) { - this.badge.html('Remove ' + model.getName()); - }, -} as CommandObject<{}, { [k: string]: any }>); diff --git a/src/common/index.ts b/src/common/index.ts index a8780b822..d44186854 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -19,6 +19,8 @@ export type ObjectAny = Record; export type ObjectStrings = Record; +export type Nullable = undefined | null | false; + // https://github.com/microsoft/TypeScript/issues/29729#issuecomment-1483854699 export type LiteralUnion = T | (U & NOOP); diff --git a/src/dom_components/model/Component.ts b/src/dom_components/model/Component.ts index c2a43c915..dd4c7854f 100644 --- a/src/dom_components/model/Component.ts +++ b/src/dom_components/model/Component.ts @@ -154,6 +154,7 @@ export default class Component extends StyleableModel { propagate: '', dmode: '', toolbar: null, + delegate: null, [keySymbol]: 0, [keySymbols]: 0, [keySymbolOvrd]: 0, @@ -182,6 +183,10 @@ export default class Component extends StyleableModel { return this.get('resizable')!; } + get delegate() { + return this.get('delegate'); + } + /** * Hook method, called once the model is created */ diff --git a/src/dom_components/model/types.ts b/src/dom_components/model/types.ts index cb986ae53..195c7dd20 100644 --- a/src/dom_components/model/types.ts +++ b/src/dom_components/model/types.ts @@ -1,4 +1,5 @@ import Frame from '../../canvas/model/Frame'; +import { Nullable } from '../../common'; import EditorModel from '../../editor/model/Editor'; import Selectors from '../../selector_manager/model/Selectors'; import { TraitProperties } from '../../trait_manager/model/Trait'; @@ -13,6 +14,10 @@ export type DragMode = 'translate' | 'absolute' | ''; export type DraggableDroppableFn = (source: Component, target: Component, index?: number) => boolean | void; +export interface ComponentDelegateProps { + remove?: (cmp: Component) => Component | Nullable; +} + export interface ComponentProperties { /** * Component type, eg. `text`, `image`, `video`, etc. @@ -167,6 +172,11 @@ export interface ComponentProperties { * By default, when `toolbar` property is falsy the editor will add automatically commands `core:component-exit` (select parent component, added if there is one), `tlb-move` (added if `draggable`) , `tlb-clone` (added if `copyable`), `tlb-delete` (added if `removable`). */ toolbar?: ToolbarButtonProps[]; + + /** + * Delegate actions to other components. + */ + delegate?: ComponentDelegateProps; ///** // * Children components. Default: `null` // */