Skip to content

Commit 5300dcc

Browse files
authored
fix(header): collapsed toolbar is no longer incorrectly shown when using ion-refresher (#22937)
resolves #22829
1 parent b064fde commit 5300dcc

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

core/src/components/header/header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export class Header implements ComponentInterface {
120120
* as well as progressively showing/hiding the main header
121121
* border as the top-most toolbar collapses or expands.
122122
*/
123-
const toolbarIntersection = (ev: any) => { handleToolbarIntersection(ev, mainHeaderIndex, scrollHeaderIndex); };
123+
const toolbarIntersection = (ev: any) => { handleToolbarIntersection(ev, mainHeaderIndex, scrollHeaderIndex, this.scrollEl!); };
124124

125125
this.intersectionObserver = new IntersectionObserver(toolbarIntersection, { root: contentEl, threshold: [0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] });
126126
this.intersectionObserver.observe(scrollHeaderIndex.toolbars[scrollHeaderIndex.toolbars.length - 1].el);

core/src/components/header/header.utils.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,21 @@ export const setToolbarBackgroundOpacity = (toolbar: ToolbarIndex, opacity?: num
7272
}
7373
};
7474

75-
const handleToolbarBorderIntersection = (ev: any, mainHeaderIndex: HeaderIndex) => {
75+
const handleToolbarBorderIntersection = (ev: any, mainHeaderIndex: HeaderIndex, scrollTop: number) => {
7676
if (!ev[0].isIntersecting) { return; }
7777

7878
/**
7979
* There is a bug in Safari where overflow scrolling on a non-body element
8080
* does not always reset the scrollTop position to 0 when letting go. It will
8181
* set to 1 once the rubber band effect has ended. This causes the background to
8282
* appear slightly on certain app setups.
83+
*
84+
* Additionally, we check if user is rubber banding (scrolling is negative)
85+
* as this can mean they are using pull to refresh. Once the refresher starts,
86+
* the content is transformed which can cause the intersection observer to erroneously
87+
* fire here as well.
8388
*/
84-
const scale = (ev[0].intersectionRatio > 0.9) ? 0 : ((1 - ev[0].intersectionRatio) * 100) / 75;
89+
const scale = (ev[0].intersectionRatio > 0.9 || scrollTop <= 0) ? 0 : ((1 - ev[0].intersectionRatio) * 100) / 75;
8590

8691
mainHeaderIndex.toolbars.forEach(toolbar => {
8792
setToolbarBackgroundOpacity(toolbar, (scale === 1) ? undefined : scale);
@@ -93,9 +98,10 @@ const handleToolbarBorderIntersection = (ev: any, mainHeaderIndex: HeaderIndex)
9398
* and show the primary toolbar content. If the toolbars are not intersecting,
9499
* hide the primary toolbar content and show the scrollable toolbar content
95100
*/
96-
export const handleToolbarIntersection = (ev: any, mainHeaderIndex: HeaderIndex, scrollHeaderIndex: HeaderIndex) => {
101+
export const handleToolbarIntersection = (ev: any, mainHeaderIndex: HeaderIndex, scrollHeaderIndex: HeaderIndex, scrollEl: HTMLElement) => {
97102
writeTask(() => {
98-
handleToolbarBorderIntersection(ev, mainHeaderIndex);
103+
const scrollTop = scrollEl.scrollTop;
104+
handleToolbarBorderIntersection(ev, mainHeaderIndex, scrollTop);
99105

100106
const event = ev[0];
101107

@@ -127,7 +133,7 @@ export const handleToolbarIntersection = (ev: any, mainHeaderIndex: HeaderIndex,
127133

128134
const hasValidIntersection = (intersection.x === 0 && intersection.y === 0) || (intersection.width !== 0 && intersection.height !== 0);
129135

130-
if (hasValidIntersection) {
136+
if (hasValidIntersection && scrollTop > 0) {
131137
setHeaderActive(mainHeaderIndex);
132138
setHeaderActive(scrollHeaderIndex, false);
133139
setToolbarBackgroundOpacity(mainHeaderIndex.toolbars[0]);

0 commit comments

Comments
 (0)