From bdde2fde4033a28159dd9ca67155863fbce702b2 Mon Sep 17 00:00:00 2001 From: chenjiajian <770230504@qq.com> Date: Thu, 4 May 2023 16:15:42 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0popconfirm=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/popconfirm/index.js | 181 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 169 insertions(+), 12 deletions(-) diff --git a/src/popconfirm/index.js b/src/popconfirm/index.js index cbbcfd3..c5ac3d7 100644 --- a/src/popconfirm/index.js +++ b/src/popconfirm/index.js @@ -4,7 +4,9 @@ * @date 2023/04/28 16:14:10 */ -import { css, html, Component } from '@bd/core' +import { css, html, Component, nextTick, styleMap } from '@bd/core' +import '../form/button.js' +import '../icon/index.js' class Popconfirm extends Component { static props = { @@ -15,17 +17,17 @@ class Popconfirm extends Component { }, 'confirm-button-text': { type: String, - default: '', + default: '确定', attribute: false }, 'cancel-button-text': { type: String, - default: '', + default: '取消', attribute: false }, 'confirm-button-type': { type: String, - default: '', + default: 'primary', attribute: false }, 'cancel-button-type': { @@ -35,15 +37,36 @@ class Popconfirm extends Component { }, icon: { type: String, - default: null, + default: 'info', attribute: false }, 'icon-color': { - type: Number, - default: null, + type: String, + default: '#ff9900', attribute: false }, - hidden: false + 'hide-icon': { + type: Boolean, + default: false, + attribute: false + }, + + //组件状态 + left: { + type: Number, + default: 0, + attribute: false + }, + top: { + type: Number, + default: 0, + attribute: false + }, + show: { + type: Boolean, + default: false, + attribute: false + } } static styles = [ @@ -54,26 +77,160 @@ class Popconfirm extends Component { } .popover { z-index: 10; - position: absolute; + position: fixed; padding: 12px; min-width: 150px; border-radius: 4px; border: 1px solid #ebeef5; color: #606266; line-height: 1.4; - text-align: justify; + text-align: left; font-size: 14px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); word-break: break-all; background: #fff; + transition: opacity 0.15s linear; + .btns { + display: flex; + justify-content: flex-end; + .cancel { + margin-right: 15px; + cursor: pointer; + color: var(--color-teal-2); + } + } + } + .content { + padding: 8px 0; + display: flex; + align-items: center; + font-size: 14px; + color: #606266; + line-height: 1.4; + text-align: justify; + word-break: break-all; + white-space: nowrap; + wc-icon { + margin-right: 5px; + --size: 14px; + } + } + + .arrow { + position: absolute; + z-index: 12; + left: 50%; + top: 100%; + transform: translateX(-50%); + border: 6px solid transparent; + border-bottom-color: #fff; + &[top] { + border-bottom-color: transparent; + top: 0; + border-top-color: #fff; + transform: translateY(-100%); + } + } + + .show { + visibility: visible; + opacity: 1; + } + .hide { + visibility: hidden; + opacity: 0; } ` ] + mounted() { + this.$slot = this.$refs.slot.assignedElements().shift() + this.$popover = this.$refs.popover + this.$arrow = this.$refs.arrow + nextTick(() => this.showPopover()) + } + + showPopover() { + const slotRect = this.$slot.getBoundingClientRect() + const popoverRect = this.$popover.getBoundingClientRect() + const halfSlotWidth = slotRect.width / 2 + const halfPopoverWidth = popoverRect.width / 2 + const left = slotRect.left + halfSlotWidth - halfPopoverWidth + + if (left < 0) { + this.left = slotRect.left + } else if (left + popoverRect.width > window.innerWidth) { + this.left = slotRect.right - popoverRect.width + } else { + this.left = left + } + + if (slotRect.bottom + 10 + popoverRect.height > window.innerHeight) { + this.top = slotRect.top - 10 - popoverRect.height + this.$arrow.setAttribute('top', '') + } else { + this.top = slotRect.bottom + 10 + } + + this.show = true + } + hide({ target }) { + this.show = false + if (target.hasAttribute('solid')) { + this.$emit('confirm') + } else { + this.$emit('cancel') + } + } + render() { + let styles = styleMap({ + left: `${this.left}px`, + top: `${this.top}px` + }) + return html`
+ ${this['hide-icon']
+ ? ''
+ : html`