Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions core/src/components/popover/popover.scss
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@
display: flex;

flex-direction: column;

overflow: hidden;
}

// Nested Popovers
Expand Down
92 changes: 92 additions & 0 deletions core/src/components/popover/test/basic/popover.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,98 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
* Translucent popovers are only available on iOS
*/
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('popover: scrolling'), async () => {
test.beforeEach(({ skip }) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/29211',
});
// We are testing if Ionic sets overflow is set correctly on elements,
// so we do not need to test across browsers
skip.browser('webkit', 'Behavior does not vary across browsers');
skip.browser('firefox', 'Behavior does not vary across browsers');
});
test('should scroll to bottom without IonContent', async ({ page }) => {
await page.setContent(
`
<style>
ion-popover {
--height: 150px;
}
</style>
<ion-popover>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
</ion-popover>
`,
config
);

const popover = page.locator('ion-popover');
const viewport = popover.locator('.popover-viewport');
const p = popover.locator('p');
const lastP = await p.last();

await popover.evaluate((el: HTMLIonPopoverElement) => el.present());

await expect(lastP).not.toBeInViewport();

// hover over viewport and scroll to bottom
await viewport.hover();
await page.mouse.wheel(0, 500);

await expect(lastP).toBeInViewport();
});
test('should scroll to bottom with IonContent', async ({ page }) => {
await page.setContent(
`
<style>
ion-popover {
--height: 150px;
}
</style>
<ion-popover>
<ion-content>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
<p>Text</p>
</ion-content>
</ion-popover>
`,
config
);

const popover = page.locator('ion-popover');
const content = popover.locator('ion-content');
const p = popover.locator('p');
const lastP = await p.last();

await popover.evaluate((el: HTMLIonPopoverElement) => el.present());

await expect(lastP).not.toBeInViewport();

// hover over viewport and scroll to bottom
await content.hover();
await page.mouse.wheel(0, 500);

await expect(lastP).toBeInViewport();
});
});
test.describe(title('popover: translucent variants'), async () => {
let popoverFixture!: PopoverFixture;
test.beforeEach(async ({ page }) => {
Expand Down
27 changes: 27 additions & 0 deletions core/src/css/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,30 @@ ion-input input::-webkit-date-and-time-value {
width: 320px;
min-height: 320px;
}

/**
* If a popover has a child ion-content (or class equivalent) then the .popover-viewport element
* should not be scrollable to ensure the inner content does scroll. However, if the popover
* does not have a child ion-content (or class equivalent) then the .popover-viewport element
* should remain scrollable. This code exists globally because popover targets
* .popover-viewport using ::slotted which only supports simple selectors.
*
* Note that we do not need to account for .ion-content-scroll-host here because that
* class should always be placed within ion-content even if ion-content is not scrollable.
*/
.popover-viewport:has(> ion-content) {
overflow: hidden;
}

/**
* :has has cross-browser support, but it is still relatively new. As a result,
* we should fallback to the old behavior for environments that do not support :has.
* Developers can explicitly enable this behavior by setting overflow: visible
* on .popover-viewport if they know they are not going to use an ion-content.
* TODO FW-6106 Remove this
*/
@supports not selector(:has(> ion-content)) {
.popover-viewport {
overflow: hidden;
}
}