@vkontakte/vkui 5.2.2 → 5.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -150,11 +150,19 @@ var Touch = function Touch(_ref) {
150
150
  if (isPressed) {
151
151
  handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);
152
152
  }
153
- didSlide.current = Boolean(isSlide);
153
+ var isTouchEnabled = (0, _touch.touchEnabled)();
154
+ if (isTouchEnabled && isSlide) {
155
+ // https://github.com/VKCOM/VKUI/issues/4414
156
+ // если тач-устройство и был зафиксирован touchmove,
157
+ // то событие клика не вызывается
158
+ didSlide.current = false;
159
+ } else {
160
+ didSlide.current = Boolean(isSlide);
161
+ }
154
162
  gesture.current = {};
155
163
 
156
164
  // Если это был тач-евент, симулируем отмену hover
157
- if ((0, _touch.touchEnabled)()) {
165
+ if (isTouchEnabled) {
158
166
  onLeave && onLeave(e);
159
167
  }
160
168
  unsubscribe();
@@ -1 +1 @@
1
- {"version":3,"file":"Touch.js","names":["Touch","onStart","onStartX","onStartY","_onMove","onMove","onMoveX","onMoveY","onLeave","onEnter","_onEnd","onEnd","onEndX","onEndY","onClickCapture","usePointerHover","slideThreshold","useCapture","Component","getRootRef","noSlideClick","stopPropagation","restProps","useDOM","document","events","React","useMemo","getSupportedEvents","didSlide","useRef","gesture","handle","e","handlers","forEach","cb","duration","Date","now","current","startT","getTime","originalEvent","enterHandler","useEventListener","leaveHandler","startHandler","initGesture","coordX","coordY","subscribe","touchEnabled","target","capture","passive","containerRef","useExternRef","useIsomorphicLayoutEffect","el","add","isPressed","isX","isY","startX","startY","shiftX","shiftY","shiftXAbs","Math","abs","shiftYAbs","touches","length","willBeX","willBeY","willBeSlidedX","willBeSlidedY","Object","assign","isSlideX","isSlideY","isSlide","Boolean","unsubscribe","listenerParams","listeners","l","remove","onDragStart","tagName","preventDefault","postGestureClick"],"sources":["../../../../src/components/Touch/Touch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useDOM } from '../../lib/dom';\nimport { coordX, coordY, getSupportedEvents, touchEnabled, VKUITouchEvent } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nexport interface TouchProps\n extends React.AllHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLElement>,\n HasComponent {\n /**\n * Привязать onEnter и onLeave через pointer-events - работает на disabled-инпутах\n */\n usePointerHover?: boolean;\n useCapture?: boolean;\n slideThreshold?: number;\n noSlideClick?: boolean;\n onEnter?: HoverHandler;\n onLeave?: HoverHandler;\n onStart?: TouchEventHandler;\n onStartX?: TouchEventHandler;\n onStartY?: TouchEventHandler;\n onMove?: TouchEventHandler;\n onMoveX?: TouchEventHandler;\n onMoveY?: TouchEventHandler;\n onEnd?: TouchEventHandler;\n onEndX?: TouchEventHandler;\n onEndY?: TouchEventHandler;\n stopPropagation?: boolean;\n}\n\nexport interface Gesture {\n startX: number;\n startY: number;\n startT: Date;\n duration: number;\n isPressed: boolean;\n isY: boolean;\n isX: boolean;\n isSlideX: boolean;\n isSlideY: boolean;\n isSlide: boolean;\n shiftX: number;\n shiftY: number;\n shiftXAbs: number;\n shiftYAbs: number;\n}\n\nexport interface TouchEvent extends Gesture {\n originalEvent: VKUITouchEvent;\n}\n\ntype HoverHandler = (outputEvent: MouseEvent) => void;\nexport type TouchEventHandler = (e: TouchEvent) => void;\nexport type ClickHandler = (e: React.MouseEvent<HTMLElement>) => void;\nexport type DragHandler = (e: React.DragEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Touch\n */\nexport const Touch = ({\n onStart,\n onStartX,\n onStartY,\n onMove: _onMove,\n onMoveX,\n onMoveY,\n onLeave,\n onEnter,\n onEnd: _onEnd,\n onEndX,\n onEndY,\n onClickCapture,\n usePointerHover,\n slideThreshold = 5,\n useCapture = false,\n Component = 'div',\n getRootRef,\n noSlideClick = false,\n stopPropagation = false,\n ...restProps\n}: TouchProps) => {\n const { document } = useDOM();\n const events = React.useMemo(getSupportedEvents, []);\n const didSlide = React.useRef(false);\n const gesture = React.useRef<Partial<Gesture> | null>(null);\n const handle = (e: VKUITouchEvent, handlers: Array<TouchEventHandler | undefined | false>) => {\n stopPropagation && e.stopPropagation();\n handlers.forEach((cb) => {\n const duration = Date.now() - (gesture.current?.startT?.getTime() ?? 0);\n cb && cb({ ...(gesture.current as Gesture), duration, originalEvent: e });\n });\n };\n\n const enterHandler = useEventListener(usePointerHover ? 'pointerenter' : 'mouseenter', onEnter);\n const leaveHandler = useEventListener(usePointerHover ? 'pointerleave' : 'mouseleave', onLeave);\n const startHandler = useEventListener(\n events[0],\n (e: VKUITouchEvent) => {\n gesture.current = initGesture(coordX(e), coordY(e));\n\n handle(e, [onStart, onStartX, onStartY]);\n // 1 line, 2 bad specs, 2 workarounds:\n subscribe(\n touchEnabled()\n ? // Touch events fire on initial target, and won't bubble if its removed\n // see: #235, #1968, https://stackoverflow.com/a/45760014\n (e.target as HTMLElement)\n : // Mouse events fire on the element under pointer, so we lose move / end\n // if pointer goes outside container.\n // Can be fixed by PointerEvents' setPointerCapture later\n document,\n );\n },\n { capture: useCapture, passive: false },\n );\n const containerRef = useExternRef(getRootRef);\n\n useIsomorphicLayoutEffect(() => {\n const el = containerRef.current;\n if (el) {\n enterHandler.add(el);\n leaveHandler.add(el);\n startHandler.add(el);\n }\n }, [Component]);\n\n function onMove(e: VKUITouchEvent) {\n const { isPressed, isX, isY, startX = 0, startY = 0 } = gesture.current ?? {};\n\n if (isPressed) {\n // смещения\n const shiftX = coordX(e) - startX;\n const shiftY = coordY(e) - startY;\n\n // абсолютные значения смещений\n const shiftXAbs = Math.abs(shiftX);\n const shiftYAbs = Math.abs(shiftY);\n\n // Если определяем мультитач, то прерываем жест\n if (!!e.touches && e.touches.length > 1) {\n return onEnd(e);\n }\n\n // если мы ещё не определились\n if (!isX && !isY) {\n const willBeX = shiftXAbs >= slideThreshold && shiftXAbs > shiftYAbs;\n const willBeY = shiftYAbs >= slideThreshold && shiftYAbs > shiftXAbs;\n const willBeSlidedX = willBeX && (!!onMoveX || !!_onMove);\n const willBeSlidedY = willBeY && (!!onMoveY || !!_onMove);\n\n if (gesture.current) {\n Object.assign(gesture.current, {\n isY: willBeY,\n isX: willBeX,\n isSlideX: willBeSlidedX,\n isSlideY: willBeSlidedY,\n isSlide: willBeSlidedX || willBeSlidedY,\n });\n }\n }\n\n if (gesture.current?.isSlide) {\n Object.assign(gesture.current, {\n shiftX,\n shiftY,\n shiftXAbs,\n shiftYAbs,\n });\n\n handle(e, [\n _onMove,\n gesture.current.isSlideX && onMoveX,\n gesture.current.isSlideY && onMoveY,\n ]);\n }\n }\n }\n\n function onEnd(e: VKUITouchEvent) {\n const { isPressed, isSlide, isSlideX, isSlideY } = gesture.current ?? {};\n\n if (isPressed) {\n handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);\n }\n\n didSlide.current = Boolean(isSlide);\n gesture.current = {};\n\n // Если это был тач-евент, симулируем отмену hover\n if (touchEnabled()) {\n onLeave && onLeave(e);\n }\n unsubscribe();\n }\n\n const listenerParams = { capture: useCapture, passive: false };\n const listeners = [\n useEventListener(events[1], onMove, listenerParams),\n useEventListener(events[2], onEnd, listenerParams),\n useEventListener(events[3], onEnd, listenerParams),\n ];\n function subscribe(el: HTMLElement | Document | null | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n /**\n * Обработчик событий dragstart\n * Отменяет нативное браузерное поведение для вложенных ссылок и изображений\n */\n const onDragStart = (e: React.DragEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'A' || target.tagName === 'IMG') {\n e.preventDefault();\n }\n };\n\n /**\n * Обработчик клика по компоненту\n * Отменяет переход по вложенной ссылке, если был зафиксирован свайп\n */\n const postGestureClick: typeof onClickCapture = (e) => {\n if (!didSlide.current) {\n return onClickCapture && onClickCapture(e);\n }\n\n if (noSlideClick) {\n e.stopPropagation();\n\n // https://github.com/VKCOM/VKUI/issues/1977\n // https://github.com/VKCOM/VKUI/issues/3892\n e.preventDefault();\n } else {\n onClickCapture && onClickCapture(e);\n }\n\n didSlide.current = false;\n };\n\n return (\n <Component\n {...restProps}\n onDragStart={onDragStart}\n onClickCapture={postGestureClick}\n ref={containerRef}\n />\n );\n};\n\nfunction initGesture(startX: number, startY: number): Gesture {\n return {\n startX,\n startY,\n startT: new Date(),\n duration: 0,\n isPressed: true,\n isY: false,\n isX: false,\n isSlideX: false,\n isSlideY: false,\n isSlide: false,\n shiftX: 0,\n shiftY: 0,\n shiftXAbs: 0,\n shiftYAbs: 0,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Touch.js","names":["Touch","onStart","onStartX","onStartY","_onMove","onMove","onMoveX","onMoveY","onLeave","onEnter","_onEnd","onEnd","onEndX","onEndY","onClickCapture","usePointerHover","slideThreshold","useCapture","Component","getRootRef","noSlideClick","stopPropagation","restProps","useDOM","document","events","React","useMemo","getSupportedEvents","didSlide","useRef","gesture","handle","e","handlers","forEach","cb","duration","Date","now","current","startT","getTime","originalEvent","enterHandler","useEventListener","leaveHandler","startHandler","initGesture","coordX","coordY","subscribe","touchEnabled","target","capture","passive","containerRef","useExternRef","useIsomorphicLayoutEffect","el","add","isPressed","isX","isY","startX","startY","shiftX","shiftY","shiftXAbs","Math","abs","shiftYAbs","touches","length","willBeX","willBeY","willBeSlidedX","willBeSlidedY","Object","assign","isSlideX","isSlideY","isSlide","isTouchEnabled","Boolean","unsubscribe","listenerParams","listeners","l","remove","onDragStart","tagName","preventDefault","postGestureClick"],"sources":["../../../../src/components/Touch/Touch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useDOM } from '../../lib/dom';\nimport { coordX, coordY, getSupportedEvents, touchEnabled, VKUITouchEvent } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nexport interface TouchProps\n extends React.AllHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLElement>,\n HasComponent {\n /**\n * Привязать onEnter и onLeave через pointer-events - работает на disabled-инпутах\n */\n usePointerHover?: boolean;\n useCapture?: boolean;\n slideThreshold?: number;\n noSlideClick?: boolean;\n onEnter?: HoverHandler;\n onLeave?: HoverHandler;\n onStart?: TouchEventHandler;\n onStartX?: TouchEventHandler;\n onStartY?: TouchEventHandler;\n onMove?: TouchEventHandler;\n onMoveX?: TouchEventHandler;\n onMoveY?: TouchEventHandler;\n onEnd?: TouchEventHandler;\n onEndX?: TouchEventHandler;\n onEndY?: TouchEventHandler;\n stopPropagation?: boolean;\n}\n\nexport interface Gesture {\n startX: number;\n startY: number;\n startT: Date;\n duration: number;\n isPressed: boolean;\n isY: boolean;\n isX: boolean;\n isSlideX: boolean;\n isSlideY: boolean;\n isSlide: boolean;\n shiftX: number;\n shiftY: number;\n shiftXAbs: number;\n shiftYAbs: number;\n}\n\nexport interface TouchEvent extends Gesture {\n originalEvent: VKUITouchEvent;\n}\n\ntype HoverHandler = (outputEvent: MouseEvent) => void;\nexport type TouchEventHandler = (e: TouchEvent) => void;\nexport type ClickHandler = (e: React.MouseEvent<HTMLElement>) => void;\nexport type DragHandler = (e: React.DragEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Touch\n */\nexport const Touch = ({\n onStart,\n onStartX,\n onStartY,\n onMove: _onMove,\n onMoveX,\n onMoveY,\n onLeave,\n onEnter,\n onEnd: _onEnd,\n onEndX,\n onEndY,\n onClickCapture,\n usePointerHover,\n slideThreshold = 5,\n useCapture = false,\n Component = 'div',\n getRootRef,\n noSlideClick = false,\n stopPropagation = false,\n ...restProps\n}: TouchProps) => {\n const { document } = useDOM();\n const events = React.useMemo(getSupportedEvents, []);\n const didSlide = React.useRef(false);\n const gesture = React.useRef<Partial<Gesture> | null>(null);\n const handle = (e: VKUITouchEvent, handlers: Array<TouchEventHandler | undefined | false>) => {\n stopPropagation && e.stopPropagation();\n handlers.forEach((cb) => {\n const duration = Date.now() - (gesture.current?.startT?.getTime() ?? 0);\n cb && cb({ ...(gesture.current as Gesture), duration, originalEvent: e });\n });\n };\n\n const enterHandler = useEventListener(usePointerHover ? 'pointerenter' : 'mouseenter', onEnter);\n const leaveHandler = useEventListener(usePointerHover ? 'pointerleave' : 'mouseleave', onLeave);\n const startHandler = useEventListener(\n events[0],\n (e: VKUITouchEvent) => {\n gesture.current = initGesture(coordX(e), coordY(e));\n\n handle(e, [onStart, onStartX, onStartY]);\n // 1 line, 2 bad specs, 2 workarounds:\n subscribe(\n touchEnabled()\n ? // Touch events fire on initial target, and won't bubble if its removed\n // see: #235, #1968, https://stackoverflow.com/a/45760014\n (e.target as HTMLElement)\n : // Mouse events fire on the element under pointer, so we lose move / end\n // if pointer goes outside container.\n // Can be fixed by PointerEvents' setPointerCapture later\n document,\n );\n },\n { capture: useCapture, passive: false },\n );\n const containerRef = useExternRef(getRootRef);\n\n useIsomorphicLayoutEffect(() => {\n const el = containerRef.current;\n if (el) {\n enterHandler.add(el);\n leaveHandler.add(el);\n startHandler.add(el);\n }\n }, [Component]);\n\n function onMove(e: VKUITouchEvent) {\n const { isPressed, isX, isY, startX = 0, startY = 0 } = gesture.current ?? {};\n\n if (isPressed) {\n // смещения\n const shiftX = coordX(e) - startX;\n const shiftY = coordY(e) - startY;\n\n // абсолютные значения смещений\n const shiftXAbs = Math.abs(shiftX);\n const shiftYAbs = Math.abs(shiftY);\n\n // Если определяем мультитач, то прерываем жест\n if (!!e.touches && e.touches.length > 1) {\n return onEnd(e);\n }\n\n // если мы ещё не определились\n if (!isX && !isY) {\n const willBeX = shiftXAbs >= slideThreshold && shiftXAbs > shiftYAbs;\n const willBeY = shiftYAbs >= slideThreshold && shiftYAbs > shiftXAbs;\n const willBeSlidedX = willBeX && (!!onMoveX || !!_onMove);\n const willBeSlidedY = willBeY && (!!onMoveY || !!_onMove);\n\n if (gesture.current) {\n Object.assign(gesture.current, {\n isY: willBeY,\n isX: willBeX,\n isSlideX: willBeSlidedX,\n isSlideY: willBeSlidedY,\n isSlide: willBeSlidedX || willBeSlidedY,\n });\n }\n }\n\n if (gesture.current?.isSlide) {\n Object.assign(gesture.current, {\n shiftX,\n shiftY,\n shiftXAbs,\n shiftYAbs,\n });\n\n handle(e, [\n _onMove,\n gesture.current.isSlideX && onMoveX,\n gesture.current.isSlideY && onMoveY,\n ]);\n }\n }\n }\n\n function onEnd(e: VKUITouchEvent) {\n const { isPressed, isSlide, isSlideX, isSlideY } = gesture.current ?? {};\n\n if (isPressed) {\n handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);\n }\n\n const isTouchEnabled = touchEnabled();\n\n if (isTouchEnabled && isSlide) {\n // https://github.com/VKCOM/VKUI/issues/4414\n // если тач-устройство и был зафиксирован touchmove,\n // то событие клика не вызывается\n didSlide.current = false;\n } else {\n didSlide.current = Boolean(isSlide);\n }\n gesture.current = {};\n\n // Если это был тач-евент, симулируем отмену hover\n if (isTouchEnabled) {\n onLeave && onLeave(e);\n }\n unsubscribe();\n }\n\n const listenerParams = { capture: useCapture, passive: false };\n const listeners = [\n useEventListener(events[1], onMove, listenerParams),\n useEventListener(events[2], onEnd, listenerParams),\n useEventListener(events[3], onEnd, listenerParams),\n ];\n function subscribe(el: HTMLElement | Document | null | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n /**\n * Обработчик событий dragstart\n * Отменяет нативное браузерное поведение для вложенных ссылок и изображений\n */\n const onDragStart = (e: React.DragEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'A' || target.tagName === 'IMG') {\n e.preventDefault();\n }\n };\n\n /**\n * Обработчик клика по компоненту\n * Отменяет переход по вложенной ссылке, если был зафиксирован свайп\n */\n const postGestureClick: typeof onClickCapture = (e) => {\n if (!didSlide.current) {\n return onClickCapture && onClickCapture(e);\n }\n\n if (noSlideClick) {\n e.stopPropagation();\n\n // https://github.com/VKCOM/VKUI/issues/1977\n // https://github.com/VKCOM/VKUI/issues/3892\n e.preventDefault();\n } else {\n onClickCapture && onClickCapture(e);\n }\n\n didSlide.current = false;\n };\n\n return (\n <Component\n {...restProps}\n onDragStart={onDragStart}\n onClickCapture={postGestureClick}\n ref={containerRef}\n />\n );\n};\n\nfunction initGesture(startX: number, startY: number): Gesture {\n return {\n startX,\n startY,\n startT: new Date(),\n duration: 0,\n isPressed: true,\n isY: false,\n isX: false,\n isSlideX: false,\n isSlideY: false,\n isSlide: false,\n shiftX: 0,\n shiftY: 0,\n shiftXAbs: 0,\n shiftYAbs: 0,\n };\n}\n"],"mappings":"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"}
@@ -142,11 +142,19 @@ export var Touch = function Touch(_ref) {
142
142
  if (isPressed) {
143
143
  handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);
144
144
  }
145
- didSlide.current = Boolean(isSlide);
145
+ var isTouchEnabled = touchEnabled();
146
+ if (isTouchEnabled && isSlide) {
147
+ // https://github.com/VKCOM/VKUI/issues/4414
148
+ // если тач-устройство и был зафиксирован touchmove,
149
+ // то событие клика не вызывается
150
+ didSlide.current = false;
151
+ } else {
152
+ didSlide.current = Boolean(isSlide);
153
+ }
146
154
  gesture.current = {};
147
155
 
148
156
  // Если это был тач-евент, симулируем отмену hover
149
- if (touchEnabled()) {
157
+ if (isTouchEnabled) {
150
158
  onLeave && onLeave(e);
151
159
  }
152
160
  unsubscribe();
@@ -1 +1 @@
1
- {"version":3,"file":"Touch.js","names":["React","useEventListener","useExternRef","useDOM","coordX","coordY","getSupportedEvents","touchEnabled","useIsomorphicLayoutEffect","Touch","onStart","onStartX","onStartY","_onMove","onMove","onMoveX","onMoveY","onLeave","onEnter","_onEnd","onEnd","onEndX","onEndY","onClickCapture","usePointerHover","slideThreshold","useCapture","Component","getRootRef","noSlideClick","stopPropagation","restProps","document","events","useMemo","didSlide","useRef","gesture","handle","e","handlers","forEach","cb","duration","Date","now","current","startT","getTime","originalEvent","enterHandler","leaveHandler","startHandler","initGesture","subscribe","target","capture","passive","containerRef","el","add","isPressed","isX","isY","startX","startY","shiftX","shiftY","shiftXAbs","Math","abs","shiftYAbs","touches","length","willBeX","willBeY","willBeSlidedX","willBeSlidedY","Object","assign","isSlideX","isSlideY","isSlide","Boolean","unsubscribe","listenerParams","listeners","l","remove","onDragStart","tagName","preventDefault","postGestureClick"],"sources":["../../../src/components/Touch/Touch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useDOM } from '../../lib/dom';\nimport { coordX, coordY, getSupportedEvents, touchEnabled, VKUITouchEvent } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nexport interface TouchProps\n extends React.AllHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLElement>,\n HasComponent {\n /**\n * Привязать onEnter и onLeave через pointer-events - работает на disabled-инпутах\n */\n usePointerHover?: boolean;\n useCapture?: boolean;\n slideThreshold?: number;\n noSlideClick?: boolean;\n onEnter?: HoverHandler;\n onLeave?: HoverHandler;\n onStart?: TouchEventHandler;\n onStartX?: TouchEventHandler;\n onStartY?: TouchEventHandler;\n onMove?: TouchEventHandler;\n onMoveX?: TouchEventHandler;\n onMoveY?: TouchEventHandler;\n onEnd?: TouchEventHandler;\n onEndX?: TouchEventHandler;\n onEndY?: TouchEventHandler;\n stopPropagation?: boolean;\n}\n\nexport interface Gesture {\n startX: number;\n startY: number;\n startT: Date;\n duration: number;\n isPressed: boolean;\n isY: boolean;\n isX: boolean;\n isSlideX: boolean;\n isSlideY: boolean;\n isSlide: boolean;\n shiftX: number;\n shiftY: number;\n shiftXAbs: number;\n shiftYAbs: number;\n}\n\nexport interface TouchEvent extends Gesture {\n originalEvent: VKUITouchEvent;\n}\n\ntype HoverHandler = (outputEvent: MouseEvent) => void;\nexport type TouchEventHandler = (e: TouchEvent) => void;\nexport type ClickHandler = (e: React.MouseEvent<HTMLElement>) => void;\nexport type DragHandler = (e: React.DragEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Touch\n */\nexport const Touch = ({\n onStart,\n onStartX,\n onStartY,\n onMove: _onMove,\n onMoveX,\n onMoveY,\n onLeave,\n onEnter,\n onEnd: _onEnd,\n onEndX,\n onEndY,\n onClickCapture,\n usePointerHover,\n slideThreshold = 5,\n useCapture = false,\n Component = 'div',\n getRootRef,\n noSlideClick = false,\n stopPropagation = false,\n ...restProps\n}: TouchProps) => {\n const { document } = useDOM();\n const events = React.useMemo(getSupportedEvents, []);\n const didSlide = React.useRef(false);\n const gesture = React.useRef<Partial<Gesture> | null>(null);\n const handle = (e: VKUITouchEvent, handlers: Array<TouchEventHandler | undefined | false>) => {\n stopPropagation && e.stopPropagation();\n handlers.forEach((cb) => {\n const duration = Date.now() - (gesture.current?.startT?.getTime() ?? 0);\n cb && cb({ ...(gesture.current as Gesture), duration, originalEvent: e });\n });\n };\n\n const enterHandler = useEventListener(usePointerHover ? 'pointerenter' : 'mouseenter', onEnter);\n const leaveHandler = useEventListener(usePointerHover ? 'pointerleave' : 'mouseleave', onLeave);\n const startHandler = useEventListener(\n events[0],\n (e: VKUITouchEvent) => {\n gesture.current = initGesture(coordX(e), coordY(e));\n\n handle(e, [onStart, onStartX, onStartY]);\n // 1 line, 2 bad specs, 2 workarounds:\n subscribe(\n touchEnabled()\n ? // Touch events fire on initial target, and won't bubble if its removed\n // see: #235, #1968, https://stackoverflow.com/a/45760014\n (e.target as HTMLElement)\n : // Mouse events fire on the element under pointer, so we lose move / end\n // if pointer goes outside container.\n // Can be fixed by PointerEvents' setPointerCapture later\n document,\n );\n },\n { capture: useCapture, passive: false },\n );\n const containerRef = useExternRef(getRootRef);\n\n useIsomorphicLayoutEffect(() => {\n const el = containerRef.current;\n if (el) {\n enterHandler.add(el);\n leaveHandler.add(el);\n startHandler.add(el);\n }\n }, [Component]);\n\n function onMove(e: VKUITouchEvent) {\n const { isPressed, isX, isY, startX = 0, startY = 0 } = gesture.current ?? {};\n\n if (isPressed) {\n // смещения\n const shiftX = coordX(e) - startX;\n const shiftY = coordY(e) - startY;\n\n // абсолютные значения смещений\n const shiftXAbs = Math.abs(shiftX);\n const shiftYAbs = Math.abs(shiftY);\n\n // Если определяем мультитач, то прерываем жест\n if (!!e.touches && e.touches.length > 1) {\n return onEnd(e);\n }\n\n // если мы ещё не определились\n if (!isX && !isY) {\n const willBeX = shiftXAbs >= slideThreshold && shiftXAbs > shiftYAbs;\n const willBeY = shiftYAbs >= slideThreshold && shiftYAbs > shiftXAbs;\n const willBeSlidedX = willBeX && (!!onMoveX || !!_onMove);\n const willBeSlidedY = willBeY && (!!onMoveY || !!_onMove);\n\n if (gesture.current) {\n Object.assign(gesture.current, {\n isY: willBeY,\n isX: willBeX,\n isSlideX: willBeSlidedX,\n isSlideY: willBeSlidedY,\n isSlide: willBeSlidedX || willBeSlidedY,\n });\n }\n }\n\n if (gesture.current?.isSlide) {\n Object.assign(gesture.current, {\n shiftX,\n shiftY,\n shiftXAbs,\n shiftYAbs,\n });\n\n handle(e, [\n _onMove,\n gesture.current.isSlideX && onMoveX,\n gesture.current.isSlideY && onMoveY,\n ]);\n }\n }\n }\n\n function onEnd(e: VKUITouchEvent) {\n const { isPressed, isSlide, isSlideX, isSlideY } = gesture.current ?? {};\n\n if (isPressed) {\n handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);\n }\n\n didSlide.current = Boolean(isSlide);\n gesture.current = {};\n\n // Если это был тач-евент, симулируем отмену hover\n if (touchEnabled()) {\n onLeave && onLeave(e);\n }\n unsubscribe();\n }\n\n const listenerParams = { capture: useCapture, passive: false };\n const listeners = [\n useEventListener(events[1], onMove, listenerParams),\n useEventListener(events[2], onEnd, listenerParams),\n useEventListener(events[3], onEnd, listenerParams),\n ];\n function subscribe(el: HTMLElement | Document | null | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n /**\n * Обработчик событий dragstart\n * Отменяет нативное браузерное поведение для вложенных ссылок и изображений\n */\n const onDragStart = (e: React.DragEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'A' || target.tagName === 'IMG') {\n e.preventDefault();\n }\n };\n\n /**\n * Обработчик клика по компоненту\n * Отменяет переход по вложенной ссылке, если был зафиксирован свайп\n */\n const postGestureClick: typeof onClickCapture = (e) => {\n if (!didSlide.current) {\n return onClickCapture && onClickCapture(e);\n }\n\n if (noSlideClick) {\n e.stopPropagation();\n\n // https://github.com/VKCOM/VKUI/issues/1977\n // https://github.com/VKCOM/VKUI/issues/3892\n e.preventDefault();\n } else {\n onClickCapture && onClickCapture(e);\n }\n\n didSlide.current = false;\n };\n\n return (\n <Component\n {...restProps}\n onDragStart={onDragStart}\n onClickCapture={postGestureClick}\n ref={containerRef}\n />\n );\n};\n\nfunction initGesture(startX: number, startY: number): Gesture {\n return {\n startX,\n startY,\n startT: new Date(),\n duration: 0,\n isPressed: true,\n isY: false,\n isX: false,\n isSlideX: false,\n isSlideY: false,\n isSlide: false,\n shiftX: 0,\n shiftY: 0,\n shiftXAbs: 0,\n shiftYAbs: 0,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Touch.js","names":["React","useEventListener","useExternRef","useDOM","coordX","coordY","getSupportedEvents","touchEnabled","useIsomorphicLayoutEffect","Touch","onStart","onStartX","onStartY","_onMove","onMove","onMoveX","onMoveY","onLeave","onEnter","_onEnd","onEnd","onEndX","onEndY","onClickCapture","usePointerHover","slideThreshold","useCapture","Component","getRootRef","noSlideClick","stopPropagation","restProps","document","events","useMemo","didSlide","useRef","gesture","handle","e","handlers","forEach","cb","duration","Date","now","current","startT","getTime","originalEvent","enterHandler","leaveHandler","startHandler","initGesture","subscribe","target","capture","passive","containerRef","el","add","isPressed","isX","isY","startX","startY","shiftX","shiftY","shiftXAbs","Math","abs","shiftYAbs","touches","length","willBeX","willBeY","willBeSlidedX","willBeSlidedY","Object","assign","isSlideX","isSlideY","isSlide","isTouchEnabled","Boolean","unsubscribe","listenerParams","listeners","l","remove","onDragStart","tagName","preventDefault","postGestureClick"],"sources":["../../../src/components/Touch/Touch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useDOM } from '../../lib/dom';\nimport { coordX, coordY, getSupportedEvents, touchEnabled, VKUITouchEvent } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nexport interface TouchProps\n extends React.AllHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLElement>,\n HasComponent {\n /**\n * Привязать onEnter и onLeave через pointer-events - работает на disabled-инпутах\n */\n usePointerHover?: boolean;\n useCapture?: boolean;\n slideThreshold?: number;\n noSlideClick?: boolean;\n onEnter?: HoverHandler;\n onLeave?: HoverHandler;\n onStart?: TouchEventHandler;\n onStartX?: TouchEventHandler;\n onStartY?: TouchEventHandler;\n onMove?: TouchEventHandler;\n onMoveX?: TouchEventHandler;\n onMoveY?: TouchEventHandler;\n onEnd?: TouchEventHandler;\n onEndX?: TouchEventHandler;\n onEndY?: TouchEventHandler;\n stopPropagation?: boolean;\n}\n\nexport interface Gesture {\n startX: number;\n startY: number;\n startT: Date;\n duration: number;\n isPressed: boolean;\n isY: boolean;\n isX: boolean;\n isSlideX: boolean;\n isSlideY: boolean;\n isSlide: boolean;\n shiftX: number;\n shiftY: number;\n shiftXAbs: number;\n shiftYAbs: number;\n}\n\nexport interface TouchEvent extends Gesture {\n originalEvent: VKUITouchEvent;\n}\n\ntype HoverHandler = (outputEvent: MouseEvent) => void;\nexport type TouchEventHandler = (e: TouchEvent) => void;\nexport type ClickHandler = (e: React.MouseEvent<HTMLElement>) => void;\nexport type DragHandler = (e: React.DragEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Touch\n */\nexport const Touch = ({\n onStart,\n onStartX,\n onStartY,\n onMove: _onMove,\n onMoveX,\n onMoveY,\n onLeave,\n onEnter,\n onEnd: _onEnd,\n onEndX,\n onEndY,\n onClickCapture,\n usePointerHover,\n slideThreshold = 5,\n useCapture = false,\n Component = 'div',\n getRootRef,\n noSlideClick = false,\n stopPropagation = false,\n ...restProps\n}: TouchProps) => {\n const { document } = useDOM();\n const events = React.useMemo(getSupportedEvents, []);\n const didSlide = React.useRef(false);\n const gesture = React.useRef<Partial<Gesture> | null>(null);\n const handle = (e: VKUITouchEvent, handlers: Array<TouchEventHandler | undefined | false>) => {\n stopPropagation && e.stopPropagation();\n handlers.forEach((cb) => {\n const duration = Date.now() - (gesture.current?.startT?.getTime() ?? 0);\n cb && cb({ ...(gesture.current as Gesture), duration, originalEvent: e });\n });\n };\n\n const enterHandler = useEventListener(usePointerHover ? 'pointerenter' : 'mouseenter', onEnter);\n const leaveHandler = useEventListener(usePointerHover ? 'pointerleave' : 'mouseleave', onLeave);\n const startHandler = useEventListener(\n events[0],\n (e: VKUITouchEvent) => {\n gesture.current = initGesture(coordX(e), coordY(e));\n\n handle(e, [onStart, onStartX, onStartY]);\n // 1 line, 2 bad specs, 2 workarounds:\n subscribe(\n touchEnabled()\n ? // Touch events fire on initial target, and won't bubble if its removed\n // see: #235, #1968, https://stackoverflow.com/a/45760014\n (e.target as HTMLElement)\n : // Mouse events fire on the element under pointer, so we lose move / end\n // if pointer goes outside container.\n // Can be fixed by PointerEvents' setPointerCapture later\n document,\n );\n },\n { capture: useCapture, passive: false },\n );\n const containerRef = useExternRef(getRootRef);\n\n useIsomorphicLayoutEffect(() => {\n const el = containerRef.current;\n if (el) {\n enterHandler.add(el);\n leaveHandler.add(el);\n startHandler.add(el);\n }\n }, [Component]);\n\n function onMove(e: VKUITouchEvent) {\n const { isPressed, isX, isY, startX = 0, startY = 0 } = gesture.current ?? {};\n\n if (isPressed) {\n // смещения\n const shiftX = coordX(e) - startX;\n const shiftY = coordY(e) - startY;\n\n // абсолютные значения смещений\n const shiftXAbs = Math.abs(shiftX);\n const shiftYAbs = Math.abs(shiftY);\n\n // Если определяем мультитач, то прерываем жест\n if (!!e.touches && e.touches.length > 1) {\n return onEnd(e);\n }\n\n // если мы ещё не определились\n if (!isX && !isY) {\n const willBeX = shiftXAbs >= slideThreshold && shiftXAbs > shiftYAbs;\n const willBeY = shiftYAbs >= slideThreshold && shiftYAbs > shiftXAbs;\n const willBeSlidedX = willBeX && (!!onMoveX || !!_onMove);\n const willBeSlidedY = willBeY && (!!onMoveY || !!_onMove);\n\n if (gesture.current) {\n Object.assign(gesture.current, {\n isY: willBeY,\n isX: willBeX,\n isSlideX: willBeSlidedX,\n isSlideY: willBeSlidedY,\n isSlide: willBeSlidedX || willBeSlidedY,\n });\n }\n }\n\n if (gesture.current?.isSlide) {\n Object.assign(gesture.current, {\n shiftX,\n shiftY,\n shiftXAbs,\n shiftYAbs,\n });\n\n handle(e, [\n _onMove,\n gesture.current.isSlideX && onMoveX,\n gesture.current.isSlideY && onMoveY,\n ]);\n }\n }\n }\n\n function onEnd(e: VKUITouchEvent) {\n const { isPressed, isSlide, isSlideX, isSlideY } = gesture.current ?? {};\n\n if (isPressed) {\n handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);\n }\n\n const isTouchEnabled = touchEnabled();\n\n if (isTouchEnabled && isSlide) {\n // https://github.com/VKCOM/VKUI/issues/4414\n // если тач-устройство и был зафиксирован touchmove,\n // то событие клика не вызывается\n didSlide.current = false;\n } else {\n didSlide.current = Boolean(isSlide);\n }\n gesture.current = {};\n\n // Если это был тач-евент, симулируем отмену hover\n if (isTouchEnabled) {\n onLeave && onLeave(e);\n }\n unsubscribe();\n }\n\n const listenerParams = { capture: useCapture, passive: false };\n const listeners = [\n useEventListener(events[1], onMove, listenerParams),\n useEventListener(events[2], onEnd, listenerParams),\n useEventListener(events[3], onEnd, listenerParams),\n ];\n function subscribe(el: HTMLElement | Document | null | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n /**\n * Обработчик событий dragstart\n * Отменяет нативное браузерное поведение для вложенных ссылок и изображений\n */\n const onDragStart = (e: React.DragEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'A' || target.tagName === 'IMG') {\n e.preventDefault();\n }\n };\n\n /**\n * Обработчик клика по компоненту\n * Отменяет переход по вложенной ссылке, если был зафиксирован свайп\n */\n const postGestureClick: typeof onClickCapture = (e) => {\n if (!didSlide.current) {\n return onClickCapture && onClickCapture(e);\n }\n\n if (noSlideClick) {\n e.stopPropagation();\n\n // https://github.com/VKCOM/VKUI/issues/1977\n // https://github.com/VKCOM/VKUI/issues/3892\n e.preventDefault();\n } else {\n onClickCapture && onClickCapture(e);\n }\n\n didSlide.current = false;\n };\n\n return (\n <Component\n {...restProps}\n onDragStart={onDragStart}\n onClickCapture={postGestureClick}\n ref={containerRef}\n />\n );\n};\n\nfunction initGesture(startX: number, startY: number): Gesture {\n return {\n startX,\n startY,\n startT: new Date(),\n duration: 0,\n isPressed: true,\n isY: false,\n isX: false,\n isSlideX: false,\n isSlideY: false,\n isSlide: false,\n shiftX: 0,\n shiftY: 0,\n shiftXAbs: 0,\n shiftYAbs: 0,\n };\n}\n"],"mappings":"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"}
@@ -9903,11 +9903,19 @@ var Touch = function Touch(_ref) {
9903
9903
  if (isPressed) {
9904
9904
  handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);
9905
9905
  }
9906
- didSlide.current = Boolean(isSlide);
9906
+ var isTouchEnabled = (0,_lib_touch__WEBPACK_IMPORTED_MODULE_5__.touchEnabled)();
9907
+ if (isTouchEnabled && isSlide) {
9908
+ // https://github.com/VKCOM/VKUI/issues/4414
9909
+ // если тач-устройство и был зафиксирован touchmove,
9910
+ // то событие клика не вызывается
9911
+ didSlide.current = false;
9912
+ } else {
9913
+ didSlide.current = Boolean(isSlide);
9914
+ }
9907
9915
  gesture.current = {};
9908
9916
 
9909
9917
  // Если это был тач-евент, симулируем отмену hover
9910
- if ((0,_lib_touch__WEBPACK_IMPORTED_MODULE_5__.touchEnabled)()) {
9918
+ if (isTouchEnabled) {
9911
9919
  onLeave && onLeave(e);
9912
9920
  }
9913
9921
  unsubscribe();
@@ -142,11 +142,19 @@ export var Touch = function Touch(_ref) {
142
142
  if (isPressed) {
143
143
  handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);
144
144
  }
145
- didSlide.current = Boolean(isSlide);
145
+ var isTouchEnabled = touchEnabled();
146
+ if (isTouchEnabled && isSlide) {
147
+ // https://github.com/VKCOM/VKUI/issues/4414
148
+ // если тач-устройство и был зафиксирован touchmove,
149
+ // то событие клика не вызывается
150
+ didSlide.current = false;
151
+ } else {
152
+ didSlide.current = Boolean(isSlide);
153
+ }
146
154
  gesture.current = {};
147
155
 
148
156
  // Если это был тач-евент, симулируем отмену hover
149
- if (touchEnabled()) {
157
+ if (isTouchEnabled) {
150
158
  onLeave && onLeave(e);
151
159
  }
152
160
  unsubscribe();
@@ -1 +1 @@
1
- {"version":3,"file":"Touch.js","names":["React","useEventListener","useExternRef","useDOM","coordX","coordY","getSupportedEvents","touchEnabled","useIsomorphicLayoutEffect","Touch","onStart","onStartX","onStartY","_onMove","onMove","onMoveX","onMoveY","onLeave","onEnter","_onEnd","onEnd","onEndX","onEndY","onClickCapture","usePointerHover","slideThreshold","useCapture","Component","getRootRef","noSlideClick","stopPropagation","restProps","document","events","useMemo","didSlide","useRef","gesture","handle","e","handlers","forEach","cb","duration","Date","now","current","startT","getTime","originalEvent","enterHandler","leaveHandler","startHandler","initGesture","subscribe","target","capture","passive","containerRef","el","add","isPressed","isX","isY","startX","startY","shiftX","shiftY","shiftXAbs","Math","abs","shiftYAbs","touches","length","willBeX","willBeY","willBeSlidedX","willBeSlidedY","Object","assign","isSlideX","isSlideY","isSlide","Boolean","unsubscribe","listenerParams","listeners","l","remove","onDragStart","tagName","preventDefault","postGestureClick"],"sources":["../../../../src/components/Touch/Touch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useDOM } from '../../lib/dom';\nimport { coordX, coordY, getSupportedEvents, touchEnabled, VKUITouchEvent } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nexport interface TouchProps\n extends React.AllHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLElement>,\n HasComponent {\n /**\n * Привязать onEnter и onLeave через pointer-events - работает на disabled-инпутах\n */\n usePointerHover?: boolean;\n useCapture?: boolean;\n slideThreshold?: number;\n noSlideClick?: boolean;\n onEnter?: HoverHandler;\n onLeave?: HoverHandler;\n onStart?: TouchEventHandler;\n onStartX?: TouchEventHandler;\n onStartY?: TouchEventHandler;\n onMove?: TouchEventHandler;\n onMoveX?: TouchEventHandler;\n onMoveY?: TouchEventHandler;\n onEnd?: TouchEventHandler;\n onEndX?: TouchEventHandler;\n onEndY?: TouchEventHandler;\n stopPropagation?: boolean;\n}\n\nexport interface Gesture {\n startX: number;\n startY: number;\n startT: Date;\n duration: number;\n isPressed: boolean;\n isY: boolean;\n isX: boolean;\n isSlideX: boolean;\n isSlideY: boolean;\n isSlide: boolean;\n shiftX: number;\n shiftY: number;\n shiftXAbs: number;\n shiftYAbs: number;\n}\n\nexport interface TouchEvent extends Gesture {\n originalEvent: VKUITouchEvent;\n}\n\ntype HoverHandler = (outputEvent: MouseEvent) => void;\nexport type TouchEventHandler = (e: TouchEvent) => void;\nexport type ClickHandler = (e: React.MouseEvent<HTMLElement>) => void;\nexport type DragHandler = (e: React.DragEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Touch\n */\nexport const Touch = ({\n onStart,\n onStartX,\n onStartY,\n onMove: _onMove,\n onMoveX,\n onMoveY,\n onLeave,\n onEnter,\n onEnd: _onEnd,\n onEndX,\n onEndY,\n onClickCapture,\n usePointerHover,\n slideThreshold = 5,\n useCapture = false,\n Component = 'div',\n getRootRef,\n noSlideClick = false,\n stopPropagation = false,\n ...restProps\n}: TouchProps) => {\n const { document } = useDOM();\n const events = React.useMemo(getSupportedEvents, []);\n const didSlide = React.useRef(false);\n const gesture = React.useRef<Partial<Gesture> | null>(null);\n const handle = (e: VKUITouchEvent, handlers: Array<TouchEventHandler | undefined | false>) => {\n stopPropagation && e.stopPropagation();\n handlers.forEach((cb) => {\n const duration = Date.now() - (gesture.current?.startT?.getTime() ?? 0);\n cb && cb({ ...(gesture.current as Gesture), duration, originalEvent: e });\n });\n };\n\n const enterHandler = useEventListener(usePointerHover ? 'pointerenter' : 'mouseenter', onEnter);\n const leaveHandler = useEventListener(usePointerHover ? 'pointerleave' : 'mouseleave', onLeave);\n const startHandler = useEventListener(\n events[0],\n (e: VKUITouchEvent) => {\n gesture.current = initGesture(coordX(e), coordY(e));\n\n handle(e, [onStart, onStartX, onStartY]);\n // 1 line, 2 bad specs, 2 workarounds:\n subscribe(\n touchEnabled()\n ? // Touch events fire on initial target, and won't bubble if its removed\n // see: #235, #1968, https://stackoverflow.com/a/45760014\n (e.target as HTMLElement)\n : // Mouse events fire on the element under pointer, so we lose move / end\n // if pointer goes outside container.\n // Can be fixed by PointerEvents' setPointerCapture later\n document,\n );\n },\n { capture: useCapture, passive: false },\n );\n const containerRef = useExternRef(getRootRef);\n\n useIsomorphicLayoutEffect(() => {\n const el = containerRef.current;\n if (el) {\n enterHandler.add(el);\n leaveHandler.add(el);\n startHandler.add(el);\n }\n }, [Component]);\n\n function onMove(e: VKUITouchEvent) {\n const { isPressed, isX, isY, startX = 0, startY = 0 } = gesture.current ?? {};\n\n if (isPressed) {\n // смещения\n const shiftX = coordX(e) - startX;\n const shiftY = coordY(e) - startY;\n\n // абсолютные значения смещений\n const shiftXAbs = Math.abs(shiftX);\n const shiftYAbs = Math.abs(shiftY);\n\n // Если определяем мультитач, то прерываем жест\n if (!!e.touches && e.touches.length > 1) {\n return onEnd(e);\n }\n\n // если мы ещё не определились\n if (!isX && !isY) {\n const willBeX = shiftXAbs >= slideThreshold && shiftXAbs > shiftYAbs;\n const willBeY = shiftYAbs >= slideThreshold && shiftYAbs > shiftXAbs;\n const willBeSlidedX = willBeX && (!!onMoveX || !!_onMove);\n const willBeSlidedY = willBeY && (!!onMoveY || !!_onMove);\n\n if (gesture.current) {\n Object.assign(gesture.current, {\n isY: willBeY,\n isX: willBeX,\n isSlideX: willBeSlidedX,\n isSlideY: willBeSlidedY,\n isSlide: willBeSlidedX || willBeSlidedY,\n });\n }\n }\n\n if (gesture.current?.isSlide) {\n Object.assign(gesture.current, {\n shiftX,\n shiftY,\n shiftXAbs,\n shiftYAbs,\n });\n\n handle(e, [\n _onMove,\n gesture.current.isSlideX && onMoveX,\n gesture.current.isSlideY && onMoveY,\n ]);\n }\n }\n }\n\n function onEnd(e: VKUITouchEvent) {\n const { isPressed, isSlide, isSlideX, isSlideY } = gesture.current ?? {};\n\n if (isPressed) {\n handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);\n }\n\n didSlide.current = Boolean(isSlide);\n gesture.current = {};\n\n // Если это был тач-евент, симулируем отмену hover\n if (touchEnabled()) {\n onLeave && onLeave(e);\n }\n unsubscribe();\n }\n\n const listenerParams = { capture: useCapture, passive: false };\n const listeners = [\n useEventListener(events[1], onMove, listenerParams),\n useEventListener(events[2], onEnd, listenerParams),\n useEventListener(events[3], onEnd, listenerParams),\n ];\n function subscribe(el: HTMLElement | Document | null | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n /**\n * Обработчик событий dragstart\n * Отменяет нативное браузерное поведение для вложенных ссылок и изображений\n */\n const onDragStart = (e: React.DragEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'A' || target.tagName === 'IMG') {\n e.preventDefault();\n }\n };\n\n /**\n * Обработчик клика по компоненту\n * Отменяет переход по вложенной ссылке, если был зафиксирован свайп\n */\n const postGestureClick: typeof onClickCapture = (e) => {\n if (!didSlide.current) {\n return onClickCapture && onClickCapture(e);\n }\n\n if (noSlideClick) {\n e.stopPropagation();\n\n // https://github.com/VKCOM/VKUI/issues/1977\n // https://github.com/VKCOM/VKUI/issues/3892\n e.preventDefault();\n } else {\n onClickCapture && onClickCapture(e);\n }\n\n didSlide.current = false;\n };\n\n return (\n <Component\n {...restProps}\n onDragStart={onDragStart}\n onClickCapture={postGestureClick}\n ref={containerRef}\n />\n );\n};\n\nfunction initGesture(startX: number, startY: number): Gesture {\n return {\n startX,\n startY,\n startT: new Date(),\n duration: 0,\n isPressed: true,\n isY: false,\n isX: false,\n isSlideX: false,\n isSlideY: false,\n isSlide: false,\n shiftX: 0,\n shiftY: 0,\n shiftXAbs: 0,\n shiftYAbs: 0,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Touch.js","names":["React","useEventListener","useExternRef","useDOM","coordX","coordY","getSupportedEvents","touchEnabled","useIsomorphicLayoutEffect","Touch","onStart","onStartX","onStartY","_onMove","onMove","onMoveX","onMoveY","onLeave","onEnter","_onEnd","onEnd","onEndX","onEndY","onClickCapture","usePointerHover","slideThreshold","useCapture","Component","getRootRef","noSlideClick","stopPropagation","restProps","document","events","useMemo","didSlide","useRef","gesture","handle","e","handlers","forEach","cb","duration","Date","now","current","startT","getTime","originalEvent","enterHandler","leaveHandler","startHandler","initGesture","subscribe","target","capture","passive","containerRef","el","add","isPressed","isX","isY","startX","startY","shiftX","shiftY","shiftXAbs","Math","abs","shiftYAbs","touches","length","willBeX","willBeY","willBeSlidedX","willBeSlidedY","Object","assign","isSlideX","isSlideY","isSlide","isTouchEnabled","Boolean","unsubscribe","listenerParams","listeners","l","remove","onDragStart","tagName","preventDefault","postGestureClick"],"sources":["../../../../src/components/Touch/Touch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useDOM } from '../../lib/dom';\nimport { coordX, coordY, getSupportedEvents, touchEnabled, VKUITouchEvent } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { HasComponent, HasRootRef } from '../../types';\n\nexport interface TouchProps\n extends React.AllHTMLAttributes<HTMLElement>,\n HasRootRef<HTMLElement>,\n HasComponent {\n /**\n * Привязать onEnter и onLeave через pointer-events - работает на disabled-инпутах\n */\n usePointerHover?: boolean;\n useCapture?: boolean;\n slideThreshold?: number;\n noSlideClick?: boolean;\n onEnter?: HoverHandler;\n onLeave?: HoverHandler;\n onStart?: TouchEventHandler;\n onStartX?: TouchEventHandler;\n onStartY?: TouchEventHandler;\n onMove?: TouchEventHandler;\n onMoveX?: TouchEventHandler;\n onMoveY?: TouchEventHandler;\n onEnd?: TouchEventHandler;\n onEndX?: TouchEventHandler;\n onEndY?: TouchEventHandler;\n stopPropagation?: boolean;\n}\n\nexport interface Gesture {\n startX: number;\n startY: number;\n startT: Date;\n duration: number;\n isPressed: boolean;\n isY: boolean;\n isX: boolean;\n isSlideX: boolean;\n isSlideY: boolean;\n isSlide: boolean;\n shiftX: number;\n shiftY: number;\n shiftXAbs: number;\n shiftYAbs: number;\n}\n\nexport interface TouchEvent extends Gesture {\n originalEvent: VKUITouchEvent;\n}\n\ntype HoverHandler = (outputEvent: MouseEvent) => void;\nexport type TouchEventHandler = (e: TouchEvent) => void;\nexport type ClickHandler = (e: React.MouseEvent<HTMLElement>) => void;\nexport type DragHandler = (e: React.DragEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Touch\n */\nexport const Touch = ({\n onStart,\n onStartX,\n onStartY,\n onMove: _onMove,\n onMoveX,\n onMoveY,\n onLeave,\n onEnter,\n onEnd: _onEnd,\n onEndX,\n onEndY,\n onClickCapture,\n usePointerHover,\n slideThreshold = 5,\n useCapture = false,\n Component = 'div',\n getRootRef,\n noSlideClick = false,\n stopPropagation = false,\n ...restProps\n}: TouchProps) => {\n const { document } = useDOM();\n const events = React.useMemo(getSupportedEvents, []);\n const didSlide = React.useRef(false);\n const gesture = React.useRef<Partial<Gesture> | null>(null);\n const handle = (e: VKUITouchEvent, handlers: Array<TouchEventHandler | undefined | false>) => {\n stopPropagation && e.stopPropagation();\n handlers.forEach((cb) => {\n const duration = Date.now() - (gesture.current?.startT?.getTime() ?? 0);\n cb && cb({ ...(gesture.current as Gesture), duration, originalEvent: e });\n });\n };\n\n const enterHandler = useEventListener(usePointerHover ? 'pointerenter' : 'mouseenter', onEnter);\n const leaveHandler = useEventListener(usePointerHover ? 'pointerleave' : 'mouseleave', onLeave);\n const startHandler = useEventListener(\n events[0],\n (e: VKUITouchEvent) => {\n gesture.current = initGesture(coordX(e), coordY(e));\n\n handle(e, [onStart, onStartX, onStartY]);\n // 1 line, 2 bad specs, 2 workarounds:\n subscribe(\n touchEnabled()\n ? // Touch events fire on initial target, and won't bubble if its removed\n // see: #235, #1968, https://stackoverflow.com/a/45760014\n (e.target as HTMLElement)\n : // Mouse events fire on the element under pointer, so we lose move / end\n // if pointer goes outside container.\n // Can be fixed by PointerEvents' setPointerCapture later\n document,\n );\n },\n { capture: useCapture, passive: false },\n );\n const containerRef = useExternRef(getRootRef);\n\n useIsomorphicLayoutEffect(() => {\n const el = containerRef.current;\n if (el) {\n enterHandler.add(el);\n leaveHandler.add(el);\n startHandler.add(el);\n }\n }, [Component]);\n\n function onMove(e: VKUITouchEvent) {\n const { isPressed, isX, isY, startX = 0, startY = 0 } = gesture.current ?? {};\n\n if (isPressed) {\n // смещения\n const shiftX = coordX(e) - startX;\n const shiftY = coordY(e) - startY;\n\n // абсолютные значения смещений\n const shiftXAbs = Math.abs(shiftX);\n const shiftYAbs = Math.abs(shiftY);\n\n // Если определяем мультитач, то прерываем жест\n if (!!e.touches && e.touches.length > 1) {\n return onEnd(e);\n }\n\n // если мы ещё не определились\n if (!isX && !isY) {\n const willBeX = shiftXAbs >= slideThreshold && shiftXAbs > shiftYAbs;\n const willBeY = shiftYAbs >= slideThreshold && shiftYAbs > shiftXAbs;\n const willBeSlidedX = willBeX && (!!onMoveX || !!_onMove);\n const willBeSlidedY = willBeY && (!!onMoveY || !!_onMove);\n\n if (gesture.current) {\n Object.assign(gesture.current, {\n isY: willBeY,\n isX: willBeX,\n isSlideX: willBeSlidedX,\n isSlideY: willBeSlidedY,\n isSlide: willBeSlidedX || willBeSlidedY,\n });\n }\n }\n\n if (gesture.current?.isSlide) {\n Object.assign(gesture.current, {\n shiftX,\n shiftY,\n shiftXAbs,\n shiftYAbs,\n });\n\n handle(e, [\n _onMove,\n gesture.current.isSlideX && onMoveX,\n gesture.current.isSlideY && onMoveY,\n ]);\n }\n }\n }\n\n function onEnd(e: VKUITouchEvent) {\n const { isPressed, isSlide, isSlideX, isSlideY } = gesture.current ?? {};\n\n if (isPressed) {\n handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);\n }\n\n const isTouchEnabled = touchEnabled();\n\n if (isTouchEnabled && isSlide) {\n // https://github.com/VKCOM/VKUI/issues/4414\n // если тач-устройство и был зафиксирован touchmove,\n // то событие клика не вызывается\n didSlide.current = false;\n } else {\n didSlide.current = Boolean(isSlide);\n }\n gesture.current = {};\n\n // Если это был тач-евент, симулируем отмену hover\n if (isTouchEnabled) {\n onLeave && onLeave(e);\n }\n unsubscribe();\n }\n\n const listenerParams = { capture: useCapture, passive: false };\n const listeners = [\n useEventListener(events[1], onMove, listenerParams),\n useEventListener(events[2], onEnd, listenerParams),\n useEventListener(events[3], onEnd, listenerParams),\n ];\n function subscribe(el: HTMLElement | Document | null | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n /**\n * Обработчик событий dragstart\n * Отменяет нативное браузерное поведение для вложенных ссылок и изображений\n */\n const onDragStart = (e: React.DragEvent<HTMLElement>) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'A' || target.tagName === 'IMG') {\n e.preventDefault();\n }\n };\n\n /**\n * Обработчик клика по компоненту\n * Отменяет переход по вложенной ссылке, если был зафиксирован свайп\n */\n const postGestureClick: typeof onClickCapture = (e) => {\n if (!didSlide.current) {\n return onClickCapture && onClickCapture(e);\n }\n\n if (noSlideClick) {\n e.stopPropagation();\n\n // https://github.com/VKCOM/VKUI/issues/1977\n // https://github.com/VKCOM/VKUI/issues/3892\n e.preventDefault();\n } else {\n onClickCapture && onClickCapture(e);\n }\n\n didSlide.current = false;\n };\n\n return (\n <Component\n {...restProps}\n onDragStart={onDragStart}\n onClickCapture={postGestureClick}\n ref={containerRef}\n />\n );\n};\n\nfunction initGesture(startX: number, startY: number): Gesture {\n return {\n startX,\n startY,\n startT: new Date(),\n duration: 0,\n isPressed: true,\n isY: false,\n isX: false,\n isSlideX: false,\n isSlideY: false,\n isSlide: false,\n shiftX: 0,\n shiftY: 0,\n shiftXAbs: 0,\n shiftYAbs: 0,\n };\n}\n"],"mappings":"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"}
package/dist/vkui.js.tmp CHANGED
@@ -10452,11 +10452,19 @@ var Touch = function Touch(_ref) {
10452
10452
  if (isPressed) {
10453
10453
  handle(e, [_onEnd, isSlideY && onEndY, isSlideX && onEndX]);
10454
10454
  }
10455
- didSlide.current = Boolean(isSlide);
10455
+ var isTouchEnabled = (0,_lib_touch__WEBPACK_IMPORTED_MODULE_5__.touchEnabled)();
10456
+ if (isTouchEnabled && isSlide) {
10457
+ // https://github.com/VKCOM/VKUI/issues/4414
10458
+ // если тач-устройство и был зафиксирован touchmove,
10459
+ // то событие клика не вызывается
10460
+ didSlide.current = false;
10461
+ } else {
10462
+ didSlide.current = Boolean(isSlide);
10463
+ }
10456
10464
  gesture.current = {};
10457
10465
 
10458
10466
  // Если это был тач-евент, симулируем отмену hover
10459
- if ((0,_lib_touch__WEBPACK_IMPORTED_MODULE_5__.touchEnabled)()) {
10467
+ if (isTouchEnabled) {
10460
10468
  onLeave && onLeave(e);
10461
10469
  }
10462
10470
  unsubscribe();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "private": false,
3
- "version": "5.2.2",
3
+ "version": "5.2.3",
4
4
  "name": "@vkontakte/vkui",
5
5
  "description": "VKUI library",
6
6
  "main": "dist/cjs/index.js",