49 lines
1.3 KiB
React
49 lines
1.3 KiB
React
import React from 'react';
|
|
import './MergedCellTable.css';
|
|
|
|
export default function MergedCellTable({ data = [], columns = [] }) {
|
|
const merged = data.map((row) => ({ ...row, _first: {}, _span: {} }));
|
|
columns.filter((c) => c.merge).forEach((c) => {
|
|
let i = 0;
|
|
while (i < merged.length) {
|
|
let j = i;
|
|
while (j + 1 < merged.length && merged[j + 1][c.key] === merged[i][c.key]) j++;
|
|
const span = j - i + 1;
|
|
for (let k = i; k <= j; k++) {
|
|
merged[k]._first[c.key] = k === i;
|
|
merged[k]._span[c.key] = span;
|
|
}
|
|
i = j + 1;
|
|
}
|
|
});
|
|
|
|
return (
|
|
<table className="aa-mergetable">
|
|
<thead>
|
|
<tr>
|
|
{columns.map((c) => (
|
|
<th key={c.key}>{c.title}</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{merged.map((row, idx) => (
|
|
<tr key={idx}>
|
|
{columns.map((c) =>
|
|
!c.merge || row._first[c.key] ? (
|
|
<td
|
|
key={c.key}
|
|
className={c.merge && row._first[c.key] ? 'aa-merged' : ''}
|
|
rowSpan={c.merge && row._first[c.key] ? row._span[c.key] : undefined}
|
|
>
|
|
{row[c.key]}
|
|
</td>
|
|
) : null
|
|
)}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
);
|
|
}
|