mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-06 16:06:28 +08:00
merge from 0.8.0
This commit is contained in:
commit
e067bcd7a5
@ -4,7 +4,11 @@
|
||||
|
||||
设计文档和组件实现均在紧密整理和开发中,部分页面可能不完善,预计 8 月份释出正式版本。
|
||||
|
||||

|
||||
<p align="center">
|
||||
<a href="http://ant.design">
|
||||
<img width="360" src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## 特性
|
||||
|
||||
|
14
components/alert/demo/basic.md
Normal file
14
components/alert/demo/basic.md
Normal file
@ -0,0 +1,14 @@
|
||||
# 基本
|
||||
|
||||
- order: 0
|
||||
|
||||
最简单的用法,适用于简短的警告提示。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Alert = require('antd/lib/alert');
|
||||
|
||||
React.render(<Alert message="警告提示的文案" type="success" />
|
||||
, document.getElementById('components-alert-demo-basic'));
|
||||
````
|
28
components/alert/demo/closable.md
Normal file
28
components/alert/demo/closable.md
Normal file
@ -0,0 +1,28 @@
|
||||
# 可关闭的警告提示
|
||||
|
||||
- order: 1
|
||||
|
||||
显示关闭按钮,点击可关闭警告提示。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Alert = require('antd/lib/alert');
|
||||
|
||||
var onClose = function(e) {
|
||||
console.log(e, '我要被关闭啦!');
|
||||
};
|
||||
|
||||
React.render(<div>
|
||||
<Alert message="警告提示的文案"
|
||||
type="warn"
|
||||
closable
|
||||
onClose={onClose} />
|
||||
<Alert message="警告提示的标题"
|
||||
description="警告提示的文案警告提示的文案警告提示的文案警告提示的文案警告提示的文案警告提示的文案警告提示的文案"
|
||||
type="error"
|
||||
closable
|
||||
onClose={onClose} />
|
||||
</div>, document.getElementById('components-alert-demo-closable'));
|
||||
````
|
||||
|
16
components/alert/demo/close-type.md
Normal file
16
components/alert/demo/close-type.md
Normal file
@ -0,0 +1,16 @@
|
||||
# 自定义关闭
|
||||
|
||||
- order: 4
|
||||
|
||||
可以自定义关闭,自定义的文字会替换原先的关闭 `Icon`。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Alert = require('antd/lib/alert');
|
||||
var link = <a href="javascript:;">不再提醒</a>
|
||||
|
||||
React.render(
|
||||
<Alert message="警告提示的文案" type="info" closeText={link} />
|
||||
, document.getElementById('components-alert-demo-close-type'));
|
||||
````
|
28
components/alert/demo/description.md
Normal file
28
components/alert/demo/description.md
Normal file
@ -0,0 +1,28 @@
|
||||
# 含有辅助性文字介绍
|
||||
|
||||
- order: 2
|
||||
|
||||
含有辅助性文字介绍的警告提示。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Alert = require('antd/lib/alert');
|
||||
|
||||
React.render(<div>
|
||||
<Alert message="警告提示的文案"
|
||||
description="警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍"
|
||||
type="success" />
|
||||
<Alert message="警告提示的文案"
|
||||
description="警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍"
|
||||
type="info" />
|
||||
<Alert
|
||||
message="警告提示的文案"
|
||||
description="警告提示的辅助性文字介绍"
|
||||
type="warn" />
|
||||
<Alert
|
||||
message="警告提示的文案"
|
||||
description="警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍警告提示的辅助性文字介绍"
|
||||
type="error" />
|
||||
</div>, document.getElementById('components-alert-demo-description'));
|
||||
````
|
19
components/alert/demo/style.md
Normal file
19
components/alert/demo/style.md
Normal file
@ -0,0 +1,19 @@
|
||||
# 四种样式
|
||||
|
||||
- order: 3
|
||||
|
||||
共有四种样式`success`、`info`、`warn`、`error`。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var Alert = require('antd/lib/alert');
|
||||
|
||||
React.render(<div>
|
||||
<Alert message="警告提示的文案" type="success" />
|
||||
<Alert message="警告提示的文案警告提示的文案" type="info" />
|
||||
<Alert message="警告提示的文案" type="warn" />
|
||||
<Alert message="警告提示的文案警告提示的文案" type="error" />
|
||||
</div>,
|
||||
document.getElementById('components-alert-demo-style'));
|
||||
````
|
76
components/alert/index.jsx
Normal file
76
components/alert/index.jsx
Normal file
@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
|
||||
export default React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
prefixCls: 'ant-alert'
|
||||
};
|
||||
},
|
||||
getInitialState() {
|
||||
return {
|
||||
display: 'block'
|
||||
};
|
||||
},
|
||||
handleClose(e) {
|
||||
if (this.props.onClose) {
|
||||
this.props.onClose.call(this, e);
|
||||
}
|
||||
this.setState({
|
||||
display: 'none'
|
||||
});
|
||||
},
|
||||
render () {
|
||||
var iconClass = this.props.description ?
|
||||
'ant-alert-with-description-icon anticon-' : 'ant-alert-icon anticon-';
|
||||
switch (this.props.type) {
|
||||
case 'success':
|
||||
iconClass += 'check-circle';
|
||||
break;
|
||||
case 'info':
|
||||
iconClass += 'question-circle';
|
||||
break;
|
||||
case 'error':
|
||||
case 'warn':
|
||||
iconClass += 'info-circle';
|
||||
break;
|
||||
default:
|
||||
iconClass += 'default';
|
||||
}
|
||||
if (this.props.description) {
|
||||
let close = this.props.closable ?
|
||||
<a onClick={this.handleClose} className={'ant-alert-with-description-close-icon'}><span
|
||||
className='ant-alert-with-description-close-icon-x'></span></a> : '';
|
||||
return (
|
||||
<div style={{display: this.state.display}}
|
||||
className={'ant-alert-with-description ant-alert-with-description-' + this.props.type}>
|
||||
<i className={'anticon ' + iconClass}></i>
|
||||
<p className={'ant-alert-with-description-message'}>{this.props.message}</p>
|
||||
<span className={'ant-alert-with-description-description'}>{this.props.description}</span>
|
||||
{close}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
if (this.props.closeText) {
|
||||
return (
|
||||
<div style={{display: this.state.display}} className={'ant-alert ant-alert-' + this.props.type}>
|
||||
<i className={'anticon ' + iconClass}></i>
|
||||
<span className={'ant-alert-description'}>{this.props.message}</span>
|
||||
<span onClick={this.handleClose} className={'ant-alert-close-text'}>{this.props.closeText}</span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
let close = this.props.closable ?
|
||||
<a onClick={this.handleClose} className={'ant-alert-close-icon'}>
|
||||
<span className='ant-alert-close-icon-x'></span>
|
||||
</a> : '';
|
||||
return (
|
||||
<div style={{display: this.state.display}} className={'ant-alert ant-alert-' + this.props.type}>
|
||||
<i className={'anticon ' + iconClass}></i>
|
||||
<span className={'ant-alert-description'}>{this.props.message}</span>
|
||||
{close}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
@ -1,6 +1,24 @@
|
||||
# Alert
|
||||
|
||||
- category: CSS
|
||||
- chinese: 通知栏
|
||||
- category: Components
|
||||
- chinese: 警告提示
|
||||
|
||||
---
|
||||
|
||||
警告提示,展现需要关注的信息。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 当系统需要向用户显示警告的信息时。
|
||||
- 始终展现,不会自动消失,用户可以点击关闭。
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------- |--------------------------------------------------------- | ---------- |-------|
|
||||
| type | 必选参数,指定警告提示的样式,有四种选择`success`、`info`、`warn`、`error` | String | 无 |
|
||||
| closable | 可选参数,值为字符串`true`时显示关闭按钮,默认不显示 | String | 无 |
|
||||
| closeText | 可选参数,自定义关闭 | String | 无 |
|
||||
| message | 必选参数,警告提示内容 | String | 无 |
|
||||
| description | 可选参数,警告提示的辅助性文字介绍 | String | 无 |
|
||||
| onClose | 可选参数,关闭时触发的回调函数 | Function | 无 |
|
||||
|
@ -2,16 +2,51 @@
|
||||
|
||||
- order: 7
|
||||
|
||||
点击后进入加载状态。
|
||||
加载按钮。最后一个按钮演示点击后进入加载状态。
|
||||
|
||||
---
|
||||
|
||||
````html
|
||||
<button class="ant-btn ant-btn-primary ant-btn-circle">
|
||||
<span class="anticon anticon-loading"></span>
|
||||
</button>
|
||||
<button class="ant-btn ant-btn-primary">
|
||||
<span>加载按钮</span>
|
||||
<span class="anticon anticon-loading"></span>
|
||||
</button>
|
||||
````jsx
|
||||
var App = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
enterLoading() {
|
||||
this.setState({
|
||||
loading: true
|
||||
});
|
||||
},
|
||||
render() {
|
||||
var loadingClass = this.state.loading ? 'ant-btn-loading' : '';
|
||||
return <div>
|
||||
<button className="ant-btn ant-btn-primary ant-btn-circle">
|
||||
<i className="anticon anticon-loading"></i>
|
||||
</button>
|
||||
<button className="ant-btn ant-btn-primary ant-btn-lg ant-btn-loading">
|
||||
加载中
|
||||
</button>
|
||||
<button className="ant-btn ant-btn-primary ant-btn-loading">
|
||||
加载中
|
||||
</button>
|
||||
<button className="ant-btn ant-btn-primary ant-btn-sm ant-btn-loading">
|
||||
加载中
|
||||
</button>
|
||||
<br />
|
||||
<button className={'ant-btn ant-btn-primary ' + loadingClass} onClick={this.enterLoading}>
|
||||
点击变加载
|
||||
</button>
|
||||
</div>;
|
||||
}
|
||||
});
|
||||
|
||||
React.render(<App />, document.getElementById('components-button-demo-loading'));
|
||||
````
|
||||
|
||||
<style>
|
||||
#components-button-demo-loading .ant-btn {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Button
|
||||
|
||||
- category: CSS
|
||||
- category: Components
|
||||
- chinese: 按钮
|
||||
- order: 2
|
||||
- order: 0
|
||||
|
||||
---
|
||||
|
||||
|
69
components/enter-animation/demo/basic.md
Normal file
69
components/enter-animation/demo/basic.md
Normal file
@ -0,0 +1,69 @@
|
||||
# 默认
|
||||
|
||||
- order: 0
|
||||
|
||||
默认子节点进场动画。为避免与本站页面的进场冲突,所以 `EnterAnimation` 里延时 1 秒,递增 `interval` 为 0.3。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var EnterAnimation = antd.EnterAnimation;
|
||||
|
||||
var Test = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<EnterAnimation delay={1} interval={0.3}>
|
||||
<div className="demo-header" enter-data>
|
||||
<div className="logo">
|
||||
<img width="30" src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg" />
|
||||
<span>logo</span>
|
||||
</div>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="demo-content" enter-data>
|
||||
<div className="demo-title">我是标题</div>
|
||||
<div className="demo-kp">
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="demo-title">我是标题</div>
|
||||
<div className="demo-listBox">
|
||||
<div className="demo-list">
|
||||
<div className="title"></div>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="demo-footer" enter-data></div>
|
||||
</EnterAnimation>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
React.render(<Test />
|
||||
, document.getElementById('components-enter-animation-demo-basic'));
|
||||
````
|
||||
|
||||
<style>
|
||||
#components-enter-animation-demo-basic {
|
||||
width: 600px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
margin: 20px auto;
|
||||
}
|
||||
</style>
|
69
components/enter-animation/demo/enter-data.md
Normal file
69
components/enter-animation/demo/enter-data.md
Normal file
@ -0,0 +1,69 @@
|
||||
# 指定节点动画进场
|
||||
|
||||
- order: 1
|
||||
|
||||
通过加上 `enter-data` 属性来指定需要动画进场的元素,并且可以定义每个元素的动画效果,用到的参数有 `type` `queueId` `delay`。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
var EnterAnimation = antd.EnterAnimation;
|
||||
|
||||
var Test = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<EnterAnimation delay={1} interval={0.2}>
|
||||
<div className="demo-header" enter-data={{type: 'alpha'}}>
|
||||
<div className="logo" enter-data={{type: 'left'}}>
|
||||
<img width="30" src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg"/>
|
||||
<span>logo</span>
|
||||
</div>
|
||||
<ul>
|
||||
<li enter-data></li>
|
||||
<li enter-data></li>
|
||||
<li enter-data></li>
|
||||
<li enter-data></li>
|
||||
<li enter-data></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="demo-content">
|
||||
<div className="demo-title" enter-data={{type:'alpha'}}>我是标题</div>
|
||||
<div className="demo-kp">
|
||||
<ul>
|
||||
<li enter-data></li>
|
||||
<li enter-data></li>
|
||||
<li enter-data></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="demo-title" enter-data={{type:'alpha',queueId:1,delay:1.6}}>我是标题</div>
|
||||
<div className="demo-listBox">
|
||||
<div className="demo-list">
|
||||
<div className="title" enter-data={{type:'bottom',queueId:1}}></div>
|
||||
<ul>
|
||||
<li enter-data={{type:'bottom',queueId:1}}></li>
|
||||
<li enter-data={{type:'bottom',queueId:1}}></li>
|
||||
<li enter-data={{type:'bottom',queueId:1}}></li>
|
||||
<li enter-data={{type:'bottom',queueId:1}}></li>
|
||||
<li enter-data={{type:'bottom',queueId:1}}></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="demo-footer" enter-data={{type:'bottom',queueId:1}}></div>
|
||||
</EnterAnimation>
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
React.render(<Test />
|
||||
, document.getElementById('components-enter-animation-demo-enter-data'));
|
||||
````
|
||||
|
||||
<style>
|
||||
#components-enter-animation-demo-enter-data {
|
||||
width: 600px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
margin: 20px auto;
|
||||
}
|
||||
</style>
|
9
components/enter-animation/index.jsx
Normal file
9
components/enter-animation/index.jsx
Normal file
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import EnterAnimation from 'enter-animation';
|
||||
|
||||
export default class AntEnterAnimation extends React.Component {
|
||||
render() {
|
||||
return <EnterAnimation {...this.props} />;
|
||||
}
|
||||
}
|
||||
AntEnterAnimation.to = EnterAnimation.to;
|
234
components/enter-animation/index.md
Normal file
234
components/enter-animation/index.md
Normal file
@ -0,0 +1,234 @@
|
||||
# EnterAnimation
|
||||
|
||||
- order: 11
|
||||
- category: Components
|
||||
- chinese: 进场动画
|
||||
- cols: 1
|
||||
|
||||
---
|
||||
|
||||
通过简单的配置对一组元素添加串行的进场动画效果。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 从内容A到内容B的转变过程时能有效的吸引用户注意力,突出视觉中心,提高整体视觉效果。
|
||||
|
||||
- 小的信息元素排布或块状较多的情况下,根据一定的路径层次依次进场,区分维度层级,来凸显量级,使页面转场更加流畅和舒适,提高整体视觉效果和产品的质感。
|
||||
|
||||
|
||||
## 如何使用
|
||||
|
||||
一级子元素依次进场。
|
||||
|
||||
```jsx
|
||||
<EnterAnimation>
|
||||
<div>依次进场</div>
|
||||
<div>依次进场</div>
|
||||
<div>依次进场</div>
|
||||
<div>依次进场</div>
|
||||
</EnterAnimation>
|
||||
```
|
||||
|
||||
如子节点有 `enter-data` 值,则只执行有 `enter-data` 的节点的动画,相反所有子节点上都没有 `enter-data` 值,则执行遍历dom下一级节点来执行动画。
|
||||
|
||||
```jsx
|
||||
<EnterAnimation type="left" delay={2}>
|
||||
<div>
|
||||
<div enter-data>
|
||||
依次进场
|
||||
</div>
|
||||
</div>
|
||||
<div enter-data>依次进场</div>
|
||||
<div enter-data={{type: 'bottom'}}>依次进场,并修改动画效果</div>
|
||||
<div enter-data={{style: 'margin-top:100px'}}>依次进场,并使用样式修改动画效果</div>
|
||||
<div>没有动画</div>
|
||||
</EnterAnimation>
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### <EnterAnimation />
|
||||
|
||||
|参数 |类型 |默认值 |详细 |
|
||||
|-----------------|-------|-------------|----------------------------------------------------|
|
||||
|type |string |`right` |执行动画的内置参数 |
|
||||
|style |string |null |同上, style 的样式动画, `type` 有值,此项无效|
|
||||
|delay |number |0 |整个区块的延时,以秒为单位|
|
||||
|interval |number |0.1 |递增延时值,以秒为单位|
|
||||
|
||||
### enter-data
|
||||
|
||||
|参数 |类型 |默认值 |详细 |
|
||||
|-----------------|-------|-----------|----------------------------------------------------|
|
||||
|enter-data |object | `right` |子标签动画参数|
|
||||
|
||||
#### enter-data={}
|
||||
|
||||
|参数 |类型 |默认值 |详细 |
|
||||
|-----------------|-----------------|----------------|----------------------------------------------------|
|
||||
|type |string |`right` |内置动画样式:<br/> `alpha` `left` `right` `top` `bottom` `scale` `scaleBig` `scaleX` `scaleY`|
|
||||
|style |string |null |动画样式,如 `transform: translateX(100px)`,`type` 有值此项无效|
|
||||
|direction |string |`enter` |动画进出场方向:`enter` `leave`|
|
||||
|duration |number |0.5 |动画的时间,以秒为单位|
|
||||
|ease |string |`cubic-bezier(0.165, 0.84, 0.44, 1)`|样式缓动,只支持 css 样式缓动|
|
||||
|delay |number |0 |动画的延时,依照结构递增以上的 `interval`|
|
||||
|queueId |number |0 |动画的线程|
|
||||
|
||||
> 由于使用了 CSS3 动画,所以 `IE9` 及更早的版本将没有进场效果。
|
||||
|
||||
<style>
|
||||
.code-box-demo .demo-header {
|
||||
width: 100%;
|
||||
background: #ebedee;
|
||||
height: 30px;
|
||||
}
|
||||
.code-box-demo .demo-header ul {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.code-box-demo .demo-header ul li {
|
||||
width: 50px;
|
||||
height: 30px;
|
||||
float: left;
|
||||
background: #e4e4e4;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.code-box-demo .demo-header ul li:before {
|
||||
margin: 10px auto;
|
||||
width: 20px;
|
||||
height: 10px;
|
||||
background: #ebeded;
|
||||
}
|
||||
.code-box-demo .demo-header .logo {
|
||||
float: left;
|
||||
margin: 0px auto 0 10px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.code-box-demo .demo-header .logo img{
|
||||
margin:auto
|
||||
}
|
||||
.code-box-demo .demo-header .logo span {
|
||||
display: block;
|
||||
float: right;
|
||||
}
|
||||
.code-box-demo .demo-content {
|
||||
width: 80%;
|
||||
margin: 10px auto;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-title {
|
||||
text-align:left;
|
||||
background: #a4a4a4;
|
||||
width: 40%;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
color: #ebeded;
|
||||
text-indent:10px
|
||||
}
|
||||
.code-box-demo .demo-content .demo-listBox {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list .title {
|
||||
height: 30px;
|
||||
background: #cacaca;
|
||||
overflow: hidden;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list .title:before,.code-box-demo .demo-content .demo-listBox .demo-list .title:after{
|
||||
width: 30%;
|
||||
height: 5px;
|
||||
background: #ebeded;
|
||||
float:left;
|
||||
margin:12px 35px 0;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list .title:after{
|
||||
width:15%;
|
||||
float:right;
|
||||
margin:12px 10px 0;
|
||||
|
||||
}
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list ul li {
|
||||
height: 25px;
|
||||
background: #ebeded;
|
||||
border-bottom: 1px solid #cacaca;
|
||||
overflow: hidden;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list ul li:before {
|
||||
width: 10px;
|
||||
height: 5px;
|
||||
background: #cacaca;
|
||||
float: left;
|
||||
margin-top:4px
|
||||
}
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list ul li:after {
|
||||
width: 50%;
|
||||
height: 5px;
|
||||
background: #cacaca;
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-kp {
|
||||
margin: 10px auto;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-kp ul li {
|
||||
display: inline-block;
|
||||
width: 32%;
|
||||
height: 40px;
|
||||
background: #cacaca;
|
||||
color: #ebeded;
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
margin-right: calc(2%);
|
||||
}
|
||||
.code-box-demo .demo-content .demo-kp ul li:last-child {
|
||||
margin-right: 0%;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-kp ul li:after {
|
||||
width: 60%;
|
||||
height: 5px;
|
||||
background: #ebeded;
|
||||
float: left;
|
||||
margin-top: 7px;
|
||||
}
|
||||
.code-box-demo .demo-content .demo-kp ul li:before {
|
||||
background: #ebeded;
|
||||
float: left;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin:2px 10% 0 0;
|
||||
|
||||
}
|
||||
.code-box-demo .demo-footer {
|
||||
margin-top: 10px;
|
||||
background: #cacaca;
|
||||
height: 40px;
|
||||
float: left;
|
||||
width: 100%;
|
||||
display: table;
|
||||
}
|
||||
.code-box-demo .demo-footer:before {
|
||||
width: 60%;
|
||||
height: 5px;
|
||||
background: #ededed;
|
||||
margin: 10px auto 0;
|
||||
}
|
||||
.code-box-demo .demo-footer:after {
|
||||
width: 30%;
|
||||
height: 5px;
|
||||
background: #ededed;
|
||||
margin: 5px auto;
|
||||
}
|
||||
.code-box-demo .demo-header ul li:before,
|
||||
.code-box-demo .demo-content .demo-kp ul li:before,
|
||||
.code-box-demo .demo-content .demo-kp ul li:after,
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list .title:before,
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list .title:after,
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list ul li:before,
|
||||
.code-box-demo .demo-content .demo-listBox .demo-list ul li:after,
|
||||
.code-box-demo .demo-footer:before,
|
||||
.code-box-demo .demo-footer:after {
|
||||
display: block;
|
||||
content: "";
|
||||
}
|
||||
</style>
|
@ -1,6 +1,6 @@
|
||||
# Form
|
||||
|
||||
- category: CSS
|
||||
- category: Components
|
||||
- chinese: 表单
|
||||
- order: 3
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Iconfont
|
||||
|
||||
- category: CSS
|
||||
- category: Components
|
||||
- chinese: 字体图标
|
||||
- order: 1
|
||||
- order: 0
|
||||
- nodemos: true
|
||||
|
||||
---
|
||||
|
@ -1 +1 @@
|
||||
<meta http-equiv="refresh" content="0; url=/components/layout" />
|
||||
<meta http-equiv="refresh" content="0; url=/components/button" />
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Layout
|
||||
|
||||
- category: CSS
|
||||
- category: Components
|
||||
- chinese: 布局
|
||||
- order: 0
|
||||
|
||||
|
@ -28,7 +28,7 @@ export default React.createClass({
|
||||
this.setState({
|
||||
confirmLoading: true
|
||||
});
|
||||
if (typeof this.props.onOk) {
|
||||
if (typeof this.props.onOk === 'function') {
|
||||
this.props.onOk();
|
||||
}
|
||||
},
|
||||
|
@ -1,39 +0,0 @@
|
||||
# Motion
|
||||
|
||||
- category: CSS
|
||||
- chinese: 组件动画
|
||||
- order: 4
|
||||
- cols: 1
|
||||
|
||||
---
|
||||
|
||||
## 组件的动画
|
||||
|
||||
通过设置组件的 `transitionName` 指定组件动画。
|
||||
|
||||
| 组件 | 中文名 | 采用动画 |
|
||||
|--------------|---------------------|-------------------------------------------------|
|
||||
| popover | 气泡浮出层 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` |
|
||||
| popconfirm | 气泡确认框 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` |
|
||||
| tooltip | 文字提示框 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` |
|
||||
| modal | 弹出框 | `zoom` |
|
||||
| confirm | 弹出确认框 | `zoom` |
|
||||
| message | 信息提示条 | `move-up` |
|
||||
| dropdown | 下拉菜单 | `slide-up` |
|
||||
| select | 选择框 | `slide-up` |
|
||||
| datepicker | 日期选择框 | `slide-up` |
|
||||
|
||||
## 缓动函数
|
||||
在以上组件的动画不适合时,请用以下缓动。
|
||||
|
||||
|名称 |参数 |说明与适用 |
|
||||
|-------------------|------------------------------------------|---------------------------|
|
||||
|@ease-out | `cubic-bezier(0.215, 0.61, 0.355, 1);` |默认后缓动;适合元素展开时; |
|
||||
|@ease-in | `cubic-bezier(0.55, 0.055, 0.675, 0.19);`|默认前缓动;适合元素关闭时; |
|
||||
|@ease-in-out | `cubic-bezier(0.645, 0.045, 0.355, 1);` |默认前后缓动;适合元素移动; |
|
||||
|@ease-out-back | `cubic-bezier(0.18, 0.89, 0.32, 1.28);` |结束回动;适合弹出框出现时; |
|
||||
|@ease-in-back | `cubic-bezier(0.6, -0.3, 0.74, 0.05);` |开始回动;适合弹出框关闭; |
|
||||
|@ease-in-out-back | `cubic-bezier(0.68, -0.55, 0.27, 1.55);` |前后回动; |
|
||||
|@ease-out-circ | `cubic-bezier(0.08, 0.82, 0.17, 1);` |圆形后缓动;适合元素展开时; |
|
||||
|@ease-in-circ | `cubic-bezier(0.6, 0.04, 0.98, 0.34);` |圆形前缓动;适合元素关闭时; |
|
||||
|@ease-in-out-circ | `cubic-bezier(0.78, 0.14, 0.15, 0.86);` |圆形缓动;适合元素移动; |
|
@ -6,6 +6,8 @@
|
||||
|
||||
---
|
||||
|
||||
单选框。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 用于在多个备选项中选中单个状态。
|
||||
@ -15,21 +17,18 @@
|
||||
## API
|
||||
|
||||
### Radio
|
||||
单选框。
|
||||
|
||||
| 参数 | 说明 | 类型 | 必选值 | 默认值 |
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|----------------|------------------------------------------|------------|---------|--------|
|
||||
| checked | 指定当前是否选中 | boolean | false | false |
|
||||
| defaultChecked | 初始是否选中 | boolean | false | false |
|
||||
| value | 组合时根据此项判定checked | -- |true | null|
|
||||
| checked | 指定当前是否选中 | Boolean | | false |
|
||||
| defaultChecked | 初始是否选中 | Boolean | | false |
|
||||
| value | 根据 value 进行比较,判断是否选中 | String | | 无 |
|
||||
|
||||
### RadioGroup
|
||||
|
||||
单选框组合;
|
||||
|
||||
| 参数 | 说明 | 类型 | 必选值 | 默认值 |
|
||||
|----------------|------------------------------------------|------------|---------|--------|
|
||||
| onChange | 变化时回调函数,组合时必须 | Function(e:Event) | false | null |
|
||||
| value | 当前值 | | | |
|
||||
| defaultValue | 初始值 | | | | |
|
||||
单选框组合,用于包裹一组 `Radio`。
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|----------------|----------------------------------|-------------------|--------|--------|
|
||||
| onChange | 选项变化时的回调函数 | Function(e:Event) | 无 | 无 |
|
||||
| value | 用于设置当前选中的值 | String | 无 | 无 |
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import Select from 'rc-select';
|
||||
|
||||
export default React.createClass({
|
||||
var AntSelect = React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
prefixCls: 'ant-select',
|
||||
@ -16,3 +16,7 @@ export default React.createClass({
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
AntSelect.Option = Select.Option;
|
||||
|
||||
export default AntSelect;
|
||||
|
@ -329,12 +329,17 @@ export default React.createClass({
|
||||
});
|
||||
}
|
||||
// 分页
|
||||
data = data.filter(function(item, i) {
|
||||
if (i >= (current - 1) * pageSize &&
|
||||
i < current * pageSize) {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
// ---
|
||||
// 当数据量少于每页数量时,直接设置数据
|
||||
// 否则进行读取分页数据
|
||||
if (data.length > pageSize || pageSize === Number.MAX_VALUE) {
|
||||
data = data.filter(function(item, i) {
|
||||
if (i >= (current - 1) * pageSize &&
|
||||
i < current * pageSize) {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 完成数据
|
||||
this.setState({
|
||||
data: data
|
||||
|
@ -1,112 +0,0 @@
|
||||
# 自然运动
|
||||
|
||||
- category: 动画
|
||||
- order: 0
|
||||
|
||||
---
|
||||
|
||||
现实物体照着一定节奏移动,并不是一开始就移动很快的。
|
||||
|
||||
当我们打开现代家具的门或抽屉时,首先会让它加速,然后慢下来。
|
||||
|
||||
当电梯开关门时,它在打开或关闭时都有一段缓冲带,是先加速,然后慢下来。
|
||||
|
||||
当某个东西往下掉时,首先是越掉越快,撞到地上后回弹,最终才又碰触地板。
|
||||
|
||||
|
||||
### 质量和重量
|
||||
|
||||
在物理世界里,是以力量附加到物体对象里,加上自身的质量才完成一段动画。力量的持续时间决定物体的加速,减速与改变方向。
|
||||
|
||||
动画停止与启动都不是瞬间完成的,因它需要一段缓冲的时间来加速或减速,因此,当动画有突然启动,停止或改变方向,都会显得很不自然。
|
||||
|
||||
#### 自然缓动
|
||||
不要用直线缓动Linear做物体出入动画的缓动;注:Linear函数可做循环动画函数;
|
||||
|
||||
如下图所示,在没有缓动的情况下启动与停止都显得突兀,感觉动画还没结束就停止了,所以在物体运动中避免直线运动;
|
||||
|
||||
<script src="/static/TweenMax.min.js"></script>
|
||||
<script src="/static/motion.js"></script>
|
||||
<div id="J-Linear">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Linear",{lineData:[{open:[],end:[],stroke:"#f2666c"},{open:[0.455, 0.03, 0.515, 0.955],end:[0.455, 0.03, 0.515, 0.955],stroke:"#71B5DE",openEaseName:"easeInOutQuad",endEaseName:"easeInOutQuad"},],mask:false});
|
||||
})
|
||||
</script>
|
||||
|
||||
上图所示缓动函数:红:Linear 蓝:easeInOutQuad;
|
||||
|
||||
|
||||
|
||||
|
||||
#### 出入动画
|
||||
不要做单向动画,进场后不做出场,直接消失元素或回到原点,会让整个画面不协调,反相只出不进也一样;
|
||||
|
||||
所以有动画的进场必须要有动画的出场,包括导航上的动画;
|
||||
|
||||
<div id="J-Symmetric">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Symmetric",{lineData:[
|
||||
{open:[0.455, 0.03, 0.515, 0.955],end:[],openEaseName:"easeInOutQuad",endEaseName:"null",stroke:"#f2666c"},
|
||||
{open:[0.645, 0.045, 0.355, 1],end:[0.645, 0.045, 0.355, 1],stroke:"#71B5DE",openEaseName:"easeInOutCubic",endEaseName:"easeInOutCubic"}],
|
||||
mask:false,exposure:"top"});
|
||||
})
|
||||
</script>
|
||||
|
||||
上图所示缓动函数:红:easeInOutQuad 蓝:easeInOutCubic;
|
||||
|
||||
|
||||
|
||||
|
||||
##### 场外出入
|
||||
场外出入需要考虑力量与引力的关系,如向空中抛物体时,开始时力量大于引力时,速度是最快的,
|
||||
|
||||
到达一定高度后,随着力量的减少,速度也跟随着降低,物体达到最高点后,力量等于引力或小于引力时,物体随之下降;
|
||||
|
||||
所以在快到达最高点和掉下来时有一定缓冲带;不要做图示红色球体下降时的缓动;
|
||||
|
||||
<div id="J-Entry">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Entry",{lineData:[
|
||||
{open:[0.25, 0.46, 0.45, 0.94],end:[0.25, 0.46, 0.45, 0.94],openEaseName:"easeOutQuad",endEaseName:"easeOutQuad",stroke:"#f2666c"},
|
||||
{open:[0.215, 0.61, 0.355, 1],end:[0.55, 0.055, 0.675, 0.19],stroke:"#71B5DE",openEaseName:"easeOutCubic",endEaseName:"easeInCubic"}],
|
||||
mask:true,exposure:"bottom"});
|
||||
})
|
||||
</script>
|
||||
|
||||
上图所示缓动函数:红:easeOutQuad,easeOutQuad 蓝:easeOutCubic,easeInCubic;
|
||||
|
||||
示例组件:<a href="/components/message/">Message全局提示</a>,<a href="/components/dropdown/">Dropdown下拉菜单</a>
|
||||
|
||||
#### 弹性动画
|
||||
|
||||
1.如蹦极跳下来时,刚跳下时速度很快,到达绳子的长度后,由于物体的重量再将绳子拉长再反弹,弹动几次后才停下。
|
||||
|
||||
动画里也由质量来决定它的反弹,一般元素最好只弹动一次就够了,收回时可以用向下浮动再上拉或直接前缓动,可适用在下拉框与弹出元素;
|
||||
|
||||
2.如球类物体掉地上的后,反弹几次后停止;
|
||||
|
||||
注:
|
||||
1.曲线图用的是3次贝塞尔曲线,没法表示Bounce,所以用line替换;
|
||||
2.弹性动画最好结合alpha;
|
||||
<div id="J-Back">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Back",{lineData:[
|
||||
{open:[],end:[0.455, 0.03, 0.515, 0.955],openEaseName:"easeOutBounce",endEaseName:"easeInOutQuad",stroke:"#70f266"},
|
||||
{open:[0.175, 0.885, 0.32, 1.275],end:[0.6, -0.28, 0.735, 0.045],stroke:"#71B5DE",openEaseName:"easeOutBack",endEaseName:"easeInBack"}],
|
||||
mask:false,exposure:"top"});
|
||||
})
|
||||
</script>
|
||||
|
||||
上图所示缓动函数:红:easeOutBounce,easeInOutQuad 蓝:easeOutBack,easeInBack;
|
@ -1,63 +0,0 @@
|
||||
# 页面转换
|
||||
|
||||
- category: 动画
|
||||
- chinese: 页面转换
|
||||
- order: 2
|
||||
|
||||
---
|
||||
|
||||
###单页面转场动画
|
||||
|
||||
从内容A到内容B的转变过程时能有效的吸引用户注意力,突出视觉中心,提高整体视觉效果。
|
||||
|
||||
####视觉连贯性
|
||||
|
||||
####三类元素(Adding ,Receding,Normal)
|
||||
|
||||
Adding: 新加入的信息元素应被告知如何使用,从页面转变的信息元素需被重新识别。
|
||||
|
||||
Receding: 与当前页无关的信息元素应采用适当方式移除
|
||||
|
||||
Normal: 指那些从转场开始到结束都没有发生变化的信息元素
|
||||
|
||||
|
||||
|
||||
#### 转场动画
|
||||
|
||||
大页面转场可采用左出右入的形式
|
||||
|
||||
小的信息元素排布或块状较多的情况下,最好根据一定的路径层次依次进场,区分维度层级,来凸显量级,间隔时间为动画时间的三分之一;
|
||||
|
||||
如不是单页面,页面动画可以为只右入和间隔性出现;
|
||||
<script src="/static/TweenMax.min.js"></script>
|
||||
<script src="/static/motion.js"></script>
|
||||
|
||||
<div class="video-player">
|
||||
<video preload loop><source src="https://t.alipayobjects.com/images/rmsweb/T1QZ4gXdJeXXXXXXXX.webm" type="video/webm"><source src="https://t.alipayobjects.com/images/rmsweb/T1BIdgXkloXXXXXXXX.mp4" type="video/mp4"></video>
|
||||
</div>
|
||||
|
||||
|
||||
####可折叠面板
|
||||
|
||||
对于信息元素内容区域的延伸,显示信息元素和进一步内容对象之间的直接连接。
|
||||
|
||||
1.被展开的信息区域内容按照一定的路劲依次进场。
|
||||
|
||||
2.信息元素在收起时照收齐点移动,在视觉上跟随关闭物体。
|
||||
|
||||
|
||||
<link rel="stylesheet" href="/static/motionDemo.css">
|
||||
|
||||
<div class="video-player">
|
||||
<video preload loop><source src="https://t.alipayobjects.com/images/rmsweb/T12I8gXexdXXXXXXXX.webm" type="video/webm"><source src="https://t.alipayobjects.com/images/rmsweb/T1e0hgXcpdXXXXXXXX.mp4" type="video/mp4"></video>
|
||||
</div>
|
||||
|
||||
|
||||
####弹出框动效
|
||||
|
||||
|
||||
从一个触发点触发一个弹出框时,弹框从所触发区域弹出,且触发区域视觉上基本保持不变。这样让触发区域和弹出区域有所关联,提高用户对新内容的认知。
|
||||
|
||||
<div class="video-player">
|
||||
<video preload loop><source src="https://t.alipayobjects.com/images/rmsweb/T1br0gXghtXXXXXXXX.webm" type="video/webm"><source src="https://t.alipayobjects.com/images/rmsweb/T1lcRgXb4gXXXXXXXX.mp4" type="video/mp4"></video>
|
||||
</div>
|
@ -1,104 +0,0 @@
|
||||
# 响应交互
|
||||
|
||||
- category: 动画
|
||||
- order: 1
|
||||
|
||||
---
|
||||
|
||||
响应交互一般是指我们在浏览页面时,点击元素时动画给我们视觉上的反馈,每个交互动效都能给我们带来不同视觉效果。
|
||||
|
||||
如搜索框,当你点击准备输入时,icon将会跑到右边方便点击,当然你按回车也是可以提交表单的;在你没有输入文字时,icon又会恢愎到原来的地置,但当你输入了文字后,icon将会停留在右边;
|
||||
|
||||
### 按钮类表面效果
|
||||
|
||||
按钮上的hover或click效果,随着你的鼠标事件而改变自身或增加元素在按钮上;
|
||||
|
||||
以下按钮对组件按钮的修改,只做示例,具体还需看组件;
|
||||
<link rel="stylesheet" href="/static/motionDemo.css">
|
||||
<script src="/static/motionDemo.js"></script>
|
||||
<div style="overflow: hidden;">
|
||||
<div style="width:200px;float:left;margin-right:60px">
|
||||
<p style="text-align: center;"> 1.按钮表面效果;</p>
|
||||
<div class="ant-btn-domebox">
|
||||
<a class="ant-btn ant-btn-primary">我是按钮</a>
|
||||
<a class="ant-btn ant-btn-primary ant-btn-ripple">
|
||||
点击涟漪按钮
|
||||
</a>
|
||||
<a class="ant-btn ant-btn-ripple">
|
||||
点击涟漪按钮
|
||||
</a>
|
||||
<button class="ant-btn ant-btn-ghost ant-btn-circle-outline ant-btn-lg" style="display: block;">
|
||||
<span class="anticon anticon-search"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width:200px;float:left;">
|
||||
<p style="text-align: center;"> 2.无素结合切换;</p>
|
||||
<div class="ant-btn-domebox">
|
||||
<button class="ant-btn ant-btn-primary ant-btn-ripple ant-btn-load ">
|
||||
<text>加载按钮</text>
|
||||
<span class='anticon anticon-loading'></span>
|
||||
</button>
|
||||
<button class="ant-btn ant-btn-primary ant-btn-reload ant-btn-ripple">
|
||||
<span class="anticon anticon-reload"></span>
|
||||
<text>刷新</text>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
### 元素类呈现效果
|
||||
|
||||
元素呈现指点击或滑过展现相关的内容或提示,如下拉菜单或弹出框等;
|
||||
|
||||
注:物体弹出点要从点击点出现,不要做凭空出现;
|
||||
|
||||
|
||||
<div style="overflow: hidden;">
|
||||
|
||||
<div style="width:200px;float:left;margin-right:60px">
|
||||
<p style="text-align: center;"> 1.icon菜单(点放大模式)</p>
|
||||
<div class="ant-btn-domebox" >
|
||||
|
||||
|
||||
<button class="ant-btn ant-btn-ghost ant-btn-circle-outline ant-btn-lg ant-btn-ripple ant-btn-listtip" style="float:right;margin:0" data-id="J-Tip">
|
||||
<span class="anticon anticon-bars"></span>
|
||||
</button>
|
||||
<div class="ant-anim-dometip ant-anim-topArrow scale-origin-iconTopRight" style="display:none;" id="J-Tip">
|
||||
<ul>
|
||||
<li>第一排文字元素</li>
|
||||
<li>第二排文字元素</li>
|
||||
<li>第三排文字元素</li>
|
||||
<li>第四排文字元素</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="width:200px;float:left;">
|
||||
<p style="text-align: center;">2.下拉菜单(下滑模式)</p>
|
||||
<div class="ant-btn-domebox">
|
||||
|
||||
|
||||
<div class="ant-dropdown-wrap">
|
||||
<button class="ant-btn ant-btn-primary ant-btn-menu ant-btn-dropdown ant-btn-ripple">
|
||||
<span>菜单按钮</span>
|
||||
<span class="anticon anticon-down"></span>
|
||||
</button>
|
||||
<div class="ant-dropdown ant-anim-dometip scale-origin-top">
|
||||
<div class="ant-dropdown-con">
|
||||
<ul>
|
||||
<li>第一排文字元素</li>
|
||||
<li>第二排文字元素</li>
|
||||
<li>第三排文字元素</li>
|
||||
<li>第四排文字元素</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
4
index.js
4
index.js
@ -23,8 +23,10 @@ var antd = {
|
||||
Collapse: require('./components/collapse'),
|
||||
message: require('./components/message'),
|
||||
Slider: require('./components/slider'),
|
||||
EnterAnimation: require('./components/enter-animation'),
|
||||
Radio: require('./components/radio'),
|
||||
RadioGroup: require('./components/radio/group')
|
||||
RadioGroup: require('./components/radio/group'),
|
||||
Alert: require('./components/alert')
|
||||
};
|
||||
|
||||
module.exports = antd;
|
||||
|
11
package.json
11
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "0.7.3-beta4",
|
||||
"version": "0.7.3-beta6",
|
||||
"stableVersion": "0.7.2",
|
||||
"title": "Ant Design",
|
||||
"description": "一个设计语言&前端框架",
|
||||
@ -32,6 +32,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"enter-animation": "~0.1.3",
|
||||
"gregorian-calendar": "~3.0.0",
|
||||
"gregorian-calendar-format": "~3.0.1",
|
||||
"object-assign": "~3.0.0",
|
||||
@ -56,12 +57,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer-loader": "~2.0.0",
|
||||
"babel": "~5.6.14",
|
||||
"babel-core": "~5.4.7",
|
||||
"babel-loader": "~5.1.3",
|
||||
"babel": "^5.8.12",
|
||||
"babel-core": "^5.8.12",
|
||||
"babel-loader": "^5.3.2",
|
||||
"css-animation": "~1.0.3",
|
||||
"css-loader": "^0.14.1",
|
||||
"eslint": "~0.22.1",
|
||||
"eslint": "^0.24.1",
|
||||
"eslint-plugin-react": "~2.5.0",
|
||||
"extract-text-webpack-plugin": "^0.8.1",
|
||||
"gh-pages": "~0.3.1",
|
||||
|
@ -95,8 +95,8 @@
|
||||
<li class="{%- if post.directory|rootDirectoryIs('docs') %}current{%- endif %}">
|
||||
<a href="/docs/introduce">使用</a>
|
||||
</li>
|
||||
<li class="{%- if post.directory|rootDirectoryIs('design') %}current{%- endif %}">
|
||||
<a class="disabled" href="/design/">设计</a>
|
||||
<li class="{%- if post.directory|rootDirectoryIs('spec') %}current{%- endif %}">
|
||||
<a href="/spec/font">设计</a>
|
||||
</li>
|
||||
<li class="{%- if post.directory|rootDirectoryIs('components') %}current{%- endif %}">
|
||||
<a href="/components">组件</a>
|
||||
|
@ -58,7 +58,10 @@ module.exports = function(nico) {
|
||||
}
|
||||
})).filter(function(n){ return n != undefined });
|
||||
categories = categories.sort(function(a, b) {
|
||||
return a.length - b.length;
|
||||
var cats = ['文字', '色彩', '动画'];
|
||||
a = cats.indexOf(a);
|
||||
b = cats.indexOf(b);
|
||||
return a - b;
|
||||
})
|
||||
Categories[rootDirectory] = categories;
|
||||
return categories;
|
||||
|
6
spec/color.md
Normal file
6
spec/color.md
Normal file
@ -0,0 +1,6 @@
|
||||
# 色系和交互
|
||||
|
||||
- category: 色彩
|
||||
- order: 0
|
||||
|
||||
---
|
125
spec/easing.md
Normal file
125
spec/easing.md
Normal file
@ -0,0 +1,125 @@
|
||||
# 缓动函数
|
||||
|
||||
- category: 动画
|
||||
- order: 1
|
||||
|
||||
---
|
||||
|
||||
现实物体照着一定节奏移动,并不是一开始就移动很快的。
|
||||
|
||||
当我们打开现代家具的门或抽屉时,首先会让它加速,然后慢下来。
|
||||
|
||||
当电梯开关门时,它在打开或关闭时都有一段缓冲带,是先加速,然后慢下来。
|
||||
|
||||
当某个东西往下掉时,首先是越掉越快,撞到地上后回弹,最终才又碰触地板。
|
||||
|
||||
|
||||
### 质量和重量
|
||||
|
||||
在物理世界里,是以力量附加到物体对象里,加上自身的质量才完成一段动画。力量的持续时间决定物体的加速,减速与改变方向。
|
||||
|
||||
动画停止与启动都不是瞬间完成的,因它需要一段缓冲的时间来加速或减速,因此,当动画有突然启动,停止或改变方向,都会显得很不自然。
|
||||
|
||||
#### 自然缓动
|
||||
|
||||
不要用直线缓动Linear做物体出入动画的缓动;注:Linear函数可做循环动画函数。
|
||||
|
||||
如下图所示,在没有缓动的情况下启动与停止都显得突兀,感觉动画还没结束就停止了,所以在物体运动中避免直线运动。
|
||||
|
||||
<script src="/static/TweenMax.min.js"></script>
|
||||
<script src="/static/motion.js"></script>
|
||||
<div id="J-Linear"></div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Linear",{lineData:[{open:[],end:[],stroke:"#f2666c"},{open:[0.455,0.03,0.515,0.955],end:[0.455,0.03,0.515,0.955],stroke:"#71B5DE",openEaseName:"easeInOutQuad",endEaseName:"easeInOutQuad"},],mask:false});
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
上图所示缓动函数:红 `Linear`,蓝 `easeInOutQuad`。
|
||||
|
||||
|
||||
#### 出入动画
|
||||
|
||||
不要做单向动画,进场后不做出场,直接消失元素或回到原点,会让整个画面不协调,反相只出不进也一样。
|
||||
|
||||
所以有动画的进场必须要有动画的出场,包括导航上的动画。
|
||||
|
||||
<div id="J-Symmetric"></div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Symmetric",{lineData:[
|
||||
{open:[0.455,0.03,0.515,0.955],end:[],openEaseName:"easeInOutQuad",endEaseName:"null",stroke:"#f2666c"},
|
||||
{open:[0.645,0.045,0.355,1],end:[0.645,0.045,0.355,1],stroke:"#71B5DE",openEaseName:"easeInOutCubic",endEaseName:"easeInOutCubic"}],
|
||||
mask:false,exposure:"top"});
|
||||
})
|
||||
</script>
|
||||
|
||||
上图所示缓动函数:红 `easeInOutQuad`,蓝 `easeInOutCubic`。
|
||||
|
||||
|
||||
##### 场外出入
|
||||
|
||||
场外出入需要考虑力量与引力的关系,如向空中抛物体时,开始时力量大于引力时,速度是最快的,
|
||||
|
||||
到达一定高度后,随着力量的减少,速度也跟随着降低,物体达到最高点后,力量等于引力或小于引力时,物体随之下降;
|
||||
|
||||
所以在快到达最高点和掉下来时有一定缓冲带;不要做图示红色球体下降时的缓动;
|
||||
|
||||
<div id="J-Entry"></div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Entry",{lineData:[
|
||||
{open:[0.25,0.46,0.45,0.94],end:[0.25,0.46,0.45,0.94],openEaseName:"easeOutQuad",endEaseName:"easeOutQuad",stroke:"#f2666c"},
|
||||
{open:[0.215,0.61,0.355,1],end:[0.55,0.055,0.675,0.19],stroke:"#71B5DE",openEaseName:"easeOutCubic",endEaseName:"easeInCubic"}],
|
||||
mask:true,exposure:"bottom"});
|
||||
})
|
||||
</script>
|
||||
|
||||
上图所示缓动函数:红 `easeOutQuad` `easeOutQuad`,蓝 `easeOutCubic` `easeInCubic`。
|
||||
|
||||
示例组件:[Message 全局提示](/components/message/),[Dropdown 下拉菜单](/components/dropdown/)。
|
||||
|
||||
#### 弹性动画
|
||||
|
||||
1. 如蹦极跳下来时,刚跳下时速度很快,到达绳子的长度后,由于物体的重量再将绳子拉长再反弹,弹动几次后才停下。
|
||||
|
||||
动画里也由质量来决定它的反弹,一般元素最好只弹动一次就够了,收回时可以用向下浮动再上拉或直接前缓动,可适用在下拉框与弹出元素。
|
||||
|
||||
2. 如球类物体掉地上的后,反弹几次后停止。
|
||||
|
||||
- 曲线图用的是3次贝塞尔曲线,没法表示Bounce,所以用line替换。
|
||||
- 弹性动画最好结合alpha。
|
||||
|
||||
<div id="J-Back"></div>
|
||||
|
||||
<script>
|
||||
$(function (){
|
||||
new Motion("#J-Back",{lineData:[
|
||||
{open:[,end:[0.455,0.03,0.515,0.955],openEaseName:"easeOutBounce",endEaseName:"easeInOutQuad",stroke:"#70f266"},
|
||||
{open:[0.175,0.885,0.32,1.275],end:[0.6,-0.28,0.735,0.045],stroke:"#71B5DE",openEaseName:"easeOutBack",endEaseName:"easeInBack"}],
|
||||
mask:false,exposure:"top"});
|
||||
})
|
||||
</script>
|
||||
|
||||
上图所示缓动函数:红 `easeOutBounce` `easeInOutQuad`,蓝 `easeOutBack` `easeInBack`。
|
||||
|
||||
|
||||
## 缓动函数
|
||||
|
||||
Ant Design 提供了一套缓动函数规范动画行为。
|
||||
|
||||
|名称 |参数 |说明与适用 |
|
||||
|-------------------|------------------------------------------|---------------------------|
|
||||
|@ease-out | `cubic-bezier(0.215,0.61,0.355,1);` |默认后缓动;适合元素展开时; |
|
||||
|@ease-in | `cubic-bezier(0.55,0.055,0.675,0.19);`|默认前缓动;适合元素关闭时; |
|
||||
|@ease-in-out | `cubic-bezier(0.645,0.045,0.355,1);` |默认前后缓动;适合元素移动; |
|
||||
|@ease-out-back | `cubic-bezier(0.18,0.89,0.32,1.28);` |结束回动;适合弹出框出现时; |
|
||||
|@ease-in-back | `cubic-bezier(0.6,-0.3,0.74,0.05);` |开始回动;适合弹出框关闭; |
|
||||
|@ease-in-out-back | `cubic-bezier(0.68,-0.55,0.27,1.55);` |前后回动; |
|
||||
|@ease-out-circ | `cubic-bezier(0.08,0.82,0.17,1);` |圆形后缓动;适合元素展开时; |
|
||||
|@ease-in-circ | `cubic-bezier(0.6,0.04,0.98,0.34);` |圆形前缓动;适合元素关闭时; |
|
||||
|@ease-in-out-circ | `cubic-bezier(0.78,0.14,0.15,0.86);` |圆形缓动;适合元素移动; |
|
7
spec/font.md
Normal file
7
spec/font.md
Normal file
@ -0,0 +1,7 @@
|
||||
# 字体
|
||||
|
||||
- category: 文字
|
||||
- order: 0
|
||||
|
||||
---
|
||||
|
@ -1,12 +1,32 @@
|
||||
# 基本
|
||||
# 组件动画
|
||||
|
||||
- category: 动画
|
||||
- order: 0
|
||||
|
||||
动画效果示例。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
Ant Design 提供了一些预设的组件动画样式。
|
||||
|
||||
<div id="components-motion-demo-basic"></div>
|
||||
|
||||
## 组件动画
|
||||
|
||||
通过设置组件的 `transitionName` 指定组件动画。
|
||||
|
||||
| 组件 | 中文名 | 采用动画 |
|
||||
|--------------|---------------------|-------------------------------------------------|
|
||||
| popover | 气泡浮出层 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` |
|
||||
| popconfirm | 气泡确认框 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` |
|
||||
| tooltip | 文字提示框 | `zoom-up` `zoom-down` `zoom-left` `zoom-right` |
|
||||
| modal | 弹出框 | `zoom` |
|
||||
| confirm | 弹出确认框 | `zoom` |
|
||||
| message | 信息提示条 | `move-up` |
|
||||
| dropdown | 下拉菜单 | `slide-up` |
|
||||
| select | 选择框 | `slide-up` |
|
||||
| datepicker | 日期选择框 | `slide-up` |
|
||||
|
||||
|
||||
`````jsx
|
||||
var cssAnimation = require('css-animation');
|
||||
var motions = [];
|
||||
motions = motions.concat([[{
|
||||
@ -196,7 +216,7 @@ var Test = React.createClass({
|
||||
});
|
||||
|
||||
React.render(<Test/>, document.getElementById('components-motion-demo-basic'));
|
||||
````
|
||||
`````
|
||||
|
||||
<style>
|
||||
.motion-container {
|
||||
@ -221,3 +241,4 @@ React.render(<Test/>, document.getElementById('components-motion-demo-basic'));
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
57
spec/page-transition.md
Normal file
57
spec/page-transition.md
Normal file
@ -0,0 +1,57 @@
|
||||
# 转场动画
|
||||
|
||||
- category: 动画
|
||||
- order: 1
|
||||
|
||||
---
|
||||
|
||||
### 单页面转场动画
|
||||
|
||||
从内容A到内容B的转变过程时能有效的吸引用户注意力,突出视觉中心,提高整体视觉效果。
|
||||
|
||||
### 视觉连贯性三元素
|
||||
|
||||
- Adding: 新加入的信息元素应被告知如何使用,从页面转变的信息元素需被重新识别。
|
||||
|
||||
- Receding: 与当前页无关的信息元素应采用适当方式移除。
|
||||
|
||||
- Normal: 指那些从转场开始到结束都没有发生变化的信息元素。
|
||||
|
||||
|
||||
### 转场动画
|
||||
|
||||
大页面转场可采用左出右入的形式。
|
||||
|
||||
小的信息元素排布或块状较多的情况下,最好根据一定的路径层次依次进场,区分维度层级,来凸显量级,间隔时间为动画时间的三分之一。
|
||||
|
||||
如不是单页面,页面动画可以为只右入和间隔性出现。
|
||||
|
||||
<script src="/static/TweenMax.min.js"></script>
|
||||
<script src="/static/motion.js"></script>
|
||||
|
||||
<div class="video-player">
|
||||
<video preload loop><source src="https://t.alipayobjects.com/images/rmsweb/T1QZ4gXdJeXXXXXXXX.webm" type="video/webm"><source src="https://t.alipayobjects.com/images/rmsweb/T1BIdgXkloXXXXXXXX.mp4" type="video/mp4"></video>
|
||||
</div>
|
||||
|
||||
|
||||
### 可折叠面板
|
||||
|
||||
对于信息元素内容区域的延伸,显示信息元素和进一步内容对象之间的直接连接。
|
||||
|
||||
1.被展开的信息区域内容按照一定的路劲依次进场。
|
||||
|
||||
2.信息元素在收起时照收齐点移动,在视觉上跟随关闭物体。
|
||||
|
||||
<link rel="stylesheet" href="/static/motionDemo.css">
|
||||
<div class="video-player">
|
||||
<video preload loop><source src="https://t.alipayobjects.com/images/rmsweb/T12I8gXexdXXXXXXXX.webm" type="video/webm"><source src="https://t.alipayobjects.com/images/rmsweb/T1e0hgXcpdXXXXXXXX.mp4" type="video/mp4"></video>
|
||||
</div>
|
||||
|
||||
|
||||
### 弹出框动效
|
||||
|
||||
从一个触发点触发一个弹出框时,弹框从所触发区域弹出,且触发区域视觉上基本保持不变。这样让触发区域和弹出区域有所关联,提高用户对新内容的认知。
|
||||
|
||||
<div class="video-player">
|
||||
<video preload loop><source src="https://t.alipayobjects.com/images/rmsweb/T1br0gXghtXXXXXXXX.webm" type="video/webm"><source src="https://t.alipayobjects.com/images/rmsweb/T1lcRgXb4gXXXXXXXX.mp4" type="video/mp4"></video>
|
||||
</div>
|
6
spec/typography.md
Normal file
6
spec/typography.md
Normal file
@ -0,0 +1,6 @@
|
||||
# 排版
|
||||
|
||||
- category: 文字
|
||||
- order: 1
|
||||
|
||||
---
|
@ -647,7 +647,7 @@ $(function (){
|
||||
var video=self.videoBox.eq(i).find("video");
|
||||
video.css({"width":"100%"});
|
||||
video.append(svg);
|
||||
svg.css({"position":"absolute","top":0});
|
||||
svg.css({"position":"absolute","top":0,"left":0});
|
||||
var playBox=_playBox(svg);
|
||||
svg.addChild(playBox);
|
||||
playBox.addEventListener("click",function (e){
|
||||
@ -670,4 +670,4 @@ $(function (){
|
||||
}
|
||||
};
|
||||
motionVideo.init();
|
||||
});
|
||||
});
|
||||
|
@ -477,6 +477,7 @@ footer ul li > a {
|
||||
-webkit-animation: xRightMatrix .5s ease-out;
|
||||
animation: xRightMatrix .5s ease-out;
|
||||
background: #fff;
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
.main-container-center {
|
||||
|
155
style/components/alert.less
Normal file
155
style/components/alert.less
Normal file
@ -0,0 +1,155 @@
|
||||
@import "../mixins/index";
|
||||
|
||||
@alertPrefixClass: ~"@{css-prefix}alert";
|
||||
@alertTitlePrefixClass: ~"@{css-prefix}alert-with-description";
|
||||
|
||||
.@{alertPrefixClass} {
|
||||
position: relative;
|
||||
padding: 8px 8px 8px 16px;
|
||||
border-radius: @border-radius-base;
|
||||
color: @text-color;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&-icon {
|
||||
margin-right: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
&-success {
|
||||
border: 1px solid tint(@success-color, 80%);
|
||||
background-color: tint(@success-color, 90%);
|
||||
.anticon {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-info {
|
||||
border: 1px solid tint(@primary-color, 80%);
|
||||
background-color: tint(@primary-color, 90%);
|
||||
.anticon {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-warn {
|
||||
border: 1px solid tint(@warning-color, 80%);
|
||||
background-color: tint(@warning-color, 90%);
|
||||
.anticon {
|
||||
color: @warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-error {
|
||||
border: 1px solid tint(@error-color, 80%);
|
||||
background-color: tint(@error-color, 90%);
|
||||
.anticon {
|
||||
color: @error-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-close-icon, &-with-description-close-icon {
|
||||
.iconfont-size-under-12px(10px);
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
transition: color .3s ease;
|
||||
color: #999;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
overflow: hidden;
|
||||
|
||||
&-x {
|
||||
position: absolute;
|
||||
top: -3px;
|
||||
&:before {
|
||||
font-weight: 700;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
content: "\e61e";
|
||||
font-family: "anticon";
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #444;
|
||||
}
|
||||
}
|
||||
|
||||
&-close-text {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
&-with-description {
|
||||
padding: 16px 16px 16px 69px;
|
||||
position: relative;
|
||||
border-radius: @border-radius-base;
|
||||
margin-bottom: 10px;
|
||||
color: @text-color;
|
||||
|
||||
&-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 24px;
|
||||
margin-top: -22px;
|
||||
font-size: 29px;
|
||||
}
|
||||
|
||||
&-close-icon {
|
||||
position: absolute;
|
||||
top: 17px;
|
||||
right: 16px;
|
||||
cursor: pointer;
|
||||
.iconfont-size-under-12px(10px);
|
||||
}
|
||||
|
||||
&-message {
|
||||
font-size: 14px;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: 12px;
|
||||
color: @legend-color;
|
||||
}
|
||||
|
||||
&-success {
|
||||
border: 1px solid tint(@success-color, 80%);
|
||||
background-color: tint(@success-color, 90%);
|
||||
.anticon {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-info {
|
||||
border: 1px solid tint(@primary-color, 80%);
|
||||
background-color: tint(@primary-color, 90%);
|
||||
.anticon {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-warn {
|
||||
border: 1px solid tint(@warning-color, 80%);
|
||||
background-color: tint(@warning-color, 90%);
|
||||
.anticon {
|
||||
color: @warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-error {
|
||||
border: 1px solid tint(@error-color, 80%);
|
||||
background-color: tint(@error-color, 90%);
|
||||
.anticon {
|
||||
color: @error-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -42,6 +42,28 @@
|
||||
.btn-circle-outline;
|
||||
}
|
||||
|
||||
&-loading {
|
||||
padding-right: 31px;
|
||||
&:after {
|
||||
font-family: anticon;
|
||||
.animation(loadingCircle 1s infinite linear);
|
||||
content: "\e610";
|
||||
position: absolute;
|
||||
height: 12px;
|
||||
line-height: 12px;
|
||||
right: 13px;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
}
|
||||
|
||||
&-sm&-loading {
|
||||
padding-right: 24px;
|
||||
&:after {
|
||||
right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&-menu {
|
||||
> .@{iconfont-css-prefix} {
|
||||
.iconfont-size-under-12px(10px);
|
||||
|
@ -13,12 +13,14 @@
|
||||
.@{confirmPrefixCls}-body {
|
||||
.@{confirmPrefixCls}-title {
|
||||
color: @text-color;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.@{confirmPrefixCls}-content {
|
||||
margin-left: 37px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
font-size: @font-size-base;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.anticon {
|
||||
|
@ -40,10 +40,9 @@
|
||||
line-height: 1;
|
||||
color: #000;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
filter: alpha(opacity=20);
|
||||
opacity: .2;
|
||||
text-decoration: none;
|
||||
transition: opacity .3s ease;
|
||||
transition: color .3s ease;
|
||||
color: #999;
|
||||
|
||||
&-x {
|
||||
position: absolute;
|
||||
@ -57,8 +56,7 @@
|
||||
height: 12px;
|
||||
.iconfont-size-under-12px(10px);
|
||||
line-height: 12px;
|
||||
color:#000;
|
||||
top:18px;
|
||||
top: 18px;
|
||||
right: 18px;
|
||||
|
||||
&:before {
|
||||
@ -69,9 +67,7 @@
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color:#000;
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
color: #444;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
@import "popover";
|
||||
@import "pagination";
|
||||
@import "form";
|
||||
@import "loading";
|
||||
@import "progress";
|
||||
@import "steps";
|
||||
@import "breadcrumb";
|
||||
@ -25,3 +24,4 @@
|
||||
@import "slider";
|
||||
@import "radio";
|
||||
@import "tag";
|
||||
@import "alert";
|
||||
|
Loading…
Reference in New Issue
Block a user