Skip to content

Commit bb00595

Browse files
authoredNov 2, 2022
fix(overlays): presenting an overlay does not create nested elements (#26154)
Resolves #26117
1 parent 1f7fc8f commit bb00595

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed
 

‎core/src/components/datetime-button/test/basic/datetime-button.e2e.ts

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ test.describe('datetime-button: switching to correct view', () => {
1717
expect(datetime).toHaveJSProperty('presentation', 'date-time');
1818

1919
await page.locator('#date-button').click();
20+
await page.waitForChanges();
2021

2122
expect(datetime).toHaveJSProperty('presentation', 'date');
2223
});
@@ -25,6 +26,7 @@ test.describe('datetime-button: switching to correct view', () => {
2526
expect(datetime).toHaveJSProperty('presentation', 'date-time');
2627

2728
await page.locator('#time-button').click();
29+
await page.waitForChanges();
2830

2931
expect(datetime).toHaveJSProperty('presentation', 'time');
3032
});

‎core/src/components/modal/test/inline/modal.e2e.ts

+40
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,44 @@ test.describe('modal: inline', () => {
2121

2222
expect(await page.screenshot()).toMatchSnapshot(`modal-inline-dismiss-${page.getSnapshotSettings()}.png`);
2323
});
24+
25+
test('presenting should create a single root element with the ion-page class', async ({ page, skip }, testInfo) => {
26+
skip.mode('md');
27+
skip.rtl();
28+
29+
testInfo.annotations.push({
30+
type: 'issue',
31+
description: 'https://github.com/ionic-team/ionic-framework/issues/26117',
32+
});
33+
34+
await page.setContent(`
35+
<ion-datetime-button datetime="datetime"></ion-datetime-button>
36+
37+
<ion-modal>
38+
<ion-datetime id="datetime" presentation="date-time"></ion-datetime>
39+
</ion-modal>
40+
`);
41+
42+
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
43+
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
44+
const modal = page.locator('ion-modal');
45+
46+
await page.locator('#date-button').click();
47+
await ionModalDidPresent.next();
48+
49+
// Verifies that the host element exists with the .ion-page class
50+
expect(await modal.evaluate((el: HTMLIonModalElement) => el.firstElementChild!.className)).toContain('ion-page');
51+
52+
await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
53+
await ionModalDidDismiss.next();
54+
55+
await page.locator('#date-button').click();
56+
await ionModalDidPresent.next();
57+
58+
// Verifies that presenting the overlay again does not create a new host element
59+
expect(await modal.evaluate((el: HTMLIonModalElement) => el.firstElementChild!.className)).toContain('ion-page');
60+
expect(
61+
await modal.evaluate((el: HTMLIonModalElement) => el.firstElementChild!.firstElementChild!.className)
62+
).not.toContain('ion-page');
63+
});
2464
});

‎core/src/utils/framework-delegate.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,22 @@ export const CoreDelegate = () => {
8787

8888
await new Promise((resolve) => componentOnReady(el, resolve));
8989
} else if (BaseComponent.children.length > 0) {
90-
// If there is no component, then we need to create a new parent
91-
// element to apply the css classes to.
92-
const el = BaseComponent.ownerDocument?.createElement('div');
93-
cssClasses.forEach((c) => el.classList.add(c));
94-
// Move each child from the original template to the new parent element.
95-
el.append(...BaseComponent.children);
96-
// Append the new parent element to the original parent element.
97-
BaseComponent.appendChild(el);
90+
const root = BaseComponent.children[0] as HTMLElement;
91+
if (!root.classList.contains('ion-delegate-host')) {
92+
/**
93+
* If the root element is not a delegate host, it means
94+
* that the overlay has not been presented yet and we need
95+
* to create the containing element with the specified classes.
96+
*/
97+
const el = BaseComponent.ownerDocument?.createElement('div');
98+
// Add a class to track if the root element was created by the delegate.
99+
el.classList.add('ion-delegate-host');
100+
cssClasses.forEach((c) => el.classList.add(c));
101+
// Move each child from the original template to the new parent element.
102+
el.append(...BaseComponent.children);
103+
// Append the new parent element to the original parent element.
104+
BaseComponent.appendChild(el);
105+
}
98106
}
99107

100108
/**

0 commit comments

Comments
 (0)
Please sign in to comment.