From 3fc89b716a2ee9ab80a4fc53638f2ee09ffcf4bc Mon Sep 17 00:00:00 2001 From: Ryan Di Date: Mon, 27 Mar 2023 17:51:31 +0800 Subject: [PATCH] editing single element --- src/components/Stats.scss | 29 +++++- src/components/Stats.tsx | 179 ++++++++++++++++++++++++-------------- 2 files changed, 139 insertions(+), 69 deletions(-) diff --git a/src/components/Stats.scss b/src/components/Stats.scss index a79e3e0e0..da58d9a50 100644 --- a/src/components/Stats.scss +++ b/src/components/Stats.scss @@ -9,8 +9,33 @@ z-index: 10; pointer-events: all; - .section { - padding: 12px; + .sectionContent { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + .elementType { + font-size: 12px; + font-weight: 700; + margin-bottom: 8px; + } + + .statsItem { + margin-bottom: 4px; + display: flex; + align-items: center; + // margin-right: 8px; + + .label { + margin-right: 4px; + width: 10px; + } + + .input { + width: 55px; + } } h3 { diff --git a/src/components/Stats.tsx b/src/components/Stats.tsx index fd608d174..0f53d914e 100644 --- a/src/components/Stats.tsx +++ b/src/components/Stats.tsx @@ -1,7 +1,12 @@ import React from "react"; import { getCommonBounds } from "../element/bounds"; -import { NonDeletedExcalidrawElement } from "../element/types"; +import { mutateElement } from "../element/mutateElement"; +import { + ExcalidrawElement, + NonDeletedExcalidrawElement, +} from "../element/types"; import { t } from "../i18n"; +import { KEYS } from "../keys"; import { getTargetElements } from "../scene"; import { AppState, ExcalidrawProps } from "../types"; import { CloseIcon } from "./icons"; @@ -19,9 +24,45 @@ export const Stats = (props: { const selectedElements = getTargetElements(props.elements, props.appState); const selectedBoundingBox = getCommonBounds(selectedElements); + const stats = + selectedElements.length === 1 + ? [ + { + label: "X", + value: Math.round(selectedBoundingBox[0]), + element: selectedElements[0], + property: "x", + }, + { + label: "Y", + value: Math.round(selectedBoundingBox[1]), + element: selectedElements[0], + property: "y", + }, + { + label: "W", + value: Math.round(selectedBoundingBox[2] - selectedBoundingBox[0]), + element: selectedElements[0], + property: "width", + }, + { + label: "H", + value: Math.round(selectedBoundingBox[3] - selectedBoundingBox[1]), + element: selectedElements[0], + property: "height", + }, + { + label: "A", + value: selectedElements[0].angle, + element: selectedElements[0], + property: "angle", + }, + ] + : []; + return (
- +
{CloseIcon} @@ -54,75 +95,79 @@ export const Stats = (props: {
{selectedElements.length > 0 && ( - <> -
+
+

{t("stats.elementStats")}

-
-

{t("stats.elementStats")}

+
+ {selectedElements.length === 1 && ( +
+ {t(`element.${selectedElements[0].type}`)} +
+ )} - - - {selectedElements.length === 1 && ( - - - - )} +
+ {stats.map((statsItem) => ( +
- - - - - - - - )} - {selectedElements.length > 0 && ( - <> - - - - - - - - - - - - - - - - - - )} - {selectedElements.length === 1 && ( - - - - - )} - -
- {t(`element.${selectedElements[0].type}`)} -
{t("stats.selected")}
{t("stats.elements")}{selectedElements.length}
{"x"}{Math.round(selectedBoundingBox[0])}
{"y"}{Math.round(selectedBoundingBox[1])}
{t("stats.width")} - {Math.round( - selectedBoundingBox[2] - selectedBoundingBox[0], - )} -
{t("stats.height")} - {Math.round( - selectedBoundingBox[3] - selectedBoundingBox[1], - )} -
{t("stats.angle")} - {`${Math.round( - (selectedElements[0].angle * 180) / Math.PI, - )}°`} -
+ if (event.key === KEYS.ENTER) { + if (!isNaN(value)) { + mutateElement(statsItem.element, { + [statsItem.property]: value, + }); + } + + event.target.value = statsItem.element[ + statsItem.property as keyof ExcalidrawElement + ] as string; + } + }} + onBlur={(event) => { + const value = Number(event.target.value); + + if (!isNaN(value)) { + mutateElement(statsItem.element, { + [statsItem.property]: value, + }); + } + + event.target.value = statsItem.element[ + statsItem.property as keyof ExcalidrawElement + ] as string; + }} + > + + ))} +
- +
)}