34aae809952717078b46dec5a479a3f46751f732b5c9f5136bec5803992c0cc349c94f87b61b52ea48e4cd7e8da7b7e9c47502096d44170554a0a58d11b2fb 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import { defineComponent, ref, computed, watch, nextTick, provide, reactive, onActivated, onMounted, onUpdated, openBlock, createElementBlock, normalizeClass, unref, createElementVNode, normalizeStyle, createBlock, resolveDynamicComponent, withCtx, renderSlot, createCommentVNode } from 'vue';
  2. import { useResizeObserver, useEventListener } from '@vueuse/core';
  3. import Bar from './bar2.mjs';
  4. import { scrollbarContextKey } from './constants.mjs';
  5. import { scrollbarProps, scrollbarEmits } from './scrollbar.mjs';
  6. import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
  7. import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
  8. import { addUnit } from '../../../utils/dom/style.mjs';
  9. import { isObject } from '@vue/shared';
  10. import { isNumber } from '../../../utils/types.mjs';
  11. const COMPONENT_NAME = "ElScrollbar";
  12. const __default__ = defineComponent({
  13. name: COMPONENT_NAME
  14. });
  15. const _sfc_main = /* @__PURE__ */ defineComponent({
  16. ...__default__,
  17. props: scrollbarProps,
  18. emits: scrollbarEmits,
  19. setup(__props, { expose, emit }) {
  20. const props = __props;
  21. const ns = useNamespace("scrollbar");
  22. let stopResizeObserver = void 0;
  23. let stopWrapResizeObserver = void 0;
  24. let stopResizeListener = void 0;
  25. let wrapScrollTop = 0;
  26. let wrapScrollLeft = 0;
  27. let direction = "";
  28. const distanceScrollState = {
  29. bottom: false,
  30. top: false,
  31. right: false,
  32. left: false
  33. };
  34. const scrollbarRef = ref();
  35. const wrapRef = ref();
  36. const resizeRef = ref();
  37. const barRef = ref();
  38. const wrapStyle = computed(() => {
  39. const style = {};
  40. if (props.height)
  41. style.height = addUnit(props.height);
  42. if (props.maxHeight)
  43. style.maxHeight = addUnit(props.maxHeight);
  44. return [props.wrapStyle, style];
  45. });
  46. const wrapKls = computed(() => {
  47. return [
  48. props.wrapClass,
  49. ns.e("wrap"),
  50. { [ns.em("wrap", "hidden-default")]: !props.native }
  51. ];
  52. });
  53. const resizeKls = computed(() => {
  54. return [ns.e("view"), props.viewClass];
  55. });
  56. const shouldSkipDirection = (direction2) => {
  57. var _a;
  58. return (_a = distanceScrollState[direction2]) != null ? _a : false;
  59. };
  60. const DIRECTION_PAIRS = {
  61. top: "bottom",
  62. bottom: "top",
  63. left: "right",
  64. right: "left"
  65. };
  66. const updateTriggerStatus = (arrivedStates) => {
  67. const oppositeDirection = DIRECTION_PAIRS[direction];
  68. if (!oppositeDirection)
  69. return;
  70. const arrived = arrivedStates[direction];
  71. const oppositeArrived = arrivedStates[oppositeDirection];
  72. if (arrived && !distanceScrollState[direction]) {
  73. distanceScrollState[direction] = true;
  74. }
  75. if (!oppositeArrived && distanceScrollState[oppositeDirection]) {
  76. distanceScrollState[oppositeDirection] = false;
  77. }
  78. };
  79. const handleScroll = () => {
  80. var _a;
  81. if (wrapRef.value) {
  82. (_a = barRef.value) == null ? void 0 : _a.handleScroll(wrapRef.value);
  83. const prevTop = wrapScrollTop;
  84. const prevLeft = wrapScrollLeft;
  85. wrapScrollTop = wrapRef.value.scrollTop;
  86. wrapScrollLeft = wrapRef.value.scrollLeft;
  87. const arrivedStates = {
  88. bottom: wrapScrollTop + wrapRef.value.clientHeight >= wrapRef.value.scrollHeight - props.distance,
  89. top: wrapScrollTop <= props.distance && prevTop !== 0,
  90. right: wrapScrollLeft + wrapRef.value.clientWidth >= wrapRef.value.scrollWidth - props.distance && prevLeft !== wrapScrollLeft,
  91. left: wrapScrollLeft <= props.distance && prevLeft !== 0
  92. };
  93. emit("scroll", {
  94. scrollTop: wrapScrollTop,
  95. scrollLeft: wrapScrollLeft
  96. });
  97. if (prevTop !== wrapScrollTop) {
  98. direction = wrapScrollTop > prevTop ? "bottom" : "top";
  99. }
  100. if (prevLeft !== wrapScrollLeft) {
  101. direction = wrapScrollLeft > prevLeft ? "right" : "left";
  102. }
  103. if (props.distance > 0) {
  104. if (shouldSkipDirection(direction)) {
  105. return;
  106. }
  107. updateTriggerStatus(arrivedStates);
  108. }
  109. if (arrivedStates[direction])
  110. emit("end-reached", direction);
  111. }
  112. };
  113. function scrollTo(arg1, arg2) {
  114. if (isObject(arg1)) {
  115. wrapRef.value.scrollTo(arg1);
  116. } else if (isNumber(arg1) && isNumber(arg2)) {
  117. wrapRef.value.scrollTo(arg1, arg2);
  118. }
  119. }
  120. const setScrollTop = (value) => {
  121. if (!isNumber(value)) {
  122. return;
  123. }
  124. wrapRef.value.scrollTop = value;
  125. };
  126. const setScrollLeft = (value) => {
  127. if (!isNumber(value)) {
  128. return;
  129. }
  130. wrapRef.value.scrollLeft = value;
  131. };
  132. const update = () => {
  133. var _a;
  134. (_a = barRef.value) == null ? void 0 : _a.update();
  135. distanceScrollState[direction] = false;
  136. };
  137. watch(() => props.noresize, (noresize) => {
  138. if (noresize) {
  139. stopResizeObserver == null ? void 0 : stopResizeObserver();
  140. stopWrapResizeObserver == null ? void 0 : stopWrapResizeObserver();
  141. stopResizeListener == null ? void 0 : stopResizeListener();
  142. } else {
  143. ({ stop: stopResizeObserver } = useResizeObserver(resizeRef, update));
  144. ({ stop: stopWrapResizeObserver } = useResizeObserver(wrapRef, update));
  145. stopResizeListener = useEventListener("resize", update);
  146. }
  147. }, { immediate: true });
  148. watch(() => [props.maxHeight, props.height], () => {
  149. if (!props.native)
  150. nextTick(() => {
  151. var _a;
  152. update();
  153. if (wrapRef.value) {
  154. (_a = barRef.value) == null ? void 0 : _a.handleScroll(wrapRef.value);
  155. }
  156. });
  157. });
  158. provide(scrollbarContextKey, reactive({
  159. scrollbarElement: scrollbarRef,
  160. wrapElement: wrapRef
  161. }));
  162. onActivated(() => {
  163. if (wrapRef.value) {
  164. wrapRef.value.scrollTop = wrapScrollTop;
  165. wrapRef.value.scrollLeft = wrapScrollLeft;
  166. }
  167. });
  168. onMounted(() => {
  169. if (!props.native)
  170. nextTick(() => {
  171. update();
  172. });
  173. });
  174. onUpdated(() => update());
  175. expose({
  176. wrapRef,
  177. update,
  178. scrollTo,
  179. setScrollTop,
  180. setScrollLeft,
  181. handleScroll
  182. });
  183. return (_ctx, _cache) => {
  184. return openBlock(), createElementBlock("div", {
  185. ref_key: "scrollbarRef",
  186. ref: scrollbarRef,
  187. class: normalizeClass(unref(ns).b())
  188. }, [
  189. createElementVNode("div", {
  190. ref_key: "wrapRef",
  191. ref: wrapRef,
  192. class: normalizeClass(unref(wrapKls)),
  193. style: normalizeStyle(unref(wrapStyle)),
  194. tabindex: _ctx.tabindex,
  195. onScroll: handleScroll
  196. }, [
  197. (openBlock(), createBlock(resolveDynamicComponent(_ctx.tag), {
  198. id: _ctx.id,
  199. ref_key: "resizeRef",
  200. ref: resizeRef,
  201. class: normalizeClass(unref(resizeKls)),
  202. style: normalizeStyle(_ctx.viewStyle),
  203. role: _ctx.role,
  204. "aria-label": _ctx.ariaLabel,
  205. "aria-orientation": _ctx.ariaOrientation
  206. }, {
  207. default: withCtx(() => [
  208. renderSlot(_ctx.$slots, "default")
  209. ]),
  210. _: 3
  211. }, 8, ["id", "class", "style", "role", "aria-label", "aria-orientation"]))
  212. ], 46, ["tabindex"]),
  213. !_ctx.native ? (openBlock(), createBlock(Bar, {
  214. key: 0,
  215. ref_key: "barRef",
  216. ref: barRef,
  217. always: _ctx.always,
  218. "min-size": _ctx.minSize
  219. }, null, 8, ["always", "min-size"])) : createCommentVNode("v-if", true)
  220. ], 2);
  221. };
  222. }
  223. });
  224. var Scrollbar = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "scrollbar.vue"]]);
  225. export { Scrollbar as default };
  226. //# sourceMappingURL=scrollbar2.mjs.map