'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var defaults = require('../defaults.js'); var props = require('../props.js'); var utils = require('../utils.js'); var util = require('../../../scrollbar/src/util.js'); var index = require('../../../../hooks/use-namespace/index.js'); var raf = require('../../../../utils/raf.js'); const ScrollBar = vue.defineComponent({ name: "ElVirtualScrollBar", props: props.virtualizedScrollbarProps, emits: ["scroll", "start-move", "stop-move"], setup(props, { emit }) { const GAP = vue.computed(() => props.startGap + props.endGap); const nsVirtualScrollbar = index.useNamespace("virtual-scrollbar"); const nsScrollbar = index.useNamespace("scrollbar"); const trackRef = vue.ref(); const thumbRef = vue.ref(); let frameHandle = null; let onselectstartStore = null; const state = vue.reactive({ isDragging: false, traveled: 0 }); const bar = vue.computed(() => util.BAR_MAP[props.layout]); const trackSize = vue.computed(() => props.clientSize - vue.unref(GAP)); const trackStyle = vue.computed(() => ({ position: "absolute", width: `${defaults.HORIZONTAL === props.layout ? trackSize.value : props.scrollbarSize}px`, height: `${defaults.HORIZONTAL === props.layout ? props.scrollbarSize : trackSize.value}px`, [defaults.ScrollbarDirKey[props.layout]]: "2px", right: "2px", bottom: "2px", borderRadius: "4px" })); const thumbSize = vue.computed(() => { const ratio = props.ratio; if (ratio >= 100) { return Number.POSITIVE_INFINITY; } if (ratio >= 50) { return ratio * trackSize.value / 100; } const SCROLLBAR_MAX_SIZE = trackSize.value / 3; return Math.floor(Math.min(Math.max(ratio * trackSize.value / 100, defaults.SCROLLBAR_MIN_SIZE), SCROLLBAR_MAX_SIZE)); }); const thumbStyle = vue.computed(() => { if (!Number.isFinite(thumbSize.value)) { return { display: "none" }; } const thumb = `${thumbSize.value}px`; const style = utils.renderThumbStyle({ bar: bar.value, size: thumb, move: state.traveled }, props.layout); return style; }); const totalSteps = vue.computed(() => Math.ceil(props.clientSize - thumbSize.value - vue.unref(GAP))); const attachEvents = () => { window.addEventListener("mousemove", onMouseMove); window.addEventListener("mouseup", onMouseUp); const thumbEl = vue.unref(thumbRef); if (!thumbEl) return; onselectstartStore = document.onselectstart; document.onselectstart = () => false; thumbEl.addEventListener("touchmove", onMouseMove, { passive: true }); thumbEl.addEventListener("touchend", onMouseUp); }; const detachEvents = () => { window.removeEventListener("mousemove", onMouseMove); window.removeEventListener("mouseup", onMouseUp); document.onselectstart = onselectstartStore; onselectstartStore = null; const thumbEl = vue.unref(thumbRef); if (!thumbEl) return; thumbEl.removeEventListener("touchmove", onMouseMove); thumbEl.removeEventListener("touchend", onMouseUp); }; const onThumbMouseDown = (e) => { e.stopImmediatePropagation(); if (e.ctrlKey || [1, 2].includes(e.button)) { return; } state.isDragging = true; state[bar.value.axis] = e.currentTarget[bar.value.offset] - (e[bar.value.client] - e.currentTarget.getBoundingClientRect()[bar.value.direction]); emit("start-move"); attachEvents(); }; const onMouseUp = () => { state.isDragging = false; state[bar.value.axis] = 0; emit("stop-move"); detachEvents(); }; const onMouseMove = (e) => { const { isDragging } = state; if (!isDragging) return; if (!thumbRef.value || !trackRef.value) return; const prevPage = state[bar.value.axis]; if (!prevPage) return; raf.cAF(frameHandle); const offset = (trackRef.value.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * -1; const thumbClickPosition = thumbRef.value[bar.value.offset] - prevPage; const distance = offset - thumbClickPosition; frameHandle = raf.rAF(() => { state.traveled = Math.max(0, Math.min(distance, totalSteps.value)); emit("scroll", distance, totalSteps.value); }); }; const clickTrackHandler = (e) => { const offset = Math.abs(e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]); const thumbHalf = thumbRef.value[bar.value.offset] / 2; const distance = offset - thumbHalf; state.traveled = Math.max(0, Math.min(distance, totalSteps.value)); emit("scroll", distance, totalSteps.value); }; vue.watch(() => props.scrollFrom, (v) => { if (state.isDragging) return; state.traveled = Math.ceil(v * totalSteps.value); }); vue.onBeforeUnmount(() => { detachEvents(); }); return () => { return vue.h("div", { role: "presentation", ref: trackRef, class: [ nsVirtualScrollbar.b(), props.class, (props.alwaysOn || state.isDragging) && "always-on" ], style: trackStyle.value, onMousedown: vue.withModifiers(clickTrackHandler, ["stop", "prevent"]), onTouchstartPrevent: onThumbMouseDown }, vue.h("div", { ref: thumbRef, class: nsScrollbar.e("thumb"), style: thumbStyle.value, onMousedown: onThumbMouseDown }, [])); }; } }); exports["default"] = ScrollBar; //# sourceMappingURL=scrollbar.js.map