add Poptip component

add Poptip component
This commit is contained in:
梁灏 2016-10-27 10:30:32 +08:00
parent 4dfacfca66
commit 9699c270dc
14 changed files with 420 additions and 120 deletions

View file

@ -28,22 +28,21 @@ export default {
boundariesElement: 'body'
}
}
},
visible: {
type: Boolean,
default: false
}
},
data() {
return {
showPopper: false
};
},
watch: {
value: {
immediate: true,
handler(val) {
this.showPopper = val;
this.visible = val;
this.$emit('input', val);
}
},
showPopper(val) {
visible(val) {
val ? this.updatePopper() : this.destroyPopper();
this.$emit('input', val);
}
@ -78,7 +77,7 @@ export default {
this.popperJS ? this.popperJS.update() : this.createPopper();
},
doDestroy() {
if (this.showPopper) return;
if (this.visible) return;
this.popperJS.destroy();
this.popperJS = null;
},

View file

@ -0,0 +1,3 @@
import Poptip from './poptip.vue';
export default Poptip;

View file

@ -0,0 +1,162 @@
<template>
<div
:class="classes"
@mouseenter="handleMouseenter"
@mouseleave="handleMouseleave"
v-clickoutside="handleClose">
<div
:class="[`${prefixCls}-rel`]"
v-el:reference
@click="handleClick"
@mousedown="handleFocus"
@mouseup="handleBlur">
<slot></slot>
</div>
<div :class="[`${prefixCls}-popper`]" :style="styles" transition="fade" v-el:popper v-show="visible">
<div :class="[`${prefixCls}-content`]">
<div :class="[`${prefixCls}-arrow`]"></div>
<div :class="[`${prefixCls}-inner`]" v-if="confirm">
<div :class="[`${prefixCls}-body`]">
<i class="ivu-icon ivu-icon-help-circled"></i>
<div :class="[`${prefixCls}-body-message`]"><slot name="title">{{ title }}</slot></div>
</div>
<div :class="[`${prefixCls}-footer`]">
<Button type="ghost" size="small" @click="cancel">{{ cancelText }}</Button>
<Button type="primary" size="small" @click="ok">{{ okText }}</Button>
</div>
</div>
<div :class="[`${prefixCls}-inner`]" v-if="!confirm">
<div :class="[`${prefixCls}-title`]" v-if="!!title"><slot name="title">{{ title }}</slot></div>
<div :class="[`${prefixCls}-body`]"><slot name="content">{{ content }}</slot></div>
</div>
</div>
</div>
</div>
</template>
<script>
import Popper from '../base/popper';
import Button from '../button/button.vue';
import clickoutside from '../../directives/clickoutside';
import { oneOf } from '../../utils/assist';
const prefixCls = 'ivu-poptip';
export default {
mixins: [Popper],
directives: { clickoutside },
components: { Button },
props: {
trigger: {
validator (value) {
return oneOf(value, ['click', 'focus', 'hover']);
},
default: 'click'
},
placement: {
validator (value) {
return oneOf(value, ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end']);
},
default: 'top'
},
title: {
type: [String, Number]
},
content: {
type: [String, Number],
default: ''
},
width: {
type: [String, Number]
},
confirm: {
type: Boolean,
default: false
},
okText: {
type: String,
default: '确定'
},
cancelText: {
type: String,
default: '取消'
}
},
data () {
return {
prefixCls: prefixCls
}
},
computed: {
classes () {
return [
`${prefixCls}`,
{
[`${prefixCls}-confirm`]: this.confirm
}
]
},
styles () {
let style = {};
if (!!this.width) {
style.width = `${this.width}px`;
}
return style;
}
},
methods: {
handleClick () {
if (this.confirm) {
this.visible = !this.visible;
return true;
}
if (this.trigger !== 'click') {
return false;
}
this.visible = !this.visible;
},
handleClose () {
if (this.confirm) {
this.visible = false;
return true;
}
if (this.trigger !== 'click') {
return false;
}
this.visible = false;
},
handleFocus () {
if (this.trigger !== 'focus' || this.confirm) {
return false;
}
this.visible = true;
},
handleBlur () {
if (this.trigger !== 'focus' || this.confirm) {
return false;
}
this.visible = false;
},
handleMouseenter () {
if (this.trigger !== 'hover' || this.confirm) {
return false;
}
this.visible = true;
},
handleMouseleave () {
if (this.trigger !== 'hover' || this.confirm) {
return false;
}
this.visible = false;
},
cancel () {
this.visible = false;
this.$emit('on-cancel');
},
ok () {
this.visible = false;
this.$emit('on-ok');
}
}
}
</script>

View file

@ -3,7 +3,7 @@
<div :class="[`${prefixCls}-rel`]" v-el:reference>
<slot></slot>
</div>
<div :class="[`${prefixCls}-popper`]" transition="fade" v-el:popper v-show="!disabled && showPopper">
<div :class="[`${prefixCls}-popper`]" transition="fade" v-el:popper v-show="!disabled && visible">
<div :class="[`${prefixCls}-content`]">
<div :class="[`${prefixCls}-arrow`]"></div>
<div :class="[`${prefixCls}-inner`]"><slot name="content">{{ content }}</slot></div>
@ -47,12 +47,12 @@
methods: {
handleShowPopper() {
this.timeout = setTimeout(() => {
this.showPopper = true;
this.visible = true;
}, this.delay);
},
handleClosePopper() {
clearTimeout(this.timeout);
this.showPopper = false;
this.visible = false;
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -26,6 +26,7 @@ import LoadingBar from './components/loading-bar';
import Modal from './components/modal';
import { Select, Option, OptionGroup } from './components/select';
import Tooltip from './components/tooltip';
import Poptip from './components/poptip';
const iview = {
Button,
@ -65,7 +66,8 @@ const iview = {
iSelect: Select,
iOption: Option,
iOptionGroup: OptionGroup,
Tooltip
Tooltip,
Poptip
};
module.exports = iview;

View file

@ -9,31 +9,31 @@
</style>
<template>
<div class="tooltip_out">
123
</div>
<div class="tooltip_out">
<Tooltip content="Tooltip 文字提示" placement="top">
<strong><a href="#">Link</a></strong>
<!--<Poptip title="标题" content="内容">-->
<!--<Button>click 触发</Button>-->
<!--</Poptip>-->
<!--<Poptip title="标题" content="内容" trigger="hover">-->
<!--<Button>hover 触发</Button>-->
<!--</Poptip>-->
<Poptip title="确定删除这条信息吗?" content="内容" trigger="focus" @on-ok="ok" @on-cancel="cancel" ok-text="yes" cancel-text="no" width="200">
<a>Delete</a>
</Poptip>
<Poptip title="标题" content="内容" trigger="focus">
<input type="text">
</Poptip>
<!--<Poptip title="标题" content="内容" trigger="focus">-->
<!--<Button>focus 触发</Button>-->
<!--</Poptip>-->
<Tooltip content="这里是提示文字">
当鼠标经过这段文字时会显示一个气泡框
</Tooltip>
</div>
<Row>
<i-col span="12">
<Tooltip content="Top Left 提示文字" placement="top-start">
<Button>上面的左面</Button>
</Tooltip>
</i-col>
<i-col span="12">
<Tooltip content="Top Left 提示文字" placement="top-start">
<Button>上面的左面</Button>
</Tooltip>
</i-col>
</Row>
</template>
<script>
import { Tooltip, Button, Row, iCol } from 'iview';
import { Tooltip, Button, Row, iCol, Poptip, iSelect, iOption, Message } from 'iview';
export default {
components: { Tooltip, Button, Row, iCol },
components: { Tooltip, Button, Row, iCol, Poptip, iSelect, iOption, Message },
props: {
},
@ -46,7 +46,12 @@
},
methods: {
ok () {
Message.info('ok');
},
cancel () {
Message.info('cancel');
}
}
}
</script>

View file

@ -1,6 +1,6 @@
{
"name": "iview",
"version": "0.9.5-rc-5",
"version": "0.9.5-rc-6",
"title": "iView",
"description": "A high quality UI components Library with Vue.js",
"homepage": "http://www.iviewui.com",

View file

@ -22,4 +22,5 @@
@import "modal";
@import "select";
@import "select-dropdown";
@import "tooltip";
@import "tooltip";
@import "poptip";

View file

@ -0,0 +1,124 @@
@poptip-prefix-cls: ~"@{css-prefix}poptip";
@poptip-arrow: ~"@{poptip-prefix-cls}-arrow";
@poptip-max-width: 250px;
@poptip-arrow-width: 5px;
@poptip-arrow-outer-width: (@poptip-arrow-width + 1);
@poptip-distance: @poptip-arrow-width - 1 + 4;
//@poptip-arrow-color: fadein(@border-color-base, 5%);
@poptip-arrow-color: hsla(0,0%,85%,.5);
.@{poptip-prefix-cls} {
display: inline-block;
&-rel{
display: inline-block;
position: relative;
}
&-title {
margin: 0;
padding: 0 16px;
height: 32px;
line-height: 32px;
border-bottom: 1px solid @border-color-split;
color: #666;
}
&-body{
padding: 8px 16px;
}
&-popper{
min-width: 150px;
font-size: @font-size-small;
.popper(@poptip-arrow, @poptip-arrow-width, @poptip-distance, @poptip-arrow-color);
&[x-placement^="top"] .@{poptip-arrow}:after {
content: " ";
bottom: 1px;
margin-left: -@poptip-arrow-width;
border-bottom-width: 0;
border-top-color: #fff;
}
&[x-placement^="right"] .@{poptip-arrow}:after {
content: " ";
left: 1px;
bottom: -@poptip-arrow-width;
border-left-width: 0;
border-right-color: #fff;
}
&[x-placement^="bottom"] .@{poptip-arrow}:after {
content: " ";
top: 1px;
margin-left: -@poptip-arrow-width;
border-top-width: 0;
border-bottom-color: #fff;
}
&[x-placement^="left"] .@{poptip-arrow}:after {
content: " ";
right: 1px;
border-right-width: 0;
border-left-color: #fff;
bottom: -@poptip-arrow-width;
}
}
&-inner{
width: 100%;
background-color: #fff;
background-clip: padding-box;
border: 1px solid @border-color-split;
border-radius: @border-radius-small;
box-shadow: @shadow-base;
white-space: nowrap;
}
&-arrow{
&, &:after{
display: block;
width: 0;
height: 0;
position: absolute;
border-color: transparent;
border-style: solid;
}
}
&-arrow {
border-width: @poptip-arrow-outer-width;
}
&-arrow:after{
content: "";
border-width: @poptip-arrow-width;
}
&-confirm &-popper{
max-width: 300px;
}
&-confirm &-inner{
white-space: normal;
}
&-confirm &-body{
padding: 16px 16px 8px;
.ivu-icon{
color: @warning-color;
line-height: 17px;
position: absolute;
}
&-message{
padding-left: 20px;
}
}
&-confirm &-footer{
text-align: right;
padding: 8px 16px 16px;
button {
margin-left: 4px;
}
}
}

View file

@ -13,89 +13,7 @@
}
&-popper{
display: block;
visibility: visible;
font-size: @font-size-small;
line-height: @line-height-base;
position: absolute;
z-index: @zindex-tooltip;
&[x-placement^="top"] {
padding: @tooltip-arrow-width 0 @tooltip-distance 0;
}
&[x-placement^="right"] {
padding: 0 @tooltip-arrow-width 0 @tooltip-distance;
}
&[x-placement^="bottom"] {
padding: @tooltip-distance 0 @tooltip-arrow-width 0;
}
&[x-placement^="left"] {
padding: 0 @tooltip-distance 0 @tooltip-arrow-width;
}
&[x-placement^="top"] .@{tooltip-arrow} {
bottom: @tooltip-distance - @tooltip-arrow-width;
border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
border-top-color: @tooltip-bg;
}
&[x-placement="top"] .@{tooltip-arrow} {
left: 50%;
margin-left: -@tooltip-arrow-width;
}
&[x-placement="top-start"] .@{tooltip-arrow} {
left: 16px;
}
&[x-placement="top-end"] .@{tooltip-arrow} {
right: 16px;
}
&[x-placement^="right"] .@{tooltip-arrow} {
left: @tooltip-distance - @tooltip-arrow-width;
border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;
border-right-color: @tooltip-bg;
}
&[x-placement="right"] .@{tooltip-arrow} {
top: 50%;
margin-top: -@tooltip-arrow-width;
}
&[x-placement="right-start"] .@{tooltip-arrow} {
top: 8px;
}
&[x-placement="right-end"] .@{tooltip-arrow} {
bottom: 8px;
}
&[x-placement^="left"] .@{tooltip-arrow} {
right: @tooltip-distance - @tooltip-arrow-width;
border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;
border-left-color: @tooltip-bg;
}
&[x-placement="left"] .@{tooltip-arrow} {
top: 50%;
margin-top: -@tooltip-arrow-width;
}
&[x-placement="left-start"] .@{tooltip-arrow} {
top: 8px;
}
&[x-placement="left-end"] .@{tooltip-arrow} {
bottom: 8px;
}
&[x-placement^="bottom"] .@{tooltip-arrow} {
top: @tooltip-distance - @tooltip-arrow-width;
border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
border-bottom-color: @tooltip-bg;
}
&[x-placement="bottom"] .@{tooltip-arrow} {
left: 50%;
margin-left: -@tooltip-arrow-width;
}
&[x-placement="bottom-start"] .@{tooltip-arrow} {
left: 16px;
}
&[x-placement="bottom-end"] .@{tooltip-arrow} {
right: 16px;
}
.popper(@tooltip-arrow, @tooltip-arrow-width, @tooltip-distance, @tooltip-bg);
}
&-inner{

View file

@ -13,4 +13,5 @@
@import "input";
@import "breadcrumb";
@import "mask";
@import "content"; // card、modal
@import "content"; // card、modal
@import "tooltip";

View file

@ -0,0 +1,85 @@
.popper(@arrow, @arrow-width, @arrow-distance, @bg){
display: block;
visibility: visible;
font-size: @font-size-small;
line-height: @line-height-base;
position: absolute;
z-index: @zindex-tooltip;
&[x-placement^="top"] {
padding: @arrow-width 0 @arrow-distance 0;
}
&[x-placement^="right"] {
padding: 0 @arrow-width 0 @arrow-distance;
}
&[x-placement^="bottom"] {
padding: @arrow-distance 0 @arrow-width 0;
}
&[x-placement^="left"] {
padding: 0 @arrow-distance 0 @arrow-width;
}
&[x-placement^="top"] .@{arrow} {
bottom: @arrow-distance - @arrow-width;
border-width: @arrow-width @arrow-width 0;
border-top-color: @bg;
}
&[x-placement="top"] .@{arrow} {
left: 50%;
margin-left: -@arrow-width;
}
&[x-placement="top-start"] .@{arrow} {
left: 16px;
}
&[x-placement="top-end"] .@{arrow} {
right: 16px;
}
&[x-placement^="right"] .@{arrow} {
left: @arrow-distance - @arrow-width;
border-width: @arrow-width @arrow-width @arrow-width 0;
border-right-color: @bg;
}
&[x-placement="right"] .@{arrow} {
top: 50%;
margin-top: -@arrow-width;
}
&[x-placement="right-start"] .@{arrow} {
top: 8px;
}
&[x-placement="right-end"] .@{arrow} {
bottom: 8px;
}
&[x-placement^="left"] .@{arrow} {
right: @arrow-distance - @arrow-width;
border-width: @arrow-width 0 @arrow-width @arrow-width;
border-left-color: @bg;
}
&[x-placement="left"] .@{arrow} {
top: 50%;
margin-top: -@arrow-width;
}
&[x-placement="left-start"] .@{arrow} {
top: 8px;
}
&[x-placement="left-end"] .@{arrow} {
bottom: 8px;
}
&[x-placement^="bottom"] .@{arrow} {
top: @arrow-distance - @arrow-width;
border-width: 0 @arrow-width @arrow-width;
border-bottom-color: @bg;
}
&[x-placement="bottom"] .@{arrow} {
left: 50%;
margin-left: -@arrow-width;
}
&[x-placement="bottom-start"] .@{arrow} {
left: 16px;
}
&[x-placement="bottom-end"] .@{arrow} {
right: 16px;
}
}