Make rows move-resilient
parent
5880fa26ea
commit
c1ec2a1fdb
|
@ -6,11 +6,13 @@
|
|||
*
|
||||
* Author: Vitaliy Filippov <vitalif@yourcmc.ru>, 2019
|
||||
* License: dual-license MPL 2.0 or GPL 3.0+
|
||||
* Version: 2019-02-11
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import bindCache from './bind-cache.js';
|
||||
import default_css from './FixedHeaderGridTableRT.css';
|
||||
|
||||
/**
|
||||
|
@ -51,7 +53,7 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
userWidths: [],
|
||||
}
|
||||
|
||||
activeRow = 0
|
||||
activeRow = null
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
|
@ -241,13 +243,14 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
}
|
||||
c = c.parentNode;
|
||||
}
|
||||
row = row || null;
|
||||
// Row highlight
|
||||
if (this.props.hasRowHover !== false)
|
||||
{
|
||||
const css = this.props.theme || default_css;
|
||||
if (this.activeRow != row)
|
||||
{
|
||||
if (this.activeRow > 0)
|
||||
if (this.activeRow != null)
|
||||
{
|
||||
for (let e of this.rootNode.querySelectorAll('*[row="'+this.activeRow+'"]'))
|
||||
{
|
||||
|
@ -255,7 +258,7 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
}
|
||||
}
|
||||
this.activeRow = row;
|
||||
if (this.activeRow > 0)
|
||||
if (this.activeRow != null)
|
||||
{
|
||||
for (let e of this.rootNode.querySelectorAll('*[row="'+this.activeRow+'"]'))
|
||||
{
|
||||
|
@ -276,14 +279,14 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
{
|
||||
// Remove row highlight
|
||||
const css = this.props.theme || default_css;
|
||||
if (this.activeRow > 0)
|
||||
if (this.activeRow != null)
|
||||
{
|
||||
for (let e of this.rootNode.querySelectorAll('*[row="'+this.activeRow+'"]'))
|
||||
{
|
||||
e.className = e.className.replace(' '+css.hover, '');
|
||||
}
|
||||
}
|
||||
this.activeRow = 0;
|
||||
this.activeRow = null;
|
||||
}
|
||||
if (this.props.isResizable === undefined || this.props.isResizable)
|
||||
{
|
||||
|
@ -296,8 +299,9 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
this.rootNode = e;
|
||||
}
|
||||
|
||||
decorateCells(row, decorateProps)
|
||||
decorateCells = (status, row, decorateProps) =>
|
||||
{
|
||||
const rowKey = decorateProps && decorateProps.key;
|
||||
const css = this.props.theme || default_css;
|
||||
let cells = [];
|
||||
let j = 0;
|
||||
|
@ -310,8 +314,8 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
}
|
||||
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 : '') +
|
||||
(status == 'first' ? ' '+css.first_row : '') +
|
||||
(status == 'last' ? ' '+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 : '') +
|
||||
|
@ -319,7 +323,7 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
(j & 1 ? ' '+css.even : '');
|
||||
if (!isDiv)
|
||||
{
|
||||
cell = (<div className={className} row={decorateProps.rowIndex} col={j} key={decorateProps.rowIndex+'-'+j}>
|
||||
cell = (<div className={className} row={rowKey} col={j} key={rowKey+'-'+j}>
|
||||
{this.props.noWrapDefault
|
||||
? <div className={css.ellipsis}>{cell}</div>
|
||||
: cell}
|
||||
|
@ -340,9 +344,8 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
else if (cell.props.sticky_row > 0)
|
||||
cls = cls + ' ' + css.stick_top;
|
||||
let props = {
|
||||
row: decorateProps.rowIndex,
|
||||
col: j,
|
||||
key: decorateProps.rowIndex+'-'+j,
|
||||
row: rowKey,
|
||||
key: rowKey+'-'+j,
|
||||
className: cls+className,
|
||||
};
|
||||
if (spec.wrap || !this.props.noWrapDefault)
|
||||
|
@ -371,19 +374,19 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
let i = 0;
|
||||
for (let row of rows)
|
||||
{
|
||||
const rowProps = { rowIndex: i, rowCount: rows.length };
|
||||
if (React.isValidElement(row))
|
||||
{
|
||||
// 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));
|
||||
cells.push(React.cloneElement(row, {
|
||||
decorateCells: this.bind('decorateCells', i == 0 ? 'first' : (i == rows.length-1 ? 'last' : '')),
|
||||
}));
|
||||
}
|
||||
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));
|
||||
cells.push.apply(cells, this.decorateCells(i, row));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -393,11 +396,13 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
// So we add some extra invisible cells to do this
|
||||
for (let col = 0; col < this.props.columnWidths.length; col++)
|
||||
{
|
||||
cells.push(<div className={css.measure_col} style={{gridColumn: (col+1)}}></div>);
|
||||
cells.push(<div key={"mc"+col} className={css.measure_col}
|
||||
style={{gridColumn: (col+1)}}></div>);
|
||||
}
|
||||
for (let row = 0; row < rows.length; row++)
|
||||
{
|
||||
cells.push(<div className={css.measure_row} style={{position: 'absolute', left: '-100px', width: '1px', height: '1px', gridColumn: 1, gridRow: (row+1)}}></div>);
|
||||
cells.push(<div key={"mr"+row} className={css.measure_row}
|
||||
style={{position: 'absolute', left: '-100px', width: '1px', height: '1px', gridColumn: 1, gridRow: (row+1)}}></div>);
|
||||
}
|
||||
}
|
||||
const ws = this.state.userWidths || [];
|
||||
|
@ -422,4 +427,6 @@ export class FixedHeaderGridTable extends React.PureComponent
|
|||
: null}
|
||||
</div>);
|
||||
}
|
||||
|
||||
bind = bindCache(this)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue