FIX: Do not loose focus when clicking on the formula we are editing

This commit is contained in:
Nicolás Hatcher
2024-09-27 19:25:26 +02:00
parent f53b39b220
commit 90cf5f74f7
5 changed files with 69 additions and 40 deletions

View File

@@ -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 (
<div
@@ -229,13 +229,18 @@ const Editor = (options: EditorOptions) => {
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();
}
}}
/>
</div>
);

View File

@@ -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 (
<Container>
<AddressContainer>
@@ -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) {
<Editor
minimalWidth={"100%"}
minimalHeight={"100%"}
display={display}
display={true}
expand={false}
originalText={formulaValue}
model={model}
workbookState={workbookState}
onEditEnd={() => {
setDisplay(false);
onChange();
}}
onTextUpdated={onTextUpdated}

View File

@@ -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<HTMLCanvasElement>;
@@ -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);

View File

@@ -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 cellAddress = useCallback(() => {
const {
sheet,
row,
column,
range: [rowStart, columnStart, rowEnd, columnEnd],
} = model.getSelectedView();
const cellAddress = getCellAddress(
return getCellAddress(
{ rowStart, rowEnd, columnStart, columnEnd },
{ row, column },
);
const formulaValue = (() => {
}, [model]);
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 (
<Container
@@ -339,15 +346,16 @@ const Workbook = (props: { model: Model; workbookState: WorkbookState }) => {
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);
}}
/>
<FormulaBar
cellAddress={cellAddress}
formulaValue={formulaValue}
cellAddress={cellAddress()}
formulaValue={formulaValue()}
onChange={() => {
setRedrawId((id) => id + 1);
rootRef.current?.focus();

View File

@@ -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: {
<SheetContainer
className="sheet-container"
ref={worksheetElement}
onPointerDown={(event) => {
// 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 => {