mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-13 05:20:26 +00:00
Fully controlled component props and callbacks + docs
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
- [Header Groups](#header-groups)
|
||||
- [Sub Tables & Components](#sub-tables-components)
|
||||
- [Server-side Data](#server-side-data)
|
||||
- [Fully Controlled Component](#fully-controlled-component)
|
||||
- [Multi-sort](#multi-sort)
|
||||
- [Component Overrides](#component-overrides)
|
||||
|
||||
@@ -123,11 +124,15 @@ These are all of the available props (and their default values) for the main `<R
|
||||
tdStyle: {}, // style object for the `td` component
|
||||
paginationStyle: {}, // style object for the `paginination` component
|
||||
|
||||
// Controlled State (see Using as a Fully Controlled Component below)
|
||||
// Controlled Props (see Using as a Fully Controlled Component below)
|
||||
page: undefined,
|
||||
pageSize: undefined,
|
||||
sorting: undefined,
|
||||
visibleSubComponents: undefined
|
||||
visibleSubComponents: undefined,
|
||||
// Controlled Callbacks
|
||||
onExpand: undefined,
|
||||
onPageChange: undefined,
|
||||
onPageSizeChange: undefined,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -266,6 +271,32 @@ If you want to handle pagination, and sorting on the server, `react-table` makes
|
||||
|
||||
For a detailed example, take a peek at our [async table mockup](https://github.com/tannerlinsley/react-table/blob/master/example/src/screens/async.js)
|
||||
|
||||
## Fully Controlled Component
|
||||
React Table by default works fantastically out of the box, but you can achieve even more control and customization if you choose to maintain the state yourself. It is very easy to do, even if you only want to manage *parts* of the state.
|
||||
|
||||
Here are the props and their corresponding callbacks that control the state of the a table:
|
||||
```javascript
|
||||
<ReactTable
|
||||
// Props
|
||||
page={0} // the index of the page you wish to display
|
||||
pageSize={20} // the number of rows per page to be displayed
|
||||
sorting={[{
|
||||
id: 'lastName',
|
||||
asc: true
|
||||
}, {
|
||||
id: 'firstName',
|
||||
asc: true
|
||||
}]} // the sorting model for the table
|
||||
visibleSubComponents={[1,4,5]} // The row indexes on the current page that should appear expanded
|
||||
|
||||
// Callbacks
|
||||
onPageChange={(pageIndex) => {...}} // Called when the page index is changed by the user
|
||||
onPageSizeChange={(pageSize, pageIndex) => {...}} // Called when the pageSize is changed by the user. The resolve page is also sent to maintain approximate position in the data
|
||||
onSortingChange={(column, shiftKey) => {...}} // Called when a sortable column header is clicked with the column itself and if the shiftkey was held.
|
||||
onExpand={(index, event) => {...}} // Called when an expander is clicked. Use this to manage `visibleSubComponents`
|
||||
/>
|
||||
```
|
||||
|
||||
## 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!
|
||||
|
||||
|
||||
+53
-44
@@ -17,13 +17,18 @@ export const ReactTableDefaults = {
|
||||
showPageJump: true,
|
||||
expanderColumnWidth: 30,
|
||||
|
||||
// State Overrides (for controlled-component style)
|
||||
// Controlled State Overrides
|
||||
// page
|
||||
// pageSize
|
||||
// sorting
|
||||
// visibleSubComponents
|
||||
|
||||
// Callbacks
|
||||
// Controlled State Callbacks
|
||||
onExpand: undefined,
|
||||
onPageChange: undefined,
|
||||
onPageSizeChange: undefined,
|
||||
|
||||
// General Callbacks
|
||||
onChange: () => null,
|
||||
onTrClick: () => null,
|
||||
// Classes
|
||||
@@ -86,17 +91,17 @@ export const ReactTableDefaults = {
|
||||
)
|
||||
},
|
||||
TdComponent: _.makeTemplateComponent('rt-td'),
|
||||
ExpanderComponent: ({isOpen, toggle, ...rest}) => {
|
||||
ExpanderComponent: ({isExpanded, toggle, ...rest}) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames('rt-expander', isOpen && '-open')}
|
||||
className={classnames('rt-expander', isExpanded && '-open')}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
},
|
||||
PaginationComponent: Pagination,
|
||||
PreviousComponent: null,
|
||||
NextComponent: null,
|
||||
PreviousComponent: undefined,
|
||||
NextComponent: undefined,
|
||||
LoadingComponent: ({loading, loadingText}) => (
|
||||
<div className={classnames('-loading', {'-active': loading})}>
|
||||
<div className='-loading-inner'>
|
||||
@@ -116,7 +121,7 @@ export default React.createClass({
|
||||
page: 0,
|
||||
pageSize: this.props.defaultPageSize || 10,
|
||||
sorting: false,
|
||||
visibleSubComponents: {}
|
||||
visibleSubComponents: []
|
||||
}
|
||||
},
|
||||
|
||||
@@ -125,6 +130,7 @@ export default React.createClass({
|
||||
},
|
||||
|
||||
render () {
|
||||
const resolvedProps = this.getResolvedState()
|
||||
const {
|
||||
className,
|
||||
style,
|
||||
@@ -146,18 +152,11 @@ export default React.createClass({
|
||||
trStyleCallback,
|
||||
tdStyle,
|
||||
showPagination,
|
||||
showPageSizeOptions,
|
||||
pageSizeOptions,
|
||||
showPageJump,
|
||||
previousText,
|
||||
nextText,
|
||||
pageText,
|
||||
ofText,
|
||||
rowsText,
|
||||
paginationClassName,
|
||||
expanderColumnWidth,
|
||||
manual,
|
||||
loadingText,
|
||||
onExpand,
|
||||
// State
|
||||
visibleSubComponents,
|
||||
loading,
|
||||
@@ -173,11 +172,9 @@ export default React.createClass({
|
||||
TdComponent,
|
||||
ExpanderComponent,
|
||||
PaginationComponent,
|
||||
PreviousComponent,
|
||||
NextComponent,
|
||||
LoadingComponent,
|
||||
SubComponent
|
||||
} = this.getResolvedState()
|
||||
} = resolvedProps
|
||||
|
||||
// Build Columns
|
||||
const decoratedColumns = []
|
||||
@@ -373,6 +370,8 @@ export default React.createClass({
|
||||
index: row.__index,
|
||||
viewIndex: i
|
||||
}
|
||||
const visibleSubComponentIndex = visibleSubComponents.indexOf(i)
|
||||
const isExpanded = visibleSubComponentIndex > -1
|
||||
return (
|
||||
<TrGroupComponent key={i}>
|
||||
<TrComponent
|
||||
@@ -387,17 +386,28 @@ export default React.createClass({
|
||||
flex: `0 0 auto`,
|
||||
width: `${expanderColumnWidth}px`
|
||||
})}
|
||||
onClick={() => {
|
||||
onClick={(e) => {
|
||||
if (onExpand) {
|
||||
return onExpand(i, e)
|
||||
}
|
||||
if (isExpanded) {
|
||||
return this.setState({
|
||||
visibleSubComponents: [
|
||||
...visibleSubComponents.slice(0, visibleSubComponentIndex - 1),
|
||||
...visibleSubComponents.slice(visibleSubComponentIndex + 1)
|
||||
]
|
||||
})
|
||||
}
|
||||
this.setState({
|
||||
visibleSubComponents: {
|
||||
...visibleSubComponents,
|
||||
[i]: !visibleSubComponents[i]
|
||||
}
|
||||
visibleSubComponents: [
|
||||
...visibleSubComponents,
|
||||
i
|
||||
]
|
||||
})
|
||||
}}
|
||||
>
|
||||
<ExpanderComponent
|
||||
isOpen={visibleSubComponents[i]}
|
||||
isExpanded={isExpanded}
|
||||
/>
|
||||
</ThComponent>
|
||||
)}
|
||||
@@ -424,7 +434,7 @@ export default React.createClass({
|
||||
)
|
||||
})}
|
||||
</TrComponent>
|
||||
{SubComponent && visibleSubComponents[i] ? (
|
||||
{SubComponent && isExpanded ? (
|
||||
SubComponent(rowInfo)
|
||||
) : null}
|
||||
</TrGroupComponent>
|
||||
@@ -468,25 +478,12 @@ export default React.createClass({
|
||||
</TableComponent>
|
||||
{showPagination && (
|
||||
<PaginationComponent
|
||||
page={page}
|
||||
{...resolvedProps}
|
||||
pagesLength={pagesLength}
|
||||
pageSize={pageSize}
|
||||
showPageSizeOptions={showPageSizeOptions}
|
||||
pageSizeOptions={pageSizeOptions}
|
||||
showPageJump={showPageJump}
|
||||
canPrevious={canPrevious}
|
||||
canNext={canNext}
|
||||
previousText={previousText}
|
||||
nextText={nextText}
|
||||
pageText={pageText}
|
||||
ofText={ofText}
|
||||
rowsText={rowsText}
|
||||
previousComponent={PreviousComponent}
|
||||
nextComponent={NextComponent}
|
||||
//
|
||||
onChange={this.setPage}
|
||||
onPageSizeChange={this.setPageSize}
|
||||
//
|
||||
onPageChange={this.onPageChange}
|
||||
onPageSizeChange={this.onPageSizeChange}
|
||||
className={paginationClassName}
|
||||
/>
|
||||
)}
|
||||
@@ -577,18 +574,30 @@ export default React.createClass({
|
||||
},
|
||||
|
||||
// User actions
|
||||
setPage (page) {
|
||||
onPageChange (page) {
|
||||
const { onPageChange } = this.props
|
||||
if (onPageChange) {
|
||||
return onPageChange(page)
|
||||
}
|
||||
this.setState({
|
||||
visibleSubComponents: {},
|
||||
visibleSubComponents: [],
|
||||
page
|
||||
}, () => {
|
||||
this.fireOnChange()
|
||||
})
|
||||
},
|
||||
setPageSize (newPageSize) {
|
||||
onPageSizeChange (newPageSize) {
|
||||
const { onPageSizeChange } = this.props
|
||||
const { pageSize, page } = this.getResolvedState()
|
||||
|
||||
// Normalize the page to display
|
||||
const currentRow = pageSize * page
|
||||
const newPage = Math.floor(currentRow / pageSize)
|
||||
|
||||
if (onPageSizeChange) {
|
||||
return onPageSizeChange(newPageSize, newPage)
|
||||
}
|
||||
|
||||
this.setState({
|
||||
pageSize: newPageSize,
|
||||
page: newPage
|
||||
|
||||
+7
-6
@@ -22,7 +22,7 @@ export default React.createClass({
|
||||
changePage (page) {
|
||||
page = this.getSafePage(page)
|
||||
this.setState({page})
|
||||
this.props.onChange(page)
|
||||
this.props.onPageChange(page)
|
||||
},
|
||||
applyPage (e) {
|
||||
e && e.preventDefault()
|
||||
@@ -31,8 +31,10 @@ export default React.createClass({
|
||||
},
|
||||
render () {
|
||||
const {
|
||||
page,
|
||||
// Computed
|
||||
pagesLength,
|
||||
// Props
|
||||
page,
|
||||
showPageSizeOptions,
|
||||
pageSizeOptions,
|
||||
pageSize,
|
||||
@@ -40,12 +42,11 @@ export default React.createClass({
|
||||
canPrevious,
|
||||
canNext,
|
||||
onPageSizeChange,
|
||||
className
|
||||
className,
|
||||
PreviousComponent = defaultButton,
|
||||
NextComponent = defaultButton
|
||||
} = this.props
|
||||
|
||||
const PreviousComponent = this.props.previousComponent || defaultButton
|
||||
const NextComponent = this.props.nextComponent || defaultButton
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames(className, '-pagination')}
|
||||
|
||||
@@ -39,19 +39,21 @@ export default () => {
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
subComponent={(row) => {
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>You can put any component you want here, even another React Table!. It has access to the row data: </em>
|
||||
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
|
||||
<em>You can put any component you want here, even another React Table!</em>
|
||||
<br />
|
||||
<br />
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
subComponent={(row) => {
|
||||
defaultPageSize={3}
|
||||
showPagination={false}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>You can put any component you want here, even another React Table! It even has access to the row data: </em>
|
||||
<em>It even has access to the row data: </em>
|
||||
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -96,9 +98,27 @@ export default (
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
subComponent={(row) => {
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<code><pre>{JSON.stringify(row, null, 2)}</pre></code>
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>You can put any component you want here, even another React Table!</em>
|
||||
<br />
|
||||
<br />
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={3}
|
||||
showPagination={false}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>It even has access to the row data: </em>
|
||||
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user