mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-16 23:10:17 +00:00
Refactor complete
May need to remove some redundant code
This commit is contained in:
+12
-10
@@ -10,13 +10,14 @@ import '../../react-table.css'
|
||||
import Readme from './stories/Readme.js'
|
||||
import HOCReadme from './stories/HOCReadme.js'
|
||||
|
||||
import { TreeTable, SelectTable } from './examples/index'
|
||||
|
||||
const exampleStories = [
|
||||
// examples
|
||||
{ name: 'TreeTable', component: TreeTable },
|
||||
{ name: 'SelectTable', component: SelectTable },
|
||||
]
|
||||
// import { TreeTable, SelectTable, SelectTreeTable } from './examples/index'
|
||||
//
|
||||
// const exampleStories = [
|
||||
// // examples
|
||||
// { name: 'TreeTable', component: TreeTable },
|
||||
// { name: 'SelectTable', component: SelectTable },
|
||||
// { name: 'SelectTreeTable', component: SelectTreeTable },
|
||||
// ]
|
||||
|
||||
const stories = [
|
||||
{ name: 'Readme', component: Readme },
|
||||
@@ -64,10 +65,11 @@ const stories = [
|
||||
name: 'Multiple Pagers (Top and Bottom)',
|
||||
component: CodeSandbox('VEZ8OgvX'),
|
||||
},
|
||||
|
||||
// other examples
|
||||
...exampleStories,
|
||||
|
||||
{ name: 'Tree Table', component: CodeSandbox('lxmr4wynzq') },
|
||||
{ name: 'Select Table', component: CodeSandbox('7yq5ylw09j') },
|
||||
{ name: 'Select Tree Table', component: CodeSandbox('2p7jp4klwp') },
|
||||
|
||||
]
|
||||
|
||||
export default class App extends React.Component {
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
import TreeTable from './treetable'
|
||||
import SelectTable from './selecttable'
|
||||
import SelectTreeTable from './selecttreetable'
|
||||
|
||||
export {
|
||||
TreeTable,
|
||||
SelectTable,
|
||||
SelectTreeTable,
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export class ComponentTest extends React.Component {
|
||||
columns: null,
|
||||
selection: [],
|
||||
selectAll: false,
|
||||
selectType: 'radio',
|
||||
selectType: 'checkbox',
|
||||
};
|
||||
}
|
||||
componentDidMount()
|
||||
@@ -111,12 +111,15 @@ export class ComponentTest extends React.Component {
|
||||
if(selectAll)
|
||||
{
|
||||
// we need to get at the internals of ReactTable
|
||||
const wrappedInstance = this.checkboxTable.getWrappedInstance();
|
||||
const wrappedInstance = this.selectTable.getWrappedInstance();
|
||||
// the 'sortedData' property contains the currently accessible records based on the filter and sort
|
||||
const currentRecords = wrappedInstance.getResolvedState().sortedData;
|
||||
// we just push all the IDs onto the selection array
|
||||
currentRecords.forEach((item)=>{
|
||||
selection.push(item._original._id);
|
||||
if(item._original)
|
||||
{
|
||||
selection.push(item._original._id);
|
||||
}
|
||||
})
|
||||
}
|
||||
this.setState({selectAll,selection})
|
||||
@@ -136,7 +139,7 @@ export class ComponentTest extends React.Component {
|
||||
this.setState({ selectType: this.state.selectType === 'radio' ? 'checkbox' : 'radio', selection: [], selectAll: false, });
|
||||
}
|
||||
render(){
|
||||
const { toggleSelection, toggleAll, isSelected, logSelection, toggleType, } = this;
|
||||
const { toggleSelection, toggleAll, isSelected, logSelection, toggleType } = this;
|
||||
const { data, columns, selectAll, selectType } = this.state;
|
||||
const extraProps =
|
||||
{
|
||||
@@ -148,7 +151,7 @@ export class ComponentTest extends React.Component {
|
||||
}
|
||||
return (
|
||||
<div style={{ padding: '10px'}}>
|
||||
<h1>react-table - Checkbox Table</h1>
|
||||
<h1>react-table - Select Table</h1>
|
||||
<button onClick={toggleType}>Select Type: <strong>{selectType}</strong></button>
|
||||
<button onClick={logSelection}>Log Selection to Console</button>
|
||||
{` (${this.state.selection.length}) selected`}
|
||||
@@ -157,7 +160,7 @@ export class ComponentTest extends React.Component {
|
||||
<SelectTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
ref={(r)=>this.checkboxTable = r}
|
||||
ref={(r)=>this.selectTable = r}
|
||||
className="-striped -highlight"
|
||||
{...extraProps}
|
||||
/>
|
||||
@@ -168,5 +171,4 @@ export class ComponentTest extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
// export default treeTableHOC(ComponentTest);
|
||||
export default ComponentTest;
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
|
||||
import React from 'react';
|
||||
import shortid from 'shortid';
|
||||
|
||||
import ReactTable from '../../../../lib/index'
|
||||
import '../../../../react-table.css'
|
||||
|
||||
import selectTableHOC from '../../../../lib/hoc/selectTable'
|
||||
import treeTableHOC from '../../../../lib/hoc/treeTable'
|
||||
|
||||
const SelectTreeTable = selectTableHOC(treeTableHOC(ReactTable));
|
||||
|
||||
async function getData()
|
||||
{
|
||||
const result = await ( await fetch('/au_500_tree.json') ).json();
|
||||
// we are adding a unique ID to the data for tracking the selected records
|
||||
return result.map((item)=>{
|
||||
const _id = shortid.generate();
|
||||
return {
|
||||
_id,
|
||||
...item,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getColumns(data)
|
||||
{
|
||||
const columns = [];
|
||||
const sample = data[0];
|
||||
for(let key in sample)
|
||||
{
|
||||
if(key==='_id') continue;
|
||||
columns.push({
|
||||
accessor: key,
|
||||
Header: key,
|
||||
})
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
function getNodes(data,node=[])
|
||||
{
|
||||
data.forEach((item)=>{
|
||||
if(item.hasOwnProperty('_subRows') && item._subRows)
|
||||
{
|
||||
node = getNodes(item._subRows,node);
|
||||
} else {
|
||||
node.push(item._original);
|
||||
}
|
||||
});
|
||||
return node;
|
||||
}
|
||||
|
||||
export class ComponentTest extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state =
|
||||
{
|
||||
data: null,
|
||||
columns: null,
|
||||
selection: [],
|
||||
selectAll: false,
|
||||
selectType: 'checkbox',
|
||||
};
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
getData().then((data)=>{
|
||||
const columns = getColumns(data);
|
||||
const pivotBy = ['state','post'];
|
||||
this.setState({ data, columns, pivotBy });
|
||||
});
|
||||
}
|
||||
toggleSelection = (key,shift,row) => {
|
||||
/*
|
||||
Implementation of how to manage the selection state is up to the developer.
|
||||
This implementation uses an array stored in the component state.
|
||||
Other implementations could use object keys, a Javascript Set, or Redux... etc.
|
||||
*/
|
||||
// start off with the existing state
|
||||
if (this.state.selectType === 'radio') {
|
||||
let selection = [];
|
||||
if (selection.indexOf(key)<0) selection.push(key);
|
||||
this.setState({selection});
|
||||
} else {
|
||||
let selection = [
|
||||
...this.state.selection
|
||||
];
|
||||
const keyIndex = selection.indexOf(key);
|
||||
// check to see if the key exists
|
||||
if(keyIndex>=0) {
|
||||
// it does exist so we will remove it using destructing
|
||||
selection = [
|
||||
...selection.slice(0,keyIndex),
|
||||
...selection.slice(keyIndex+1)
|
||||
]
|
||||
} else {
|
||||
// it does not exist so add it
|
||||
selection.push(key);
|
||||
}
|
||||
// update the state
|
||||
this.setState({selection});
|
||||
}
|
||||
}
|
||||
toggleAll = () => {
|
||||
/*
|
||||
'toggleAll' is a tricky concept with any filterable table
|
||||
do you just select ALL the records that are in your data?
|
||||
OR
|
||||
do you only select ALL the records that are in the current filtered data?
|
||||
|
||||
The latter makes more sense because 'selection' is a visual thing for the user.
|
||||
This is especially true if you are going to implement a set of external functions
|
||||
that act on the selected information (you would not want to DELETE the wrong thing!).
|
||||
|
||||
So, to that end, access to the internals of ReactTable are required to get what is
|
||||
currently visible in the table (either on the current page or any other page).
|
||||
|
||||
The HOC provides a method call 'getWrappedInstance' to get a ref to the wrapped
|
||||
ReactTable and then get the internal state and the 'sortedData'.
|
||||
That can then be iterrated to get all the currently visible records and set
|
||||
the selection state.
|
||||
*/
|
||||
const selectAll = this.state.selectAll?false:true;
|
||||
const selection = [];
|
||||
if(selectAll)
|
||||
{
|
||||
// we need to get at the internals of ReactTable
|
||||
const wrappedInstance = this.selectTable.getWrappedInstance();
|
||||
// the 'sortedData' property contains the currently accessible records based on the filter and sort
|
||||
const currentRecords = wrappedInstance.getResolvedState().sortedData;
|
||||
// we need to get all the 'real' (original) records out to get at their IDs
|
||||
const nodes = getNodes(currentRecords);
|
||||
// we just push all the IDs onto the selection array
|
||||
nodes.forEach((item)=>{
|
||||
selection.push(item._id);
|
||||
})
|
||||
}
|
||||
this.setState({selectAll,selection})
|
||||
}
|
||||
isSelected = (key) => {
|
||||
/*
|
||||
Instead of passing our external selection state we provide an 'isSelected'
|
||||
callback and detect the selection state ourselves. This allows any implementation
|
||||
for selection (either an array, object keys, or even a Javascript Set object).
|
||||
*/
|
||||
return this.state.selection.includes(key);
|
||||
}
|
||||
logSelection = () => {
|
||||
console.log('selection:',this.state.selection);
|
||||
}
|
||||
toggleType = () => {
|
||||
this.setState({ selectType: this.state.selectType === 'radio' ? 'checkbox' : 'radio', selection: [], selectAll: false, });
|
||||
}
|
||||
toggleTree = () => {
|
||||
if(this.state.pivotBy.length) {
|
||||
this.setState({pivotBy:[],expanded:{}});
|
||||
} else {
|
||||
this.setState({pivotBy:['state','post'],expanded:{}});
|
||||
}
|
||||
}
|
||||
onExpandedChange = (expanded) => {
|
||||
this.setState({expanded});
|
||||
}
|
||||
render(){
|
||||
const { toggleSelection, toggleAll, isSelected, logSelection, toggleType, toggleTree, onExpandedChange, } = this;
|
||||
const { data, columns, selectAll, selectType, pivotBy, expanded, } = this.state;
|
||||
const extraProps =
|
||||
{
|
||||
selectAll,
|
||||
isSelected,
|
||||
toggleAll,
|
||||
toggleSelection,
|
||||
selectType,
|
||||
pivotBy,
|
||||
expanded,
|
||||
onExpandedChange,
|
||||
pageSize: 5,
|
||||
}
|
||||
return (
|
||||
<div style={{ padding: '10px'}}>
|
||||
<h1>react-table - Select Tree Table</h1>
|
||||
<p>This example combines two HOCs (the TreeTable and the SelectTable) to make a composite component.</p>
|
||||
<p>We'll call it SelectTreeTable!</p>
|
||||
<p>Here is what the buttons do:</p>
|
||||
<ul>
|
||||
<li><strong>Toggle Tree:</strong> enables or disabled the pivotBy on the table.</li>
|
||||
<li><strong>Select Type:</strong> changes from 'checkbox' to 'radio' and back again.</li>
|
||||
<li><strong>Log Selection to Console:</strong> open your console to see what has been selected.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>NOTE:</strong> the selection is maintained when toggling the tree on and off but is cleared
|
||||
when switching between select types (radio, checkbox).
|
||||
</p>
|
||||
<button onClick={toggleTree}>Toggle Tree [{pivotBy && pivotBy.length ? pivotBy.join(', ') : ''}]</button>
|
||||
<button onClick={toggleType}>Select Type: <strong>{selectType}</strong></button>
|
||||
<button onClick={logSelection}>Log Selection to Console</button>
|
||||
{` (${this.state.selection.length}) selected`}
|
||||
{
|
||||
data?
|
||||
<SelectTreeTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
ref={(r)=>this.selectTable = r}
|
||||
className="-striped -highlight"
|
||||
freezeWhenExpanded={true}
|
||||
{...extraProps}
|
||||
/>
|
||||
:null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ComponentTest;
|
||||
+120
-4
@@ -1,6 +1,122 @@
|
||||
|
||||
# This is the readme for HOCs with ReactTable
|
||||
<div style="text-align:center;">
|
||||
<a href="https://github.com/react-tools/react-table" target="\_parent"><img src="https://github.com/react-tools/media/raw/master/logo-react-table.png" alt="React Table Logo" style="width:450px;"/></a>
|
||||
</div>
|
||||
|
||||
## TO DO
|
||||
- Document the HOCs
|
||||
- Document the standard for writing HOCs with ReactTable
|
||||
# ReactTable - expanding with HOCs
|
||||
This documentation is about expanding ReactTable using Higher Order Components/Functions.
|
||||
|
||||
## Covered in this README
|
||||
- A Brief explanation of HOCs and why they are a good approach for ReactTable enhancements
|
||||
- Documentation of the currently available HOCs
|
||||
- TreeTable
|
||||
- SelectTable
|
||||
- Documentation of the standard for writing HOCs with ReactTable
|
||||
|
||||
## What are HOCs and why use them with ReactTable
|
||||
HOCs (or Higher Order Components/Functions) are either a React Component (or a function that returns a React Component)
|
||||
that are used to enhance the functionality of an existing component. How much you can enhance depends on the props that
|
||||
the component exposes.
|
||||
|
||||
Fortunately, ReactTable exposes a LOT of functionality as props to the component. In some cases there are too many
|
||||
props to keep track of and that is where HOCs come in.
|
||||
|
||||
You can write a HOC that just focusses on the additional functionality you want to enhance and keep those enhancements to
|
||||
reuse over and over again when you need them. You don't have to edit the ReactSource code, just wrap ReactTable in one or
|
||||
more HOCs (more on some issues related to chaining HOCs later) that provide the additional functionality you want to expose.
|
||||
|
||||
The most obvious HOC is one that can add `checkbox` or select functionality. The HOC included provides `select` functionality
|
||||
that allows the developer to specify if they want a `checkbox` or `radio` style of select column. The implementation of the
|
||||
selection is recorded (e.g. in component state, Redux, etc.) and how to manage multiple selections. The HOC really only handles
|
||||
the rendering pieces.
|
||||
|
||||
But there is more documentation on the `select` HOC below.
|
||||
|
||||
|
||||
## Currently Available HOCs
|
||||
|
||||
### TreeTable
|
||||
TreeTable takes over the rendering of the generated pivot rows of ReactTable so that they appear more like an expandable Tree.
|
||||
|
||||
It accomplishes this by rendering a 100% wide div and then only rendering the cell that controls the pivot at that level.
|
||||
|
||||
Using it is as simple as doing the following:
|
||||
```javascript
|
||||
import ReactTable from 'react-table'
|
||||
import treeTableHOC from 'react-table/lib/hoc/treeTable'
|
||||
|
||||
const TreeTable = treeTableHOC(ReactTable)
|
||||
```
|
||||
After you have done the above, you can then use `TreeTable` just as you would `ReactTable` but it will render pivots using
|
||||
the Tree style described above.
|
||||
|
||||
|
||||
### SelectTable
|
||||
SelectTable is a little trickier. The HOCs attempt to avoid adding additional state and, as there is no internal ID for a row that
|
||||
can be relied on to be static (ReactTable just reuses indexes when rendering) the developer has to maintain the state outside of even
|
||||
the wrapped component. So it is largely based on callbacks.
|
||||
|
||||
You include the HOC in the same manner as you would for the treeTableHOC but then need to provide the following overrides:
|
||||
- isSelected - returns `true` if the key passed is selected otherwise it should return `false`
|
||||
- selectAll - a property that indicates if the selectAll is set (`true|false`)
|
||||
- toggleAll - called when the user clicks the `selectAll` checkbox/radio
|
||||
- toggleSelection - called when the use clicks a specific checkbox/radio in a row
|
||||
- selectType - either `checkbox|radio` to indicate what type of selection is required
|
||||
|
||||
In the case of `radio` there is no `selectAll` displayed but the developer is responsible for only making one selection in
|
||||
the controlling component's state. You could select multiple but it wouldn't make sense and you should use `checkbox` instead.
|
||||
|
||||
You also have to decide what `selectAll` means. Given ReactTable is a paged solution there are other records off-page. When someone
|
||||
selects the `selectAll` checkbox, should it mark every possible record, only what might be visible to due a Filter or only those items
|
||||
on the current page?
|
||||
|
||||
The example opts for the middle approach so it gets a `ref` to the ReactTable instance and pulls the `sortedData` out of the resolved
|
||||
state (then walks through those records and pulls their ID into the `selection` state of the controlling component).
|
||||
|
||||
You can also replace the input component that is used to render the select box and select all box:
|
||||
- SelectAllInputComponent - the checkbox in the top left corner
|
||||
- SelectInputComponent - the checkbox used on a row
|
||||
|
||||
### SelectTreeTable
|
||||
SelectTreeTable is a combination of TreeTable and SelectTable.
|
||||
|
||||
To function correctly the chain has to be in the correct order as follows (see the comments in the guid on HOCs below).
|
||||
|
||||
```Javascript
|
||||
const SelectTreeTable = selectTableHOC(treeTableHOC(ReactTable));
|
||||
```
|
||||
|
||||
In this particular instance it is (probably) because the functions need access to the state on the wrapped component to manage
|
||||
the selected items. Although that is not totally clearly the issue.
|
||||
|
||||
## HOC Guide for ReactTable
|
||||
There are a few rules required when writing a HOC for ReactTable (other than meeting the normal lint standards - which are
|
||||
still being developed).
|
||||
|
||||
Firstly, there are issues with `ref` when you write a HOC. Consider a deeply nested component wrapped in multiple HOCs...
|
||||
|
||||
A HOC in the middle of the chain requires access to the instance of the component it thinks it is wrapping but there is at
|
||||
least one other wrapper in the way. The challenge is: How do I get to the actual wrapped component?
|
||||
|
||||
Each HOC is required to be a React Class so that a `ref` can be obtained against each component:
|
||||
|
||||
```Javascript
|
||||
<Component ... ref={r => this.wrappedInstance = r} />
|
||||
```
|
||||
*NOTE:* "Component" can also be the `<ReactTable />` instance.
|
||||
|
||||
Then the following method needs
|
||||
to be placed on the class so that it exposes the correct instance of ReactTable:
|
||||
|
||||
```Javascript
|
||||
getWrappedInstance() {
|
||||
if (!this.wrappedInstance) console.warn('<component name here> - No wrapped instance')
|
||||
if (this.wrappedInstance.getWrappedInstance) return this.wrappedInstance.getWrappedInstance()
|
||||
else return this.wrappedInstance
|
||||
}
|
||||
```
|
||||
Essentially this will walk down the chain (if there are chained HOCs) and stop when it gets to the end and return the wrapped instance.
|
||||
|
||||
Finally, sometimes the chains need to be in a specific order to function correctly. It is not clear if this is just an architectural
|
||||
issue or if it would be better solved using a library like `recompose`. Anyone who is able to contribute a reliable solution to this
|
||||
is welcome to submit a PR.
|
||||
|
||||
@@ -2,60 +2,79 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const defaultSelectInputComponent = (props) => {
|
||||
return (
|
||||
<input
|
||||
type={props.selectType || 'checkbox'}
|
||||
checked={props.checked}
|
||||
onClick={(e)=>{
|
||||
const { shiftKey } = e;
|
||||
e.stopPropagation();
|
||||
props.onClick(props.id, shiftKey, props.row);
|
||||
}}
|
||||
onChange={()=>{}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default (Component) => {
|
||||
|
||||
const wrapper = class RTCheckboxTable extends React.Component {
|
||||
// we only need a Component so we can get the 'ref' - pure components can't get a 'ref'
|
||||
const wrapper = class RTSelectTable extends React.Component {
|
||||
|
||||
rowSelector = (row) =>
|
||||
constructor(props)
|
||||
{
|
||||
if(!row || !row.hasOwnProperty(this.props.keyField)) return null;
|
||||
const checked = this.props.isSelected(row[this.props.keyField]);
|
||||
return (
|
||||
<input
|
||||
type={this.props.selectType}
|
||||
checked={checked}
|
||||
onClick={(e)=>{
|
||||
const { shiftKey } = e;
|
||||
e.stopPropagation();
|
||||
this.props.toggleSelection(row[this.props.keyField],shiftKey,row);
|
||||
}}
|
||||
onChange={()=>{}}
|
||||
value=''
|
||||
/>
|
||||
);
|
||||
super(props);
|
||||
}
|
||||
|
||||
headSelector = (row) =>
|
||||
{
|
||||
if (this.props.selectType === 'radio') return null;
|
||||
const checked = this.props.selectAll;
|
||||
return (
|
||||
<input
|
||||
type={this.props.selectType}
|
||||
checked={checked}
|
||||
onClick={(e)=>{
|
||||
e.stopPropagation();
|
||||
this.props.toggleAll();
|
||||
}}
|
||||
onChange={()=>{}}
|
||||
value=''
|
||||
/>
|
||||
);
|
||||
rowSelector(row) {
|
||||
if(!row || !row.hasOwnProperty(this.props.keyField)) return null;
|
||||
const { toggleSelection, selectType, keyField } = this.props;
|
||||
const checked = this.props.isSelected(row[this.props.keyField]);
|
||||
const inputProps =
|
||||
{
|
||||
checked,
|
||||
onClick: toggleSelection,
|
||||
selectType,
|
||||
id: row[keyField],
|
||||
row,
|
||||
}
|
||||
return React.createElement(this.props.SelectInputComponent,inputProps);
|
||||
}
|
||||
|
||||
headSelector(row) {
|
||||
const { selectType } = this.props;
|
||||
if (selectType === 'radio') return null;
|
||||
|
||||
const { toggleAll, selectAll: checked, SelectAllInputComponent, } = this.props;
|
||||
const inputProps =
|
||||
{
|
||||
checked,
|
||||
onClick: toggleAll,
|
||||
selectType,
|
||||
}
|
||||
|
||||
return React.createElement(SelectAllInputComponent,inputProps);
|
||||
}
|
||||
|
||||
// this is so we can expose the underlying ReactTable to get at the sortedData for selectAll
|
||||
getWrappedInstance = ()=>this.wrappedInstance
|
||||
getWrappedInstance() {
|
||||
if (!this.wrappedInstance) console.warn('RTSelectTable - No wrapped instance');
|
||||
if (this.wrappedInstance.getWrappedInstance) return this.wrappedInstance.getWrappedInstance();
|
||||
else return this.wrappedInstance
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
const { columns:originalCols, isSelected, toggleSelection, toggleAll, keyField, selectAll, ...rest } = this.props;
|
||||
const { rowSelector, headSelector, } = this;
|
||||
const {
|
||||
columns:originalCols, isSelected, toggleSelection, toggleAll, keyField, selectAll,
|
||||
selectType, SelectAllInputComponent, SelectInputComponent,
|
||||
...rest
|
||||
} = this.props;
|
||||
const select = {
|
||||
id: '_selector',
|
||||
accessor: ()=>'x', // this value is not important
|
||||
Header: headSelector,
|
||||
Cell: (ci) => { return rowSelector(ci.original); },
|
||||
Header: this.headSelector.bind(this),
|
||||
Cell: (ci) => { return this.rowSelector.bind(this)(ci.original); },
|
||||
width: 30,
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
@@ -75,7 +94,7 @@ export default (Component) => {
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.displayName = 'RTCheckboxTable';
|
||||
wrapper.displayName = 'RTSelectTable';
|
||||
wrapper.defaultProps =
|
||||
{
|
||||
keyField: '_id',
|
||||
@@ -83,7 +102,9 @@ export default (Component) => {
|
||||
selectAll: false,
|
||||
toggleSelection: (key, shift, row)=>{ console.log('No toggleSelection handler provided:', { key, shift, row }) },
|
||||
toggleAll: () => { console.log('No toggleAll handler provided.') },
|
||||
selectType: 'radio',
|
||||
selectType: 'check',
|
||||
SelectInputComponent: defaultSelectInputComponent,
|
||||
SelectAllInputComponent: defaultSelectInputComponent,
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
|
||||
+51
-29
@@ -3,56 +3,78 @@
|
||||
import React from 'react'
|
||||
|
||||
export default (Component) => {
|
||||
const wrapper = (componentProps) => {
|
||||
const TrComponent = (props) => {
|
||||
const { ri, ...rest } = props;
|
||||
const wrapper = class RTTreeTable extends React.Component {
|
||||
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
this.getWrappedInstance.bind(this);
|
||||
this.TrComponent.bind(this);
|
||||
this.getTrProps.bind(this);
|
||||
}
|
||||
|
||||
// this is so we can expose the underlying ReactTable to get at the sortedData for selectAll
|
||||
getWrappedInstance = () => {
|
||||
if (!this.wrappedInstance) console.warn('RTTreeTable - No wrapped instance');
|
||||
if (this.wrappedInstance.getWrappedInstance) return this.wrappedInstance.getWrappedInstance();
|
||||
else return this.wrappedInstance
|
||||
}
|
||||
|
||||
TrComponent = (props) => {
|
||||
const {
|
||||
ri,
|
||||
...rest
|
||||
} = props;
|
||||
if(ri && ri.groupedByPivot) {
|
||||
const cell = props.children[ri.level];
|
||||
const cell = {...props.children[ri.level]};
|
||||
|
||||
cell.props.style.flex = 'unset';
|
||||
cell.props.style.width = '100%';
|
||||
cell.props.style.maxWidth = 'unset';
|
||||
cell.props.style.paddingLeft = `${componentProps.treeTableIndent*ri.level}px`;
|
||||
cell.props.style.paddingLeft = `${this.props.treeTableIndent*ri.level}px`;
|
||||
// cell.props.style.backgroundColor = '#DDD';
|
||||
cell.props.style.borderBottom = '1px solid rgba(128,128,128,0.2)';
|
||||
|
||||
return <div {...rest}>{cell}</div>;
|
||||
return <div className={`rt-tr ${rest.className}`} style={rest.style}>{cell}</div>;
|
||||
}
|
||||
return <Component.defaultProps.TrComponent {...rest} />;
|
||||
}
|
||||
|
||||
const getTrProps = (state,ri,ci,instance) => {
|
||||
getTrProps = (state,ri,ci,instance) => {
|
||||
return {ri};
|
||||
}
|
||||
|
||||
const { columns, ...rest } = componentProps;
|
||||
const extra = {
|
||||
columns: columns.map((col)=>{
|
||||
let column = col;
|
||||
if(rest.pivotBy && rest.pivotBy.includes(col.accessor))
|
||||
{
|
||||
column = {
|
||||
accessor: col.accessor,
|
||||
width: `${componentProps.treeTableIndent}px`,
|
||||
show: false,
|
||||
Header: '',
|
||||
render() {
|
||||
const { columns, treeTableIndent, ...rest } = this.props;
|
||||
const { TrComponent, getTrProps } = this;
|
||||
const extra = {
|
||||
columns: columns.map((col)=>{
|
||||
let column = col;
|
||||
if(rest.pivotBy && rest.pivotBy.includes(col.accessor))
|
||||
{
|
||||
column = {
|
||||
accessor: col.accessor,
|
||||
width: `${treeTableIndent}px`,
|
||||
show: false,
|
||||
Header: '',
|
||||
}
|
||||
}
|
||||
}
|
||||
return column;
|
||||
}),
|
||||
TrComponent,
|
||||
getTrProps,
|
||||
};
|
||||
|
||||
return (
|
||||
<Component {...rest} {...extra} />
|
||||
)
|
||||
return column;
|
||||
}),
|
||||
TrComponent,
|
||||
getTrProps,
|
||||
};
|
||||
|
||||
return (
|
||||
<Component {...rest} {...extra} ref={ r => this.wrappedInstance=r }/>
|
||||
)
|
||||
}
|
||||
}
|
||||
wrapper.displayName = 'RTTreeTable';
|
||||
wrapper.defaultProps =
|
||||
{
|
||||
treeTableRowBackground: '#EEE',
|
||||
treeTableIndent: 10,
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user