Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: inline editor arrow key interactions (edit & enter states) #1972

Merged
merged 25 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b69be09
fix: inline editor arrow key interactions (edit & enter states)
AyushAgrawal-A2 Oct 15, 2024
526c629
Merge branch 'qa' of github.com:quadratichq/quadratic into ayush/1961
AyushAgrawal-A2 Oct 15, 2024
1676921
Merge branch 'qa' of github.com:quadratichq/quadratic into ayush/1961
AyushAgrawal-A2 Oct 15, 2024
63d315f
fix bugs
AyushAgrawal-A2 Oct 17, 2024
e0f6f13
Merge branch 'qa' of github.com:quadratichq/quadratic into ayush/1961
AyushAgrawal-A2 Oct 17, 2024
9fafe8e
bug
AyushAgrawal-A2 Oct 17, 2024
7be1442
inline cursor mode ui
AyushAgrawal-A2 Oct 18, 2024
b079e74
tweak appearance
jimniels Oct 18, 2024
f501620
Update BottomBar.tsx
jimniels Oct 18, 2024
f941ab0
fix cursor flash at (0,0)
AyushAgrawal-A2 Oct 18, 2024
f05e22b
Merge branch 'ayush/1961' of github.com:quadratichq/quadratic into ay…
AyushAgrawal-A2 Oct 18, 2024
d7d7ae5
fix insert cell highlight showing corners
AyushAgrawal-A2 Oct 18, 2024
e7b312b
DK feedback
AyushAgrawal-A2 Oct 19, 2024
823f6eb
Merge branch 'qa' of github.com:quadratichq/quadratic into ayush/1961
AyushAgrawal-A2 Oct 19, 2024
2d192d2
fix bug
AyushAgrawal-A2 Oct 19, 2024
51dc576
Merge branch 'qa' into ayush/1961
AyushAgrawal-A2 Oct 22, 2024
25e280b
Merge branch 'qa' into ayush/1961
AyushAgrawal-A2 Nov 6, 2024
353444b
Merge branch 'qa' into ayush/1961
AyushAgrawal-A2 Nov 6, 2024
19a19c1
Merge branch 'qa' of github.com:quadratichq/quadratic into ayush/1961
AyushAgrawal-A2 Nov 19, 2024
94941bb
Merge branch 'ayush/1961' of github.com:quadratichq/quadratic into ay…
AyushAgrawal-A2 Nov 19, 2024
1973e31
Merge branch 'qa' of github.com:quadratichq/quadratic into ayush/1961
AyushAgrawal-A2 Nov 20, 2024
44dfb23
reverse mode display and icon size / pos
AyushAgrawal-A2 Nov 20, 2024
5933819
fix height
AyushAgrawal-A2 Nov 20, 2024
5809b4a
revert height
AyushAgrawal-A2 Nov 20, 2024
5378d8b
add : adn ! to wantsCellRef
AyushAgrawal-A2 Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions quadratic-client/src/app/actions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export enum Action {
MoveCursorRightWithSelection = 'move_cursor_right_with_selection',
MoveCursorLeftWithSelection = 'move_cursor_left_with_selection',
EditCell = 'edit_cell',
ToggleArrowMode = 'toggle_arrow_mode',
DeleteCell = 'delete_cell',
ShowCellTypeMenu = 'show_cell_type_menu',
CloseInlineEditor = 'close_inline_editor',
Expand Down
50 changes: 42 additions & 8 deletions quadratic-client/src/app/actions/editActionsSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '@/app/grid/actions/clipboard/clipboard';
import { sheets } from '@/app/grid/controller/Sheets';
import { inlineEditorHandler } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorHandler';
import { CursorMode } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorKeyboard';
import { doubleClickCell } from '@/app/gridGL/interaction/pointer/doubleClickCell';
import { pixiAppSettings } from '@/app/gridGL/pixiApp/PixiAppSettings';
import { downloadFile } from '@/app/helpers/downloadFileInBrowser';
Expand Down Expand Up @@ -42,6 +43,7 @@ type EditActionSpec = Pick<
| Action.FillRight
| Action.FillDown
| Action.EditCell
| Action.ToggleArrowMode
| Action.DeleteCell
| Action.CloseInlineEditor
| Action.SaveInlineEditor
Expand Down Expand Up @@ -162,19 +164,51 @@ export const editActionsSpec: EditActionSpec = {
label: 'Edit cell',
run: () => {
if (!inlineEditorHandler.isEditingFormula()) {
const cursor = sheets.sheet.cursor;
const cursorPosition = cursor.cursorPosition;
const column = cursorPosition.x;
const row = cursorPosition.y;
quadraticCore.getCodeCell(sheets.sheet.id, column, row).then((code) => {
const { x, y } = sheets.sheet.cursor.cursorPosition;
quadraticCore.getCodeCell(sheets.sheet.id, x, y).then((code) => {
if (code) {
doubleClickCell({ column: Number(code.x), row: Number(code.y), language: code.language, cell: '' });
doubleClickCell({
column: Number(code.x),
row: Number(code.y),
language: code.language,
cell: '',
});
} else {
quadraticCore.getEditCell(sheets.sheet.id, x, y).then((cell) => {
doubleClickCell({
column: x,
row: y,
cell,
cursorMode: cell ? CursorMode.Edit : CursorMode.Enter,
});
});
}
});
return true;
}
},
},
[Action.ToggleArrowMode]: {
label: 'Toggle arrow mode',
run: () => {
if (!inlineEditorHandler.isEditingFormula()) {
const { x, y } = sheets.sheet.cursor.cursorPosition;
quadraticCore.getCodeCell(sheets.sheet.id, x, y).then((code) => {
if (code) {
doubleClickCell({
column: Number(code.x),
row: Number(code.y),
language: code.language,
cell: '',
cursorMode: CursorMode.Edit,
});
} else {
quadraticCore.getEditCell(sheets.sheet.id, column, row).then((cell) => {
doubleClickCell({ column, row, cell });
quadraticCore.getEditCell(sheets.sheet.id, x, y).then((cell) => {
doubleClickCell({ column: x, row: y, cell, cursorMode: CursorMode.Edit });
});
}
});
return true;
}
},
},
Expand Down
11 changes: 9 additions & 2 deletions quadratic-client/src/app/atoms/inlineEditorAtom.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import { CursorMode, inlineEditorKeyboard } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorKeyboard';
import { inlineEditorMonaco } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorMonaco';
import { pixiApp } from '@/app/gridGL/pixiApp/PixiApp';
import { LINE_HEIGHT } from '@/app/web-workers/renderWebWorker/worker/cellsLabel/CellLabel';
import { atom } from 'recoil';

export interface InlineEditorState {
visible: boolean;
formula: boolean;
left: number;
top: number;
lineHeight: number;
height: number;
editMode: boolean;
}

export const defaultInlineEditor: InlineEditorState = {
visible: false,
formula: false,
left: 0,
top: 0,
lineHeight: 19,
height: LINE_HEIGHT,
editMode: false,
};

export const inlineEditorAtom = atom({
Expand All @@ -26,6 +31,8 @@ export const inlineEditorAtom = atom({
if (newValue.visible) {
inlineEditorMonaco.focus();
}
inlineEditorKeyboard.cursorMode = newValue.editMode ? CursorMode.Edit : CursorMode.Enter;
pixiApp.cursor.dirty = true;
});
},
],
Expand Down
3 changes: 2 additions & 1 deletion quadratic-client/src/app/events/events.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ErrorValidation } from '@/app/gridGL/cells/CellsSheet';
import { EditingCell } from '@/app/gridGL/HTMLGrid/hoverCell/HoverCell';
import { CursorMode } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorKeyboard';
import { CodeCell } from '@/app/gridGL/types/codeCell';
import { SheetPosTS } from '@/app/gridGL/types/size';
import {
Expand Down Expand Up @@ -51,7 +52,7 @@ interface EventTypes {
setCursor: (cursor?: string, selection?: Selection) => void;
cursorPosition: () => void;
generateThumbnail: () => void;
changeInput: (input: boolean, initialValue?: string) => void;
changeInput: (input: boolean, initialValue?: string, cursorMode?: CursorMode) => void;
headingSize: (width: number, height: number) => void;
gridSettings: () => void;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
//! in inlineEditorHandler.ts.

import { inlineEditorAtom } from '@/app/atoms/inlineEditorAtom';
import { sheets } from '@/app/grid/controller/Sheets';
import { inlineEditorHandler } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorHandler';
import { CURSOR_THICKNESS } from '@/app/gridGL/UI/Cursor';
import { colors } from '@/app/theme/colors';
import { DockToLeftIcon } from '@/shared/components/Icons';
import { Button } from '@/shared/shadcn/ui/button';
import { SubtitlesOutlined } from '@mui/icons-material';
import { Tooltip } from '@mui/material';
import { TooltipPopover } from '@/shared/shadcn/ui/tooltip';
import { useCallback } from 'react';
import { useRecoilValue } from 'recoil';
import './inlineEditorStyles.scss';
Expand All @@ -21,12 +23,12 @@ export const InlineEditor = () => {
}
}, []);

// Note: I switched to using material's Tooltip because radix-ui's Tooltip did
// not keep position during viewport changes. Even forcing a remount did not
// fix its positioning problem. There's probably a workaround, but it was too
// much work.

const { visible, formula, left, top } = useRecoilValue(inlineEditorAtom);
let { visible, formula, left, top, height } = useRecoilValue(inlineEditorAtom);
height += CURSOR_THICKNESS * 1.5;
const inlineShowing = inlineEditorHandler.getShowing();
if (inlineShowing) {
height = Math.max(height, sheets.sheet.getCellOffsets(inlineShowing.x, inlineShowing.y).height);
}

return (
<div
Expand All @@ -44,26 +46,28 @@ export const InlineEditor = () => {
<div id="cell-edit"></div>

{visible && formula ? (
<Tooltip title="Open Formula in multi-line code editor">
<TooltipPopover label="Open Formula in multi-line code editor">
<Button
variant="ghost"
style={{
boxSizing: 'content-box',
position: 'absolute',
display: 'flex',
alignItems: 'center',
alignItems: 'flex-start',
borderRadius: '0',
padding: '0',
marginTop: '-0.23px',
width: '23px',
height: '23.23px',
height: `${height}px`,
right: '-24px',
backgroundColor: colors.languageFormula,
}}
onClick={(e) => inlineEditorHandler.openCodeEditor(e)}
onClick={(e) => {
e.stopPropagation();
inlineEditorHandler.openCodeEditor();
}}
>
<SubtitlesOutlined sx={{ width: '18px', height: '18px', color: 'white' }} />
<DockToLeftIcon style={{ color: 'white', width: '20px', height: '20px' }} />
</Button>
</Tooltip>
</TooltipPopover>
) : null}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ class InlineEditorFormula {
// or by keyboard input) or whether they want to switch to a different cell.
wantsCellRef() {
const lastCharacter = inlineEditorMonaco.getNonWhitespaceCharBeforeCursor();
return ['', ',', '+', '-', '*', '/', '%', '=', '<', '>', '&', '.', '(', '{'].includes(lastCharacter);
return (
!!lastCharacter && ['', ',', '+', '-', '*', '/', '%', '=', '<', '>', '&', '.', '(', '{'].includes(lastCharacter)
);
}

// Returns whether we are editing a formula only if it is valid (used for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { events } from '@/app/events/events';
import { sheets } from '@/app/grid/controller/Sheets';
import { inlineEditorFormula } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorFormula';
import { inlineEditorKeyboard } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorKeyboard';
import { CursorMode, inlineEditorKeyboard } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorKeyboard';
import { inlineEditorMonaco, PADDING_FOR_INLINE_EDITOR } from '@/app/gridGL/HTMLGrid/inlineEditor/inlineEditorMonaco';
import { pixiApp } from '@/app/gridGL/pixiApp/PixiApp';
import { pixiAppSettings } from '@/app/gridGL/pixiApp/PixiAppSettings';
Expand Down Expand Up @@ -171,7 +171,7 @@ class InlineEditorHandler {
};

// Handler for the changeInput event.
private changeInput = async (input: boolean, initialValue?: string) => {
private changeInput = async (input: boolean, initialValue?: string, cursorMode?: CursorMode) => {
if (!input && !this.open) return;

if (initialValue) {
Expand All @@ -197,16 +197,30 @@ class InlineEditorHandler {
let changeToFormula = false;
if (initialValue) {
value = initialValue;
this.changeToFormula(value[0] === '=');
changeToFormula = value[0] === '=';
} else {
const formula = await quadraticCore.getCodeCell(this.location.sheetId, this.location.x, this.location.y);
if (formula?.language === 'Formula') {
value = '=' + formula.code_string;
changeToFormula = true;
} else {
value = (await quadraticCore.getEditCell(this.location.sheetId, this.location.x, this.location.y)) || '';
changeToFormula = false;
}
}

if (cursorMode === undefined) {
if (changeToFormula) {
cursorMode = value.length > 1 ? CursorMode.Edit : CursorMode.Enter;
} else {
cursorMode = value ? CursorMode.Edit : CursorMode.Enter;
}
}
pixiAppSettings.setInlineEditorState?.((prev) => ({
...prev,
editMode: cursorMode === CursorMode.Edit,
}));

this.formatSummary = await quadraticCore.getCellFormatSummary(
this.location.sheetId,
this.location.x,
Expand Down Expand Up @@ -358,8 +372,8 @@ class InlineEditorHandler {
pixiAppSettings.setInlineEditorState((prev) => ({
...prev,
left: this.x,
top: this.y + OPEN_SANS_FIX.y / 3,
lineHeight: this.height,
top: this.y,
height: this.height,
}));

pixiApp.cursor.dirty = true;
Expand Down Expand Up @@ -502,8 +516,7 @@ class InlineEditorHandler {
};

// Handler for the click for the expand code editor button.
openCodeEditor = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation();
openCodeEditor = () => {
if (!pixiAppSettings.setCodeEditorState) {
throw new Error('Expected setCodeEditorState to be defined in openCodeEditor');
}
Expand Down
Loading
Loading