fix: cmd/ctrl native browser behavior blocked in inputs (#4589)
* fix: cmd/ctrl native browser behavior blocked in inputs * add basic test for fontSize increase/decrease via keyboard * add tests for fontSize resizing via keyboard outside wysiwyg * Update src/element/textWysiwyg.test.tsx Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com> * Update src/tests/resize.test.tsx Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com> * Update src/tests/resize.test.tsx Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com> Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
This commit is contained in:
parent
dba71e358d
commit
1fd2fe56ee
@ -25,7 +25,7 @@ export const actionCut = register({
|
||||
name: "cut",
|
||||
perform: (elements, appState, data, app) => {
|
||||
actionCopy.perform(elements, appState, data, app);
|
||||
return actionDeleteSelected.perform(elements, appState, data, app);
|
||||
return actionDeleteSelected.perform(elements, appState);
|
||||
},
|
||||
contextItemLabel: "labels.cut",
|
||||
keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.code === CODES.X,
|
||||
|
@ -2,7 +2,9 @@ import { Action } from "./types";
|
||||
|
||||
export let actions: readonly Action[] = [];
|
||||
|
||||
export const register = (action: Action): Action => {
|
||||
export const register = <T extends Action>(action: T) => {
|
||||
actions = actions.concat(action);
|
||||
return action;
|
||||
return action as T & {
|
||||
keyTest?: unknown extends T["keyTest"] ? never : T["keyTest"];
|
||||
};
|
||||
};
|
||||
|
@ -1649,10 +1649,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
|
||||
if (
|
||||
(isWritableElement(event.target) &&
|
||||
event.key !== KEYS.ESCAPE &&
|
||||
// handle cmd/ctrl-modifier shortcuts even inside inputs
|
||||
!event[KEYS.CTRL_OR_CMD]) ||
|
||||
(isWritableElement(event.target) && event.key !== KEYS.ESCAPE) ||
|
||||
// case: using arrows to move between buttons
|
||||
(isArrowKey(event.key) && isInputLike(event.target))
|
||||
) {
|
||||
@ -1993,6 +1990,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}),
|
||||
element,
|
||||
excalidrawContainer: this.excalidrawContainerRef.current,
|
||||
app: this,
|
||||
});
|
||||
// deselect all other elements when inserting text
|
||||
this.deselectElements();
|
||||
|
@ -5,7 +5,10 @@ import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
|
||||
import { KEYS } from "../keys";
|
||||
import { fireEvent } from "../tests/test-utils";
|
||||
import { BOUND_TEXT_PADDING, FONT_FAMILY } from "../constants";
|
||||
import { ExcalidrawTextElementWithContainer } from "./types";
|
||||
import {
|
||||
ExcalidrawTextElement,
|
||||
ExcalidrawTextElementWithContainer,
|
||||
} from "./types";
|
||||
import * as textElementUtils from "./textElement";
|
||||
// Unmount ReactDOM from root
|
||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
||||
@ -16,12 +19,13 @@ const mouse = new Pointer("mouse");
|
||||
describe("textWysiwyg", () => {
|
||||
describe("Test unbounded text", () => {
|
||||
let textarea: HTMLTextAreaElement;
|
||||
let textElement: ExcalidrawTextElement;
|
||||
beforeEach(async () => {
|
||||
await render(<ExcalidrawApp />);
|
||||
|
||||
const element = UI.createElement("text");
|
||||
textElement = UI.createElement("text");
|
||||
|
||||
mouse.clickOn(element);
|
||||
mouse.clickOn(textElement);
|
||||
textarea = document.querySelector(
|
||||
".excalidraw-textEditorContainer > textarea",
|
||||
)!;
|
||||
@ -171,7 +175,30 @@ describe("textWysiwyg", () => {
|
||||
|
||||
expect(textarea.value).toEqual(`Line#1\nLine#2`);
|
||||
});
|
||||
|
||||
it("should resize text via shortcuts while in wysiwyg", () => {
|
||||
textarea.value = "abc def";
|
||||
const origFontSize = textElement.fontSize;
|
||||
textarea.dispatchEvent(
|
||||
new KeyboardEvent("keydown", {
|
||||
key: KEYS.CHEVRON_RIGHT,
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
}),
|
||||
);
|
||||
expect(textElement.fontSize).toBe(origFontSize * 1.1);
|
||||
|
||||
textarea.dispatchEvent(
|
||||
new KeyboardEvent("keydown", {
|
||||
key: KEYS.CHEVRON_LEFT,
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
}),
|
||||
);
|
||||
expect(textElement.fontSize).toBe(origFontSize);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Test bounded text", () => {
|
||||
let rectangle: any;
|
||||
const {
|
||||
|
@ -17,6 +17,11 @@ import {
|
||||
getContainerElement,
|
||||
wrapText,
|
||||
} from "./textElement";
|
||||
import {
|
||||
actionDecreaseFontSize,
|
||||
actionIncreaseFontSize,
|
||||
} from "../actions/actionProperties";
|
||||
import App from "../components/App";
|
||||
|
||||
const normalizeText = (text: string) => {
|
||||
return (
|
||||
@ -60,6 +65,7 @@ export const textWysiwyg = ({
|
||||
element,
|
||||
canvas,
|
||||
excalidrawContainer,
|
||||
app,
|
||||
}: {
|
||||
id: ExcalidrawElement["id"];
|
||||
appState: AppState;
|
||||
@ -73,6 +79,7 @@ export const textWysiwyg = ({
|
||||
element: ExcalidrawTextElement;
|
||||
canvas: HTMLCanvasElement | null;
|
||||
excalidrawContainer: HTMLDivElement | null;
|
||||
app: App;
|
||||
}) => {
|
||||
const textPropertiesUpdated = (
|
||||
updatedElement: ExcalidrawTextElement,
|
||||
@ -293,16 +300,18 @@ export const textWysiwyg = ({
|
||||
}
|
||||
|
||||
editable.onkeydown = (event) => {
|
||||
if (!event[KEYS.CTRL_OR_CMD]) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
if (event.key === KEYS.ESCAPE) {
|
||||
event.stopPropagation();
|
||||
|
||||
if (actionDecreaseFontSize.keyTest(event)) {
|
||||
app.actionManager.executeAction(actionDecreaseFontSize);
|
||||
} else if (actionIncreaseFontSize.keyTest(event)) {
|
||||
app.actionManager.executeAction(actionIncreaseFontSize);
|
||||
} else if (event.key === KEYS.ESCAPE) {
|
||||
event.preventDefault();
|
||||
submittedViaKeyboard = true;
|
||||
handleSubmit();
|
||||
} else if (event.key === KEYS.ENTER && event[KEYS.CTRL_OR_CMD]) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (event.isComposing || event.keyCode === 229) {
|
||||
return;
|
||||
}
|
||||
@ -315,7 +324,6 @@ export const textWysiwyg = ({
|
||||
event.code === CODES.BRACKET_RIGHT))
|
||||
) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (event.shiftKey || event.code === CODES.BRACKET_LEFT) {
|
||||
outdent();
|
||||
} else {
|
||||
|
@ -8,7 +8,10 @@ import {
|
||||
getTransformHandles,
|
||||
TransformHandleDirection,
|
||||
} from "../element/transformHandles";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types";
|
||||
import ExcalidrawApp from "../excalidraw-app";
|
||||
import { API } from "./helpers/api";
|
||||
import { KEYS } from "../keys";
|
||||
|
||||
const mouse = new Pointer("mouse");
|
||||
|
||||
@ -143,3 +146,31 @@ const resize = (
|
||||
mouse.up();
|
||||
});
|
||||
};
|
||||
|
||||
describe("Test text element", () => {
|
||||
it("should update font size via keyboard", async () => {
|
||||
await render(<ExcalidrawApp />);
|
||||
|
||||
const textElement = API.createElement({
|
||||
type: "text",
|
||||
text: "abc",
|
||||
});
|
||||
|
||||
window.h.elements = [textElement];
|
||||
|
||||
API.setSelectedElements([textElement]);
|
||||
|
||||
const origFontSize = textElement.fontSize;
|
||||
|
||||
Keyboard.withModifierKeys({ shift: true, ctrl: true }, () => {
|
||||
Keyboard.keyDown(KEYS.CHEVRON_RIGHT);
|
||||
expect((window.h.elements[0] as ExcalidrawTextElement).fontSize).toBe(
|
||||
origFontSize * 1.1,
|
||||
);
|
||||
Keyboard.keyDown(KEYS.CHEVRON_LEFT);
|
||||
expect((window.h.elements[0] as ExcalidrawTextElement).fontSize).toBe(
|
||||
origFontSize,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user