This commit is contained in:
Boyuzhou 2017-01-11 17:01:50 +08:00
parent c23e4597ca
commit c41fd2efe6
20 changed files with 790 additions and 1111 deletions

View File

@ -3,8 +3,51 @@
@import "../node_modules/bee-layout/src/Layout.scss"; @import "../node_modules/bee-layout/src/Layout.scss";
@import "../node_modules/bee-button/src/Button.scss"; @import "../node_modules/bee-button/src/Button.scss";
@import "../node_modules/bee-transition/src/Transition.scss"; @import "../node_modules/bee-transition/src/Transition.scss";
@import "../src/animation.scss";
@import "../src/bordered.scss";
@import "../src/index.scss"; @import "../src/index.scss";
@import "../node_modules/bee-dropdown/src/Dropdown.scss"; @import "../node_modules/bee-dropdown/src/Dropdown.scss";
@import "../node_modules/bee-menus/src/Menus.scss"; @import "../node_modules/bee-menus/src/Menus.scss";
@import "../node_modules/bee-popconfirm/src/Popconfirm.scss";
@import "../node_modules/bee-form-control/src/FormControl.scss";
.editable-cell {
position: relative;
}
.editable-cell-input-wrapper,
.editable-cell-text-wrapper {
padding-right: 24px;
}
.editable-cell-text-wrapper {
padding: 5px 24px 5px 5px;
}
.editable-cell-icon,
.editable-cell-icon-check {
position: absolute;
right: 0;
width: 20px;
cursor: pointer;
}
.editable-cell-icon {
line-height: 18px;
display: none;
}
.editable-cell-icon-check {
line-height: 28px;
}
.editable-cell:hover .editable-cell-icon {
display: inline-block;
}
.editable-cell-icon:hover,
.editable-cell-icon-check:hover {
color:#2db7f5;
}
.editable-add-btn {
margin-bottom: 8px;
}

View File

