diff --git a/CHANGELOG.md b/CHANGELOG.md index a19120cce..74779401a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.7.3 (2015-07-30) + +* 小幅重构了 Table 分页,修复了分页导致的数据不展示的问题。 +* 更新了部分文档。 + ## 0.7.2 (2015-07-27) * 修复本地模式下 pagination 为 false 时数据无法显示的 [问题](https://github.com/ant-design/ant-design/commit/1954586665e59031eae5d2c8b2cdb08f83d64fcb)。 diff --git a/README.md b/README.md index 08626d4e5..ab66c985f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Ant Design [![](https://img.shields.io/travis/ant-design/ant-design.svg?style=flat-square)](https://travis-ci.org/ant-design/ant-design) [![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd) [![Dependency Status](https://david-dm.org/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design) +[![Join the chat at https://gitter.im/ant-design/ant-design](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + 一套企业级的前端设计语言和基于 React 的实现。 设计文档和组件实现均在紧密整理和开发中,部分页面可能不完善,预计 8 月份释出正式版本。 diff --git a/components/button/demo/loading.md b/components/button/demo/loading.md index a818b92e8..9f5a314be 100644 --- a/components/button/demo/loading.md +++ b/components/button/demo/loading.md @@ -21,9 +21,6 @@ var App = React.createClass({ render() { var loadingClass = this.state.loading ? 'ant-btn-loading' : ''; return
- diff --git a/components/enter-animation/index.md b/components/enter-animation/index.md index 5ed1928f8..cf39487d4 100644 --- a/components/enter-animation/index.md +++ b/components/enter-animation/index.md @@ -20,7 +20,7 @@ 一级子元素依次进场。 -```jsx +```html
依次进场
依次进场
@@ -31,7 +31,7 @@ 如子节点有 `enter-data` 值,则只执行有 `enter-data` 的节点的动画,相反所有子节点上都没有 `enter-data` 值,则执行遍历dom下一级节点来执行动画。 -```jsx +```html
@@ -40,7 +40,6 @@
依次进场
依次进场,并修改动画效果
-
依次进场,并使用样式修改动画效果
没有动画
``` diff --git a/components/layout/index.md b/components/layout/index.md index 9d3e96cf1..5d330fc93 100644 --- a/components/layout/index.md +++ b/components/layout/index.md @@ -3,6 +3,7 @@ - category: Components - chinese: 布局 - order: 0 +- cols: 1 --- diff --git a/components/message/demo/success.md b/components/message/demo/success.md index 4df02f515..47fc24b7a 100644 --- a/components/message/demo/success.md +++ b/components/message/demo/success.md @@ -8,6 +8,7 @@ ````jsx var message = antd.message; + var success = function() { message.success('这是一条成功的提示'); }; diff --git a/components/message/index.jsx b/components/message/index.jsx index b038d3c71..9f9ddb20d 100644 --- a/components/message/index.jsx +++ b/components/message/index.jsx @@ -2,13 +2,19 @@ import React from 'react'; import Notification from 'rc-notification'; let defaultDuration = 1.5; +let top; + +var messageInstance; function getMessageInstance() { - return Notification.newInstance({ + messageInstance = messageInstance || Notification.newInstance({ prefixCls: 'ant-message', transitionName: 'move-up', - style: {} // 覆盖原来的样式 + style: { + top: top + } // 覆盖原来的样式 }); + return messageInstance; } function notice(content, duration = defaultDuration, type) { @@ -18,7 +24,6 @@ function notice(content, duration = defaultDuration, type) { 'error': 'anticon-exclamation-circle ant-message-error' })[type]; getMessageInstance().notice({ - key: 'simpleMessage', duration: duration, style: {}, content:
@@ -37,5 +42,10 @@ export default { }, error(content, duration) { notice(content, duration, 'error'); + }, + config(options) { + if (options.top) { + top = options.top; + } } }; diff --git a/components/message/index.md b/components/message/index.md index 3ceebbf79..245beb24a 100644 --- a/components/message/index.md +++ b/components/message/index.md @@ -25,3 +25,18 @@ |------------|----------------|----------------------------|--------------| | content | 提示内容 | React.Element or String | 无 | | duration | 自动关闭的延时 | number | 1.5 | + + +还提供了一个全局配置方法: + +- `message.config(options)` + +```js +message.config({ + top: 100 +}); +``` + +| 参数 | 说明 | 类型 | 默认值 | +|------------|--------------------|----------------------------|--------------| +| top | 消息距离顶部的位置 | Number | 24px | diff --git a/components/progress/demo/line-mini.md b/components/progress/demo/line-mini.md index 265f8fc28..a326a9844 100644 --- a/components/progress/demo/line-mini.md +++ b/components/progress/demo/line-mini.md @@ -10,10 +10,11 @@ var Progress = antd.Progress.Line; React.render( -
- - - +
+ + + +
, document.getElementById('components-progress-demo-line-mini')); ```` diff --git a/components/progress/demo/line.md b/components/progress/demo/line.md index 90895477a..ad51685c6 100644 --- a/components/progress/demo/line.md +++ b/components/progress/demo/line.md @@ -12,8 +12,10 @@ var Progress = antd.Progress.Line; React.render(
+ +
, document.getElementById('components-progress-demo-line')); ```` diff --git a/components/progress/index.jsx b/components/progress/index.jsx index 1c380a8fc..083311e7e 100644 --- a/components/progress/index.jsx +++ b/components/progress/index.jsx @@ -1,65 +1,72 @@ -import {Line as Progressline, Circle as Progresscircle} from 'rc-progress'; +import {Circle as Progresscircle} from 'rc-progress'; import React from 'react'; import assign from 'object-assign'; +const prefixCls = 'ant-progress'; + +const statusColorMap = { + 'normal': '#2db7f5', + 'exception': '#ff6600', + 'success': '#87d068' +}; + var Line = React.createClass({ + propTypes: { + status: React.PropTypes.oneOf(['normal', 'exception', 'active', 'success']), + showInfo: React.PropTypes.bool, + percent: React.PropTypes.number, + strokeWidth: React.PropTypes.number + }, getDefaultProps() { return { - width: 300, percent: 0, - strokeWidth: 3, - status: 'normal' // exception + strokeWidth: 10, + status: 'normal', // exception active + showInfo: true }; }, render() { - var statusColorMap = { - 'normal': '#3FC7FA', - 'exception': '#FE8C6A', - 'success': '#85D262' - }; - var props = assign({}, this.props); if (parseInt(props.percent) === 100) { props.status = 'success'; } - var style = { - 'width': props.width - }; - var fontSize = (props.width / 100 * props.strokeWidth); - var iconStyle = { - 'fontSize': (fontSize < 12) ? 12 : fontSize - }; - var textStyle = { - 'color': statusColorMap[props.status] - }; - var progressInfo; - if (props.status === 'exception') { - progressInfo = ( - - - - ); - } else if (props.status === 'success') { - progressInfo = ( - - - - ); - } else { - progressInfo = ( - {props.percent}% - ); + var progressInfo, fullCls = ''; + if(props.showInfo === true){ + if (props.status === 'exception') { + progressInfo = ( + + + + ); + } else if (props.status === 'success') { + progressInfo = ( + + + + ); + } else { + progressInfo = ( + {props.percent}% + ); + } + }else { + fullCls = ' ' + prefixCls + '-line-wrap-full'; } + var persentStyle = { + width: props.percent + '%', + height: props.strokeWidth + }; return ( -
-
- -
+
{progressInfo} +
+
+
+
+
); } @@ -75,12 +82,6 @@ var Circle = React.createClass({ }; }, render() { - var statusColorMap = { - 'normal': '#3FC7FA', - 'exception': '#FE8C6A', - 'success': '#85D262' - }; - var props = assign({}, this.props); if (parseInt(props.percent) === 100) { @@ -89,36 +90,31 @@ var Circle = React.createClass({ var style = { 'width': props.width, - 'height': props.width - }; - var wrapStyle = { + 'height': props.width, 'fontSize': props.width * 0.16 + 6 }; - var textStyle = { - 'color': statusColorMap[props.status] - }; var progressInfo; if (props.status === 'exception') { progressInfo = ( - + ); } else if (props.status === 'success') { progressInfo = ( - + ); } else { progressInfo = ( - {props.percent}% + {props.percent}% ); } return ( -
-
+
+
{progressInfo} diff --git a/components/progress/index.md b/components/progress/index.md index dbf6293d9..3e8972335 100644 --- a/components/progress/index.md +++ b/components/progress/index.md @@ -16,15 +16,25 @@ * 当需要显示一个操作完成的百分比时。 -## API +## Progress Circle API | 参数 | 说明 | 类型 | 默认值 | |----------|---------------|----------|-------------| | percent | 百分比 | number | 0 | | status | 状态,有两个值normal、exception | string | normal | -| strokeWidth | 进度条线宽度,单位是进度条画布宽度的百分比 | number | 1 | +| strokeWidth | 进度条线的宽度,单位是进度条画布宽度的百分比 | number | 1 | | width | 必填,进度条画布宽度,单位px。这里没有提供height属性设置,Line型高度就是strokeWidth,Circle型高度等于width | number | null | +## Progress Bar API + +| 参数 | 说明 | 类型 | 默认值 | +|----------|---------------|----------|-------------| +| percent | 百分比 | number | 0 | +| status | 状态,有两个值normal、exception、active三种状态 | string | normal | +| strokeWidth | 进度条线的宽度,单位是px | number | 1 | +| showInfo | 是否显示进度数值和状态图标 | bool | true | + + diff --git a/components/table/filterMenu.jsx b/components/table/filterMenu.jsx index 45e618941..470540951 100644 --- a/components/table/filterMenu.jsx +++ b/components/table/filterMenu.jsx @@ -1,38 +1,47 @@ import React from 'react'; import Menu from 'rc-menu'; -export default React.createClass({ +var FilterMenu = React.createClass({ getInitialState() { return { - selectedFilters: [] + selectedFilters: this.props.selectedFilters }; }, + componentWillReceiveProps(nextProps){ + this.setState({ + selectedFilters: nextProps.selectedFilters + }); + }, getDefaultProps() { return { - handleFilter: function() {}, + handleFilter: function () { + }, column: null }; }, - handleSelectFilter: function(selected) { - this.state.selectedFilters.push(selected); + handleSelectFilter: function (selected) { this.setState({ - selectedFilters: this.state.selectedFilters + selectedFilters: this.state.selectedFilters.concat(selected) }); }, - handleDeselectFilter: function(key) { + handleDeselectFilter: function (key) { var index = this.state.selectedFilters.indexOf(key); if (index !== -1) { - this.state.selectedFilters.splice(index, 1); + var selectedFilters = this.state.selectedFilters.concat(); + selectedFilters.splice(index, 1); + this.setState({ + selectedFilters: selectedFilters + }); } - this.setState({ - selectedFilters: this.state.selectedFilters - }); }, handleClearFilters() { this.setState({ selectedFilters: [] }); }, + handleConfirm(){ + this.props.confirmFilter(this.props.column, this.state.selectedFilters); + }, renderMenus(items) { let menuItems = items.map((item) => { return {item.text}; @@ -41,33 +50,34 @@ export default React.createClass({ }, render() { let column = this.props.column; - column.selectedFilters = this.state.selectedFilters; return + prefixCls="ant-dropdown-menu" + className="ant-table-filter-dropdown" + onSelect={this.handleSelectFilter} + onDeselect={this.handleDeselectFilter} + selectedKeys={this.state.selectedFilters}> {this.renderMenus(column.filters)} + onClick={this.handleConfirm}> 确定 + onClick={this.handleClearFilters}> 清空 ; } }); + +export default FilterMenu; diff --git a/components/table/index.jsx b/components/table/index.jsx index 357d4b56f..e271d88d3 100644 --- a/components/table/index.jsx +++ b/components/table/index.jsx @@ -6,22 +6,33 @@ import Checkbox from '../checkbox'; import FilterMenu from './filterMenu'; import Pagination from '../pagination'; import objectAssign from 'object-assign'; +import equals from 'is-equal-shallow'; + +function noop() { +} + +function defaultResolve(data) { + return data || []; +} export default React.createClass({ getInitialState() { - this.initDataSource(this.props.dataSource); - - let noPagination = (this.props.pagination === false); - let pagination = this.initPagination(this.props.pagination); - return { + // 减少状态 selectedRowKeys: [], - loading: false, - pagination: pagination, - noPagination: noPagination, - data: [] + // only for remote + data: [], + filters: {}, + loading: !this.isLocalDataSource(), + sortColumn: '', + sortOrder: '', + sorter: null, + pagination: this.hasPagination() ? objectAssign({ + pageSize: 10 + }, this.props.pagination) : {} }; }, + getDefaultProps() { return { prefixCls: 'ant-table', @@ -30,44 +41,47 @@ export default React.createClass({ size: 'normal' }; }, + componentWillReceiveProps(nextProps) { - if ('pagination' in nextProps) { - let noPagination = (nextProps.pagination === false); + if (('pagination' in nextProps) && nextProps.pagination !== false) { this.setState({ - pagination: this.initPagination(nextProps.pagination), - noPagination: noPagination + pagination: objectAssign({}, this.state.pagination, nextProps.pagination) }); } - if ('dataSource' in nextProps) { - this.initDataSource(nextProps.dataSource); + if (!this.isLocalDataSource()) { + if (!equals(nextProps, this.props)) { + this.setState({ + selectedRowKeys: [], + loading: true + }, this.fetch); + } + } + if (nextProps.columns !== this.props.columns) { this.setState({ - data: nextProps.dataSource + filters: {} }); } }, - initDataSource(dataSource) { - // 支持两种模式 - if (Array.isArray(dataSource)) { - this.mode = 'local'; - // 保留原来的数据 - this.originDataSource = dataSource.slice(0); - } else { - this.mode = 'remote'; - this.dataSource = objectAssign({ - resolve: function(data) { - return data || []; - }, - getParams: function() {}, - getPagination: function() {} - }, dataSource); + + hasPagination(pagination) { + if (pagination === undefined) { + pagination = this.props.pagination; } + return pagination !== false; }, - initPagination(pagination) { + + isLocalDataSource() { + return Array.isArray(this.props.dataSource); + }, + + getRemoteDataSource() { return objectAssign({ - pageSize: 10, - total: this.props.dataSource.length - }, pagination); + resolve: defaultResolve, + getParams: noop, + getPagination: noop + }, this.props.dataSource); }, + toggleSortOrder(order, column) { let sortColumn = this.state.sortColumn; let sortOrder = this.state.sortOrder; @@ -89,8 +103,8 @@ export default React.createClass({ sortColumn.className = 'ant-table-column-sort'; } } - if (this.mode === 'local') { - sorter = function() { + if (this.isLocalDataSource()) { + sorter = function () { let result = column.sorter.apply(this, arguments); if (sortOrder === 'ascend') { return result; @@ -99,87 +113,101 @@ export default React.createClass({ } }; } - this.setState({ + this.fetch({ sortOrder: sortOrder, sortColumn: sortColumn, sorter: sorter - }, this.fetch); + }); }, - handleFilter(column) { - let columnIndex = this.props.columns.indexOf(column); - let filterFns = []; - if (this.mode === 'local') { - filterFns[columnIndex] = function(record) { - if (column.selectedFilters.length === 0) { - return true; - } - return column.selectedFilters.some(function(value) { - return column.onFilter.call(this, value, record); - }); - }; - } - this.setState({ - filterFns: filterFns - }, this.fetch); + + handleFilter(column, filters) { + filters = objectAssign({}, this.state.filters, { + [this.getColumnKey(column)]: filters + }); + this.fetch({ + selectedRowKeys: [], + filters: filters + }); }, - handleSelect(rowIndex, e) { + + handleSelect(record, rowIndex, e) { let checked = e.target.checked; + let selectedRowKeys = this.state.selectedRowKeys.concat(); + let key = this.getRecordKey(record, rowIndex); if (checked) { - this.state.selectedRowKeys.push(rowIndex); + selectedRowKeys.push(this.getRecordKey(record, rowIndex)); } else { - this.state.selectedRowKeys = this.state.selectedRowKeys.filter(function(i) { - return rowIndex !== i; + selectedRowKeys = selectedRowKeys.filter((i) => { + return key !== i; }); } this.setState({ - selectedRowKeys: this.state.selectedRowKeys + selectedRowKeys: selectedRowKeys }); if (this.props.rowSelection.onSelect) { - let currentRow = this.state.data[rowIndex - 1]; - let selectedRows = this.state.data.filter((row, i) => { - return this.state.selectedRowKeys.indexOf(i + 1) >= 0; + let data = this.getCurrentPageData(); + let selectedRows = data.filter((row, i) => { + return selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0; }); - this.props.rowSelection.onSelect(currentRow, checked, selectedRows); + this.props.rowSelection.onSelect(record, checked, selectedRows); } }, + handleSelectAllRow(e) { let checked = e.target.checked; - let selectedRowKeys = checked ? this.state.data.map(function(item, i) { - return i + 1; - }) : []; + let data = this.getCurrentPageData(); + let selectedRowKeys = checked ? data.map((item, i) => { + return this.getRecordKey(item, i); + }) : []; this.setState({ selectedRowKeys: selectedRowKeys }); if (this.props.rowSelection.onSelectAll) { - let selectedRows = this.state.data.filter((row, i) => { - return selectedRowKeys.indexOf(i + 1) >= 0; + let selectedRows = data.filter((row, i) => { + return selectedRowKeys.indexOf(this.getRecordKey(row, i)) >= 0; }); this.props.rowSelection.onSelectAll(checked, selectedRows); } }, + handlePageChange(current) { - let pagination = this.state.pagination || {}; + let pagination = objectAssign({}, this.state.pagination); if (current) { pagination.current = current; } else { pagination.current = pagination.current || 1; } - this.setState({ + this.fetch({ + // 防止内存泄漏,只维持当页 + selectedRowKeys: [], pagination: pagination - }, this.fetch); + }); }, + renderSelectionCheckBox(value, record, index) { - let rowIndex = index + 1; // 从 1 开始 + let rowIndex = this.getRecordKey(record, index); // 从 1 开始 let checked = this.state.selectedRowKeys.indexOf(rowIndex) >= 0; - return ; + return ; }, + + getRecordKey(record, index) { + return record.key || index; + }, + renderRowSelection() { - var columns = this.props.columns; + let columns = this.props.columns.concat(); if (this.props.rowSelection) { - let checked = this.state.data.every(function(item, i) { - return this.state.selectedRowKeys.indexOf(i + 1) >= 0; - }, this); - let checkboxAll = ; + let data = this.getCurrentPageData(); + let checked; + if (!data.length) { + checked = false; + } else { + checked = data.every((item, i) => { + let key = this.getRecordKey(item, i); + return this.state.selectedRowKeys.indexOf(key) >= 0; + }); + } + let checkboxAll = ; let selectionColumn = { key: 'selection-column', title: checkboxAll, @@ -188,7 +216,7 @@ export default React.createClass({ className: 'ant-table-selection-column' }; if (columns[0] && - columns[0].key === 'selection-column') { + columns[0].key === 'selection-column') { columns[0] = selectionColumn; } else { columns.unshift(selectionColumn); @@ -196,22 +224,31 @@ export default React.createClass({ } return columns; }, - renderColumnsDropdown() { - return this.props.columns.map((column) => { - if (!column.originTitle) { - column.originTitle = column.title; - } + + getCurrentPageData() { + return this.isLocalDataSource() ? this.getLocalDataPaging() : this.state.data; + }, + + getColumnKey(column) { + return column.key || column.dataIndex; + }, + + renderColumnsDropdown(columns) { + return columns.map((column) => { + let key = this.getColumnKey(column); let filterDropdown, menus, sortButton; if (column.filters && column.filters.length > 0) { - column.selectedFilters = column.selectedFilters || []; - menus = ; + let colFilters = this.state.filters[key] || []; + menus = ; let dropdownSelectedClass = ''; - if (column.selectedFilters && column.selectedFilters.length > 0) { + if (colFilters.length > 0) { dropdownSelectedClass = 'ant-table-filter-selected'; } filterDropdown = + closeOnSelect={false} + overlay={menus}> ; } @@ -220,151 +257,195 @@ export default React.createClass({ sortButton =
+ title="升序排序" + onClick={this.toggleSortOrder.bind(this, 'ascend', column)}> + title="降序排序" + onClick={this.toggleSortOrder.bind(this, 'descend', column)}>
; } + if (!column.originalTitle) { + column.originalTitle = column.title; + } column.title = [ - column.originTitle, + column.originalTitle, sortButton, filterDropdown ]; return column; }); }, + renderPagination() { // 强制不需要分页 - if (this.state.noPagination) { - return ''; + if (!this.hasPagination()) { + return null; } let classString = 'ant-table-pagination'; if (this.props.size === 'small') { classString += ' mini'; } + let total; + if (this.isLocalDataSource()) { + total = this.getLocalData().length; + } return ; }, - prepareParamsArguments() { + + prepareParamsArguments(state) { // 准备筛选、排序、分页的参数 let pagination; let filters = {}; let sorter = {}; - pagination = this.state.pagination; - this.props.columns.forEach(function(column) { - if (column.dataIndex && column.selectedFilters && - column.selectedFilters.length > 0) { - filters[column.dataIndex] = column.selectedFilters; + pagination = state.pagination; + this.props.columns.forEach((column) => { + let colFilters = state.filters[this.getColumnKey(column)] || []; + if (colFilters.length > 0) { + filters[this.getColumnKey(column)] = colFilters; } }); - if (this.state.sortColumn && this.state.sortOrder && - this.state.sortColumn.dataIndex) { - sorter.field = this.state.sortColumn.dataIndex; - sorter.order = this.state.sortOrder; + if (state.sortColumn && + state.sortOrder && + state.sortColumn.dataIndex) { + sorter.field = state.sortColumn.dataIndex; + sorter.order = state.sortOrder; } return [pagination, filters, sorter]; }, - fetch() { - if (this.mode === 'remote') { + + fetch(newState) { + if (this.isLocalDataSource()) { + if (newState) { + this.setState(newState); + } + } else { + let state = objectAssign({}, this.state, newState); + if (newState || !this.state.loading) { + this.setState(objectAssign({ + loading: true + }, newState)); + } // remote 模式使用 this.dataSource - let dataSource = this.dataSource; - this.setState({ - loading: true - }); + let dataSource = this.getRemoteDataSource(); jQuery.ajax({ url: dataSource.url, - data: dataSource.getParams.apply(this, this.prepareParamsArguments()) || {}, + data: dataSource.getParams.apply(this, this.prepareParamsArguments(state)) || {}, headers: dataSource.headers, dataType: 'json', success: (result) => { if (this.isMounted()) { let pagination = objectAssign( - this.state.pagination, + state.pagination, dataSource.getPagination.call(this, result) ); this.setState({ + loading: false, data: dataSource.resolve.call(this, result), - pagination: pagination, - loading: false + pagination: pagination }); } }, error: () => { this.setState({ - loading: false + loading: false, + data: [] }); } }); - } else { - let data = this.props.dataSource; - let current, pageSize; - // 如果没有分页的话,默认全部展示 - if (this.state.noPagination) { - pageSize = Number.MAX_VALUE; - current = 1; - } else { - pageSize = this.state.pagination.pageSize; - current = this.state.pagination.current; - } - // 排序 - if (this.state.sortOrder && this.state.sorter) { - data = data.sort(this.state.sorter); - } else { - data = this.originDataSource.slice(); - } - // 筛选 - if (this.state.filterFns) { - this.state.filterFns.forEach(function(filterFn) { - if (typeof filterFn === 'function') { - data = data.filter(filterFn); - } - }); - } - // 分页 - // --- - // 当数据量少于每页数量时,直接设置数据 - // 否则进行读取分页数据 - 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 - }); } }, - componentDidMount() { - this.handlePageChange(); - }, - render() { - this.props.columns = this.renderRowSelection(); - var classString = ''; - if (this.state.loading) { + findColumn(myKey) { + return this.props.columns.filter((c) => { + return this.getColumnKey(c) === myKey; + })[0]; + }, + + getLocalDataPaging() { + let data = this.getLocalData(); + let current, pageSize; + let state = this.state; + // 如果没有分页的话,默认全部展示 + if (!this.hasPagination()) { + pageSize = Number.MAX_VALUE; + current = 1; + } else { + pageSize = state.pagination.pageSize; + current = state.pagination.current; + } + // 分页 + // --- + // 当数据量少于每页数量时,直接设置数据 + // 否则进行读取分页数据 + if (data.length > pageSize || pageSize === Number.MAX_VALUE) { + data = data.filter((item, i) => { + if (i >= (current - 1) * pageSize && + i < current * pageSize) { + return item; + } + }); + } + return data; + }, + + getLocalData() { + let state = this.state; + let data = this.props.dataSource; + // 排序 + if (state.sortOrder && state.sorter) { + data = data.sort(state.sorter); + } + // 筛选 + if (state.filters) { + Object.keys(state.filters).forEach((columnKey) => { + let col = this.findColumn(columnKey); + let values = state.filters[columnKey] || []; + if (values.length === 0) { + return; + } + data = data.filter((record) => { + return values.some((v)=> { + return col.onFilter(v, record); + }); + }); + }); + } + return data; + }, + + componentDidMount() { + if (!this.isLocalDataSource()) { + this.fetch(); + } + }, + + render() { + let data = this.getCurrentPageData(); + let columns = this.renderRowSelection(); + let classString = ''; + if (this.state.loading && this.isLocalDataSource()) { classString += ' ant-table-loading'; } if (this.props.size === 'small') { classString += ' ant-table-small'; } - + columns = this.renderColumnsDropdown(columns); return
- +
{this.renderPagination()} ; } diff --git a/components/tag/demo/basic.md b/components/tag/demo/basic.md new file mode 100644 index 000000000..a5ba2d374 --- /dev/null +++ b/components/tag/demo/basic.md @@ -0,0 +1,22 @@ +# 基本 + +- order: 0 + +简单的标签展示,添加 closable 表示可关闭。 + +--- + +````jsx +var Tag = antd.Tag; + +function onClose(e) { + console.log(this.props.children); +} + +React.render(
+ 标签一 + 标签二 + 标签三 + 标签四(链接) +
, document.getElementById('components-tag-demo-basic')); +```` diff --git a/components/tag/demo/colorful.md b/components/tag/demo/colorful.md new file mode 100644 index 000000000..b387c25cb --- /dev/null +++ b/components/tag/demo/colorful.md @@ -0,0 +1,19 @@ +# 各种类型 + +四种颜色的标签。 + +- order: 1 + +--- + +````jsx +var Tag = antd.Tag; + +React.render(
+ 蓝色 + 绿色 + 黄色 + 红色 +
, document.getElementById('components-tag-demo-colorful')); +```` + diff --git a/components/tag/index.jsx b/components/tag/index.jsx new file mode 100644 index 000000000..ab3c57854 --- /dev/null +++ b/components/tag/index.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +const prefixCls = 'ant-tag'; + +class AntTag extends React.Component { + constructor(props) { + super(props); + + this.state = { + closed: false + }; + } + close(e) { + this.setState({ + closed: true + }); + this.props.onClose.call(this, e); + } + render() { + let close = this.props.closable ? + : ''; + let colorClass = this.props.prefixCls + '-' + this.props.color; + + return this.state.closed ? null : ; + } +} + +AntTag.defaultProps = { + prefixCls: prefixCls, + closable: false, + onClose: function() {} +}; + +export default AntTag; diff --git a/components/tag/index.md b/components/tag/index.md index 5a2d7fde2..6261d1372 100644 --- a/components/tag/index.md +++ b/components/tag/index.md @@ -4,3 +4,19 @@ - chinese: 标签 --- + +进行标记和分类的小标签。 + +## 何时使用 + +- 用于标记事物的属性和维度。 +- 进行分类。 + +## API + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +|----------------|--------------------------------|------------|---------|--------| +| href | 链接的地址,会传给 a 标签 | string | | false | +| closable | 标签是否可以关闭 | boolean | | false | +| onClose | 组合时根据此项判定checked | function | | 无 | +| color | 标签的色彩 | string | blue green yellow red | 无 | diff --git a/index.js b/index.js index f21dc4ba1..a3eab3171 100644 --- a/index.js +++ b/index.js @@ -19,6 +19,7 @@ var antd = { Switch: require('./components/switch'), Checkbox: require('./components/checkbox'), Table: require('./components/table'), + Tag: require('./components/tag'), Collapse: require('./components/collapse'), message: require('./components/message'), Slider: require('./components/slider'), diff --git a/package.json b/package.json index f320d2c4e..85da62702 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "antd", - "version": "0.7.3-beta6", - "stableVersion": "0.7.2", + "version": "0.8.0-beta1", + "stableVersion": "0.7.3", "title": "Ant Design", "description": "一个设计语言&前端框架", "homepage": "http://ant.design/", @@ -35,6 +35,7 @@ "enter-animation": "~0.1.3", "gregorian-calendar": "~3.0.0", "gregorian-calendar-format": "~3.0.1", + "is-equal-shallow": "~0.1.3", "object-assign": "~3.0.0", "rc-calendar": "~3.11.0", "rc-checkbox": "~1.0.6", diff --git a/scripts/demo.js b/scripts/demo.js index 7994f981e..302a55521 100644 --- a/scripts/demo.js +++ b/scripts/demo.js @@ -18,7 +18,7 @@ $(function () { return ; }); }, @@ -34,12 +34,11 @@ $(function () { }, render() { - return ; } }); diff --git a/site/templates/layout.html b/site/templates/layout.html index 60276c01a..d6082bead 100644 --- a/site/templates/layout.html +++ b/site/templates/layout.html @@ -78,7 +78,7 @@ {% block scripts %}{% endblock %} -