import React from "react"; import { Action } from "./types"; import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types"; import { getCommonAttributeOfSelectedElements, isSomeElementSelected, } from "../scene"; import { ButtonSelect } from "../components/ButtonSelect"; import { isTextElement, redrawTextBoundingBox } from "../element"; import { ColorPicker } from "../components/ColorPicker"; import { AppState } from "../../src/types"; import { t } from "../i18n"; 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)) ?? (isSomeElementSelected(elements) ? 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 }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => ( <> 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 }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => ( <> 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, })), appState: { ...appState, currentItemFillStyle: value }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => (
{t("labels.fill")} element.fillStyle, appState.currentItemFillStyle, )} onChange={value => { updateData(value); }} />
), }; export const actionChangeStrokeWidth: Action = { name: "changeStrokeWidth", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, strokeWidth: value, })), appState: { ...appState, currentItemStrokeWidth: value }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => (
{t("labels.strokeWidth")} element.strokeWidth, appState.currentItemStrokeWidth, )} onChange={value => updateData(value)} />
), }; export const actionChangeSloppiness: Action = { name: "changeSloppiness", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, roughness: value, })), appState: { ...appState, currentItemRoughness: value }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => (
{t("labels.sloppiness")} element.roughness, appState.currentItemRoughness, )} onChange={value => updateData(value)} />
), }; export const actionChangeOpacity: Action = { name: "changeOpacity", perform: (elements, appState, value) => { return { elements: changeProperty(elements, el => ({ ...el, shape: null, opacity: value, })), appState: { ...appState, currentItemOpacity: value }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => ( ), }; 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; }), appState: { ...appState, currentItemFont: `${value}px ${ appState.currentItemFont.split("px ")[1] }`, }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => (
{t("labels.fontSize")} isTextElement(element) && +element.font.split("px ")[0], +(appState.currentItemFont || "20px Virgil").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; }), appState: { ...appState, currentItemFont: `${ appState.currentItemFont.split("px ")[0] }px ${value}`, }, }; }, commitToHistory: () => true, PanelComponent: ({ elements, appState, updateData }) => (
{t("labels.fontFamily")} isTextElement(element) && element.font.split("px ")[1], (appState.currentItemFont || "20px Virgil").split("px ")[1], )} onChange={value => updateData(value)} />
), };