UNPKG

primevue

Version:

PrimeVue is a premium UI library for Vue featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock, wh

403 lines (397 loc) 14.8 kB
import { isElement } from '@primeuix/utils/dom'; import { mergeProps, openBlock, createBlock, resolveDynamicComponent, withCtx, renderSlot, normalizeClass } from 'vue'; import BaseComponent from '@primevue/core/basecomponent'; import ScrollAreaStyle from 'primevue/scrollarea/style'; var script$1 = { name: 'BaseScrollArea', "extends": BaseComponent, props: { variant: { type: String, "default": 'auto' }, mask: { type: Boolean, "default": false }, as: { type: [String, Object], "default": 'DIV' }, asChild: { type: Boolean, "default": false }, tabIndex: { type: Number, "default": 0 } }, style: ScrollAreaStyle, provide: function provide() { return { $pcScrollArea: this, $parentInstance: this }; } }; var SCROLL_TIMEOUT = 500; var MIN_HANDLE_SIZE = 20; var script = { name: 'ScrollArea', "extends": script$1, inheritAttrs: false, resizeObserver: null, resizeObserverRaf: null, rafId: null, scrollXTimeout: null, scrollYTimeout: null, isDragging: false, dragOrientation: null, dragStart: { pointerPos: 0, scrollPos: 0 }, prevScroll: { top: 0, left: 0 }, data: function data() { return { viewportEl: null, scrollbarYEl: null, scrollbarXEl: null, hovering: false, scrollingX: false, scrollingY: false, scrollMeta: { hiddenX: true, hiddenY: true, cornerWidth: 0, cornerHeight: 0, xBefore: false, xAfter: false, yBefore: false, yAfter: false } }; }, watch: { viewportEl: function viewportEl(newEl, oldEl) { if (oldEl && oldEl !== newEl) { this.unbindResizeObserver(); } if (newEl) { this.bindResizeObserver(); this.$nextTick(this.computeHandle); } else { this.unbindResizeObserver(); } } }, beforeUnmount: function beforeUnmount() { this.unbindResizeObserver(); if (this.scrollXTimeout) { clearTimeout(this.scrollXTimeout); this.scrollXTimeout = null; } if (this.scrollYTimeout) { clearTimeout(this.scrollYTimeout); this.scrollYTimeout = null; } if (this.rafId) { cancelAnimationFrame(this.rafId); this.rafId = null; } }, methods: { setViewportEl: function setViewportEl(el) { this.viewportEl = isElement(el) ? el : null; }, setScrollbarEl: function setScrollbarEl(el, orientation) { var value = isElement(el) ? el : null; if (orientation === 'vertical') this.scrollbarYEl = value;else this.scrollbarXEl = value; if (this.viewportEl) { this.$nextTick(this.computeHandle); } }, getHandleSize: function getHandleSize(scrollbar, isVertical) { if (!scrollbar) return 0; var value = scrollbar.style.getPropertyValue(isVertical ? '--px-handle-height' : '--px-handle-width'); return parseFloat(value) || 0; }, bindResizeObserver: function bindResizeObserver() { var _this = this; if (!this.viewportEl || typeof ResizeObserver === 'undefined') return; this.unbindResizeObserver(); this.resizeObserver = new ResizeObserver(function () { if (_this.resizeObserverRaf) return; _this.resizeObserverRaf = requestAnimationFrame(function () { _this.resizeObserverRaf = null; _this.computeHandle(); }); }); this.resizeObserver.observe(this.viewportEl); if (this.viewportEl.firstElementChild) { this.resizeObserver.observe(this.viewportEl.firstElementChild); } }, unbindResizeObserver: function unbindResizeObserver() { if (this.resizeObserverRaf) { cancelAnimationFrame(this.resizeObserverRaf); this.resizeObserverRaf = null; } if (this.resizeObserver) { this.resizeObserver.disconnect(); this.resizeObserver = null; } }, computeHandle: function computeHandle() { var vp = this.viewportEl; if (!vp) return; var scrollHeight = vp.scrollHeight, scrollWidth = vp.scrollWidth, clientHeight = vp.clientHeight, clientWidth = vp.clientWidth, scrollTop = vp.scrollTop, scrollLeft = vp.scrollLeft; var yHidden = clientHeight >= scrollHeight; var xHidden = clientWidth >= scrollWidth; var scrollbarY = this.scrollbarYEl; var scrollbarX = this.scrollbarXEl; var cw = !yHidden && !xHidden && scrollbarY ? scrollbarY.offsetWidth : 0; var ch = !yHidden && !xHidden && scrollbarX ? scrollbarX.offsetHeight : 0; var scrollbarYHeight = scrollbarY && !yHidden ? scrollbarY.offsetHeight : 0; var scrollbarXWidth = scrollbarX && !xHidden ? scrollbarX.offsetWidth : 0; var next = { hiddenX: xHidden, hiddenY: yHidden, cornerWidth: cw, cornerHeight: ch, xBefore: !xHidden && scrollLeft > 0, xAfter: !xHidden && scrollWidth - clientWidth - scrollLeft > 1, yBefore: !yHidden && scrollTop > 0, yAfter: !yHidden && scrollHeight - clientHeight - scrollTop > 1 }; var prev = this.scrollMeta; var changed = prev.hiddenX !== next.hiddenX || prev.hiddenY !== next.hiddenY || prev.cornerWidth !== next.cornerWidth || prev.cornerHeight !== next.cornerHeight || prev.xBefore !== next.xBefore || prev.xAfter !== next.xAfter || prev.yBefore !== next.yBefore || prev.yAfter !== next.yAfter; if (changed) { this.scrollMeta = next; if (prev.hiddenX !== next.hiddenX || prev.hiddenY !== next.hiddenY) { this.$nextTick(this.computeHandle); } } if (scrollbarY && !yHidden && scrollbarYHeight > 0) { var handleRatio = clientHeight / scrollHeight; var handleHeight = Math.max(handleRatio * scrollbarYHeight, MIN_HANDLE_SIZE); var availableTrack = scrollbarYHeight - handleHeight; var maxScrollTop = scrollHeight - clientHeight; var scrollRatio = maxScrollTop > 0 ? scrollTop / maxScrollTop : 0; var offsetPx = scrollRatio * availableTrack; scrollbarY.style.setProperty('--px-handle-height', "".concat(handleHeight, "px")); scrollbarY.style.setProperty('--px-handle-offset', "".concat(offsetPx, "px")); } else if (scrollbarY) { scrollbarY.style.removeProperty('--px-handle-height'); scrollbarY.style.removeProperty('--px-handle-offset'); } if (scrollbarX && !xHidden && scrollbarXWidth > 0) { var _handleRatio = clientWidth / scrollWidth; var handleWidth = Math.max(_handleRatio * scrollbarXWidth, MIN_HANDLE_SIZE); var _availableTrack = scrollbarXWidth - handleWidth; var maxScrollLeft = scrollWidth - clientWidth; var _scrollRatio = maxScrollLeft > 0 ? scrollLeft / maxScrollLeft : 0; var _offsetPx = _scrollRatio * _availableTrack; scrollbarX.style.setProperty('--px-handle-width', "".concat(handleWidth, "px")); scrollbarX.style.setProperty('--px-handle-offset', "".concat(_offsetPx, "px")); } else if (scrollbarX) { scrollbarX.style.removeProperty('--px-handle-width'); scrollbarX.style.removeProperty('--px-handle-offset'); } }, onScroll: function onScroll() { var _this2 = this; if (!this.rafId) { this.rafId = requestAnimationFrame(function () { _this2.rafId = null; _this2.computeHandle(); }); } var vp = this.viewportEl; if (!vp) return; var scrollTop = vp.scrollTop, scrollLeft = vp.scrollLeft; if (!this.prevScroll) this.prevScroll = { top: 0, left: 0 }; var prev = this.prevScroll; if (scrollTop !== prev.top) { this.scrollingY = true; if (this.scrollYTimeout) clearTimeout(this.scrollYTimeout); this.scrollYTimeout = setTimeout(function () { _this2.scrollingY = false; }, SCROLL_TIMEOUT); } if (scrollLeft !== prev.left) { this.scrollingX = true; if (this.scrollXTimeout) clearTimeout(this.scrollXTimeout); this.scrollXTimeout = setTimeout(function () { _this2.scrollingX = false; }, SCROLL_TIMEOUT); } prev.top = scrollTop; prev.left = scrollLeft; }, onPointerEnter: function onPointerEnter(event) { if (event.pointerType !== 'touch') { this.hovering = true; } }, onPointerLeave: function onPointerLeave() { this.hovering = false; }, onScrollbarPointerDown: function onScrollbarPointerDown(event, orientation) { if (event.pointerType === 'mouse' && event.button !== 0) return; event.preventDefault(); var isVertical = orientation === 'vertical'; var scrollbar = isVertical ? this.scrollbarYEl : this.scrollbarXEl; var vp = this.viewportEl; if (!scrollbar || !vp) return; if (scrollbar.setPointerCapture && event.pointerId != null) { scrollbar.setPointerCapture(event.pointerId); } this.isDragging = true; this.dragOrientation = orientation; var rect = scrollbar.getBoundingClientRect(); var handleSize = this.getHandleSize(scrollbar, isVertical); var trackSize = isVertical ? rect.height : rect.width; var effectiveTrack = trackSize - handleSize; if (effectiveTrack > 0) { var clickPos = (isVertical ? event.clientY - rect.top : event.clientX - rect.left) - handleSize / 2; var ratio = Math.max(0, Math.min(1, clickPos / effectiveTrack)); var maxScroll = isVertical ? vp.scrollHeight - vp.clientHeight : vp.scrollWidth - vp.clientWidth; if (isVertical) { vp.scrollTop = ratio * maxScroll; } else { vp.scrollLeft = ratio * maxScroll; } } this.dragStart = { pointerPos: isVertical ? event.clientY : event.clientX, scrollPos: isVertical ? vp.scrollTop : vp.scrollLeft }; }, onScrollbarPointerMove: function onScrollbarPointerMove(event) { if (!this.isDragging) return; event.preventDefault(); var isVertical = this.dragOrientation === 'vertical'; var vp = this.viewportEl; var scrollbar = isVertical ? this.scrollbarYEl : this.scrollbarXEl; if (!vp || !scrollbar) return; var rect = scrollbar.getBoundingClientRect(); var handleSize = this.getHandleSize(scrollbar, isVertical); var trackSize = isVertical ? rect.height : rect.width; var effectiveTrack = trackSize - handleSize; if (effectiveTrack <= 0) return; var currentPos = isVertical ? event.clientY : event.clientX; var delta = currentPos - this.dragStart.pointerPos; var maxScroll = isVertical ? vp.scrollHeight - vp.clientHeight : vp.scrollWidth - vp.clientWidth; var scrollDelta = delta / effectiveTrack * maxScroll; if (isVertical) { vp.scrollTop = this.dragStart.scrollPos + scrollDelta; } else { vp.scrollLeft = this.dragStart.scrollPos + scrollDelta; } }, onScrollbarPointerUp: function onScrollbarPointerUp(event) { var _event$currentTarget, _event$currentTarget$; if (!this.isDragging) return; event.preventDefault(); if ((_event$currentTarget = event.currentTarget) !== null && _event$currentTarget !== void 0 && (_event$currentTarget$ = _event$currentTarget.hasPointerCapture) !== null && _event$currentTarget$ !== void 0 && _event$currentTarget$.call(_event$currentTarget, event.pointerId)) { event.currentTarget.releasePointerCapture(event.pointerId); } this.isDragging = false; this.dragOrientation = null; }, onScrollbarWheel: function onScrollbarWheel(event, orientation) { var vp = this.viewportEl; if (!vp || event.ctrlKey) return; event.preventDefault(); if (orientation === 'vertical') { vp.scrollTop += event.deltaY; } else { vp.scrollLeft += event.deltaX || event.deltaY; } }, onHandlePointerDown: function onHandlePointerDown(event, orientation) { if (event.pointerType === 'mouse' && event.button !== 0) return; event.preventDefault(); event.stopPropagation(); var isVertical = orientation === 'vertical'; var scrollbar = isVertical ? this.scrollbarYEl : this.scrollbarXEl; var vp = this.viewportEl; if (!scrollbar || !vp) return; if (scrollbar.setPointerCapture && event.pointerId != null) { scrollbar.setPointerCapture(event.pointerId); } this.isDragging = true; this.dragOrientation = orientation; this.dragStart = { pointerPos: isVertical ? event.clientY : event.clientX, scrollPos: isVertical ? vp.scrollTop : vp.scrollLeft }; } }, computed: { rootStyle: function rootStyle() { return { '--px-corner-height': "".concat(this.scrollMeta.cornerHeight, "px"), '--px-corner-width': "".concat(this.scrollMeta.cornerWidth, "px") }; }, hasOverflowX: function hasOverflowX() { return !this.scrollMeta.hiddenX; }, hasOverflowY: function hasOverflowY() { return !this.scrollMeta.hiddenY; }, attrs: function attrs() { return mergeProps(this.a11yAttrs, this.ptmi('root')); }, a11yAttrs: function a11yAttrs() { return { 'data-variant': this.variant, 'data-mask': this.mask ? '' : undefined, 'data-scrolling': this.scrollingX || this.scrollingY ? '' : undefined, 'data-has-overflow-x': this.hasOverflowX ? '' : undefined, 'data-has-overflow-y': this.hasOverflowY ? '' : undefined, 'data-scroll-x-before': this.scrollMeta.xBefore ? '' : undefined, 'data-scroll-x-after': this.scrollMeta.xAfter ? '' : undefined, 'data-scroll-y-before': this.scrollMeta.yBefore ? '' : undefined, 'data-scroll-y-after': this.scrollMeta.yAfter ? '' : undefined, role: 'presentation', style: this.rootStyle, onPointerenter: this.onPointerEnter, onPointerleave: this.onPointerLeave }; } } }; function render(_ctx, _cache, $props, $setup, $data, $options) { return !_ctx.asChild ? (openBlock(), createBlock(resolveDynamicComponent(_ctx.as), mergeProps({ key: 0, "class": _ctx.cx('root'), style: _ctx.sx('root') }, $options.attrs), { "default": withCtx(function () { return [renderSlot(_ctx.$slots, "default")]; }), _: 3 }, 16, ["class", "style"])) : renderSlot(_ctx.$slots, "default", { key: 1, "class": normalizeClass(_ctx.cx('root')), a11yAttrs: $options.a11yAttrs }); } script.render = render; export { script as default };