FIX: Do not loose focus when clicking on the formula we are editing
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 (
|
||||
<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();
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
Reference in New Issue
Block a user