mirror of
https://github.com/gosticks/react-table.git
synced 2025-10-16 11:55:36 +00:00
- adding isTop prop into pagination component, which allows differentiate if pagination is on top or bottom of the table
868 lines
28 KiB
JavaScript
868 lines
28 KiB
JavaScript
import React, { Component } from 'react'
|
|
import classnames from 'classnames'
|
|
//
|
|
import _ from './utils'
|
|
import Lifecycle from './lifecycle'
|
|
import Methods from './methods'
|
|
import defaultProps from './defaultProps'
|
|
import propTypes from './propTypes'
|
|
|
|
export const ReactTableDefaults = defaultProps
|
|
|
|
export default class ReactTable extends Methods(Lifecycle(Component)) {
|
|
static propTypes = propTypes
|
|
static defaultProps = defaultProps
|
|
|
|
constructor (props) {
|
|
super()
|
|
|
|
this.getResolvedState = this.getResolvedState.bind(this)
|
|
this.getDataModel = this.getDataModel.bind(this)
|
|
this.getSortedData = this.getSortedData.bind(this)
|
|
this.fireFetchData = this.fireFetchData.bind(this)
|
|
this.getPropOrState = this.getPropOrState.bind(this)
|
|
this.getStateOrProp = this.getStateOrProp.bind(this)
|
|
this.filterData = this.filterData.bind(this)
|
|
this.sortData = this.sortData.bind(this)
|
|
this.getMinRows = this.getMinRows.bind(this)
|
|
this.onPageChange = this.onPageChange.bind(this)
|
|
this.onPageSizeChange = this.onPageSizeChange.bind(this)
|
|
this.sortColumn = this.sortColumn.bind(this)
|
|
this.filterColumn = this.filterColumn.bind(this)
|
|
this.resizeColumnStart = this.resizeColumnStart.bind(this)
|
|
this.resizeColumnEnd = this.resizeColumnEnd.bind(this)
|
|
this.resizeColumnMoving = this.resizeColumnMoving.bind(this)
|
|
|
|
this.state = {
|
|
page: props.defaultPage,
|
|
pageSize: props.defaultPageSize,
|
|
sorted: props.defaultSorted,
|
|
expanded: props.defaultExpanded,
|
|
filtered: props.defaultFiltered,
|
|
resized: props.defaultResized,
|
|
currentlyResizing: false,
|
|
skipNextSort: false,
|
|
}
|
|
}
|
|
|
|
render () {
|
|
const resolvedState = this.getResolvedState()
|
|
const {
|
|
children,
|
|
className,
|
|
style,
|
|
getProps,
|
|
getTableProps,
|
|
getTheadGroupProps,
|
|
getTheadGroupTrProps,
|
|
getTheadGroupThProps,
|
|
getTheadProps,
|
|
getTheadTrProps,
|
|
getTheadThProps,
|
|
getTheadFilterProps,
|
|
getTheadFilterTrProps,
|
|
getTheadFilterThProps,
|
|
getTbodyProps,
|
|
getTrGroupProps,
|
|
getTrProps,
|
|
getTdProps,
|
|
getTfootProps,
|
|
getTfootTrProps,
|
|
getTfootTdProps,
|
|
getPaginationProps,
|
|
getLoadingProps,
|
|
getNoDataProps,
|
|
getResizerProps,
|
|
showPagination,
|
|
showPaginationTop,
|
|
showPaginationBottom,
|
|
manual,
|
|
loadingText,
|
|
noDataText,
|
|
sortable,
|
|
multiSort,
|
|
resizable,
|
|
filterable,
|
|
// Pivoting State
|
|
pivotIDKey,
|
|
pivotValKey,
|
|
pivotBy,
|
|
subRowsKey,
|
|
aggregatedKey,
|
|
originalKey,
|
|
indexKey,
|
|
groupedByPivotKey,
|
|
// State
|
|
loading,
|
|
pageSize,
|
|
page,
|
|
sorted,
|
|
filtered,
|
|
resized,
|
|
expanded,
|
|
pages,
|
|
onExpandedChange,
|
|
// Components
|
|
TableComponent,
|
|
TheadComponent,
|
|
TbodyComponent,
|
|
TrGroupComponent,
|
|
TrComponent,
|
|
ThComponent,
|
|
TdComponent,
|
|
TfootComponent,
|
|
PaginationComponent,
|
|
LoadingComponent,
|
|
SubComponent,
|
|
NoDataComponent,
|
|
ResizerComponent,
|
|
ExpanderComponent,
|
|
PivotValueComponent,
|
|
PivotComponent,
|
|
AggregatedComponent,
|
|
FilterComponent,
|
|
PadRowComponent,
|
|
// Data model
|
|
resolvedData,
|
|
allVisibleColumns,
|
|
headerGroups,
|
|
hasHeaderGroups,
|
|
// Sorted Data
|
|
sortedData,
|
|
currentlyResizing,
|
|
} = resolvedState
|
|
|
|
// Pagination
|
|
const startRow = pageSize * page
|
|
const endRow = startRow + pageSize
|
|
let pageRows = manual ? resolvedData : sortedData.slice(startRow, endRow)
|
|
const minRows = this.getMinRows()
|
|
const padRows = _.range(Math.max(minRows - pageRows.length, 0))
|
|
|
|
const hasColumnFooter = allVisibleColumns.some(d => d.Footer)
|
|
const hasFilters = filterable || allVisibleColumns.some(d => d.filterable)
|
|
|
|
const recurseRowsViewIndex = (rows, path = [], index = -1) => [
|
|
rows.map((row, i) => {
|
|
index += 1
|
|
const rowWithViewIndex = {
|
|
...row,
|
|
_viewIndex: index,
|
|
}
|
|
const newPath = path.concat([i])
|
|
if (rowWithViewIndex[subRowsKey] && _.get(expanded, newPath)) {
|
|
[rowWithViewIndex[subRowsKey], index] = recurseRowsViewIndex(
|
|
rowWithViewIndex[subRowsKey],
|
|
newPath,
|
|
index
|
|
)
|
|
}
|
|
return rowWithViewIndex
|
|
}),
|
|
index,
|
|
];
|
|
[pageRows] = recurseRowsViewIndex(pageRows)
|
|
|
|
const canPrevious = page > 0
|
|
const canNext = page + 1 < pages
|
|
|
|
const rowMinWidth = _.sum(
|
|
allVisibleColumns.map(d => {
|
|
const resizedColumn = resized.find(x => x.id === d.id) || {}
|
|
return _.getFirstDefined(resizedColumn.value, d.width, d.minWidth)
|
|
})
|
|
)
|
|
|
|
let rowIndex = -1
|
|
|
|
const finalState = {
|
|
...resolvedState,
|
|
startRow,
|
|
endRow,
|
|
pageRows,
|
|
minRows,
|
|
padRows,
|
|
hasColumnFooter,
|
|
canPrevious,
|
|
canNext,
|
|
rowMinWidth,
|
|
}
|
|
|
|
const rootProps = _.splitProps(getProps(finalState, undefined, undefined, this))
|
|
const tableProps = _.splitProps(getTableProps(finalState, undefined, undefined, this))
|
|
const tBodyProps = _.splitProps(getTbodyProps(finalState, undefined, undefined, this))
|
|
const loadingProps = getLoadingProps(finalState, undefined, undefined, this)
|
|
const noDataProps = getNoDataProps(finalState, undefined, undefined, this)
|
|
|
|
// Visual Components
|
|
|
|
const makeHeaderGroup = (column, i) => {
|
|
const resizedValue = col => (resized.find(x => x.id === col.id) || {}).value
|
|
const flex = _.sum(
|
|
column.columns.map(col => (col.width || resizedValue(col) ? 0 : col.minWidth))
|
|
)
|
|
const width = _.sum(
|
|
column.columns.map(col => _.getFirstDefined(resizedValue(col), col.width, col.minWidth))
|
|
)
|
|
const maxWidth = _.sum(
|
|
column.columns.map(col => _.getFirstDefined(resizedValue(col), col.width, col.maxWidth))
|
|
)
|
|
|
|
const theadGroupThProps = _.splitProps(
|
|
getTheadGroupThProps(finalState, undefined, column, this)
|
|
)
|
|
const columnHeaderProps = _.splitProps(
|
|
column.getHeaderProps(finalState, undefined, column, this)
|
|
)
|
|
|
|
const classes = [
|
|
column.headerClassName,
|
|
theadGroupThProps.className,
|
|
columnHeaderProps.className,
|
|
]
|
|
|
|
const styles = {
|
|
...column.headerStyle,
|
|
...theadGroupThProps.style,
|
|
...columnHeaderProps.style,
|
|
}
|
|
|
|
const rest = {
|
|
...theadGroupThProps.rest,
|
|
...columnHeaderProps.rest,
|
|
}
|
|
|
|
const flexStyles = {
|
|
flex: `${flex} 0 auto`,
|
|
width: _.asPx(width),
|
|
maxWidth: _.asPx(maxWidth),
|
|
}
|
|
|
|
return (
|
|
<ThComponent
|
|
key={`${i}-${column.id}`}
|
|
className={classnames(classes)}
|
|
style={{
|
|
...styles,
|
|
...flexStyles,
|
|
}}
|
|
{...rest}
|
|
>
|
|
{_.normalizeComponent(column.Header, {
|
|
data: sortedData,
|
|
column,
|
|
})}
|
|
</ThComponent>
|
|
)
|
|
}
|
|
|
|
const makeHeaderGroups = () => {
|
|
const theadGroupProps = _.splitProps(
|
|
getTheadGroupProps(finalState, undefined, undefined, this)
|
|
)
|
|
const theadGroupTrProps = _.splitProps(
|
|
getTheadGroupTrProps(finalState, undefined, undefined, this)
|
|
)
|
|
return (
|
|
<TheadComponent
|
|
className={classnames('-headerGroups', theadGroupProps.className)}
|
|
style={{
|
|
...theadGroupProps.style,
|
|
minWidth: `${rowMinWidth}px`,
|
|
}}
|
|
{...theadGroupProps.rest}
|
|
>
|
|
<TrComponent
|
|
className={theadGroupTrProps.className}
|
|
style={theadGroupTrProps.style}
|
|
{...theadGroupTrProps.rest}
|
|
>
|
|
{headerGroups.map(makeHeaderGroup)}
|
|
</TrComponent>
|
|
</TheadComponent>
|
|
)
|
|
}
|
|
|
|
const makeHeader = (column, i) => {
|
|
const resizedCol = resized.find(x => x.id === column.id) || {}
|
|
const sort = sorted.find(d => d.id === column.id)
|
|
const show = typeof column.show === 'function' ? column.show() : column.show
|
|
const width = _.getFirstDefined(resizedCol.value, column.width, column.minWidth)
|
|
const maxWidth = _.getFirstDefined(resizedCol.value, column.width, column.maxWidth)
|
|
const theadThProps = _.splitProps(getTheadThProps(finalState, undefined, column, this))
|
|
const columnHeaderProps = _.splitProps(
|
|
column.getHeaderProps(finalState, undefined, column, this)
|
|
)
|
|
|
|
const classes = [column.headerClassName, theadThProps.className, columnHeaderProps.className]
|
|
|
|
const styles = {
|
|
...column.headerStyle,
|
|
...theadThProps.style,
|
|
...columnHeaderProps.style,
|
|
}
|
|
|
|
const rest = {
|
|
...theadThProps.rest,
|
|
...columnHeaderProps.rest,
|
|
}
|
|
|
|
const isResizable = _.getFirstDefined(column.resizable, resizable, false)
|
|
const resizer = isResizable ? (
|
|
<ResizerComponent
|
|
onMouseDown={e => this.resizeColumnStart(e, column, false)}
|
|
onTouchStart={e => this.resizeColumnStart(e, column, true)}
|
|
{...getResizerProps('finalState', undefined, column, this)}
|
|
/>
|
|
) : null
|
|
|
|
const isSortable = _.getFirstDefined(column.sortable, sortable, false)
|
|
|
|
return (
|
|
<ThComponent
|
|
key={`${i}-${column.id}`}
|
|
className={classnames(
|
|
classes,
|
|
isResizable && 'rt-resizable-header',
|
|
sort ? (sort.desc ? '-sort-desc' : '-sort-asc') : '',
|
|
isSortable && '-cursor-pointer',
|
|
!show && '-hidden',
|
|
pivotBy && pivotBy.slice(0, -1).includes(column.id) && 'rt-header-pivot'
|
|
)}
|
|
style={{
|
|
...styles,
|
|
flex: `${width} 0 auto`,
|
|
width: _.asPx(width),
|
|
maxWidth: _.asPx(maxWidth),
|
|
}}
|
|
toggleSort={e => {
|
|
if (isSortable) this.sortColumn(column, multiSort ? e.shiftKey : false)
|
|
}}
|
|
{...rest}
|
|
>
|
|
<div className={classnames(isResizable && 'rt-resizable-header-content')}>
|
|
{_.normalizeComponent(column.Header, {
|
|
data: sortedData,
|
|
column,
|
|
})}
|
|
</div>
|
|
{resizer}
|
|
</ThComponent>
|
|
)
|
|
}
|
|
|
|
const makeHeaders = () => {
|
|
const theadProps = _.splitProps(getTheadProps(finalState, undefined, undefined, this))
|
|
const theadTrProps = _.splitProps(getTheadTrProps(finalState, undefined, undefined, this))
|
|
return (
|
|
<TheadComponent
|
|
className={classnames('-header', theadProps.className)}
|
|
style={{
|
|
...theadProps.style,
|
|
minWidth: `${rowMinWidth}px`,
|
|
}}
|
|
{...theadProps.rest}
|
|
>
|
|
<TrComponent
|
|
className={theadTrProps.className}
|
|
style={theadTrProps.style}
|
|
{...theadTrProps.rest}
|
|
>
|
|
{allVisibleColumns.map(makeHeader)}
|
|
</TrComponent>
|
|
</TheadComponent>
|
|
)
|
|
}
|
|
|
|
const makeFilter = (column, i) => {
|
|
const resizedCol = resized.find(x => x.id === column.id) || {}
|
|
const width = _.getFirstDefined(resizedCol.value, column.width, column.minWidth)
|
|
const maxWidth = _.getFirstDefined(resizedCol.value, column.width, column.maxWidth)
|
|
const theadFilterThProps = _.splitProps(
|
|
getTheadFilterThProps(finalState, undefined, column, this)
|
|
)
|
|
const columnHeaderProps = _.splitProps(
|
|
column.getHeaderProps(finalState, undefined, column, this)
|
|
)
|
|
|
|
const classes = [
|
|
column.headerClassName,
|
|
theadFilterThProps.className,
|
|
columnHeaderProps.className,
|
|
]
|
|
|
|
const styles = {
|
|
...column.headerStyle,
|
|
...theadFilterThProps.style,
|
|
...columnHeaderProps.style,
|
|
}
|
|
|
|
const rest = {
|
|
...theadFilterThProps.rest,
|
|
...columnHeaderProps.rest,
|
|
}
|
|
|
|
const filter = filtered.find(filter => filter.id === column.id)
|
|
|
|
const ResolvedFilterComponent = column.Filter || FilterComponent
|
|
|
|
const isFilterable = _.getFirstDefined(column.filterable, filterable, false)
|
|
|
|
return (
|
|
<ThComponent
|
|
key={`${i}-${column.id}`}
|
|
className={classnames(classes)}
|
|
style={{
|
|
...styles,
|
|
flex: `${width} 0 auto`,
|
|
width: _.asPx(width),
|
|
maxWidth: _.asPx(maxWidth),
|
|
}}
|
|
{...rest}
|
|
>
|
|
{isFilterable
|
|
? _.normalizeComponent(
|
|
ResolvedFilterComponent,
|
|
{
|
|
column,
|
|
filter,
|
|
onChange: value => this.filterColumn(column, value),
|
|
},
|
|
defaultProps.column.Filter
|
|
)
|
|
: null}
|
|
</ThComponent>
|
|
)
|
|
}
|
|
|
|
const makeFilters = () => {
|
|
const theadFilterProps = _.splitProps(
|
|
getTheadFilterProps(finalState, undefined, undefined, this)
|
|
)
|
|
const theadFilterTrProps = _.splitProps(
|
|
getTheadFilterTrProps(finalState, undefined, undefined, this)
|
|
)
|
|
return (
|
|
<TheadComponent
|
|
className={classnames('-filters', theadFilterProps.className)}
|
|
style={{
|
|
...theadFilterProps.style,
|
|
minWidth: `${rowMinWidth}px`,
|
|
}}
|
|
{...theadFilterProps.rest}
|
|
>
|
|
<TrComponent
|
|
className={theadFilterTrProps.className}
|
|
style={theadFilterTrProps.style}
|
|
{...theadFilterTrProps.rest}
|
|
>
|
|
{allVisibleColumns.map(makeFilter)}
|
|
</TrComponent>
|
|
</TheadComponent>
|
|
)
|
|
}
|
|
|
|
const makePageRow = (row, i, path = []) => {
|
|
const rowInfo = {
|
|
original: row[originalKey],
|
|
row,
|
|
index: row[indexKey],
|
|
viewIndex: (rowIndex += 1),
|
|
pageSize,
|
|
page,
|
|
level: path.length,
|
|
nestingPath: path.concat([i]),
|
|
aggregated: row[aggregatedKey],
|
|
groupedByPivot: row[groupedByPivotKey],
|
|
subRows: row[subRowsKey],
|
|
}
|
|
const isExpanded = _.get(expanded, rowInfo.nestingPath)
|
|
const trGroupProps = getTrGroupProps(finalState, rowInfo, undefined, this)
|
|
const trProps = _.splitProps(getTrProps(finalState, rowInfo, undefined, this))
|
|
return (
|
|
<TrGroupComponent key={rowInfo.nestingPath.join('_')} {...trGroupProps}>
|
|
<TrComponent
|
|
className={classnames(trProps.className, row._viewIndex % 2 ? '-even' : '-odd')}
|
|
style={trProps.style}
|
|
{...trProps.rest}
|
|
>
|
|
{allVisibleColumns.map((column, i2) => {
|
|
const resizedCol = resized.find(x => x.id === column.id) || {}
|
|
const show = typeof column.show === 'function' ? column.show() : column.show
|
|
const width = _.getFirstDefined(resizedCol.value, column.width, column.minWidth)
|
|
const maxWidth = _.getFirstDefined(resizedCol.value, column.width, column.maxWidth)
|
|
const tdProps = _.splitProps(getTdProps(finalState, rowInfo, column, this))
|
|
const columnProps = _.splitProps(column.getProps(finalState, rowInfo, column, this))
|
|
|
|
const classes = [tdProps.className, column.className, columnProps.className]
|
|
|
|
const styles = {
|
|
...tdProps.style,
|
|
...column.style,
|
|
...columnProps.style,
|
|
}
|
|
|
|
const cellInfo = {
|
|
...rowInfo,
|
|
isExpanded,
|
|
column: { ...column },
|
|
value: rowInfo.row[column.id],
|
|
pivoted: column.pivoted,
|
|
expander: column.expander,
|
|
resized,
|
|
show,
|
|
width,
|
|
maxWidth,
|
|
tdProps,
|
|
columnProps,
|
|
classes,
|
|
styles,
|
|
}
|
|
|
|
const value = cellInfo.value
|
|
|
|
let useOnExpanderClick
|
|
let isBranch
|
|
let isPreview
|
|
|
|
const onExpanderClick = e => {
|
|
let newExpanded = _.clone(expanded)
|
|
if (isExpanded) {
|
|
newExpanded = _.set(newExpanded, cellInfo.nestingPath, false)
|
|
} else {
|
|
newExpanded = _.set(newExpanded, cellInfo.nestingPath, {})
|
|
}
|
|
|
|
return this.setStateWithData(
|
|
{
|
|
expanded: newExpanded,
|
|
},
|
|
() => onExpandedChange && onExpandedChange(newExpanded, cellInfo.nestingPath, e)
|
|
)
|
|
}
|
|
|
|
// Default to a standard cell
|
|
let resolvedCell = _.normalizeComponent(column.Cell, cellInfo, value)
|
|
|
|
// Resolve Renderers
|
|
const ResolvedAggregatedComponent =
|
|
column.Aggregated || (!column.aggregate ? AggregatedComponent : column.Cell)
|
|
const ResolvedExpanderComponent = column.Expander || ExpanderComponent
|
|
const ResolvedPivotValueComponent = column.PivotValue || PivotValueComponent
|
|
const DefaultResolvedPivotComponent =
|
|
PivotComponent ||
|
|
(props => (
|
|
<div>
|
|
<ResolvedExpanderComponent {...props} />
|
|
<ResolvedPivotValueComponent {...props} />
|
|
</div>
|
|
))
|
|
const ResolvedPivotComponent = column.Pivot || DefaultResolvedPivotComponent
|
|
|
|
// Is this cell expandable?
|
|
if (cellInfo.pivoted || cellInfo.expander) {
|
|
// Make it expandable by defualt
|
|
cellInfo.expandable = true
|
|
useOnExpanderClick = true
|
|
// If pivoted, has no subRows, and does not have a subComponent,
|
|
// do not make expandable
|
|
if (cellInfo.pivoted && !cellInfo.subRows && !SubComponent) {
|
|
cellInfo.expandable = false
|
|
}
|
|
}
|
|
|
|
if (cellInfo.pivoted) {
|
|
// Is this column a branch?
|
|
isBranch = rowInfo.row[pivotIDKey] === column.id && cellInfo.subRows
|
|
// Should this column be blank?
|
|
isPreview =
|
|
pivotBy.indexOf(column.id) > pivotBy.indexOf(rowInfo.row[pivotIDKey]) &&
|
|
cellInfo.subRows
|
|
// Pivot Cell Render Override
|
|
if (isBranch) {
|
|
// isPivot
|
|
resolvedCell = _.normalizeComponent(
|
|
ResolvedPivotComponent,
|
|
{
|
|
...cellInfo,
|
|
value: row[pivotValKey],
|
|
},
|
|
row[pivotValKey]
|
|
)
|
|
} else if (isPreview) {
|
|
// Show the pivot preview
|
|
resolvedCell = _.normalizeComponent(ResolvedAggregatedComponent, cellInfo, value)
|
|
} else {
|
|
resolvedCell = null
|
|
}
|
|
} else if (cellInfo.aggregated) {
|
|
resolvedCell = _.normalizeComponent(ResolvedAggregatedComponent, cellInfo, value)
|
|
}
|
|
|
|
if (cellInfo.expander) {
|
|
resolvedCell = _.normalizeComponent(
|
|
ResolvedExpanderComponent,
|
|
cellInfo,
|
|
row[pivotValKey]
|
|
)
|
|
if (pivotBy) {
|
|
if (cellInfo.groupedByPivot) {
|
|
resolvedCell = null
|
|
}
|
|
if (!cellInfo.subRows && !SubComponent) {
|
|
resolvedCell = null
|
|
}
|
|
}
|
|
}
|
|
|
|
const resolvedOnExpanderClick = useOnExpanderClick ? onExpanderClick : () => {}
|
|
|
|
// If there are multiple onClick events, make sure they don't
|
|
// override eachother. This should maybe be expanded to handle all
|
|
// function attributes
|
|
const interactionProps = {
|
|
onClick: resolvedOnExpanderClick,
|
|
}
|
|
|
|
if (tdProps.rest.onClick) {
|
|
interactionProps.onClick = e => {
|
|
tdProps.rest.onClick(e, () => resolvedOnExpanderClick(e))
|
|
}
|
|
}
|
|
|
|
if (columnProps.rest.onClick) {
|
|
interactionProps.onClick = e => {
|
|
columnProps.rest.onClick(e, () => resolvedOnExpanderClick(e))
|
|
}
|
|
}
|
|
|
|
// Return the cell
|
|
return (
|
|
<TdComponent
|
|
// eslint-disable-next-line react/no-array-index-key
|
|
key={`${i2}-${column.id}`}
|
|
className={classnames(
|
|
classes,
|
|
!cellInfo.expandable && !show && 'hidden',
|
|
cellInfo.expandable && 'rt-expandable',
|
|
(isBranch || isPreview) && 'rt-pivot'
|
|
)}
|
|
style={{
|
|
...styles,
|
|
flex: `${width} 0 auto`,
|
|
width: _.asPx(width),
|
|
maxWidth: _.asPx(maxWidth),
|
|
}}
|
|
{...tdProps.rest}
|
|
{...columnProps.rest}
|
|
{...interactionProps}
|
|
>
|
|
{resolvedCell}
|
|
</TdComponent>
|
|
)
|
|
})}
|
|
</TrComponent>
|
|
{rowInfo.subRows &&
|
|
isExpanded &&
|
|
rowInfo.subRows.map((d, i) => makePageRow(d, i, rowInfo.nestingPath))}
|
|
{SubComponent && !rowInfo.subRows && isExpanded && SubComponent(rowInfo, () => {
|
|
let newExpanded = _.clone(expanded)
|
|
newExpanded = _.set(newExpanded, cellInfo.nestingPath, false)
|
|
})}
|
|
</TrGroupComponent>
|
|
)
|
|
}
|
|
|
|
const makePadColumn = (column, i) => {
|
|
const resizedCol = resized.find(x => x.id === column.id) || {}
|
|
const show = typeof column.show === 'function' ? column.show() : column.show
|
|
const width = _.getFirstDefined(resizedCol.value, column.width, column.minWidth)
|
|
const flex = width
|
|
const maxWidth = _.getFirstDefined(resizedCol.value, column.width, column.maxWidth)
|
|
const tdProps = _.splitProps(getTdProps(finalState, undefined, column, this))
|
|
const columnProps = _.splitProps(column.getProps(finalState, undefined, column, this))
|
|
|
|
const classes = [tdProps.className, column.className, columnProps.className]
|
|
|
|
const styles = {
|
|
...tdProps.style,
|
|
...column.style,
|
|
...columnProps.style,
|
|
}
|
|
|
|
return (
|
|
<TdComponent
|
|
key={`${i}-${column.id}`}
|
|
className={classnames(classes, !show && 'hidden')}
|
|
style={{
|
|
...styles,
|
|
flex: `${flex} 0 auto`,
|
|
width: _.asPx(width),
|
|
maxWidth: _.asPx(maxWidth),
|
|
}}
|
|
{...tdProps.rest}
|
|
>
|
|
{_.normalizeComponent(PadRowComponent)}
|
|
</TdComponent>
|
|
)
|
|
}
|
|
|
|
const makePadRow = (row, i) => {
|
|
const trGroupProps = getTrGroupProps(finalState, undefined, undefined, this)
|
|
const trProps = _.splitProps(getTrProps(finalState, undefined, undefined, this))
|
|
return (
|
|
<TrGroupComponent key={`pad-${i}`} {...trGroupProps}>
|
|
<TrComponent
|
|
className={classnames(
|
|
'-padRow',
|
|
(pageRows.length + i) % 2 ? '-even' : '-odd',
|
|
trProps.className
|
|
)}
|
|
style={trProps.style || {}}
|
|
>
|
|
{allVisibleColumns.map(makePadColumn)}
|
|
</TrComponent>
|
|
</TrGroupComponent>
|
|
)
|
|
}
|
|
|
|
const makeColumnFooter = (column, i) => {
|
|
const resizedCol = resized.find(x => x.id === column.id) || {}
|
|
const show = typeof column.show === 'function' ? column.show() : column.show
|
|
const width = _.getFirstDefined(resizedCol.value, column.width, column.minWidth)
|
|
const maxWidth = _.getFirstDefined(resizedCol.value, column.width, column.maxWidth)
|
|
const tFootTdProps = _.splitProps(getTfootTdProps(finalState, undefined, undefined, this))
|
|
const columnProps = _.splitProps(column.getProps(finalState, undefined, column, this))
|
|
const columnFooterProps = _.splitProps(
|
|
column.getFooterProps(finalState, undefined, column, this)
|
|
)
|
|
|
|
const classes = [
|
|
tFootTdProps.className,
|
|
column.className,
|
|
columnProps.className,
|
|
columnFooterProps.className,
|
|
]
|
|
|
|
const styles = {
|
|
...tFootTdProps.style,
|
|
...column.style,
|
|
...columnProps.style,
|
|
...columnFooterProps.style,
|
|
}
|
|
|
|
return (
|
|
<TdComponent
|
|
key={`${i}-${column.id}`}
|
|
className={classnames(classes, !show && 'hidden')}
|
|
style={{
|
|
...styles,
|
|
flex: `${width} 0 auto`,
|
|
width: _.asPx(width),
|
|
maxWidth: _.asPx(maxWidth),
|
|
}}
|
|
{...columnProps.rest}
|
|
{...tFootTdProps.rest}
|
|
{...columnFooterProps.rest}
|
|
>
|
|
{_.normalizeComponent(column.Footer, {
|
|
data: sortedData,
|
|
column,
|
|
})}
|
|
</TdComponent>
|
|
)
|
|
}
|
|
|
|
const makeColumnFooters = () => {
|
|
const tFootProps = _.splitProps(getTfootProps(finalState, undefined, undefined, this))
|
|
const tFootTrProps = _.splitProps(getTfootTrProps(finalState, undefined, undefined, this))
|
|
return (
|
|
<TfootComponent
|
|
className={tFootProps.className}
|
|
style={{
|
|
...tFootProps.style,
|
|
minWidth: `${rowMinWidth}px`,
|
|
}}
|
|
{...tFootProps.rest}
|
|
>
|
|
<TrComponent
|
|
className={classnames(tFootTrProps.className)}
|
|
style={tFootTrProps.style}
|
|
{...tFootTrProps.rest}
|
|
>
|
|
{allVisibleColumns.map(makeColumnFooter)}
|
|
</TrComponent>
|
|
</TfootComponent>
|
|
)
|
|
}
|
|
|
|
const makePagination = (isTop) => {
|
|
const paginationProps = _.splitProps(
|
|
getPaginationProps(finalState, undefined, undefined, this)
|
|
)
|
|
return (
|
|
<PaginationComponent
|
|
{...resolvedState}
|
|
pages={pages}
|
|
canPrevious={canPrevious}
|
|
canNext={canNext}
|
|
onPageChange={this.onPageChange}
|
|
onPageSizeChange={this.onPageSizeChange}
|
|
className={paginationProps.className}
|
|
style={paginationProps.style}
|
|
isTop={isTop}
|
|
{...paginationProps.rest}
|
|
/>
|
|
)
|
|
}
|
|
|
|
const makeTable = () => {
|
|
return (
|
|
<div
|
|
className={classnames('ReactTable', className, rootProps.className)}
|
|
style={{
|
|
...style,
|
|
...rootProps.style,
|
|
}}
|
|
{...rootProps.rest}
|
|
>
|
|
{showPagination && showPaginationTop ? (
|
|
<div className="pagination-top">{makePagination(true)}</div>
|
|
) : null}
|
|
<TableComponent
|
|
className={classnames(tableProps.className, currentlyResizing ? 'rt-resizing' : '')}
|
|
style={tableProps.style}
|
|
{...tableProps.rest}
|
|
>
|
|
{hasHeaderGroups ? makeHeaderGroups() : null}
|
|
{makeHeaders()}
|
|
{hasFilters ? makeFilters() : null}
|
|
<TbodyComponent
|
|
className={classnames(tBodyProps.className)}
|
|
style={{
|
|
...tBodyProps.style,
|
|
minWidth: `${rowMinWidth}px`,
|
|
}}
|
|
{...tBodyProps.rest}
|
|
>
|
|
{pageRows.map((d, i) => makePageRow(d, i))}
|
|
{padRows.map(makePadRow)}
|
|
</TbodyComponent>
|
|
{hasColumnFooter ? makeColumnFooters() : null}
|
|
</TableComponent>
|
|
{showPagination && showPaginationBottom ? (
|
|
<div className="pagination-bottom">{makePagination(false)}</div>
|
|
) : null}
|
|
{!pageRows.length && (
|
|
<NoDataComponent {...noDataProps}>{_.normalizeComponent(noDataText)}</NoDataComponent>
|
|
)}
|
|
<LoadingComponent loading={loading} loadingText={loadingText} {...loadingProps} />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
// childProps are optionally passed to a function-as-a-child
|
|
return children ? children(finalState, makeTable, this) : makeTable()
|
|
}
|
|
}
|