UNPKG

@aplus-frontend/antdv

Version:

Vue basic component library maintained based on ant-design-vue

254 lines (253 loc) 7.46 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _vue = require("vue"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classNames = _interopRequireDefault(require("../_util/classNames")); var _createRef = _interopRequireDefault(require("../_util/createRef")); var _raf = _interopRequireDefault(require("../_util/raf")); var _supportsPassive = _interopRequireDefault(require("../_util/supportsPassive")); const MIN_SIZE = 20; function getPageY(e) { return 'touches' in e ? e.touches[0].pageY : e.pageY; } var _default = exports.default = (0, _vue.defineComponent)({ compatConfig: { MODE: 3 }, 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() { return { moveRaf: null, scrollbarRef: (0, _createRef.default)(), thumbRef: (0, _createRef.default)(), visibleTimeout: null, state: (0, _vue.reactive)({ dragging: false, pageY: null, startTop: null, visible: false }) }; }, watch: { scrollTop: { handler() { this.delayHidden(); }, flush: 'post' } }, mounted() { var _a, _b; (_a = this.scrollbarRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('touchstart', this.onScrollbarTouchStart, _supportsPassive.default ? { passive: false } : false); (_b = this.thumbRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('touchstart', this.onMouseDown, _supportsPassive.default ? { passive: false } : false); }, beforeUnmount() { this.removeEvents(); clearTimeout(this.visibleTimeout); }, methods: { delayHidden() { clearTimeout(this.visibleTimeout); this.state.visible = true; this.visibleTimeout = setTimeout(() => { this.state.visible = false; }, 2000); }, onScrollbarTouchStart(e) { e.preventDefault(); }, onContainerMouseDown(e) { e.stopPropagation(); e.preventDefault(); }, // ======================= Clean ======================= patchEvents() { window.addEventListener('mousemove', this.onMouseMove); window.addEventListener('mouseup', this.onMouseUp); this.thumbRef.current.addEventListener('touchmove', this.onMouseMove, _supportsPassive.default ? { passive: false } : false); this.thumbRef.current.addEventListener('touchend', this.onMouseUp); }, removeEvents() { window.removeEventListener('mousemove', this.onMouseMove); window.removeEventListener('mouseup', this.onMouseUp); this.scrollbarRef.current.removeEventListener('touchstart', this.onScrollbarTouchStart, _supportsPassive.default ? { passive: false } : false); if (this.thumbRef.current) { this.thumbRef.current.removeEventListener('touchstart', this.onMouseDown, _supportsPassive.default ? { passive: false } : false); this.thumbRef.current.removeEventListener('touchmove', this.onMouseMove, _supportsPassive.default ? { passive: false } : false); this.thumbRef.current.removeEventListener('touchend', this.onMouseUp); } _raf.default.cancel(this.moveRaf); }, // ======================= Thumb ======================= onMouseDown(e) { const { onStartMove } = this.$props; (0, _extends2.default)(this.state, { dragging: true, pageY: getPageY(e), startTop: this.getTop() }); onStartMove(); this.patchEvents(); e.stopPropagation(); e.preventDefault(); }, onMouseMove(e) { const { dragging, pageY, startTop } = this.state; const { onScroll } = this.$props; _raf.default.cancel(this.moveRaf); if (dragging) { const offsetY = getPageY(e) - pageY; const newTop = startTop + offsetY; const enableScrollRange = this.getEnableScrollRange(); const enableHeightRange = this.getEnableHeightRange(); const ptg = enableHeightRange ? newTop / enableHeightRange : 0; const newScrollTop = Math.ceil(ptg * enableScrollRange); this.moveRaf = (0, _raf.default)(() => { onScroll(newScrollTop); }); } }, onMouseUp() { const { onStopMove } = this.$props; this.state.dragging = false; onStopMove(); this.removeEvents(); }, // ===================== Calculate ===================== getSpinHeight() { const { height, scrollHeight } = this.$props; let baseHeight = height / scrollHeight * 100; baseHeight = Math.max(baseHeight, MIN_SIZE); baseHeight = Math.min(baseHeight, height / 2); return Math.floor(baseHeight); }, getEnableScrollRange() { const { scrollHeight, height } = this.$props; return scrollHeight - height || 0; }, getEnableHeightRange() { const { height } = this.$props; const spinHeight = this.getSpinHeight(); return height - spinHeight || 0; }, getTop() { const { scrollTop } = this.$props; const enableScrollRange = this.getEnableScrollRange(); const enableHeightRange = this.getEnableHeightRange(); if (scrollTop === 0 || enableScrollRange === 0) { return 0; } const ptg = scrollTop / enableScrollRange; return ptg * enableHeightRange; }, // Not show scrollbar when height is large than scrollHeight showScroll() { const { height, scrollHeight } = this.$props; return scrollHeight > height; } }, render() { // eslint-disable-next-line no-unused-vars const { dragging, visible } = this.state; const { prefixCls } = this.$props; const spinHeight = this.getSpinHeight() + 'px'; const top = this.getTop() + 'px'; const canScroll = this.showScroll(); const mergedVisible = canScroll && visible; return (0, _vue.createVNode)("div", { "ref": this.scrollbarRef, "class": (0, _classNames.default)(`${prefixCls}-scrollbar`, { [`${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 }, [(0, _vue.createVNode)("div", { "ref": this.thumbRef, "class": (0, _classNames.default)(`${prefixCls}-scrollbar-thumb`, { [`${prefixCls}-scrollbar-thumb-moving`]: dragging }), "style": { width: '100%', height: spinHeight, top, left: 0, position: 'absolute', background: 'rgba(0, 0, 0, 0.5)', borderRadius: '99px', cursor: 'pointer', userSelect: 'none' }, "onMousedown": this.onMouseDown }, null)]); } });