+ {/* -- Header / Toolbar -------------------------------------------- */}
+
+
+
+ {filename}
+
+
+ {ext}
+
+ {dirty && (
+
+ Unsaved
+
+ )}
+ {saveFlash && (
+
+ Saved
+
+ )}
+
+
+
+ {/* Toolbar buttons */}
+ {!compact && (
+
+
+
+
+
+
+
+
+
+
+
+
+
activeCell && insertRow(activeCell.row)}
+ title="Insert row above"
+ disabled={!activeCell}
+ >
+
+
+
activeCell && insertCol(activeCell.column)}
+ title="Insert column left"
+ disabled={!activeCell}
+ >
+
+
+
+
setShowSearch((p) => !p)} title="Find (⌘F)">
+
+
+
+ )}
+
+ {/* Compact save button */}
+ {compact && dirty && (
+
+
+
+ )}
+
+
+ {/* -- Formula bar ------------------------------------------------- */}
+ {!compact && (
+
+
+ {activeCell ? cellRef(activeCell) : "\u00A0"}
+
+
+
+ fx
+
+
handleFormulaChange(e.target.value)}
+ placeholder="Select a cell"
+ style={{
+ flex: 1,
+ background: "transparent",
+ border: "none",
+ outline: "none",
+ fontSize: "12px",
+ color: "var(--color-text)",
+ fontFamily: "monospace",
+ }}
+ />
+
+ )}
+
+ {/* -- Search bar -------------------------------------------------- */}
+ {showSearch && (
+
setShowSearch(false)}
+ />
+ )}
+
+ {/* -- Spreadsheet grid -------------------------------------------- */}
+
+ }
+ data={currentData}
+ onChange={handleChange}
+ columnLabels={columnLabels}
+ onActivate={setActiveCell}
+ onSelect={setSelection}
+ darkMode={typeof document !== "undefined" && document.documentElement.classList.contains("dark")}
+ className="spreadsheet-editor-grid"
+ />
+
+
+ {/* -- Context menu ------------------------------------------------ */}
+ setContextMenu(null)}
+ onInsertRowAbove={() => contextMenu && insertRow(contextMenu.row)}
+ onInsertRowBelow={() => contextMenu && insertRow(contextMenu.row + 1)}
+ onInsertColLeft={() => contextMenu && insertCol(contextMenu.col)}
+ onInsertColRight={() => contextMenu && insertCol(contextMenu.col + 1)}
+ onDeleteRow={() => contextMenu && deleteRow(contextMenu.row)}
+ onDeleteCol={() => contextMenu && deleteCol(contextMenu.col)}
+ onClearCells={clearSelection}
+ />
+
+ {/* -- Sheet tabs -------------------------------------------------- */}
+ {sheets.length > 1 && (
+
+ {sheets.map((s, idx) => (
+
+ ))}
+
+ )}
+
+ {/* -- Status bar -------------------------------------------------- */}
+
+
+ {currentData.length} row{currentData.length !== 1 ? "s" : ""}
+ {" \u00d7 "}
+ {colCount} col{colCount !== 1 ? "s" : ""}
+ {sheets.length > 1
+ ? ` \u00b7 ${sheets.length} sheets`
+ : ""}
+
+ {stats && (
+
+ Count: {stats.count}
+ {stats.numericCount > 0 && (
+ <>
+ {" \u00b7 "}Sum: {stats.sum.toLocaleString()}
+ {" \u00b7 "}Avg: {stats.avg.toLocaleString(undefined, { maximumFractionDigits: 2 })}
+ >
+ )}
+
+ )}
+
+
+ );
+}
+
+// ---------------------------------------------------------------------------
+// Icon
+// ---------------------------------------------------------------------------
+
+function SpreadsheetIcon({ size = 16 }: { size?: number }) {
+ return (
+