@ -1,67 +1,36 @@
/** /**
* *
* @title 这是标题 * @title 简单表格
* @description 这是描述 * @description
* *
*/ */
class Demo1 extends React.Component {
constructor(props) {
super(props);
this.columns = [
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
{ id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
{
title: 'Operations', dataIndex: '', key: 'd', render: (text, record) =>
<a onClick={e => this.onDelete(record.key, e)} href="#">Delete</a>,
},
];
this.state = {
data: [
{ a: '123', key: '1' },
{ a: 'cdd', b: 'edd', key: '2' },
{ a: '1333', c: 'eee', key: '3' },
],
};
}
onDelete(key, e) { const columns = [
console.log('Delete', key); { title: '用户名', dataIndex: 'a', key: 'a', width: 100 },
e.preventDefault(); { id: '123', title: '性别', dataIndex: 'b', key: 'b', width: 100 },
const data = this.state.data.filter(item => item.key !== key); { title: '年龄', dataIndex: 'c', key: 'c', width: 200 },
this.setState({ data }); {
} title: '操作', dataIndex: '', key: 'd', render() {
return <a href="#">一些操作</a>;
},
},
];
onAdd() { const data = [
const data = [...this.state.data]; { a: '令狐冲', b: '男', c: 41, key: '1' },
data.push({ { a: '杨过', b: '男', c: 67, key: '2' },
a: 'new data', { a: '郭靖', b: '男', c: 25, key: '3' },
b: 'new data', ];
c: 'new data',
key: Date.now(),
});
this.setState({ data });
}
getBodyWrapper(body) { class Demo1 extends Component {
return ( render () {
<Animate transitionName="move" component="tbody" className={body.props.className}> return (
{body.props.children} <Table
</Animate> columns={columns}
); data={data}
} title={currentData => <div>标题: {currentData.length} 个元素</div>}
footer={currentData => <div>表尾: {currentData.length} 个元素</div>}
render() { />
return ( )
<div style={{ margin: 20 }}> }
<h2>Table row with animation</h2>
<button onClick={() => this.onAdd()}>添加</button>
<Table
columns={this.columns}
data={this.state.data}
getBodyWrapper={this.getBodyWrapper}
/>
</div>
);
}
} }

View File

@ -5,86 +5,166 @@
* *
*/ */
const columns1 = [{ class EditableCell extends React.Component {
title: 'Name', state = {
dataIndex: 'name', value: this.props.value,
key: 'name', editable: false,
width: 400, }
}, { handleChange = (e) => {
title: 'Age', const value = e.target.value;
dataIndex: 'age', this.setState({ value });
key: 'age', }
width: 100, check = () => {
}, { this.setState({ editable: false });
title: 'Address', if (this.props.onChange) {
dataIndex: 'address', this.props.onChange(this.state.value);
key: 'address',
width: 200,
}, {
title: 'Operations',
dataIndex: 'operation',
key: 'x',
width: 150,
}];
const data1 = [{
key: 1,
name: 'a',
age: 32,
address: 'I am a',
children: [{
key: 11,
name: 'aa',
age: 33,
address: 'I am aa',
}, {
key: 12,
name: 'ab',
age: 33,
address: 'I am ab',
children: [{
key: 121,
name: 'aba',
age: 33,
address: 'I am aba',
}],
}, {
key: 13,
name: 'ac',
age: 33,
address: 'I am ac',
children: [{
key: 131,
name: 'aca',
age: 33,
address: 'I am aca',
children: [{
key: 1311,
name: 'acaa',
age: 33,
address: 'I am acaa',
}, {
key: 1312,
name: 'acab',
age: 33,
address: 'I am acab',
}],
}],
}],
}, {
key: 2,
name: 'b',
age: 32,
address: 'I am b',
}];
function onExpand(expanded, record) {
console.log('onExpand', expanded, record);
}
class Demo2 extends Component {
render () {
return (
<Table defaultExpandAllRows columns={columns1} data={data1} indentSize={30} onExpand={onExpand} />
)
} }
}
edit = () => {
this.setState({ editable: true });
}
handleKeydown = (event) => {
console.log(event);
if(event.keyCode == 13){
this.check();
}
}
render() {
const { value, editable } = this.state;
return (<div className="editable-cell">
{
editable ?
<div className="editable-cell-input-wrapper">
<Input
value={value}
onChange={this.handleChange}
onKeyDown = {this.handleKeydown}
/>
<Icon
type="uf-correct"
className="editable-cell-icon-check"
onClick={this.check}
/>
</div>
:
<div className="editable-cell-text-wrapper">
{value || ' '}
<Icon
type="uf-pencil"
className="editable-cell-icon"
onClick={this.edit}
/>
</div>
}
</div>);
}
}
class Demo2 extends React.Component {
constructor(props) {
super(props);
this.columns = [{
title: '姓名',
dataIndex: 'name',
key:'name',
width: '30%',
render: (text, record, index) => (
<EditableCell
value={text}
onChange={this.onCellChange(index, 'name')}
/>
),
}, {
title: '年龄',
dataIndex: 'age',
key:'age',
}, {
title: '你懂的',
dataIndex: 'address',
key:'address',
}, {
title: '操作',
dataIndex: 'operation',
key: 'operation',
render: (text, record, index) => {
return (
this.state.dataSource.length > 1 ?
(
<Popconfirm content="确认删除?" id='aa' onClose={this.onDelete(index)}>
<Icon type="uf-del"></Icon>
</Popconfirm>
) : null
);
},
}];
this.state = {
dataSource: [{
key: '0',
name: '沉鱼',
age: '18',
address: '96, 77, 89',
}, {
key: '1',
name: '落雁',
age: '16',
address: '90, 70, 80',
}, {
key: '2',
name: '闭月',
age: '17',
address: '80, 60, 80',
}, {
key: '3',
name: '羞花',
age: '20',
address: '120, 60, 90',
}],
count: 4,
};
}
onCellChange = (index, key) => {
return (value) => {
const dataSource = [...this.state.dataSource];
dataSource[index][key] = value;
this.setState({ dataSource });
};
}
onDelete = (index) => {
return () => {
const dataSource = [...this.state.dataSource];
dataSource.splice(index, 1);
this.setState({ dataSource });
};
}
handleAdd = () => {
const { count, dataSource } = this.state;
const newData = {
key: count,
name: `凤姐 ${count}`,
age: 32,
address: `100 100 100`,
};
this.setState({
dataSource: [...dataSource, newData],
count: count + 1,
});
}
getBodyWrapper = (body) => {
return (
<Animate transitionName="move" component="tbody" className={body.props.className}>
{body.props.children}
</Animate>
);
}
render() {
const { dataSource } = this.state;
const columns = this.columns;
return (<div>
<Button className="editable-add-btn" type="ghost" onClick={this.handleAdd}>添加</Button>
<Table bordered data={dataSource} columns={columns} getBodyWrapper={this.getBodyWrapper} />
</div>);
}
} }

View File

@ -1,49 +0,0 @@
/**
*
* @title 这是标题
* @description 这是描述
*
*/
const columns2 = [
{ title: 'title1', dataIndex: 'a',
className: 'a',
key: 'a', width: 100 },
{ id: '123', title: 'title2', dataIndex: 'b',
className: 'b',
key: 'b', width: 100 },
{ title: 'title3', dataIndex: 'c',
className: 'c',
key: 'c', width: 200 },
{
title: 'Operations', dataIndex: '',
className: 'd',
key: 'd', render() {
return <a href="#">Operations</a>;
},
},
];
const data2 = [
{ a: '123', key: '1' },
{ a: 'cdd', b: 'edd', key: '2' },
{ a: '1333', c: 'eee', d: 2, key: '3' },
];
class Demo3 extends Component {
render () {
return (
<div>
<h2>rowClassName and className</h2>
<Table
columns={columns2}
rowClassName={(record, i) => `row-${i}`}
expandedRowRender={record => <p>extra: {record.a}</p>}
expandedRowClassName={(record, i) => `ex-row-${i}`}
data={data2}
className="table"
/>
</div>
)
}
}

View File

@ -1,112 +0,0 @@
/**
*
* @title 这是标题
* @description 这是描述
*
*/
const columns3 = [
{ title: '手机号', dataIndex: 'a', colSpan: 2, width: 100, key: 'a', render(o, row, index) {
const obj = {
children: o,
props: {},
};
// 设置第一行为链接
if (index === 0) {
obj.children = <a href="#">{o}</a>;
}
// 第5行合并两列
if (index === 4) {
obj.props.colSpan = 2;
}
if (index === 5) {
obj.props.colSpan = 6;
}
return obj;
} },
{ title: '电话', dataIndex: 'b', colSpan: 0, width: 100, key: 'b', render(o, row, index) {
const obj = {
children: o,
props: {},
};
// 列合并掉的表格设置colSpan=0不会去渲染
if (index === 4 || index === 5) {
obj.props.colSpan = 0;
}
return obj;
} },
{ title: 'Name', dataIndex: 'c', width: 100, key: 'c', render(o, row, index) {
const obj = {
children: o,
props: {},
};
if (index === 5) {
obj.props.colSpan = 0;
}
return obj;
} },
{ title: 'Address', dataIndex: 'd', width: 200, key: 'd', render(o, row, index) {
const obj = {
children: o,
props: {},
};
if (index === 0) {
obj.props.rowSpan = 2;
}
if (index === 1 || index === 5) {
obj.props.rowSpan = 0;
}
return obj;
} },
{ title: 'Gender', dataIndex: 'e', width: 200, key: 'e', render(o, row, index) {
const obj = {
children: o,
props: {},
};
if (index === 5) {
obj.props.colSpan = 0;
}
return obj;
} },
{
title: 'Operations', dataIndex: '', key: 'f',
render(o, row, index) {
if (index === 5) {
return {
props: {
colSpan: 0,
},
};
}
return <a href="#">Operations</a>;
},
},
];
const data3 = [
{ a: '13812340987', b: '0571-12345678', c: '张三', d: '文一西路', e: 'Male', key: '1' },
{ a: '13812340986', b: '0571-98787658', c: '张夫人', d: '文一西路', e: 'Female', key: '2' },
{ a: '13812988888', b: '0571-099877', c: '李四', d: '文二西路', e: 'Male', key: '3' },
{ a: '1381200008888', b: '0571-099877', c: '王五', d: '文二西路', e: 'Male', key: '4' },
{ a: '0571-88888110', c: '李警官', d: '武林门', e: 'Male', key: '5' },
{ a: '资料统计完毕于xxxx年xxx月xxx日', key: '6' },
];
class Demo4 extends Component {
render () {
return (
<div>
<h2>colSpan & rowSpan</h2>
<Table
columns={columns3}
data={data3}
className="table"
/>
</div>
)
}
}

View File

@ -1,102 +0,0 @@
/**
*
* @title 这是标题
* @description 这是描述
*
*/
const data = [];
for (let i = 0; i < 10; i++) {
data.push({
key: i,
a: `a${i}`,
b: `b${i}`,
c: `c${i}`,
});
}
const Demo5 = React.createClass({
getInitialState() {
this.filters = [];
return {
visible: false,
};
},
handleVisibleChange(visible) {
this.setState({ visible });
},
handleSelect(selected) {
this.filters.push(selected);
},
handleDeselect(key) {
const index = this.filters.indexOf(key);
if (index !== -1) {
this.filters.splice(index, 1);
}
},
confirmFilter() {
console.log(this.filters.join(','));
this.setState({
visible: false,
});
},
render() {
const menu = (
<Menu
style={{ width: 200 }}
multiple
onSelect={this.handleSelect}
onDeselect={this.handleDeselect}
>
<Item key="1">one</Item>
<Item key="2">two</Item>
<Item key="3">three</Item>
<Divider />
<Item disabled>
<button
style={{
cursor: 'pointer',
color: '#000',
pointerEvents: 'visible',
}}
onClick={this.confirmFilter}
>确定</button>
</Item>
</Menu>
);
const columns = [
{
title: (
<div>
title1
<DropDown
trigger={['click']}
onVisibleChange={this.handleVisibleChange}
visible={this.state.visible}
overlay={menu}
>
<a href="#">filter</a>
</DropDown>
</div>
), key: 'a', dataIndex: 'a', width: 100,
},
{ title: 'title2', key: 'b', dataIndex: 'b', width: 100 },
{ title: 'title3', key: 'c', dataIndex: 'c', width: 200 },
];
return (
<Table
columns={columns}
data={data}
rowKey={record => record.key}
/>
);
},
});

View File

@ -8,11 +8,13 @@ import Table from '../src';
import Animate from 'bee-animate'; import Animate from 'bee-animate';
import Menu, { Item, Divider } from 'bee-menus'; import Menu, { Item, Divider } from 'bee-menus';
import DropDown from 'bee-dropdown'; import DropDown from 'bee-dropdown';
import Icon from "bee-icon";
import Input from 'bee-form-control';
import Popconfirm from 'bee-popconfirm';
const CARET = <i className="uf uf-arrow-down"></i>;
const CARET = <i className="uf uf-chevronarrowdown"></i>; const CARETUP = <i className="uf uf-arrow-up"></i>;
const CARETUP = <i className="uf uf-chevronarrowup"></i>;
{demolist} {demolist}
@ -42,14 +44,9 @@ class Demo extends Component {
); );
const header = ( const header = (
<Row> <Row>
<Col md={11}> <Col md={12}>
{ example } { example }
</Col> </Col>
<Col md={1}>
<Button shape="icon" onClick={ this.handleClick }>
{ caret }
</Button>
</Col>
</Row> </Row>
); );
return ( return (

File diff suppressed because one or more lines are too long

View File

@ -41,18 +41,19 @@
"warning": "^3.0.0" "warning": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"bee-animate": "0.0.3", "bee-animate": "latest",
"bee-button": "latest", "bee-button": "latest",
"bee-dropdown": "^0.1.4", "bee-form-control": "^0.1.7",
"bee-icon": "0.0.5",
"bee-layout": "latest", "bee-layout": "latest",
"bee-menus": "0.0.5",
"bee-panel": "latest", "bee-panel": "latest",
"bee-popconfirm": "^0.2.1",
"chai": "^3.5.0", "chai": "^3.5.0",
"console-polyfill": "~0.2.1", "console-polyfill": "~0.2.1",
"enzyme": "^2.4.1", "enzyme": "^2.4.1",
"es5-shim": "~4.1.10", "es5-shim": "~4.1.10",
"react": "~0.14.0", "react": "15.3.2",
"react-addons-test-utils": "15.3.2", "react-addons-test-utils": "15.3.2",
"react-dom": "~0.14.0" "react-dom": "15.3.2"
} }
} }

