diff --git a/webapp/src/components/editor/editor.tsx b/webapp/src/components/editor/editor.tsx
index 56f4703..a305347 100644
--- a/webapp/src/components/editor/editor.tsx
+++ b/webapp/src/components/editor/editor.tsx
@@ -193,7 +193,7 @@ const Editor = (options: EditorOptions) => {
const isCellEditing = workbookState.getEditingCell() !== null;
const showEditor =
- isCellEditing && (display || type === "formula-bar") ? "block" : "none";
+ (isCellEditing && display) || type === "formula-bar" ? "block" : "none";
return (
{
resize: "none",
border: "none",
height,
- display: display ? "block" : "none",
overflow: "hidden",
}}
defaultValue={text}
spellCheck="false"
onKeyDown={onKeyDown}
onBlur={onChange}
+ onClick={(event) => {
+ // Prevents this from bubbling up and focusing on the spreadsheet
+ if (isCellEditing && type === "cell") {
+ event.stopPropagation();
+ }
+ }}
/>
);
diff --git a/webapp/src/components/formulabar.tsx b/webapp/src/components/formulabar.tsx
index dfbc4f4..f1bac38 100644
--- a/webapp/src/components/formulabar.tsx
+++ b/webapp/src/components/formulabar.tsx
@@ -1,7 +1,6 @@
import type { Model } from "@ironcalc/wasm";
import { Button, styled } from "@mui/material";
import { ChevronDown } from "lucide-react";
-import { useState } from "react";
import { Fx } from "../icons";
import Editor from "./editor/editor";
import type { WorkbookState } from "./workbookState";
@@ -27,9 +26,6 @@ function FormulaBar(properties: FormulaBarProps) {
onTextUpdated,
workbookState,
} = properties;
-
- const [display, setDisplay] = useState(false);
-
return (
@@ -55,7 +51,6 @@ function FormulaBar(properties: FormulaBarProps) {
focus: "formula-bar",
activeRanges: [],
});
- setDisplay(true);
event.stopPropagation();
event.preventDefault();
}}
@@ -63,13 +58,12 @@ function FormulaBar(properties: FormulaBarProps) {
{
- setDisplay(false);
onChange();
}}
onTextUpdated={onTextUpdated}
diff --git a/webapp/src/components/usePointer.ts b/webapp/src/components/usePointer.ts
index 78a12d3..7328392 100644
--- a/webapp/src/components/usePointer.ts
+++ b/webapp/src/components/usePointer.ts
@@ -1,3 +1,4 @@
+import type { Model } from "@ironcalc/wasm";
import { type PointerEvent, type RefObject, useCallback, useRef } from "react";
import type WorksheetCanvas from "./WorksheetCanvas/worksheetCanvas";
import {
@@ -5,6 +6,7 @@ import {
headerRowHeight,
} from "./WorksheetCanvas/worksheetCanvas";
import type { Cell } from "./types";
+import type { WorkbookState } from "./workbookState";
interface PointerSettings {
canvasElement: RefObject;
@@ -15,6 +17,8 @@ interface PointerSettings {
onAreaSelected: () => void;
onExtendToCell: (cell: Cell) => void;
onExtendToEnd: () => void;
+ model: Model;
+ workbookState: WorkbookState;
}
interface PointerEvents {
@@ -99,7 +103,13 @@ const usePointer = (options: PointerSettings): PointerEvents => {
(event: PointerEvent) => {
let x = event.clientX;
let y = event.clientY;
- const { canvasElement, worksheetElement, worksheetCanvas } = options;
+ const {
+ canvasElement,
+ model,
+ worksheetElement,
+ worksheetCanvas,
+ workbookState,
+ } = options;
const worksheet = worksheetCanvas.current;
const canvas = canvasElement.current;
const worksheetWrapper = worksheetElement.current;
@@ -132,8 +142,28 @@ const usePointer = (options: PointerSettings): PointerEvents => {
}
return;
}
+ // if we are editing a cell finish that
+ const editingCell = workbookState.getEditingCell();
+
const cell = worksheet.getCellByCoordinates(x, y);
if (cell) {
+ if (editingCell) {
+ if (
+ cell.row === editingCell.row &&
+ cell.column === editingCell.column
+ ) {
+ // We are clicking on the cell we are editing
+ // we do nothing
+ return;
+ }
+ workbookState.clearEditingCell();
+ model.setUserInput(
+ editingCell.sheet,
+ editingCell.row,
+ editingCell.column,
+ editingCell.text,
+ );
+ }
options.onCellSelected(cell, event);
isSelecting.current = true;
worksheetWrapper.setPointerCapture(event.pointerId);
diff --git a/webapp/src/components/workbook.tsx b/webapp/src/components/workbook.tsx
index 015b38c..e5ef842 100644
--- a/webapp/src/components/workbook.tsx
+++ b/webapp/src/components/workbook.tsx
@@ -1,6 +1,6 @@
import type { BorderOptions, Model, WorksheetProperties } from "@ironcalc/wasm";
import { styled } from "@mui/material/styles";
-import { useEffect, useRef, useState } from "react";
+import { useCallback, useEffect, useRef, useState } from "react";
import { LAST_COLUMN } from "./WorksheetCanvas/constants";
import FormulaBar from "./formulabar";
import Navigation from "./navigation/navigation";
@@ -262,26 +262,33 @@ const Workbook = (props: { model: Model; workbookState: WorkbookState }) => {
}
});
- const {
- sheet,
- row,
- column,
- range: [rowStart, columnStart, rowEnd, columnEnd],
- } = model.getSelectedView();
+ const cellAddress = useCallback(() => {
+ const {
+ row,
+ column,
+ range: [rowStart, columnStart, rowEnd, columnEnd],
+ } = model.getSelectedView();
+ return getCellAddress(
+ { rowStart, rowEnd, columnStart, columnEnd },
+ { row, column },
+ );
+ }, [model]);
- const cellAddress = getCellAddress(
- { rowStart, rowEnd, columnStart, columnEnd },
- { row, column },
- );
- const formulaValue = (() => {
+ const formulaValue = () => {
const cell = workbookState.getEditingCell();
if (cell) {
return cell.text;
}
+ const { sheet, row, column } = model.getSelectedView();
return model.getCellContent(sheet, row, column);
- })();
+ };
- const style = model.getCellStyle(sheet, row, column);
+ const getCellStyle = useCallback(() => {
+ const { sheet, row, column } = model.getSelectedView();
+ return model.getCellStyle(sheet, row, column);
+ }, [model]);
+
+ const style = getCellStyle();
return (
{
verticalAlign={style.alignment ? style.alignment.vertical : "center"}
canEdit={true}
numFmt={style.num_fmt}
- showGridLines={model.getShowGridLines(sheet)}
+ showGridLines={model.getShowGridLines(model.getSelectedSheet())}
onToggleShowGridLines={(show) => {
+ const sheet = model.getSelectedSheet();
model.setShowGridLines(sheet, show);
setRedrawId((id) => id + 1);
}}
/>
{
setRedrawId((id) => id + 1);
rootRef.current?.focus();
diff --git a/webapp/src/components/worksheet.tsx b/webapp/src/components/worksheet.tsx
index bacade0..0b3663f 100644
--- a/webapp/src/components/worksheet.tsx
+++ b/webapp/src/components/worksheet.tsx
@@ -47,7 +47,6 @@ function Worksheet(props: {
const ignoreScrollEventRef = useRef(false);
- const [display, setDisplay] = useState(false);
const [originalText, setOriginalText] = useState("");
const { model, workbookState, refresh } = props;
@@ -143,6 +142,8 @@ function Worksheet(props: {
onPointerUp,
// onContextMenu,
} = usePointer({
+ model,
+ workbookState,
onCellSelected: (cell: Cell, event: React.MouseEvent) => {
event.preventDefault();
event.stopPropagation();
@@ -315,18 +316,11 @@ function Worksheet(props: {
{
- // if we are editing a cell finish that
- const cell = workbookState.getEditingCell();
- if (cell) {
- workbookState.clearEditingCell();
- model.setUserInput(cell.sheet, cell.row, cell.column, cell.text);
- }
- onPointerDown(event);
- }}
+ onPointerDown={onPointerDown}
onPointerMove={onPointerMove}
onPointerUp={onPointerUp}
onDoubleClick={(event) => {
+ // Starts editing cell
const { sheet, row, column } = model.getSelectedView();
const text = model.getCellContent(sheet, row, column) || "";
workbookState.setEditingCell({
@@ -334,11 +328,10 @@ function Worksheet(props: {
row,
column,
text,
- cursor: 0,
+ cursor: text.length,
focus: "cell",
activeRanges: [],
});
- setDisplay(true);
setOriginalText(text);
event.stopPropagation();
event.preventDefault();
@@ -354,7 +347,6 @@ function Worksheet(props: {
expand={true}
originalText={workbookState.getEditingCell()?.text || originalText}
onEditEnd={(): void => {
- setDisplay(false);
props.refresh();
}}
onTextUpdated={(): void => {