Skip to content

Commit 715ff05

Browse files
committed
Allow overriding elements
1 parent b66ec99 commit 715ff05

13 files changed

+288
-40
lines changed
File renamed without 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>Custom Component</h2>
184+
<Demo />
185+
</div>,
186+
document.getElementById('__react-content')
187+
);

examples/styled-components.html

Whitespace-only changes.

examples/custom-component.js renamed to examples/styled-components.js

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
3+
import styled from 'styled-components';
34
import Table from 'rc-table';
45
import 'rc-table/assets/index.less';
56

@@ -23,25 +24,15 @@ const data = [
2324
{ a: '1333', c: 'eee', d: 2, key: '3' },
2425
];
2526

26-
const MyTable = props => <table name="my-table" {...props} />;
27-
const HeaderWrapper = props => <thead name="my-header-wrapper" {...props} />;
28-
const HeaderRow = props => <tr name="my-header-row" {...props} />;
29-
const HeaderCell = props => <th name="my-header-cell" {...props} />;
30-
const BodyWrapper = props => <tbody name="my-body-wrapper" {...props} />;
31-
const BodyRow = props => <tr name="my-body-row" {...props} />;
32-
const BodyCell = props => <td name="my-body-cell" {...props} />;
27+
const BodyRow = styled.tr`
28+
&:hover {
29+
background: palevioletred !important;
30+
}
31+
`;
3332

3433
const components = {
35-
table: MyTable,
36-
header: {
37-
wrapper: HeaderWrapper,
38-
row: HeaderRow,
39-
cell: HeaderCell,
40-
},
4134
body: {
42-
wrapper: BodyWrapper,
4335
row: BodyRow,
44-
cell: BodyCell,
4536
},
4637
};
4738

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: 8 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,7 +44,7 @@ class BaseTable extends React.Component {
4444
onRowContextMenu,
4545
onRowMouseEnter,
4646
onRowMouseLeave,
47-
components,
47+
onRow,
4848
} = table.props;
4949
const { getRowKey, fixed, expander } = this.props;
5050

@@ -96,6 +96,7 @@ class BaseTable extends React.Component {
9696
prefixCls={rowPrefixCls}
9797
childrenColumnName={childrenColumnName}
9898
columns={leafColumns}
99+
onRow={onRow}
99100
onRowDoubleClick={onRowDoubleClick}
100101
onRowContextMenu={onRowContextMenu}
101102
onRowMouseEnter={onRowMouseEnter}
@@ -131,7 +132,9 @@ class BaseTable extends React.Component {
131132
}
132133

133134
render() {
134-
const { prefixCls, scroll, data, getBodyWrapper, components } = this.context.table.props;
135+
const { table } = this.context;
136+
const { components } = table;
137+
const { prefixCls, scroll, data, getBodyWrapper } = table.props;
135138
const { expander, tableClassName, hasHead, hasBody, fixed, columns } = this.props;
136139
const tableStyle = {};
137140

@@ -144,9 +147,8 @@ class BaseTable extends React.Component {
144147
}
145148
}
146149

147-
const Table = hasBody ? (components.table || 'table') : 'table';
148-
const BodyWrapper = components.body && components.body.wrapper || 'tbody';
149-
150+
const Table = hasBody ? components.table : 'table';
151+
const BodyWrapper = components.body.wrapper;
150152

151153
return (
152154
<Table className={tableClassName} style={tableStyle} key="table">

src/ExpandableTable.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ class ExpandableTable extends React.Component {
146146
}
147147

148148
const rowKey = `${ancestorKeys[0]}-extra-row`;
149+
const components = {
150+
body: {
151+
row: 'tr',
152+
cell: 'td',
153+
},
154+
};
149155

150156
return (
151157
<TableRow
@@ -157,6 +163,7 @@ class ExpandableTable extends React.Component {
157163
prefixCls={`${prefixCls}-expanded-row`}
158164
indent={1}
159165
fixed={fixed}
166+
components={components}
160167
/>
161168
);
162169
}

src/Table.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { debounce, warningOnce } from './utils';
44
import shallowequal from 'shallowequal';
55
import addEventListener from 'rc-util/lib/Dom/addEventListener';
66
import { Provider, create } from 'mini-store';
7+
import merge from 'lodash.merge';
78
import ColumnManager from './ColumnManager';
89
import classes from 'component-classes';
910
import HeadTable from './HeadTable';
@@ -20,6 +21,7 @@ export default class Table extends React.Component {
2021
style: PropTypes.object,
2122
rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
2223
rowClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
24+
onRow: PropTypes.func,
2325
onRowClick: PropTypes.func,
2426
onRowDoubleClick: PropTypes.func,
2527
onRowContextMenu: PropTypes.func,
@@ -51,13 +53,15 @@ export default class Table extends React.Component {
5153

5254
static childContextTypes = {
5355
table: PropTypes.any,
56+
components: PropTypes.any,
5457
}
5558

5659
static defaultProps = {
5760
data: [],
5861
useFixedHeader: false,
5962
rowKey: 'key',
6063
rowClassName: () => '',
64+
onRow() {},
6165
onRowClick() {},
6266
onRowDoubleClick() {},
6367
onRowContextMenu() {},
@@ -71,7 +75,6 @@ export default class Table extends React.Component {
7175
rowRef: () => null,
7276
getBodyWrapper: body => body,
7377
emptyText: () => 'No Data',
74-
components: {},
7578
}
7679

7780
constructor(props) {
@@ -96,6 +99,19 @@ export default class Table extends React.Component {
9699
props: this.props,
97100
columnManager: this.columnManager,
98101
saveRef: this.saveRef,
102+
components: merge({
103+
table: 'table',
104+
header: {
105+
wrapper: 'thead',
106+
row: 'tr',
107+
cell: 'th',
108+
},
109+
body: {
110+
wrapper: 'tbody',
111+
row: 'tr',
112+
cell: 'td',
113+
},
114+
}, this.props.components),
99115
},
100116
};
101117
}

0 commit comments

Comments
 (0)