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",
|
name: "cut",
|
||||||
perform: (elements, appState, data, app) => {
|
perform: (elements, appState, data, app) => {
|
||||||
actionCopy.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",
|
contextItemLabel: "labels.cut",
|
||||||
keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.code === CODES.X,
|
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 let actions: readonly Action[] = [];
|
||||||
|
|
||||||
export const register = (action: Action): Action => {
|
export const register = <T extends Action>(action: T) => {
|
||||||
actions = actions.concat(action);
|
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 (
|
if (
|
||||||
(isWritableElement(event.target) &&
|
(isWritableElement(event.target) && event.key !== KEYS.ESCAPE) ||
|
||||||
event.key !== KEYS.ESCAPE &&
|
|
||||||
// handle cmd/ctrl-modifier shortcuts even inside inputs
|
|
||||||
!event[KEYS.CTRL_OR_CMD]) ||
|
|
||||||
// case: using arrows to move between buttons
|
// case: using arrows to move between buttons
|
||||||
(isArrowKey(event.key) && isInputLike(event.target))
|
(isArrowKey(event.key) && isInputLike(event.target))
|
||||||
) {
|
) {
|
||||||
@ -1993,6 +1990,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}),
|
}),
|
||||||
element,
|
element,
|
||||||
excalidrawContainer: this.excalidrawContainerRef.current,
|
excalidrawContainer: this.excalidrawContainerRef.current,
|
||||||
|
app: this,
|
||||||
});
|
});
|
||||||
// deselect all other elements when inserting text
|
// deselect all other elements when inserting text
|
||||||
this.deselectElements();
|
this.deselectElements();
|
||||||
|
@ -5,7 +5,10 @@ import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
|
|||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
import { fireEvent } from "../tests/test-utils";
|
import { fireEvent } from "../tests/test-utils";
|
||||||
import { BOUND_TEXT_PADDING, FONT_FAMILY } from "../constants";
|
import { BOUND_TEXT_PADDING, FONT_FAMILY } from "../constants";
|
||||||
import { ExcalidrawTextElementWithContainer } from "./types";
|
import {
|
||||||
|
ExcalidrawTextElement,
|
||||||
|
ExcalidrawTextElementWithContainer,
|
||||||
|
} from "./types";
|
||||||
import * as textElementUtils from "./textElement";
|
import * as textElementUtils from "./textElement";
|
||||||
// Unmount ReactDOM from root
|
// Unmount ReactDOM from root
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
||||||
@ -16,12 +19,13 @@ const mouse = new Pointer("mouse");
|
|||||||
describe("textWysiwyg", () => {
|
describe("textWysiwyg", () => {
|
||||||
describe("Test unbounded text", () => {
|
describe("Test unbounded text", () => {
|
||||||
let textarea: HTMLTextAreaElement;
|
let textarea: HTMLTextAreaElement;
|
||||||
|
let textElement: ExcalidrawTextElement;
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await render(<ExcalidrawApp />);
|
await render(<ExcalidrawApp />);
|
||||||
|
|
||||||
const element = UI.createElement("text");
|
textElement = UI.createElement("text");
|
||||||
|
|
||||||
mouse.clickOn(element);
|
mouse.clickOn(textElement);
|
||||||
textarea = document.querySelector(
|
textarea = document.querySelector(
|
||||||
".excalidraw-textEditorContainer > textarea",
|
".excalidraw-textEditorContainer > textarea",
|
||||||
)!;
|
)!;
|
||||||
@ -171,7 +175,30 @@ describe("textWysiwyg", () => {
|
|||||||
|
|
||||||
expect(textarea.value).toEqual(`Line#1\nLine#2`);
|
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", () => {
|
describe("Test bounded text", () => {
|
||||||
let rectangle: any;
|
let rectangle: any;
|
||||||
const {
|
const {
|
||||||
|
@ -17,6 +17,11 @@ import {
|
|||||||
getContainerElement,
|
getContainerElement,
|
||||||
wrapText,
|
wrapText,
|
||||||
} from "./textElement";
|
} from "./textElement";
|
||||||
|
import {
|
||||||
|
actionDecreaseFontSize,
|
||||||
|
actionIncreaseFontSize,
|
||||||
|
} from "../actions/actionProperties";
|
||||||
|
import App from "../components/App";
|
||||||
|
|
||||||
const normalizeText = (text: string) => {
|
const normalizeText = (text: string) => {
|
||||||
return (
|
return (
|
||||||
@ -60,6 +65,7 @@ export const textWysiwyg = ({
|
|||||||
element,
|
element,
|
||||||
canvas,
|
canvas,
|
||||||
excalidrawContainer,
|
excalidrawContainer,
|
||||||
|
app,
|
||||||
}: {
|
}: {
|
||||||
id: ExcalidrawElement["id"];
|
id: ExcalidrawElement["id"];
|
||||||
appState: AppState;
|
appState: AppState;
|
||||||
@ -73,6 +79,7 @@ export const textWysiwyg = ({
|
|||||||
element: ExcalidrawTextElement;
|
element: ExcalidrawTextElement;
|
||||||
canvas: HTMLCanvasElement | null;
|
canvas: HTMLCanvasElement | null;
|
||||||
excalidrawContainer: HTMLDivElement | null;
|
excalidrawContainer: HTMLDivElement | null;
|
||||||
|
app: App;
|
||||||
}) => {
|
}) => {
|
||||||
const textPropertiesUpdated = (
|
const textPropertiesUpdated = (
|
||||||
updatedElement: ExcalidrawTextElement,
|
updatedElement: ExcalidrawTextElement,
|
||||||
@ -293,16 +300,18 @@ export const textWysiwyg = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
editable.onkeydown = (event) => {
|
editable.onkeydown = (event) => {
|
||||||
if (!event[KEYS.CTRL_OR_CMD]) {
|
event.stopPropagation();
|
||||||
event.stopPropagation();
|
|
||||||
}
|
if (actionDecreaseFontSize.keyTest(event)) {
|
||||||
if (event.key === KEYS.ESCAPE) {
|
app.actionManager.executeAction(actionDecreaseFontSize);
|
||||||
|
} else if (actionIncreaseFontSize.keyTest(event)) {
|
||||||
|
app.actionManager.executeAction(actionIncreaseFontSize);
|
||||||
|
} else if (event.key === KEYS.ESCAPE) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
submittedViaKeyboard = true;
|
submittedViaKeyboard = true;
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
} else if (event.key === KEYS.ENTER && event[KEYS.CTRL_OR_CMD]) {
|
} else if (event.key === KEYS.ENTER && event[KEYS.CTRL_OR_CMD]) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
|
||||||
if (event.isComposing || event.keyCode === 229) {
|
if (event.isComposing || event.keyCode === 229) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -315,7 +324,6 @@ export const textWysiwyg = ({
|
|||||||
event.code === CODES.BRACKET_RIGHT))
|
event.code === CODES.BRACKET_RIGHT))
|
||||||
) {
|
) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
|
||||||
if (event.shiftKey || event.code === CODES.BRACKET_LEFT) {
|
if (event.shiftKey || event.code === CODES.BRACKET_LEFT) {
|
||||||
outdent();
|
outdent();
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,7 +8,10 @@ import {
|
|||||||
getTransformHandles,
|
getTransformHandles,
|
||||||
TransformHandleDirection,
|
TransformHandleDirection,
|
||||||
} from "../element/transformHandles";
|
} 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");
|
const mouse = new Pointer("mouse");
|
||||||
|
|
||||||
@ -143,3 +146,31 @@ const resize = (
|
|||||||
mouse.up();
|
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