UNPKG

wot-design

Version:

Mobile UI components built on vue.js

261 lines (233 loc) 7.98 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _clickoutside = _interopRequireDefault(require("wot-design/lib/utils/clickoutside")); /** * @param {String} [placement=bottom] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -end), left(-start, -end) * @param {Number} [offset=5] - Amount of pixels the popper will be shifted (can be negative). * @param {Boolean} [visibleArrow=false] Visibility of the arrow * @param {Boolean} [value=false] Visibility of the component * @param {Boolean} [disabled=false] Disabled to change. * @param {Boolean} [closeOutside=true] 点击外部关闭 */ var _default = { props: { placement: { type: String, default: 'bottom' }, visibleArrow: { type: Boolean, default: true }, offset: { type: Number, default: 0 }, value: Boolean, closeOutside: { type: Boolean, default: true }, disabled: Boolean }, directives: { Clickoutside: _clickoutside.default }, data: function data() { return { popStyle: {}, arrowStyle: {}, showPop: false }; }, computed: { arrowClass: function arrowClass() { var _ref; var el = "wd-" + this.el + "__arrow"; return this.visibleArrow ? (_ref = {}, _ref[el] = true, _ref[el + '-up'] = this.placement === 'bottom' || this.placement === 'bottom-start' || this.placement === 'bottom-end', _ref[el + '-right'] = this.placement === 'left' || this.placement === 'left-start' || this.placement === 'left-end', _ref[el + '-left'] = this.placement === 'right' || this.placement === 'right-start' || this.placement === 'right-end', _ref[el + '-down'] = this.placement === 'top' || this.placement === 'top-start' || this.placement === 'top-end', _ref) : ''; } }, watch: { 'value': { immediate: true, // immediate选项可以开启首次赋值监听 handler: function handler(newVal) { if (newVal === this.showPop) return; this.toggle(true); } } }, methods: { /** * @param {Boolean} isOutsideControl 判定是否是value控制的显隐, 默认值为空 */ toggle: function toggle(isOutsideControl) { var _this = this; if (isOutsideControl === void 0) { isOutsideControl = false; } if (this.disabled) return; this.showPop = isOutsideControl ? this.value : !this.showPop; if (this.showPop) { this.$nextTick(function () { _this.init(); }); } this.$emit("" + (this.showPop === true ? 'show' : 'hide')); this.$emit('input', this.showPop); }, // 点击外部关闭 handleOutsideClick: function handleOutsideClick() { if (!this.closeOutside || this.disabled) return; this.showPop && this.toggle(); }, // 位置初始化函数 init: function init() { // 目标对象 dom(被跟随) var trigger = this.$refs.trigger ? this.$refs.trigger.children[0] : {}; // 文字提示 dom var popover = this.$refs[this.el]; var arrow = this.$refs.arrow || ''; var arrowHeight = arrow.offsetHeight || 0; var arrowWidth = arrow.offsetWidth || 0; var arrowStyle = {}; var position = {}; // 上下位(纵轴)对应的距离左边的距离 var verticalX = trigger.offsetWidth / 2; // 上下位(纵轴)对应的距离底部的距离 var verticalY = trigger.offsetHeight + arrowHeight + 5; // 左右位(横轴)对应的距离左边的距离 var horizontalX = trigger.offsetWidth + arrowWidth + 5; // 左右位(横轴)对应的距离底部的距离 var horizontalY = trigger.offsetHeight / 2; var offsetX = (verticalX - arrowWidth > 0 ? 0 : verticalX - 25) + this.offset; var offsetY = (horizontalY - arrowHeight > 0 ? 0 : horizontalY - 20) + this.offset; // 定位元素,考虑滚动该高度,当前参照对象的距离顶部高度,左侧相对屏幕距离 switch (this.placement) { case 'top': position = { left: verticalX + "px", transform: 'translateX(-50%)', bottom: verticalY + "px" }; arrowStyle = { left: '50%' }; break; case 'top-start': position = { left: offsetX + "px", bottom: verticalY + "px" }; arrowStyle = { left: (popover.offsetWidth >= trigger.offsetWidth ? verticalX : popover.offsetWidth - 25) - offsetX + "px" }; break; case 'top-end': position = { right: offsetX + "px", bottom: verticalY + "px" }; arrowStyle = { right: (popover.offsetWidth >= trigger.offsetWidth ? verticalX : popover.offsetWidth - 25) - offsetX + "px", transform: 'translateX(50%)' }; break; case 'bottom': position = { left: verticalX + "px", transform: 'translateX(-50%)', top: verticalY + "px" }; arrowStyle = { left: '50%' }; break; case 'bottom-start': position = { left: offsetX + "px", top: verticalY + "px" }; arrowStyle = { left: 25 - this.offset + "px" }; break; case 'bottom-end': position = { right: offsetX + "px", top: verticalY + "px" }; arrowStyle = { right: 25 - this.offset + "px", transform: 'translateX(50%)' }; break; case 'left': position = { right: horizontalX + "px", top: horizontalY + "px", transform: 'translateY(-50%)' }; arrowStyle = { top: '50%' }; break; case 'left-start': position = { right: horizontalX + "px", top: offsetY + "px" }; arrowStyle = { top: 20 - this.offset + "px" }; break; case 'left-end': position = { right: horizontalX + "px", bottom: offsetY + "px" }; arrowStyle = { bottom: (popover.offsetHeight >= trigger.offsetHeight ? horizontalY : popover.offsetHeight - 20) - offsetX + "px", transform: 'translateY(50%)' }; break; case 'right': position = { left: horizontalX + "px", top: horizontalY + "px", transform: 'translateY(-50%)' }; arrowStyle = { top: '50%' }; break; case 'right-start': position = { left: horizontalX + "px", top: offsetY + "px" }; arrowStyle = { top: (popover.offsetHeight >= trigger.offsetHeight ? horizontalY : popover.offsetHeight - 20) - offsetX + "px" }; break; case 'right-end': position = { left: horizontalX + "px", bottom: offsetY + "px" }; arrowStyle = { bottom: (popover.offsetHeight >= trigger.offsetHeight ? horizontalY : popover.offsetHeight - 20) - offsetX + "px", transform: 'translateY(50%)' }; break; default: console.warn('[wot design] warning: wrong placement prop'); } this.popStyle = position; this.arrowStyle = arrowStyle; } }, mounted: function mounted() { window.addEventListener('resize', this.init); }, beforeDestroy: function beforeDestroy() { window.removeEventListener('resize', this.init); } }; exports.default = _default;