Table = ({ value: rows, onChange, selected_cell, onSelectedChange }) => {
let values = build_runtime(rows);
let reference_names = null;
let error = null;
if (selected_cell != null) {
try {
let column_index = selected_cell.column.charCodeAt(0) - 65;
let current_cell = rows[selected_cell.row - 1][column_index];
if (current_cell.startsWith('=')) {
let code = current_cell.slice(1);
let cell_ast = parser.parseCell(code);
reference_names = (cell_ast.references || [])
.map(x => x.name)
.filter(x => x.match(/[A-Z]\d?/));
}
} catch (err) {
error = err;
}
}
return htm`
<div class="list-table" style=${{ width: width }}>
<div class="row">
<div style=${{ width: 50 }}></div>
${rows[0].map(
(column, _column_index) => htm`
<div class="table-column-header" style=${{
width: 200
}}>${String.fromCharCode(65 + _column_index)}</div>
`
)}
</div>
${rows.map((row, _row_index) => {
let row_index = _row_index + 1;
return htm`<div class="row">
<div class="table-row-header" style=${{
width: 50
}}>${row_index}</div>
${row.map((value, _column_index) => {
let column_index = String.fromCharCode(65 + _column_index);
let cell_name = `${column_index}${row_index}`;
return htm`
<${Cell}
derived_from=${reference_names != null &&
reference_names.some(x => cell_name.startsWith(x))}
column=${column_index}
row=${row_index}
selected_cell=${selected_cell}
value=${value}
display=${values[`${column_index}${row_index}`]}
onClick=${() => {
onSelectedChange({ column: column_index, row: row_index });
}}
onBlur=${() => {
onSelectedChange(null);
}}
style=${{ width: 200 }}
onChange=${value => {
onChange(
immer.default(rows, draft => {
draft[_row_index][_column_index] = value;
})
);
}}
/>
`;
})}
</div>`;
})}
</div>
`;
}