Skip to content

Commit

Permalink
fix(refresher): attach scroll listener to custom scroll target (#25335)
Browse files Browse the repository at this point in the history
Resolves #25318
  • Loading branch information
sean-perkins committed May 24, 2022
1 parent 15f0c06 commit 8f5e4cd
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 275 deletions.
23 changes: 17 additions & 6 deletions core/src/components/refresher/refresher.tsx
Expand Up @@ -4,7 +4,12 @@ import { Component, Element, Event, Host, Method, Prop, State, Watch, h, readTas
import { getIonMode } from '../../global/ionic-global';
import type { Animation, Gesture, GestureDetail, RefresherEventDetail } from '../../interface';
import { getTimeGivenProgression } from '../../utils/animation/cubic-bezier';
import { findClosestIonContent, getScrollElement, printIonContentErrorMsg } from '../../utils/content';
import {
getScrollElement,
ION_CONTENT_CLASS_SELECTOR,
ION_CONTENT_ELEMENT_SELECTOR,
printIonContentErrorMsg,
} from '../../utils/content';
import { clamp, getElementRoot, raf, transitionEndAsync } from '../../utils/helpers';
import { hapticImpact } from '../../utils/native/haptic';

Expand Down Expand Up @@ -436,13 +441,21 @@ export class Refresher implements ComponentInterface {
return;
}

const contentEl = findClosestIonContent(this.el);
const contentEl = this.el.closest(ION_CONTENT_ELEMENT_SELECTOR);
if (!contentEl) {
printIonContentErrorMsg(this.el);
return;
}

this.scrollEl = await getScrollElement(contentEl);
const customScrollTarget = contentEl.querySelector(ION_CONTENT_CLASS_SELECTOR);

/**
* Query the custom scroll target (if available), first. In refresher implementations,
* the ion-refresher element will always be a direct child of ion-content (slot="fixed"). By
* querying the custom scroll target first and falling back to the ion-content element,
* the correct scroll element will be returned by the implementation.
*/
this.scrollEl = await getScrollElement(customScrollTarget ?? contentEl);

/**
* Query the host `ion-content` directly (if it is available), to use its
Expand All @@ -452,9 +465,7 @@ export class Refresher implements ComponentInterface {
* This makes it so that implementers do not need to re-create the background content
* element and styles.
*/
const backgroundContentHost = this.el.closest('ion-content') ?? contentEl;

this.backgroundContentEl = getElementRoot(backgroundContentHost).querySelector(
this.backgroundContentEl = getElementRoot(contentEl ?? customScrollTarget).querySelector(
'#background-content'
) as HTMLElement;

Expand Down
51 changes: 0 additions & 51 deletions core/src/components/refresher/test/basic/e2e.ts

This file was deleted.

2 changes: 1 addition & 1 deletion core/src/components/refresher/test/basic/index.html
Expand Up @@ -53,7 +53,7 @@
refresher.complete();
render();
// Custom event consumed by e2e tests
document.dispatchEvent(new CustomEvent('ionRefreshComplete'));
window.dispatchEvent(new CustomEvent('ionRefreshComplete'));
});

function render() {
Expand Down
41 changes: 41 additions & 0 deletions core/src/components/refresher/test/basic/refresher.e2e.ts
@@ -0,0 +1,41 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';

import { pullToRefresh } from '../test.utils';

test.describe('refresher: basic', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/refresher/test/basic');
});

test.describe('legacy refresher', () => {
test('should load more items when performing a pull-to-refresh', async ({ page }) => {
const items = page.locator('ion-item');

expect(await items.count()).toBe(30);

await pullToRefresh(page);

expect(await items.count()).toBe(60);
});
});

test.describe('native refresher', () => {
test('should load more items when performing a pull-to-refresh', async ({ page }) => {
const refresherContent = page.locator('ion-refresher-content');
refresherContent.evaluateHandle((el: any) => {
// Resets the pullingIcon to enable the native refresher
el.pullingIcon = undefined;
});

await page.waitForChanges();

const items = page.locator('ion-item');
expect(await items.count()).toBe(30);

await pullToRefresh(page);

expect(await items.count()).toBe(60);
});
});
});
47 changes: 0 additions & 47 deletions core/src/components/refresher/test/scroll-target/e2e.ts

This file was deleted.

6 changes: 3 additions & 3 deletions core/src/components/refresher/test/scroll-target/index.html
Expand Up @@ -44,8 +44,8 @@
<ion-refresher id="refresher" slot="fixed">
<ion-refresher-content></ion-refresher-content>
</ion-refresher>
<div id="content" class="ion-content-scroll-host">
<div id="inner-scroll">
<div id="content">
<div id="inner-scroll" class="ion-content-scroll-host">
<ion-list id="list"></ion-list>
</div>
</div>
Expand All @@ -65,7 +65,7 @@
refresher.complete();
render();
// Custom event consumed by e2e tests
document.dispatchEvent(new CustomEvent('ionRefreshComplete'));
window.dispatchEvent(new CustomEvent('ionRefreshComplete'));
});

function render() {
Expand Down
42 changes: 42 additions & 0 deletions core/src/components/refresher/test/scroll-target/refresher.e2e.ts
@@ -0,0 +1,42 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';

import { pullToRefresh } from '../test.utils';

test.describe('refresher: custom scroll target', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/refresher/test/scroll-target');
});

test.describe('legacy refresher', () => {
test('should load more items when performing a pull-to-refresh', async ({ page }) => {
const items = page.locator('ion-item');

expect(await items.count()).toBe(30);

await pullToRefresh(page, '#inner-scroll');

expect(await items.count()).toBe(60);
});
});

test.describe('native refresher', () => {
test('should load more items when performing a pull-to-refresh', async ({ page }) => {
const refresherContent = page.locator('ion-refresher-content');
refresherContent.evaluateHandle((el: any) => {
// Resets the pullingIcon to enable the native refresher
el.pullingIcon = undefined;
});

await page.waitForChanges();

const items = page.locator('ion-item');

expect(await items.count()).toBe(30);

await pullToRefresh(page, '#inner-scroll');

expect(await items.count()).toBe(60);
});
});
});
10 changes: 0 additions & 10 deletions core/src/components/refresher/test/spec/e2e.ts

This file was deleted.

0 comments on commit 8f5e4cd

Please sign in to comment.