diff --git a/packages/vkui/src/components/View/View.test.tsx b/packages/vkui/src/components/View/View.test.tsx index 791998e29e..6a9cdb13c0 100644 --- a/packages/vkui/src/components/View/View.test.tsx +++ b/packages/vkui/src/components/View/View.test.tsx @@ -214,7 +214,7 @@ describe(View, () => { fireEvent.mouseUp(view); expect(events.onSwipeBack).not.toHaveBeenCalled(); expect(events.onSwipeBackCancel).not.toHaveBeenCalled(); - await waitCSSTransitionEnd(getViewPanelById('p1'), { propertyName: 'transform' }); + await waitCSSTransitionEnd(getViewPanelById('p2'), { propertyName: 'transform' }); expect(events.onSwipeBack).toHaveBeenCalledTimes(1); }); it('should swipe back by start touch anywhere', async () => { @@ -231,7 +231,7 @@ describe(View, () => { expect(events.onSwipeBackStart).toHaveBeenCalledTimes(1); fireEvent.mouseUp(view); - await waitCSSTransitionEnd(getViewPanelById('p1'), { + await waitCSSTransitionEnd(getViewPanelById('p2'), { propertyName: 'transform', }); @@ -343,7 +343,7 @@ describe(View, () => { scrollToLeftAndSwipe(100); expect(events.onSwipeBackStart).toHaveBeenCalledTimes(1); - await waitCSSTransitionEnd(getViewPanelById('p1'), { propertyName: 'transform' }); + await waitCSSTransitionEnd(getViewPanelById('p2'), { propertyName: 'transform' }); expect(events.onSwipeBack).toHaveBeenCalledTimes(1); expect(events.onSwipeBackCancel).not.toHaveBeenCalled(); @@ -386,7 +386,7 @@ describe(View, () => { scrollToLeftAndSwipe(0); expect(events.onSwipeBackStart).toHaveBeenCalledTimes(1); - await waitCSSTransitionEnd(getViewPanelById('p1'), { propertyName: 'transform' }); + await waitCSSTransitionEnd(getViewPanelById('p2'), { propertyName: 'transform' }); expect(events.onSwipeBack).toHaveBeenCalledTimes(1); expect(events.onSwipeBackCancel).not.toHaveBeenCalled(); }); diff --git a/packages/vkui/src/components/View/View.tsx b/packages/vkui/src/components/View/View.tsx index 3795d2d3e1..e840e669c7 100644 --- a/packages/vkui/src/components/View/View.tsx +++ b/packages/vkui/src/components/View/View.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { classNames } from '@vkontakte/vkjs'; import { usePlatform } from '../../hooks/usePlatform'; import { usePrevious } from '../../hooks/usePrevious'; -import { blurActiveElement, canUseDOM, useDOM } from '../../lib/dom'; +import { blurActiveElement, useDOM } from '../../lib/dom'; import { getNavId, NavIdProps } from '../../lib/getNavId'; import { warnOnce } from '../../lib/warnOnce'; import { HTMLAttributesWithRootRef } from '../../types'; @@ -156,11 +156,11 @@ export const View = ({ [activePanelProp, layoutEffectCall, onTransition, scroll], ); - const onAnimationEnd = React.useCallback(() => { + const handleAnimatedTargetAnimationEnd = () => { if (prevPanel !== null) { flushTransition(prevPanel, Boolean(isBack)); } - }, [flushTransition, isBack, prevPanel]); + }; const onSwipeBackSuccess = React.useCallback(() => { onSwipeBack && onSwipeBack(); @@ -275,56 +275,41 @@ export const View = ({ } }; - const calcPanelSwipeStyles = (panelId: string | undefined): React.CSSProperties => { - if (!canUseDOM || !window) { - return {}; - } - - const isPrev = panelId === swipeBackPrevPanel; - const isNext = panelId === swipeBackNextPanel; - + const calcPanelSwipeStyles = (isPrev: boolean, isNext: boolean): React.CSSProperties => { if ((!isPrev && !isNext) || swipeBackResult) { return {}; } - let prevPanelTranslate = `${swipeBackShift}px`; - let nextPanelTranslate = `${-50 + (swipeBackShift * 100) / window.innerWidth / 2}%`; - if (isNext) { - return { - transform: `translate3d(${nextPanelTranslate}, 0, 0)`, - }; + return window + ? { + transform: `translate3d(${-50 + (swipeBackShift * 100) / window.innerWidth / 2}%, 0, 0)`, + } + : {}; } + if (isPrev) { - return { - transform: `translate3d(${prevPanelTranslate}, 0, 0)`, - }; + return { transform: `translate3d(${swipeBackShift}px, 0, 0)` }; } return {}; }; - const calcPanelSwipeBackOverlayStyles = (panelId?: string): React.CSSProperties => { - if (!canUseDOM || !window) { + const calcPanelSwipeBackOverlayStyles = (isNext: boolean): React.CSSProperties => { + if (!window || !isNext) { return {}; } - - const isNext = panelId === swipeBackNextPanel; - if (!isNext) { - return {}; - } - - const calculatedOpacity = 1 - swipeBackShift / window.innerWidth; const opacityOnSwipeEnd = swipeBackResult === 'success' ? 0 : swipeBackResult === 'fail' ? 1 : null; return { display: 'block', - opacity: opacityOnSwipeEnd === null ? calculatedOpacity : opacityOnSwipeEnd, + opacity: + opacityOnSwipeEnd === null ? 1 - swipeBackShift / window.innerWidth : opacityOnSwipeEnd, }; }; - const onTransitionEnd = (event: React.TransitionEvent) => { + const handleSwipeBackTargetTransitionEnd = (event: React.TransitionEvent) => { if (event.propertyName.includes('transform')) { swipingBackTransitionEndHandler(); } @@ -482,7 +467,7 @@ export const View = ({ const isSwipeBackPrev = panelId === swipeBackPrevPanel; const isSwipeBackNext = panelId === swipeBackNextPanel; - const isSwipeBackTarget = !prevSwipeBackResult && swipeBackResult && isSwipeBackNext; + const isSwipeBackTarget = swipeBackResult && isSwipeBackPrev; let scrollCompensateStyle: React.CSSProperties | undefined = undefined; @@ -507,16 +492,16 @@ export const View = ({ swipeBackResult === 'success' && styles['View__panel--swipe-back-success'], swipeBackResult === 'fail' && styles['View__panel--swipe-back-failed'], )} - onTransitionEnd={isSwipeBackTarget ? onTransitionEnd : undefined} - onAnimationEnd={isAnimatedTarget ? onAnimationEnd : undefined} + onTransitionEnd={isSwipeBackTarget ? handleSwipeBackTargetTransitionEnd : undefined} + onAnimationEnd={isAnimatedTarget ? handleAnimatedTargetAnimationEnd : undefined} ref={(el) => panelId !== undefined && (panelNodes.current[panelId] = el)} - style={calcPanelSwipeStyles(panelId)} + style={calcPanelSwipeStyles(isSwipeBackPrev, isSwipeBackNext)} key={panelId} > {platform === 'ios' && (
)}