fix cases around blurring

This commit is contained in:
dwelle 2021-04-10 12:23:31 +02:00
parent 652d35b7ce
commit 959734a348
7 changed files with 34 additions and 6 deletions

View file

@ -18,7 +18,7 @@ import { isBindingElement } from "../element/typeChecks";
export const actionFinalize = register({
name: "finalize",
perform: (elements, appState, _, { canvas }) => {
perform: (elements, appState, _, { canvas, focusContainer }) => {
if (appState.editingLinearElement) {
const {
elementId,
@ -51,7 +51,7 @@ export const actionFinalize = register({
let newElements = elements;
if (window.document.activeElement instanceof HTMLElement) {
window.document.activeElement.blur();
focusContainer();
}
const multiPointElement = appState.multiElement

View file

@ -12,7 +12,11 @@ import { MODES } from "../constants";
// This is the <App> component, but for now we don't care about anything but its
// `canvas` state.
type App = { canvas: HTMLCanvasElement | null; props: AppProps };
type App = {
canvas: HTMLCanvasElement | null;
focusContainer: () => void;
props: AppProps;
};
export class ActionManager implements ActionsManagerInterface {
actions = {} as ActionsManagerInterface["actions"];

View file

@ -15,11 +15,13 @@ export type ActionResult =
}
| false;
type AppAPI = { canvas: HTMLCanvasElement | null; focusContainer(): void };
type ActionFn = (
elements: readonly ExcalidrawElement[],
appState: Readonly<AppState>,
formData: any,
app: { canvas: HTMLCanvasElement | null },
app: AppAPI,
) => ActionResult | Promise<ActionResult>;
export type UpdaterFn = (res: ActionResult) => void;

View file

@ -510,6 +510,10 @@ class App extends React.Component<AppProps, AppState> {
);
}
public focusContainer = () => {
this.excalidrawContainerRef.current?.focus();
};
public getSceneElementsIncludingDeleted = () => {
return this.scene.getElementsIncludingDeleted();
};
@ -789,6 +793,10 @@ class App extends React.Component<AppProps, AppState> {
this.scene.addCallback(this.onSceneUpdated);
this.addEventListeners();
if (this.excalidrawContainerRef.current) {
this.focusContainer();
}
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
this.resizeObserver = new ResizeObserver(() => {
// compute isMobile state
@ -1617,7 +1625,7 @@ class App extends React.Component<AppProps, AppState> {
setCursorForShape(this.canvas, elementType);
}
if (isToolIcon(document.activeElement)) {
document.activeElement.blur();
this.focusContainer();
}
if (!isLinearElementType(elementType)) {
this.setState({ suggestedBindings: [] });
@ -1747,6 +1755,8 @@ class App extends React.Component<AppProps, AppState> {
if (this.state.elementLocked) {
setCursorForShape(this.canvas, this.state.elementType);
}
this.focusContainer();
}),
element,
});

View file

@ -38,6 +38,7 @@ export const Modal = (props: {
<div
className="Modal__content"
style={{ "--max-width": `${props.maxWidth}px` }}
tabIndex={0}
>
{props.children}
</div>

View file

@ -17,6 +17,14 @@ export class ProjectName extends Component<Props, State> {
fileName: this.props.value,
};
private handleBlur = (event: any) => {
let parent = (event.target as HTMLInputElement).parentElement;
while (parent) {
if (parent.tabIndex > -1) {
parent.focus();
break;
}
parent = parent.parentElement;
}
const value = event.target.value;
if (value !== this.props.value) {
this.props.onChange(value);

View file

@ -159,11 +159,14 @@ export const textWysiwyg = ({
// so that we don't need to create separate a callback for event handlers
let submittedViaKeyboard = false;
const handleSubmit = () => {
// cleanup must be run before onSubmit otherwise when app blurs the wysiwyg
// it'd get stuck in an infinite loop of blur→onSubmit after we re-focus the
// wysiwyg on update
cleanup();
onSubmit({
text: normalizeText(editable.value),
viaKeyboard: submittedViaKeyboard,
});
cleanup();
};
const cleanup = () => {