完成popconfirm组件的重构
parent
2f2d1ebbe9
commit
007ee67e87
|
@ -4,13 +4,26 @@
|
||||||
* @date 2023/03/21 16:14:10
|
* @date 2023/03/21 16:14:10
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { css, html, Component, bind, styleMap, offset } from 'wkit'
|
import {
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
Component,
|
||||||
|
bind,
|
||||||
|
unbind,
|
||||||
|
styleMap,
|
||||||
|
offset,
|
||||||
|
outsideClick,
|
||||||
|
clearOutsideClick
|
||||||
|
} from 'wkit'
|
||||||
|
|
||||||
|
import '../form/button.js'
|
||||||
|
|
||||||
const DEFAULT_TIPS = '请确认你的操作!'
|
const DEFAULT_TIPS = '请确认你的操作!'
|
||||||
|
|
||||||
class PopConfirm extends Component {
|
class PopConfirm extends Component {
|
||||||
static props = {
|
static props = {
|
||||||
title: 'str!'
|
title: 'str!',
|
||||||
|
confirmButtonType: 'str!primary'
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = [
|
||||||
|
@ -29,14 +42,14 @@ class PopConfirm extends Component {
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
max-width: 360px;
|
max-width: 260px;
|
||||||
min-width: 32px;
|
min-width: 32px;
|
||||||
padding: 6px 8px;
|
padding: 8px 12px 12px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-size: var(--wc-tooltip-font, 14px);
|
font-size: var(--wc-popconfirm-font, 14px);
|
||||||
background: var(--wc-tooltip-background, #fff);
|
background: var(--wc-popconfirm-background, #fff);
|
||||||
color: var(--wc-tooltip-color, var(--color-dark-1));
|
color: var(--wc-popconfirm-color, var(--color-dark-1));
|
||||||
box-shadow: 0 0 3px var(--wc-tooltip-shadow, rgba(0, 0, 0, 0.2));
|
box-shadow: 0 0 3px var(--wc-popconfirm-shadow, rgba(0, 0, 0, 0.3));
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
@ -47,17 +60,18 @@ class PopConfirm extends Component {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background: var(--wc-tooltip-background, #fff);
|
background: var(--wc-popconfirm-background, #fff);
|
||||||
content: '';
|
content: '';
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
box-shadow: -1px -1px 0 var(--wc-tooltip-shadow, rgba(0, 0, 0, 0.1));
|
box-shadow: -1px -1px 0 var(--wc-popconfirm-shadow, rgba(0, 0, 0, 0.1));
|
||||||
}
|
}
|
||||||
|
|
||||||
&[placement='left-top'] {
|
&[placement='left-top'] {
|
||||||
&::after {
|
&::after {
|
||||||
right: 16px;
|
right: 16px;
|
||||||
bottom: -4px;
|
bottom: -4px;
|
||||||
box-shadow: 1px 1px 0 var(--wc-tooltip-shadow, rgba(0, 0, 0, 0.1));
|
box-shadow: 1px 1px 0
|
||||||
|
var(--wc-popconfirm-shadow, rgba(0, 0, 0, 0.1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&[placement='left-bottom'] {
|
&[placement='left-bottom'] {
|
||||||
|
@ -70,7 +84,8 @@ class PopConfirm extends Component {
|
||||||
&::after {
|
&::after {
|
||||||
left: 16px;
|
left: 16px;
|
||||||
bottom: -4px;
|
bottom: -4px;
|
||||||
box-shadow: 1px 1px 0 var(--wc-tooltip-shadow, rgba(0, 0, 0, 0.1));
|
box-shadow: 1px 1px 0
|
||||||
|
var(--wc-popconfirm-shadow, rgba(0, 0, 0, 0.1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&[placement='right-bottom'] {
|
&[placement='right-bottom'] {
|
||||||
|
@ -80,23 +95,68 @@ class PopConfirm extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
|
||||||
|
css`
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 0;
|
||||||
|
--wc-icon-size: 16px;
|
||||||
|
|
||||||
|
wc-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: var(--wc-popconfirm-icon-color, var(--color-red-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host([hide-icon]) {
|
||||||
|
.title wc-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 4px;
|
||||||
|
margin-top: 8px;
|
||||||
|
|
||||||
|
wc-button {
|
||||||
|
min-width: 40px;
|
||||||
|
height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
--wc-button-border-color: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
`
|
`
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#poped = false
|
||||||
|
|
||||||
#click(ev) {
|
#click(ev) {
|
||||||
let { left, top } = offset(this)
|
let { left, top } = offset(this)
|
||||||
let placement = 'left'
|
let placement = 'left'
|
||||||
let styles = { display: 'block' }
|
let styles = { display: 'block' }
|
||||||
|
let st = document.documentElement.scrollTop
|
||||||
|
|
||||||
if (left < 360 || (left > 360 && window.innerWidth - left > 360)) {
|
if (this.#poped) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left < 260 || (left > 260 && window.innerWidth - left > 260)) {
|
||||||
placement = 'right'
|
placement = 'right'
|
||||||
styles.left = left + 'px'
|
styles.left = left + 'px'
|
||||||
} else {
|
} else {
|
||||||
let right = window.innerWidth - left - this.clientWidth
|
let right = window.innerWidth - left + this.clientWidth
|
||||||
styles.right = right + 'px'
|
styles.right = right + 'px'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (top < 96) {
|
if (top < 160) {
|
||||||
top += 8 + this.clientHeight
|
top += 8 + this.clientHeight
|
||||||
placement += '-bottom'
|
placement += '-bottom'
|
||||||
styles.top = top + 'px'
|
styles.top = top + 'px'
|
||||||
|
@ -104,28 +164,68 @@ class PopConfirm extends Component {
|
||||||
let bottom = window.innerHeight - top + 8
|
let bottom = window.innerHeight - top + 8
|
||||||
placement += '-top'
|
placement += '-top'
|
||||||
styles.bottom = bottom + 'px'
|
styles.bottom = bottom + 'px'
|
||||||
|
if (st > 0) {
|
||||||
|
styles.transform = `translateY(-${st}px)`
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#poped = true
|
||||||
|
|
||||||
//
|
//
|
||||||
this.$refs.tips.setAttribute('placement', placement)
|
this.$refs.tips.setAttribute('placement', placement)
|
||||||
this.$refs.tips.style.cssText = styleMap(styles)
|
this.$refs.tips.style.cssText = styleMap(styles)
|
||||||
this.$refs.tips.$animate()
|
this.$refs.tips.$animate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#close() {
|
||||||
|
if (this.#poped) {
|
||||||
|
this.#poped = false
|
||||||
|
this.$refs.tips.$animate(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm() {
|
||||||
|
this.$emit('confirm')
|
||||||
|
this.#close()
|
||||||
|
}
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
// bind(this.$refs.wrap, 'mouseleave', ev => {
|
this._outFn = outsideClick(this, _ => this.#close())
|
||||||
// this.$refs.tips.$animate(true)
|
|
||||||
// })
|
this._scrollFn = bind(document, 'scroll', ev => {
|
||||||
|
if (this.#poped) {
|
||||||
|
let st = document.documentElement.scrollTop
|
||||||
|
this.$refs.tips.style.transform = `translateY(-${st}px)`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
unmounted() {
|
||||||
|
unbind(document, 'scroll', this._scrollFn)
|
||||||
|
clearOutsideClick(this._outFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<div class="wrapper" ref="wrap" @click=${this.#click}>
|
<div class="wrapper" @click=${this.#click}>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="tooltip" ref="tips" #animation=${{}}>
|
<div class="tooltip" ref="tips" #animation=${{}}>
|
||||||
<slot name="title">${this.title || DEFAULT_TIPS}</slot
|
<header class="title">
|
||||||
><i class="trigon"></i>
|
<wc-icon name="info"></wc-icon>
|
||||||
|
${this.title || DEFAULT_TIPS}
|
||||||
|
</header>
|
||||||
|
<footer class="actions">
|
||||||
|
<wc-button @click=${this.#close}>取消</wc-button>
|
||||||
|
<wc-button
|
||||||
|
solid
|
||||||
|
type=${this.confirmButtonType || 'primary'}
|
||||||
|
@click=${this.#confirm}
|
||||||
|
>确定</wc-button
|
||||||
|
>
|
||||||
|
</footer>
|
||||||
|
<i class="trigon"></i>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
`
|
`
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Tooltip extends Component {
|
||||||
font-size: var(--wc-tooltip-font, 14px);
|
font-size: var(--wc-tooltip-font, 14px);
|
||||||
background: var(--wc-tooltip-background, #fff);
|
background: var(--wc-tooltip-background, #fff);
|
||||||
color: var(--wc-tooltip-color, var(--color-dark-1));
|
color: var(--wc-tooltip-color, var(--color-dark-1));
|
||||||
box-shadow: 0 0 3px var(--wc-tooltip-shadow, rgba(0, 0, 0, 0.2));
|
box-shadow: 0 0 3px var(--wc-tooltip-shadow, rgba(0, 0, 0, 0.3));
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
@ -104,7 +104,6 @@ class Tooltip extends Component {
|
||||||
top += 8 + this.clientHeight
|
top += 8 + this.clientHeight
|
||||||
placement += '-bottom'
|
placement += '-bottom'
|
||||||
styles.top = top + 'px'
|
styles.top = top + 'px'
|
||||||
// console.log('<><><>', st)
|
|
||||||
} else {
|
} else {
|
||||||
let bottom = window.innerHeight - top + 8 + st
|
let bottom = window.innerHeight - top + 8 + st
|
||||||
placement += '-top'
|
placement += '-top'
|
||||||
|
|
Loading…
Reference in New Issue