mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-14 09:45:27 +01:00
fix preferred tool
This commit is contained in:
@@ -11,7 +11,6 @@ import {
|
|||||||
THEME,
|
THEME,
|
||||||
DEFAULT_GRID_STEP,
|
DEFAULT_GRID_STEP,
|
||||||
isTestEnv,
|
isTestEnv,
|
||||||
isMobileOrTablet,
|
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
import type { AppState, NormalizedZoomValue } from "./types";
|
import type { AppState, NormalizedZoomValue } from "./types";
|
||||||
@@ -56,7 +55,7 @@ export const getDefaultAppState = (): Omit<
|
|||||||
fromSelection: false,
|
fromSelection: false,
|
||||||
lastActiveTool: null,
|
lastActiveTool: null,
|
||||||
},
|
},
|
||||||
preferredSelectionTool: isMobileOrTablet() ? "lasso" : "selection",
|
preferredSelectionTool: "selection",
|
||||||
penMode: false,
|
penMode: false,
|
||||||
penDetected: false,
|
penDetected: false,
|
||||||
errorMessage: null,
|
errorMessage: null,
|
||||||
|
|||||||
@@ -1034,12 +1034,12 @@ export const MobileShapeActions = ({
|
|||||||
|
|
||||||
export const ShapesSwitcher = ({
|
export const ShapesSwitcher = ({
|
||||||
activeTool,
|
activeTool,
|
||||||
appState,
|
setAppState,
|
||||||
app,
|
app,
|
||||||
UIOptions,
|
UIOptions,
|
||||||
}: {
|
}: {
|
||||||
activeTool: UIAppState["activeTool"];
|
activeTool: UIAppState["activeTool"];
|
||||||
appState: UIAppState;
|
setAppState: React.Component<any, AppState>["setState"];
|
||||||
app: AppClassProperties;
|
app: AppClassProperties;
|
||||||
UIOptions: AppProps["UIOptions"];
|
UIOptions: AppProps["UIOptions"];
|
||||||
}) => {
|
}) => {
|
||||||
@@ -1061,7 +1061,9 @@ export const ShapesSwitcher = ({
|
|||||||
const frameToolSelected = activeTool.type === "frame";
|
const frameToolSelected = activeTool.type === "frame";
|
||||||
const laserToolSelected = activeTool.type === "laser";
|
const laserToolSelected = activeTool.type === "laser";
|
||||||
const lassoToolSelected =
|
const lassoToolSelected =
|
||||||
activeTool.type === "lasso" && app.state.preferredSelectionTool !== "lasso";
|
app.state.stylesPanelMode === "full" &&
|
||||||
|
activeTool.type === "lasso" &&
|
||||||
|
app.state.preferredSelectionTool !== "lasso";
|
||||||
|
|
||||||
const embeddableToolSelected = activeTool.type === "embeddable";
|
const embeddableToolSelected = activeTool.type === "embeddable";
|
||||||
|
|
||||||
@@ -1092,14 +1094,14 @@ export const ShapesSwitcher = ({
|
|||||||
// use a ToolPopover for selection/lasso toggle as well
|
// use a ToolPopover for selection/lasso toggle as well
|
||||||
if (
|
if (
|
||||||
(value === "selection" || value === "lasso") &&
|
(value === "selection" || value === "lasso") &&
|
||||||
appState.stylesPanelMode === "compact"
|
app.state.stylesPanelMode === "compact"
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<ToolPopover
|
<ToolPopover
|
||||||
key={"selection-popover"}
|
key={"selection-popover"}
|
||||||
app={app}
|
app={app}
|
||||||
options={SELECTION_TOOLS}
|
options={SELECTION_TOOLS}
|
||||||
activeTool={activeTool as any}
|
activeTool={activeTool}
|
||||||
defaultOption={app.state.preferredSelectionTool}
|
defaultOption={app.state.preferredSelectionTool}
|
||||||
namePrefix="selectionType"
|
namePrefix="selectionType"
|
||||||
title={capitalizeString(t("toolBar.selection"))}
|
title={capitalizeString(t("toolBar.selection"))}
|
||||||
@@ -1107,7 +1109,9 @@ export const ShapesSwitcher = ({
|
|||||||
onToolChange={(type: string) => {
|
onToolChange={(type: string) => {
|
||||||
if (type === "selection" || type === "lasso") {
|
if (type === "selection" || type === "lasso") {
|
||||||
app.setActiveTool({ type });
|
app.setActiveTool({ type });
|
||||||
app.state.preferredSelectionTool = type as any;
|
setAppState({
|
||||||
|
preferredSelectionTool: type,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
displayedOption={
|
displayedOption={
|
||||||
@@ -1115,9 +1119,7 @@ export const ShapesSwitcher = ({
|
|||||||
(tool) => tool.type === app.state.preferredSelectionTool,
|
(tool) => tool.type === app.state.preferredSelectionTool,
|
||||||
) || SELECTION_TOOLS[0]
|
) || SELECTION_TOOLS[0]
|
||||||
}
|
}
|
||||||
isActive={
|
fillable={activeTool.type === "selection"}
|
||||||
activeTool.type === "selection" || activeTool.type === "lasso"
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1136,12 +1138,12 @@ export const ShapesSwitcher = ({
|
|||||||
aria-keyshortcuts={shortcut}
|
aria-keyshortcuts={shortcut}
|
||||||
data-testid={`toolbar-${value}`}
|
data-testid={`toolbar-${value}`}
|
||||||
onPointerDown={({ pointerType }) => {
|
onPointerDown={({ pointerType }) => {
|
||||||
if (!appState.penDetected && pointerType === "pen") {
|
if (!app.state.penDetected && pointerType === "pen") {
|
||||||
app.togglePenMode(true);
|
app.togglePenMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === "selection") {
|
if (value === "selection") {
|
||||||
if (appState.activeTool.type === "selection") {
|
if (app.state.activeTool.type === "selection") {
|
||||||
app.setActiveTool({ type: "lasso" });
|
app.setActiveTool({ type: "lasso" });
|
||||||
} else {
|
} else {
|
||||||
app.setActiveTool({ type: "selection" });
|
app.setActiveTool({ type: "selection" });
|
||||||
@@ -1149,7 +1151,7 @@ export const ShapesSwitcher = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onChange={({ pointerType }) => {
|
onChange={({ pointerType }) => {
|
||||||
if (appState.activeTool.type !== value) {
|
if (app.state.activeTool.type !== value) {
|
||||||
trackEvent("toolbar", value, "ui");
|
trackEvent("toolbar", value, "ui");
|
||||||
}
|
}
|
||||||
if (value === "image") {
|
if (value === "image") {
|
||||||
@@ -1222,7 +1224,7 @@ export const ShapesSwitcher = ({
|
|||||||
>
|
>
|
||||||
{t("toolBar.laser")}
|
{t("toolBar.laser")}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
{appState.stylesPanelMode === "full" && (
|
{app.state.stylesPanelMode === "full" && (
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
onSelect={() => app.setActiveTool({ type: "lasso" })}
|
onSelect={() => app.setActiveTool({ type: "lasso" })}
|
||||||
icon={LassoIcon}
|
icon={LassoIcon}
|
||||||
|
|||||||
@@ -2375,12 +2375,13 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
activeTool.type === "selection"
|
activeTool.type === "selection"
|
||||||
? {
|
? {
|
||||||
...activeTool,
|
...activeTool,
|
||||||
type: this.state.preferredSelectionTool,
|
type: scene.appState.preferredSelectionTool,
|
||||||
}
|
}
|
||||||
: scene.appState.activeTool,
|
: scene.appState.activeTool,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
toast: this.state.toast,
|
toast: this.state.toast,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (initialData?.scrollToContent) {
|
if (initialData?.scrollToContent) {
|
||||||
scene.appState = {
|
scene.appState = {
|
||||||
...scene.appState,
|
...scene.appState,
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ const LayerUI = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<ShapesSwitcher
|
<ShapesSwitcher
|
||||||
appState={appState}
|
setAppState={setAppState}
|
||||||
activeTool={appState.activeTool}
|
activeTool={appState.activeTool}
|
||||||
UIOptions={UIOptions}
|
UIOptions={UIOptions}
|
||||||
app={app}
|
app={app}
|
||||||
|
|||||||
@@ -97,9 +97,9 @@ export const MobileMenu = ({
|
|||||||
const renderToolbar = () => {
|
const renderToolbar = () => {
|
||||||
return (
|
return (
|
||||||
<MobileToolBar
|
<MobileToolBar
|
||||||
appState={appState}
|
|
||||||
app={app}
|
app={app}
|
||||||
onHandToolToggle={onHandToolToggle}
|
onHandToolToggle={onHandToolToggle}
|
||||||
|
setAppState={setAppState}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -82,17 +82,17 @@ const LINEAR_ELEMENT_TOOLS = [
|
|||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
type MobileToolBarProps = {
|
type MobileToolBarProps = {
|
||||||
appState: UIAppState;
|
|
||||||
app: AppClassProperties;
|
app: AppClassProperties;
|
||||||
onHandToolToggle: () => void;
|
onHandToolToggle: () => void;
|
||||||
|
setAppState: React.Component<any, UIAppState>["setState"];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MobileToolBar = ({
|
export const MobileToolBar = ({
|
||||||
appState,
|
|
||||||
app,
|
app,
|
||||||
onHandToolToggle,
|
onHandToolToggle,
|
||||||
|
setAppState,
|
||||||
}: MobileToolBarProps) => {
|
}: MobileToolBarProps) => {
|
||||||
const activeTool = appState.activeTool;
|
const activeTool = app.state.activeTool;
|
||||||
const [isOtherShapesMenuOpen, setIsOtherShapesMenuOpen] = useState(false);
|
const [isOtherShapesMenuOpen, setIsOtherShapesMenuOpen] = useState(false);
|
||||||
const [lastActiveGenericShape, setLastActiveGenericShape] = useState<
|
const [lastActiveGenericShape, setLastActiveGenericShape] = useState<
|
||||||
"rectangle" | "diamond" | "ellipse"
|
"rectangle" | "diamond" | "ellipse"
|
||||||
@@ -128,12 +128,12 @@ export const MobileToolBar = ({
|
|||||||
const { TTDDialogTriggerTunnel } = useTunnels();
|
const { TTDDialogTriggerTunnel } = useTunnels();
|
||||||
|
|
||||||
const handleToolChange = (toolType: string, pointerType?: string) => {
|
const handleToolChange = (toolType: string, pointerType?: string) => {
|
||||||
if (appState.activeTool.type !== toolType) {
|
if (app.state.activeTool.type !== toolType) {
|
||||||
trackEvent("toolbar", toolType, "ui");
|
trackEvent("toolbar", toolType, "ui");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toolType === "selection") {
|
if (toolType === "selection") {
|
||||||
if (appState.activeTool.type === "selection") {
|
if (app.state.activeTool.type === "selection") {
|
||||||
// Toggle selection tool behavior if needed
|
// Toggle selection tool behavior if needed
|
||||||
} else {
|
} else {
|
||||||
app.setActiveTool({ type: "selection" });
|
app.setActiveTool({ type: "selection" });
|
||||||
@@ -172,17 +172,17 @@ export const MobileToolBar = ({
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
const extraToolSelected = extraTools.includes(appState.activeTool.type);
|
const extraToolSelected = extraTools.includes(activeTool.type);
|
||||||
const extraIcon = extraToolSelected
|
const extraIcon = extraToolSelected
|
||||||
? appState.activeTool.type === "frame"
|
? activeTool.type === "frame"
|
||||||
? frameToolIcon
|
? frameToolIcon
|
||||||
: appState.activeTool.type === "embeddable"
|
: activeTool.type === "embeddable"
|
||||||
? EmbedIcon
|
? EmbedIcon
|
||||||
: appState.activeTool.type === "laser"
|
: activeTool.type === "laser"
|
||||||
? laserPointerToolIcon
|
? laserPointerToolIcon
|
||||||
: appState.activeTool.type === "text"
|
: activeTool.type === "text"
|
||||||
? TextIcon
|
? TextIcon
|
||||||
: appState.activeTool.type === "magicframe"
|
: activeTool.type === "magicframe"
|
||||||
? MagicIcon
|
? MagicIcon
|
||||||
: extraToolsIcon
|
: extraToolsIcon
|
||||||
: extraToolsIcon;
|
: extraToolsIcon;
|
||||||
@@ -191,7 +191,7 @@ export const MobileToolBar = ({
|
|||||||
<div className="mobile-toolbar" ref={toolbarRef}>
|
<div className="mobile-toolbar" ref={toolbarRef}>
|
||||||
{/* Hand Tool */}
|
{/* Hand Tool */}
|
||||||
<HandButton
|
<HandButton
|
||||||
checked={isHandToolActive(appState)}
|
checked={isHandToolActive(app.state)}
|
||||||
onChange={onHandToolToggle}
|
onChange={onHandToolToggle}
|
||||||
title={t("toolBar.hand")}
|
title={t("toolBar.hand")}
|
||||||
isMobile
|
isMobile
|
||||||
@@ -209,7 +209,9 @@ export const MobileToolBar = ({
|
|||||||
onToolChange={(type: string) => {
|
onToolChange={(type: string) => {
|
||||||
if (type === "selection" || type === "lasso") {
|
if (type === "selection" || type === "lasso") {
|
||||||
app.setActiveTool({ type });
|
app.setActiveTool({ type });
|
||||||
app.state.preferredSelectionTool = type;
|
setAppState({
|
||||||
|
preferredSelectionTool: type,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
displayedOption={
|
displayedOption={
|
||||||
@@ -217,9 +219,6 @@ export const MobileToolBar = ({
|
|||||||
(tool) => tool.type === app.state.preferredSelectionTool,
|
(tool) => tool.type === app.state.preferredSelectionTool,
|
||||||
) || SELECTION_TOOLS[0]
|
) || SELECTION_TOOLS[0]
|
||||||
}
|
}
|
||||||
isActive={
|
|
||||||
activeTool.type === "selection" || activeTool.type === "lasso"
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Free Draw */}
|
{/* Free Draw */}
|
||||||
@@ -285,7 +284,6 @@ export const MobileToolBar = ({
|
|||||||
SHAPE_TOOLS.find((tool) => tool.type === lastActiveGenericShape) ||
|
SHAPE_TOOLS.find((tool) => tool.type === lastActiveGenericShape) ||
|
||||||
SHAPE_TOOLS[0]
|
SHAPE_TOOLS[0]
|
||||||
}
|
}
|
||||||
isActive={["rectangle", "diamond", "ellipse"].includes(activeTool.type)}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Arrow/Line */}
|
{/* Arrow/Line */}
|
||||||
@@ -315,7 +313,6 @@ export const MobileToolBar = ({
|
|||||||
(tool) => tool.type === lastActiveLinearElement,
|
(tool) => tool.type === lastActiveLinearElement,
|
||||||
) || LINEAR_ELEMENT_TOOLS[0]
|
) || LINEAR_ELEMENT_TOOLS[0]
|
||||||
}
|
}
|
||||||
isActive={["arrow", "line"].includes(activeTool.type)}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Image */}
|
{/* Image */}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ type ToolPopoverProps = {
|
|||||||
"data-testid": string;
|
"data-testid": string;
|
||||||
onToolChange: (type: string) => void;
|
onToolChange: (type: string) => void;
|
||||||
displayedOption: ToolOption;
|
displayedOption: ToolOption;
|
||||||
isActive: boolean;
|
|
||||||
fillable?: boolean;
|
fillable?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,12 +43,12 @@ export const ToolPopover = ({
|
|||||||
title,
|
title,
|
||||||
"data-testid": dataTestId,
|
"data-testid": dataTestId,
|
||||||
onToolChange,
|
onToolChange,
|
||||||
isActive,
|
|
||||||
displayedOption,
|
displayedOption,
|
||||||
fillable = false,
|
fillable = false,
|
||||||
}: ToolPopoverProps) => {
|
}: ToolPopoverProps) => {
|
||||||
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
||||||
const currentType = activeTool.type;
|
const currentType = activeTool.type;
|
||||||
|
const isActive = displayedOption.type === currentType;
|
||||||
const SIDE_OFFSET = 32 / 2 + 10;
|
const SIDE_OFFSET = 32 / 2 + 10;
|
||||||
|
|
||||||
// if currentType is not in options, close popup
|
// if currentType is not in options, close popup
|
||||||
|
|||||||
Reference in New Issue
Block a user