<code><!-- language: lang-jsx -->
import React, { useState, useCallback, useRef, useEffect, useMemo } from 'react';
import { FixedSizeGrid as Grid } from 'react-window';
// Function to generate column labels
const generateColumnLabels = (numColumns) => {
const labels = [];
let i = 0;
while (labels.length < numColumns) {
let label = '';
let temp = i;
while (temp >= 0) {
label = String.fromCharCode((temp % 26) + 65) + label;
temp = Math.floor(temp / 26) - 1;
}
labels.push(label);
i++;
}
return labels;
};
const Cell = React.memo(({ columnIndex, rowIndex, style, data, handleInputChange, inputRefs }) => {
const inputRef = useRef(null);
useEffect(() => {
inputRefs.current[`${rowIndex}-${columnIndex}`] = inputRef.current;
}, [rowIndex, columnIndex, inputRefs]);
return (
<div style={{ ...style, width: 150 }}>
<input
ref={inputRef}
type="text"
style={{ width: '100%' }}
value={
data[rowIndex] && data[rowIndex][columnIndex] !== undefined
? data[rowIndex][columnIndex]
: ''
}
onChange={(e) => handleInputChange(rowIndex, columnIndex, e.target.value)}
data-row={rowIndex}
data-col={columnIndex}
/>
</div>
);
});
const ExcelTable = ({ _rows = 30, _columns = 20, _data = [] }) => {
const [rows] = useState(_rows);
const [columns] = useState(_columns);
const [data, setData] = useState(_data);
const inputRefs = useRef({});
const columnLabels = useMemo(() => generateColumnLabels(columns), [columns]);
const handleInputChange = useCallback((rowIndex, colIndex, value) => {
setData((prevData) => {
const newData = [...prevData];
if (!newData[rowIndex]) {
newData[rowIndex] = [];
}
newData[rowIndex][colIndex] = value;
return newData;
});
}, []);
return (
<div className="table-wrapper">
<Grid
columnCount={columns}
columnWidth={150}
height={600}
rowCount={rows}
rowHeight={40}
width={1000}
>
{({ columnIndex, rowIndex, style }) => (
<Cell
columnIndex={columnIndex}
rowIndex={rowIndex}
style={style}
data={data}
handleInputChange={handleInputChange}
inputRefs={inputRefs}
/>
)}
</Grid>
</div>
);
};
export default ExcelTable;
<!-- language: lang-jsx -->
</code>
<code><!-- language: lang-jsx -->
import React, { useState, useCallback, useRef, useEffect, useMemo } from 'react';
import { FixedSizeGrid as Grid } from 'react-window';
// Function to generate column labels
const generateColumnLabels = (numColumns) => {
const labels = [];
let i = 0;
while (labels.length < numColumns) {
let label = '';
let temp = i;
while (temp >= 0) {
label = String.fromCharCode((temp % 26) + 65) + label;
temp = Math.floor(temp / 26) - 1;
}
labels.push(label);
i++;
}
return labels;
};
const Cell = React.memo(({ columnIndex, rowIndex, style, data, handleInputChange, inputRefs }) => {
const inputRef = useRef(null);
useEffect(() => {
inputRefs.current[`${rowIndex}-${columnIndex}`] = inputRef.current;
}, [rowIndex, columnIndex, inputRefs]);
return (
<div style={{ ...style, width: 150 }}>
<input
ref={inputRef}
type="text"
style={{ width: '100%' }}
value={
data[rowIndex] && data[rowIndex][columnIndex] !== undefined
? data[rowIndex][columnIndex]
: ''
}
onChange={(e) => handleInputChange(rowIndex, columnIndex, e.target.value)}
data-row={rowIndex}
data-col={columnIndex}
/>
</div>
);
});
const ExcelTable = ({ _rows = 30, _columns = 20, _data = [] }) => {
const [rows] = useState(_rows);
const [columns] = useState(_columns);
const [data, setData] = useState(_data);
const inputRefs = useRef({});
const columnLabels = useMemo(() => generateColumnLabels(columns), [columns]);
const handleInputChange = useCallback((rowIndex, colIndex, value) => {
setData((prevData) => {
const newData = [...prevData];
if (!newData[rowIndex]) {
newData[rowIndex] = [];
}
newData[rowIndex][colIndex] = value;
return newData;
});
}, []);
return (
<div className="table-wrapper">
<Grid
columnCount={columns}
columnWidth={150}
height={600}
rowCount={rows}
rowHeight={40}
width={1000}
>
{({ columnIndex, rowIndex, style }) => (
<Cell
columnIndex={columnIndex}
rowIndex={rowIndex}
style={style}
data={data}
handleInputChange={handleInputChange}
inputRefs={inputRefs}
/>
)}
</Grid>
</div>
);
};
export default ExcelTable;
<!-- language: lang-jsx -->
</code>
<!-- language: lang-jsx -->
import React, { useState, useCallback, useRef, useEffect, useMemo } from 'react';
import { FixedSizeGrid as Grid } from 'react-window';
// Function to generate column labels
const generateColumnLabels = (numColumns) => {
const labels = [];
let i = 0;
while (labels.length < numColumns) {
let label = '';
let temp = i;
while (temp >= 0) {
label = String.fromCharCode((temp % 26) + 65) + label;
temp = Math.floor(temp / 26) - 1;
}
labels.push(label);
i++;
}
return labels;
};
const Cell = React.memo(({ columnIndex, rowIndex, style, data, handleInputChange, inputRefs }) => {
const inputRef = useRef(null);
useEffect(() => {
inputRefs.current[`${rowIndex}-${columnIndex}`] = inputRef.current;
}, [rowIndex, columnIndex, inputRefs]);
return (
<div style={{ ...style, width: 150 }}>
<input
ref={inputRef}
type="text"
style={{ width: '100%' }}
value={
data[rowIndex] && data[rowIndex][columnIndex] !== undefined
? data[rowIndex][columnIndex]
: ''
}
onChange={(e) => handleInputChange(rowIndex, columnIndex, e.target.value)}
data-row={rowIndex}
data-col={columnIndex}
/>
</div>
);
});
const ExcelTable = ({ _rows = 30, _columns = 20, _data = [] }) => {
const [rows] = useState(_rows);
const [columns] = useState(_columns);
const [data, setData] = useState(_data);
const inputRefs = useRef({});
const columnLabels = useMemo(() => generateColumnLabels(columns), [columns]);
const handleInputChange = useCallback((rowIndex, colIndex, value) => {
setData((prevData) => {
const newData = [...prevData];
if (!newData[rowIndex]) {
newData[rowIndex] = [];
}
newData[rowIndex][colIndex] = value;
return newData;
});
}, []);
return (
<div className="table-wrapper">
<Grid
columnCount={columns}
columnWidth={150}
height={600}
rowCount={rows}
rowHeight={40}
width={1000}
>
{({ columnIndex, rowIndex, style }) => (
<Cell
columnIndex={columnIndex}
rowIndex={rowIndex}
style={style}
data={data}
handleInputChange={handleInputChange}
inputRefs={inputRefs}
/>
)}
</Grid>
</div>
);
};
export default ExcelTable;
<!-- language: lang-jsx -->