Skip to content

Commit

Permalink
Examples Refactor + multiSort flag (#619)
Browse files Browse the repository at this point in the history
* chore: Update the devDependencies for the linter

* A few HOC examples for react-table.
Not really integrated with the whole codesandbox.io approach.

* Missing dependency - shortid

* Refactor HOCs to /src/hoc
Still have to write the HOCReadme.md (still just a placeholder for now)

* Refactor complete
May need to remove some redundant code

* Text change for the HOC samples

* Introduced a 'multiSort' flag
Defaults to 'true'
A 'false' value will turn multi-sort off.

* refactor: Fix defaultProps.js linter errors

* refactor: Fix lifecycle.js linter errors

* refactor: Fix pagination.js linter errors

* refactor: Fix propTypes.js linter errors

* refactor: Fix utils.js linter errors

* refactor: Fix methods.js linter errors

* refactor: Fix index.js linter errors

* Fix for linter changes + CHANGELOG update
  • Loading branch information
gary-menzel committed Nov 23, 2017
1 parent 1cf9e49 commit f74ba3c
Show file tree
Hide file tree
Showing 21 changed files with 1,275 additions and 375 deletions.
55 changes: 55 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,58 @@
## 6.7.4
#### Fixes & Optimizations
- Fix Prop types for columns

## 6.7.3
#### Fixes & Optimizations
- Fix the rest of the proptypes

## 6.7.2
#### Fixes & Optimizations
- `getPropTypes` proptype check

## 6.7.1
#### Fixes & Optimizations
- `eslint-config` moved to dev deps

## 6.7.0
## 6.7.0-alpha-0
#### New Features
- Expose page/pageSize to rows/cells
- Supply sort direction to custom sort methods

#### Fixes & Optimizations
- README updates
- Linter cleanup
- Added PropTypes node module
- Deps, linting and style upgrades

## 6.6.0
#### Fixes & Optimizations
- moved repo to react-tools
- Doc examples moved to codesandbox.io
- README updates
- CSS refacting for rt-tfoot to match rt-thead
- CSS more specific for input and select

## 6.5.3
#### Fixes & Optimizations
- `onClick` proxying and eslint

## 6.5.2
#### New Features
- Provide onClick handleOriginal function - #406

#### Fixes & Optimizations
- README updates
- `makePathArray` in utils - #326
- Various fixes: #294, #376, #398, #415,

## 6.5.1
#### Fixes & Optimizations
- `defaultExpanded` now works correctly - #372
- `column.getProps().rest` props are now applied correctly
- `makeTemplateComponent` now supports `displayName` - #289

## 6.5.0
##### New Features
- `column.filterAll` - defaults to `false`, but when set to `true` will provide the entire array of rows to `filterMethod` as opposed to one row at a time. This allows for more fine-grained filtering using any method you can dream up. See the [Custom Filtering example](https://react-table.js.org/#/story/custom-filtering) for more info.
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ These are all of the available props (and their default values) for the main `<R
collapseOnDataChange: true,
freezeWhenExpanded: false,
sortable: true,
multiSort: true,
resizable: true,
filterable: false,
defaultSortDesc: false,
Expand Down Expand Up @@ -833,6 +834,9 @@ Sorting comes built in with React-Table.
## Multi-Sort
When clicking on a column header, hold shift to multi-sort! You can toggle `ascending` `descending` and `none` for multi-sort columns. Clicking on a header without holding shift will clear the multi-sort and replace it with the single sort of that column. It's quite handy!

You can set the `multiSort` prop to `false` to disable this feature (which may be useful for server-side sorting when you are not
going to sort multiple columns).

## Custom Sorting Algorithm
To override the default sorting algorithm for the whole table use the `defaultSortMethod` prop.

Expand Down
9 changes: 9 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
"babel-preset-react": "6.11.1",
"babel-preset-stage-2": "6.13.0",
"eslint": "^4.1.1",
"eslint-config-standard": "^10.2.1",
"eslint-plugin-class-property": "^1.0.6",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-react": "^7.4.0",
"eslint-plugin-standard": "^3.0.1",
"html-element-attributes": "^1.3.0",
"match-sorter": "^1.8.0",
"npm-run-all": "^3.1.1",
"onchange": "^3.0.2",
Expand Down
23 changes: 19 additions & 4 deletions docs/src/App.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable */

import React from 'react'
//
import ReactStory, { defaultProps } from 'react-story'
Expand All @@ -6,6 +8,18 @@ import './stories/utils/prism.css'
import '../../react-table.css'

import Readme from './stories/Readme.js'
import HOCReadme from './stories/HOCReadme.js'

// import Tester from './examples/expander';

// import { TreeTable, SelectTable, SelectTreeTable } from './examples/index'
//
// const exampleStories = [
// // examples
// { name: 'TreeTable', component: TreeTable },
// { name: 'SelectTable', component: SelectTable },
// { name: 'SelectTreeTable', component: SelectTreeTable },
// ]

import { TreeTable, CheckboxTable } from './examples/index'

Expand All @@ -17,7 +31,9 @@ const exampleStories = [

const stories = [
{ name: 'Readme', component: Readme },
{ name: 'HOC Readme', component: HOCReadme },

// { name: 'Tester', component: Tester },
{ name: 'Simple Table', component: CodeSandbox('X6npLXPRW') },
{
name: 'Cell Renderers & Custom Components',
Expand Down Expand Up @@ -60,10 +76,9 @@ const stories = [
name: 'Multiple Pagers (Top and Bottom)',
component: CodeSandbox('VEZ8OgvX'),
},

// other examples
...exampleStories,

{ name: 'Tree Table (HOC)', component: CodeSandbox('lxmr4wynzq') },
{ name: 'Select Table (HOC)', component: CodeSandbox('7yq5ylw09j') },
{ name: 'Select Tree Table (HOC)', component: CodeSandbox('2p7jp4klwp') },
]

export default class App extends React.Component {
Expand Down
54 changes: 54 additions & 0 deletions docs/src/examples/expander/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* eslint-disable */

import React from 'react';

import ReactTable from '../../../../lib/index'
import '../../../../react-table.css'

const data = [
{one:"1.1",two:"1.2"},
{one:"2.1",two:"2.2"},
{one:"3.1",two:"3.2"},
{one:"4.1",two:"4.2"},
]

const columns = [
{accessor:'one', Header: 'One'},
{accessor:'two', Header: 'Two'},
]

class ExpanderComponent extends React.Component {
render()
{
return (
<div className={`rt-expander ${this.props.isExpanded ? '-open' : ''}`}>
&bull;
</div>
)
}
}

class SubComponent extends React.Component {
render()
{
return <div>Nothing</div>
}
}

export default class ComponentTest extends React.Component {
render()
{
const rtProps = {
data,
columns,
ExpanderComponent: (props)=><ExpanderComponent {...props} />,
SubComponent: (props)=><SubComponent {...props} />,
multiSort: false,
}
return (
<ReactTable
{...rtProps}
/>
)
}
}
9 changes: 6 additions & 3 deletions docs/src/examples/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
/* eslint-disable */

import TreeTable from './treetable';
import CheckboxTable from './checkbox';
import TreeTable from './treetable'
import SelectTable from './selecttable'
import SelectTreeTable from './selecttreetable'

export {
TreeTable,
CheckboxTable,
SelectTable,
SelectTreeTable,
}
174 changes: 174 additions & 0 deletions docs/src/examples/selecttable/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@

import React from 'react';
import shortid from 'shortid';

import ReactTable from '../../../../lib/index'
import '../../../../react-table.css'

import selectTableHOC from '../../../../lib/hoc/selectTable'

const SelectTable = selectTableHOC(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,
selectType: 'checkbox',
};
}
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
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 just push all the IDs onto the selection array
currentRecords.forEach((item)=>{
if(item._original)
{
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);
}
toggleType = () => {
this.setState({ selectType: this.state.selectType === 'radio' ? 'checkbox' : 'radio', selection: [], selectAll: false, });
}
render(){
const { toggleSelection, toggleAll, isSelected, logSelection, toggleType } = this;
const { data, columns, selectAll, selectType } = this.state;
const extraProps =
{
selectAll,
isSelected,
toggleAll,
toggleSelection,
selectType,
}
return (
<div style={{ padding: '10px'}}>
<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`}
{
data?
<SelectTable
data={data}
columns={columns}
ref={(r)=>this.selectTable = r}
className="-striped -highlight"
{...extraProps}
/>
:null
}
</div>
);
}
}

export default ComponentTest;
Loading

0 comments on commit f74ba3c

Please sign in to comment.