8 changed files with 554 additions and 18 deletions
Split View
Diff Options
-
237components/popover/index.js
-
7components/popover/index.json
-
17components/popover/index.wxml
-
193components/popover/index.wxss
-
66pages/agent/detail/item-money-info/money-info.js
-
4pages/agent/detail/item-money-info/money-info.json
-
40pages/agent/detail/item-money-info/money-info.wxml
-
8pages/agent/detail/pound-info/pound-info.wxml
@ -0,0 +1,237 @@ |
|||
import baseComponent from '../helpers/baseComponent' |
|||
import classNames from '../helpers/classNames' |
|||
import styleToCssString from '../helpers/styleToCssString' |
|||
import { $wuxBackdrop } from '../index' |
|||
|
|||
const getPlacements = ([a, s, b] = rects, placement = 'top') => { |
|||
switch (placement) { |
|||
case 'topLeft': |
|||
return { |
|||
top: s.scrollTop + a.top - b.height - 4, |
|||
left: s.scrollLeft + a.left, |
|||
} |
|||
case 'top': |
|||
return { |
|||
top: s.scrollTop + a.top - b.height - 4, |
|||
left: s.scrollLeft + a.left + (a.width - b.width) / 2, |
|||
} |
|||
case 'topRight': |
|||
return { |
|||
top: s.scrollTop + a.top - b.height - 4, |
|||
left: s.scrollLeft + a.left + a.width - b.width, |
|||
} |
|||
case 'rightTop': |
|||
return { |
|||
top: s.scrollTop + a.top, |
|||
left: s.scrollLeft + a.left + a.width + 4, |
|||
} |
|||
case 'right': |
|||
return { |
|||
top: s.scrollTop + a.top + (a.height - b.height) / 2, |
|||
left: s.scrollLeft + a.left + a.width + 4, |
|||
} |
|||
case 'rightBottom': |
|||
return { |
|||
top: s.scrollTop + a.top + a.height - b.height, |
|||
left: s.scrollLeft + a.left + a.width + 4, |
|||
} |
|||
case 'bottomRight': |
|||
return { |
|||
top: s.scrollTop + a.top + a.height + 4, |
|||
left: s.scrollLeft + a.left + a.width - b.width, |
|||
} |
|||
case 'bottom': |
|||
return { |
|||
top: s.scrollTop + a.top + a.height + 4, |
|||
left: s.scrollLeft + a.left + (a.width - b.width) / 2, |
|||
} |
|||
case 'bottomLeft': |
|||
return { |
|||
top: s.scrollTop + a.top + a.height + 4, |
|||
left: s.scrollLeft + a.left, |
|||
} |
|||
case 'leftBottom': |
|||
return { |
|||
top: s.scrollTop + a.top + a.height - b.height, |
|||
left: s.scrollLeft + a.left - b.width - 4, |
|||
} |
|||
case 'left': |
|||
return { |
|||
top: s.scrollTop + a.top + (a.height - b.height) / 2, |
|||
left: s.scrollLeft + a.left - b.width - 4, |
|||
} |
|||
case 'leftTop': |
|||
return { |
|||
top: s.scrollTop + a.top, |
|||
left: s.scrollLeft + a.left - b.width - 4, |
|||
} |
|||
default: |
|||
return { |
|||
left: 0, |
|||
top: 0, |
|||
} |
|||
} |
|||
} |
|||
|
|||
baseComponent({ |
|||
properties: { |
|||
prefixCls: { |
|||
type: String, |
|||
value: 'wux-popover', |
|||
}, |
|||
classNames: { |
|||
type: null, |
|||
value: 'wux-animate--fadeIn', |
|||
}, |
|||
theme: { |
|||
type: String, |
|||
value: 'light', |
|||
}, |
|||
title: { |
|||
type: String, |
|||
value: '', |
|||
}, |
|||
content: { |
|||
type: String, |
|||
value: '', |
|||
}, |
|||
placement: { |
|||
type: String, |
|||
value: 'top', |
|||
}, |
|||
trigger: { |
|||
type: String, |
|||
value: 'click', |
|||
}, |
|||
bodyStyle: { |
|||
type: [String, Object], |
|||
value: '', |
|||
observer(newVal) { |
|||
this.setData({ |
|||
extStyle: styleToCssString(newVal), |
|||
}) |
|||
}, |
|||
}, |
|||
defaultVisible: { |
|||
type: Boolean, |
|||
value: false, |
|||
}, |
|||
visible: { |
|||
type: Boolean, |
|||
value: false, |
|||
observer(newVal) { |
|||
if (this.data.controlled) { |
|||
this.updated(newVal) |
|||
} |
|||
}, |
|||
}, |
|||
controlled: { |
|||
type: Boolean, |
|||
value: false, |
|||
}, |
|||
mask: { |
|||
type: Boolean, |
|||
value: false, |
|||
}, |
|||
maskClosable: { |
|||
type: Boolean, |
|||
value: true, |
|||
}, |
|||
}, |
|||
data: { |
|||
extStyle: '', |
|||
popoverStyle: '', |
|||
popoverVisible: false, |
|||
}, |
|||
computed: { |
|||
classes: ['prefixCls, theme, placement', function(prefixCls, theme, placement) { |
|||
const wrap = classNames(prefixCls, { |
|||
[`${prefixCls}--theme-${theme}`]: theme, |
|||
[`${prefixCls}--placement-${placement}`]: placement, |
|||
}) |
|||
const content = `${prefixCls}__content` |
|||
const arrow = `${prefixCls}__arrow` |
|||
const inner = `${prefixCls}__inner` |
|||
const title = `${prefixCls}__title` |
|||
const innerContent = `${prefixCls}__inner-content` |
|||
const element = `${prefixCls}__element` |
|||
|
|||
return { |
|||
wrap, |
|||
content, |
|||
arrow, |
|||
inner, |
|||
title, |
|||
innerContent, |
|||
element, |
|||
} |
|||
}], |
|||
}, |
|||
methods: { |
|||
updated(popoverVisible) { |
|||
if (this.data.popoverVisible !== popoverVisible) { |
|||
this.setData({ popoverVisible }) |
|||
this.setBackdropVisible(popoverVisible) |
|||
} |
|||
}, |
|||
getPopoverStyle() { |
|||
const { prefixCls, placement } = this.data |
|||
const query = wx.createSelectorQuery().in(this) |
|||
query.select(`.${prefixCls}__element`).boundingClientRect() |
|||
query.selectViewport().scrollOffset() |
|||
query.select(`.${prefixCls}`).boundingClientRect() |
|||
query.exec((rects) => { |
|||
if (rects.filter((n) => !n).length) return |
|||
|
|||
const placements = getPlacements(rects, placement) |
|||
const popoverStyle = styleToCssString(placements) |
|||
|
|||
this.setData({ |
|||
popoverStyle, |
|||
}) |
|||
}) |
|||
}, |
|||
/** |
|||
* 当组件进入过渡的开始状态时,设置气泡框位置信息 |
|||
*/ |
|||
onEnter() { |
|||
this.getPopoverStyle() |
|||
}, |
|||
onChange() { |
|||
const { popoverVisible, controlled } = this.data |
|||
const nextVisible = !popoverVisible |
|||
|
|||
if (!controlled) { |
|||
this.updated(nextVisible) |
|||
} |
|||
|
|||
this.triggerEvent('change', { visible: nextVisible }) |
|||
}, |
|||
onClick() { |
|||
if (this.data.trigger === 'click') { |
|||
this.onChange() |
|||
} |
|||
}, |
|||
setBackdropVisible(visible) { |
|||
if (this.data.mask && this.$wuxBackdrop) { |
|||
this.$wuxBackdrop[visible ? 'retain' : 'release']() |
|||
} |
|||
}, |
|||
onMaskClick() { |
|||
const { maskClosable, popoverVisible } = this.data |
|||
if (maskClosable && popoverVisible) { |
|||
this.onChange() |
|||
} |
|||
}, |
|||
}, |
|||
ready() { |
|||
const { defaultVisible, visible, controlled } = this.data |
|||
const popoverVisible = controlled ? visible : defaultVisible |
|||
|
|||
if (this.data.mask) { |
|||
this.$wuxBackdrop = $wuxBackdrop('#wux-backdrop', this) |
|||
} |
|||
|
|||
this.updated(popoverVisible) |
|||
}, |
|||
}) |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"component": true, |
|||
"usingComponents": { |
|||
"wux-animation-group": "../animation-group/index", |
|||
"wux-backdrop": "../backdrop/index" |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
<wux-backdrop id="wux-backdrop" wx:if="{{ mask }}" bind:click="onMaskClick" /> |
|||
<view class="wux-class {{ classes.wrap }}" style="{{ extStyle + popoverStyle }}"> |
|||
<wux-animation-group in="{{ popoverVisible }}" classNames="{{ classNames }}" bind:enter="onEnter"> |
|||
<view class="{{ classes.content }}"> |
|||
<view class="{{ classes.arrow }}"></view> |
|||
<view class="{{ classes.inner }}"> |
|||
<view class="{{ classes.title }}" wx:if="{{ title }}">{{ title }}</view> |
|||
<slot name="title" wx:else></slot> |
|||
<view class="{{ classes.innerContent }}" wx:if="{{ content }}">{{ content }}</view> |
|||
<slot name="content" wx:else></slot> |
|||
</view> |
|||
</view> |
|||
</wux-animation-group> |
|||
</view> |
|||
<view class="{{ classes.element }}" catchtap="onClick"> |
|||
<slot></slot> |
|||
</view> |
|||
@ -0,0 +1,193 @@ |
|||
.wux-popover { |
|||
font-family: Monospaced Number,Chinese Quote,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif; |
|||
font-size: 28rpx; |
|||
line-height: 1.5; |
|||
color: rgba(0,0,0,.65); |
|||
box-sizing: border-box; |
|||
margin: 0; |
|||
padding: 0; |
|||
list-style: none; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: 1030; |
|||
cursor: auto; |
|||
-webkit-user-select: text; |
|||
-moz-user-select: text; |
|||
-ms-user-select: text; |
|||
user-select: text; |
|||
white-space: normal; |
|||
font-weight: 400; |
|||
text-align: left |
|||
} |
|||
.wux-popover::after { |
|||
content: ""; |
|||
position: absolute; |
|||
background: rgba(255,255,255,.01) |
|||
} |
|||
.wux-popover__container { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100% |
|||
} |
|||
.wux-popover__element { |
|||
display: inline-block; |
|||
line-height: 1 |
|||
} |
|||
.wux-popover--theme-dark .wux-popover__inner { |
|||
background-color: #333 |
|||
} |
|||
.wux-popover--theme-dark.wux-popover--placement-top .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-topLeft .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-topRight .wux-popover__arrow { |
|||
border-top-color: #333 |
|||
} |
|||
.wux-popover--theme-dark.wux-popover--placement-right .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-rightBottom .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-rightTop .wux-popover__arrow { |
|||
border-right-color: #333 |
|||
} |
|||
.wux-popover--theme-dark.wux-popover--placement-bottom .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-bottomLeft .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-bottomRight .wux-popover__arrow { |
|||
border-bottom-color: #333 |
|||
} |
|||
.wux-popover--theme-dark.wux-popover--placement-left .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-leftBottom .wux-popover__arrow, |
|||
.wux-popover--theme-dark.wux-popover--placement-leftTop .wux-popover__arrow { |
|||
border-left-color: #333 |
|||
} |
|||
.wux-popover--theme-dark .wux-popover__inner, |
|||
.wux-popover--theme-dark .wux-popover__title { |
|||
color: #fff |
|||
} |
|||
.wux-popover--placement-top, |
|||
.wux-popover--placement-topLeft, |
|||
.wux-popover--placement-topRight { |
|||
padding-bottom: 10px |
|||
} |
|||
.wux-popover--placement-right, |
|||
.wux-popover--placement-rightBottom, |
|||
.wux-popover--placement-rightTop { |
|||
padding-left: 10px |
|||
} |
|||
.wux-popover--placement-bottom, |
|||
.wux-popover--placement-bottomLeft, |
|||
.wux-popover--placement-bottomRight { |
|||
padding-top: 10px |
|||
} |
|||
.wux-popover--placement-left, |
|||
.wux-popover--placement-leftBottom, |
|||
.wux-popover--placement-leftTop { |
|||
padding-right: 10px |
|||
} |
|||
.wux-popover__inner { |
|||
background-color: #fff; |
|||
background-clip: padding-box; |
|||
border-radius: 4px; |
|||
box-shadow: 0 2px 8px rgba(0,0,0,.15); |
|||
color: rgba(0,0,0,.65) |
|||
} |
|||
.wux-popover__title { |
|||
position: relative; |
|||
min-width: 120px; |
|||
margin: 0; |
|||
padding: 5px 16px 4px; |
|||
min-height: 32px; |
|||
box-sizing: border-box; |
|||
color: rgba(0,0,0,.85); |
|||
font-weight: 500 |
|||
} |
|||
.wux-popover__title::after { |
|||
content: " "; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: 0; |
|||
right: 0; |
|||
height: 1PX; |
|||
border-bottom: 1PX solid #d9d9d9; |
|||
color: #d9d9d9; |
|||
transform-origin: 0 100%; |
|||
transform: scaleY(.5) |
|||
} |
|||
.wux-popover__inner-content { |
|||
padding: 24rpx 32rpx |
|||
} |
|||
.wux-popover__arrow { |
|||
width: 0; |
|||
height: 0; |
|||
position: absolute; |
|||
display: block; |
|||
border-color: transparent; |
|||
border-style: solid; |
|||
border-width: 16.97056274rpx |
|||
} |
|||
.wux-popover--placement-top .wux-popover__arrow, |
|||
.wux-popover--placement-topLeft .wux-popover__arrow, |
|||
.wux-popover--placement-topRight .wux-popover__arrow { |
|||
bottom: 8rpx; |
|||
border-bottom-width: 0; |
|||
border-top-color: #fff |
|||
} |
|||
.wux-popover--placement-top .wux-popover__arrow { |
|||
left: 50%; |
|||
transform: translateX(-50%) |
|||
} |
|||
.wux-popover--placement-topLeft .wux-popover__arrow { |
|||
left: 32rpx |
|||
} |
|||
.wux-popover--placement-topRight .wux-popover__arrow { |
|||
right: 32rpx |
|||
} |
|||
.wux-popover--placement-right .wux-popover__arrow, |
|||
.wux-popover--placement-rightBottom .wux-popover__arrow, |
|||
.wux-popover--placement-rightTop .wux-popover__arrow { |
|||
left: 8rpx; |
|||
border-left-width: 0; |
|||
border-right-color: #fff |
|||
} |
|||
.wux-popover--placement-right .wux-popover__arrow { |
|||
top: 50%; |
|||
transform: translateY(-50%) |
|||
} |
|||
.wux-popover--placement-rightTop .wux-popover__arrow { |
|||
top: 24rpx |
|||
} |
|||
.wux-popover--placement-rightBottom .wux-popover__arrow { |
|||
bottom: 24rpx |
|||
} |
|||
.wux-popover--placement-bottom .wux-popover__arrow, |
|||
.wux-popover--placement-bottomLeft .wux-popover__arrow, |
|||
.wux-popover--placement-bottomRight .wux-popover__arrow { |
|||
top: 8rpx; |
|||
border-top-width: 0; |
|||
border-bottom-color: #fff |
|||
} |
|||
.wux-popover--placement-bottom .wux-popover__arrow { |
|||
left: 50%; |
|||
transform: translateX(-50%) |
|||
} |
|||
.wux-popover--placement-bottomLeft .wux-popover__arrow { |
|||
left: 32rpx |
|||
} |
|||
.wux-popover--placement-bottomRight .wux-popover__arrow { |
|||
right: 32rpx |
|||
} |
|||
.wux-popover--placement-left .wux-popover__arrow, |
|||
.wux-popover--placement-leftBottom .wux-popover__arrow, |
|||
.wux-popover--placement-leftTop .wux-popover__arrow { |
|||
right: 8rpx; |
|||
border-right-width: 0; |
|||
border-left-color: #fff |
|||
} |
|||
.wux-popover--placement-left .wux-popover__arrow { |
|||
top: 50%; |
|||
transform: translateY(-50%) |
|||
} |
|||
.wux-popover--placement-leftTop .wux-popover__arrow { |
|||
top: 24rpx |
|||
} |
|||
.wux-popover--placement-leftBottom .wux-popover__arrow { |
|||
bottom: 24rpx |
|||
} |
|||
@ -1,4 +1,6 @@ |
|||
{ |
|||
"component": true, |
|||
"usingComponents": {} |
|||
"usingComponents": { |
|||
"wux-popover": "/components/popover/index" |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save