diff --git a/packages/core/src/dom_components/model/Components.ts b/packages/core/src/dom_components/model/Components.ts index 190d3c2bb..5e77970c6 100644 --- a/packages/core/src/dom_components/model/Components.ts +++ b/packages/core/src/dom_components/model/Components.ts @@ -210,6 +210,7 @@ Component> { sels.remove(rulesRemoved.map((rule) => rule.getSelectors().at(0))); if (!removed.opt.temporary) { + em.removeSelected(removed); em.Commands.run('core:component-style-clear', { target: removed }); removed.views.forEach((view) => { view.scriptContainer && diff --git a/packages/core/test/specs/editor/index.ts b/packages/core/test/specs/editor/index.ts index eac0baf31..cd22608c3 100644 --- a/packages/core/test/specs/editor/index.ts +++ b/packages/core/test/specs/editor/index.ts @@ -165,6 +165,50 @@ describe('Editor', () => { expect(editor.getSelectedAll().length).toBe(0); }); + test('Removing a selected component removes it from the selection', () => { + const wrapper = editor.getWrapper()!; + const added = wrapper.append('
Component 1
'); + editor.select(added[0]); + expect(editor.getSelectedAll().length).toBe(1); + + added[0].remove(); + expect(editor.getSelectedAll().length).toBe(0); + }); + + test('Replacing a selected component removes it from the selection', () => { + const wrapper = editor.getWrapper()!; + const added = wrapper.append('
Component 1
'); + editor.select(added[0]); + + added[0].replaceWith('Replacement'); + expect(editor.getSelectedAll().length).toBe(0); + }); + + test('Undo after replaceWith inside component:selected restores content without orphan selection', () => { + const um = editor.UndoManager; + const wrapper = editor.getWrapper()!; + wrapper.append('
A
B
'); + um.clear(); + + let replaced = false; + editor.on('component:selected', (cmp) => { + if (replaced) return; + replaced = true; + cmp.replaceWith('C'); + }); + + editor.select(wrapper.components().at(0)); + expect(replaced).toBe(true); + expect(wrapper.getInnerHTML()).toBe('C
B
'); + + um.undo(); + expect(wrapper.getInnerHTML()).toBe('
A
B
'); + // Whatever selection the undo restored must reference components still in the tree + editor.getSelectedAll().forEach((cmp) => { + expect(cmp.parent()).toBeTruthy(); + }); + }); + test.skip('Shift key selecting a component that is being edited should not clear any text selections', () => { const all = editor.Components.allById(); const em = editor.em;