UNPKG

uikit

Version:

UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.

108 lines (92 loc) 3.06 kB
import { css, dimensions, flipPosition, includes, isRtl, positionAt, scrollParent, toPx, } from 'uikit-util'; export default { props: { pos: String, offset: Boolean, flip: Boolean, shift: Boolean, inset: Boolean, }, data: { pos: `bottom-${isRtl ? 'right' : 'left'}`, offset: false, flip: true, shift: true, inset: false, }, connected() { this.pos = this.$props.pos.split('-').concat('center').slice(0, 2); [this.dir, this.align] = this.pos; this.axis = includes(['top', 'bottom'], this.dir) ? 'y' : 'x'; }, methods: { positionAt(element, target, boundary) { let offset = [this.getPositionOffset(element), this.getShiftOffset(element)]; const placement = [this.flip && 'flip', this.shift && 'shift']; const attach = { element: [this.inset ? this.dir : flipPosition(this.dir), this.align], target: [this.dir, this.align], }; if (this.axis === 'y') { for (const prop in attach) { attach[prop].reverse(); } offset.reverse(); placement.reverse(); } const restoreScrollPosition = storeScrollPosition(element); // Ensure none positioned element does not generate scrollbars const elDim = dimensions(element); css(element, { top: -elDim.height, left: -elDim.width }); positionAt(element, target, { attach, offset, boundary, placement, viewportOffset: this.getViewportOffset(element), }); restoreScrollPosition(); }, getPositionOffset(element = this.$el) { return ( toPx( this.offset === false ? css(element, '--uk-position-offset') : this.offset, this.axis === 'x' ? 'width' : 'height', element, ) * (includes(['left', 'top'], this.dir) ? -1 : 1) * (this.inset ? -1 : 1) ); }, getShiftOffset(element = this.$el) { return this.align === 'center' ? 0 : toPx( css(element, '--uk-position-shift-offset'), this.axis === 'y' ? 'width' : 'height', element, ) * (includes(['left', 'top'], this.align) ? 1 : -1); }, getViewportOffset(element) { return toPx(css(element, '--uk-position-viewport-offset')); }, }, }; export function storeScrollPosition(element) { const scrollElement = scrollParent(element); const { scrollTop } = scrollElement; return () => { if (scrollTop !== scrollElement.scrollTop) { scrollElement.scrollTop = scrollTop; } }; }