mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
only show hint when a new node is created
This commit is contained in:
parent
56a0b33101
commit
d0274ad5d3
4 changed files with 49 additions and 85 deletions
|
@ -121,7 +121,6 @@ export const getDefaultAppState = (): Omit<
|
||||||
isCropping: false,
|
isCropping: false,
|
||||||
croppingElementId: null,
|
croppingElementId: null,
|
||||||
searchMatches: [],
|
searchMatches: [],
|
||||||
showShapeSwitchPanel: false,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -246,7 +245,6 @@ const APP_STATE_STORAGE_CONF = (<
|
||||||
isCropping: { browser: false, export: false, server: false },
|
isCropping: { browser: false, export: false, server: false },
|
||||||
croppingElementId: { browser: false, export: false, server: false },
|
croppingElementId: { browser: false, export: false, server: false },
|
||||||
searchMatches: { browser: false, export: false, server: false },
|
searchMatches: { browser: false, export: false, server: false },
|
||||||
showShapeSwitchPanel: { browser: false, export: false, server: false },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const _clearAppStateForStorage = <
|
const _clearAppStateForStorage = <
|
||||||
|
|
|
@ -391,7 +391,7 @@ import {
|
||||||
getMinTextElementWidth,
|
getMinTextElementWidth,
|
||||||
} from "../element/textMeasurements";
|
} from "../element/textMeasurements";
|
||||||
|
|
||||||
import ShapeSwitch from "./ShapeSwitch";
|
import ShapeSwitch, { shapeSwitchAtom } from "./ShapeSwitch";
|
||||||
|
|
||||||
import { activeConfirmDialogAtom } from "./ActiveConfirmDialog";
|
import { activeConfirmDialogAtom } from "./ActiveConfirmDialog";
|
||||||
import BraveMeasureTextError from "./BraveMeasureTextError";
|
import BraveMeasureTextError from "./BraveMeasureTextError";
|
||||||
|
@ -4113,24 +4113,11 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
selectedElements.length === 1 &&
|
selectedElements.length === 1 &&
|
||||||
(isGenericSwitchable || isLinearSwitchable)
|
(isGenericSwitchable || isLinearSwitchable)
|
||||||
) {
|
) {
|
||||||
if (this.state.showShapeSwitchPanel && event.key === KEYS.ESCAPE) {
|
if (event.key === KEYS.ESCAPE) {
|
||||||
this.setState({
|
editorJotaiStore.set(shapeSwitchAtom, null);
|
||||||
showShapeSwitchPanel: false,
|
} else if (event.key === KEYS.SLASH || event.key === KEYS.TAB) {
|
||||||
});
|
editorJotaiStore.set(shapeSwitchAtom, "panel");
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === KEYS.SLASH || event.key === KEYS.TAB) {
|
|
||||||
if (!this.state.showShapeSwitchPanel) {
|
|
||||||
flushSync(() =>
|
|
||||||
this.setState({
|
|
||||||
showShapeSwitchPanel: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.showShapeSwitchPanel) {
|
|
||||||
if (isGenericSwitchable) {
|
if (isGenericSwitchable) {
|
||||||
const index = ["rectangle", "diamond", "ellipse"].indexOf(
|
const index = ["rectangle", "diamond", "ellipse"].indexOf(
|
||||||
selectedElements[0].type,
|
selectedElements[0].type,
|
||||||
|
@ -4140,20 +4127,11 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
] as ToolType;
|
] as ToolType;
|
||||||
this.setActiveTool({ type: nextType });
|
this.setActiveTool({ type: nextType });
|
||||||
} else if (isLinearSwitchable) {
|
} else if (isLinearSwitchable) {
|
||||||
const index = ["arrow", "line"].indexOf(
|
const index = ["arrow", "line"].indexOf(selectedElements[0].type);
|
||||||
selectedElements[0].type,
|
|
||||||
);
|
|
||||||
const nextType = ["arrow", "line"][(index + 1) % 2] as ToolType;
|
const nextType = ["arrow", "line"][(index + 1) % 2] as ToolType;
|
||||||
this.setActiveTool({ type: nextType });
|
this.setActiveTool({ type: nextType });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
showShapeSwitchPanel: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -4717,6 +4695,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
canvasOffsets: this.getEditorUIOffsets(),
|
canvasOffsets: this.getEditorUIOffsets(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editorJotaiStore.set(shapeSwitchAtom, "hint");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.flowChartCreator.clear();
|
this.flowChartCreator.clear();
|
||||||
|
@ -8985,7 +8965,6 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
cursorButton: "up",
|
cursorButton: "up",
|
||||||
snapLines: updateStable(prevState.snapLines, []),
|
snapLines: updateStable(prevState.snapLines, []),
|
||||||
originSnapOffset: null,
|
originSnapOffset: null,
|
||||||
showShapeSwitchPanel: false,
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.lastPointerMoveCoords = null;
|
this.lastPointerMoveCoords = null;
|
||||||
|
|
|
@ -4,16 +4,13 @@ import clsx from "clsx";
|
||||||
|
|
||||||
import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
||||||
|
|
||||||
|
import { editorJotaiStore, atom } from "../editor-jotai";
|
||||||
|
|
||||||
import { getElementAbsoluteCoords } from "../element";
|
import { getElementAbsoluteCoords } from "../element";
|
||||||
import { sceneCoordsToViewportCoords } from "../utils";
|
import { sceneCoordsToViewportCoords } from "../utils";
|
||||||
import { getSelectedElements } from "../scene";
|
import { getSelectedElements } from "../scene";
|
||||||
import { trackEvent } from "../analytics";
|
import { trackEvent } from "../analytics";
|
||||||
import {
|
import { isArrowElement, isLinearElement } from "../element/typeChecks";
|
||||||
isArrowElement,
|
|
||||||
isGenericSwitchableElement,
|
|
||||||
isLinearElement,
|
|
||||||
isLinearSwitchableElement,
|
|
||||||
} from "../element/typeChecks";
|
|
||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
|
|
||||||
import "./ShapeSwitch.scss";
|
import "./ShapeSwitch.scss";
|
||||||
|
@ -34,48 +31,29 @@ import type { ToolType } from "../types";
|
||||||
const GAP_HORIZONTAL = 8;
|
const GAP_HORIZONTAL = 8;
|
||||||
const GAP_VERTICAL = 10;
|
const GAP_VERTICAL = 10;
|
||||||
|
|
||||||
|
export const shapeSwitchAtom = atom<"hint" | "panel" | null>(null);
|
||||||
|
|
||||||
const ShapeSwitch = ({ app }: { app: App }) => {
|
const ShapeSwitch = ({ app }: { app: App }) => {
|
||||||
|
const shapeSwitchAtomValue = editorJotaiStore.get(shapeSwitchAtom);
|
||||||
|
|
||||||
|
if (!shapeSwitchAtomValue) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const selectedElements = getSelectedElements(
|
const selectedElements = getSelectedElements(
|
||||||
app.scene.getNonDeletedElementsMap(),
|
app.scene.getNonDeletedElementsMap(),
|
||||||
app.state,
|
app.state,
|
||||||
);
|
);
|
||||||
const firstElement = selectedElements[0];
|
const firstElement = selectedElements[0];
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
return app.setState({ showShapeSwitchPanel: false });
|
|
||||||
}, [app]);
|
|
||||||
|
|
||||||
const isGeneric = firstElement && isGenericSwitchableElement(firstElement);
|
|
||||||
const isLinear = firstElement && isLinearSwitchableElement(firstElement);
|
|
||||||
const isGenericInChart =
|
|
||||||
isGeneric &&
|
|
||||||
app.scene
|
|
||||||
.getNonDeletedElements()
|
|
||||||
.some(
|
|
||||||
(el) =>
|
|
||||||
el.type === "arrow" &&
|
|
||||||
(el.startBinding?.elementId === firstElement.id ||
|
|
||||||
el.endBinding?.elementId === firstElement.id),
|
|
||||||
);
|
|
||||||
const isLinearInChart =
|
|
||||||
isLinear &&
|
|
||||||
isArrowElement(firstElement) &&
|
|
||||||
(firstElement.startBinding || firstElement.endBinding);
|
|
||||||
|
|
||||||
if (firstElement && selectedElements.length === 1) {
|
if (firstElement && selectedElements.length === 1) {
|
||||||
if (isGeneric) {
|
switch (shapeSwitchAtomValue) {
|
||||||
return app.state.showShapeSwitchPanel ? (
|
case "hint":
|
||||||
<Panel app={app} element={firstElement} />
|
return <Hint app={app} element={firstElement} />;
|
||||||
) : isGenericInChart ? (
|
case "panel":
|
||||||
<Hint app={app} element={firstElement} />
|
return <Panel app={app} element={firstElement} />;
|
||||||
) : null;
|
default:
|
||||||
}
|
return null;
|
||||||
if (isLinear) {
|
|
||||||
return app.state.showShapeSwitchPanel ? (
|
|
||||||
<Panel app={app} element={firstElement} />
|
|
||||||
) : isLinearInChart ? (
|
|
||||||
<Hint app={app} element={firstElement} />
|
|
||||||
) : null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,9 +87,14 @@ const Hint = ({ app, element }: { app: App; element: ExcalidrawElement }) => {
|
||||||
hintRef.current?.classList.remove("animation");
|
hintRef.current?.classList.remove("animation");
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hintRef.current) {
|
const hint = hintRef.current;
|
||||||
hintRef.current.addEventListener("animationend", listener);
|
|
||||||
|
if (hint) {
|
||||||
|
hint.addEventListener("animationend", listener);
|
||||||
|
editorJotaiStore.set(shapeSwitchAtom, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return () => hint?.removeEventListener("animationend", listener);
|
||||||
}, [element.id]);
|
}, [element.id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -171,6 +154,12 @@ const Panel = ({ app, element }: { app: App; element: ExcalidrawElement }) => {
|
||||||
["ellipse", "4", EllipseIcon],
|
["ellipse", "4", EllipseIcon],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
editorJotaiStore.set(shapeSwitchAtom, null);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|
|
@ -410,8 +410,6 @@ export interface AppState {
|
||||||
croppingElementId: ExcalidrawElement["id"] | null;
|
croppingElementId: ExcalidrawElement["id"] | null;
|
||||||
|
|
||||||
searchMatches: readonly SearchMatch[];
|
searchMatches: readonly SearchMatch[];
|
||||||
|
|
||||||
showShapeSwitchPanel: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchMatch = {
|
type SearchMatch = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue