Support element rows
parent
67297ccdce
commit
5880fa26ea
|
@ -37,7 +37,8 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
{
|
||||
static propTypes = {
|
||||
theme: PropTypes.object,
|
||||
rows: PropTypes.arrayOf(PropTypes.array).isRequired,
|
||||
rows: PropTypes.array.isRequired,
|
||||
columnWidths: PropTypes.arrayOf(PropTypes.string),
|
||||
isResizable: PropTypes.arrayOf(PropTypes.bool),
|
||||
noWrapDefault: PropTypes.bool,
|
||||
hasRowHover: PropTypes.bool,
|
||||
|
@ -295,6 +296,73 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
this.rootNode = e;
|
||||
}
|
||||
|
||||
decorateCells(row, decorateProps)
|
||||
{
|
||||
const css = this.props.theme || default_css;
|
||||
let cells = [];
|
||||
let j = 0;
|
||||
for (let cell of row)
|
||||
{
|
||||
if (cell == null)
|
||||
{
|
||||
// Skip null or undefined cells
|
||||
continue;
|
||||
}
|
||||
const isDiv = React.isValidElement(cell) && cell.type == 'div';
|
||||
const className = ' ' + css.cell + ' ' +
|
||||
(decorateProps.rowIndex == 0 ? ' '+css.first_row : '') +
|
||||
(decorateProps.rowIndex == decorateProps.rowCount-1 ? ' '+css.last_row : '') +
|
||||
(j == 0 && (!isDiv || !cell.props.style ||
|
||||
!cell.props.style.gridColumn && !cell.props.style.gridColumnStart ||
|
||||
cell.props.style.gridColumn == 1 || cell.props.style.gridColumnStart == 1) ? ' '+css.first_col : '') +
|
||||
(j == row.length-1 ? ' '+css.last_col : '') +
|
||||
(j & 1 ? ' '+css.even : '');
|
||||
if (!isDiv)
|
||||
{
|
||||
cell = (<div className={className} row={decorateProps.rowIndex} col={j} key={decorateProps.rowIndex+'-'+j}>
|
||||
{this.props.noWrapDefault
|
||||
? <div className={css.ellipsis}>{cell}</div>
|
||||
: cell}
|
||||
</div>);
|
||||
}
|
||||
else
|
||||
{
|
||||
let spec = {};
|
||||
let cls = cell.props.className
|
||||
? cell.props.className.replace(/(^|\s)(wrap)(?=$|\s)/g, (m, m1, m2) => { spec[m2] = true; return ''; })
|
||||
: '';
|
||||
if (cell.props.sticky_col < 0)
|
||||
cls = cls + ' ' + css.stick_right;
|
||||
else if (cell.props.sticky_col > 0)
|
||||
cls = cls + ' ' + css.stick_left;
|
||||
if (cell.props.sticky_row < 0)
|
||||
cls = cls + ' ' + css.stick_bottom;
|
||||
else if (cell.props.sticky_row > 0)
|
||||
cls = cls + ' ' + css.stick_top;
|
||||
let props = {
|
||||
row: decorateProps.rowIndex,
|
||||
col: j,
|
||||
key: decorateProps.rowIndex+'-'+j,
|
||||
className: cls+className,
|
||||
};
|
||||
if (spec.wrap || !this.props.noWrapDefault)
|
||||
{
|
||||
cell = React.cloneElement(cell, props);
|
||||
}
|
||||
else
|
||||
{
|
||||
// By default cells are non-wrappable with text-overflow: ellipsis
|
||||
cell = React.cloneElement(cell, props, (<div className={css.ellipsis}>
|
||||
{cell.props.children}
|
||||
</div>));
|
||||
}
|
||||
}
|
||||
cells.push(cell);
|
||||
j++;
|
||||
}
|
||||
return cells;
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
const css = this.props.theme || default_css;
|
||||
|
@ -303,65 +371,19 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
let i = 0;
|
||||
for (let row of rows)
|
||||
{
|
||||
let j = 0;
|
||||
for (let cell of row)
|
||||
const rowProps = { rowIndex: i, rowCount: rows.length };
|
||||
if (React.isValidElement(row))
|
||||
{
|
||||
if (cell == null)
|
||||
{
|
||||
// skip null or undefined cells
|
||||
continue;
|
||||
}
|
||||
const isDiv = React.isValidElement(cell) && cell.type == 'div';
|
||||
const className = ' ' + css.cell + ' ' +
|
||||
(i == 0 ? ' '+css.first_row : '') +
|
||||
(i == rows.length-1 ? ' '+css.last_row : '') +
|
||||
(j == 0 && (!isDiv || !cell.props.style ||
|
||||
!cell.props.style.gridColumn && !cell.props.style.gridColumnStart ||
|
||||
cell.props.style.gridColumn == 1 || cell.props.style.gridColumnStart == 1) ? ' '+css.first_col : '') +
|
||||
(j == row.length-1 ? ' '+css.last_col : '') +
|
||||
(j & 1 ? ' '+css.even : '');
|
||||
if (!isDiv)
|
||||
{
|
||||
cell = (<div className={className} row={i} col={j} key={i+'-'+j}>
|
||||
{this.props.noWrapDefault
|
||||
? <div className={css.ellipsis}>{cell}</div>
|
||||
: cell}
|
||||
</div>);
|
||||
}
|
||||
else
|
||||
{
|
||||
let spec = {};
|
||||
let cls = cell.props.className
|
||||
? cell.props.className.replace(/(^|\s)(wrap)(?=$|\s)/g, (m, m1, m2) => { spec[m2] = true; return ''; })
|
||||
: '';
|
||||
if (cell.props.sticky_col < 0)
|
||||
cls = cls + ' ' + css.stick_right;
|
||||
else if (cell.props.sticky_col > 0)
|
||||
cls = cls + ' ' + css.stick_left;
|
||||
if (cell.props.sticky_row < 0)
|
||||
cls = cls + ' ' + css.stick_bottom;
|
||||
else if (cell.props.sticky_row > 0)
|
||||
cls = cls + ' ' + css.stick_top;
|
||||
let props = {
|
||||
row: i,
|
||||
col: j,
|
||||
key: i+'-'+j,
|
||||
className: cls+className,
|
||||
};
|
||||
if (spec.wrap || !this.props.noWrapDefault)
|
||||
{
|
||||
cell = React.cloneElement(cell, props);
|
||||
}
|
||||
else
|
||||
{
|
||||
// By default cells are non-wrappable with text-overflow: ellipsis
|
||||
cell = React.cloneElement(cell, props, (<div className={css.ellipsis}>
|
||||
{cell.props.children}
|
||||
</div>));
|
||||
}
|
||||
}
|
||||
cells.push(cell);
|
||||
j++;
|
||||
// Allow element rows
|
||||
// In fact, this should be the default use-case
|
||||
rowProps.decorateCells = (cells) => this.decorateCells(cells, rowProps);
|
||||
cells.push(React.cloneElement(row, rowProps));
|
||||
}
|
||||
else
|
||||
{
|
||||
// In other case just process cells in-place
|
||||
// BUT this is slow, because such cells are reconciled on each render
|
||||
cells.push.apply(cells, this.decorateCells(row, rowProps));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue