Skip to content

Commit 5c9df88

Browse files
authored
Merge pull request #171 from react-component/elements-overriding
Elements overriding
2 parents 0a9207b + e7458ae commit 5c9df88

14 files changed

+865
-35
lines changed

examples/react-dnd.html

Whitespace-only changes.

examples/react-dnd.js

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/* eslint-disable no-unused-expressions,new-cap */
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
import { injectGlobal } from 'styled-components';
5+
import update from 'immutability-helper';
6+
import { DragDropContext, DragSource, DropTarget } from 'react-dnd';
7+
import HTML5Backend from 'react-dnd-html5-backend';
8+
import Table from 'rc-table';
9+
import 'rc-table/assets/index.less';
10+
11+
injectGlobal`
12+
tr.drop-over-downward td {
13+
border-bottom: 2px dashed red;
14+
}
15+
16+
tr.drop-over-upward td {
17+
border-top: 2px dashed red;
18+
}
19+
`;
20+
21+
function dragDirection(
22+
dragIndex,
23+
hoverIndex,
24+
initialClientOffset,
25+
clientOffset,
26+
sourceClientOffset,
27+
) {
28+
const hoverMiddleY = (initialClientOffset.y - sourceClientOffset.y) / 2;
29+
const hoverClientY = clientOffset.y - sourceClientOffset.y;
30+
if (dragIndex < hoverIndex && hoverClientY > hoverMiddleY) {
31+
return 'downward';
32+
}
33+
if (dragIndex > hoverIndex && hoverClientY < hoverMiddleY) {
34+
return 'upward';
35+
}
36+
}
37+
38+
let BodyRow = (props) => {
39+
const {
40+
isOver,
41+
connectDragSource,
42+
connectDropTarget,
43+
moveRow,
44+
dragRow,
45+
clientOffset,
46+
sourceClientOffset,
47+
initialClientOffset,
48+
...restProps,
49+
} = props;
50+
const style = { cursor: 'move' };
51+
52+
let className = restProps.className;
53+
if (isOver && initialClientOffset) {
54+
const direction = dragDirection(
55+
dragRow.index,
56+
restProps.index,
57+
initialClientOffset,
58+
clientOffset,
59+
sourceClientOffset
60+
);
61+
if (direction === 'downward') {
62+
className += ' drop-over-downward';
63+
}
64+
if (direction === 'upward') {
65+
className += ' drop-over-upward';
66+
}
67+
}
68+
69+
return connectDragSource(
70+
connectDropTarget(
71+
<tr
72+
{...restProps}
73+
className={className}
74+
style={style}
75+
/>
76+
)
77+
);
78+
};
79+
80+
const rowSource = {
81+
beginDrag(props) {
82+
return {
83+
index: props.index,
84+
};
85+
},
86+
};
87+
88+
const rowTarget = {
89+
drop(props, monitor) {
90+
const dragIndex = monitor.getItem().index;
91+
const hoverIndex = props.index;
92+
93+
// Don't replace items with themselves
94+
if (dragIndex === hoverIndex) {
95+
return;
96+
}
97+
98+
// Time to actually perform the action
99+
props.moveRow(dragIndex, hoverIndex);
100+
101+
// Note: we're mutating the monitor item here!
102+
// Generally it's better to avoid mutations,
103+
// but it's good here for the sake of performance
104+
// to avoid expensive index searches.
105+
monitor.getItem().index = hoverIndex;
106+
},
107+
};
108+
109+
BodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
110+
connectDropTarget: connect.dropTarget(),
111+
isOver: monitor.isOver(),
112+
sourceClientOffset: monitor.getSourceClientOffset(),
113+
}))(
114+
DragSource('row', rowSource, (connect, monitor) => ({
115+
connectDragSource: connect.dragSource(),
116+
dragRow: monitor.getItem(),
117+
clientOffset: monitor.getClientOffset(),
118+
initialClientOffset: monitor.getInitialClientOffset(),
119+
}))(BodyRow)
120+
);
121+
122+
const columns = [
123+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
124+
{ id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
125+
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
126+
{
127+
title: 'Operations',
128+
dataIndex: '',
129+
key: 'd',
130+
render() {
131+
return <a href="#">Operations</a>;
132+
},
133+
},
134+
];
135+
136+
class Demo extends React.Component {
137+
state = {
138+
data: [
139+
{ a: '123', key: '1' },
140+
{ a: 'cdd', b: 'edd', key: '2' },
141+
{ a: '1333', c: 'eee', d: 2, key: '3' },
142+
],
143+
}
144+
145+
components = {
146+
body: {
147+
row: BodyRow,
148+
},
149+
}
150+
151+
moveRow = (dragIndex, hoverIndex) => {
152+
const { data } = this.state;
153+
const dragRow = data[dragIndex];
154+
155+
this.setState(
156+
update(this.state, {
157+
data: {
158+
$splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
159+
},
160+
}),
161+
);
162+
}
163+
164+
render() {
165+
return (
166+
<Table
167+
columns={columns}
168+
data={this.state.data}
169+
components={this.components}
170+
onRow={(record, index) => ({
171+
index,
172+
moveRow: this.moveRow,
173+
})}
174+
/>
175+
);
176+
}
177+
}
178+
179+
Demo = DragDropContext(HTML5Backend)(Demo);
180+
181+
ReactDOM.render(
182+
<div>
183+
<h2>Integrate with react-dnd</h2>
184+
<Demo />
185+
</div>,
186+
document.getElementById('__react-content')
187+
);

examples/styled-components.html

Whitespace-only changes.

examples/styled-components.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import styled from 'styled-components';
4+
import Table from 'rc-table';
5+
import 'rc-table/assets/index.less';
6+
7+
const columns = [
8+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
9+
{ id: '123', title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
10+
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
11+
{
12+
title: 'Operations',
13+
dataIndex: '',
14+
key: 'd',
15+
render() {
16+
return <a href="#">Operations</a>;
17+
},
18+
},
19+
];
20+
21+
const data = [
22+
{ a: '123', key: '1' },
23+
{ a: 'cdd', b: 'edd', key: '2' },
24+
{ a: '1333', c: 'eee', d: 2, key: '3' },
25+
];
26+
27+
const BodyRow = styled.tr`
28+
&:hover {
29+
background: palevioletred !important;
30+
}
31+
`;
32+
33+
const components = {
34+
body: {
35+
row: BodyRow,
36+
},
37+
};
38+
39+
ReactDOM.render(
40+
<div>
41+
<h2>Integrate with styled-components</h2>
42+
<Table columns={columns} data={data} components={components} />
43+
</div>,
44+
document.getElementById('__react-content')
45+
);

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"babel-runtime": "6.x",
7272
"component-classes": "^1.2.6",
7373
"lodash.get": "^4.4.2",
74+
"lodash.merge": "^4.6.0",
7475
"mini-store": "^1.0.2",
7576
"prop-types": "^15.5.8",
7677
"rc-util": "^4.0.4",
@@ -82,15 +83,20 @@
8283
"enzyme": "^3.1.0",
8384
"enzyme-adapter-react-16": "^1.0.1",
8485
"enzyme-to-json": "^3.1.2",
86+
"immutability-helper": "^2.4.0",
8587
"jest": "^21.2.1",
8688
"pre-commit": "1.x",
8789
"rc-animate": "^2.3.0",
8890
"rc-dropdown": "~2.0.1",
8991
"rc-menu": "^5.0.11",
9092
"rc-tools": "7.x",
9193
"react": "^16.0.0",
94+
"react-dnd": "^2.5.4",
95+
"react-dnd-html5-backend": "^2.5.4",
9296
"react-dom": "^16.0.0",
93-
"react-test-renderer": "^16.0.0"
97+
"react-test-renderer": "^16.0.0",
98+
"react-virtualized": "^9.12.0",
99+
"styled-components": "^2.2.1"
94100
},
95101
"pre-commit": [
96102
"lint"

src/BaseTable.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class BaseTable extends React.Component {
3333

3434
renderRows = (renderData, indent, ancestorKeys = []) => {
3535
const { table } = this.context;
36-
const { columnManager } = table;
36+
const { columnManager, components } = table;
3737
const {
3838
prefixCls,
3939
childrenColumnName,
@@ -44,6 +44,7 @@ class BaseTable extends React.Component {
4444
onRowContextMenu,
4545
onRowMouseEnter,
4646
onRowMouseLeave,
47+
onRow,
4748
} = table.props;
4849
const { getRowKey, fixed, expander } = this.props;
4950

@@ -95,6 +96,7 @@ class BaseTable extends React.Component {
9596
prefixCls={rowPrefixCls}
9697
childrenColumnName={childrenColumnName}
9798
columns={leafColumns}
99+
onRow={onRow}
98100
onRowDoubleClick={onRowDoubleClick}
99101
onRowContextMenu={onRowContextMenu}
100102
onRowMouseEnter={onRowMouseEnter}
@@ -103,6 +105,7 @@ class BaseTable extends React.Component {
103105
rowKey={key}
104106
ancestorKeys={ancestorKeys}
105107
ref={rowRef(record, i, indent)}
108+
components={components}
106109
{...expandableRow}
107110
/>
108111
)}
@@ -129,7 +132,9 @@ class BaseTable extends React.Component {
129132
}
130133

131134
render() {
132-
const { prefixCls, scroll, data, getBodyWrapper } = this.context.table.props;
135+
const { table } = this.context;
136+
const { components } = table;
137+
const { prefixCls, scroll, data, getBodyWrapper } = table.props;
133138
const { expander, tableClassName, hasHead, hasBody, fixed, columns } = this.props;
134139
const tableStyle = {};
135140

@@ -142,16 +147,19 @@ class BaseTable extends React.Component {
142147
}
143148
}
144149

150+
const Table = hasBody ? components.table : 'table';
151+
const BodyWrapper = components.body.wrapper;
152+
145153
return (
146-
<table className={tableClassName} style={tableStyle} key="table">
154+
<Table className={tableClassName} style={tableStyle} key="table">
147155
<ColGroup columns={columns} fixed={fixed} />
148156
{hasHead && <TableHeader expander={expander} columns={columns} fixed={fixed} /> }
149157
{hasBody && getBodyWrapper(
150-
<tbody className={`${prefixCls}-tbody`}>
158+
<BodyWrapper className={`${prefixCls}-tbody`}>
151159
{this.renderRows(data, 0)}
152-
</tbody>
160+
</BodyWrapper>
153161
)}
154-
</table>
162+
</Table>
155163
);
156164
}
157165
}

src/ExpandableTable.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,14 @@ class ExpandableTable extends React.Component {
111111
return;
112112
}
113113

114-
rows[0].unshift({
115-
key: 'rc-table-expandIconAsCell',
114+
const iconColumn = {
115+
key: 'rc-table-expand-icon-cell',
116116
className: `${prefixCls}-expand-icon-th`,
117117
title: '',
118118
rowSpan: rows.length,
119-
});
119+
};
120+
121+
rows[0].unshift({ ...iconColumn, column: iconColumn });
120122
}
121123

122124
renderExpandedRow(content, className, ancestorKeys, fixed) {
@@ -146,6 +148,12 @@ class ExpandableTable extends React.Component {
146148
}
147149

148150
const rowKey = `${ancestorKeys[0]}-extra-row`;
151+
const components = {
152+
body: {
153+
row: 'tr',
154+
cell: 'td',
155+
},
156+
};
149157

150158
return (
151159
<TableRow
@@ -157,6 +165,7 @@ class ExpandableTable extends React.Component {
157165
prefixCls={`${prefixCls}-expanded-row`}
158166
indent={1}
159167
fixed={fixed}
168+
components={components}
160169
/>
161170
);
162171
}

0 commit comments

Comments
 (0)