mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
file & variable renaming
This commit is contained in:
parent
3dc24a9437
commit
e636f84bb6
6 changed files with 111 additions and 138 deletions
|
@ -119,7 +119,7 @@ export const CLASSES = {
|
||||||
SHAPE_ACTIONS_MENU: "App-menu__left",
|
SHAPE_ACTIONS_MENU: "App-menu__left",
|
||||||
ZOOM_ACTIONS: "zoom-actions",
|
ZOOM_ACTIONS: "zoom-actions",
|
||||||
SEARCH_MENU_INPUT_WRAPPER: "layer-ui__search-inputWrapper",
|
SEARCH_MENU_INPUT_WRAPPER: "layer-ui__search-inputWrapper",
|
||||||
SHAPE_SWITCH_PANEL_CLASSNAME: "ShapeSwitch__Panel",
|
CONVERT_ELEMENT_TYPE_POPUP: "ConvertElementTypePopup",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CJK_HAND_DRAWN_FALLBACK_FONT = "Xiaolai";
|
export const CJK_HAND_DRAWN_FALLBACK_FONT = "Xiaolai";
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import type { ExcalidrawElement } from "@excalidraw/element/types";
|
import type { ExcalidrawElement } from "@excalidraw/element/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getSwitchCategoryFromElements,
|
getConversionTypeFromElements,
|
||||||
shapeSwitchAtom,
|
convertElementTypePopupAtom,
|
||||||
} from "../components/ShapeSwitch";
|
} from "../components/ConvertElementTypePopup";
|
||||||
import { editorJotaiStore } from "../editor-jotai";
|
import { editorJotaiStore } from "../editor-jotai";
|
||||||
import { CaptureUpdateAction } from "../store";
|
import { CaptureUpdateAction } from "../store";
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ export const actionToggleShapeSwitch = register({
|
||||||
},
|
},
|
||||||
keywords: ["change", "switch", "swap"],
|
keywords: ["change", "switch", "swap"],
|
||||||
perform(elements, appState, _, app) {
|
perform(elements, appState, _, app) {
|
||||||
editorJotaiStore.set(shapeSwitchAtom, {
|
editorJotaiStore.set(convertElementTypePopupAtom, {
|
||||||
type: "panel",
|
type: "panel",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,5 +30,5 @@ export const actionToggleShapeSwitch = register({
|
||||||
},
|
},
|
||||||
checked: (appState) => appState.gridModeEnabled,
|
checked: (appState) => appState.gridModeEnabled,
|
||||||
predicate: (elements, appState, props) =>
|
predicate: (elements, appState, props) =>
|
||||||
getSwitchCategoryFromElements(elements as ExcalidrawElement[]) !== null,
|
getConversionTypeFromElements(elements as ExcalidrawElement[]) !== null,
|
||||||
});
|
});
|
||||||
|
|
|
@ -468,11 +468,11 @@ import { LassoTrail } from "../lasso";
|
||||||
|
|
||||||
import { EraserTrail } from "../eraser";
|
import { EraserTrail } from "../eraser";
|
||||||
|
|
||||||
import ShapeSwitch, {
|
import ConvertElementTypePopup, {
|
||||||
getSwitchCategoryFromElements,
|
getConversionTypeFromElements,
|
||||||
shapeSwitchAtom,
|
convertElementTypePopupAtom,
|
||||||
switchShapes,
|
convertElementTypes,
|
||||||
} from "./ShapeSwitch";
|
} from "./ConvertElementTypePopup";
|
||||||
|
|
||||||
import { activeConfirmDialogAtom } from "./ActiveConfirmDialog";
|
import { activeConfirmDialogAtom } from "./ActiveConfirmDialog";
|
||||||
import BraveMeasureTextError from "./BraveMeasureTextError";
|
import BraveMeasureTextError from "./BraveMeasureTextError";
|
||||||
|
@ -1599,7 +1599,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
const firstSelectedElement = selectedElements[0];
|
const firstSelectedElement = selectedElements[0];
|
||||||
|
|
||||||
const showShapeSwitchPanel =
|
const showShapeSwitchPanel =
|
||||||
editorJotaiStore.get(shapeSwitchAtom)?.type === "panel";
|
editorJotaiStore.get(convertElementTypePopupAtom)?.type === "panel";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -1875,7 +1875,9 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.renderFrameNames()}
|
{this.renderFrameNames()}
|
||||||
{showShapeSwitchPanel && <ShapeSwitch app={this} />}
|
{showShapeSwitchPanel && (
|
||||||
|
<ConvertElementTypePopup app={this} />
|
||||||
|
)}
|
||||||
</ExcalidrawActionManagerContext.Provider>
|
</ExcalidrawActionManagerContext.Provider>
|
||||||
{this.renderEmbeddables()}
|
{this.renderEmbeddables()}
|
||||||
</ExcalidrawElementsContext.Provider>
|
</ExcalidrawElementsContext.Provider>
|
||||||
|
@ -4178,31 +4180,33 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
|
|
||||||
// Shape switching
|
// Shape switching
|
||||||
if (event.key === KEYS.ESCAPE) {
|
if (event.key === KEYS.ESCAPE) {
|
||||||
this.updateEditorAtom(shapeSwitchAtom, null);
|
this.updateEditorAtom(convertElementTypePopupAtom, null);
|
||||||
} else if (
|
} else if (
|
||||||
event.key === KEYS.TAB &&
|
event.key === KEYS.TAB &&
|
||||||
(document.activeElement === this.excalidrawContainerRef?.current ||
|
(document.activeElement === this.excalidrawContainerRef?.current ||
|
||||||
document.activeElement?.classList.contains(
|
document.activeElement?.classList.contains(
|
||||||
CLASSES.SHAPE_SWITCH_PANEL_CLASSNAME,
|
CLASSES.CONVERT_ELEMENT_TYPE_POPUP,
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const switchCategory =
|
const conversionType =
|
||||||
getSwitchCategoryFromElements(selectedElements);
|
getConversionTypeFromElements(selectedElements);
|
||||||
|
|
||||||
if (editorJotaiStore.get(shapeSwitchAtom)?.type === "panel") {
|
|
||||||
if (
|
if (
|
||||||
switchShapes(this, {
|
editorJotaiStore.get(convertElementTypePopupAtom)?.type === "panel"
|
||||||
switchCategory,
|
) {
|
||||||
|
if (
|
||||||
|
convertElementTypes(this, {
|
||||||
|
conversionType,
|
||||||
direction: event.shiftKey ? "left" : "right",
|
direction: event.shiftKey ? "left" : "right",
|
||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
this.store.shouldCaptureIncrement();
|
this.store.shouldCaptureIncrement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (switchCategory) {
|
if (conversionType) {
|
||||||
this.updateEditorAtom(shapeSwitchAtom, {
|
this.updateEditorAtom(convertElementTypePopupAtom, {
|
||||||
type: "panel",
|
type: "panel",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6418,8 +6422,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
this.updateEditorAtom(searchItemInFocusAtom, null);
|
this.updateEditorAtom(searchItemInFocusAtom, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (editorJotaiStore.get(shapeSwitchAtom)) {
|
if (editorJotaiStore.get(convertElementTypePopupAtom)) {
|
||||||
this.updateEditorAtom(shapeSwitchAtom, null);
|
this.updateEditorAtom(convertElementTypePopupAtom, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// since contextMenu options are potentially evaluated on each render,
|
// since contextMenu options are potentially evaluated on each render,
|
||||||
|
|
18
packages/excalidraw/components/ConvertElementTypePopup.scss
Normal file
18
packages/excalidraw/components/ConvertElementTypePopup.scss
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
@import "../css//variables.module.scss";
|
||||||
|
|
||||||
|
.excalidraw {
|
||||||
|
.ConvertElementTypePopup {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.2rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
background: var(--island-bg-color);
|
||||||
|
box-shadow: var(--shadow-island);
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -76,7 +76,7 @@ import {
|
||||||
import { trackEvent } from "../analytics";
|
import { trackEvent } from "../analytics";
|
||||||
import { atom, editorJotaiStore, useSetAtom } from "../editor-jotai";
|
import { atom, editorJotaiStore, useSetAtom } from "../editor-jotai";
|
||||||
|
|
||||||
import "./ShapeSwitch.scss";
|
import "./ConvertElementTypePopup.scss";
|
||||||
import { ToolButton } from "./ToolButton";
|
import { ToolButton } from "./ToolButton";
|
||||||
import {
|
import {
|
||||||
DiamondIcon,
|
DiamondIcon,
|
||||||
|
@ -124,12 +124,12 @@ const isConvertibleLinearType = (
|
||||||
elementType === "arrow" ||
|
elementType === "arrow" ||
|
||||||
CONVERTIBLE_LINEAR_TYPES.has(elementType as ConvertibleLinearTypes);
|
CONVERTIBLE_LINEAR_TYPES.has(elementType as ConvertibleLinearTypes);
|
||||||
|
|
||||||
export const shapeSwitchAtom = atom<{
|
export const convertElementTypePopupAtom = atom<{
|
||||||
type: "panel";
|
type: "panel";
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
// NOTE doesn't need to be an atom. Review once we integrate with properties panel.
|
// NOTE doesn't need to be an atom. Review once we integrate with properties panel.
|
||||||
export const shapeSwitchFontSizeAtom = atom<{
|
export const fontSize_conversionCacheAtom = atom<{
|
||||||
[id: string]: {
|
[id: string]: {
|
||||||
fontSize: number;
|
fontSize: number;
|
||||||
elementType: ConvertibleGenericTypes;
|
elementType: ConvertibleGenericTypes;
|
||||||
|
@ -137,7 +137,7 @@ export const shapeSwitchFontSizeAtom = atom<{
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
// NOTE doesn't need to be an atom. Review once we integrate with properties panel.
|
// NOTE doesn't need to be an atom. Review once we integrate with properties panel.
|
||||||
export const shapeSwitchLinearAtom = atom<{
|
export const linearElement_conversionCacheAtom = atom<{
|
||||||
[id: string]: {
|
[id: string]: {
|
||||||
properties:
|
properties:
|
||||||
| Partial<ExcalidrawLinearElement>
|
| Partial<ExcalidrawLinearElement>
|
||||||
|
@ -146,40 +146,40 @@ export const shapeSwitchLinearAtom = atom<{
|
||||||
};
|
};
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
const ShapeSwitch = ({ app }: { app: App }) => {
|
const ConvertElementTypePopup = ({ app }: { app: App }) => {
|
||||||
const setShapeSwitchFontSize = useSetAtom(shapeSwitchFontSizeAtom);
|
const setFontSizeCache = useSetAtom(fontSize_conversionCacheAtom);
|
||||||
const setShapeSwitchLinear = useSetAtom(shapeSwitchLinearAtom);
|
const setLinearElementCache = useSetAtom(linearElement_conversionCacheAtom);
|
||||||
|
|
||||||
const selectedElements = app.scene.getSelectedElements(app.state);
|
const selectedElements = app.scene.getSelectedElements(app.state);
|
||||||
const elementsCategoryRef = useRef<SwitchShapeCategory>(null);
|
const elementsCategoryRef = useRef<ConversionType>(null);
|
||||||
|
|
||||||
// close shape switch panel if selecting different "types" of elements
|
// close shape switch panel if selecting different "types" of elements
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedElements.length === 0) {
|
if (selectedElements.length === 0) {
|
||||||
app.updateEditorAtom(shapeSwitchAtom, null);
|
app.updateEditorAtom(convertElementTypePopupAtom, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const switchCategory = getSwitchCategoryFromElements(selectedElements);
|
const conversionType = getConversionTypeFromElements(selectedElements);
|
||||||
|
|
||||||
if (switchCategory && !elementsCategoryRef.current) {
|
if (conversionType && !elementsCategoryRef.current) {
|
||||||
elementsCategoryRef.current = switchCategory;
|
elementsCategoryRef.current = conversionType;
|
||||||
} else if (
|
} else if (
|
||||||
(elementsCategoryRef.current && !switchCategory) ||
|
(elementsCategoryRef.current && !conversionType) ||
|
||||||
(elementsCategoryRef.current &&
|
(elementsCategoryRef.current &&
|
||||||
switchCategory !== elementsCategoryRef.current)
|
conversionType !== elementsCategoryRef.current)
|
||||||
) {
|
) {
|
||||||
app.updateEditorAtom(shapeSwitchAtom, null);
|
app.updateEditorAtom(convertElementTypePopupAtom, null);
|
||||||
elementsCategoryRef.current = null;
|
elementsCategoryRef.current = null;
|
||||||
}
|
}
|
||||||
}, [selectedElements, app]);
|
}, [selectedElements, app]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
setShapeSwitchFontSize(null);
|
setFontSizeCache(null);
|
||||||
setShapeSwitchLinear(null);
|
setLinearElementCache(null);
|
||||||
};
|
};
|
||||||
}, [setShapeSwitchFontSize, setShapeSwitchLinear]);
|
}, [setFontSizeCache, setLinearElementCache]);
|
||||||
|
|
||||||
return <Panel app={app} elements={selectedElements} />;
|
return <Panel app={app} elements={selectedElements} />;
|
||||||
};
|
};
|
||||||
|
@ -191,15 +191,15 @@ const Panel = ({
|
||||||
app: App;
|
app: App;
|
||||||
elements: ExcalidrawElement[];
|
elements: ExcalidrawElement[];
|
||||||
}) => {
|
}) => {
|
||||||
const switchCategory = getSwitchCategoryFromElements(elements);
|
const conversionType = getConversionTypeFromElements(elements);
|
||||||
const generic = switchCategory === "generic";
|
const generic = conversionType === "generic";
|
||||||
const linear = switchCategory === "linear";
|
const linear = conversionType === "linear";
|
||||||
|
|
||||||
const genericElements = useMemo(() => {
|
const genericElements = useMemo(() => {
|
||||||
return generic ? getGenericSwitchableElements(elements) : [];
|
return generic ? filterGenericConvetibleElements(elements) : [];
|
||||||
}, [generic, elements]);
|
}, [generic, elements]);
|
||||||
const linearElements = useMemo(() => {
|
const linearElements = useMemo(() => {
|
||||||
return linear ? getLinearSwitchableElements(elements) : [];
|
return linear ? filterLinearConvertibleElements(elements) : [];
|
||||||
}, [linear, elements]);
|
}, [linear, elements]);
|
||||||
|
|
||||||
const sameType = generic
|
const sameType = generic
|
||||||
|
@ -257,7 +257,7 @@ const Panel = ({
|
||||||
}, [genericElements, linearElements, app.scene, app.state]);
|
}, [genericElements, linearElements, app.scene, app.state]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editorJotaiStore.get(shapeSwitchLinearAtom)) {
|
if (editorJotaiStore.get(linearElement_conversionCacheAtom)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,8 +274,8 @@ const Panel = ({
|
||||||
? getElbowArrowProperties(linearElement)
|
? getElbowArrowProperties(linearElement)
|
||||||
: {};
|
: {};
|
||||||
|
|
||||||
editorJotaiStore.set(shapeSwitchLinearAtom, {
|
editorJotaiStore.set(linearElement_conversionCacheAtom, {
|
||||||
...editorJotaiStore.get(shapeSwitchLinearAtom),
|
...editorJotaiStore.get(linearElement_conversionCacheAtom),
|
||||||
[linearElement.id]: {
|
[linearElement.id]: {
|
||||||
properties: cachedProperties,
|
properties: cachedProperties,
|
||||||
initialType,
|
initialType,
|
||||||
|
@ -285,7 +285,7 @@ const Panel = ({
|
||||||
}, [linearElements]);
|
}, [linearElements]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editorJotaiStore.get(shapeSwitchFontSizeAtom)) {
|
if (editorJotaiStore.get(fontSize_conversionCacheAtom)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,8 +295,8 @@ const Panel = ({
|
||||||
app.scene.getNonDeletedElementsMap(),
|
app.scene.getNonDeletedElementsMap(),
|
||||||
);
|
);
|
||||||
if (boundText) {
|
if (boundText) {
|
||||||
editorJotaiStore.set(shapeSwitchFontSizeAtom, {
|
editorJotaiStore.set(fontSize_conversionCacheAtom, {
|
||||||
...editorJotaiStore.get(shapeSwitchFontSizeAtom),
|
...editorJotaiStore.get(fontSize_conversionCacheAtom),
|
||||||
[element.id]: {
|
[element.id]: {
|
||||||
fontSize: boundText.fontSize,
|
fontSize: boundText.fontSize,
|
||||||
elementType: element.type as ConvertibleGenericTypes,
|
elementType: element.type as ConvertibleGenericTypes,
|
||||||
|
@ -335,7 +335,7 @@ const Panel = ({
|
||||||
left: `${panelPosition.x - app.state.offsetLeft - GAP_HORIZONTAL}px`,
|
left: `${panelPosition.x - app.state.offsetLeft - GAP_HORIZONTAL}px`,
|
||||||
zIndex: 2,
|
zIndex: 2,
|
||||||
}}
|
}}
|
||||||
className={CLASSES.SHAPE_SWITCH_PANEL_CLASSNAME}
|
className={CLASSES.CONVERT_ELEMENT_TYPE_POPUP}
|
||||||
>
|
>
|
||||||
{SHAPES.map(([type, icon]) => {
|
{SHAPES.map(([type, icon]) => {
|
||||||
const isSelected =
|
const isSelected =
|
||||||
|
@ -350,17 +350,17 @@ const Panel = ({
|
||||||
type="radio"
|
type="radio"
|
||||||
icon={icon}
|
icon={icon}
|
||||||
checked={isSelected}
|
checked={isSelected}
|
||||||
name="shape-switch-option"
|
name="convertElementType-option"
|
||||||
title={type}
|
title={type}
|
||||||
keyBindingLabel={""}
|
keyBindingLabel={""}
|
||||||
aria-label={type}
|
aria-label={type}
|
||||||
data-testid={`toolbar-${type}`}
|
data-testid={`toolbar-${type}`}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
if (app.state.activeTool.type !== type) {
|
if (app.state.activeTool.type !== type) {
|
||||||
trackEvent("shape-switch", type, "ui");
|
trackEvent("convertElementType", type, "ui");
|
||||||
}
|
}
|
||||||
switchShapes(app, {
|
convertElementTypes(app, {
|
||||||
switchCategory,
|
conversionType,
|
||||||
nextType: type as
|
nextType: type as
|
||||||
| ConvertibleGenericTypes
|
| ConvertibleGenericTypes
|
||||||
| ConvertibleLinearTypes,
|
| ConvertibleLinearTypes,
|
||||||
|
@ -420,21 +420,21 @@ export const adjustBoundTextSize = (
|
||||||
redrawTextBoundingBox(boundText, container, scene);
|
redrawTextBoundingBox(boundText, container, scene);
|
||||||
};
|
};
|
||||||
|
|
||||||
type SwitchShapeCategory = "generic" | "linear" | null;
|
type ConversionType = "generic" | "linear" | null;
|
||||||
|
|
||||||
export const switchShapes = (
|
export const convertElementTypes = (
|
||||||
app: App,
|
app: App,
|
||||||
{
|
{
|
||||||
switchCategory,
|
conversionType,
|
||||||
nextType,
|
nextType,
|
||||||
direction = "right",
|
direction = "right",
|
||||||
}: {
|
}: {
|
||||||
switchCategory: SwitchShapeCategory;
|
conversionType: ConversionType;
|
||||||
nextType?: ConvertibleTypes;
|
nextType?: ConvertibleTypes;
|
||||||
direction?: "left" | "right";
|
direction?: "left" | "right";
|
||||||
},
|
},
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (!switchCategory) {
|
if (!conversionType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,16 +447,16 @@ export const switchShapes = (
|
||||||
|
|
||||||
const advancement = direction === "right" ? 1 : -1;
|
const advancement = direction === "right" ? 1 : -1;
|
||||||
|
|
||||||
if (switchCategory === "generic") {
|
if (conversionType === "generic") {
|
||||||
const selectedGenericSwitchableElements =
|
const convertibleGenericElements =
|
||||||
getGenericSwitchableElements(selectedElements);
|
filterGenericConvetibleElements(selectedElements);
|
||||||
|
|
||||||
const sameType = selectedGenericSwitchableElements.every(
|
const sameType = convertibleGenericElements.every(
|
||||||
(element) => element.type === selectedGenericSwitchableElements[0].type,
|
(element) => element.type === convertibleGenericElements[0].type,
|
||||||
);
|
);
|
||||||
|
|
||||||
const index = sameType
|
const index = sameType
|
||||||
? GENERIC_TYPES.indexOf(selectedGenericSwitchableElements[0].type)
|
? GENERIC_TYPES.indexOf(convertibleGenericElements[0].type)
|
||||||
: -1;
|
: -1;
|
||||||
|
|
||||||
nextType =
|
nextType =
|
||||||
|
@ -468,7 +468,7 @@ export const switchShapes = (
|
||||||
if (nextType && isConvertibleGenericType(nextType)) {
|
if (nextType && isConvertibleGenericType(nextType)) {
|
||||||
const convertedElements: Record<string, ExcalidrawElement> = {};
|
const convertedElements: Record<string, ExcalidrawElement> = {};
|
||||||
|
|
||||||
for (const element of selectedGenericSwitchableElements) {
|
for (const element of convertibleGenericElements) {
|
||||||
const convertedElement = convertElementType(element, nextType, app);
|
const convertedElement = convertElementType(element, nextType, app);
|
||||||
convertedElements[convertedElement.id] = convertedElement;
|
convertedElements[convertedElement.id] = convertedElement;
|
||||||
}
|
}
|
||||||
|
@ -492,12 +492,12 @@ export const switchShapes = (
|
||||||
);
|
);
|
||||||
if (boundText) {
|
if (boundText) {
|
||||||
if (
|
if (
|
||||||
editorJotaiStore.get(shapeSwitchFontSizeAtom)?.[element.id]
|
editorJotaiStore.get(fontSize_conversionCacheAtom)?.[element.id]
|
||||||
?.elementType === nextType
|
?.elementType === nextType
|
||||||
) {
|
) {
|
||||||
mutateElement(boundText, app.scene.getNonDeletedElementsMap(), {
|
mutateElement(boundText, app.scene.getNonDeletedElementsMap(), {
|
||||||
fontSize:
|
fontSize:
|
||||||
editorJotaiStore.get(shapeSwitchFontSizeAtom)?.[element.id]
|
editorJotaiStore.get(fontSize_conversionCacheAtom)?.[element.id]
|
||||||
?.fontSize ?? boundText.fontSize,
|
?.fontSize ?? boundText.fontSize,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -521,13 +521,13 @@ export const switchShapes = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switchCategory === "linear") {
|
if (conversionType === "linear") {
|
||||||
const selectedLinearSwitchableElements = getLinearSwitchableElements(
|
const convertibleLinearElements = filterLinearConvertibleElements(
|
||||||
selectedElements,
|
selectedElements,
|
||||||
) as ExcalidrawLinearElement[];
|
) as ExcalidrawLinearElement[];
|
||||||
|
|
||||||
const arrowType = getArrowType(selectedLinearSwitchableElements[0]);
|
const arrowType = getArrowType(convertibleLinearElements[0]);
|
||||||
const sameType = selectedLinearSwitchableElements.every(
|
const sameType = convertibleLinearElements.every(
|
||||||
(element) => getArrowType(element) === arrowType,
|
(element) => getArrowType(element) === arrowType,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -540,9 +540,11 @@ export const switchShapes = (
|
||||||
|
|
||||||
if (nextType && isConvertibleLinearType(nextType)) {
|
if (nextType && isConvertibleLinearType(nextType)) {
|
||||||
const convertedElements: Record<string, ExcalidrawElement> = {};
|
const convertedElements: Record<string, ExcalidrawElement> = {};
|
||||||
for (const element of selectedLinearSwitchableElements) {
|
for (const element of convertibleLinearElements) {
|
||||||
const { properties, initialType } =
|
const { properties, initialType } =
|
||||||
editorJotaiStore.get(shapeSwitchLinearAtom)?.[element.id] || {};
|
editorJotaiStore.get(linearElement_conversionCacheAtom)?.[
|
||||||
|
element.id
|
||||||
|
] || {};
|
||||||
|
|
||||||
// If the initial type is not elbow, and when we switch to elbow,
|
// If the initial type is not elbow, and when we switch to elbow,
|
||||||
// the linear line might be "bent" and the points would likely be different.
|
// the linear line might be "bent" and the points would likely be different.
|
||||||
|
@ -597,9 +599,9 @@ export const switchShapes = (
|
||||||
app.scene.replaceAllElements(nextElements);
|
app.scene.replaceAllElements(nextElements);
|
||||||
|
|
||||||
for (const element of Object.values(convertedElements)) {
|
for (const element of Object.values(convertedElements)) {
|
||||||
const cachedLinear = editorJotaiStore.get(shapeSwitchLinearAtom)?.[
|
const cachedLinear = editorJotaiStore.get(
|
||||||
element.id
|
linearElement_conversionCacheAtom,
|
||||||
];
|
)?.[element.id];
|
||||||
|
|
||||||
if (cachedLinear) {
|
if (cachedLinear) {
|
||||||
const { properties, initialType } = cachedLinear;
|
const { properties, initialType } = cachedLinear;
|
||||||
|
@ -642,7 +644,7 @@ export const switchShapes = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const convertedSelectedLinearElements = getLinearSwitchableElements(
|
const convertedSelectedLinearElements = filterLinearConvertibleElements(
|
||||||
app.scene.getSelectedElements(app.state),
|
app.scene.getSelectedElements(app.state),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -664,9 +666,9 @@ export const switchShapes = (
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSwitchCategoryFromElements = (
|
export const getConversionTypeFromElements = (
|
||||||
elements: ExcalidrawElement[],
|
elements: ExcalidrawElement[],
|
||||||
): SwitchShapeCategory => {
|
): ConversionType => {
|
||||||
if (elements.length === 0) {
|
if (elements.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -776,14 +778,14 @@ const getElbowArrowProperties = (
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGenericSwitchableElements = (elements: ExcalidrawElement[]) =>
|
const filterGenericConvetibleElements = (elements: ExcalidrawElement[]) =>
|
||||||
elements.filter((element) => isConvertibleGenericType(element.type)) as Array<
|
elements.filter((element) => isConvertibleGenericType(element.type)) as Array<
|
||||||
| ExcalidrawRectangleElement
|
| ExcalidrawRectangleElement
|
||||||
| ExcalidrawDiamondElement
|
| ExcalidrawDiamondElement
|
||||||
| ExcalidrawEllipseElement
|
| ExcalidrawEllipseElement
|
||||||
>;
|
>;
|
||||||
|
|
||||||
const getLinearSwitchableElements = (elements: ExcalidrawElement[]) =>
|
const filterLinearConvertibleElements = (elements: ExcalidrawElement[]) =>
|
||||||
elements.filter((element) =>
|
elements.filter((element) =>
|
||||||
isEligibleLinearElement(element),
|
isEligibleLinearElement(element),
|
||||||
) as ExcalidrawLinearElement[];
|
) as ExcalidrawLinearElement[];
|
||||||
|
@ -1049,4 +1051,4 @@ const isValidConversion = (
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ShapeSwitch;
|
export default ConvertElementTypePopup;
|
|
@ -1,51 +0,0 @@
|
||||||
@import "../css//variables.module.scss";
|
|
||||||
|
|
||||||
@keyframes disappear {
|
|
||||||
from {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.excalidraw {
|
|
||||||
.ShapeSwitch__Hint {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
opacity: 0;
|
|
||||||
|
|
||||||
.key {
|
|
||||||
background: var(--color-primary-light);
|
|
||||||
padding: 0.4rem 0.8rem;
|
|
||||||
font-weight: bold;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.animation {
|
|
||||||
opacity: 1;
|
|
||||||
animation: disappear 2s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ShapeSwitch__Panel {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 0.2rem;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
background: var(--island-bg-color);
|
|
||||||
box-shadow: var(--shadow-island);
|
|
||||||
padding: 0.5rem;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue