Skip to content

Commit

Permalink
ADD: implement Tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
HopeLyn committed Nov 1, 2016
1 parent 4f9640e commit 91bf4f7
Show file tree
Hide file tree
Showing 10 changed files with 1,554 additions and 2 deletions.
131 changes: 131 additions & 0 deletions site/docs/zh-CN/tooltip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
## Tooltip 文字提示

常用于展示鼠标 hover 时的提示信息。

### 基础用法

在这里我们提供 9 种不同方向的展示方式,可以通过以下完整示例来理解,选择你要的效果。

:::demo 使用`content`属性来决定`hover`时的提示信息。由`placement`属性决定展示效果:`placement`属性值为:`方向-对齐位置`;四个方向:`top``left``right``bottom`;三种对齐位置:`start`, `end`,默认为空。如`placement="left-end"`,则提示信息出现在目标元素的左侧,且提示信息的底部与目标元素的底部对齐。

```html

<div className="box">
<div className="top">
<Tooltip className="item" effect="dark" content="Top Left 提示文字" placement="top-start">
<Button>上左</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Top Center 提示文字" placement="top">
<Button>上边</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Top Right 提示文字" placement="top-end">
<Button>上右</Button>
</Tooltip>
</div>
<div className="left">
<Tooltip className="item" effect="dark" content="Left Top 提示文字" placement="left-start">
<Button>左上</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Left Center 提示文字" placement="left">
<Button>左边</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Left Bottom 提示文字" placement="left-end">
<Button>左下</Button>
</Tooltip>
</div>

<div className="right">
<Tooltip className="item" effect="dark" content="Right Top 提示文字" placement="right-start">
<Button>右上</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Right Center 提示文字" placement="right">
<Button>右边</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Right Bottom 提示文字" placement="right-end">
<Button>右下</Button>
</Tooltip>
</div>
<div className="bottom">
<Tooltip className="item" effect="dark" content="Bottom Left 提示文字" placement="bottom-start">
<Button>下左</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Bottom Center 提示文字" placement="bottom">
<Button>下边</Button>
</Tooltip>
<Tooltip className="item" effect="dark" content="Bottom Right 提示文字" placement="bottom-end">
<Button>下右</Button>
</Tooltip>
</div>
</div>
```
:::

### 主题

Tooltip 组件提供了两个不同的主题:`dark``light`


:::demo 通过设置`effect`属性来改变主题,默认为`dark`
```html
<div>
<Tooltip content="Top center" placement="top">
<Button>Dark</Button>
</Tooltip>
<Tooltip content="Bottom center" placement="bottom" effect="light">
<Button>Light</Button>
</Tooltip>
</div>
```
:::

### 更多 Content

展示多行文本或者是设置文本内容的格式

:::demo 用具名 slot 分发`content`,替代`tooltip`中的`content`属性。
```html
<Tooltip
placement="top"
content={
<div>多行信息<br/>第二行信息</div>
}
>
<Button>Top center</Button>
</Tooltip>
```
:::

### 高级扩展

除了这些基本设置外,还有一些属性可以让使用者更好的定制自己的效果:

`transition`属性可以定制显隐的动画效果,默认为`fade-in-linear`

如果需要关闭`tooltip`功能,`disabled`属性可以满足这个需求,它接受一个`Boolean`,设置为`true`即可。

