element-plus
Version:
A Component Library for Vue 3
1 lines • 7.38 kB
Source Map (JSON)
{"version":3,"file":"thumb2.mjs","sources":["../../../../../../packages/components/scrollbar/src/thumb.vue"],"sourcesContent":["<template>\n <transition :name=\"ns.b('fade')\">\n <div\n v-show=\"always || visible\"\n ref=\"instance\"\n :class=\"[ns.e('bar'), ns.is(bar.key)]\"\n @mousedown=\"clickTrackHandler\"\n >\n <div\n ref=\"thumb\"\n :class=\"ns.e('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, isClient } from '@vueuse/core'\nimport { scrollbarContextKey } from '@element-plus/tokens'\nimport { throwError } from '@element-plus/utils'\nimport { useNamespace } from '@element-plus/hooks'\nimport { BAR_MAP, renderThumbStyle } from './util'\n\nimport { thumbProps } from './thumb'\n\nconst COMPONENT_NAME = 'Thumb'\nexport default defineComponent({\n name: COMPONENT_NAME,\n props: thumbProps,\n\n setup(props) {\n const scrollbar = inject(scrollbarContextKey)\n const ns = useNamespace('scrollbar')\n\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 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 return {\n ns,\n instance,\n thumb,\n bar,\n thumbStyle,\n visible,\n clickTrackHandler,\n clickThumbHandler,\n }\n },\n})\n</script>\n"],"names":[],"mappings":";;;;;;;;;;;;AAmCA,MAAM,iBAAiB;AACvB,MAAK,YAAa,gBAAa;AAAA,EAC7B,MAAM;AAAA,EACN,OAAO;AAAA,EAEP,MAAM,OAAO;AACX,UAAM,YAAY,OAAO;AACzB,UAAM,KAAK,aAAa;AAExB,QAAI,CAAC;AACH,iBAAW,gBAAgB;AAE7B,UAAM,WAAW;AACjB,UAAM,QAAQ;AAEd,UAAM,aAAa,IAAI;AACvB,UAAM,UAAU,IAAI;AAEpB,QAAI,aAAa;AACjB,QAAI,cAAc;AAClB,QAAI,wBAEO,WAAW,SAAS,gBAAgB;AAE/C,UAAM,MAAM,SACV,MAAM,QAAQ,MAAM,WAAW,aAAa;AAG9C,UAAM,aAAa,SAAS,MAC1B,iBAAiB;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,KAAK,IAAI;AAAA;AAIb,UAAM,cAAc,SAClB,MAIE,SAAS,MAAO,IAAI,MAAM,WAAW,IACrC,UAAU,YAAa,IAAI,MAAM,cACjC,MAAM,QACN,MAAM,MAAO,IAAI,MAAM;AAG3B,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;AACA;AAAwC;AAG1C;AACE,UAAI;AACF;AAAyB;AAG7B;AAKA,qBACE,MAAM,WAAW,qBACjB;AAIF;AAAO;AACL,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA;;SAhMe;AAAI;;;AACrB,qBAEM;AAAU;AACR,QACL;AAAW;;AAEZ;AACa;AACL,UACL;AAAO,UACP,sBAAS;AAAA;;;AATM;;;;;;;;;;;"}