UNPKG

@arco-design/web-vue

Version:

Arco Design Vue 2.0: A Vue.js 3 UI Library

265 lines (264 loc) 9 kB
"use strict"; var vue = require("vue"); var resizeObserverV2 = require("../_components/resize-observer-v2.js"); var thumb = require("./thumb.js"); var globalConfig = require("../_utils/global-config.js"); var is = require("../_utils/is.js"); var pluginVue_exportHelper = require("../_virtual/plugin-vue_export-helper.js"); const THUMB_MIN_SIZE = 20; const TRACK_SIZE = 15; const _sfc_main = vue.defineComponent({ name: "Scrollbar", components: { ResizeObserver: resizeObserverV2, Thumb: thumb }, inheritAttrs: false, props: { type: { type: String, default: "embed" }, outerClass: [String, Object, Array], outerStyle: { type: [String, Object, Array] }, hide: { type: Boolean, default: false }, disableHorizontal: { type: Boolean, default: false }, disableVertical: { type: Boolean, default: false } }, emits: { scroll: (ev) => true }, setup(props, { emit }) { const prefixCls = globalConfig.getPrefixCls("scrollbar"); const containerRef = vue.ref(); const horizontalData = vue.ref(); const verticalData = vue.ref(); const horizontalThumbRef = vue.ref(); const verticalThumbRef = vue.ref(); const _hasHorizontalScrollbar = vue.ref(false); const _hasVerticalScrollbar = vue.ref(false); const hasHorizontalScrollbar = vue.computed( () => _hasHorizontalScrollbar.value && !props.disableHorizontal ); const hasVerticalScrollbar = vue.computed( () => _hasVerticalScrollbar.value && !props.disableVertical ); const isBoth = vue.ref(false); const getContainerSize = () => { var _a, _b, _c, _d, _e, _f; if (containerRef.value) { const { clientWidth, clientHeight, offsetWidth, offsetHeight, scrollWidth, scrollHeight, scrollTop, scrollLeft } = containerRef.value; _hasHorizontalScrollbar.value = scrollWidth > clientWidth; _hasVerticalScrollbar.value = scrollHeight > clientHeight; isBoth.value = hasHorizontalScrollbar.value && hasVerticalScrollbar.value; const horizontalTrackWidth = props.type === "embed" && isBoth.value ? offsetWidth - TRACK_SIZE : offsetWidth; const verticalTrackHeight = props.type === "embed" && isBoth.value ? offsetHeight - TRACK_SIZE : offsetHeight; const horizontalThumbWidth = Math.round( horizontalTrackWidth / Math.min( scrollWidth / clientWidth, horizontalTrackWidth / THUMB_MIN_SIZE ) ); const maxHorizontalOffset = horizontalTrackWidth - horizontalThumbWidth; const horizontalRatio = (scrollWidth - clientWidth) / maxHorizontalOffset; const verticalThumbHeight = Math.round( verticalTrackHeight / Math.min( scrollHeight / clientHeight, verticalTrackHeight / THUMB_MIN_SIZE ) ); const maxVerticalOffset = verticalTrackHeight - verticalThumbHeight; const verticalRatio = (scrollHeight - clientHeight) / maxVerticalOffset; horizontalData.value = { ratio: horizontalRatio, thumbSize: horizontalThumbWidth, max: maxHorizontalOffset }; verticalData.value = { ratio: verticalRatio, thumbSize: verticalThumbHeight, max: maxVerticalOffset }; if (scrollTop > 0) { const verticalOffset = Math.round( scrollTop / ((_b = (_a = verticalData.value) == null ? void 0 : _a.ratio) != null ? _b : 1) ); (_c = verticalThumbRef.value) == null ? void 0 : _c.setOffset(verticalOffset); } if (scrollLeft > 0) { const horizontalOffset = Math.round( scrollLeft / ((_e = (_d = verticalData.value) == null ? void 0 : _d.ratio) != null ? _e : 1) ); (_f = horizontalThumbRef.value) == null ? void 0 : _f.setOffset(horizontalOffset); } } }; vue.onMounted(() => { getContainerSize(); }); const handleResize = () => { getContainerSize(); }; const handleScroll = (ev) => { var _a, _b, _c, _d, _e, _f; if (containerRef.value) { if (hasHorizontalScrollbar.value && !props.disableHorizontal) { const horizontalOffset = Math.round( containerRef.value.scrollLeft / ((_b = (_a = horizontalData.value) == null ? void 0 : _a.ratio) != null ? _b : 1) ); (_c = horizontalThumbRef.value) == null ? void 0 : _c.setOffset(horizontalOffset); } if (hasVerticalScrollbar.value && !props.disableVertical) { const verticalOffset = Math.round( containerRef.value.scrollTop / ((_e = (_d = verticalData.value) == null ? void 0 : _d.ratio) != null ? _e : 1) ); (_f = verticalThumbRef.value) == null ? void 0 : _f.setOffset(verticalOffset); } } emit("scroll", ev); }; const handleHorizontalScroll = (offset) => { var _a, _b; if (containerRef.value) { containerRef.value.scrollTo({ left: offset * ((_b = (_a = horizontalData.value) == null ? void 0 : _a.ratio) != null ? _b : 1) }); } }; const handleVerticalScroll = (offset) => { var _a, _b; if (containerRef.value) { containerRef.value.scrollTo({ top: offset * ((_b = (_a = verticalData.value) == null ? void 0 : _a.ratio) != null ? _b : 1) }); } }; const style = vue.computed(() => { const style2 = {}; if (props.type === "track") { if (hasHorizontalScrollbar.value) { style2.paddingBottom = `${TRACK_SIZE}px`; } if (hasVerticalScrollbar.value) { style2.paddingRight = `${TRACK_SIZE}px`; } } return [style2, props.outerStyle]; }); const cls = vue.computed(() => [ `${prefixCls}`, `${prefixCls}-type-${props.type}`, { [`${prefixCls}-both`]: isBoth.value }, props.outerClass ]); return { prefixCls, cls, style, containerRef, horizontalThumbRef, verticalThumbRef, horizontalData, verticalData, isBoth, hasHorizontalScrollbar, hasVerticalScrollbar, handleResize, handleScroll, handleHorizontalScroll, handleVerticalScroll }; }, methods: { scrollTo(options, y) { var _a, _b; if (is.isObject(options)) { (_a = this.$refs.containerRef) == null ? void 0 : _a.scrollTo(options); } else if (options || y) { (_b = this.$refs.containerRef) == null ? void 0 : _b.scrollTo( options, y ); } }, scrollTop(top) { var _a; (_a = this.$refs.containerRef) == null ? void 0 : _a.scrollTo({ top }); }, scrollLeft(left) { var _a; (_a = this.$refs.containerRef) == null ? void 0 : _a.scrollTo({ left }); } } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_ResizeObserver = vue.resolveComponent("ResizeObserver"); const _component_thumb = vue.resolveComponent("thumb"); return vue.openBlock(), vue.createElementBlock("div", { class: vue.normalizeClass(_ctx.cls), style: vue.normalizeStyle(_ctx.style) }, [ vue.createVNode(_component_ResizeObserver, { onResize: _ctx.handleResize }, { default: vue.withCtx(() => [ vue.createElementVNode("div", vue.mergeProps({ ref: "containerRef", class: `${_ctx.prefixCls}-container` }, _ctx.$attrs, { onScroll: _cache[0] || (_cache[0] = (...args) => _ctx.handleScroll && _ctx.handleScroll(...args)) }), [ vue.createVNode(_component_ResizeObserver, { onResize: _ctx.handleResize }, { default: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, "default") ]), _: 3 }, 8, ["onResize"]) ], 16) ]), _: 3 }, 8, ["onResize"]), !_ctx.hide && _ctx.hasHorizontalScrollbar ? (vue.openBlock(), vue.createBlock(_component_thumb, { key: 0, ref: "horizontalThumbRef", data: _ctx.horizontalData, direction: "horizontal", both: _ctx.isBoth, onScroll: _ctx.handleHorizontalScroll }, null, 8, ["data", "both", "onScroll"])) : vue.createCommentVNode("v-if", true), !_ctx.hide && _ctx.hasVerticalScrollbar ? (vue.openBlock(), vue.createBlock(_component_thumb, { key: 1, ref: "verticalThumbRef", data: _ctx.verticalData, direction: "vertical", both: _ctx.isBoth, onScroll: _ctx.handleVerticalScroll }, null, 8, ["data", "both", "onScroll"])) : vue.createCommentVNode("v-if", true) ], 6); } var _Scrollbar = /* @__PURE__ */ pluginVue_exportHelper(_sfc_main, [["render", _sfc_render]]); module.exports = _Scrollbar;