mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
refactor: rename elementType to activeTool and make it an object (#4968)
* refactor: rename elementType to activeTool * update docs * fix snap * update activeToll to be an object and review fixes * fix tests * fix
This commit is contained in:
parent
2209e2c1e8
commit
127af9db23
25 changed files with 364 additions and 207 deletions
|
@ -811,10 +811,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
scene.appState = {
|
||||
...scene.appState,
|
||||
elementType:
|
||||
scene.appState.elementType === "image"
|
||||
? "selection"
|
||||
: scene.appState.elementType,
|
||||
activeTool:
|
||||
scene.appState.activeTool.type === "image"
|
||||
? { type: "selection" }
|
||||
: scene.appState.activeTool,
|
||||
isLoading: false,
|
||||
};
|
||||
if (initialData?.scrollToContent) {
|
||||
|
@ -1068,15 +1068,15 @@ class App extends React.Component<AppProps, AppState> {
|
|||
Object.keys(this.state.selectedElementIds).length &&
|
||||
isEraserActive(this.state)
|
||||
) {
|
||||
this.setState({ elementType: "selection" });
|
||||
this.setState({ activeTool: { type: "selection" } });
|
||||
}
|
||||
if (prevState.theme !== this.state.theme) {
|
||||
setEraserCursor(this.canvas, this.state.theme);
|
||||
}
|
||||
// Hide hyperlink popup if shown when element type is not selection
|
||||
if (
|
||||
prevState.elementType === "selection" &&
|
||||
this.state.elementType !== "selection" &&
|
||||
prevState.activeTool.type === "selection" &&
|
||||
this.state.activeTool.type !== "selection" &&
|
||||
this.state.showHyperlinkPopup
|
||||
) {
|
||||
this.setState({ showHyperlinkPopup: false });
|
||||
|
@ -1130,7 +1130,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
const { multiElement } = prevState;
|
||||
if (
|
||||
prevState.elementType !== this.state.elementType &&
|
||||
prevState.activeTool !== this.state.activeTool &&
|
||||
multiElement != null &&
|
||||
isBindingEnabled(this.state) &&
|
||||
isBindingElement(multiElement)
|
||||
|
@ -1433,7 +1433,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
} else if (data.text) {
|
||||
this.addTextFromPaste(data.text);
|
||||
}
|
||||
this.selectShapeTool("selection");
|
||||
this.setActiveTool({ type: "selection" });
|
||||
event?.preventDefault();
|
||||
},
|
||||
);
|
||||
|
@ -1521,7 +1521,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
},
|
||||
);
|
||||
this.selectShapeTool("selection");
|
||||
this.setActiveTool({ type: "selection" });
|
||||
};
|
||||
|
||||
private addTextFromPaste(text: any) {
|
||||
|
@ -1574,9 +1574,9 @@ class App extends React.Component<AppProps, AppState> {
|
|||
this.setState((prevState) => {
|
||||
return {
|
||||
elementLocked: !prevState.elementLocked,
|
||||
elementType: prevState.elementLocked
|
||||
? "selection"
|
||||
: prevState.elementType,
|
||||
activeTool: prevState.elementLocked
|
||||
? { type: "selection" }
|
||||
: prevState.activeTool,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
@ -1851,7 +1851,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
) {
|
||||
const shape = findShapeByKey(event.key);
|
||||
if (shape) {
|
||||
this.selectShapeTool(shape);
|
||||
this.setActiveTool({ type: shape });
|
||||
} else if (event.key === KEYS.Q) {
|
||||
this.toggleLock();
|
||||
}
|
||||
|
@ -1868,7 +1868,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
this.state,
|
||||
);
|
||||
if (
|
||||
this.state.elementType === "selection" &&
|
||||
this.state.activeTool.type === "selection" &&
|
||||
!selectedElements.length
|
||||
) {
|
||||
return;
|
||||
|
@ -1876,7 +1876,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
if (
|
||||
event.key === KEYS.G &&
|
||||
(hasBackground(this.state.elementType) ||
|
||||
(hasBackground(this.state.activeTool.type) ||
|
||||
selectedElements.some((element) => hasBackground(element.type)))
|
||||
) {
|
||||
this.setState({ openPopup: "backgroundColorPicker" });
|
||||
|
@ -1892,7 +1892,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
if (event.key === KEYS.SPACE) {
|
||||
if (this.state.viewModeEnabled) {
|
||||
setCursor(this.canvas, CURSOR_TYPE.GRAB);
|
||||
} else if (this.state.elementType === "selection") {
|
||||
} else if (this.state.activeTool.type === "selection") {
|
||||
resetCursor(this.canvas);
|
||||
} else {
|
||||
setCursorForShape(this.canvas, this.state);
|
||||
|
@ -1919,28 +1919,28 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
});
|
||||
|
||||
private selectShapeTool(elementType: AppState["elementType"]) {
|
||||
private setActiveTool(tool: AppState["activeTool"]) {
|
||||
if (!isHoldingSpace) {
|
||||
setCursorForShape(this.canvas, this.state);
|
||||
}
|
||||
if (isToolIcon(document.activeElement)) {
|
||||
this.focusContainer();
|
||||
}
|
||||
if (!isLinearElementType(elementType)) {
|
||||
if (!isLinearElementType(tool.type)) {
|
||||
this.setState({ suggestedBindings: [] });
|
||||
}
|
||||
if (elementType === "image") {
|
||||
if (tool.type === "image") {
|
||||
this.onImageAction();
|
||||
}
|
||||
if (elementType !== "selection") {
|
||||
if (tool.type !== "selection") {
|
||||
this.setState({
|
||||
elementType,
|
||||
activeTool: tool,
|
||||
selectedElementIds: {},
|
||||
selectedGroupIds: {},
|
||||
editingGroupId: null,
|
||||
});
|
||||
} else {
|
||||
this.setState({ elementType });
|
||||
this.setState({ activeTool: tool });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2314,7 +2314,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
return;
|
||||
}
|
||||
// we should only be able to double click when mode is selection
|
||||
if (this.state.elementType !== "selection") {
|
||||
if (this.state.activeTool.type !== "selection") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2504,7 +2504,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
const distance = getDistance(Array.from(gesture.pointers.values()));
|
||||
const scaleFactor =
|
||||
this.state.elementType === "freedraw" && this.state.penMode
|
||||
this.state.activeTool.type === "freedraw" && this.state.penMode
|
||||
? 1
|
||||
: distance / gesture.initialDistance;
|
||||
|
||||
|
@ -2579,7 +2579,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
}
|
||||
|
||||
if (isBindingElementType(this.state.elementType)) {
|
||||
if (isBindingElementType(this.state.activeTool.type)) {
|
||||
// Hovering with a selected tool or creating new linear element via click
|
||||
// and point
|
||||
const { draggingElement } = this.state;
|
||||
|
@ -2655,9 +2655,9 @@ class App extends React.Component<AppProps, AppState> {
|
|||
const hasDeselectedButton = Boolean(event.buttons);
|
||||
if (
|
||||
hasDeselectedButton ||
|
||||
(this.state.elementType !== "selection" &&
|
||||
this.state.elementType !== "text" &&
|
||||
this.state.elementType !== "eraser")
|
||||
(this.state.activeTool.type !== "selection" &&
|
||||
this.state.activeTool.type !== "text" &&
|
||||
this.state.activeTool.type !== "eraser")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -2734,7 +2734,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
!this.state.showHyperlinkPopup
|
||||
) {
|
||||
this.setState({ showHyperlinkPopup: "info" });
|
||||
} else if (this.state.elementType === "text") {
|
||||
} else if (this.state.activeTool.type === "text") {
|
||||
setCursor(
|
||||
this.canvas,
|
||||
isTextElement(hitElement) ? CURSOR_TYPE.TEXT : CURSOR_TYPE.CROSSHAIR,
|
||||
|
@ -2946,27 +2946,27 @@ class App extends React.Component<AppProps, AppState> {
|
|||
const allowOnPointerDown =
|
||||
!this.state.penMode ||
|
||||
event.pointerType !== "touch" ||
|
||||
this.state.elementType === "selection" ||
|
||||
this.state.elementType === "text" ||
|
||||
this.state.elementType === "image";
|
||||
this.state.activeTool.type === "selection" ||
|
||||
this.state.activeTool.type === "text" ||
|
||||
this.state.activeTool.type === "image";
|
||||
|
||||
if (!allowOnPointerDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.state.elementType === "text") {
|
||||
if (this.state.activeTool.type === "text") {
|
||||
this.handleTextOnPointerDown(event, pointerDownState);
|
||||
return;
|
||||
} else if (
|
||||
this.state.elementType === "arrow" ||
|
||||
this.state.elementType === "line"
|
||||
this.state.activeTool.type === "arrow" ||
|
||||
this.state.activeTool.type === "line"
|
||||
) {
|
||||
this.handleLinearElementOnPointerDown(
|
||||
event,
|
||||
this.state.elementType,
|
||||
this.state.activeTool.type,
|
||||
pointerDownState,
|
||||
);
|
||||
} else if (this.state.elementType === "image") {
|
||||
} else if (this.state.activeTool.type === "image") {
|
||||
// reset image preview on pointerdown
|
||||
setCursor(this.canvas, CURSOR_TYPE.CROSSHAIR);
|
||||
|
||||
|
@ -2986,15 +2986,15 @@ class App extends React.Component<AppProps, AppState> {
|
|||
x,
|
||||
y,
|
||||
});
|
||||
} else if (this.state.elementType === "freedraw") {
|
||||
} else if (this.state.activeTool.type === "freedraw") {
|
||||
this.handleFreeDrawElementOnPointerDown(
|
||||
event,
|
||||
this.state.elementType,
|
||||
this.state.activeTool.type,
|
||||
pointerDownState,
|
||||
);
|
||||
} else if (this.state.elementType !== "eraser") {
|
||||
} else if (this.state.activeTool.type !== "eraser") {
|
||||
this.createGenericElementOnPointerDown(
|
||||
this.state.elementType,
|
||||
this.state.activeTool.type,
|
||||
pointerDownState,
|
||||
);
|
||||
}
|
||||
|
@ -3312,7 +3312,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
|
||||
private clearSelectionIfNotUsingSelection = (): void => {
|
||||
if (this.state.elementType !== "selection") {
|
||||
if (this.state.activeTool.type !== "selection") {
|
||||
this.setState({
|
||||
selectedElementIds: {},
|
||||
selectedGroupIds: {},
|
||||
|
@ -3328,7 +3328,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
event: React.PointerEvent<HTMLCanvasElement>,
|
||||
pointerDownState: PointerDownState,
|
||||
): boolean => {
|
||||
if (this.state.elementType === "selection") {
|
||||
if (this.state.activeTool.type === "selection") {
|
||||
const elements = this.scene.getElements();
|
||||
const selectedElements = getSelectedElements(elements, this.state);
|
||||
if (selectedElements.length === 1 && !this.state.editingLinearElement) {
|
||||
|
@ -3573,7 +3573,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
resetCursor(this.canvas);
|
||||
if (!this.state.elementLocked) {
|
||||
this.setState({
|
||||
elementType: "selection",
|
||||
activeTool: { type: "selection" },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -3882,8 +3882,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||
// triggering pointermove)
|
||||
if (
|
||||
!pointerDownState.drag.hasOccurred &&
|
||||
(this.state.elementType === "arrow" ||
|
||||
this.state.elementType === "line")
|
||||
(this.state.activeTool.type === "arrow" ||
|
||||
this.state.activeTool.type === "line")
|
||||
) {
|
||||
if (
|
||||
distance2d(
|
||||
|
@ -4078,7 +4078,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
if (shouldRotateWithDiscreteAngle(event) && points.length === 2) {
|
||||
({ width: dx, height: dy } = getPerfectElementSize(
|
||||
this.state.elementType,
|
||||
this.state.activeTool.type,
|
||||
dx,
|
||||
dy,
|
||||
));
|
||||
|
@ -4106,7 +4106,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
this.maybeDragNewGenericElement(pointerDownState, event);
|
||||
}
|
||||
|
||||
if (this.state.elementType === "selection") {
|
||||
if (this.state.activeTool.type === "selection") {
|
||||
pointerDownState.boxSelection.hasOccurred = true;
|
||||
|
||||
const elements = this.scene.getElements();
|
||||
|
@ -4217,7 +4217,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
draggingElement,
|
||||
resizingElement,
|
||||
multiElement,
|
||||
elementType,
|
||||
activeTool,
|
||||
elementLocked,
|
||||
isResizing,
|
||||
isRotating,
|
||||
|
@ -4386,7 +4386,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
resetCursor(this.canvas);
|
||||
this.setState((prevState) => ({
|
||||
draggingElement: null,
|
||||
elementType: "selection",
|
||||
activeTool: { type: "selection" },
|
||||
selectedElementIds: {
|
||||
...prevState.selectedElementIds,
|
||||
[this.state.draggingElement!.id]: true,
|
||||
|
@ -4406,7 +4406,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
|
||||
if (
|
||||
elementType !== "selection" &&
|
||||
activeTool.type !== "selection" &&
|
||||
draggingElement &&
|
||||
isInvisiblySmallElement(draggingElement)
|
||||
) {
|
||||
|
@ -4575,7 +4575,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!elementLocked && elementType !== "freedraw" && draggingElement) {
|
||||
if (!elementLocked && activeTool.type !== "freedraw" && draggingElement) {
|
||||
this.setState((prevState) => ({
|
||||
selectedElementIds: {
|
||||
...prevState.selectedElementIds,
|
||||
|
@ -4585,7 +4585,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
}
|
||||
|
||||
if (
|
||||
elementType !== "selection" ||
|
||||
activeTool.type !== "selection" ||
|
||||
isSomeElementSelected(this.scene.getElements(), this.state)
|
||||
) {
|
||||
this.history.resumeRecording();
|
||||
|
@ -4599,12 +4599,12 @@ class App extends React.Component<AppProps, AppState> {
|
|||
);
|
||||
}
|
||||
|
||||
if (!elementLocked && elementType !== "freedraw") {
|
||||
if (!elementLocked && activeTool.type !== "freedraw") {
|
||||
resetCursor(this.canvas);
|
||||
this.setState({
|
||||
draggingElement: null,
|
||||
suggestedBindings: [],
|
||||
elementType: "selection",
|
||||
activeTool: { type: "selection" },
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
|
@ -4910,7 +4910,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
{
|
||||
pendingImageElement: null,
|
||||
editingElement: null,
|
||||
elementType: "selection",
|
||||
activeTool: { type: "selection" },
|
||||
},
|
||||
() => {
|
||||
this.actionManager.executeAction(actionFinalize);
|
||||
|
@ -5280,7 +5280,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
(event.nativeEvent.pointerType === "pen" &&
|
||||
// always allow if user uses a pen secondary button
|
||||
event.button !== POINTER_BUTTON.SECONDARY)) &&
|
||||
this.state.elementType !== "selection"
|
||||
this.state.activeTool.type !== "selection"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -5314,10 +5314,13 @@ class App extends React.Component<AppProps, AppState> {
|
|||
if (!draggingElement) {
|
||||
return;
|
||||
}
|
||||
if (draggingElement.type === "selection") {
|
||||
if (
|
||||
draggingElement.type === "selection" &&
|
||||
this.state.activeTool.type !== "eraser"
|
||||
) {
|
||||
dragNewElement(
|
||||
draggingElement,
|
||||
this.state.elementType,
|
||||
this.state.activeTool.type,
|
||||
pointerDownState.origin.x,
|
||||
pointerDownState.origin.y,
|
||||
pointerCoords.x,
|
||||
|
@ -5344,7 +5347,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
dragNewElement(
|
||||
draggingElement,
|
||||
this.state.elementType,
|
||||
this.state.activeTool.type,
|
||||
pointerDownState.originInGrid.x,
|
||||
pointerDownState.originInGrid.y,
|
||||
gridX,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue