Support element rows
parent
67297ccdce
commit
5880fa26ea
|
@ -37,7 +37,8 @@ export class FixedHeaderGridTable extends React.PureComponent
|
||||||
{
|
{
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
theme: PropTypes.object,
|
theme: PropTypes.object,
|
||||||
rows: PropTypes.arrayOf(PropTypes.array).isRequired,
|
rows: PropTypes.array.isRequired,
|
||||||
|
columnWidths: PropTypes.arrayOf(PropTypes.string),
|
||||||
isResizable: PropTypes.arrayOf(PropTypes.bool),
|
isResizable: PropTypes.arrayOf(PropTypes.bool),
|
||||||
noWrapDefault: PropTypes.bool,
|
noWrapDefault: PropTypes.bool,
|
||||||
hasRowHover: PropTypes.bool,
|
hasRowHover: PropTypes.bool,
|
||||||
|
@ -295,6 +296,73 @@ export class FixedHeaderGridTable extends React.PureComponent
|
||||||
this.rootNode = e;
|
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()
|
render()
|
||||||
{
|
{
|
||||||
const css = this.props.theme || default_css;
|
const css = this.props.theme || default_css;
|
||||||
|
@ -303,65 +371,19 @@ export class FixedHeaderGridTable extends React.PureComponent
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (let row of rows)
|
for (let row of rows)
|
||||||
{
|
{
|
||||||
let j = 0;
|
const rowProps = { rowIndex: i, rowCount: rows.length };
|
||||||
for (let cell of row)
|
if (React.isValidElement(row))
|
||||||
{
|
{
|
||||||
if (cell == null)
|
// Allow element rows
|
||||||
{
|
// In fact, this should be the default use-case
|
||||||
// skip null or undefined cells
|
rowProps.decorateCells = (cells) => this.decorateCells(cells, rowProps);
|
||||||
continue;
|
cells.push(React.cloneElement(row, rowProps));
|
||||||
}
|
}
|
||||||
const isDiv = React.isValidElement(cell) && cell.type == 'div';
|
else
|
||||||
const className = ' ' + css.cell + ' ' +
|
{
|
||||||
(i == 0 ? ' '+css.first_row : '') +
|
// In other case just process cells in-place
|
||||||
(i == rows.length-1 ? ' '+css.last_row : '') +
|
// BUT this is slow, because such cells are reconciled on each render
|
||||||
(j == 0 && (!isDiv || !cell.props.style ||
|
cells.push.apply(cells, this.decorateCells(row, rowProps));
|
||||||
!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++;
|
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue