Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/ExpandIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';

export default ({ expandable, prefixCls, onExpand, needIndentSpaced, expanded, record }) => {
if (expandable) {
const expandClassName = expanded ? 'expanded' : 'collapsed';
return (
<span
className={`${prefixCls}-expand-icon ${prefixCls}-${expandClassName}`}
onClick={() => onExpand(!expanded, record)}
/>
);
} else if (needIndentSpaced) {
return <span className={`${prefixCls}-expand-icon ${prefixCls}-spaced`} />;
}
return null;
};
90 changes: 90 additions & 0 deletions src/TableCell.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { PropTypes } from 'react';
import objectPath from 'object-path';
import shallowequal from 'shallowequal';
import ExpandIcon from './ExpandIcon';

const TableCell = React.createClass({
propTypes: {
record: PropTypes.object,
prefixCls: PropTypes.string,
isColumnHaveExpandIcon: PropTypes.bool,
index: PropTypes.number,
expanded: PropTypes.bool,
expandable: PropTypes.any,
onExpand: PropTypes.func,
needIndentSpaced: PropTypes.bool,
className: PropTypes.string,
indent: PropTypes.number,
indentSize: PropTypes.number,
expandIconAsCell: PropTypes.bool,
dataIndex: PropTypes.string,
render: PropTypes.func,
},
shouldComponentUpdate(nextProps) {
return !shallowequal(nextProps, this.props);
},
isInvalidRenderCellText(text) {
return text && !React.isValidElement(text) &&
Object.prototype.toString.call(text) === '[object Object]';
},
render() {
const { className, dataIndex, render, record, indentSize, prefixCls, indent,
isColumnHaveExpandIcon, index, expandable, onExpand, needIndentSpaced,
expanded } = this.props;

let text = objectPath.get(record, dataIndex);
let tdProps;
let colSpan;
let rowSpan;

if (render) {
text = render(text, record, index);
if (this.isInvalidRenderCellText(text)) {
tdProps = text.props || {};
rowSpan = tdProps.rowSpan;
colSpan = tdProps.colSpan;
text = text.children;
}
}

// Fix https://github.com/ant-design/ant-design/issues/1202
if (this.isInvalidRenderCellText(text)) {
text = null;
}

const expandIcon = (
<ExpandIcon
expandable={expandable}
prefixCls={prefixCls}
onExpand={onExpand}
needIndentSpaced={needIndentSpaced}
expanded={expanded}
record={record}
/>
);

const indentText = (
<span
style={{ paddingLeft: `${indentSize * indent}px` }}
className={`${prefixCls}-indent indent-level-${indent}`}
/>
);

if (rowSpan === 0 || colSpan === 0) {
return null;
}
return (
<td
colSpan={colSpan}
rowSpan={rowSpan}
className={className}
>
{isColumnHaveExpandIcon ? indentText : null}
{isColumnHaveExpandIcon ? expandIcon : null}
{text}
</td>
);
},
});

export default TableCell;
141 changes: 51 additions & 90 deletions src/TableRow.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { PropTypes } from 'react';
import objectPath from 'object-path';
import shallowequal from 'shallowequal';
import TableCell from './TableCell';
import ExpandIcon from './ExpandIcon';

