add demo
This commit is contained in:
parent
c23e4597ca
commit
c41fd2efe6
|
@ -3,8 +3,51 @@
|
|||
@import "../node_modules/bee-layout/src/Layout.scss";
|
||||
@import "../node_modules/bee-button/src/Button.scss";
|
||||
@import "../node_modules/bee-transition/src/Transition.scss";
|
||||
@import "../src/animation.scss";
|
||||
@import "../src/bordered.scss";
|
||||
@import "../src/index.scss";
|
||||
@import "../node_modules/bee-dropdown/src/Dropdown.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;
|
||||
}
|
||||
|
|
|
@ -1,67 +1,36 @@
|
|||
/**
|
||||
*
|
||||
* @title 这是标题
|
||||
* @description 这是描述
|
||||
* @title 简单表格
|
||||
* @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) {
|
||||
console.log('Delete', key);
|
||||
e.preventDefault();
|
||||
const data = this.state.data.filter(item => item.key !== key);
|
||||
this.setState({ data });
|
||||
}
|
||||
const columns = [
|
||||
{ title: '用户名', dataIndex: 'a', key: 'a', width: 100 },
|
||||
{ id: '123', title: '性别', dataIndex: 'b', key: 'b', width: 100 },
|
||||
{ title: '年龄', dataIndex: 'c', key: 'c', width: 200 },
|
||||
{
|
||||
title: '操作', dataIndex: '', key: 'd', render() {
|
||||
return <a href="#">一些操作</a>;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
onAdd() {
|
||||
const data = [...this.state.data];
|
||||
data.push({
|
||||
a: 'new data',
|
||||
b: 'new data',
|
||||
c: 'new data',
|
||||
key: Date.now(),
|
||||
});
|
||||
this.setState({ data });
|
||||
}
|
||||
const data = [
|
||||
{ a: '令狐冲', b: '男', c: 41, key: '1' },
|
||||
{ a: '杨过', b: '男', c: 67, key: '2' },
|
||||
{ a: '郭靖', b: '男', c: 25, key: '3' },
|
||||
];
|
||||
|
||||
getBodyWrapper(body) {
|
||||
return (
|
||||
<Animate transitionName="move" component="tbody" className={body.props.className}>
|
||||
{body.props.children}
|
||||
</Animate>
|
||||
);
|
||||
}
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
class Demo1 extends Component {
|
||||
render () {
|
||||
return (
|
||||
<Table
|
||||
columns={columns}
|
||||
data={data}
|
||||
title={currentData => <div>标题: {currentData.length} 个元素</div>}
|
||||
footer={currentData => <div>表尾: {currentData.length} 个元素</div>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,86 +5,166 @@
|
|||
*
|
||||
*/
|
||||
|
||||
const columns1 = [{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 400,
|
||||
}, {
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
key: 'age',
|
||||
width: 100,
|
||||
}, {
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
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} />
|
||||
)
|
||||
class EditableCell extends React.Component {
|
||||
state = {
|
||||
value: this.props.value,
|
||||
editable: false,
|
||||
}
|
||||
handleChange = (e) => {
|
||||
const value = e.target.value;
|
||||
this.setState({ value });
|
||||
}
|
||||
check = () => {
|
||||
this.setState({ editable: false });
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(this.state.value);
|
||||
}
|
||||
}
|
||||
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>);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
},
|
||||
});
|
|
@ -8,11 +8,13 @@ import Table from '../src';
|
|||
import Animate from 'bee-animate';
|
||||
import Menu, { Item, Divider } from 'bee-menus';
|
||||
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-chevronarrowup"></i>;
|
||||
const CARETUP = <i className="uf uf-arrow-up"></i>;
|
||||
|
||||
|
||||
{demolist}
|
||||
|
@ -42,14 +44,9 @@ class Demo extends Component {
|
|||
);
|
||||
const header = (
|
||||
<Row>
|
||||
<Col md={11}>
|
||||
<Col md={12}>
|
||||
{ example }
|
||||
</Col>
|
||||
<Col md={1}>
|
||||
<Button shape="icon" onClick={ this.handleClick }>
|
||||
{ caret }
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
return (
|
||||
|
|
591
demo/index.js
591
demo/index.js
File diff suppressed because one or more lines are too long
11
package.json
11
package.json
|
@ -41,18 +41,19 @@
|
|||
"warning": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bee-animate": "0.0.3",
|
||||
"bee-animate": "latest",
|
||||
"bee-button": "latest",
|
||||
"bee-dropdown": "^0.1.4",
|
||||
"bee-form-control": "^0.1.7",
|
||||
"bee-icon": "0.0.5",
|
||||
"bee-layout": "latest",
|
||||
"bee-menus": "0.0.5",
|
||||
"bee-panel": "latest",
|
||||
"bee-popconfirm": "^0.2.1",
|
||||
"chai": "^3.5.0",
|
||||
"console-polyfill": "~0.2.1",
|
||||
"enzyme": "^2.4.1",
|
||||
"es5-shim": "~4.1.10",
|
||||
"react": "~0.14.0",
|
||||
"react": "15.3.2",
|
||||
"react-addons-test-utils": "15.3.2",
|
||||
"react-dom": "~0.14.0"
|
||||
"react-dom": "15.3.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ import React from 'react';
|
|||
import Column from './Column';
|
||||
import ColumnGroup from './ColumnGroup';
|
||||
|
||||
//行控制管理
|
||||
|
||||
export default class ColumnManager {
|
||||
_cached = {}
|
||||
|
||||
|
|
|
@ -1,33 +1,39 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import shallowequal from 'shallowequal';
|
||||
|
||||
const ExpandIcon = React.createClass({
|
||||
propTypes: {
|
||||
const propTypes = {
|
||||
record: PropTypes.object,
|
||||
prefixCls: PropTypes.string,
|
||||
clsPrefix: PropTypes.string,
|
||||
expandable: PropTypes.any,
|
||||
expanded: PropTypes.bool,
|
||||
needIndentSpaced: PropTypes.bool,
|
||||
onExpand: PropTypes.func,
|
||||
},
|
||||
};
|
||||
|
||||
class ExpandIcon extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
}
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return !shallowequal(nextProps, this.props);
|
||||
},
|
||||
}
|
||||
render() {
|
||||
const { expandable, prefixCls, onExpand, needIndentSpaced, expanded, record } = this.props;
|
||||
const { expandable, clsPrefix, onExpand, needIndentSpaced, expanded, record } = this.props;
|
||||
if (expandable) {
|
||||
const expandClassName = expanded ? 'expanded' : 'collapsed';
|
||||
return (
|
||||
<span
|
||||
className={`${prefixCls}-expand-icon ${prefixCls}-${expandClassName}`}
|
||||
className={`${clsPrefix}-expand-icon ${clsPrefix}-${expandClassName}`}
|
||||
onClick={(e) => onExpand(!expanded, record, e)}
|
||||
/>
|
||||
);
|
||||
} else if (needIndentSpaced) {
|
||||
return <span className={`${prefixCls}-expand-icon ${prefixCls}-spaced`} />;
|
||||
return <span className={`${clsPrefix}-expand-icon ${clsPrefix}-spaced`} />;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ExpandIcon.propTypes = propTypes;
|
||||
|
||||
export default ExpandIcon;
|
|
@ -1,4 +1,4 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import TableRow from './TableRow';
|
||||
import TableHeader from './TableHeader';
|
||||
import { measureScrollbar, debounce, warningOnce } from './utils';
|
||||
|
@ -7,8 +7,7 @@ import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
|||
import ColumnManager from './ColumnManager';
|
||||
import createStore from './createStore';
|
||||
|
||||
const Table = React.createClass({
|
||||
propTypes: {
|
||||
const propTypes = {
|
||||
data: PropTypes.array,
|
||||
expandIconAsCell: PropTypes.bool,
|
||||
defaultExpandAllRows: PropTypes.bool,
|
||||
|
@ -16,9 +15,10 @@ const Table = React.createClass({
|
|||
defaultExpandedRowKeys: PropTypes.array,
|
||||
useFixedHeader: PropTypes.bool,
|
||||
columns: PropTypes.array,
|
||||
prefixCls: PropTypes.string,
|
||||
clsPrefix: PropTypes.string,
|
||||
bodyStyle: PropTypes.object,
|
||||
style: PropTypes.object,
|
||||
//特殊的渲染规则的key值
|
||||
rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
||||
rowClassName: PropTypes.func,
|
||||
expandedRowClassName: PropTypes.func,
|
||||
|
@ -29,6 +29,7 @@ const Table = React.createClass({
|
|||
onRowClick: PropTypes.func,
|
||||
onRowDoubleClick: PropTypes.func,
|
||||
expandIconColumnIndex: PropTypes.number,
|
||||
//是否显示表头
|
||||
showHeader: PropTypes.bool,
|
||||
title: PropTypes.func,
|
||||
footer: PropTypes.func,
|
||||
|
@ -37,61 +38,87 @@ const Table = React.createClass({
|
|||
rowRef: PropTypes.func,
|
||||
getBodyWrapper: PropTypes.func,
|
||||
children: PropTypes.node,
|
||||
},
|
||||
};
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
data: [],
|
||||
useFixedHeader: false,
|
||||
expandIconAsCell: false,
|
||||
defaultExpandAllRows: false,
|
||||
defaultExpandedRowKeys: [],
|
||||
rowKey: 'key',
|
||||
rowClassName: () => '',
|
||||
expandedRowClassName: () => '',
|
||||
onExpand() {},
|
||||
onExpandedRowsChange() {},
|
||||
onRowClick() {},
|
||||
onRowDoubleClick() {},
|
||||
prefixCls: 'u-table',
|
||||
bodyStyle: {},
|
||||
style: {},
|
||||
childrenColumnName: 'children',
|
||||
indentSize: 15,
|
||||
expandIconColumnIndex: 0,
|
||||
showHeader: true,
|
||||
scroll: {},
|
||||
rowRef: () => null,
|
||||
getBodyWrapper: body => body,
|
||||
emptyText: () => 'No Data',
|
||||
};
|
||||
},
|
||||
const defaultProps = {
|
||||
data: [],
|
||||
useFixedHeader: false,
|
||||
expandIconAsCell: false,
|
||||
defaultExpandAllRows: false,
|
||||
defaultExpandedRowKeys: [],
|
||||
rowKey: 'key',
|
||||
rowClassName: () => '',
|
||||
expandedRowClassName: () => '',
|
||||
onExpand() {},
|
||||
onExpandedRowsChange() {},
|
||||
onRowClick() {},
|
||||
onRowDoubleClick() {},
|
||||
clsPrefix: 'u-table',
|
||||
bodyStyle: {},
|
||||
style: {},
|
||||
childrenColumnName: 'children',
|
||||
indentSize: 15,
|
||||
expandIconColumnIndex: 0,
|
||||
showHeader: true,
|
||||
scroll: {},
|
||||
rowRef: () => null,
|
||||
getBodyWrapper: body => body,
|
||||
emptyText: () => 'No Data',
|
||||
};
|
||||
|
||||
getInitialState() {
|
||||
const props = this.props;
|
||||
let expandedRowKeys = [];
|
||||
let rows = [...props.data];
|
||||
this.columnManager = new ColumnManager(props.columns, props.children);
|
||||
this.store = createStore({ currentHoverKey: null });
|
||||
class Table extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
let expandedRowKeys = [];
|
||||
let rows = [...props.data];
|
||||
this.columnManager = new ColumnManager(props.columns, props.children);
|
||||
this.store = createStore({ currentHoverKey: null });
|
||||
|
||||
if (props.defaultExpandAllRows) {
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
expandedRowKeys.push(this.getRowKey(row, i));
|
||||
rows = rows.concat(row[props.childrenColumnName] || []);
|
||||
if (props.defaultExpandAllRows) {
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
expandedRowKeys.push(this.getRowKey(row, i));
|
||||
rows = rows.concat(row[props.childrenColumnName] || []);
|
||||
}
|
||||
} else {
|
||||
expandedRowKeys = props.expandedRowKeys || props.defaultExpandedRowKeys;
|
||||
}
|
||||
} else {
|
||||
expandedRowKeys = props.expandedRowKeys || props.defaultExpandedRowKeys;
|
||||
}
|
||||
return {
|
||||
expandedRowKeys,
|
||||
data: props.data,
|
||||
currentHoverKey: null,
|
||||
scrollPosition: 'left',
|
||||
fixedColumnsHeadRowsHeight: [],
|
||||
fixedColumnsBodyRowsHeight: [],
|
||||
};
|
||||
},
|
||||
this.state = {
|
||||
expandedRowKeys,
|
||||
data: props.data,
|
||||
currentHoverKey: null,
|
||||
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() {
|
||||
this.resetScrollY();
|
||||
|
@ -101,7 +128,7 @@ const Table = React.createClass({
|
|||
window, 'resize', debounce(this.syncFixedTableRowHeight, 150)
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if ('data' in nextProps) {
|
||||
|
@ -122,24 +149,24 @@ const Table = React.createClass({
|
|||
} else if (nextProps.children !== this.props.children) {
|
||||
this.columnManager.reset(null, nextProps.children);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.syncFixedTableRowHeight();
|
||||
},
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.resizeEvent) {
|
||||
this.resizeEvent.remove();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
onExpandedRowsChange(expandedRowKeys) {
|
||||
if (!this.props.expandedRowKeys) {
|
||||
this.setState({ expandedRowKeys });
|
||||
}
|
||||
this.props.onExpandedRowsChange(expandedRowKeys);
|
||||
},
|
||||
}
|
||||
|
||||
onExpanded(expanded, record, e, index) {
|
||||
if (e) {
|
||||
|
@ -155,7 +182,7 @@ const Table = React.createClass({
|
|||
this.onExpandedRowsChange(expandedRows);
|
||||
}
|
||||
this.props.onExpand(expanded, record);
|
||||
},
|
||||
}
|
||||
|
||||
onRowDestroy(record, rowIndex) {
|
||||
const expandedRows = this.getExpandedRows().concat();
|
||||
|
@ -170,7 +197,7 @@ const Table = React.createClass({
|
|||
expandedRows.splice(index, 1);
|
||||
}
|
||||
this.onExpandedRowsChange(expandedRows);
|
||||
},
|
||||
}
|
||||
|
||||
getRowKey(record, index) {
|
||||
const rowKey = this.props.rowKey;
|
||||
|
@ -182,20 +209,20 @@ const Table = React.createClass({
|
|||
'or set `rowKey` to an unique primary key.'
|
||||
);
|
||||
return key;
|
||||
},
|
||||
}
|
||||
|
||||
getExpandedRows() {
|
||||
return this.props.expandedRowKeys || this.state.expandedRowKeys;
|
||||
},
|
||||
}
|
||||
|
||||
getHeader(columns, fixed) {
|
||||
const { showHeader, expandIconAsCell, prefixCls } = this.props;
|
||||
const { showHeader, expandIconAsCell, clsPrefix } = this.props;
|
||||
const rows = this.getHeaderRows(columns);
|
||||
|
||||
if (expandIconAsCell && fixed !== 'right') {
|
||||
rows[0].unshift({
|
||||
key: 'rc-table-expandIconAsCell',
|
||||
className: `${prefixCls}-expand-icon-th`,
|
||||
className: `${clsPrefix}-expand-icon-th`,
|
||||
title: '',
|
||||
rowSpan: rows.length,
|
||||
});
|
||||
|
@ -205,12 +232,12 @@ const Table = React.createClass({
|
|||
|
||||
return showHeader ? (
|
||||
<TableHeader
|
||||
prefixCls={prefixCls}
|
||||
clsPrefix={clsPrefix}
|
||||
rows={rows}
|
||||
rowStyle={trStyle}
|
||||
/>
|
||||
) : null;
|
||||
},
|
||||
}
|
||||
|
||||
getHeaderRows(columns, currentRow = 0, rows) {
|
||||
rows = rows || [];
|
||||
|
@ -241,10 +268,10 @@ const Table = React.createClass({
|
|||
}
|
||||
});
|
||||
return rows.filter(row => row.length > 0);
|
||||
},
|
||||
}
|
||||
|
||||
getExpandedRow(key, content, visible, className, fixed) {
|
||||
const { prefixCls, expandIconAsCell } = this.props;
|
||||
const { clsPrefix, expandIconAsCell } = this.props;
|
||||
let colCount;
|
||||
if (fixed === 'left') {
|
||||
colCount = this.columnManager.leftLeafColumns().length;
|
||||
|
@ -274,13 +301,13 @@ const Table = React.createClass({
|
|||
visible={visible}
|
||||
className={className}
|
||||
key={`${key}-extra-row`}
|
||||
prefixCls={`${prefixCls}-expanded-row`}
|
||||
clsPrefix={`${clsPrefix}-expanded-row`}
|
||||
indent={1}
|
||||
expandable={false}
|
||||
store={this.store}
|
||||
/>
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
getRowsByData(data, visible, indent, columns, fixed) {
|
||||
const props = this.props;
|
||||
|
@ -343,7 +370,7 @@ const Table = React.createClass({
|
|||
onExpand={this.onExpanded}
|
||||
expandable={childrenColumn || expandedRowRender}
|
||||
expanded={isRowExpanded}
|
||||
prefixCls={`${props.prefixCls}-row`}
|
||||
clsPrefix={`${props.clsPrefix}-row`}
|
||||
childrenColumnName={childrenColumnName}
|
||||
columns={leafColumns}
|
||||
expandIconColumnIndex={expandIconColumnIndex}
|
||||
|
@ -372,18 +399,18 @@ const Table = React.createClass({
|
|||
}
|
||||
}
|
||||
return rst;
|
||||
},
|
||||
}
|
||||
|
||||
getRows(columns, fixed) {
|
||||
return this.getRowsByData(this.state.data, true, 0, columns, fixed);
|
||||
},
|
||||
}
|
||||
|
||||
getColGroup(columns, fixed) {
|
||||
let cols = [];
|
||||
if (this.props.expandIconAsCell && fixed !== 'right') {
|
||||
cols.push(
|
||||
<col
|
||||
className={`${this.props.prefixCls}-expand-icon-col`}
|
||||
className={`${this.props.clsPrefix}-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 <colgroup>{cols}</colgroup>;
|
||||
},
|
||||
}
|
||||
|
||||
getLeftFixedTable() {
|
||||
return this.getTable({
|
||||
columns: this.columnManager.leftColumns(),
|
||||
fixed: 'left',
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
getRightFixedTable() {
|
||||
return this.getTable({
|
||||
columns: this.columnManager.rightColumns(),
|
||||
fixed: 'right',
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
getTable(options = {}) {
|
||||
const { columns, fixed } = options;
|
||||
const { prefixCls, scroll = {}, getBodyWrapper } = this.props;
|
||||
const { clsPrefix, scroll = {}, getBodyWrapper } = this.props;
|
||||
let { useFixedHeader } = this.props;
|
||||
const bodyStyle = { ...this.props.bodyStyle };
|
||||
const headStyle = {};
|
||||
|
||||
let tableClassName = '';
|
||||
if (scroll.x || fixed) {
|
||||
tableClassName = `${prefixCls}-fixed`;
|
||||
tableClassName = `${clsPrefix}-fixed`;
|
||||
bodyStyle.overflowX = bodyStyle.overflowX || 'auto';
|
||||
}
|
||||
|
||||
|
@ -459,7 +486,7 @@ const Table = React.createClass({
|
|||
}
|
||||
}
|
||||
const tableBody = hasBody ? getBodyWrapper(
|
||||
<tbody className={`${prefixCls}-tbody`}>
|
||||
<tbody className={`${clsPrefix}-tbody`}>
|
||||
{this.getRows(columns, fixed)}
|
||||
</tbody>
|
||||
) : null;
|
||||
|
@ -477,7 +504,7 @@ const Table = React.createClass({
|
|||
if (useFixedHeader) {
|
||||
headTable = (
|
||||
<div
|
||||
className={`${prefixCls}-header`}
|
||||
className={`${clsPrefix}-header`}
|
||||
ref={fixed ? null : 'headTable'}
|
||||
style={headStyle}
|
||||
onMouseOver={this.detectScrollTarget}
|
||||
|
@ -491,7 +518,7 @@ const Table = React.createClass({
|
|||
|
||||
let BodyTable = (
|
||||
<div
|
||||
className={`${prefixCls}-body`}
|
||||
className={`${clsPrefix}-body`}
|
||||
style={bodyStyle}
|
||||
ref="bodyTable"
|
||||
onMouseOver={this.detectScrollTarget}
|
||||
|
@ -513,11 +540,11 @@ const Table = React.createClass({
|
|||
delete bodyStyle.overflowY;
|
||||
BodyTable = (
|
||||
<div
|
||||
className={`${prefixCls}-body-outer`}
|
||||
className={`${clsPrefix}-body-outer`}
|
||||
style={{ ...bodyStyle }}
|
||||
>
|
||||
<div
|
||||
className={`${prefixCls}-body-inner`}
|
||||
className={`${clsPrefix}-body-inner`}
|
||||
ref={refName}
|
||||
onMouseOver={this.detectScrollTarget}
|
||||
onTouchStart={this.detectScrollTarget}
|
||||
|
@ -530,34 +557,34 @@ const Table = React.createClass({
|
|||
}
|
||||
|
||||
return <span>{headTable}{BodyTable}</span>;
|
||||
},
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
const { title, prefixCls } = this.props;
|
||||
const { title, clsPrefix } = this.props;
|
||||
return title ? (
|
||||
<div className={`${prefixCls}-title`}>
|
||||
<div className={`${clsPrefix}-title`}>
|
||||
{title(this.state.data)}
|
||||
</div>
|
||||
) : null;
|
||||
},
|
||||
}
|
||||
|
||||
getFooter() {
|
||||
const { footer, prefixCls } = this.props;
|
||||
const { footer, clsPrefix } = this.props;
|
||||
return footer ? (
|
||||
<div className={`${prefixCls}-footer`}>
|
||||
<div className={`${clsPrefix}-footer`}>
|
||||
{footer(this.state.data)}
|
||||
</div>
|
||||
) : null;
|
||||
},
|
||||
}
|
||||
|
||||
getEmptyText() {
|
||||
const { emptyText, prefixCls, data } = this.props;
|
||||
const { emptyText, clsPrefix, data } = this.props;
|
||||
return !data.length ? (
|
||||
<div className={`${prefixCls}-placeholder`}>
|
||||
<div className={`${clsPrefix}-placeholder`}>
|
||||
{emptyText()}
|
||||
</div>
|
||||
) : null;
|
||||
},
|
||||
}
|
||||
|
||||
getHeaderRowStyle(columns, rows) {
|
||||
const { fixedColumnsHeadRowsHeight } = this.state;
|
||||
|
@ -569,14 +596,14 @@ const Table = React.createClass({
|
|||
return { height: headerHeight / rows.length };
|
||||
}
|
||||
return null;
|
||||
},
|
||||
}
|
||||
|
||||
syncFixedTableRowHeight() {
|
||||
const { prefixCls } = this.props;
|
||||
const { clsPrefix } = this.props;
|
||||
const headRows = this.refs.headTable ?
|
||||
this.refs.headTable.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(
|
||||
headRows, row => row.getBoundingClientRect().height || 'auto'
|
||||
);
|
||||
|
@ -591,7 +618,7 @@ const Table = React.createClass({
|
|||
fixedColumnsHeadRowsHeight,
|
||||
fixedColumnsBodyRowsHeight,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
resetScrollY() {
|
||||
if (this.refs.headTable) {
|
||||
|
@ -600,22 +627,22 @@ const Table = React.createClass({
|
|||
if (this.refs.bodyTable) {
|
||||
this.refs.bodyTable.scrollLeft = 0;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
findExpandedRow(record, index) {
|
||||
const rows = this.getExpandedRows().filter(i => i === this.getRowKey(record, index));
|
||||
return rows[0];
|
||||
},
|
||||
}
|
||||
|
||||
isRowExpanded(record, index) {
|
||||
return typeof this.findExpandedRow(record, index) !== 'undefined';
|
||||
},
|
||||
}
|
||||
|
||||
detectScrollTarget(e) {
|
||||
if (this.scrollTarget !== e.currentTarget) {
|
||||
this.scrollTarget = e.currentTarget;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
handleBodyScroll(e) {
|
||||
// Prevent scrollTop setter trigger onScroll event
|
||||
|
@ -654,26 +681,26 @@ const Table = React.createClass({
|
|||
}
|
||||
// Remember last scrollLeft for scroll direction detecting.
|
||||
this.lastScrollLeft = e.target.scrollLeft;
|
||||
},
|
||||
}
|
||||
|
||||
handleRowHover(isHover, key) {
|
||||
this.store.setState({
|
||||
currentHoverKey: isHover ? key : null,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const prefixCls = props.prefixCls;
|
||||
const clsPrefix = props.clsPrefix;
|
||||
|
||||
let className = props.prefixCls;
|
||||
let className = props.clsPrefix;
|
||||
if (props.className) {
|
||||
className += ` ${props.className}`;
|
||||
}
|
||||
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() ||
|
||||
props.scroll.x ||
|
||||
|
@ -682,24 +709,27 @@ const Table = React.createClass({
|
|||
return (
|
||||
<div className={className} style={props.style}>
|
||||
{this.getTitle()}
|
||||
<div className={`${prefixCls}-content`}>
|
||||
<div className={`${clsPrefix}-content`}>
|
||||
{this.columnManager.isAnyColumnsLeftFixed() &&
|
||||
<div className={`${prefixCls}-fixed-left`}>
|
||||
<div className={`${clsPrefix}-fixed-left`}>
|
||||
{this.getLeftFixedTable()}
|
||||
</div>}
|
||||
<div className={isTableScroll ? `${prefixCls}-scroll` : ''}>
|
||||
<div className={isTableScroll ? `${clsPrefix}-scroll` : ''}>
|
||||
{this.getTable({ columns: this.columnManager.groupedColumns() })}
|
||||
{this.getEmptyText()}
|
||||
{this.getFooter()}
|
||||
</div>
|
||||
{this.columnManager.isAnyColumnsRightFixed() &&
|
||||
<div className={`${prefixCls}-fixed-right`}>
|
||||
<div className={`${clsPrefix}-fixed-right`}>
|
||||
{this.getRightFixedTable()}
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Table.propTypes = propTypes;
|
||||
Table.defaultProps = defaultProps;
|
||||
|
||||
export default Table;
|
|
@ -1,28 +1,34 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import objectPath from 'object-path';
|
||||
|
||||
const TableCell = React.createClass({
|
||||
propTypes: {
|
||||
const propTypes = {
|
||||
record: PropTypes.object,
|
||||
prefixCls: PropTypes.string,
|
||||
clsPrefix: PropTypes.string,
|
||||
index: PropTypes.number,
|
||||
indent: PropTypes.number,
|
||||
indentSize: PropTypes.number,
|
||||
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) {
|
||||
return text && !React.isValidElement(text) &&
|
||||
Object.prototype.toString.call(text) === '[object Object]';
|
||||
},
|
||||
}
|
||||
handleClick(e) {
|
||||
const { record, column: { onCellClick } } = this.props;
|
||||
if (onCellClick) {
|
||||
onCellClick(record, e);
|
||||
}
|
||||
},
|
||||
}
|
||||
render() {
|
||||
const { record, indentSize, prefixCls, indent,
|
||||
const { record, indentSize, clsPrefix, indent,
|
||||
index, expandIcon, column } = this.props;
|
||||
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)) {
|
||||
text = null;
|
||||
}
|
||||
|
@ -49,7 +55,7 @@ const TableCell = React.createClass({
|
|||
const indentText = expandIcon ? (
|
||||
<span
|
||||
style={{ paddingLeft: `${indentSize * indent}px` }}
|
||||
className={`${prefixCls}-indent indent-level-${indent}`}
|
||||
className={`${clsPrefix}-indent indent-level-${indent}`}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
|
@ -68,7 +74,9 @@ const TableCell = React.createClass({
|
|||
{text}
|
||||
</td>
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
TableCell.propTypes = propTypes;
|
||||
|
||||
export default TableCell;
|
|
@ -1,19 +1,23 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import shallowequal from 'shallowequal';
|
||||
|
||||
export default React.createClass({
|
||||
propTypes: {
|
||||
prefixCls: PropTypes.string,
|
||||
const propTypes = {
|
||||
clsPrefix: PropTypes.string,
|
||||
rowStyle: PropTypes.object,
|
||||
rows: PropTypes.array,
|
||||
},
|
||||
}
|
||||
|
||||
class TableHeader extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
}
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return !shallowequal(nextProps, this.props);
|
||||
},
|
||||
}
|
||||
render() {
|
||||
const { prefixCls, rowStyle, rows } = this.props;
|
||||
const { clsPrefix, rowStyle, rows } = this.props;
|
||||
return (
|
||||
<thead className={`${prefixCls}-thead`}>
|
||||
<thead className={`${clsPrefix}-thead`}>
|
||||
{
|
||||
rows.map((row, index) => (
|
||||
<tr key={index} style={rowStyle}>
|
||||
|
@ -23,5 +27,9 @@ export default React.createClass({
|
|||
}
|
||||
</thead>
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
TableHeader.propTypes = propTypes;
|
||||
|
||||
export default TableHeader;
|
|
@ -1,14 +1,13 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import TableCell from './TableCell';
|
||||
import ExpandIcon from './ExpandIcon';
|
||||
|
||||
const TableRow = React.createClass({
|
||||
propTypes: {
|
||||
const propTypes = {
|
||||
onDestroy: PropTypes.func,
|
||||
onRowClick: PropTypes.func,
|
||||
onRowDoubleClick: PropTypes.func,
|
||||
record: PropTypes.object,
|
||||
prefixCls: PropTypes.string,
|
||||
clsPrefix: PropTypes.string,
|
||||
expandIconColumnIndex: PropTypes.number,
|
||||
onHover: PropTypes.func,
|
||||
columns: PropTypes.array,
|
||||
|
@ -29,24 +28,30 @@ const TableRow = React.createClass({
|
|||
expandIconAsCell: PropTypes.bool,
|
||||
expandRowByClick: PropTypes.bool,
|
||||
store: PropTypes.object.isRequired,
|
||||
},
|
||||
};
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
onRowClick() {},
|
||||
onRowDoubleClick() {},
|
||||
onDestroy() {},
|
||||
expandIconColumnIndex: 0,
|
||||
expandRowByClick: false,
|
||||
onHover() {},
|
||||
};
|
||||
},
|
||||
const defaultProps = {
|
||||
onRowClick() {},
|
||||
onRowDoubleClick() {},
|
||||
onDestroy() {},
|
||||
expandIconColumnIndex: 0,
|
||||
expandRowByClick: false,
|
||||
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() {
|
||||
const { store, hoverKey } = this.props;
|
||||
|
@ -57,7 +62,7 @@ const TableRow = React.createClass({
|
|||
this.setState({ hovered: false });
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { record, onDestroy, index } = this.props;
|
||||
|
@ -65,7 +70,7 @@ const TableRow = React.createClass({
|
|||
if (this.unsubscribe) {
|
||||
this.unsubscribe();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
onRowClick(event) {
|
||||
const {
|
||||
|
@ -81,26 +86,26 @@ const TableRow = React.createClass({
|
|||
onExpand(!expanded, record, index);
|
||||
}
|
||||
onRowClick(record, index, event);
|
||||
},
|
||||
}
|
||||
|
||||
onRowDoubleClick(event) {
|
||||
const { record, index, onRowDoubleClick } = this.props;
|
||||
onRowDoubleClick(record, index, event);
|
||||
},
|
||||
}
|
||||
|
||||
onMouseEnter() {
|
||||
const { onHover, hoverKey } = this.props;
|
||||
onHover(true, hoverKey);
|
||||
},
|
||||
}
|
||||
|
||||
onMouseLeave() {
|
||||
const { onHover, hoverKey } = this.props;
|
||||
onHover(false, hoverKey);
|
||||
},
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
prefixCls, columns, record, height, visible, index,
|
||||
clsPrefix, columns, record, height, visible, index,
|
||||
expandIconColumnIndex, expandIconAsCell, expanded, expandRowByClick,
|
||||
expandable, onExpand, needIndentSpaced, indent, indentSize,
|
||||
} = this.props;
|
||||
|
@ -108,7 +113,7 @@ const TableRow = React.createClass({
|
|||
let { className } = this.props;
|
||||
|
||||
if (this.state.hovered) {
|
||||
className += ` ${prefixCls}-hover`;
|
||||
className += ` ${clsPrefix}-hover`;
|
||||
}
|
||||
|
||||
const cells = [];
|
||||
|
@ -116,7 +121,7 @@ const TableRow = React.createClass({
|
|||
const expandIcon = (
|
||||
<ExpandIcon
|
||||
expandable={expandable}
|
||||
prefixCls={prefixCls}
|
||||
clsPrefix={clsPrefix}
|
||||
onExpand={onExpand}
|
||||
needIndentSpaced={needIndentSpaced}
|
||||
expanded={expanded}
|
||||
|
@ -128,7 +133,7 @@ const TableRow = React.createClass({
|
|||
if (expandIconAsCell && i === 0) {
|
||||
cells.push(
|
||||
<td
|
||||
className={`${prefixCls}-expand-icon-cell`}
|
||||
className={`${clsPrefix}-expand-icon-cell`}
|
||||
key="rc-table-expand-icon-cell"
|
||||
>
|
||||
{expandIcon}
|
||||
|
@ -139,7 +144,7 @@ const TableRow = React.createClass({
|
|||
? false : (i === expandIconColumnIndex);
|
||||
cells.push(
|
||||
<TableCell
|
||||
prefixCls={prefixCls}
|
||||
clsPrefix={clsPrefix}
|
||||
record={record}
|
||||
indentSize={indentSize}
|
||||
indent={indent}
|
||||
|
@ -161,13 +166,16 @@ const TableRow = React.createClass({
|
|||
onDoubleClick={this.onRowDoubleClick}
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
className={`${prefixCls} ${className} ${prefixCls}-level-${indent}`}
|
||||
className={`${clsPrefix} ${className} ${clsPrefix}-level-${indent}`}
|
||||
style={style}
|
||||
>
|
||||
{cells}
|
||||
</tr>
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
TableRow.propTypes = propTypes;
|
||||
TableRow.defaultProps = defaultProps;
|
||||
|
||||
export default TableRow;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
$table-border-color: #e9e9e9;
|
||||
|
||||
.u-table.bordered {
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid $table-border-color;
|
||||
}
|
||||
}
|
145
src/index.scss
145
src/index.scss
|
@ -2,10 +2,16 @@
|
|||
$text-color : #666;
|
||||
$font-size-base : 12px;
|
||||
$line-height: 1.5;
|
||||
$table-border-color: #e9e9e9;
|
||||
$table-border-color: $border-color-base;
|
||||
$table-head-background-color: #f7f7f7;
|
||||
$vertical-padding: 16px;
|
||||
$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 {
|
||||
font-size: $font-size-base;
|
||||
|
@ -15,6 +21,38 @@ $horizontal-padding: 8px;
|
|||
line-height: $line-height;
|
||||
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 {
|
||||
overflow: auto;
|
||||
}
|
||||
|
@ -64,39 +102,6 @@ $horizontal-padding: 8px;
|
|||
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 {
|
||||
width: 10px;
|
||||
}
|
||||
|
@ -209,3 +214,75 @@ $horizontal-padding: 8px;
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue