import React from "react";
import { ActionManager } from "../actions/manager";
import { getNonDeletedElements } from "../element";
import { ExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import useIsMobile from "../is-mobile";
import {
canChangeSharpness,
canHaveArrowheads,
getTargetElements,
hasBackground,
hasStroke,
hasText,
} from "../scene";
import { SHAPES } from "../shapes";
import { AppState, Zoom } from "../types";
import { capitalizeString, isTransparent, setCursorForShape } from "../utils";
import Stack from "./Stack";
import { ToolButton } from "./ToolButton";
export const SelectedShapeActions = ({
appState,
elements,
renderAction,
elementType,
}: {
appState: AppState;
elements: readonly ExcalidrawElement[];
renderAction: ActionManager["renderAction"];
elementType: ExcalidrawElement["type"];
}) => {
const targetElements = getTargetElements(
getNonDeletedElements(elements),
appState,
);
const isEditing = Boolean(appState.editingElement);
const isMobile = useIsMobile();
const isRTL = document.documentElement.getAttribute("dir") === "rtl";
const showFillIcons =
hasBackground(elementType) ||
targetElements.some(
(element) =>
hasBackground(element.type) && !isTransparent(element.backgroundColor),
);
const showChangeBackgroundIcons =
hasBackground(elementType) ||
targetElements.some((element) => hasBackground(element.type));
return (
{renderAction("changeStrokeColor")}
{showChangeBackgroundIcons && renderAction("changeBackgroundColor")}
{showFillIcons && renderAction("changeFillStyle")}
{(hasStroke(elementType) ||
targetElements.some((element) => hasStroke(element.type))) && (
<>
{renderAction("changeStrokeWidth")}
{renderAction("changeStrokeStyle")}
{renderAction("changeSloppiness")}
>
)}
{(canChangeSharpness(elementType) ||
targetElements.some((element) => canChangeSharpness(element.type))) && (
<>{renderAction("changeSharpness")}>
)}
{(hasText(elementType) ||
targetElements.some((element) => hasText(element.type))) && (
<>
{renderAction("changeFontSize")}
{renderAction("changeFontFamily")}
{renderAction("changeTextAlign")}
>
)}
{(canHaveArrowheads(elementType) ||
targetElements.some((element) => canHaveArrowheads(element.type))) && (
<>{renderAction("changeArrowhead")}>
)}
{renderAction("changeOpacity")}
{targetElements.length > 1 && (
)}
{!isMobile && !isEditing && targetElements.length > 0 && (
)}
);
};
const LIBRARY_ICON = (
// fa-th-large
);
export const ShapesSwitcher = ({
elementType,
setAppState,
isLibraryOpen,
}: {
elementType: ExcalidrawElement["type"];
setAppState: React.Component["setState"];
isLibraryOpen: boolean;
}) => (
<>
{SHAPES.map(({ value, icon, key }, index) => {
const label = t(`toolBar.${value}`);
const letter = typeof key === "string" ? key : key[0];
const shortcut = `${capitalizeString(letter)} ${t("helpDialog.or")} ${
index + 1
}`;
return (
{
setAppState({
elementType: value,
multiElement: null,
selectedElementIds: {},
});
setCursorForShape(value);
setAppState({});
}}
/>
);
})}
{
setAppState({ isLibraryOpen: !isLibraryOpen });
}}
/>
>
);
export const ZoomActions = ({
renderAction,
zoom,
}: {
renderAction: ActionManager["renderAction"];
zoom: Zoom;
}) => (
{renderAction("zoomIn")}
{renderAction("zoomOut")}
{renderAction("resetZoom")}
{(zoom.value * 100).toFixed(0)}%
);