diff --git a/packages/crud/src/vaadin-crud.js b/packages/crud/src/vaadin-crud.js index fc9beb0818..f736981fe1 100644 --- a/packages/crud/src/vaadin-crud.js +++ b/packages/crud/src/vaadin-crud.js @@ -820,14 +820,15 @@ class Crud extends ControllerMixin(ElementMixin(ThemableMixin(PolymerElement))) /** @private */ __moveChildNodes(target) { - const nodes = [this._headerNode, this._form, this._saveButton, this._cancelButton, this._deleteButton]; + const nodes = [this._headerNode, this._form]; + const buttons = [this._saveButton, this._cancelButton, this._deleteButton].filter(Boolean); if (!nodes.every((node) => node instanceof HTMLElement)) { return; } // Teleport header node, form, and the buttons to corresponding slots. // NOTE: order in which buttons are moved matches the order of slots. - nodes.forEach((node) => { + [...nodes, ...buttons].forEach((node) => { target.appendChild(node); }); diff --git a/packages/crud/test/crud-buttons.test.js b/packages/crud/test/crud-buttons.test.js index 57da4eda17..f264e77c2d 100644 --- a/packages/crud/test/crud-buttons.test.js +++ b/packages/crud/test/crud-buttons.test.js @@ -931,6 +931,7 @@ describe('crud buttons', () => { beforeEach(async () => { crud = document.createElement('vaadin-crud'); crud._noDefaultButtons = true; + crud.items = [{ foo: 'bar' }]; document.body.appendChild(crud); await nextRender(); }); @@ -954,6 +955,14 @@ describe('crud buttons', () => { it('should not create default delete-button', () => { expect(crud.querySelector('[slot="delete-button"]')).to.be.null; }); + + it('should teleport form and header when no default buttons set', async () => { + crud.editedItem = { foo: 'baz' }; + await nextRender(); + const overlay = crud.$.dialog.$.overlay; + expect(crud._form.parentElement).to.equal(overlay); + expect(crud._headerNode.parentElement).to.equal(overlay); + }); }); describe('dataProvider', () => {