diff --git a/core/src/components/range/range.tsx b/core/src/components/range/range.tsx index c3875c8e30e..2b0da05dad0 100644 --- a/core/src/components/range/range.tsx +++ b/core/src/components/range/range.tsx @@ -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. @@ -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); diff --git a/core/src/components/range/test/scroll/range.e2e.ts b/core/src/components/range/test/scroll/range.e2e.ts index 9353d5fe2d5..a049a853db4 100644 --- a/core/src/components/range/test/scroll/range.e2e.ts +++ b/core/src/components/range/test/scroll/range.e2e.ts @@ -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); + }); }); }); diff --git a/core/src/components/range/test/scroll/scroll-y-false.html b/core/src/components/range/test/scroll/scroll-y-false.html new file mode 100644 index 00000000000..444d09ec31e --- /dev/null +++ b/core/src/components/range/test/scroll/scroll-y-false.html @@ -0,0 +1,73 @@ + + +
+ ++ 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. +
+ ++ 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. +
+ ++ 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. +
+ ++ 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. +
+ ++ 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.! +
+