{"version":3,"file":"thumb2.mjs","sources":["../../../../../../packages/components/scrollbar/src/thumb.vue"],"sourcesContent":["<template>\n  <transition name=\"fade\">\n    <div\n      v-show=\"always || visible\"\n      ref=\"instance\"\n      :class=\"['scrollbar-bar', 'is-' + bar.key]\"\n      @mousedown=\"clickTrackHandler\"\n    >\n      <div\n        ref=\"thumb\"\n        class=\"scrollbar-thumb\"\n        :style=\"thumbStyle\"\n        @mousedown=\"clickThumbHandler\"\n      ></div>\n    </div>\n  </transition>\n</template>\n\n<script lang=\"ts\">\nimport {\n  computed,\n  defineComponent,\n  inject,\n  onBeforeUnmount,\n  ref,\n  toRef,\n} from 'vue'\nimport { useEventListener } from '@vueuse/core'\nimport { scrollbarContextKey } from '@hongluan-ui/tokens'\nimport { isClient, throwError } from '@hongluan-ui/utils'\nimport { BAR_MAP, renderThumbStyle } from './util'\n\nimport { scrollbarThumbProps } from './thumb'\n\nconst COMPONENT_NAME = 'Thumb'\nexport default defineComponent({\n  name: COMPONENT_NAME,\n  props: scrollbarThumbProps,\n\n  setup(props) {\n    const scrollbar = inject(scrollbarContextKey)\n    if (!scrollbar)\n      throwError(COMPONENT_NAME, 'can not inject scrollbar context')\n\n    const instance = ref<HTMLDivElement>()\n    const thumb = ref<HTMLDivElement>()\n\n    const thumbState = ref({})\n    const visible = ref(false)\n\n    let cursorDown = false\n    let cursorLeave = false\n    let originalOnSelectStart:\n    | ((this: GlobalEventHandlers, ev: Event) => any)\n    | null = isClient ? document.onselectstart : null\n\n    const bar = computed(\n      () => BAR_MAP[props.vertical ? 'vertical' : 'horizontal'],\n    )\n\n    const thumbStyle = computed(() =>\n      renderThumbStyle({\n        size: props.size,\n        move: props.move,\n        bar: bar.value,\n      }),\n    )\n\n    const offsetRatio = computed(\n      () =>\n        // offsetRatioX = original width of thumb / current width of thumb / ratioX\n        // offsetRatioY = original height of thumb / current height of thumb / ratioY\n        // instance height = wrap height - GAP\n        instance.value[bar.value.offset] ** 2 /\n        scrollbar.wrapElement[bar.value.scrollSize] /\n        props.ratio /\n        thumb.value[bar.value.offset],\n    )\n\n    const clickThumbHandler = (e: MouseEvent) => {\n      // prevent click event of middle and right button\n      e.stopPropagation()\n      if (e.ctrlKey || [1, 2].includes(e.button)) return\n\n      window.getSelection()?.removeAllRanges()\n      startDrag(e)\n\n      const el = e.currentTarget as HTMLDivElement\n      if (!el) return\n      thumbState.value[bar.value.axis] =\n        el[bar.value.offset] -\n        (e[bar.value.client] - el.getBoundingClientRect()[bar.value.direction])\n    }\n\n    const clickTrackHandler = (e: MouseEvent) => {\n      if (!thumb.value || !instance.value || !scrollbar.wrapElement) return\n\n      const offset = Math.abs(\n        (e.target as HTMLElement).getBoundingClientRect()[bar.value.direction] -\n          e[bar.value.client],\n      )\n      const thumbHalf = thumb.value[bar.value.offset] / 2\n      const thumbPositionPercentage =\n        ((offset - thumbHalf) * 100 * offsetRatio.value) /\n        instance.value[bar.value.offset]\n\n      scrollbar.wrapElement[bar.value.scroll] =\n        (thumbPositionPercentage *\n          scrollbar.wrapElement[bar.value.scrollSize]) /\n        100\n    }\n\n    const startDrag = (e: MouseEvent) => {\n      e.stopImmediatePropagation()\n      cursorDown = true\n      document.addEventListener('mousemove', mouseMoveDocumentHandler)\n      document.addEventListener('mouseup', mouseUpDocumentHandler)\n      originalOnSelectStart = document.onselectstart\n      document.onselectstart = () => false\n    }\n\n    const mouseMoveDocumentHandler = (e: MouseEvent) => {\n      if (!instance.value || !thumb.value) return\n      if (cursorDown === false) return\n\n      const prevPage = thumbState.value[bar.value.axis]\n      if (!prevPage) return\n\n      const offset =\n        (instance.value.getBoundingClientRect()[bar.value.direction] -\n          e[bar.value.client]) *\n        -1\n      const thumbClickPosition = thumb.value[bar.value.offset] - prevPage\n      const thumbPositionPercentage =\n        ((offset - thumbClickPosition) * 100 * offsetRatio.value) /\n        instance.value[bar.value.offset]\n      scrollbar.wrapElement[bar.value.scroll] =\n        (thumbPositionPercentage *\n          scrollbar.wrapElement[bar.value.scrollSize]) /\n        100\n    }\n\n    const mouseUpDocumentHandler = () => {\n      cursorDown = false\n      thumbState.value[bar.value.axis] = 0\n      document.removeEventListener('mousemove', mouseMoveDocumentHandler)\n      document.removeEventListener('mouseup', mouseUpDocumentHandler)\n      restoreOnselectstart()\n      if (cursorLeave) visible.value = false\n    }\n\n    const mouseMoveScrollbarHandler = () => {\n      cursorLeave = false\n      visible.value = !!props.size\n    }\n\n    const mouseLeaveScrollbarHandler = () => {\n      cursorLeave = true\n      visible.value = cursorDown\n    }\n\n    const scrollHorizontally = (e: any) => {\n      if (!props.vertical && visible.value &&\n        (scrollbar.scrollbarElement.querySelector('.is-vertical') as HTMLElement).style.display) {\n        const delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)))\n        scrollbar.wrapElement.scrollLeft -= delta * 28\n        e.preventDefault()\n      }\n    }\n\n    onBeforeUnmount(() => {\n      restoreOnselectstart()\n      document.removeEventListener('mouseup', mouseUpDocumentHandler)\n    })\n\n    const restoreOnselectstart = () => {\n      if (document.onselectstart !== originalOnSelectStart)\n        document.onselectstart = originalOnSelectStart\n    }\n\n    useEventListener(\n      toRef(scrollbar, 'scrollbarElement'),\n      'mousemove',\n      mouseMoveScrollbarHandler,\n    )\n    useEventListener(\n      toRef(scrollbar, 'scrollbarElement'),\n      'mouseleave',\n      mouseLeaveScrollbarHandler,\n    )\n\n    !props.vertical && useEventListener(\n      toRef(scrollbar, 'scrollbarElement'),\n      'mousewheel',\n      scrollHorizontally,\n    )\n\n    return {\n      instance,\n      thumb,\n      bar,\n      thumbStyle,\n      visible,\n      clickTrackHandler,\n      clickThumbHandler,\n    }\n  },\n})\n</script>\n"],"names":[],"mappings":";;;;;;;;;;AAkCA,MAAM,iBAAiB;AACvB,MAAK,YAAa,gBAAa;AAAA,EAC7B,MAAM;AAAA,EACN,OAAO;AAAA,EAEP,MAAM,OAAO;AACX,UAAM,YAAY,OAAO,mBAAmB;AAC5C,QAAI,CAAC;AACH,iBAAW,gBAAgB,kCAAkC;AAE/D,UAAM,WAAW;AACjB,UAAM,QAAQ;AAEd,UAAM,aAAa,IAAI,EAAE;AACzB,UAAM,UAAU,IAAI,KAAK;AAEzB,QAAI,aAAa;AACjB,QAAI,cAAc;AAClB,QAAI,wBAEK,WAAW,SAAS,gBAAgB;AAE7C,UAAM,MAAM,SACV,MAAM,QAAQ,MAAM,WAAW,aAAa,aAC9C;AAEA,UAAM,aAAa,SAAS,MAC1B,iBAAiB;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,KAAK,IAAI;AAAA,KACV,CACH;AAEA,UAAM,cAAc,SAClB,MAIE,SAAS,MAAM,IAAI,MAAM,WAAW,IACpC,UAAU,YAAY,IAAI,MAAM,cAChC,MAAM,QACN,MAAM,MAAM,IAAI,MAAM,OAC1B;AAEA,UAAM,oBAAoB,CAAC,MAAkB;AAE3C;AACA,uBAAiB;AAA2B;AAE5C;AACA;AAEA,iBAAW,EAAE;AACb;AAAS;AACT;AAE8D;AAGhE;AACE,UAAI,iBAAiB;AAA0C;AAE/D;AAIA,YAAM,kBAAkB;AACxB,YAAM;AAIN,sCAAgC,UAC7B,oCACW,YAAY,UAAU,cAClC;AAAA;AAGJ;AACE;AACA;AACA;AACA,eAAS,iBAAiB,WAAW;AACrC;AACA;AAA+B;AAGjC;AACE,UAAI;AAAiC;AACrC;AAA0B;AAE1B;AACA;AAAe;AAEf;AAIA,YAAM,qDAAqD;AAC3D,YAAM,0BACF,UAAS;AAEb,sCAAgC,UAC7B,gDACuB,wBACxB;AAAA;AAGJ;AACE;AACA;AACA;AACA,eAAS,oBAAoB,WAAW;AACxC;AACA;AAAiB;AAAgB;AAGnC;AACE;AACA;AAAwB;AAG1B;AACE;AACA;AAAgB;AAGlB;AACE,UAAI;AAEF,wEAAkE,CAAC;AACnE,8BAAsB,cAAc;AACpC;AAAiB;AACnB;AAGF;AACE;AACA;AAA8D;AAGhE;AACE,UAAI;AACF;AAAyB;AAG7B;AAKA,qBACE,MAAM,WAAW,kBAAkB,GACnC,wCAEF;AAEA,yDACmB;AAKnB,WAAO;AAAA;AACL,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AACF;AAEJ;;mDA9Mc;AAAW;AAaf,qBAZN;AAYM;AAVA,QACH;AAAwC,QACxC;AAAW;;AAOL;AAJD,UACJ;AAAM,UACL,OAAK;AAAY,UACjB;AAAW;;;AATW;;;;;;;;;;"}