Skip to content
Open
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
26 changes: 16 additions & 10 deletions core/src/components/range/range.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,22 @@ export class Range implements ComponentInterface {
const { contentEl, initialContentScrollY } = this;
const currentX = (detail as GestureDetail).currentX ?? (detail as MouseEvent).clientX;

/**
* Scrolling is disabled in `onMove`, which also assigns `pressedKnob`.
* A tap on the bar never drags, so `pressedKnob` is still undefined here
* and the content's original `scrollY` was never captured.
*
* Restore scrolling only after a drag that disabled it. Checking this
* after `setPressedKnob` would treat a tap as a drag and apply the
* default `initialContentScrollY` (`true`), re-enabling scrolling on
* an `ion-content` that had `scroll-y="false"`.
*
* The user can scroll on the view in the next gesture event.
*/
if (contentEl && this.pressedKnob !== undefined) {
resetContentScrollY(contentEl, initialContentScrollY);
}

/**
* The `pressedKnob` can be undefined if the user never
* dragged the knob. They just tapped on the bar.
Expand All @@ -580,16 +596,6 @@ export class Range implements ComponentInterface {
this.setPressedKnob(currentX);
}

/**
* The user is no longer dragging the bar or
* knob (if they were dragging it).
*
* The user can now scroll on the view in the next gesture event.
*/
if (contentEl && this.pressedKnob !== undefined) {
resetContentScrollY(contentEl, initialContentScrollY);
}

// update the active knob's position
this.update(currentX);

Expand Down
38 changes: 38 additions & 0 deletions core/src/components/range/test/scroll/range.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,43 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>

expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollTop)).toEqual(0);
});

test('should not scroll after tapping the range bar when scrollY is false', async ({ page, skip }) => {
/**
* The Playwright team has stated that they will not implement this feature:
* https://github.com/microsoft/playwright/issues/28755
*/
skip.browser('webkit', 'mouse.wheel is not available in WebKit');

await page.goto(`/src/components/range/test/scroll/scroll-y-false.html`, config);

const rangeSlider = page.locator('ion-range .range-slider');
const scrollEl = page.locator('ion-content .inner-scroll');
const contentEl = page.locator('ion-content');

expect(await contentEl.evaluate((el: HTMLIonContentElement) => el.scrollY)).toBe(false);
expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollHeight > el.clientHeight)).toBe(true);
expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollTop)).toEqual(0);

/**
* Click the bar without dragging. A tap stays under the gesture
* threshold, so it goes through pointerup rather than the drag path.
*/
await rangeSlider.click();
await page.waitForChanges();

expect(await contentEl.evaluate((el: HTMLIonContentElement) => el.scrollY)).toBe(false);

/**
* Do not use scrollToBottom() or other scrolling methods
* on ion-content as those will update the scroll position.
* Setting scrollTop still works even with overflow-y: hidden.
* However, simulating a user gesture should not scroll the content.
*/
await page.mouse.wheel(0, 100);
await page.waitForChanges();

expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollTop)).toEqual(0);
});
});
});
73 changes: 73 additions & 0 deletions core/src/components/range/test/scroll/scroll-y-false.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Range - Scroll Y Disabled</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Range - Scroll Y Disabled</ion-title>
</ion-toolbar>
</ion-header>

<ion-content class="ion-padding" scroll-y="false">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur faucibus nulla a nunc tincidunt semper. Nam
nibh lorem, pharetra ac ex ac, tempus fringilla est. Aenean tincidunt ipsum pellentesque, consequat libero id,
feugiat leo. In vestibulum faucibus velit, non tincidunt erat tincidunt in. Donec a diam sed nisl convallis
maximus. Aenean cursus sagittis lorem vitae tristique. Pellentesque pellentesque, quam eget lobortis finibus,
lectus lorem maximus purus, quis sagittis tortor sem sed tellus.
</p>

<ion-range value="40">
<div slot="label">Range Label</div>
<ion-label slot="start">Start</ion-label>
<ion-label slot="end">End</ion-label>
</ion-range>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur faucibus nulla a nunc tincidunt semper. Nam
nibh lorem, pharetra ac ex ac, tempus fringilla est. Aenean tincidunt ipsum pellentesque, consequat libero id,
feugiat leo. In vestibulum faucibus velit, non tincidunt erat tincidunt in. Donec a diam sed nisl convallis
maximus. Aenean cursus sagittis lorem vitae tristique. Pellentesque pellentesque, quam eget lobortis finibus,
lectus lorem maximus purus, quis sagittis tortor sem sed tellus.
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur faucibus nulla a nunc tincidunt semper. Nam
nibh lorem, pharetra ac ex ac, tempus fringilla est. Aenean tincidunt ipsum pellentesque, consequat libero id,
feugiat leo. In vestibulum faucibus velit, non tincidunt erat tincidunt in. Donec a diam sed nisl convallis
maximus. Aenean cursus sagittis lorem vitae tristique. Pellentesque pellentesque, quam eget lobortis finibus,
lectus lorem maximus purus, quis sagittis tortor sem sed tellus.
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur faucibus nulla a nunc tincidunt semper. Nam
nibh lorem, pharetra ac ex ac, tempus fringilla est. Aenean tincidunt ipsum pellentesque, consequat libero id,
feugiat leo. In vestibulum faucibus velit, non tincidunt erat tincidunt in. Donec a diam sed nisl convallis
maximus. Aenean cursus sagittis lorem vitae tristique. Pellentesque pellentesque, quam eget lobortis finibus,
lectus lorem maximus purus, quis sagittis tortor sem sed tellus.
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur faucibus nulla a nunc tincidunt semper. Nam
nibh lorem, pharetra ac ex ac, tempus fringilla est. Aenean tincidunt ipsum pellentesque, consequat libero id,
feugiat leo. In vestibulum faucibus velit, non tincidunt erat tincidunt in. Donec a diam sed nisl convallis
maximus. Aenean cursus sagittis lorem vitae tristique. Pellentesque pellentesque, quam eget lobortis finibus,
lectus lorem maximus purus, quis sagittis tortor sem sed tellus.!
</p>
</ion-content>
</ion-app>
</body>
</html>
Loading