diff --git a/src/popover/demo/index.vue b/src/popover/demo/index.vue index 644a69370..07d4cfea6 100644 --- a/src/popover/demo/index.vue +++ b/src/popover/demo/index.vue @@ -17,7 +17,7 @@ v-model="show.lightTheme" theme="light" :actions="t('actions')" - placement="bottom" + placement="right-end" > {{ t('lightTheme') }} diff --git a/src/popover/index.js b/src/popover/index.js index 39dbc01ed..ed6e72535 100644 --- a/src/popover/index.js +++ b/src/popover/index.js @@ -26,7 +26,7 @@ export default createComponent({ closeOnClickAction: Boolean, offset: { type: Array, - default: [0, 0], + default: () => [0, 8], }, theme: { type: String, @@ -113,7 +113,7 @@ export default createComponent({ ref="popover" value={this.value} style={this.location} - class={bem([this.theme])} + class={bem([this.theme, `placement-${this.placement}`])} overlay={this.overlay} position="" transition="van-popover-zoom" @@ -121,6 +121,7 @@ export default createComponent({ getContainer={this.getContainer} onInput={this.onToggle} > +
{this.actions.map(this.renderAction)} {this.slots('default')} diff --git a/src/popover/index.less b/src/popover/index.less index f27fe55db..7f8a4fb7a 100644 --- a/src/popover/index.less +++ b/src/popover/index.less @@ -3,6 +3,7 @@ .van-popover { position: absolute; + overflow: visible; border-radius: @border-radius-lg; transition-duration: 0s; @@ -10,6 +11,15 @@ display: inline-block; } + &__arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 6px; + } + &__action { position: relative; display: flex; @@ -28,11 +38,131 @@ } } + &--placement-top, + &--placement-top-start, + &--placement-top-end { + .van-popover__arrow { + bottom: 0; + border-top-color: currentColor; + border-bottom-width: 0; + transform: translate(-50%, 100%); + } + } + + &--placement-top { + .van-popover__arrow { + left: 50%; + } + } + + &--placement-top-start { + .van-popover__arrow { + left: @padding-md; + } + } + + &--placement-top-end { + .van-popover__arrow { + right: @padding-md; + } + } + + &--placement-left, + &--placement-left-start, + &--placement-left-end { + .van-popover__arrow { + right: 0; + border-right-width: 0; + border-left-color: currentColor; + transform: translate(100%, -50%); + } + } + + &--placement-left { + .van-popover__arrow { + top: 50%; + } + } + + &--placement-left-start { + .van-popover__arrow { + top: @padding-md; + } + } + + &--placement-left-end { + .van-popover__arrow { + bottom: @padding-md; + } + } + + &--placement-right, + &--placement-right-start, + &--placement-right-end { + .van-popover__arrow { + left: 0; + border-right-color: currentColor; + border-left-width: 0; + transform: translate(-100%, -50%); + } + } + + &--placement-right { + .van-popover__arrow { + top: 50%; + } + } + + &--placement-right-start { + .van-popover__arrow { + top: @padding-md; + } + } + + &--placement-right-end { + .van-popover__arrow { + bottom: @padding-md; + } + } + + &--placement-bottom, + &--placement-bottom-start, + &--placement-bottom-end { + .van-popover__arrow { + top: 0; + border-top-width: 0; + border-bottom-color: currentColor; + transform: translate(-50%, -100%); + } + } + + &--placement-bottom { + .van-popover__arrow { + left: 50%; + } + } + + &--placement-bottom-start { + .van-popover__arrow { + left: @padding-md; + } + } + + &--placement-bottom-end { + .van-popover__arrow { + right: @padding-md; + } + } + &--light { color: @text-color; background-color: @white; box-shadow: 0 2px 12px rgba(50, 50, 51, 0.12); + .van-popover__arrow { + color: @white; + } + .van-popover__action { &:active { background-color: @active-color; @@ -45,6 +175,10 @@ background-color: @gray-8; opacity: 0.9; + .van-popover__arrow { + color: @gray-8; + } + .van-popover__action { &::after { border-color: @gray-7;