{"version":3,"file":"use-tab-nav-touch.mjs","names":[],"sources":["../../../../../../../packages/components/tabs/src/composables/use-tab-nav-touch.ts"],"sourcesContent":["import { computed, ref } from 'vue'\nimport { clamp, isUndefined } from 'lodash-unified'\nimport { getClientXY } from '@element-plus/utils'\n\nimport type { ComputedRef, Ref } from 'vue'\n\nexport interface Scrollable {\n  next?: boolean\n  prev?: number\n}\n\ninterface TouchState {\n  startX: number\n  startY: number\n  startOffset: number\n}\n\nconst TOUCH_SCROLL_THRESHOLD = 5\n\ninterface UseTabNavTouchParams {\n  scrollable: Ref<false | Scrollable>\n  navOffset: Ref<number>\n  navSize: ComputedRef<number>\n  navContainerSize: ComputedRef<number>\n  isHorizontal: ComputedRef<boolean>\n}\n\nexport const useTabNavTouch = ({\n  scrollable,\n  navOffset,\n  navSize,\n  navContainerSize,\n  isHorizontal,\n}: UseTabNavTouchParams) => {\n  const isTouchScrolling = ref(false)\n  const maxOffset = computed(() =>\n    Math.max(navSize.value - navContainerSize.value, 0)\n  )\n  let touchState: TouchState | undefined\n  let isMainAxisTouch: boolean | undefined\n\n  const handleTouchStart = (event: TouchEvent) => {\n    if (!scrollable.value || event.touches.length !== 1) return\n\n    const { clientX, clientY } = getClientXY(event)\n    touchState = {\n      startX: clientX,\n      startY: clientY,\n      startOffset: navOffset.value,\n    }\n    isMainAxisTouch = undefined\n  }\n\n  const handleTouchMove = (event: TouchEvent) => {\n    if (!touchState || !scrollable.value) return\n\n    if (event.touches.length !== 1) {\n      handleTouchEnd()\n      return\n    }\n\n    const { clientX, clientY } = getClientXY(event)\n    const deltaX = touchState.startX - clientX\n    const deltaY = touchState.startY - clientY\n    const mainAxisDelta = isHorizontal.value ? deltaX : deltaY\n    const crossAxisDelta = isHorizontal.value ? deltaY : deltaX\n    const mainAxisDistance = Math.abs(mainAxisDelta)\n    const crossAxisDistance = Math.abs(crossAxisDelta)\n\n    if (isUndefined(isMainAxisTouch)) {\n      if (\n        Math.max(mainAxisDistance, crossAxisDistance) <= TOUCH_SCROLL_THRESHOLD\n      ) {\n        return\n      }\n      isMainAxisTouch = mainAxisDistance > crossAxisDistance\n    }\n\n    if (!isMainAxisTouch) {\n      return\n    }\n\n    const nextOffset = clamp(\n      touchState.startOffset + mainAxisDelta,\n      0,\n      maxOffset.value\n    )\n\n    if (\n      maxOffset.value <= 0 ||\n      nextOffset === navOffset.value ||\n      !event.cancelable\n    ) {\n      return\n    }\n\n    event.preventDefault()\n    isTouchScrolling.value = true\n    navOffset.value = nextOffset\n  }\n\n  const handleTouchEnd = () => {\n    touchState = undefined\n    isMainAxisTouch = undefined\n    isTouchScrolling.value = false\n  }\n\n  return {\n    isTouchScrolling,\n    handleTouchStart,\n    handleTouchMove,\n    handleTouchEnd,\n  }\n}\n"],"mappings":";;;;AAiBA,MAAM,yBAAyB;AAU/B,MAAa,kBAAkB,EAC7B,YACA,WACA,SACA,kBACA,mBAC0B;CAC1B,MAAM,mBAAmB,IAAI,KAAK;CAClC,MAAM,YAAY,eAChB,KAAK,IAAI,QAAQ,QAAQ,iBAAiB,OAAO,CAAC,CACpD;CACA,IAAI;CACJ,IAAI;CAEJ,MAAM,oBAAoB,UAAsB;EAC9C,IAAI,CAAC,WAAW,SAAS,MAAM,QAAQ,WAAW,GAAG;EAErD,MAAM,EAAE,SAAS,YAAY,YAAY,KAAK;EAC9C,aAAa;GACX,QAAQ;GACR,QAAQ;GACR,aAAa,UAAU;EACzB;EACA,kBAAkB,KAAA;CACpB;CAEA,MAAM,mBAAmB,UAAsB;EAC7C,IAAI,CAAC,cAAc,CAAC,WAAW,OAAO;EAEtC,IAAI,MAAM,QAAQ,WAAW,GAAG;GAC9B,eAAe;GACf;EACF;EAEA,MAAM,EAAE,SAAS,YAAY,YAAY,KAAK;EAC9C,MAAM,SAAS,WAAW,SAAS;EACnC,MAAM,SAAS,WAAW,SAAS;EACnC,MAAM,gBAAgB,aAAa,QAAQ,SAAS;EACpD,MAAM,iBAAiB,aAAa,QAAQ,SAAS;EACrD,MAAM,mBAAmB,KAAK,IAAI,aAAa;EAC/C,MAAM,oBAAoB,KAAK,IAAI,cAAc;EAEjD,IAAI,YAAY,eAAe,GAAG;GAChC,IACE,KAAK,IAAI,kBAAkB,iBAAiB,KAAK,wBAEjD;GAEF,kBAAkB,mBAAmB;EACvC;EAEA,IAAI,CAAC,iBACH;EAGF,MAAM,aAAa,MACjB,WAAW,cAAc,eACzB,GACA,UAAU,KACZ;EAEA,IACE,UAAU,SAAS,KACnB,eAAe,UAAU,SACzB,CAAC,MAAM,YAEP;EAGF,MAAM,eAAe;EACrB,iBAAiB,QAAQ;EACzB,UAAU,QAAQ;CACpB;CAEA,MAAM,uBAAuB;EAC3B,aAAa,KAAA;EACb,kBAAkB,KAAA;EAClB,iBAAiB,QAAQ;CAC3B;CAEA,OAAO;EACL;EACA;EACA;EACA;CACF;AACF"}