Build a spreadsheet app as one self-contained index.html (no external assets, no network). UI: a visible grid with columns A-Z and rows 1-1000, a formula bar, click a cell to edit, Enter commits, arrow keys move. It should look like a tool someone would actually use. Also expose this exact API on window.Sheet. It must stay in sync with the UI: - set(ref, text): enter text into a cell, as if typed. Empty string clears it. - get(ref): the computed value. A number for numeric results (JS number), a string for text and for errors, "" for empty cells. - getRaw(ref): exactly what was entered. - undo(), redo(): cover set, insertRow, deleteRow and fromCSV. A new edit clears the redo history. - insertRow(n), deleteRow(n): 1-based. Rows shift, and formulas are rewritten as Excel does. Both relative and $absolute references move with their cells. A reference to a deleted single cell becomes #REF! in the formula text (for example "=#REF!"). A range that loses a row shrinks. - toCSV(): RFC 4180 raw text (formulas as typed), rectangular up to the last non-empty row and column, rows joined by \n, no trailing newline. - fromCSV(text): replaces the whole sheet, starting at A1. Handles quoted commas, doubled quotes and newlines inside quotes. Formulas start with "=". Case-insensitive, whitespace ignored. - Operators: + - * / ^ & (text concat), postfix %, parentheses. ^ is right-associative. Unary minus binds tighter than ^, as in Excel, so =-2^2 is 4. - References: A1, $A$1, $A1, A$1. Ranges: A1:B3. - Functions: SUM, AVERAGE, MIN, MAX, COUNT, IF(cond, a, b). Conditions use = <> < > <= >=. - Text in double quotes. - Empty cells are 0 in arithmetic and "" in concat. Range functions skip text and empty cells. Numbers concat in plain form (5 & "x" is "5x"). - Errors, exact strings: #DIV/0!, #REF!, #CYCLE!, #NAME? (unknown function), #VALUE! (text in arithmetic). Errors propagate, including through range functions. Every cell in a cycle, and every cell depending on one, shows #CYCLE!. Fixing the cycle recovers them. - Cells recalculate automatically. With 10,000 filled cells and a SUM over them, editing one input must finish recalculating within 1 second. A dependency chain 1000 cells deep must work. A numeric cell typed as 42 or 3.5 is a number. Anything else not starting with "=" is text.
Discussion