View File

@ -2,6 +2,8 @@ import React from 'react';
import Column from './Column'; import Column from './Column';
import ColumnGroup from './ColumnGroup'; import ColumnGroup from './ColumnGroup';
//行控制管理
export default class ColumnManager { export default class ColumnManager {
_cached = {} _cached = {}

View File

@ -1,33 +1,39 @@
import React, { PropTypes } from 'react'; import React, { PropTypes, Component } from 'react';
import shallowequal from 'shallowequal'; import shallowequal from 'shallowequal';
const ExpandIcon = React.createClass({ const propTypes = {
propTypes: {
record: PropTypes.object, record: PropTypes.object,
prefixCls: PropTypes.string, clsPrefix: PropTypes.string,
expandable: PropTypes.any, expandable: PropTypes.any,
expanded: PropTypes.bool, expanded: PropTypes.bool,
needIndentSpaced: PropTypes.bool, needIndentSpaced: PropTypes.bool,
onExpand: PropTypes.func, onExpand: PropTypes.func,
}, };
class ExpandIcon extends Component{
constructor(props){
super(props);
}
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
return !shallowequal(nextProps, this.props); return !shallowequal(nextProps, this.props);
}, }
render() { render() {
const { expandable, prefixCls, onExpand, needIndentSpaced, expanded, record } = this.props; const { expandable, clsPrefix, onExpand, needIndentSpaced, expanded, record } = this.props;
if (expandable) { if (expandable) {
const expandClassName = expanded ? 'expanded' : 'collapsed'; const expandClassName = expanded ? 'expanded' : 'collapsed';
return ( return (
<span <span
className={`${prefixCls}-expand-icon ${prefixCls}-${expandClassName}`} className={`${clsPrefix}-expand-icon ${clsPrefix}-${expandClassName}`}
onClick={(e) => onExpand(!expanded, record, e)} onClick={(e) => onExpand(!expanded, record, e)}
/> />
); );
} else if (needIndentSpaced) { } else if (needIndentSpaced) {
return <span className={`${prefixCls}-expand-icon ${prefixCls}-spaced`} />; return <span className={`${clsPrefix}-expand-icon ${clsPrefix}-spaced`} />;
} }
return null; return null;
}, }
}); };
ExpandIcon.propTypes = propTypes;
export default ExpandIcon; export default ExpandIcon;

View File

