From dcb19c0f11fb4f76449aeffd32d02c832733a2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Fri, 18 Mar 2022 17:21:51 +0100 Subject: [PATCH] MOBILE-3814 collapsible: Recalculate Height when slotted --- src/core/directives/collapsible-footer.ts | 4 ++ src/core/services/utils/dom.ts | 47 +++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/core/directives/collapsible-footer.ts b/src/core/directives/collapsible-footer.ts index e041fa096..57f24d707 100644 --- a/src/core/directives/collapsible-footer.ts +++ b/src/core/directives/collapsible-footer.ts @@ -72,6 +72,10 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy { await this.calculateHeight(); + CoreDomUtils.onElementSlot(this.element, () => { + this.calculateHeight(); + }); + this.listenScrollEvents(); } diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index 2df0fcfc1..88215d904 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -220,6 +220,53 @@ export class CoreDomUtilsProvider { ); } + /** + * Runs a function when an element has been slotted. + * + * @param element HTML Element inside an ion-content to wait for slot. + * @param callback Function to execute on resize. + */ + onElementSlot(element: HTMLElement, callback: (ev?: Event) => void): void { + if (!element.slot) { + // Element not declared to be slotted. + return; + } + + const slotName = element.slot; + if (element.assignedSlot?.name === slotName) { + // Slot already assigned. + callback(); + + return; + } + + const content = element.closest('ion-content'); + if (!content || !content.shadowRoot) { + // Cannot find content. + return; + } + + const slots = content.shadowRoot.querySelectorAll('slot'); + const slot = Array.from(slots).find((slot) => slot.name === slotName); + + if (!slot) { + // Slot not found. + return; + } + + const slotListener = () => { + if (element.assignedSlot?.name !== slotName) { + return; + } + + callback(); + // It would happen only once. + slot.removeEventListener('slotchange', slotListener); + }; + + slot.addEventListener('slotchange', slotListener);; + } + /** * Window resize is widely checked and may have many performance issues, debouce usage is needed to avoid calling it too much. * This function helps setting up the debounce feature and remove listener easily.