Skip to content

Commit

Permalink
fix(Column): fix rowSpan cell layer covering fixed columns (#331)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonguo authored Apr 6, 2022
1 parent 42c8071 commit 16fab36
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 30 deletions.
7 changes: 7 additions & 0 deletions docs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ import fakeObjectDataListStore, { createFakeRowObjectData } from './data/fakeObj
import { useDrag, useDrop, DndProvider } from 'react-dnd';
import Backend from 'react-dnd-html5-backend';
import GearIcon from '@rsuite/icons/Gear';
import 'rsuite/Popover/styles/index.less';
import 'rsuite/Toggle/styles/index.less';
import 'rsuite/Grid/styles/index.less';
import 'rsuite/Button/styles/index.less';
import 'rsuite/ButtonGroup/styles/index.less';
import 'rsuite/Checkbox/styles/index.less';
import 'rsuite/Nav/styles/index.less';

function App() {
return (
Expand Down
5 changes: 2 additions & 3 deletions docs/less/index.less
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
@import '~react-code-view/lib/less/index.less';
@import '../../src/less/index.less';
@import '~rsuite/styles/index.less';

.btn-toolbar {
padding: 10px 0;
}
.icon-code:before{
.icon-code:before {
content: '';
}
}
1 change: 1 addition & 0 deletions docs/md/ColumnGroupTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const App = () => {
<Table
classPrefix="rs-table"
bordered
cellBordered
height={400}
headerHeight={100}
data={fakeDataForColSpan}
Expand Down
1 change: 1 addition & 0 deletions docs/md/CustomColumns.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const App = () => {
<Table
classPrefix="rs-table"
bordered
cellBordered
height={400}
headerHeight={100}
data={fakeDataForColSpan}
Expand Down
15 changes: 14 additions & 1 deletion docs/md/RowspanTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ const App = () => {
return (
<Table
bordered
cellBordered
height={400}
data={fakeDataForRowSpan}
onRowClick={data => {
console.log(data);
}}
>
<Column width={60} fixed>
<HeaderCell>id</HeaderCell>
<Cell dataKey="id" />
</Column>
<Column
width={200}
verticalAlign="middle"
Expand Down Expand Up @@ -45,7 +50,15 @@ const App = () => {
<Cell dataKey="lastName" />
</Column>

<Column width={200} flexGrow={1}>
<Column width={200}>
<HeaderCell>Company Name</HeaderCell>
<Cell dataKey="companyName" />
</Column>
<Column width={200}>
<HeaderCell>Company Name</HeaderCell>
<Cell dataKey="companyName" />
</Column>
<Column width={200}>
<HeaderCell>Company Name</HeaderCell>
<Cell dataKey="companyName" />
</Column>
Expand Down
46 changes: 33 additions & 13 deletions src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,16 @@ const Table = React.forwardRef((props: TableProps, ref) => {
getTranslateDOMPositionXY({ forceUseTransform: true, enable3DTransform: translate3d })
);

// Check for the existence of fixed columns in all column properties.
const shouldFixedColumn = Array.from(flatten(children as any) as Iterable<any>).some(
child => child?.props?.fixed
);

// Check all column properties for the existence of rowSpan.
const shouldRowSpanColumn = Array.from(flatten(children as any) as Iterable<any>).some(
child => child?.props?.rowSpan
);

const visibleRows = useRef<React.ReactNode[]>([]);
const mouseAreaRef = useRef<HTMLDivElement>(null);
const tableRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -529,7 +535,7 @@ const Table = React.forwardRef((props: TableProps, ref) => {
className,
withClassPrefix({
bordered,
hover,
hover: hover && !shouldRowSpanColumn,
loading,
treetable: isTree,
'word-wrap': wordWrap,
Expand Down Expand Up @@ -762,6 +768,12 @@ const Table = React.forwardRef((props: TableProps, ref) => {
[expandedRowKeys, onExpandChange, setExpandedRowKeys]
);

/**
* Records the status of merged rows.
* { cellKey: [count,index]}
*/
const rowSpanState = useRef<{ [cellKey: string]: [number, number] }>({});

const renderRowData = (
bodyCells: any[],
rowData: any,
Expand All @@ -788,22 +800,29 @@ const Table = React.forwardRef((props: TableProps, ref) => {
const cell = bodyCells[i];
const rowSpan: number = cell.props?.rowSpan?.(rowData);
const rowHeight = rowSpan ? rowSpan * (props.height || 46) : props.height;
const cellKey = cell.props.dataKey || i;

// Record the cell state of the merged row
if (rowSpanState.current[cellKey]?.[1] > 0) {
rowSpanState.current[cellKey][1] -= 1;

// Restart counting when merged to the last cell.
if (rowSpanState.current[cellKey][1] === 0) {
rowSpanState.current[cellKey][0] = 0;
}
}

if (rowSpan) {
// The state of the initial merged cell
rowSpanState.current[cellKey] = [rowSpan, rowSpan];
rowProps.rowSpan = rowSpan;
rowProps.style = {
/**
* In the case of multiple-column merged rows,
* the `zIndex` value of the previous row should be greater than the `zIndex` value of the following row.
* So `rowSpan` is used as the `zIndex` value.
*/
zIndex: rowProps.style?.zIndex || rowSpan,
overflow: 'inherit'
};

// TODO: Do not render those cells merged by `rowSpan`
rowProps.style = { overflow: 'inherit' };
}

// Cells marked as deleted when checking for merged cell.
const removedCell =
cell.props?.rowSpan && !rowSpan && rowSpanState.current[cellKey]?.[0] !== 0 ? true : false;

cells.push(
React.cloneElement(cell, {
hasChildren,
Expand All @@ -816,7 +835,8 @@ const Table = React.forwardRef((props: TableProps, ref) => {
onTreeToggle: handleTreeToggle,
rowKey: nextRowKey,
expanded,
rowSpan
rowSpan,
removed: removedCell
})
);
}
Expand Down
13 changes: 3 additions & 10 deletions src/less/table.less
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@
height: 36px;
width: 100%;
top: 0;
border-bottom: 1px solid @border-color;
}
&-row-rowspan + &-row {
border-top: 1px solid #eee;
}

&-hover &-row:hover {
Expand Down Expand Up @@ -109,6 +105,7 @@
}
&-content {
padding: 8px;
border-bottom: 1px solid #eee;
.ellipsis();
}

Expand All @@ -120,10 +117,6 @@
display: inline-block;
}
}

&-rowspan {
border-bottom: 1px solid @border-color !important;
}
}
&-column-resize-spanner {
height: 36px;
Expand Down Expand Up @@ -166,8 +159,8 @@
z-index: 6;
}

&-bordered &-cell {
border-width: 0 1px 0 0;
&-cell-bordered &-cell-content {
border-right: 1px solid #eee;
}

&-word-wrap &-cell-content {
Expand Down
12 changes: 9 additions & 3 deletions test/TableSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1074,13 +1074,19 @@ describe('Table', () => {
);

const rowspanCells = instance.querySelectorAll('.rs-table-cell-rowspan');
const rowspanRows = instance.querySelectorAll('.rs-table-row-rowspan');
const rows = instance.querySelectorAll('.rs-table-body-row-wrapper .rs-table-row');
assert.equal(rowspanCells[0].style.height, `${40 * 2}px`);
assert.equal(rowspanCells[1].style.height, `${40 * 3}px`);
assert.equal(rowspanRows[0].style.zIndex, 2);
assert.equal(rowspanRows[1].style.zIndex, 3);

assert.equal(instance.querySelectorAll('.rs-table-cell-rowspan').length, 2);
assert.equal(instance.querySelectorAll('.rs-table-row-rowspan').length, 2);

// Check if merged cells are removed.
assert.equal(rows[0].querySelectorAll('.rs-table-cell').length, 2);
assert.equal(rows[1].querySelectorAll('.rs-table-cell').length, 1);
assert.equal(rows[2].querySelectorAll('.rs-table-cell').length, 2);
assert.equal(rows[3].querySelectorAll('.rs-table-cell').length, 1);
assert.equal(rows[4].querySelectorAll('.rs-table-cell').length, 1);
});

// fix https://github.com/rsuite/rsuite/issues/2051
Expand Down

0 comments on commit 16fab36

Please sign in to comment.