import React from "react"; import { Action } from "./types"; import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types"; 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[], callback: (element: ExcalidrawElement) => ExcalidrawElement, ) => { return elements.map(element => { if (element.isSelected) { return callback(element); } return element; }); }; const getFormValue = function( 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) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, strokeColor: value, })), appState: { ...appState, currentItemStrokeColor: value }, }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.stroke")}
element.strokeColor, appState.currentItemStrokeColor, )} onChange={updateData} /> ), }; export const actionChangeBackgroundColor: Action = { name: "changeBackgroundColor", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, backgroundColor: value, })), appState: { ...appState, currentItemBackgroundColor: value }, }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.background")}
element.backgroundColor, appState.currentItemBackgroundColor, )} onChange={updateData} /> ), }; export const actionChangeFillStyle: Action = { name: "changeFillStyle", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, fillStyle: value, })), }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.fill")}
element.fillStyle, )} onChange={value => { updateData(value); }} /> ), }; export const actionChangeStrokeWidth: Action = { name: "changeStrokeWidth", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, strokeWidth: value, })), }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.strokeWidth")}
element.strokeWidth, )} onChange={value => updateData(value)} /> ), }; export const actionChangeSloppiness: Action = { name: "changeSloppiness", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, roughness: value, })), }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.sloppiness")}
element.roughness, )} onChange={value => updateData(value)} /> ), }; export const actionChangeOpacity: Action = { name: "changeOpacity", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, opacity: value, })), }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.opacity")}
updateData(+e.target.value)} value={ getFormValue( appState.editingElement, elements, element => element.opacity, 100 /* default opacity */, ) ?? undefined } /> ), }; export const actionChangeFontSize: Action = { name: "changeFontSize", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => { if (isTextElement(el)) { const element: ExcalidrawTextElement = { ...el, shape: null, font: `${value}px ${el.font.split("px ")[1]}`, }; redrawTextBoundingBox(element); return element; } return el; }), }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.fontSize")}
isTextElement(element) && +element.font.split("px ")[0], )} onChange={value => updateData(value)} /> ), }; export const actionChangeFontFamily: Action = { name: "changeFontFamily", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => { if (isTextElement(el)) { const element: ExcalidrawTextElement = { ...el, shape: null, font: `${el.font.split("px ")[0]}px ${value}`, }; redrawTextBoundingBox(element); return element; } return el; }), }; }, PanelComponent: ({ elements, appState, updateData, t }) => ( <>
{t("labels.fontFamily")}
isTextElement(element) && element.font.split("px ")[1], )} onChange={value => updateData(value)} /> ), };