@ -1,4 +1,4 @@
import React, { PropTypes } from 'react'; import React, { PropTypes, Component } from 'react';
import TableRow from './TableRow'; import TableRow from './TableRow';
import TableHeader from './TableHeader'; import TableHeader from './TableHeader';
import { measureScrollbar, debounce, warningOnce } from './utils'; import { measureScrollbar, debounce, warningOnce } from './utils';
@ -7,8 +7,7 @@ import addEventListener from 'rc-util/lib/Dom/addEventListener';
import ColumnManager from './ColumnManager'; import ColumnManager from './ColumnManager';
import createStore from './createStore'; import createStore from './createStore';
const Table = React.createClass({ const propTypes = {
propTypes: {
data: PropTypes.array, data: PropTypes.array,
expandIconAsCell: PropTypes.bool, expandIconAsCell: PropTypes.bool,
defaultExpandAllRows: PropTypes.bool, defaultExpandAllRows: PropTypes.bool,
@ -16,9 +15,10 @@ const Table = React.createClass({
defaultExpandedRowKeys: PropTypes.array, defaultExpandedRowKeys: PropTypes.array,
useFixedHeader: PropTypes.bool, useFixedHeader: PropTypes.bool,
columns: PropTypes.array, columns: PropTypes.array,
prefixCls: PropTypes.string, clsPrefix: PropTypes.string,
bodyStyle: PropTypes.object, bodyStyle: PropTypes.object,
style: PropTypes.object, style: PropTypes.object,
//特殊的渲染规则的key值
rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
rowClassName: PropTypes.func, rowClassName: PropTypes.func,
expandedRowClassName: PropTypes.func, expandedRowClassName: PropTypes.func,
@ -29,6 +29,7 @@ const Table = React.createClass({
onRowClick: PropTypes.func, onRowClick: PropTypes.func,
onRowDoubleClick: PropTypes.func, onRowDoubleClick: PropTypes.func,
expandIconColumnIndex: PropTypes.number, expandIconColumnIndex: PropTypes.number,
//是否显示表头
showHeader: PropTypes.bool, showHeader: PropTypes.bool,
title: PropTypes.func, title: PropTypes.func,
footer: PropTypes.func, footer: PropTypes.func,
@ -37,61 +38,87 @@ const Table = React.createClass({
rowRef: PropTypes.func, rowRef: PropTypes.func,
getBodyWrapper: PropTypes.func, getBodyWrapper: PropTypes.func,
children: PropTypes.node, children: PropTypes.node,
}, };
getDefaultProps() { const defaultProps = {
return { data: [],
data: [], useFixedHeader: false,
useFixedHeader: false, expandIconAsCell: false,
expandIconAsCell: false, defaultExpandAllRows: false,
defaultExpandAllRows: false, defaultExpandedRowKeys: [],
defaultExpandedRowKeys: [], rowKey: 'key',
rowKey: 'key', rowClassName: () => '',
rowClassName: () => '', expandedRowClassName: () => '',
expandedRowClassName: () => '', onExpand() {},
onExpand() {}, onExpandedRowsChange() {},
onExpandedRowsChange() {}, onRowClick() {},
onRowClick() {}, onRowDoubleClick() {},
onRowDoubleClick() {}, clsPrefix: 'u-table',
prefixCls: 'u-table', bodyStyle: {},
bodyStyle: {}, style: {},
style: {}, childrenColumnName: 'children',
childrenColumnName: 'children', indentSize: 15,
indentSize: 15, expandIconColumnIndex: 0,
expandIconColumnIndex: 0, showHeader: true,
showHeader: true, scroll: {},
scroll: {}, rowRef: () => null,
rowRef: () => null, getBodyWrapper: body => body,
getBodyWrapper: body => body, emptyText: () => 'No Data',
emptyText: () => 'No Data', };
};
},
getInitialState() { class Table extends Component{
const props = this.props; constructor(props){
let expandedRowKeys = []; super(props);
let rows = [...props.data]; let expandedRowKeys = [];
this.columnManager = new ColumnManager(props.columns, props.children); let rows = [...props.data];
this.store = createStore({ currentHoverKey: null }); this.columnManager = new ColumnManager(props.columns, props.children);
this.store = createStore({ currentHoverKey: null });
if (props.defaultExpandAllRows) { if (props.defaultExpandAllRows) {
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {
const row = rows[i]; const row = rows[i];
expandedRowKeys.push(this.getRowKey(row, i)); expandedRowKeys.push(this.getRowKey(row, i));
rows = rows.concat(row[props.childrenColumnName] || []); rows = rows.concat(row[props.childrenColumnName] || []);
}
} else {
expandedRowKeys = props.expandedRowKeys || props.defaultExpandedRowKeys;
} }
} else { this.state = {
expandedRowKeys = props.expandedRowKeys || props.defaultExpandedRowKeys; expandedRowKeys,
} data: props.data,
return { currentHoverKey: null,
expandedRowKeys, scrollPosition: 'left',
data: props.data, fixedColumnsHeadRowsHeight: [],
currentHoverKey: null, fixedColumnsBodyRowsHeight: [],
scrollPosition: 'left', }
fixedColumnsHeadRowsHeight: [],
fixedColumnsBodyRowsHeight: [], this.onExpandedRowsChange = this.onExpandedRowsChange.bind(this);
}; this.onExpanded = this.onExpanded.bind(this);
}, this.onRowDestroy = this.onRowDestroy.bind(this);
this.getRowKey = this.getRowKey.bind(this);
this.getExpandedRows = this.getExpandedRows.bind(this);
this.getHeader = this.getHeader.bind(this);
this.getHeaderRows = this.getHeaderRows.bind(this);
this.getExpandedRow = this.getExpandedRow.bind(this);
this.getRowsByData = this.getRowsByData.bind(this);
this.getRows = this.getRows.bind(this);
this.getColGroup = this.getColGroup.bind(this);
this.getLeftFixedTable = this.getLeftFixedTable.bind(this);
this.getRightFixedTable = this.getRightFixedTable.bind(this);
this.getTable = this.getTable.bind(this);
this.getTitle = this.getTitle.bind(this);
this.getFooter = this.getFooter.bind(this);
this.getEmptyText = this.getEmptyText.bind(this);
this.getHeaderRowStyle = this.getHeaderRowStyle.bind(this);
this.syncFixedTableRowHeight = this.syncFixedTableRowHeight.bind(this);
this.resetScrollY = this.resetScrollY.bind(this);
this.findExpandedRow = this.findExpandedRow.bind(this);
this.isRowExpanded = this.isRowExpanded.bind(this);
this.detectScrollTarget = this.detectScrollTarget.bind(this);
this.handleBodyScroll = this.handleBodyScroll.bind(this);
this.handleRowHover = this.handleRowHover.bind(this);
}
componentDidMount() { componentDidMount() {
this.resetScrollY(); this.resetScrollY();
@ -101,7 +128,7 @@ const Table = React.createClass({
window, 'resize', debounce(this.syncFixedTableRowHeight, 150) window, 'resize', debounce(this.syncFixedTableRowHeight, 150)
); );
} }
}, }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if ('data' in nextProps) { if ('data' in nextProps) {
@ -122,24 +149,24 @@ const Table = React.createClass({
} else if (nextProps.children !== this.props.children) { } else if (nextProps.children !== this.props.children) {
this.columnManager.reset(null, nextProps.children); this.columnManager.reset(null, nextProps.children);
} }
}, }
componentDidUpdate() { componentDidUpdate() {
this.syncFixedTableRowHeight(); this.syncFixedTableRowHeight();
}, }
componentWillUnmount() { componentWillUnmount() {
if (this.resizeEvent) { if (this.resizeEvent) {
this.resizeEvent.remove(); this.resizeEvent.remove();
} }
}, }
onExpandedRowsChange(expandedRowKeys) { onExpandedRowsChange(expandedRowKeys) {
if (!this.props.expandedRowKeys) { if (!this.props.expandedRowKeys) {
this.setState({ expandedRowKeys }); this.setState({ expandedRowKeys });
} }
this.props.onExpandedRowsChange(expandedRowKeys); this.props.onExpandedRowsChange(expandedRowKeys);
}, }
onExpanded(expanded, record, e, index) { onExpanded(expanded, record, e, index) {
if (e) { if (e) {
@ -155,7 +182,7 @@ const Table = React.createClass({
this.onExpandedRowsChange(expandedRows); this.onExpandedRowsChange(expandedRows);
} }
this.props.onExpand(expanded, record); this.props.onExpand(expanded, record);
}, }
onRowDestroy(record, rowIndex) { onRowDestroy(record, rowIndex) {
const expandedRows = this.getExpandedRows().concat(); const expandedRows = this.getExpandedRows().concat();
@ -170,7 +197,7 @@ const Table = React.createClass({
expandedRows.splice(index, 1); expandedRows.splice(index, 1);
} }
this.onExpandedRowsChange(expandedRows); this.onExpandedRowsChange(expandedRows);
}, }
getRowKey(record, index) { getRowKey(record, index) {
const rowKey = this.props.rowKey; const rowKey = this.props.rowKey;
@ -182,20 +209,20 @@ const Table = React.createClass({
'or set `rowKey` to an unique primary key.' 'or set `rowKey` to an unique primary key.'
); );
return key; return key;
}, }
getExpandedRows() { getExpandedRows() {
return this.props.expandedRowKeys || this.state.expandedRowKeys; return this.props.expandedRowKeys || this.state.expandedRowKeys;
}, }
getHeader(columns, fixed) { getHeader(columns, fixed) {
const { showHeader, expandIconAsCell, prefixCls } = this.props; const { showHeader, expandIconAsCell, clsPrefix } = this.props;
const rows = this.getHeaderRows(columns); const rows = this.getHeaderRows(columns);
if (expandIconAsCell && fixed !== 'right') { if (expandIconAsCell && fixed !== 'right') {
rows[0].unshift({ rows[0].unshift({
key: 'rc-table-expandIconAsCell', key: 'rc-table-expandIconAsCell',
className: `${prefixCls}-expand-icon-th`, className: `${clsPrefix}-expand-icon-th`,
title: '', title: '',
rowSpan: rows.length, rowSpan: rows.length,
}); });
@ -205,12 +232,12 @@ const Table = React.createClass({
return showHeader ? ( return showHeader ? (
<TableHeader <TableHeader
prefixCls={prefixCls} clsPrefix={clsPrefix}
rows={rows} rows={rows}
rowStyle={trStyle} rowStyle={trStyle}
/> />
) : null; ) : null;
}, }
getHeaderRows(columns, currentRow = 0, rows) { getHeaderRows(columns, currentRow = 0, rows) {
rows = rows || []; rows = rows || [];
@ -241,10 +268,10 @@ const Table = React.createClass({
} }
}); });
return rows.filter(row => row.length > 0); return rows.filter(row => row.length > 0);
}, }
getExpandedRow(key, content, visible, className, fixed) { getExpandedRow(key, content, visible, className, fixed) {
const { prefixCls, expandIconAsCell } = this.props; const { clsPrefix, expandIconAsCell } = this.props;
let colCount; let colCount;
if (fixed === 'left') { if (fixed === 'left') {
colCount = this.columnManager.leftLeafColumns().length; colCount = this.columnManager.leftLeafColumns().length;
@ -274,13 +301,13 @@ const Table = React.createClass({
visible={visible} visible={visible}
className={className} className={className}
key={`${key}-extra-row`} key={`${key}-extra-row`}
prefixCls={`${prefixCls}-expanded-row`} clsPrefix={`${clsPrefix}-expanded-row`}
indent={1} indent={1}
expandable={false} expandable={false}
store={this.store} store={this.store}
/> />
); );
}, }
getRowsByData(data, visible, indent, columns, fixed) { getRowsByData(data, visible, indent, columns, fixed) {
const props = this.props; const props = this.props;
@ -343,7 +370,7 @@ const Table = React.createClass({
onExpand={this.onExpanded} onExpand={this.onExpanded}
expandable={childrenColumn || expandedRowRender} expandable={childrenColumn || expandedRowRender}
expanded={isRowExpanded} expanded={isRowExpanded}
prefixCls={`${props.prefixCls}-row`} clsPrefix={`${props.clsPrefix}-row`}
childrenColumnName={childrenColumnName} childrenColumnName={childrenColumnName}
columns={leafColumns} columns={leafColumns}
expandIconColumnIndex={expandIconColumnIndex} expandIconColumnIndex={expandIconColumnIndex}
@ -372,18 +399,18 @@ const Table = React.createClass({
} }
} }
return rst; return rst;
}, }
getRows(columns, fixed) { getRows(columns, fixed) {
return this.getRowsByData(this.state.data, true, 0, columns, fixed); return this.getRowsByData(this.state.data, true, 0, columns, fixed);
}, }
getColGroup(columns, fixed) { getColGroup(columns, fixed) {
let cols = []; let cols = [];
if (this.props.expandIconAsCell && fixed !== 'right') { if (this.props.expandIconAsCell && fixed !== 'right') {
cols.push( cols.push(
<col <col
className={`${this.props.prefixCls}-expand-icon-col`} className={`${this.props.clsPrefix}-expand-icon-col`}
key="rc-table-expand-icon-col" key="rc-table-expand-icon-col"
/> />
); );
@ -400,32 +427,32 @@ const Table = React.createClass({
return <col key={c.key} style={{ width: c.width, minWidth: c.width }} />; return <col key={c.key} style={{ width: c.width, minWidth: c.width }} />;
})); }));
return <colgroup>{cols}</colgroup>; return <colgroup>{cols}</colgroup>;
}, }
getLeftFixedTable() { getLeftFixedTable() {
return this.getTable({ return this.getTable({
columns: this.columnManager.leftColumns(), columns: this.columnManager.leftColumns(),
fixed: 'left', fixed: 'left',
}); });
}, }
getRightFixedTable() { getRightFixedTable() {
return this.getTable({ return this.getTable({
columns: this.columnManager.rightColumns(), columns: this.columnManager.rightColumns(),
fixed: 'right', fixed: 'right',
}); });
}, }
getTable(options = {}) { getTable(options = {}) {
const { columns, fixed } = options; const { columns, fixed } = options;
const { prefixCls, scroll = {}, getBodyWrapper } = this.props; const { clsPrefix, scroll = {}, getBodyWrapper } = this.props;
let { useFixedHeader } = this.props; let { useFixedHeader } = this.props;
const bodyStyle = { ...this.props.bodyStyle }; const bodyStyle = { ...this.props.bodyStyle };
const headStyle = {}; const headStyle = {};
let tableClassName = ''; let tableClassName = '';
if (scroll.x || fixed) { if (scroll.x || fixed) {
tableClassName = `${prefixCls}-fixed`; tableClassName = `${clsPrefix}-fixed`;
bodyStyle.overflowX = bodyStyle.overflowX || 'auto'; bodyStyle.overflowX = bodyStyle.overflowX || 'auto';
} }
@ -459,7 +486,7 @@ const Table = React.createClass({
} }
} }
const tableBody = hasBody ? getBodyWrapper( const tableBody = hasBody ? getBodyWrapper(
<tbody className={`${prefixCls}-tbody`}> <tbody className={`${clsPrefix}-tbody`}>
{this.getRows(columns, fixed)} {this.getRows(columns, fixed)}
</tbody> </tbody>
) : null; ) : null;
@ -477,7 +504,7 @@ const Table = React.createClass({
if (useFixedHeader) { if (useFixedHeader) {
headTable = ( headTable = (
<div <div
className={`${prefixCls}-header`} className={`${clsPrefix}-header`}
ref={fixed ? null : 'headTable'} ref={fixed ? null : 'headTable'}
style={headStyle} style={headStyle}
onMouseOver={this.detectScrollTarget} onMouseOver={this.detectScrollTarget}
@ -491,7 +518,7 @@ const Table = React.createClass({
let BodyTable = ( let BodyTable = (
<div <div
className={`${prefixCls}-body`} className={`${clsPrefix}-body`}
style={bodyStyle} style={bodyStyle}
ref="bodyTable" ref="bodyTable"
onMouseOver={this.detectScrollTarget} onMouseOver={this.detectScrollTarget}
@ -513,11 +540,11 @@ const Table = React.createClass({
delete bodyStyle.overflowY; delete bodyStyle.overflowY;
BodyTable = ( BodyTable = (
<div <div
className={`${prefixCls}-body-outer`} className={`${clsPrefix}-body-outer`}
style={{ ...bodyStyle }} style={{ ...bodyStyle }}
> >
<div <div
className={`${prefixCls}-body-inner`} className={`${clsPrefix}-body-inner`}
ref={refName} ref={refName}
onMouseOver={this.detectScrollTarget} onMouseOver={this.detectScrollTarget}
onTouchStart={this.detectScrollTarget} onTouchStart={this.detectScrollTarget}
@ -530,34 +557,34 @@ const Table = React.createClass({
} }
return <span>{headTable}{BodyTable}</span>; return <span>{headTable}{BodyTable}</span>;
}, }
getTitle() { getTitle() {
const { title, prefixCls } = this.props; const { title, clsPrefix } = this.props;
return title ? ( return title ? (
<div className={`${prefixCls}-title`}> <div className={`${clsPrefix}-title`}>
{title(this.state.data)} {title(this.state.data)}
</div> </div>
) : null; ) : null;
}, }
getFooter() { getFooter() {
const { footer, prefixCls } = this.props; const { footer, clsPrefix } = this.props;
return footer ? ( return footer ? (
<div className={`${prefixCls}-footer`}> <div className={`${clsPrefix}-footer`}>
{footer(this.state.data)} {footer(this.state.data)}
</div> </div>
) : null; ) : null;
}, }
getEmptyText() { getEmptyText() {
const { emptyText, prefixCls, data } = this.props; const { emptyText, clsPrefix, data } = this.props;
return !data.length ? ( return !data.length ? (
<div className={`${prefixCls}-placeholder`}> <div className={`${clsPrefix}-placeholder`}>
{emptyText()} {emptyText()}
</div> </div>
) : null; ) : null;
}, }
getHeaderRowStyle(columns, rows) { getHeaderRowStyle(columns, rows) {
const { fixedColumnsHeadRowsHeight } = this.state; const { fixedColumnsHeadRowsHeight } = this.state;
@ -569,14 +596,14 @@ const Table = React.createClass({
return { height: headerHeight / rows.length }; return { height: headerHeight / rows.length };
} }
return null; return null;
}, }
syncFixedTableRowHeight() { syncFixedTableRowHeight() {
const { prefixCls } = this.props; const { clsPrefix } = this.props;
const headRows = this.refs.headTable ? const headRows = this.refs.headTable ?
this.refs.headTable.querySelectorAll('thead') : this.refs.headTable.querySelectorAll('thead') :
this.refs.bodyTable.querySelectorAll('thead'); this.refs.bodyTable.querySelectorAll('thead');
const bodyRows = this.refs.bodyTable.querySelectorAll(`.${prefixCls}-row`) || []; const bodyRows = this.refs.bodyTable.querySelectorAll(`.${clsPrefix}-row`) || [];
const fixedColumnsHeadRowsHeight = [].map.call( const fixedColumnsHeadRowsHeight = [].map.call(
headRows, row => row.getBoundingClientRect().height || 'auto' headRows, row => row.getBoundingClientRect().height || 'auto'
); );
@ -591,7 +618,7 @@ const Table = React.createClass({
fixedColumnsHeadRowsHeight, fixedColumnsHeadRowsHeight,
fixedColumnsBodyRowsHeight, fixedColumnsBodyRowsHeight,
}); });
}, }
resetScrollY() { resetScrollY() {
if (this.refs.headTable) { if (this.refs.headTable) {
@ -600,22 +627,22 @@ const Table = React.createClass({
if (this.refs.bodyTable) { if (this.refs.bodyTable) {
this.refs.bodyTable.scrollLeft = 0; this.refs.bodyTable.scrollLeft = 0;
} }
}, }
findExpandedRow(record, index) { findExpandedRow(record, index) {
const rows = this.getExpandedRows().filter(i => i === this.getRowKey(record, index)); const rows = this.getExpandedRows().filter(i => i === this.getRowKey(record, index));
return rows[0]; return rows[0];
}, }
isRowExpanded(record, index) { isRowExpanded(record, index) {
return typeof this.findExpandedRow(record, index) !== 'undefined'; return typeof this.findExpandedRow(record, index) !== 'undefined';
}, }
detectScrollTarget(e) { detectScrollTarget(e) {
if (this.scrollTarget !== e.currentTarget) { if (this.scrollTarget !== e.currentTarget) {
this.scrollTarget = e.currentTarget; this.scrollTarget = e.currentTarget;
} }
}, }
handleBodyScroll(e) { handleBodyScroll(e) {
// Prevent scrollTop setter trigger onScroll event // Prevent scrollTop setter trigger onScroll event
@ -654,26 +681,26 @@ const Table = React.createClass({
} }
// Remember last scrollLeft for scroll direction detecting. // Remember last scrollLeft for scroll direction detecting.
this.lastScrollLeft = e.target.scrollLeft; this.lastScrollLeft = e.target.scrollLeft;
}, }
handleRowHover(isHover, key) { handleRowHover(isHover, key) {
this.store.setState({ this.store.setState({
currentHoverKey: isHover ? key : null, currentHoverKey: isHover ? key : null,
}); });
}, }
render() { render() {
const props = this.props; const props = this.props;
const prefixCls = props.prefixCls; const clsPrefix = props.clsPrefix;
let className = props.prefixCls; let className = props.clsPrefix;
if (props.className) { if (props.className) {
className += ` ${props.className}`; className += ` ${props.className}`;
} }
if (props.useFixedHeader || (props.scroll && props.scroll.y)) { if (props.useFixedHeader || (props.scroll && props.scroll.y)) {
className += ` ${prefixCls}-fixed-header`; className += ` ${clsPrefix}-fixed-header`;
} }
className += ` ${prefixCls}-scroll-position-${this.state.scrollPosition}`; className += ` ${clsPrefix}-scroll-position-${this.state.scrollPosition}`;
const isTableScroll = this.columnManager.isAnyColumnsFixed() || const isTableScroll = this.columnManager.isAnyColumnsFixed() ||
props.scroll.x || props.scroll.x ||
@ -682,24 +709,27 @@ const Table = React.createClass({
return ( return (
<div className={className} style={props.style}> <div className={className} style={props.style}>
{this.getTitle()} {this.getTitle()}
<div className={`${prefixCls}-content`}> <div className={`${clsPrefix}-content`}>
{this.columnManager.isAnyColumnsLeftFixed() && {this.columnManager.isAnyColumnsLeftFixed() &&
<div className={`${prefixCls}-fixed-left`}> <div className={`${clsPrefix}-fixed-left`}>
{this.getLeftFixedTable()} {this.getLeftFixedTable()}
</div>} </div>}
<div className={isTableScroll ? `${prefixCls}-scroll` : ''}> <div className={isTableScroll ? `${clsPrefix}-scroll` : ''}>
{this.getTable({ columns: this.columnManager.groupedColumns() })} {this.getTable({ columns: this.columnManager.groupedColumns() })}
{this.getEmptyText()} {this.getEmptyText()}
{this.getFooter()} {this.getFooter()}
</div> </div>
{this.columnManager.isAnyColumnsRightFixed() && {this.columnManager.isAnyColumnsRightFixed() &&
<div className={`${prefixCls}-fixed-right`}> <div className={`${clsPrefix}-fixed-right`}>
{this.getRightFixedTable()} {this.getRightFixedTable()}
</div>} </div>}
</div> </div>
</div> </div>
); );
}, }
}); };
Table.propTypes = propTypes;
Table.defaultProps = defaultProps;
export default Table; export default Table;

View File

@ -1,28 +1,34 @@
import React, { PropTypes } from 'react'; import React, { PropTypes, Component } from 'react';
import objectPath from 'object-path'; import objectPath from 'object-path';
const TableCell = React.createClass({ const propTypes = {
propTypes: {
record: PropTypes.object, record: PropTypes.object,
prefixCls: PropTypes.string, clsPrefix: PropTypes.string,
index: PropTypes.number, index: PropTypes.number,
indent: PropTypes.number, indent: PropTypes.number,
indentSize: PropTypes.number, indentSize: PropTypes.number,
column: PropTypes.object, column: PropTypes.object,
expandIcon: PropTypes.node, expandIcon: PropTypes.node
}, };
class TableCell extends Component{
constructor(props){
super(props);
this.isInvalidRenderCellText = this.isInvalidRenderCellText.bind(this);
this.handleClick = this.handleClick.bind(this);
}
isInvalidRenderCellText(text) { isInvalidRenderCellText(text) {
return text && !React.isValidElement(text) && return text && !React.isValidElement(text) &&
Object.prototype.toString.call(text) === '[object Object]'; Object.prototype.toString.call(text) === '[object Object]';
}, }
handleClick(e) { handleClick(e) {
const { record, column: { onCellClick } } = this.props; const { record, column: { onCellClick } } = this.props;
if (onCellClick) { if (onCellClick) {
onCellClick(record, e); onCellClick(record, e);
} }
}, }
render() { render() {
const { record, indentSize, prefixCls, indent, const { record, indentSize, clsPrefix, indent,
index, expandIcon, column } = this.props; index, expandIcon, column } = this.props;
const { dataIndex, render, className = '' } = column; const { dataIndex, render, className = '' } = column;
@ -41,7 +47,7 @@ const TableCell = React.createClass({
} }
} }
// Fix https://github.com/ant-design/ant-design/issues/1202
if (this.isInvalidRenderCellText(text)) { if (this.isInvalidRenderCellText(text)) {
text = null; text = null;
} }
@ -49,7 +55,7 @@ const TableCell = React.createClass({
const indentText = expandIcon ? ( const indentText = expandIcon ? (
<span <span
style={{ paddingLeft: `${indentSize * indent}px` }} style={{ paddingLeft: `${indentSize * indent}px` }}
className={`${prefixCls}-indent indent-level-${indent}`} className={`${clsPrefix}-indent indent-level-${indent}`}
/> />
) : null; ) : null;
@ -68,7 +74,9 @@ const TableCell = React.createClass({
{text} {text}
</td> </td>
); );
}, }
}); };
TableCell.propTypes = propTypes;
export default TableCell; export default TableCell;

View File

@ -1,19 +1,23 @@
import React, { PropTypes } from 'react'; import React, { PropTypes, Component } from 'react';
import shallowequal from 'shallowequal'; import shallowequal from 'shallowequal';
export default React.createClass({ const propTypes = {
propTypes: { clsPrefix: PropTypes.string,
prefixCls: PropTypes.string,
rowStyle: PropTypes.object, rowStyle: PropTypes.object,
rows: PropTypes.array, rows: PropTypes.array,
}, }
class TableHeader extends Component{
constructor(props){
super(props);
}
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
return !shallowequal(nextProps, this.props); return !shallowequal(nextProps, this.props);
}, }
render() { render() {
const { prefixCls, rowStyle, rows } = this.props; const { clsPrefix, rowStyle, rows } = this.props;
return ( return (
<thead className={`${prefixCls}-thead`}> <thead className={`${clsPrefix}-thead`}>
{ {
rows.map((row, index) => ( rows.map((row, index) => (
<tr key={index} style={rowStyle}> <tr key={index} style={rowStyle}>
@ -23,5 +27,9 @@ export default React.createClass({
} }
</thead> </thead>
); );
}, }
}); };
TableHeader.propTypes = propTypes;
export default TableHeader;

View File

@ -1,14 +1,13 @@
import React, { PropTypes } from 'react'; import React, { PropTypes, Component } from 'react';
import TableCell from './TableCell'; import TableCell from './TableCell';
import ExpandIcon from './ExpandIcon'; import ExpandIcon from './ExpandIcon';
const TableRow = React.createClass({ const propTypes = {
propTypes: {
onDestroy: PropTypes.func, onDestroy: PropTypes.func,
onRowClick: PropTypes.func, onRowClick: PropTypes.func,
onRowDoubleClick: PropTypes.func, onRowDoubleClick: PropTypes.func,
record: PropTypes.object, record: PropTypes.object,
prefixCls: PropTypes.string, clsPrefix: PropTypes.string,
expandIconColumnIndex: PropTypes.number, expandIconColumnIndex: PropTypes.number,
onHover: PropTypes.func, onHover: PropTypes.func,
columns: PropTypes.array, columns: PropTypes.array,
@ -29,24 +28,30 @@ const TableRow = React.createClass({
expandIconAsCell: PropTypes.bool, expandIconAsCell: PropTypes.bool,
expandRowByClick: PropTypes.bool, expandRowByClick: PropTypes.bool,
store: PropTypes.object.isRequired, store: PropTypes.object.isRequired,
}, };
getDefaultProps() { const defaultProps = {
return { onRowClick() {},
onRowClick() {}, onRowDoubleClick() {},
onRowDoubleClick() {}, onDestroy() {},
onDestroy() {}, expandIconColumnIndex: 0,
expandIconColumnIndex: 0, expandRowByClick: false,
expandRowByClick: false, onHover() {},
onHover() {}, };
};
}, class TableRow extends Component{
constructor(props){
super(props);
this.state = {
hovered: false,
};
this.onRowClick = this.onRowClick.bind(this);
this.onRowDoubleClick = this.onRowDoubleClick.bind(this);
this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
}
getInitialState() {
return {
hovered: false,
};
},
componentDidMount() { componentDidMount() {
const { store, hoverKey } = this.props; const { store, hoverKey } = this.props;
@ -57,7 +62,7 @@ const TableRow = React.createClass({
this.setState({ hovered: false }); this.setState({ hovered: false });
} }
}); });
}, }
componentWillUnmount() { componentWillUnmount() {
const { record, onDestroy, index } = this.props; const { record, onDestroy, index } = this.props;
@ -65,7 +70,7 @@ const TableRow = React.createClass({
if (this.unsubscribe) { if (this.unsubscribe) {
this.unsubscribe(); this.unsubscribe();
} }
}, }
onRowClick(event) { onRowClick(event) {
const { const {
@ -81,26 +86,26 @@ const TableRow = React.createClass({
onExpand(!expanded, record, index); onExpand(!expanded, record, index);
} }
onRowClick(record, index, event); onRowClick(record, index, event);
}, }
onRowDoubleClick(event) { onRowDoubleClick(event) {
const { record, index, onRowDoubleClick } = this.props; const { record, index, onRowDoubleClick } = this.props;
onRowDoubleClick(record, index, event); onRowDoubleClick(record, index, event);
}, }
onMouseEnter() { onMouseEnter() {
const { onHover, hoverKey } = this.props; const { onHover, hoverKey } = this.props;
onHover(true, hoverKey); onHover(true, hoverKey);
}, }
onMouseLeave() { onMouseLeave() {
const { onHover, hoverKey } = this.props; const { onHover, hoverKey } = this.props;
onHover(false, hoverKey); onHover(false, hoverKey);
}, }
render() { render() {
const { const {
prefixCls, columns, record, height, visible, index, clsPrefix, columns, record, height, visible, index,
expandIconColumnIndex, expandIconAsCell, expanded, expandRowByClick, expandIconColumnIndex, expandIconAsCell, expanded, expandRowByClick,
expandable, onExpand, needIndentSpaced, indent, indentSize, expandable, onExpand, needIndentSpaced, indent, indentSize,
} = this.props; } = this.props;
@ -108,7 +113,7 @@ const TableRow = React.createClass({
let { className } = this.props; let { className } = this.props;
if (this.state.hovered) { if (this.state.hovered) {
className += ` ${prefixCls}-hover`; className += ` ${clsPrefix}-hover`;
} }
const cells = []; const cells = [];
@ -116,7 +121,7 @@ const TableRow = React.createClass({
const expandIcon = ( const expandIcon = (
<ExpandIcon <ExpandIcon
expandable={expandable} expandable={expandable}
prefixCls={prefixCls} clsPrefix={clsPrefix}
onExpand={onExpand} onExpand={onExpand}
needIndentSpaced={needIndentSpaced} needIndentSpaced={needIndentSpaced}
expanded={expanded} expanded={expanded}
@ -128,7 +133,7 @@ const TableRow = React.createClass({
if (expandIconAsCell && i === 0) { if (expandIconAsCell && i === 0) {
cells.push( cells.push(
<td <td
className={`${prefixCls}-expand-icon-cell`} className={`${clsPrefix}-expand-icon-cell`}
key="rc-table-expand-icon-cell" key="rc-table-expand-icon-cell"
> >
{expandIcon} {expandIcon}
@ -139,7 +144,7 @@ const TableRow = React.createClass({
? false : (i === expandIconColumnIndex); ? false : (i === expandIconColumnIndex);
cells.push( cells.push(
<TableCell <TableCell
prefixCls={prefixCls} clsPrefix={clsPrefix}
record={record} record={record}
indentSize={indentSize} indentSize={indentSize}
indent={indent} indent={indent}
@ -161,13 +166,16 @@ const TableRow = React.createClass({
onDoubleClick={this.onRowDoubleClick} onDoubleClick={this.onRowDoubleClick}
onMouseEnter={this.onMouseEnter} onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave} onMouseLeave={this.onMouseLeave}
className={`${prefixCls} ${className} ${prefixCls}-level-${indent}`} className={`${clsPrefix} ${className} ${clsPrefix}-level-${indent}`}
style={style} style={style}
> >
{cells} {cells}
</tr> </tr>
); );
}, }
}); };
TableRow.propTypes = propTypes;
TableRow.defaultProps = defaultProps;
export default TableRow; export default TableRow;

View File

@ -1,59 +0,0 @@
.move-enter, .move-appear {
opacity: 0;
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
animation-duration: 2.5s;
animation-fill-mode: both;
animation-play-state: paused;
}
.move-leave {
animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
animation-duration: .5s;
animation-fill-mode: both;
animation-play-state: paused;
}
.move-enter.move-enter-active, .move-appear.move-enter-active {
animation-name: moveLeftIn;
animation-play-state: running;
}
.move-leave.move-leave-active {
animation-name: moveRightOut;
animation-play-state: running;
}
@keyframes moveLeftIn {
0% {
transform-origin: 0 0;
transform: translateX(30px);
opacity: 0;
background: #fff6de;
}
20% {
transform-origin: 0 0;
transform: translateX(0);
opacity: 1;
}
80%{
background: #fff6de;
}
100%{
background: transparent;
opacity: 1;
}
}
@keyframes moveRightOut {
0% {
transform-origin: 0 0;
transform: translateX(0);
opacity: 1;
}
100% {
transform-origin: 0 0;
transform: translateX(-30px);
opacity: 0;
}
}

View File

@ -1,11 +0,0 @@
$table-border-color: #e9e9e9;
.u-table.bordered {
table {
border-collapse: collapse;
}
th, td {
border: 1px solid $table-border-color;
}
}

View File

@ -2,10 +2,16 @@
$text-color : #666; $text-color : #666;
$font-size-base : 12px; $font-size-base : 12px;
$line-height: 1.5; $line-height: 1.5;
$table-border-color: #e9e9e9; $table-border-color: $border-color-base;
$table-head-background-color: #f7f7f7; $table-head-background-color: #f7f7f7;
$vertical-padding: 16px; $vertical-padding: 16px;
$horizontal-padding: 8px; $horizontal-padding: 8px;
$table-border-color: #e9e9e9;
$table-hover-color: unquote("rgb(#{$palette-blue-50})") !default;
$table-move-in-color: $bg-color-base;
.u-table { .u-table {
font-size: $font-size-base; font-size: $font-size-base;
@ -15,6 +21,38 @@ $horizontal-padding: 8px;
line-height: $line-height; line-height: $line-height;
overflow: hidden; overflow: hidden;
table {
width: 100%;
border-collapse: collapse;
text-align: left;
}
th {
background: $table-head-background-color;
font-weight: bold;
transition: background .3s ease;
}
td {
border-bottom: 1px solid $table-border-color;
}
tr {
transition: all .3s ease;
&:hover {
background: $table-hover-color;
}
}
tr.tr-row-hover {
background: $table-hover-color;
}
th, td {
padding: $vertical-padding $horizontal-padding;
}
&-scroll { &-scroll {
overflow: auto; overflow: auto;
} }
@ -64,39 +102,6 @@ $horizontal-padding: 8px;
position: relative; position: relative;
} }
table {
width: 100%;
border-collapse: separate;
text-align: left;
}
th {
background: $table-head-background-color;
font-weight: bold;
transition: background .3s ease;
}
td {
border-bottom: 1px solid $table-border-color;
}
tr {
transition: all .3s ease;
&:hover {
background: #eaf8fe;
}
}
tr.tr-row-hover {
background: #eaf8fe;
}
th, td {
padding: $vertical-padding $horizontal-padding;
}
}
.u-table {
&-expand-icon-col { &-expand-icon-col {
width: 10px; width: 10px;
} }
@ -209,3 +214,75 @@ $horizontal-padding: 8px;
box-shadow: none; box-shadow: none;
} }
} }
.u-table.bordered {
table {
border-collapse: collapse;
}
th, td {
border: 1px solid $table-border-color;
}
}
.move-enter, .move-appear {
opacity: 0;
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
animation-duration: 2.5s;
animation-fill-mode: both;
animation-play-state: paused;
}
.move-leave {
animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
animation-duration: .5s;
animation-fill-mode: both;
animation-play-state: paused;
}
.move-enter.move-enter-active, .move-appear.move-enter-active {
animation-name: moveLeftIn;
animation-play-state: running;
}
.move-leave.move-leave-active {
animation-name: moveRightOut;
animation-play-state: running;
}
@keyframes moveLeftIn {
0% {
transform-origin: 0 0;
transform: translateX(30px);
opacity: 0;
background: $table-move-in-color;
}
20% {
transform-origin: 0 0;
transform: translateX(0);
opacity: 1;
}
80%{
background: $table-move-in-color;
}
100%{
background: transparent;
opacity: 1;
}
}
@keyframes moveRightOut {
0% {
transform-origin: 0 0;
transform: translateX(0);
opacity: 1;
}
100% {
transform-origin: 0 0;
transform: translateX(-30px);
opacity: 0;
}
}