From 2f012e928097a53ddc5f780c6a664ffe923ce38f Mon Sep 17 00:00:00 2001 From: dmitrybrovka Date: Mon, 11 Nov 2024 14:16:04 +0300 Subject: [PATCH] :rocket: Added trackContentSwipes to b-bottom-slide --- .../base/b-bottom-slide/CHANGELOG.md | 6 +++++ src/components/base/b-bottom-slide/README.md | 6 +++++ .../base/b-bottom-slide/b-bottom-slide.ss | 5 +---- .../base/b-bottom-slide/b-bottom-slide.ts | 22 +++++++++++++++++++ src/components/base/b-bottom-slide/props.ts | 8 +++++++ .../base/b-bottom-slide/test/unit/gestures.ts | 21 ++++++++++++++++++ 6 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/components/base/b-bottom-slide/CHANGELOG.md b/src/components/base/b-bottom-slide/CHANGELOG.md index 5994dbc59e..abfe99683a 100644 --- a/src/components/base/b-bottom-slide/CHANGELOG.md +++ b/src/components/base/b-bottom-slide/CHANGELOG.md @@ -9,6 +9,12 @@ Changelog > - :house: [Internal] > - :nail_care: [Polish] +## v4.0.0-beta.?? (2024-??-??) + +#### :rocket: New Feature + +* Added `trackContentSwipes` - a flag to prevent unexpected closure of a component instance + ## v4.0.0-beta.94 (2024-04-24) #### :bug: Bug Fix diff --git a/src/components/base/b-bottom-slide/README.md b/src/components/base/b-bottom-slide/README.md index 3f90d1687e..f29478ae68 100644 --- a/src/components/base/b-bottom-slide/README.md +++ b/src/components/base/b-bottom-slide/README.md @@ -246,6 +246,12 @@ Component height mode: * `content` - the height value is based on the component content, but no larger than the viewport height; * `full` - the height value is equal to the height of the viewport. +#### [trackContentSwipes = `true`] + +A flag to control swipes tracking on passed content. If true, component tracks touch events on content to animate sheet pulling or to close an instance. + +Setting `trackContentSwipes` to `false` is useful when passed content (such as game or map layout) uses gestures to provide additional functionality. + #### [stepsProp = `[]`] A list of allowed component positions relative to screen height (percentage). diff --git a/src/components/base/b-bottom-slide/b-bottom-slide.ss b/src/components/base/b-bottom-slide/b-bottom-slide.ss index 158b1e7fdf..c82c23048d 100644 --- a/src/components/base/b-bottom-slide/b-bottom-slide.ss +++ b/src/components/base/b-bottom-slide/b-bottom-slide.ss @@ -41,10 +41,7 @@ - block view < .&__view & ref = view | - v-on-resize = {handler: recalculateState} | - @touchstart = swipeControl.onPullStart | - @touchmove = swipeControl.onPull | - v-safe-on:touchend = swipeControl.onPullEnd.bind(swipeControl) + :v-attrs = viewBlockAttrs . - block content < .&__content ref = content diff --git a/src/components/base/b-bottom-slide/b-bottom-slide.ts b/src/components/base/b-bottom-slide/b-bottom-slide.ts index 129192064b..aa084ac8dc 100644 --- a/src/components/base/b-bottom-slide/b-bottom-slide.ts +++ b/src/components/base/b-bottom-slide/b-bottom-slide.ts @@ -202,6 +202,28 @@ class bBottomSlide extends iBottomSlideProps implements iLockPageScroll, iOpen, this.emit('moveStateChange', value); } + /** + * Attributes object for the component view block + */ + protected get viewBlockAttrs(): object { + const defaultAttrs = { + 'v-on-resize': {handler: this.recalculateState.bind(this)} + }; + + const tracking = this.trackContentSwipes ? + { + '@touchstart': (e: TouchEvent) => this.swipeControl.onPullStart(e), + '@touchmove': (e: TouchEvent) => this.swipeControl.onPull(e), + 'v-safe-on:touchend': () => this.swipeControl.onPullEnd() + } : + {}; + + return { + ...defaultAttrs, + ...tracking + }; + } + /** * The minimum value of the height of the component visible part (in percent), * i.e., even if the component is closed, this part will still be visible diff --git a/src/components/base/b-bottom-slide/props.ts b/src/components/base/b-bottom-slide/props.ts index c1a41723fd..711b55ff39 100644 --- a/src/components/base/b-bottom-slide/props.ts +++ b/src/components/base/b-bottom-slide/props.ts @@ -12,6 +12,7 @@ import iBlock, { component, prop } from 'components/super/i-block/i-block'; import { heightMode } from 'components/base/b-bottom-slide/const'; import type { HeightMode } from 'components/base/b-bottom-slide/interface'; +import type { SwipeControl } from 'components/base/b-bottom-slide/modules'; @component({partial: 'bBottomSlide'}) export default abstract class iBottomSlideProps extends iBlock { @@ -49,6 +50,13 @@ export default abstract class iBottomSlideProps extends iBlock { @prop({type: Number, validator: Number.isPositive}) readonly fastSwipeDelay: number = (0.3).seconds(); + /** + * True, if need to track touch events on a component content to close a component instance + * {@link SwipeControl} + */ + @prop(Boolean) + readonly trackContentSwipes: boolean = true; + /** * The minimum required number of scroll pixels, after which it can be considered that there was a fast swipe */ diff --git a/src/components/base/b-bottom-slide/test/unit/gestures.ts b/src/components/base/b-bottom-slide/test/unit/gestures.ts index 5d9f8e94d7..536bf44de9 100644 --- a/src/components/base/b-bottom-slide/test/unit/gestures.ts +++ b/src/components/base/b-bottom-slide/test/unit/gestures.ts @@ -91,6 +91,27 @@ test.describe(' gestures', () => { test.expect(openedModVal).toBe('true'); }); + test('should stop tracking gestures on the content block when content swipes tracking disabled', async ({page}) => { + const component = await renderBottomSlide(page, { + heightMode: 'content', + trackContentSwipes: false, + visible: 80 + }); + + await open(page, component); + + const + windowY = await getComponentWindowYPos(component); + + await gestures.evaluate((ctx, windowY) => + ctx.swipe(ctx.buildSteps(5, 40, windowY + 20, 0, 30)), windowY); + + const + openedModVal = await component.evaluate(({mods}) => mods.opened); + + test.expect(openedModVal).toBe('true'); + }); + test('should pull up the window when the cursor moves up', async ({page}) => { const component = await renderBottomSlide(page, { heightMode: 'full',