提交 d720a908 编写于 作者: Z zhujun24

Merge remote-tracking branch 'upstream/master' into vertical-steps

## 0.8.1 (2015-08-31)
### Table
* 新增无数据的展示样式。[4c54644](https://github.com/ant-design/ant-design/commit/4c54644116d46cb2510d2d475234529bad60e5d5)
* 修复本地模式 `dataSource` 无法更新的问题。[6d2dcc4](https://github.com/ant-design/ant-design/commit/6d2dcc45393b6ec0ad1ba73caf8b1ec42353743f)
* 修复远程模式 loading 失效的问题。[9b8abb2](https://github.com/ant-design/ant-design/commit/9b8abb219934c246970a84200818aa8f85974bdf)
### Upload
* 新增 `onRemove(file) {}` 接口,作为移除上传文件的回调。
* 新增 `urlResolver(res) {}` 接口,可以拿到请求回调数据里的远程文件地址,展示在文件列表中方便下载。
* 新增 `limit` 属性,用于限制文件上传列表的数量。
### Notification
* 修复不会自动消失的问题。[23fce55](https://github.com/ant-design/ant-design/commit/23fce559b0b2faf4e0b686a92dbcdd045727a464)
### Steps
* 新增竖版的步骤条。
### Carousel
* 修复 fade 模式下可以拖拽的问题。#212
## 0.8.0 (2015-08-25)
这个版本是第一个稳定版,组件经过三期迭代,基本到齐,并有大量改进和变化,不向下兼容。
......
......@@ -14,6 +14,7 @@ const AntCarousel = React.createClass({
if (props.effect === 'fade') {
props.fade = true;
props.draggable = false;
}
let className = 'ant-carousel';
......
......@@ -27,13 +27,13 @@ function animate(node, show, transitionName, done) {
const animation = {
enter(node, done) {
animate(node, false, 'slideDown', done);
return animate(node, false, 'slideDown', done);
},
leave(node, done) {
animate(node, true, 'slideUp', done);
return animate(node, true, 'slideUp', done);
},
appear(node, done) {
animate(node, false, 'slideDown', done);
return animate(node, false, 'slideDown', done);
},
};
......
......@@ -16,7 +16,7 @@ let defaultCalendarValue = new GregorianCalendar(zhCn);
defaultCalendarValue.setTime(Date.now());
function createPicker(Calendar){
function createPicker(Calendar) {
return React.createClass({
getInitialState() {
var value;
......
......@@ -37,7 +37,7 @@ React.render(
<div className="ant-input-group">
<input type="text" className="ant-input" id="site4" placeholder="www.mysite" />
<div className="ant-input-group-wrap">
<Select value=".com" style={{width:65}}>
<Select defaultValue=".com" style={{width:70}}>
<Option value=".com">.com</Option>
<Option value=".jp">.jp</Option>
<Option value=".cn">.cn</Option>
......
import React from 'react';
import Menu from 'rc-menu';
import velocity from 'velocity-animate';
import animation from '../common/openAnimation';
const AntMenu = React.createClass({
......
......@@ -2,7 +2,7 @@
- order: 1
自定义通知框自动关闭的延时,默认`3s`,取消自动关闭只要将该值设为`0`即可。
自定义通知框自动关闭的延时,默认`4.5s`,取消自动关闭只要将该值设为 `0` 即可。
---
......
......@@ -22,7 +22,7 @@ function getNotificationInstance() {
function notice(args) {
let duration;
if (args.duration === undefined) {
duration = 500;
duration = 4.5;
} else {
duration = args.duration;
}
......
......@@ -34,7 +34,7 @@ config 参数如下:
| btn | 自定义关闭按钮 | React.Element | 无 |
| key | 当前通知唯一标志 | String | 无 |
| onClose | 点击默认关闭按钮时触发的回调函数 | Function | 无 |
| duration | 默认五秒后自动关闭,配置为 null 则不自动关闭 | Number | 5 |
| duration | 默认 4.5 秒后自动关闭,配置为 null 则不自动关闭 | Number | 4.5 |
还提供了一个全局配置方法,需要在调用前提前配置,一次有效。
......
......@@ -54,7 +54,7 @@ var Line = React.createClass({
}else {
fullCls = ' ' + prefixCls + '-line-wrap-full';
}
var persentStyle = {
var percentStyle = {
width: props.percent + '%',
height: props.strokeWidth
};
......@@ -64,7 +64,7 @@ var Line = React.createClass({
{progressInfo}
<div className={prefixCls + '-line-outer'}>
<div className={prefixCls + '-line-inner'}>
<div className={prefixCls + '-line-bg'} style={persentStyle}></div>
<div className={prefixCls + '-line-bg'} style={percentStyle}></div>
</div>
</div>
</div>
......
......@@ -3,7 +3,7 @@ import Radio from './radio';
function getCheckedValue(children) {
var checkedValue = null;
children.forEach(function (radio) {
React.Children.forEach(children, function (radio) {
if (radio.props && radio.props.checked) {
checkedValue = radio.props.value;
}
......@@ -34,7 +34,7 @@ export default React.createClass({
},
render: function () {
var props = this.props;
var children = props.children.map((radio) => {
var children = React.Children.map(props.children, (radio) => {
if (radio.props) {
return <Radio
key={radio.props.value}
......
......@@ -22,7 +22,7 @@ function handleChange(value) {
React.render(
<Select
style={{width:400}}
style={{width: '100%'}}
tags defaultValue={['name2', 'name3']} onChange={handleChange}>
{children}
</Select>
......
......@@ -35,6 +35,7 @@ var dataSource = new Table.DataSource({
resolve: function(result) {
return result.data;
},
data: {},
// 和后台接口返回的分页数据进行适配
getPagination: function(result) {
return {
......
......@@ -36,14 +36,17 @@ var columns = [{
}
}];
var data = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
}, {
key: '3',
name: '李大嘴',
age: 32,
address: '西湖区湖底公园1号'
......
......@@ -23,14 +23,17 @@ var columns = [{
}];
var data = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
}, {
key: '3',
name: '李大嘴',
age: 32,
address: '西湖区湖底公园1号'
......
{
"data": [{
"key": "1",
"name": "胡彦斌ajax1",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "2",
"name": "胡彦祖ajax2",
"age": 42,
"address": "西湖区湖底公园1号"
}, {
"key": "3",
"name": "李大嘴ajax3",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "4",
"name": "李大嘴ajax4",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "5",
"name": "李大嘴ajax5",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "6",
"name": "李大嘴ajax6",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "7",
"name": "李大嘴ajax7",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "8",
"name": "李大嘴ajax8",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "9",
"name": "李大嘴ajax9",
"age": 32,
"address": "西湖区湖底公园1号"
}, {
"key": "10",
"name": "李大嘴ajax10",
"age": 32,
"address": "西湖区湖底公园1号"
......
......@@ -43,18 +43,22 @@ var columns = [{
}];
var data = [{
key: '1',
name: '胡斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园12号'
}, {
key: '3',
name: '李大嘴',
age: 32,
address: '西湖区湖底公园123号'
}, {
key: '4',
name: '李秀莲大嘴哥',
age: 32,
address: '西湖区湖底公园123号'
......
# 外界控制数据
- order: 11
由父元素控制自身数据展示。
---
````jsx
var Table = antd.Table;
var columns = [{
title: '姓名',
dataIndex: 'name',
render: function(text) {
return <a href="javascript:;">{text}</a>;
}
}, {
title: '年龄',
dataIndex: 'age'
}, {
title: '住址',
dataIndex: 'address'
}];
var data1 = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
}, {
key: '3',
name: '李大嘴',
age: 32,
address: '西湖区湖底公园1号'
}];
var data2 = [{
key: '11',
name: '胡彦斌2',
age: 32,
address: '西湖区湖底公园2号'
}, {
key: '22',
name: '胡彦祖2',
age: 42,
address: '西湖区湖底公园2号'
}, {
key: '33',
name: '李大嘴2',
age: 32,
address: '西湖区湖底公园2号'
}];
var App = React.createClass({
getInitialState() {
return {
data: []
};
},
handleClick1() {
this.setState({
data: data1
});
},
handleClick2() {
this.setState({
data: data2
});
},
render() {
return <div>
<Table columns={columns} dataSource={this.state.data} />
<button className="ant-btn" onClick={this.handleClick1}>加载本地数据1</button>
&nbsp;
<button className="ant-btn" onClick={this.handleClick2}>加载本地数据2</button>
</div>;
}
})
React.render(<App />
, document.getElementById('components-table-demo-local-data'));
````
......@@ -20,14 +20,17 @@ var columns = [{
}];
var data = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
}, {
key: '3',
name: '李大嘴',
age: 32,
address: '西湖区湖底公园1号'
......
......@@ -26,6 +26,7 @@ var data = [];
for (let i=0; i<46; i++) {
data.push({
key: i,
name: '李大嘴' + i,
age: 32,
address: '西湖区湖底公园' + i + ''
......
......@@ -22,14 +22,17 @@ var columns = [{
dataIndex: 'address'
}];
var data = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
}, {
key: '3',
name: '李大嘴',
age: 32,
address: '西湖区湖底公园1号'
......
......@@ -19,14 +19,17 @@ var columns = [{
dataIndex: 'address'
}];
var data = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
}, {
key: '3',
name: '李大嘴',
age: 32,
address: '西湖区湖底公园1号'
......
......@@ -31,7 +31,7 @@ class DataSource {
}
clone(config = {}) {
return new DataSource(objectAssign(config, this.config));
return new DataSource(objectAssign({}, this.config, config));
}
}
......@@ -42,13 +42,15 @@ var AntTable = React.createClass({
selectedRowKeys: [],
// only for remote
data: [],
dataSource: this.props.dataSource,
filters: {},
loading: !this.isLocalDataSource(),
loading: false,
sortColumn: '',
sortOrder: '',
sorter: null,
pagination: this.hasPagination() ? objectAssign({
pageSize: 10
pageSize: 10,
current: 1
}, this.props.pagination) : {}
};
},
......@@ -68,25 +70,23 @@ var AntTable = React.createClass({
},
componentWillReceiveProps(nextProps) {
let newState = {};
if (('pagination' in nextProps) && nextProps.pagination !== false) {
this.setState({
pagination: objectAssign({}, this.state.pagination, nextProps.pagination)
});
newState.pagination = objectAssign({}, this.state.pagination, nextProps.pagination);
}
if (!this.isLocalDataSource()) {
// 外界只有 dataSource 的变化会触发请请求
if (nextProps.dataSource !== this.props.dataSource) {
this.setState({
selectedRowKeys: [],
loading: true
}, this.fetch);
}
// 外界只有 dataSource 的变化会触发新请求
if ('dataSource' in nextProps &&
nextProps.dataSource !== this.props.dataSource) {
newState = {
selectedRowKeys: [],
dataSource: nextProps.dataSource,
loading: true
};
}
if (nextProps.columns !== this.props.columns) {
this.setState({
filters: {}
});
newState.filters = {};
}
this.setState(newState, this.fetch);
},
hasPagination(pagination) {
......@@ -97,11 +97,11 @@ var AntTable = React.createClass({
},
isLocalDataSource() {
return Array.isArray(this.props.dataSource);
return Array.isArray(this.state.dataSource);
},
getRemoteDataSource() {
return this.props.dataSource;
return this.state.dataSource;
},
toggleSortOrder(order, column) {
......@@ -295,11 +295,11 @@ var AntTable = React.createClass({
</span>
</div>;
}
column.title = [
column.title,
sortButton,
filterDropdown
];
column.title = <div>
{column.title}
{sortButton}
{filterDropdown}
</div>;
return column;
});
},
......@@ -313,15 +313,15 @@ var AntTable = React.createClass({
if (this.props.size === 'small') {
classString += ' mini';
}
let total;
if (this.isLocalDataSource()) {
let total = this.state.pagination.total;
if (!total && this.isLocalDataSource()) {
total = this.getLocalData().length;
}
return <Pagination className={classString}
return (total > 0) ? <Pagination className={classString}
onChange={this.handlePageChange}
total={total}
pageSize={10}
{...this.state.pagination} />;
{...this.state.pagination} /> : null;
},
prepareParamsArguments(state) {
......@@ -424,7 +424,7 @@ var AntTable = React.createClass({
getLocalData() {
let state = this.state;
let data = this.props.dataSource;
let data = this.state.dataSource;
// 排序
if (state.sortOrder && state.sorter) {
data = data.sort(state.sorter);
......@@ -457,7 +457,7 @@ var AntTable = React.createClass({
let data = this.getCurrentPageData();
let columns = this.renderRowSelection();
let classString = '';
if (this.state.loading && this.isLocalDataSource()) {
if (this.state.loading && !this.isLocalDataSource()) {
classString += ' ant-table-loading';
}
if (this.props.size === 'small') {
......@@ -467,13 +467,24 @@ var AntTable = React.createClass({
classString += ' ant-table-bordered';
}
columns = this.renderColumnsDropdown(columns);
columns = columns.map((column, i) => {
column.key = column.dataIndex || i;
return column;
});
let emptyText;
if (!data || data.length === 0) {
emptyText = <div className="ant-table-empty">
<i className="anticon anticon-frown"></i>暂无数据
</div>;
}
return <div className="clearfix">
<Table
{...this.props}
data={data || []}
data={data}
columns={columns}
className={classString}
/>
{emptyText}
{this.renderPagination()}
</div>;
}
......
......@@ -24,10 +24,12 @@ Table 有两种模式,本地数据和远程数据模式。
```jsx
var dataSource = [{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号'
}, {
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号'
......@@ -64,6 +66,7 @@ var dataSource = new Table.DataSource({
| size | 正常或迷你类型 | string | `normal` or `small` | normal |
| dataSource | 数据源,可以为数组(本地模式)或一个数据源描述对象(远程模式) | Array or Object | | |
| columns | 表格列的配置描述,具体项见下表 | Array | | 无 |
| rowKey | 表格列 key 的取值 | Function(recode,index):string | | record.key |
### Column
......
import React from 'react';
import Tree from 'rc-tree';
import velocity from 'velocity-animate';
import animation from '../common/openAnimation';
const AntTree = React.createClass({
......
# 点击上传
- order: 1
- order: 0
经典款式,用户点击按钮弹出文件选择框。
......@@ -15,12 +15,9 @@ var props = {
data: {},
accept: '',
uploadTip: '',
start: function(file){
console.log(file.name)
},
error: function() {},
success: function() {},
progress: function() {}
onStart(file){
console.log(file.uid);
}
};
React.render(
......
......@@ -14,11 +14,7 @@ var props = {
action: '/upload.do',
data: {},
accept: '',
uploadTip: '',
error: function() {},
success: function() {},
progress: function() {},
start: function() {}
uploadTip: ''
};
React.render(
......
......@@ -14,15 +14,7 @@ var props = {
action: '/upload.do',
data: {},
accept: 'i',
uploadTip: '',
error: function(err) {
console.log(err)
},
success: function() {},
progress: function() {},
start: function(file){
console.log(file)
}
uploadTip: ''
};
React.render(
......@@ -31,7 +23,7 @@ React.render(
<i className="anticon anticon-inbox"></i>
</p>
<p className="ant-upload-text">点击或将文件拖拽到此区域上传</p>
<p className="ant-upload-hint">支持单个或批量上传,严上传公司内部资料及其他违禁文件</p>
<p className="ant-upload-hint">支持单个或批量上传,严上传公司内部资料及其他违禁文件</p>
</Dragger>,
document.getElementById('components-upload-demo-drag')
);
......
# 文件列表限制
- order: 3
`limit` 属性控制文件列表数的上限。如设为 1 时,表示只能上传一个文件,新文件会顶掉旧文件。
---
````jsx
var Upload = antd.Upload;
var props = {
description: '支持扩展名为: .rar .zip ...',
action: '/upload.do',
data: {},
accept: '',
uploadTip: '',
limit: 1,
onStart(file){
console.log(file.uid);
}
};
React.render(
<Upload {...props}>
<button className="ant-btn ant-btn-ghost">
<i className="anticon anticon-upload"></i> 点击上传,只支持一个文件
</button>
</Upload>,
document.getElementById('components-upload-demo-limit')
);
````
......@@ -7,36 +7,71 @@ import getFileItem from './getFileItem';
const prefixCls = 'ant-upload';
let fileIndex = 0;
function noop() {
}
const AntUpload = React.createClass({
getInitialState() {
return {
downloadList: []
};
},
handleStart(file) {
onStart(file) {
let nextDownloadList = this.state.downloadList;
nextDownloadList.push({
index: fileIndex++,
uid: file.uid || '',
filename: file.name,
file: file,
status: 'downloading'
});
if (nextDownloadList.length === this.props.limit + 1) {
nextDownloadList = nextDownloadList.slice(1);
}
this.setState({
downloadList: nextDownloadList
});
this.props.onStart(file);
},
handleSuccess(ret, file) {
Message.success(file.name + '上传完成');
let targetItem = getFileItem(file, this.state.downloadList);
targetItem.status = 'done';
removeFile(file){
var downloadList = this.state.downloadList.concat();
let targetItem = getFileItem(file, downloadList);
var index = downloadList.indexOf(targetItem);
if (index !== -1) {
downloadList.splice(index, 1);
}
this.setState({
downloadList: this.state.downloadList
downloadList: downloadList
});
},
handleProgress() {
onSuccess(ret, file) {
var res = this.props.onSuccess(ret, file);
if (res !== false) {
var downloadList = this.state.downloadList.concat();
Message.success(file.name + '上传完成');
let targetItem = getFileItem(file, downloadList);
targetItem.status = 'done';
// 解析出文件上传后的远程地址
if (typeof this.props.urlResolver === 'function') {
targetItem.url = this.props.urlResolver(ret);
}
this.setState({
downloadList: downloadList
});
} else {
this.removeFile(file);
}
},
onProgress(e, file) {
this.props.onProgress(e, file);
},
onError(err, responce, file) {
Message.error(file.name + ' 上传失败');
this.removeFile(file);
this.props.onError(err, responce, file);
},
handleError() {
Message.error('上传失败');
onRemove(file){
this.props.onRemove(file);
},
getDefaultProps() {
return {
......@@ -47,32 +82,27 @@ const AntUpload = React.createClass({
data: {},
accept: '',
uploadTip: '',
start: function() {},
error: function() {},
success: function() {},
progress: function() {}
onStart: noop,
onError: noop,
onSuccess: noop,
onProgress: noop,
onRemove: noop,
limit: Number.MAX_VALUE,
urlResolver: function(ret) {
try {
return JSON.parse(ret).url;
} catch(e) {}
}
};
},
render() {
let type = this.props.type || 'select';
let props = assign({}, this.props);
props.onStart = (file) => {
this.handleStart(file);
props.start.call(this, file);
};
props.onSuccess = (ret, file) => {
this.handleSuccess(ret, file);
props.success.call(this, ret, file);
};
props.onProgress = (step) => {
this.handleProgress(step);
props.progress.call(this, step);
};
props.onError = (err, responce, file) => {
this.handleError(err);
props.error.call(this, err, responce, file);
};
let props = assign({}, this.props, {
onStart: this.onStart,
onError: this.onError,
onProgress: this.onProgress,
onSuccess: this.onSuccess,
});
if (type === 'drag') {
return (
<div className={prefixCls + ' ' + prefixCls + '-drag'}>
......@@ -91,7 +121,9 @@ const AntUpload = React.createClass({
{this.props.children}
</Upload>
</div>
<UploadList items={this.state.downloadList} />
<UploadList items={this.state.downloadList}
onRemove={this.onRemove}
limit={props.limit} />
</div>
);
}
......@@ -100,7 +132,7 @@ const AntUpload = React.createClass({
AntUpload.Dragger = React.createClass({
render() {
return <AntUpload {...this.props} type="drag" style={{height: this.props.height}} />;
return <AntUpload {...this.props} type="drag" style={{height: this.props.height}}/>;
}
});
......
......@@ -28,6 +28,8 @@
| onError | 可选参数, error callback |Function | 无 |
| onSuccess | 可选参数, success callback | Function | 无 |
| onProgress | 可选参数, progress callback, 现代浏览器有效 | Function | 无 |
| urlResolver| 通过解析请求返回数据,获得文件上传的远程地址 | Function | `function() { return JSON.parse(ret).url }` |
| limit | 文件上传数量的限制 | Number | Number.MAX_VALUE |
### onError
......
......@@ -30,15 +30,19 @@ export default React.createClass({
this.setState({
items: items
});
this.props.onRemove(file.file);
},
render() {
let items = this.state.items;
let downloadItem = (file) => {
let statusIcon = file.status === 'done' ? <i className={'anticon anticon-check ' + prefixCls + '-success-icon'}></i> : <i className="anticon anticon-loading"></i>;
let statusIcon = file.status === 'done' ? <i className={'anticon anticon-check ' + prefixCls + '-success-icon'}></i> :
<i className="anticon anticon-loading"></i>;
let filename = file.url ? <a className={prefixCls + '-item-name'} href={file.url} _target="_blank">{file.filename}</a> :
<b className={prefixCls + '-item-name'}>{file.filename}</b>;
return (
<div className={prefixCls + '-list-item'} key={file.index}>
{statusIcon}
<b className={prefixCls + '-item-name'}>{file.filename}</b>
{filename}
<i className="anticon anticon-cross" ref="theCloseBtn"
onClick={this.handleClose.bind(this, file)}></i>
</div>
......
......@@ -78,17 +78,15 @@ var App = React.createClass({
};
},
handleChange(value) {
message.info('您选择的日期是: ' + value.toString());
this.setState({
date: value
});
},
notice() {
message.info(this.state.date.toString());
},
render() {
return <div>
return <div style={{width: 400, margin: '100px auto'}}>
<Datepicker onSelect={this.handleChange} />
<button className="ant-btn ant-btn-primary" onClick={this.notice}>显示日期</button>
<div style={{marginTop: 20}}>当前日期:{this.state.date.toString()}</div>
</div>;
}
});
......
......@@ -74,7 +74,10 @@ exports.middlewares = [
busboy.on('finish', function() {
console.log('Done parsing form!');
//res.writeHead(303, { Connection: 'close', Location: '/' });
res.end('success');
res.end(JSON.stringify({
'status': 'success',
'url': '/example.file'
}));
});
req.pipe(busboy);
}
......
{
"name": "antd",
"version": "0.8.1-beta1",
"version": "0.8.1-beta2",
"stableVersion": "0.8.0",
"title": "Ant Design",
"description": "一个 UI 设计语言",
......
......@@ -35,7 +35,7 @@ $(function () {
},
render() {
return <Select combobox style={{width: 260}}
return <Select combobox style={{width: '100%'}}
onSelect={this.handleSelect}
optionLabelProp="text"
dropdownClassName="autoComplete"
......
......@@ -106,6 +106,7 @@
</li>
</ul>
</nav>
<div class="nav-phone-icon"></div>
</header>
<div class="main-wrapper">
{% block aside %}{% endblock %} {% block content %}{% endblock %}
......
......@@ -95,9 +95,9 @@ mask:true,exposure:"bottom"});
2. 如球类物体掉地上的后,反弹几次后停止。
- 弹性动画最好结合 alpha。
弹性动画最好结合 alpha。
> 慎用Bounce或Elastic,这两种适用在特殊元素下,一般back即可满足页面上元素的弹动;
> 慎用 Bounce 或 Elastic,这两种适用在特殊元素下,一般 back 即可满足页面上元素的弹动;
<div id="J-Back"></div>
......@@ -110,7 +110,7 @@ mask:false,exposure:"top"});
})
</script>
上图所示缓动函数:绿 `easeOutBounce` `easeOutElastic`( css 需自配), 蓝 `ease-out-back` `ease-in-back`
上图所示缓动函数:绿 `easeOutBounce` `easeOutElastic`(css 需自配), 蓝 `ease-out-back` `ease-in-back`
## 缓动函数
......@@ -119,15 +119,15 @@ 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);` |圆形前后缓动 |
|@ease-out-quint | `cubic-bezier(0.23, 1, 0.32, 1);`| quint后缓动|
|@ease-in-quint | `cubic-bezier(0.755, 0.05, 0.855, 0.06);`|quint前缓动|
|@ease-in-out-quint | `cubic-bezier(0.86, 0, 0.07, 1);`| quint前后缓动|
|@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);` |圆形前后缓动 |
|@ease-out-quint | `cubic-bezier(0.23, 1, 0.32, 1);`| quint 后缓动|
|@ease-in-quint | `cubic-bezier(0.755, 0.05, 0.855, 0.06);`|quint 前缓动|
|@ease-in-out-quint | `cubic-bezier(0.86, 0, 0.07, 1);`| quint 前后缓动|
......@@ -15,12 +15,14 @@
<div class="col col-12 paragraph-12px">
<h3>12px 段落</h3>
<p>汉学家称这个空白字为「盘古之白」,因为它劈开了全角字和半角字之间的混沌。</p>
<p>另有有研究显示,打字的时候不喜欢在中文和英文之间加空格的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。毕竟爱情跟书写都需要适时地留白。</p>
<p>另有研究显示,打字的时候不喜欢在中文和英文之间加空格的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。毕竟爱情跟书写都需要适时地留白。</p>
<p>文案来自 <a href="https://github.com/vinta/paranoid-auto-spacing#%E7%82%BA%E4%BB%80%E9%BA%BC%E4%BD%A0%E5%80%91%E5%B0%B1%E6%98%AF%E4%B8%8D%E8%83%BD%E5%8A%A0%E5%80%8B%E7%A9%BA%E6%A0%BC%E5%91%A2">此处</a></p>
</div>
<div class="col col-12 paragraph-14px">
<h3>14px 段落</h3>
<p>汉学家称这个空白字为「盘古之白」,因为它劈开了全角字和半角字之间的混沌。</p>
<p>另有有研究显示,打字的时候不喜欢在中文和英文之间加空格的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。毕竟爱情跟书写都需要适时地留白。</p>
<p>另有研究显示,打字的时候不喜欢在中文和英文之间加空格的人,感情路都走得很辛苦,有七成的比例会在 34 岁的时候跟自己不爱的人结婚,而其余三成的人最后只能把遗产留给自己的猫。毕竟爱情跟书写都需要适时地留白。</p>
<p>文案来自 <a href="https://github.com/vinta/paranoid-auto-spacing#%E7%82%BA%E4%BB%80%E9%BA%BC%E4%BD%A0%E5%80%91%E5%B0%B1%E6%98%AF%E4%B8%8D%E8%83%BD%E5%8A%A0%E5%80%8B%E7%A9%BA%E6%A0%BC%E5%91%A2">此处</a></p>
</div>
</div>
......@@ -92,7 +94,7 @@
## 文案长度
语言通常是越简单越明确,而提示性文字更需要简明扼要,让用户一目了然,减少操作失误。提示性句子长度业务而定,建议一般不超过 16–18 个字。
语言通常是越简单越明确,而提示性文字更需要简明扼要,让用户一目了然,减少操作失误。提示性句子长度业务而定,建议一般不超过 16–18 个字。
<img align="right" style="margin:30px 100px" src="https://t.alipayobjects.com/images/T17cthXgpbXXXXXXXX.png" width="300">
......
......@@ -37,6 +37,10 @@ $(function() {
// 移动 API 文档到演示下方
$('.markdown #api').nextAll().andSelf().appendTo('.api-container');
$('.nav-phone-icon').click(function() {
$(this).prev().toggle();
});
$.easing['jswing'] = $.easing['swing'];
$.extend($.easing,{
easeInCirc: function (x, t, b, c, d) {
......
......@@ -105,7 +105,7 @@ a.logo {
.search {
float: left;
height: 22px;
padding: 0px 30px;
padding: 0px 0 0 30px;
margin: 32px auto 0;
border-left: 1px solid #EBEDEE;
position: relative;
......@@ -113,6 +113,7 @@ a.logo {
#autoComplete {
margin-top: -2px;
width: 230px;
}
#autoComplete .ant-select {
......@@ -1883,10 +1884,31 @@ a.entry-link:hover .anticon-smile {
.logo {
margin: 10px;
width: 110px;
height: auto;
}
.nav {
position: absolute;
z-index: 1000;
top: 50px;
right: 0;
background: #fff;
overflow: hidden;
height: auto;
line-height: 50px;
margin-right: 0;
border: 1px solid #e9e9e9;
width: 50%;
}
.nav .bar {
display: none!important;
}
.nav ul li {
width: 100%;
}
.nav-phone-icon {
display: block;
width: 49px;
......@@ -1915,11 +1937,25 @@ a.entry-link:hover .anticon-smile {
height: calc(100% - 86px);
}
footer ul {
display: none;
.aside-container {
float: none;
width: auto;
}
footer h3 {
display: block;
.main-container {
margin-left: 0;
}
.markdown {
width: 100%;
}
footer {
text-align: center;
}
footer ul li {
float: none;
width: auto;
}
}
......@@ -105,7 +105,7 @@ input[type="checkbox"] {
position: absolute;
font-size: @font-size-base;
line-height: @line-height-base;
bottom: - @line-height-computed;
bottom: -@line-height-computed;
}
......
@select-prefix-cls: ant-select;
@import "../mixins/iconfont";
......@@ -17,9 +18,9 @@
font-family: 'anticon';
font-weight: bold;
position: absolute;
top: 6px;
top: 7px;
right: 0;
padding-right: 16px;
padding-right: 15px;
color: @primary-color;
}
}
......
......@@ -176,6 +176,21 @@
}
}
}
&-empty {
height: 100px;
line-height: 100px;
text-align: center;
font-size: 12px;
color: #999;
border-bottom: 1px solid #E9E9E9;
margin-bottom: 16px;
.anticon {
margin-right: 4px;
position: relative;
top: -1px;
}
}
}
.@{table-prefix-cls}-pagination {
......
......@@ -90,11 +90,13 @@
}
.@{upload-prefix-cls}-item-name {
font-size: 12px;
color: #666;
margin-left: 4px;
margin-right: 8px;
font-weight: normal;
}
b.@{upload-prefix-cls}-item-name {
color: #666;
}
.@{upload-prefix-cls}-success-icon {
color: @success-color;
font-weight: bold;
......
.zoom-motion(@className, @keyframeName) {
.make-motion(@className, @keyframeName);
.@{className}-enter, .@{className}-appear {
transform: scale(0, 0); // need this by yiminghe
animation-timing-function: @ease-out-quint;
transform: scale(0); // need this by yiminghe
animation-timing-function: @ease-out-circ;
}
.@{className}-leave {
animation-timing-function: @ease-in-quint;
animation-timing-function: @ease-in-out-circ;
}
}
......@@ -18,20 +18,20 @@
@keyframes zoomIn {
0% {
opacity: 0;
transform: scale(0, 0);
transform: scale(0);
}
100% {
transform: scale(1, 1);
transform: scale(1);
}
}
@keyframes zoomOut {
0% {
transform: scale(1, 1);
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0, 0);
transform: scale(0);
}
}
......@@ -39,23 +39,23 @@
0% {
opacity: 0;
transform-origin: 50% 0%;
transform: scale(0, 0);
transform: scale(.8);
}
100% {
transform-origin: 50% 0%;
transform: scale(1, 1);
transform: scale(1);
}
}
@keyframes zoomUpOut {
0% {
transform-origin: 50% 0%;
transform: scale(1, 1);
transform: scale(1);
}
100% {
opacity: 0;
transform-origin: 50% 0%;
transform: scale(0, 0);
transform: scale(.8);
}
}
......@@ -63,23 +63,23 @@
0% {
opacity: 0;
transform-origin: 0% 50%;
transform: scale(0, 0);
transform: scale(.8);
}
100% {
transform-origin: 0% 50%;
transform: scale(1, 1);
transform: scale(1);
}
}
@keyframes zoomLeftOut {
0% {
transform-origin: 0% 50%;
transform: scale(1, 1);
transform: scale(1);
}
100% {
opacity: 0;
transform-origin: 0% 50%;
transform: scale(0, 0);
transform: scale(.8);
}
}
......@@ -87,23 +87,23 @@
0% {
opacity: 0;
transform-origin: 100% 50%;
transform: scale(0, 0);
transform: scale(.8);
}
100% {
transform-origin: 100% 50%;
transform: scale(1, 1);
transform: scale(1);
}
}
@keyframes zoomRightOut {
0% {
transform-origin: 100% 50%;
transform: scale(1, 1);
transform: scale(1);
}
100% {
opacity: 0;
transform-origin: 100% 50%;
transform: scale(0, 0);
transform: scale(.8);
}
}
......@@ -111,22 +111,22 @@
0% {
opacity: 0;
transform-origin: 50% 100%;
transform: scale(0, 0);
transform: scale(.8);
}
100% {
transform-origin: 50% 100%;
transform: scale(1, 1);
transform: scale(1);
}
}
@keyframes zoomDownOut {
0% {
transform-origin: 50% 100%;
transform: scale(1, 1);
transform: scale(1);
}
100% {
opacity: 0;
transform-origin: 50% 100%;
transform: scale(0, 0);
transform: scale(.8);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册