{"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,MAAM;CACnC,MAAM,YAAY,eAChB,KAAK,IAAI,QAAQ,QAAQ,iBAAiB,OAAO,EAAE,CACpD;CACD,IAAI;CACJ,IAAI;CAEJ,MAAM,oBAAoB,UAAsB;EAC9C,IAAI,CAAC,WAAW,SAAS,MAAM,QAAQ,WAAW,GAAG;EAErD,MAAM,EAAE,SAAS,YAAY,YAAY,MAAM;EAC/C,aAAa;GACX,QAAQ;GACR,QAAQ;GACR,aAAa,UAAU;GACxB;EACD,kBAAkB,KAAA;;CAGpB,MAAM,mBAAmB,UAAsB;EAC7C,IAAI,CAAC,cAAc,CAAC,WAAW,OAAO;EAEtC,IAAI,MAAM,QAAQ,WAAW,GAAG;GAC9B,gBAAgB;GAChB;;EAGF,MAAM,EAAE,SAAS,YAAY,YAAY,MAAM;EAC/C,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,cAAc;EAChD,MAAM,oBAAoB,KAAK,IAAI,eAAe;EAElD,IAAI,YAAY,gBAAgB,EAAE;GAChC,IACE,KAAK,IAAI,kBAAkB,kBAAkB,IAAI,wBAEjD;GAEF,kBAAkB,mBAAmB;;EAGvC,IAAI,CAAC,iBACH;EAGF,MAAM,aAAa,MACjB,WAAW,cAAc,eACzB,GACA,UAAU,MACX;EAED,IACE,UAAU,SAAS,KACnB,eAAe,UAAU,SACzB,CAAC,MAAM,YAEP;EAGF,MAAM,gBAAgB;EACtB,iBAAiB,QAAQ;EACzB,UAAU,QAAQ;;CAGpB,MAAM,uBAAuB;EAC3B,aAAa,KAAA;EACb,kBAAkB,KAAA;EAClB,iBAAiB,QAAQ;;CAG3B,OAAO;EACL;EACA;EACA;EACA;EACD"}