this.wrappedInstance=r}/>
+ )
+ }
+ }
+
+ wrapper.displayName = 'RTCheckboxTable';
+ wrapper.defaultProps =
+ {
+ keyField: '_id',
+ isSelected: (key)=>{ console.log('No isSelected handler provided:',{key})},
+ selectAll: false,
+ toggleSelection: (key, shift, row)=>{ console.log('No toggleSelection handler provided:', { key, shift, row }) },
+ toggleAll: () => { console.log('No toggleAll handler provided.') },
+ }
+
+ return wrapper;
+}
diff --git a/docs/src/examples/checkbox/index.js b/docs/src/examples/checkbox/index.js
new file mode 100644
index 0000000..428fd4d
--- /dev/null
+++ b/docs/src/examples/checkbox/index.js
@@ -0,0 +1,160 @@
+
+import React from 'react';
+import shortid from 'shortid';
+
+import ReactTable from '../../../../lib/index'
+import '../../../../react-table.css'
+
+import checkboxTableHOC from './checkboxHOC';
+
+const CheckboxTable = checkboxTableHOC(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;
+}
+
+export class ComponentTest extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state =
+ {
+ data: null,
+ columns: null,
+ selection: [],
+ selectAll: false,
+ };
+ }
+ componentDidMount()
+ {
+ getData().then((data)=>{
+ const columns = getColumns(data);
+ this.setState({ data, columns });
+ });
+ }
+ 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
+ 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.checkboxTable.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);
+ })
+ }
+ 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);
+ }
+ render(){
+ const { toggleSelection, toggleAll, isSelected, logSelection } = this;
+ const { data, columns, selectAll } = this.state;
+ const extraProps =
+ {
+ selectAll,
+ isSelected,
+ toggleAll,
+ toggleSelection,
+ }
+ return (
+
+
react-table - Checkbox Table
+
+ {` (${this.state.selection.length}) selected`}
+ {
+ data?
+ this.checkboxTable = r}
+ className="-striped -highlight"
+ {...extraProps}
+ />
+ :null
+ }
+
+ );
+ }
+}
+
+// export default treeTableHOC(ComponentTest);
+export default ComponentTest;
diff --git a/docs/src/examples/index.js b/docs/src/examples/index.js
new file mode 100644
index 0000000..ffcd74d
--- /dev/null
+++ b/docs/src/examples/index.js
@@ -0,0 +1,8 @@
+
+import TreeTable from './treetable';
+import CheckboxTable from './checkbox';
+
+export {
+ TreeTable,
+ CheckboxTable,
+}
diff --git a/docs/src/examples/treetable/index.js b/docs/src/examples/treetable/index.js
new file mode 100644
index 0000000..34ecc51
--- /dev/null
+++ b/docs/src/examples/treetable/index.js
@@ -0,0 +1,80 @@
+
+import React from 'react';
+
+import ReactTable from '../../../../lib/index'
+import '../../../../react-table.css'
+
+import treeTableHOC from './treeTableHOC';
+
+async function getData()
+{
+ const result = await ( await fetch('/au_500_tree.json') ).json();
+ return result;
+}
+
+function getColumns(data,pivotBy)
+{
+ const columns = [];
+ const sample = data[0];
+ for(let key in sample)
+ {
+ columns.push({
+ accessor: key,
+ Header: key,
+ })
+ }
+ return columns;
+}
+
+export class ComponentTest extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state =
+ {
+ data: null,
+ columns: null,
+ pivotBy: null, // ["firstName", "lastName"],
+ };
+ }
+ componentDidMount()
+ {
+ getData().then((data)=>{
+ // console.log('cwm data:',data);
+ const pivotBy = ['state','post','city'];
+ const columns = getColumns(data,pivotBy);
+ // console.log('cwm cols:',columns);
+ this.setState({data,columns,pivotBy});
+ });
+ }
+ showState = ()=>
+ {
+ console.log('state:',this.reactTable.getResolvedState());
+ }
+ render(){
+ const { data, columns, pivotBy } = this.state;
+ const extraProps =
+ {
+ data,
+ columns,
+ pivotBy,
+ }
+ const TreeTable = treeTableHOC(ReactTable);
+ return (
+
+
react-table - Tree Table
+ {
+ data?
+ this.reactTable=r}
+ className="-striped -highlight"
+ defaultPageSize={5}
+ {...extraProps}
+ />
+ :null
+ }
+
+ );
+ }
+}
+
+export default ComponentTest;
diff --git a/docs/src/examples/treetable/treeTableHOC.js b/docs/src/examples/treetable/treeTableHOC.js
new file mode 100644
index 0000000..078d808
--- /dev/null
+++ b/docs/src/examples/treetable/treeTableHOC.js
@@ -0,0 +1,58 @@
+
+
+import React from 'react';
+
+export default (Component) => {
+ const wrapper = (componentProps) => {
+ const TrComponent = (props) => {
+ const { ri, ...rest } = props;
+ if(ri && ri.groupedByPivot) {
+ 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.backgroundColor = '#DDD';
+ cell.props.style.borderBottom = '1px solid rgba(128,128,128,0.2)';
+
+ return {cell}
;
+ }
+ return ;
+ }
+
+ const 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: '',
+ }
+ }
+ return column;
+ }),
+ TrComponent,
+ getTrProps,
+ };
+
+ return (
+
+ )
+ }
+ wrapper.displayName = 'RTTreeTable';
+ wrapper.defaultProps =
+ {
+ treeTableRowBackground: '#EEE',
+ treeTableIndent: 10,
+ }
+ return wrapper;
+}
diff --git a/docs/src/examples/utils.js b/docs/src/examples/utils.js
new file mode 100644
index 0000000..cd5d5c6
--- /dev/null
+++ b/docs/src/examples/utils.js
@@ -0,0 +1,34 @@
+
+import namor from "namor";
+
+const range = len => {
+ const arr = [];
+ for (let i = 0; i < len; i++) {
+ arr.push(i);
+ }
+ return arr;
+};
+
+const newPerson = () => {
+ const statusChance = Math.random();
+ return {
+ firstName: namor.generate({ words: 1, numbers: 0 }),
+ lastName: namor.generate({ words: 1, numbers: 0 }),
+ age: Math.floor(Math.random() * 30),
+ visits: Math.floor(Math.random() * 100),
+ progress: Math.floor(Math.random() * 100),
+ status:
+ statusChance > 0.66
+ ? "relationship"
+ : statusChance > 0.33 ? "complicated" : "single"
+ };
+};
+
+export function makeData(len = 5553) {
+ return range(len).map(d => {
+ return {
+ ...newPerson(),
+ children: range(10).map(newPerson)
+ };
+ });
+}