Skip to content

Commit

Permalink
fix(popover): handle scrolling in content so header can be sticky (#2…
Browse files Browse the repository at this point in the history
  • Loading branch information
amandaejohnston committed Dec 6, 2021
1 parent b083ae4 commit f6a00ea
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 2 deletions.
27 changes: 27 additions & 0 deletions core/src/components/content/content.scss
Expand Up @@ -140,10 +140,37 @@
}

:host(.content-sizing) {
display: flex;

flex-direction: column;

/**
* This resolves a sizing issue in popovers where extra long content
* would overflow the popover's height, preventing scrolling. It's a
* quirk of flexbox that forces the content to shrink to fit.
*
* overflow: hidden can't be used here because it prevents the visual
* effect from showing on translucent headers.
*/
min-height: 0;

contain: none;
}
:host(.content-sizing) .inner-scroll {
position: relative;

/**
* Because the outer content has display: flex here (to help enable
* scrolling in a popover), offsetting via `top` (such as when using
* a translucent header) creates white space under the content. Use
* a negative margin instead to keep the bottom in place. (A similar
* thing happens with `bottom` and footers.)
*/
top: 0;
bottom: 0;

margin-top: calc(var(--offset-top) * -1);
margin-bottom: calc(var(--offset-bottom) * -1);
}

.transition-effect {
Expand Down
9 changes: 8 additions & 1 deletion core/src/components/content/content.tsx
Expand Up @@ -374,10 +374,17 @@ const getPageElement = (el: HTMLElement) => {
if (tabs) {
return tabs;
}
const page = el.closest('ion-app,ion-page,.ion-page,page-inner');

/**
* If we're in a popover, we need to use its wrapper so we can account for space
* between the popover and the edges of the screen. But if the popover contains
* its own page element, we should use that instead.
*/
const page = el.closest('ion-app, ion-page, .ion-page, page-inner, .popover-content');
if (page) {
return page;
}

return getParentElement(el);
};

Expand Down
6 changes: 5 additions & 1 deletion core/src/components/popover/popover.scss
Expand Up @@ -75,5 +75,9 @@
--ion-safe-area-right: 0px;
--ion-safe-area-bottom: 0px;
--ion-safe-area-left: 0px;
}
display: flex;

flex-direction: column;

overflow: hidden;
}
16 changes: 16 additions & 0 deletions core/src/components/popover/test/basic/e2e.ts
Expand Up @@ -57,6 +57,14 @@ test('popover: custom class', async () => {
await testPopover(DIRECTORY, '#custom-class-popover');
});

test('popover: header', async () => {
await testPopover(DIRECTORY, '#header-popover');
});

test('popover: translucent header', async () => {
await testPopover(DIRECTORY, '#translucent-header-popover');
});

/**
* RTL Tests
*/
Expand All @@ -81,6 +89,14 @@ test('popover:rtl: custom class', async () => {
await testPopover(DIRECTORY, '#custom-class-popover', true);
});

test('popover:rtl: header', async () => {
await testPopover(DIRECTORY, '#header-popover', true);
});

test('popover:rtl: translucent header', async () => {
await testPopover(DIRECTORY, '#translucent-header-popover', true);
});

test('popover: htmlAttributes', async () => {
const page = await newE2EPage({ url: '/src/components/popover/test/basic?ionic:_testing=true' });

Expand Down
52 changes: 52 additions & 0 deletions core/src/components/popover/test/basic/index.html
Expand Up @@ -34,6 +34,8 @@
<ion-button id="long-list-popover" expand="block" color="secondary" onclick="presentPopover({ component: 'list-page', event: event })">Show Long List Popover</ion-button>
<ion-button id="no-event-popover" expand="block" color="danger" onclick="presentPopover({ component: 'profile-page' })">No Event Popover</ion-button>
<ion-button id="custom-class-popover" expand="block" color="tertiary" onclick="presentPopover({ component: 'translucent-page', event: event, cssClass: 'my-custom-class' })">Custom Class Popover</ion-button>
<ion-button id="header-popover" expand="block" onclick="presentPopover({ component: 'header-page' })">Popover With Header</ion-button>
<ion-button id="translucent-header-popover" expand="block" onclick="presentPopover({ component: 'translucent-header-page' })">Popover With Translucent Header</ion-button>
</ion-content>

<ion-footer>
Expand Down Expand Up @@ -126,6 +128,56 @@ <h1>Translucent Popover</h1>
}

customElements.define('translucent-page', TranslucentPage);

class HeaderPage extends HTMLElement {
constructor() {
super();
}

connectedCallback() {
this.innerHTML = `
<ion-header>
<ion-toolbar>
<ion-title>Header</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding" color="primary">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.In rutrum tortor lacus, ac interdum ipsum bibendum vel.Aenean non nibh gravida, ullamcorper mi at, tempor nulla.Proin malesuada tellus ut ullamcorper accumsan.Donec semper justo vulputate neque tempus ultricies.Proin non aliquet ipsum.Praesent mauris sem, facilisis eu justo nec, euismod imperdiet tellus.Duis eget justo congue, lacinia orci sed, fermentum urna.Quisque sed massa faucibus, interdum dolor rhoncus, molestie erat.Proin suscipit ante non mauris volutpat egestas.Donec a ultrices ligula.Mauris in felis vel dui consectetur viverra.Nam vitae quam in arcu aliquam aliquam.Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Cras non velit nisl.Donec viverra, magna quis vestibulum volutpat, metus ante tincidunt augue, non porta nisi mi sit amet neque.Proin dapibus eros vitae nibh tincidunt, blandit rhoncus est porttitor.
</ion-content>
`;
}
}

customElements.define('header-page', HeaderPage);

class TranslucentHeaderPage extends HTMLElement {
constructor() {
super();
}

connectedCallback() {
this.innerHTML = `
<ion-header translucent>
<ion-toolbar>
<ion-title>Header</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding" fullscreen color="primary">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.In rutrum tortor lacus, ac interdum ipsum bibendum vel.Aenean non nibh gravida, ullamcorper mi at, tempor nulla.Proin malesuada tellus ut ullamcorper accumsan.Donec semper justo vulputate neque tempus ultricies.Proin non aliquet ipsum.Praesent mauris sem, facilisis eu justo nec, euismod imperdiet tellus.Duis eget justo congue, lacinia orci sed, fermentum urna.Quisque sed massa faucibus, interdum dolor rhoncus, molestie erat.Proin suscipit ante non mauris volutpat egestas.Donec a ultrices ligula.Mauris in felis vel dui consectetur viverra.Nam vitae quam in arcu aliquam aliquam.Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Cras non velit nisl.Donec viverra, magna quis vestibulum volutpat, metus ante tincidunt augue, non porta nisi mi sit amet neque.Proin dapibus eros vitae nibh tincidunt, blandit rhoncus est porttitor.
</ion-content>
<ion-footer translucent>
<ion-toolbar>
<ion-title>Footer</ion-title>
</ion-toolbar>
</ion-footer>
`;
}
}

customElements.define('translucent-header-page', TranslucentHeaderPage);
</script>
</body>

Expand Down

0 comments on commit f6a00ea

Please sign in to comment.