thumb2.mjs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { defineComponent, inject, ref, computed, onBeforeUnmount, toRef, openBlock, createBlock, Transition, unref, withCtx, withDirectives, createElementVNode, normalizeClass, normalizeStyle, vShow } from 'vue';
  2. import { isClient, useEventListener } from '@vueuse/core';
  3. import '../../../tokens/index.mjs';
  4. import '../../../utils/index.mjs';
  5. import '../../../hooks/index.mjs';
  6. import { BAR_MAP, renderThumbStyle } from './util.mjs';
  7. import { thumbProps } from './thumb.mjs';
  8. import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
  9. import { scrollbarContextKey } from '../../../tokens/scrollbar.mjs';
  10. import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
  11. import { throwError } from '../../../utils/error.mjs';
  12. const COMPONENT_NAME = "Thumb";
  13. const _sfc_main = /* @__PURE__ */ defineComponent({
  14. __name: "thumb",
  15. props: thumbProps,
  16. setup(__props) {
  17. const props = __props;
  18. const scrollbar = inject(scrollbarContextKey);
  19. const ns = useNamespace("scrollbar");
  20. if (!scrollbar)
  21. throwError(COMPONENT_NAME, "can not inject scrollbar context");
  22. const instance = ref();
  23. const thumb = ref();
  24. const thumbState = ref({});
  25. const visible = ref(false);
  26. let cursorDown = false;
  27. let cursorLeave = false;
  28. let originalOnSelectStart = isClient ? document.onselectstart : null;
  29. const bar = computed(() => BAR_MAP[props.vertical ? "vertical" : "horizontal"]);
  30. const thumbStyle = computed(() => renderThumbStyle({
  31. size: props.size,
  32. move: props.move,
  33. bar: bar.value
  34. }));
  35. const offsetRatio = computed(() => instance.value[bar.value.offset] ** 2 / scrollbar.wrapElement[bar.value.scrollSize] / props.ratio / thumb.value[bar.value.offset]);
  36. const clickThumbHandler = (e) => {
  37. var _a;
  38. e.stopPropagation();
  39. if (e.ctrlKey || [1, 2].includes(e.button))
  40. return;
  41. (_a = window.getSelection()) == null ? void 0 : _a.removeAllRanges();
  42. startDrag(e);
  43. const el = e.currentTarget;
  44. if (!el)
  45. return;
  46. thumbState.value[bar.value.axis] = el[bar.value.offset] - (e[bar.value.client] - el.getBoundingClientRect()[bar.value.direction]);
  47. };
  48. const clickTrackHandler = (e) => {
  49. if (!thumb.value || !instance.value || !scrollbar.wrapElement)
  50. return;
  51. const offset = Math.abs(e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]);
  52. const thumbHalf = thumb.value[bar.value.offset] / 2;
  53. const thumbPositionPercentage = (offset - thumbHalf) * 100 * offsetRatio.value / instance.value[bar.value.offset];
  54. scrollbar.wrapElement[bar.value.scroll] = thumbPositionPercentage * scrollbar.wrapElement[bar.value.scrollSize] / 100;
  55. };
  56. const startDrag = (e) => {
  57. e.stopImmediatePropagation();
  58. cursorDown = true;
  59. document.addEventListener("mousemove", mouseMoveDocumentHandler);
  60. document.addEventListener("mouseup", mouseUpDocumentHandler);
  61. originalOnSelectStart = document.onselectstart;
  62. document.onselectstart = () => false;
  63. };
  64. const mouseMoveDocumentHandler = (e) => {
  65. if (!instance.value || !thumb.value)
  66. return;
  67. if (cursorDown === false)
  68. return;
  69. const prevPage = thumbState.value[bar.value.axis];
  70. if (!prevPage)
  71. return;
  72. const offset = (instance.value.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * -1;
  73. const thumbClickPosition = thumb.value[bar.value.offset] - prevPage;
  74. const thumbPositionPercentage = (offset - thumbClickPosition) * 100 * offsetRatio.value / instance.value[bar.value.offset];
  75. scrollbar.wrapElement[bar.value.scroll] = thumbPositionPercentage * scrollbar.wrapElement[bar.value.scrollSize] / 100;
  76. };
  77. const mouseUpDocumentHandler = () => {
  78. cursorDown = false;
  79. thumbState.value[bar.value.axis] = 0;
  80. document.removeEventListener("mousemove", mouseMoveDocumentHandler);
  81. document.removeEventListener("mouseup", mouseUpDocumentHandler);
  82. restoreOnselectstart();
  83. if (cursorLeave)
  84. visible.value = false;
  85. };
  86. const mouseMoveScrollbarHandler = () => {
  87. cursorLeave = false;
  88. visible.value = !!props.size;
  89. };
  90. const mouseLeaveScrollbarHandler = () => {
  91. cursorLeave = true;
  92. visible.value = cursorDown;
  93. };
  94. onBeforeUnmount(() => {
  95. restoreOnselectstart();
  96. document.removeEventListener("mouseup", mouseUpDocumentHandler);
  97. });
  98. const restoreOnselectstart = () => {
  99. if (document.onselectstart !== originalOnSelectStart)
  100. document.onselectstart = originalOnSelectStart;
  101. };
  102. useEventListener(toRef(scrollbar, "scrollbarElement"), "mousemove", mouseMoveScrollbarHandler);
  103. useEventListener(toRef(scrollbar, "scrollbarElement"), "mouseleave", mouseLeaveScrollbarHandler);
  104. return (_ctx, _cache) => {
  105. return openBlock(), createBlock(Transition, {
  106. name: unref(ns).b("fade"),
  107. persisted: ""
  108. }, {
  109. default: withCtx(() => [
  110. withDirectives(createElementVNode("div", {
  111. ref_key: "instance",
  112. ref: instance,
  113. class: normalizeClass([unref(ns).e("bar"), unref(ns).is(unref(bar).key)]),
  114. onMousedown: clickTrackHandler
  115. }, [
  116. createElementVNode("div", {
  117. ref_key: "thumb",
  118. ref: thumb,
  119. class: normalizeClass(unref(ns).e("thumb")),
  120. style: normalizeStyle(unref(thumbStyle)),
  121. onMousedown: clickThumbHandler
  122. }, null, 38)
  123. ], 34), [
  124. [vShow, _ctx.always || visible.value]
  125. ])
  126. ]),
  127. _: 1
  128. }, 8, ["name"]);
  129. };
  130. }
  131. });
  132. var Thumb = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "/home/runner/work/element-plus/element-plus/packages/components/scrollbar/src/thumb.vue"]]);
  133. export { Thumb as default };
  134. //# sourceMappingURL=thumb2.mjs.map