事实上,这是基于 [Vue-popper](https://github.com/element-component/vue-popper) 的扩展,你可以自定义任意 Vue-popper 中允许定义的字段。

当然,Tooltip 组件实际上十分强大,文末的API文档会做一一说明。

:::demo 通过 state 中的 disabled 控制是否触发 tooltip
```html
<Tooltip disabled={ this.state.disabled } content="点击关闭 tooltip 功能" placement="bottom" effect="light">
<Button onClick={ e => this.setState({ disabled: true}) }>点击关闭 tooltip 功能</Button>
</Tooltip>
```
:::

### Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|--------------------|----------------------------------------------------------|-------------------|-------------|--------|
| effect | 默认提供的主题 | String | `dark`, `light` | dark |
| content | 显示的内容,也可以通过 `slot#content` 传入 DOM | String |||
| placement | Tooltip 的出现位置 | String | `top`, `top-start`, `top-end`, `bottom`, `bottom-start`, `bottom-end`, `left`, `left-start`, `left-end`, `right`, `right-start`, `right-end` | bottom |
| value(v-model) | 状态是否可见 | Boolean || false |
| disabled | Tooltip 是否可用 | Boolean || false |
| offset | 出现位置的偏移量 | Number || 0 |
| transition | 定义渐变动画 | String || `fade-in-linear` |
| visible-arrow | 是否显示 Tooltip 箭头,更多参数可见[Vue-popper](https://github.com/element-component/vue-popper) | Boolean || true |
| options | [popper.js](https://popper.js.org/documentation.html) 的参数 | Object | 参考 [popper.js](https://popper.js.org/documentation.html) 文档 | `{ boundariesElement: 'body', gpuAcceleration: false }` |
| openDelay | 延迟出现,单位毫秒 | Number || 0 |
| manual | 手动控制模式,设置为 true 后,mouseenter 和 mouseleave 事件将不会生效 | Boolean | true,false| false |
2 changes: 2 additions & 0 deletions site/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Dialog from './dialog';
import Progress from './progress';
import Badge from './badge';
import Tree from './tree';
import Tooltip from './tooltip';
import Input from './input';
import Icon from './icon';
import Menu from './menu';
Expand Down Expand Up @@ -59,6 +60,7 @@ const pages = {
},
'Others': {
dialog: { title: 'Dialog 对话框', component: Dialog },
tooltip: { title: 'Tooltip 文字提示', component: Tooltip },
card: { title: 'Card 卡片', component: Card }
}
};
Expand Down
19 changes: 19 additions & 0 deletions site/pages/tooltip/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import './style.scss';

import React from 'react';
import { Component, Markdown } from '../../../libs';
import template from '../../docs/zh-CN/tooltip.md';

export default class Playground extends Component {
constructor(props){
super(props);

this.state = {
disabled: false
}
}

render() {
return <Markdown context={this} component="Tooltip">{template}</Markdown>
}
}
31 changes: 31 additions & 0 deletions site/pages/tooltip/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.box {
width: 400px;

.top {
text-align: center;
}

.left {
float: left;
width: 60px;
}

.right {
float: right;
width: 60px;
}

.bottom {
clear: both;
text-align: center;
}

.item {
margin: 4px;
}

.left .el-tooltip__popper,
.right .el-tooltip__popper {
padding: 8px 10px;
}
}
2 changes: 0 additions & 2 deletions src/dialog/Dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ export default class Dialog extends Component {
}

onKeyDown(e) {
console.log('keydown');
console.log(e);
if (this.props.closeOnPressEscape && e.keyCode === KeyCode.ESC) {
this.close(e);
}
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export { default as Icon } from './icon';
export { default as Menu } from './menu';
export { default as Steps } from './steps';
export { default as Breadcrumb } from './breadcrumb';
export { default as Tooltip } from './tooltip';
Empty file added src/tooltip/Popper.jsx
Empty file.
115 changes: 115 additions & 0 deletions src/tooltip/Tooltip.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import classnames from 'classnames';
import { Component, View } from '../../libs';
import PopperJS from './utils/popper';

export default class Tooltip extends Component {
constructor(props) {
super(props);

this.state = {
showPopper: false
}
}

componentDidUpdate() {
const popper = this.refs.popper;
if (popper) popper.setAttribute('x-placement', this.props.placement);

const arrow = this.refs.arrow;
if (arrow) arrow.setAttribute('x-arrow', "");

const { placement } = this.props;
if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(placement)) {
return;
}

if (popper) {
const reference = this.refs.reference;
const options = { placement };

popper.setAttribute('x-placement', placement);
this.popperJS = new PopperJS(reference, popper, options);
}
}

handleShowPopper() {
if (this.props.manual) return ;

this.setState({
timeout: setTimeout(() => {
this.setState({ showPopper: true })
}, this.props.openDelay)
});
}

handleClosePopper() {
if (this.props.manual) return ;

clearTimeout(this.state.timeout);
this.setState({ showPopper: false});
}

render() {
const { showPopper } = this.state;
const { effect, content, disabled, transition, visibleArrow } = this.props;

return (
<div
className="el-tooltip"
onMouseEnter={ e => this.handleShowPopper(e) }
onMouseLeave={ e => this.handleClosePopper(e) }
>
<div className="el-tooltip__rel" ref="reference">
<div>{ this.props.children }</div>
</div>

<View
show={ !disabled && showPopper }
transition={ transition }
transitionKey={ `tooltip-${transition}`}
>
<div ref="popper" className={ classnames("el-tooltip__popper", `is-${effect}`) }>
<div>{ content }</div>
{ visibleArrow ? <div ref="arrow" className="popper__arrow"></div> : null }
</div>
</View>
</div>
)
}
}

Tooltip.propTypes = {
// 默认提供的主题: dark, light
effect: PropTypes.string,
// 显示的内容,也可以通过 slot#content 传入 DOM
content: PropTypes.node,
// Tooltip 的出现位置 [top, top-start, top-end, bottom, bottom-start, bottom-end, left, left-start, left-end, right, right-start, right-end]
placement: PropTypes.string,
// 状态是否可用
disabled: PropTypes.bool,
// 渐变动画定义
transition: PropTypes.string,
// 是否显示 Tooltip 箭头
visibleArrow: PropTypes.bool,
// 延迟出现(单位: 毫秒)
openDelay: PropTypes.number,
// 手动控制模式,设置为 true 后,mouseenter 和 mouseleave 事件将不会生效
manual: PropTypes.bool,

// TODO: 作用什么是什么?
value: PropTypes.bool
};

Tooltip.defaultProps = {
effect: "dark",
// placement: "bottom",
placement: "top",
visible: false,
disabled: false,
transition: "fade-in-linear",
visibleArrow: true,
openDelay: 0,
manual: false
};
3 changes: 3 additions & 0 deletions src/tooltip/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Tooltip from './Tooltip';

export default Tooltip;
Loading

0 comments on commit 91bf4f7

Please sign in to comment.