| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- '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
|