UNPKG

react-cm-ui

Version:
240 lines (216 loc) 7.4 kB
import { flatMap, isFunction, map, isArray, isNil, } from 'lodash'; import ClassNames from 'classnames'; import PropTypes from 'prop-types'; import React from 'react'; import { BEM_DATA_GRID } from '../../global/constants'; import { SORTABLE_PROP_TYPES } from './dataGridConstants'; import DataGridTableRow from './dataGridTableRow'; import Table from '../table'; import DataGridTableReactSortable from './dataGridTableReactSortable'; const propTypes = { bleed: PropTypes.bool, className: PropTypes.string, columns: PropTypes.arrayOf(PropTypes.shape({ className: PropTypes.string, id: PropTypes.string, style: PropTypes.shape({}), })).isRequired, data: PropTypes.arrayOf( PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.shape({})), PropTypes.shape({}), ]), ).isRequired, dropShadow: PropTypes.bool, fontSize: PropTypes.string, id: PropTypes.string.isRequired, idPrefix: PropTypes.string, resizableColumnWidthPercentage: PropTypes.number, rowProps: PropTypes.func, size: PropTypes.oneOf([ 'small', 'medium', ]), sortable: PropTypes.arrayOf(SORTABLE_PROP_TYPES), stickyColumns: PropTypes.number, stretch: PropTypes.oneOfType([ PropTypes.oneOf(['very']), PropTypes.bool, ]), style: PropTypes.shape({}), }; const defaultProps = { bleed: true, className: undefined, dropShadow: false, fontSize: 'xsmall', idPrefix: 'base', resizableColumnWidthPercentage: undefined, rowProps: () => ({ className: null, id: null, onClick: null, selected: null, style: null, }), size: 'small', sortable: null, stickyColumns: undefined, stretch: false, style: undefined, }; class DataGridTable extends React.PureComponent { constructor(props) { super(props); this.onSortableChange = this.onSortableChange.bind(this); } onSortableChange(newData, index) { const { sortable, } = this.props; if (isFunction(sortable[index].onChange)) { sortable[index].onChange(newData, index); } } render() { const { bleed: bleedProp, className, columns, data: dataProp, dropShadow, fontSize, id, idPrefix, rowProps, resizableColumnWidthPercentage, size, sortable, stickyColumns, stretch, style, } = this.props; const isSelectable = isFunction(rowProps().onClick); let rowKeyNum = 1; const tableRows = (data, handle) => flatMap(data, (row) => { rowKeyNum += 1; return ( <DataGridTableRow columns={columns} handle={handle} id={id} idPrefix={idPrefix} isClickable={isSelectable} key={`tableBodyRow-${row.id || rowKeyNum}`} row={row} rowIndex={rowKeyNum} rowProps={rowProps(row)} /> ); }); let tableBody; const bodyClasses = ClassNames({ [`${BEM_DATA_GRID}--table_body-drop_shadow`]: dropShadow }); if (isArray(sortable) && sortable.length === 1 && !isArray(dataProp[0])) { tableBody = ( <DataGridTableReactSortable arrayIndex={0} className={bodyClasses} list={dataProp} sortable={{ ...sortable, filter: `${BEM_DATA_GRID}--table-filter`, }} > {tableRows( dataProp, !isNil(sortable[0].handle) ? sortable[0].handle : true, )} </DataGridTableReactSortable> ); } else if (isArray(sortable) && isArray(dataProp[0])) { let tBodyKeyNum = 1; tableBody = map(dataProp, (arrayOfData, arrayIndex) => { const hasHandle = !isNil(sortable[arrayIndex].handle) ? sortable[arrayIndex].handle : true; tBodyKeyNum += 1; return ( <DataGridTableReactSortable arrayIndex={arrayIndex} className={bodyClasses} key={`tbody--${tBodyKeyNum}`} list={arrayOfData} sortable={{ ...sortable, filter: `${BEM_DATA_GRID}--table-filter`, }} > {tableRows( arrayOfData, hasHandle, )} </DataGridTableReactSortable> ); }); } else { tableBody = ( <Table.Body className={bodyClasses} > {tableRows(dataProp)} </Table.Body> ); } const rootClasses = ClassNames('ui', `${BEM_DATA_GRID}--table`, className); const bleed = bleedProp ? 'very' : stretch; return ( <div className={rootClasses} style={style} > <Table basic className={`${BEM_DATA_GRID}--table_component`} fontSize={fontSize} selectable={isSelectable} size={size} stretch={bleed} stickyColumnCount={stickyColumns} resizableColumnWidthPercentage={resizableColumnWidthPercentage} > <Table.Header> <Table.Row> {map(columns, (column, index) => { const headerCellClasses = ClassNames( `${BEM_DATA_GRID}--table_header_cell`, column.className, ); const cellId = column.id || `${BEM_DATA_GRID}--table_${id}_header_${idPrefix}-${index}`; return ( <Table.HeaderCell className={headerCellClasses} id={cellId} key={`tableBodyRow-${index}`} style={column.style} > {column.header} </Table.HeaderCell> ); })} </Table.Row> </Table.Header> {tableBody} </Table> </div> ); } } DataGridTable.propTypes = propTypes; DataGridTable.defaultProps = defaultProps; export default DataGridTable;