Skip to content

Commit 5824b3a

Browse files
committed
fix(content): detect header/footer wrapped in custom components
1 parent fc49604 commit 5824b3a

1 file changed

Lines changed: 30 additions & 0 deletions

File tree

core/src/components/content/content.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,27 @@ export class Content implements ComponentInterface {
183183
/**
184184
* Detects sibling ion-header and ion-footer elements.
185185
* When these are absent, content needs to handle safe-area padding directly.
186+
*
187+
* Checks both direct siblings and elements wrapped in custom components
188+
* (e.g., <my-header><ion-header>...</ion-header></my-header>).
186189
*/
187190
private detectSiblingElements() {
188191
// Check parent element for sibling header/footer.
189192
const parent = this.el.parentElement;
190193
if (parent) {
194+
// First check for direct ion-header/ion-footer siblings
191195
this.hasHeader = parent.querySelector(':scope > ion-header') !== null;
192196
this.hasFooter = parent.querySelector(':scope > ion-footer') !== null;
197+
198+
// If not found as direct siblings, check if any sibling contains them.
199+
// This handles cases where header/footer are wrapped in custom components
200+
// (common in React, Vue, Angular component-based architectures).
201+
if (!this.hasHeader) {
202+
this.hasHeader = this.siblingContainsElement(parent, 'ion-header');
203+
}
204+
if (!this.hasFooter) {
205+
this.hasFooter = this.siblingContainsElement(parent, 'ion-footer');
206+
}
193207
}
194208

195209
// If no footer found, check if we're inside ion-tabs which has ion-tab-bar
@@ -201,6 +215,22 @@ export class Content implements ComponentInterface {
201215
}
202216
}
203217

218+
/**
219+
* Checks if any sibling element of ion-content contains the specified element.
220+
* Only searches one level deep to avoid finding elements in nested pages.
221+
*/
222+
private siblingContainsElement(parent: Element, tagName: string): boolean {
223+
for (const sibling of parent.children) {
224+
// Skip ion-content itself
225+
if (sibling === this.el) continue;
226+
// Check if this sibling contains the target element as an immediate child
227+
if (sibling.querySelector(`:scope > ${tagName}`) !== null) {
228+
return true;
229+
}
230+
}
231+
return false;
232+
}
233+
204234
disconnectedCallback() {
205235
this.onScrollEnd();
206236

0 commit comments

Comments
 (0)