ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
233 lines (224 loc) • 7.68 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _extends from "@babel/runtime/helpers/esm/extends";
import { createVNode as _createVNode } from "vue";
import { defineComponent, reactive } from 'vue';
import classNames from '../_util/classNames';
import createRef from '../_util/createRef';
import raf from '../_util/raf';
import supportsPassive from '../_util/supportsPassive';
var MIN_SIZE = 20;
function getPageY(e) {
return 'touches' in e ? e.touches[0].pageY : e.pageY;
}
export default defineComponent({
name: 'ScrollBar',
inheritAttrs: false,
props: {
prefixCls: String,
scrollTop: Number,
scrollHeight: Number,
height: Number,
count: Number,
onScroll: {
type: Function
},
onStartMove: {
type: Function
},
onStopMove: {
type: Function
}
},
setup: function setup() {
return {
moveRaf: null,
scrollbarRef: createRef(),
thumbRef: createRef(),
visibleTimeout: null,
state: reactive({
dragging: false,
pageY: null,
startTop: null,
visible: false
})
};
},
watch: {
scrollTop: {
handler: function handler() {
this.delayHidden();
},
flush: 'post'
}
},
mounted: function mounted() {
var _a, _b;
(_a = this.scrollbarRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('touchstart', this.onScrollbarTouchStart, supportsPassive ? {
passive: false
} : false);
(_b = this.thumbRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('touchstart', this.onMouseDown, supportsPassive ? {
passive: false
} : false);
},
beforeUnmount: function beforeUnmount() {
this.removeEvents();
clearTimeout(this.visibleTimeout);
},
methods: {
delayHidden: function delayHidden() {
var _this = this;
clearTimeout(this.visibleTimeout);
this.state.visible = true;
this.visibleTimeout = setTimeout(function () {
_this.state.visible = false;
}, 2000);
},
onScrollbarTouchStart: function onScrollbarTouchStart(e) {
e.preventDefault();
},
onContainerMouseDown: function onContainerMouseDown(e) {
e.stopPropagation();
e.preventDefault();
},
// ======================= Clean =======================
patchEvents: function patchEvents() {
window.addEventListener('mousemove', this.onMouseMove);
window.addEventListener('mouseup', this.onMouseUp);
this.thumbRef.current.addEventListener('touchmove', this.onMouseMove, supportsPassive ? {
passive: false
} : false);
this.thumbRef.current.addEventListener('touchend', this.onMouseUp);
},
removeEvents: function removeEvents() {
window.removeEventListener('mousemove', this.onMouseMove);
window.removeEventListener('mouseup', this.onMouseUp);
this.scrollbarRef.current.removeEventListener('touchstart', this.onScrollbarTouchStart, supportsPassive ? {
passive: false
} : false);
this.thumbRef.current.removeEventListener('touchstart', this.onMouseDown, supportsPassive ? {
passive: false
} : false);
this.thumbRef.current.removeEventListener('touchmove', this.onMouseMove, supportsPassive ? {
passive: false
} : false);
this.thumbRef.current.removeEventListener('touchend', this.onMouseUp);
raf.cancel(this.moveRaf);
},
// ======================= Thumb =======================
onMouseDown: function onMouseDown(e) {
var onStartMove = this.$props.onStartMove;
_extends(this.state, {
dragging: true,
pageY: getPageY(e),
startTop: this.getTop()
});
onStartMove();
this.patchEvents();
e.stopPropagation();
e.preventDefault();
},
onMouseMove: function onMouseMove(e) {
var _this$state = this.state,
dragging = _this$state.dragging,
pageY = _this$state.pageY,
startTop = _this$state.startTop;
var onScroll = this.$props.onScroll;
raf.cancel(this.moveRaf);
if (dragging) {
var offsetY = getPageY(e) - pageY;
var newTop = startTop + offsetY;
var enableScrollRange = this.getEnableScrollRange();
var enableHeightRange = this.getEnableHeightRange();
var ptg = enableHeightRange ? newTop / enableHeightRange : 0;
var newScrollTop = Math.ceil(ptg * enableScrollRange);
this.moveRaf = raf(function () {
onScroll(newScrollTop);
});
}
},
onMouseUp: function onMouseUp() {
var onStopMove = this.$props.onStopMove;
this.state.dragging = false;
onStopMove();
this.removeEvents();
},
// ===================== Calculate =====================
getSpinHeight: function getSpinHeight() {
var _this$$props = this.$props,
height = _this$$props.height,
count = _this$$props.count;
var baseHeight = height / count * 10;
baseHeight = Math.max(baseHeight, MIN_SIZE);
baseHeight = Math.min(baseHeight, height / 2);
return Math.floor(baseHeight);
},
getEnableScrollRange: function getEnableScrollRange() {
var _this$$props2 = this.$props,
scrollHeight = _this$$props2.scrollHeight,
height = _this$$props2.height;
return scrollHeight - height || 0;
},
getEnableHeightRange: function getEnableHeightRange() {
var height = this.$props.height;
var spinHeight = this.getSpinHeight();
return height - spinHeight || 0;
},
getTop: function getTop() {
var scrollTop = this.$props.scrollTop;
var enableScrollRange = this.getEnableScrollRange();
var enableHeightRange = this.getEnableHeightRange();
if (scrollTop === 0 || enableScrollRange === 0) {
return 0;
}
var ptg = scrollTop / enableScrollRange;
return ptg * enableHeightRange;
},
// Not show scrollbar when height is large than scrollHeight
showScroll: function showScroll() {
var _this$$props3 = this.$props,
height = _this$$props3.height,
scrollHeight = _this$$props3.scrollHeight;
return scrollHeight > height;
}
},
render: function render() {
// eslint-disable-next-line no-unused-vars
var _this$state2 = this.state,
dragging = _this$state2.dragging,
visible = _this$state2.visible;
var prefixCls = this.$props.prefixCls;
var spinHeight = this.getSpinHeight() + 'px';
var top = this.getTop() + 'px';
var canScroll = this.showScroll();
var mergedVisible = canScroll && visible;
return _createVNode("div", {
"ref": this.scrollbarRef,
"class": classNames("".concat(prefixCls, "-scrollbar"), _defineProperty({}, "".concat(prefixCls, "-scrollbar-show"), canScroll)),
"style": {
width: '8px',
top: 0,
bottom: 0,
right: 0,
position: 'absolute',
display: mergedVisible ? undefined : 'none'
},
"onMousedown": this.onContainerMouseDown,
"onMousemove": this.delayHidden
}, [_createVNode("div", {
"ref": this.thumbRef,
"class": classNames("".concat(prefixCls, "-scrollbar-thumb"), _defineProperty({}, "".concat(prefixCls, "-scrollbar-thumb-moving"), dragging)),
"style": {
width: '100%',
height: spinHeight,
top: top,
left: 0,
position: 'absolute',
background: 'rgba(0, 0, 0, 0.5)',
borderRadius: '99px',
cursor: 'pointer',
userSelect: 'none'
},
"onMousedown": this.onMouseDown
}, null)]);
}
});