mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-04-14 16:40:58 -04:00
fix cases around blurring
This commit is contained in:
parent
652d35b7ce
commit
959734a348
7 changed files with 34 additions and 6 deletions
|
@ -18,7 +18,7 @@ import { isBindingElement } from "../element/typeChecks";
|
||||||
|
|
||||||
export const actionFinalize = register({
|
export const actionFinalize = register({
|
||||||
name: "finalize",
|
name: "finalize",
|
||||||
perform: (elements, appState, _, { canvas }) => {
|
perform: (elements, appState, _, { canvas, focusContainer }) => {
|
||||||
if (appState.editingLinearElement) {
|
if (appState.editingLinearElement) {
|
||||||
const {
|
const {
|
||||||
elementId,
|
elementId,
|
||||||
|
@ -51,7 +51,7 @@ export const actionFinalize = register({
|
||||||
|
|
||||||
let newElements = elements;
|
let newElements = elements;
|
||||||
if (window.document.activeElement instanceof HTMLElement) {
|
if (window.document.activeElement instanceof HTMLElement) {
|
||||||
window.document.activeElement.blur();
|
focusContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
const multiPointElement = appState.multiElement
|
const multiPointElement = appState.multiElement
|
||||||
|
|
|
@ -12,7 +12,11 @@ import { MODES } from "../constants";
|
||||||
|
|
||||||
// This is the <App> component, but for now we don't care about anything but its
|
// This is the <App> component, but for now we don't care about anything but its
|
||||||
// `canvas` state.
|
// `canvas` state.
|
||||||
type App = { canvas: HTMLCanvasElement | null; props: AppProps };
|
type App = {
|
||||||
|
canvas: HTMLCanvasElement | null;
|
||||||
|
focusContainer: () => void;
|
||||||
|
props: AppProps;
|
||||||
|
};
|
||||||
|
|
||||||
export class ActionManager implements ActionsManagerInterface {
|
export class ActionManager implements ActionsManagerInterface {
|
||||||
actions = {} as ActionsManagerInterface["actions"];
|
actions = {} as ActionsManagerInterface["actions"];
|
||||||
|
|
|
@ -15,11 +15,13 @@ export type ActionResult =
|
||||||
}
|
}
|
||||||
| false;
|
| false;
|
||||||
|
|
||||||
|
type AppAPI = { canvas: HTMLCanvasElement | null; focusContainer(): void };
|
||||||
|
|
||||||
type ActionFn = (
|
type ActionFn = (
|
||||||
elements: readonly ExcalidrawElement[],
|
elements: readonly ExcalidrawElement[],
|
||||||
appState: Readonly<AppState>,
|
appState: Readonly<AppState>,
|
||||||
formData: any,
|
formData: any,
|
||||||
app: { canvas: HTMLCanvasElement | null },
|
app: AppAPI,
|
||||||
) => ActionResult | Promise<ActionResult>;
|
) => ActionResult | Promise<ActionResult>;
|
||||||
|
|
||||||
export type UpdaterFn = (res: ActionResult) => void;
|
export type UpdaterFn = (res: ActionResult) => void;
|
||||||
|
|
|
@ -510,6 +510,10 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public focusContainer = () => {
|
||||||
|
this.excalidrawContainerRef.current?.focus();
|
||||||
|
};
|
||||||
|
|
||||||
public getSceneElementsIncludingDeleted = () => {
|
public getSceneElementsIncludingDeleted = () => {
|
||||||
return this.scene.getElementsIncludingDeleted();
|
return this.scene.getElementsIncludingDeleted();
|
||||||
};
|
};
|
||||||
|
@ -789,6 +793,10 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
this.scene.addCallback(this.onSceneUpdated);
|
this.scene.addCallback(this.onSceneUpdated);
|
||||||
this.addEventListeners();
|
this.addEventListeners();
|
||||||
|
|
||||||
|
if (this.excalidrawContainerRef.current) {
|
||||||
|
this.focusContainer();
|
||||||
|
}
|
||||||
|
|
||||||
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
|
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
|
||||||
this.resizeObserver = new ResizeObserver(() => {
|
this.resizeObserver = new ResizeObserver(() => {
|
||||||
// compute isMobile state
|
// compute isMobile state
|
||||||
|
@ -1617,7 +1625,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
setCursorForShape(this.canvas, elementType);
|
setCursorForShape(this.canvas, elementType);
|
||||||
}
|
}
|
||||||
if (isToolIcon(document.activeElement)) {
|
if (isToolIcon(document.activeElement)) {
|
||||||
document.activeElement.blur();
|
this.focusContainer();
|
||||||
}
|
}
|
||||||
if (!isLinearElementType(elementType)) {
|
if (!isLinearElementType(elementType)) {
|
||||||
this.setState({ suggestedBindings: [] });
|
this.setState({ suggestedBindings: [] });
|
||||||
|
@ -1747,6 +1755,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
if (this.state.elementLocked) {
|
if (this.state.elementLocked) {
|
||||||
setCursorForShape(this.canvas, this.state.elementType);
|
setCursorForShape(this.canvas, this.state.elementType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.focusContainer();
|
||||||
}),
|
}),
|
||||||
element,
|
element,
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,6 +38,7 @@ export const Modal = (props: {
|
||||||
<div
|
<div
|
||||||
className="Modal__content"
|
className="Modal__content"
|
||||||
style={{ "--max-width": `${props.maxWidth}px` }}
|
style={{ "--max-width": `${props.maxWidth}px` }}
|
||||||
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,14 @@ export class ProjectName extends Component<Props, State> {
|
||||||
fileName: this.props.value,
|
fileName: this.props.value,
|
||||||
};
|
};
|
||||||
private handleBlur = (event: any) => {
|
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;
|
const value = event.target.value;
|
||||||
if (value !== this.props.value) {
|
if (value !== this.props.value) {
|
||||||
this.props.onChange(value);
|
this.props.onChange(value);
|
||||||
|
|
|
@ -159,11 +159,14 @@ export const textWysiwyg = ({
|
||||||
// so that we don't need to create separate a callback for event handlers
|
// so that we don't need to create separate a callback for event handlers
|
||||||
let submittedViaKeyboard = false;
|
let submittedViaKeyboard = false;
|
||||||
const handleSubmit = () => {
|
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({
|
onSubmit({
|
||||||
text: normalizeText(editable.value),
|
text: normalizeText(editable.value),
|
||||||
viaKeyboard: submittedViaKeyboard,
|
viaKeyboard: submittedViaKeyboard,
|
||||||
});
|
});
|
||||||
cleanup();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue