Android_Retail/src/Pages/StockMaster/VirtualizedTable.jsx

172 lines
4.9 KiB
React
Raw Normal View History

2026-02-06 14:27:37 +05:30
import { useRef } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
const VirtualizedTable = ({
dataSource = [],
columns = [],
rowHeight = 54,
height = '50vh',
overscan = 10,
rowKey = 'id',
}) => {
const parentRef = useRef();
const headerRef = useRef();
const rowVirtualizer = useVirtualizer({
count: dataSource.length,
getScrollElement: () => parentRef.current,
estimateSize: () => rowHeight,
overscan,
});
const handleBodyScroll = (e) => {
if (headerRef.current) {
headerRef.current.scrollLeft = e.target.scrollLeft;
}
};
const virtualItems = rowVirtualizer.getVirtualItems();
const totalSize = rowVirtualizer.getTotalSize();
return (
<div
style={{
border: '1px solid #d1d1d1',
borderRadius: '4px',
width: '100%',
overflow: 'hidden',
}}
>
{/* Header */}
<div ref={headerRef} style={{ overflowX: 'hidden', overflowY: 'hidden' }}>
<table
style={{
borderCollapse: 'collapse',
width: '100%',
tableLayout: 'auto',
}}
>
<thead style={{ background: '#2c88ee', color: '#fff' }}>
<tr className="proReceiptTD">
{columns.map((col) => (
<th
key={col.key || col.dataIndex}
style={{
padding: '10px 6px',
textAlign: col.align || 'left',
fontWeight: 600,
fontSize: '13px',
borderRight: '1px solid rgba(255,255,255,0.3)',
boxSizing: 'border-box',
width: col.width || 'auto',
minWidth: col.width || 80,
whiteSpace: 'nowrap',
}}
>
{col.title}
</th>
))}
</tr>
</thead>
</table>
</div>
{/* Body */}
<div
ref={parentRef}
onScroll={handleBodyScroll}
style={{
height,
overflowY: 'auto',
overflowX: 'auto',
position: 'relative',
scrollbarWidth: 'thin',
}}
>
<div style={{ height: `${totalSize}px`, position: 'relative' }}>
{virtualItems.map((virtualRow) => {
const record = dataSource[virtualRow.index];
const key = record?.[rowKey] || virtualRow.index;
return (
<div
className="UppertablePR"
key={key}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: `${rowHeight}px`,
transform: `translateY(${virtualRow.start}px)`,
}}
>
<table
style={{
borderCollapse: 'collapse',
width: '100%',
tableLayout: 'auto',
height: '100%',
}}
>
<tbody>
<tr
className="proReceiptTD"
style={{
backgroundColor:
virtualRow.index % 2 === 0 ? '#e2e2e2' : '#fff',
borderBottom: '1px solid #f0f0f0',
}}
>
{columns.map((col) => (
<td
className="tdProductrecipt"
key={col.key || col.dataIndex}
style={{
padding: '6px',
borderRight: '1px solid #f0f0f0',
fontSize: '12px',
fontWeight: 500,
boxSizing: 'border-box',
width: col.width || 'auto',
minWidth: col.width || 80,
textAlign: col.align || 'left',
verticalAlign: 'middle',
}}
>
{col.render
? col.render(
record?.[col.dataIndex],
record,
virtualRow.index
)
: record?.[col.dataIndex]}
</td>
))}
</tr>
</tbody>
</table>
</div>
);
})}
</div>
</div>
{dataSource.length === 0 && (
<div
style={{
textAlign: 'center',
padding: '20px',
color: '#999',
fontSize: '14px',
}}
>
No data
</div>
)}
</div>
);
};
export default VirtualizedTable;