mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Sync panel props to editing element (#470)
* ensure panel props are sync to editing elem * ensure we don't create empty-text elements (fixes #468) * remove dead code Co-authored-by: Christopher Chedeau <vjeuxx@gmail.com>
This commit is contained in:
parent
ff7a340d2f
commit
2340dddaad
7 changed files with 159 additions and 100 deletions
|
@ -1,10 +1,11 @@
|
|||
import React from "react";
|
||||
import { Action } from "./types";
|
||||
import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types";
|
||||
import { getSelectedAttribute } from "../scene";
|
||||
import { getCommonAttributeOfSelectedElements } from "../scene";
|
||||
import { ButtonSelect } from "../components/ButtonSelect";
|
||||
import { isTextElement, redrawTextBoundingBox } from "../element";
|
||||
import { ColorPicker } from "../components/ColorPicker";
|
||||
import { AppState } from "../../src/types";
|
||||
|
||||
const changeProperty = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
|
@ -18,6 +19,20 @@ const changeProperty = (
|
|||
});
|
||||
};
|
||||
|
||||
const getFormValue = function<T>(
|
||||
editingElement: AppState["editingElement"],
|
||||
elements: readonly ExcalidrawElement[],
|
||||
getAttribute: (element: ExcalidrawElement) => T,
|
||||
defaultValue?: T
|
||||
): T | null {
|
||||
return (
|
||||
(editingElement && getAttribute(editingElement)) ||
|
||||
getCommonAttributeOfSelectedElements(elements, getAttribute) ||
|
||||
defaultValue ||
|
||||
null
|
||||
);
|
||||
};
|
||||
|
||||
export const actionChangeStrokeColor: Action = {
|
||||
name: "changeStrokeColor",
|
||||
perform: (elements, appState, value) => {
|
||||
|
@ -30,21 +45,21 @@ export const actionChangeStrokeColor: Action = {
|
|||
appState: { ...appState, currentItemStrokeColor: value }
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => {
|
||||
return (
|
||||
<>
|
||||
<h5>{t("labels.stroke")}</h5>
|
||||
<ColorPicker
|
||||
type="elementStroke"
|
||||
color={
|
||||
getSelectedAttribute(elements, element => element.strokeColor) ||
|
||||
appState.currentItemStrokeColor
|
||||
}
|
||||
onChange={updateData}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
<>
|
||||
<h5>{t("labels.stroke")}</h5>
|
||||
<ColorPicker
|
||||
type="elementStroke"
|
||||
color={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => element.strokeColor,
|
||||
appState.currentItemStrokeColor
|
||||
)}
|
||||
onChange={updateData}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
||||
export const actionChangeBackgroundColor: Action = {
|
||||
|
@ -64,10 +79,12 @@ export const actionChangeBackgroundColor: Action = {
|
|||
<h5>{t("labels.background")}</h5>
|
||||
<ColorPicker
|
||||
type="elementBackground"
|
||||
color={
|
||||
getSelectedAttribute(elements, element => element.backgroundColor) ||
|
||||
color={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => element.backgroundColor,
|
||||
appState.currentItemBackgroundColor
|
||||
}
|
||||
)}
|
||||
onChange={updateData}
|
||||
/>
|
||||
</>
|
||||
|
@ -85,7 +102,7 @@ export const actionChangeFillStyle: Action = {
|
|||
}))
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
<>
|
||||
<h5>{t("labels.fill")}</h5>
|
||||
<ButtonSelect
|
||||
|
@ -94,7 +111,11 @@ export const actionChangeFillStyle: Action = {
|
|||
{ value: "hachure", text: "Hachure" },
|
||||
{ value: "cross-hatch", text: "Cross-hatch" }
|
||||
]}
|
||||
value={getSelectedAttribute(elements, element => element.fillStyle)}
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => element.fillStyle
|
||||
)}
|
||||
onChange={value => {
|
||||
updateData(value);
|
||||
}}
|
||||
|
@ -123,7 +144,11 @@ export const actionChangeStrokeWidth: Action = {
|
|||
{ value: 2, text: "Bold" },
|
||||
{ value: 4, text: "Extra Bold" }
|
||||
]}
|
||||
value={getSelectedAttribute(elements, element => element.strokeWidth)}
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => element.strokeWidth
|
||||
)}
|
||||
onChange={value => updateData(value)}
|
||||
/>
|
||||
</>
|
||||
|
@ -150,7 +175,11 @@ export const actionChangeSloppiness: Action = {
|
|||
{ value: 1, text: "Artist" },
|
||||
{ value: 3, text: "Cartoonist" }
|
||||
]}
|
||||
value={getSelectedAttribute(elements, element => element.roughness)}
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => element.roughness
|
||||
)}
|
||||
onChange={value => updateData(value)}
|
||||
/>
|
||||
</>
|
||||
|
@ -168,7 +197,7 @@ export const actionChangeOpacity: Action = {
|
|||
}))
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
<>
|
||||
<h5>{t("labels.oppacity")}</h5>
|
||||
<input
|
||||
|
@ -177,8 +206,12 @@ export const actionChangeOpacity: Action = {
|
|||
max="100"
|
||||
onChange={e => updateData(+e.target.value)}
|
||||
value={
|
||||
getSelectedAttribute(elements, element => element.opacity) ||
|
||||
0 /* Put the opacity at 0 if there are two conflicting ones */
|
||||
getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => element.opacity,
|
||||
100 /* default opacity */
|
||||
) || undefined
|
||||
}
|
||||
/>
|
||||
</>
|
||||
|
@ -204,7 +237,7 @@ export const actionChangeFontSize: Action = {
|
|||
})
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
<>
|
||||
<h5>{t("labels.fontSize")}</h5>
|
||||
<ButtonSelect
|
||||
|
@ -214,7 +247,8 @@ export const actionChangeFontSize: Action = {
|
|||
{ value: 28, text: "Large" },
|
||||
{ value: 36, text: "Very Large" }
|
||||
]}
|
||||
value={getSelectedAttribute(
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => isTextElement(element) && +element.font.split("px ")[0]
|
||||
)}
|
||||
|
@ -243,7 +277,7 @@ export const actionChangeFontFamily: Action = {
|
|||
})
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
<>
|
||||
<h5>{t("labels.fontFamily")}</h5>
|
||||
<ButtonSelect
|
||||
|
@ -252,7 +286,8 @@ export const actionChangeFontFamily: Action = {
|
|||
{ value: "Helvetica", text: t("labels.normal") },
|
||||
{ value: "Cascadia", text: t("labels.code") }
|
||||
]}
|
||||
value={getSelectedAttribute(
|
||||
value={getFormValue(
|
||||
appState.editingElement,
|
||||
elements,
|
||||
element => isTextElement(element) && element.font.split("px ")[1]
|
||||
)}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue