UNPKG

react-table-6

Version:

A fast, lightweight, opinionated table and datagrid built on React

235 lines (188 loc) 6.22 kB
/* eslint-disable */ import React from 'react' import left from './left.svg' import right from './right.svg' const defaultFoldIconComponent = ({ collapsed }) => { const style = { width: 25 } if (collapsed) return <img src={right} style={style} alt="right" /> return <img src={left} style={style} alt="left" /> } const defaultFoldButtonComponent = ({ header, collapsed, icon, onClick }) => { const style = { marginLeft: '0px', marginTop: '-5px', marginBottom: '-8px', float: 'left', cursor: 'pointer', } return ( <div> <div style={style} onClick={onClick}> {icon} </div> {!collapsed && <div>{header}</div>} </div> ) } export default ReactTable => { const wrapper = class RTFoldableTable extends React.Component { static getDerivedStateFromProps(props, state) { if (state.resized !== props.resized) { return { resized: props.resized || [], }; } return null; } constructor(props, context) { super(props, context) this.state = { folded: props.onFoldChange ? undefined : {}, resized: props.resized || [], } } onResizedChange = resized => { const { onResizedChange } = this.props if (onResizedChange) onResizedChange(resized) else { this.setState(p => ({ resized })) } } removeResized = column => { const { id } = column if (!id) return const { resized } = this.state if (!resized) return const rs = resized.find(r => r.id === id) if (!rs) return const newResized = resized.filter(r => r !== rs) this.onResizedChange(newResized) } // this is so we can expose the underlying ReactTable. getWrappedInstance = () => { if (!this.wrappedInstance) console.warn('RTFoldableTable - No wrapped instance') if (this.wrappedInstance.getWrappedInstance) return this.wrappedInstance.getWrappedInstance() return this.wrappedInstance } getCopiedKey = key => { const { foldableOriginalKey } = this.props return `${foldableOriginalKey}${key}` } copyOriginals = column => { const { FoldedColumn } = this.props // Stop copy if the column already copied if (column.original_Header) return Object.keys(FoldedColumn).forEach(k => { const copiedKey = this.getCopiedKey(k) if (k === 'Cell') column[copiedKey] = column[k] ? column[k] : c => c.value else column[copiedKey] = column[k] }) // Copy sub Columns if (column.columns && !column.original_Columns) column.original_Columns = column.columns // Copy Header if (!column.original_Header) column.original_Header = column.Header } restoreToOriginal = column => { const { FoldedColumn } = this.props Object.keys(FoldedColumn).forEach(k => { // ignore header as handling by foldableHeaderRender if (k === 'Header') return const copiedKey = this.getCopiedKey(k) column[k] = column[copiedKey] }) if (column.columns && column.original_Columns) column.columns = column.original_Columns } getState = () => (this.props.onFoldChange ? this.props.folded : this.state.folded) isFolded = col => { const folded = this.getState() return folded[col.id] === true } foldingHandler = col => { if (!col || !col.id) return const { onFoldChange } = this.props const folded = this.getState() const { id } = col const newFold = Object.assign({}, folded) newFold[id] = !newFold[id] // Remove the Resized if have this.removeResized(col) if (onFoldChange) onFoldChange(newFold) else { this.setState(previous => ({ folded: newFold })) } } foldableHeaderRender = cell => { const { FoldButtonComponent, FoldIconComponent } = this.props const { column } = cell const collapsed = this.isFolded(column) const icon = React.createElement(FoldIconComponent, { collapsed }) const onClick = () => this.foldingHandler(column) return React.createElement(FoldButtonComponent, { header: column.original_Header, collapsed, icon, onClick, }) } applyFoldableForColumn = column => { const collapsed = this.isFolded(column) const { FoldedColumn } = this.props // Handle Column Header if (column.columns) { if (collapsed) { column.columns = [FoldedColumn] column.width = FoldedColumn.width column.style = FoldedColumn.style } else this.restoreToOriginal(column) } // Handle Normal Column. else if (collapsed) column = Object.assign(column, FoldedColumn) else { this.restoreToOriginal(column) } } applyFoldableForColumns = columns => columns.map((col, index) => { if (!col.foldable) return col // If col don't have id then generate id based on index if (!col.id) col.id = `col_${index}` this.copyOriginals(col) // Replace current header with internal header render. col.Header = c => this.foldableHeaderRender(c) // apply foldable this.applyFoldableForColumn(col) // return the new column out return col }) render() { const { columns: originalCols, FoldButtonComponent, FoldIconComponent, FoldedColumn, ...rest } = this.props const columns = this.applyFoldableForColumns([...originalCols]) const extra = { columns, onResizedChange: this.onResizedChange, resized: this.state.resized, } return <ReactTable {...rest} {...extra} ref={r => (this.wrappedInstance = r)} /> } } wrapper.displayName = 'RTFoldableTable' wrapper.defaultProps = { FoldIconComponent: defaultFoldIconComponent, FoldButtonComponent: defaultFoldButtonComponent, foldableOriginalKey: 'original_', FoldedColumn: { Cell: c => '', width: 30, sortable: false, resizable: false, filterable: false, }, } return wrapper }