const TableRow = React.createClass({
propTypes: {
Expand All @@ -9,6 +11,19 @@ const TableRow = React.createClass({
prefixCls: PropTypes.string,
expandIconColumnIndex: PropTypes.number,
onHover: PropTypes.func,
columns: PropTypes.array,
style: PropTypes.object,
visible: PropTypes.bool,
index: PropTypes.number,
hoverKey: PropTypes.any,
expanded: PropTypes.bool,
expandable: PropTypes.any,
onExpand: PropTypes.func,
needIndentSpaced: PropTypes.bool,
className: PropTypes.string,
indent: PropTypes.number,
indentSize: PropTypes.number,
expandIconAsCell: PropTypes.bool,
},

getDefaultProps() {
Expand All @@ -20,119 +35,65 @@ const TableRow = React.createClass({
};
},

componentWillUnmount() {
this.props.onDestroy(this.props.record);
shouldComponentUpdate(nextProps) {
return !shallowequal(nextProps, this.props);
},

isInvalidRenderCellText(text) {
return text && !React.isValidElement(text) &&
Object.prototype.toString.call(text) === '[object Object]';
componentWillUnmount() {
this.props.onDestroy(this.props.record);
},

render() {
const props = this.props;
const prefixCls = props.prefixCls;
const columns = props.columns;
const record = props.record;
const style = props.style;
const visible = props.visible;
const index = props.index;
const hoverKey = props.hoverKey;
const {
prefixCls, columns, record, style, visible, index, hoverKey,
expandIconColumnIndex, expandIconAsCell, onRowClick, onHover, expanded,
expandable, onExpand, needIndentSpaced, className, indent, indentSize,
} = this.props;

const cells = [];
const expanded = props.expanded;
const expandable = props.expandable;
const expandIconAsCell = props.expandIconAsCell;
const indent = props.indent;
const indentSize = props.indentSize;
const needIndentSpaced = props.needIndentSpaced;
const onRowClick = props.onRowClick;
const expandIconColumnIndex = props.expandIconColumnIndex;

for (let i = 0; i < columns.length; i++) {
const col = columns[i];
const colClassName = col.className || '';
const render = col.render;
let text = objectPath.get(record, col.dataIndex);

let expandIcon;
let tdProps;
let colSpan;
let rowSpan;
let notRender = false;

if (expandable) {
const expandClassName = expanded ? 'expanded' : 'collapsed';
expandIcon = (
<span
className={`${prefixCls}-expand-icon ${prefixCls}-${expandClassName}`}
onClick={props.onExpand.bind(null, !expanded, record)}
/>
);
} else if (needIndentSpaced) {
expandIcon = <span className={`${prefixCls}-expand-icon ${prefixCls}-spaced`} />;
}

const isColumnHaveExpandIcon = expandIconAsCell ? false : (i === expandIconColumnIndex);

if (expandIconAsCell && i === 0) {
cells.push(
<td
className={`${prefixCls}-expand-icon-cell`}
key="rc-table-expand-icon-cell"
>
{expandIcon}
<ExpandIcon
expandable={expandable}
prefixCls={prefixCls}
onExpand={onExpand}
needIndentSpaced={needIndentSpaced}
expanded={expanded}
record={record}
/>
</td>
);
}

if (render) {
text = render(text, record, index);
if (this.isInvalidRenderCellText(text)) {
tdProps = text.props || {};
rowSpan = tdProps.rowSpan;
colSpan = tdProps.colSpan;
text = text.children;
}
}

// Fix https://github.com/ant-design/ant-design/issues/1202
if (this.isInvalidRenderCellText(text)) {
text = null;
}

if (rowSpan === 0 || colSpan === 0) {
notRender = true;
}

const indentText = (
<span
style={{ paddingLeft: `${indentSize * indent}px` }}
className={`${prefixCls}-indent indent-level-${indent}`}
const isColumnHaveExpandIcon = expandIconAsCell ? false : (i === expandIconColumnIndex);
cells.push(
<TableCell
prefixCls={prefixCls}
record={record}
indentSize={indentSize}
indent={indent}
index={index}
expandable={expandable}
onExpand={onExpand}
needIndentSpaced={needIndentSpaced}
expanded={expanded}
isColumnHaveExpandIcon={isColumnHaveExpandIcon}
{...columns[i]}
/>
);

if (!notRender) {
cells.push(
<td
key={col.key}
colSpan={colSpan}
rowSpan={rowSpan}
className={colClassName}
>
{isColumnHaveExpandIcon ? indentText : null}
{isColumnHaveExpandIcon ? expandIcon : null}
{text}
</td>
);
}
}

return (
<tr
onClick={onRowClick.bind(null, record, index)}
onMouseEnter={props.onHover.bind(null, true, hoverKey)}
onMouseLeave={props.onHover.bind(null, false, hoverKey)}
className={`${prefixCls} ${props.className} ${prefixCls}-level-${indent}`}
onMouseEnter={onHover.bind(null, true, hoverKey)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看能不能不要每次 bind

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗯,这里不需要 bind 的。直接 onMouseEnter={() => onHover(true, hoverKey)}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是尽量不要在 render 中生成函数

onMouseLeave={onHover.bind(null, false, hoverKey)}
className={`${prefixCls} ${className} ${prefixCls}-level-${indent}`}
style={visible ? style : { ...style, display: 'none' }}
>
{cells}
Expand Down