mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-15 02:04:21 +01:00
feat: add toggle to use elbow
This commit is contained in:
@@ -22,6 +22,8 @@ import {
|
|||||||
isDevEnv,
|
isDevEnv,
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
|
import { debugDrawBounds } from "@excalidraw/utils/visualdebug";
|
||||||
|
|
||||||
import type { AppState } from "@excalidraw/excalidraw/types";
|
import type { AppState } from "@excalidraw/excalidraw/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -6,5 +6,19 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
padding-inline: 2.5rem;
|
padding-inline: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-arrow-type {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8;
|
||||||
|
// height: 2rem;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import { EDITOR_LS_KEYS, debounce, isDevEnv } from "@excalidraw/common";
|
|||||||
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";
|
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";
|
||||||
|
|
||||||
import { useApp } from "../App";
|
import { useApp } from "../App";
|
||||||
import { ArrowRightIcon } from "../icons";
|
import { ArrowRightIcon, elbowArrowIcon, roundArrowIcon } from "../icons";
|
||||||
import { EditorLocalStorage } from "../../data/EditorLocalStorage";
|
import { EditorLocalStorage } from "../../data/EditorLocalStorage";
|
||||||
import { t } from "../../i18n";
|
import { t } from "../../i18n";
|
||||||
import Trans from "../Trans";
|
import Trans from "../Trans";
|
||||||
|
|
||||||
|
import { RadioGroup } from "../RadioGroup";
|
||||||
|
|
||||||
import { TTDDialogInput } from "./TTDDialogInput";
|
import { TTDDialogInput } from "./TTDDialogInput";
|
||||||
import { TTDDialogOutput } from "./TTDDialogOutput";
|
import { TTDDialogOutput } from "./TTDDialogOutput";
|
||||||
import { TTDDialogPanel } from "./TTDDialogPanel";
|
import { TTDDialogPanel } from "./TTDDialogPanel";
|
||||||
@@ -43,6 +45,7 @@ const MermaidToExcalidraw = ({
|
|||||||
);
|
);
|
||||||
const deferredText = useDeferredValue(text.trim());
|
const deferredText = useDeferredValue(text.trim());
|
||||||
const [error, setError] = useState<Error | null>(null);
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
const [arrowType, setArrowType] = useState<"arrow" | "elbow">("arrow");
|
||||||
|
|
||||||
const canvasRef = useRef<HTMLDivElement>(null);
|
const canvasRef = useRef<HTMLDivElement>(null);
|
||||||
const data = useRef<{
|
const data = useRef<{
|
||||||
@@ -59,6 +62,7 @@ const MermaidToExcalidraw = ({
|
|||||||
mermaidToExcalidrawLib,
|
mermaidToExcalidrawLib,
|
||||||
setError,
|
setError,
|
||||||
mermaidDefinition: deferredText,
|
mermaidDefinition: deferredText,
|
||||||
|
useElbow: arrowType === "elbow",
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
if (isDevEnv()) {
|
if (isDevEnv()) {
|
||||||
console.error("Failed to parse mermaid definition", err);
|
console.error("Failed to parse mermaid definition", err);
|
||||||
@@ -66,7 +70,7 @@ const MermaidToExcalidraw = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
debouncedSaveMermaidDefinition(deferredText);
|
debouncedSaveMermaidDefinition(deferredText);
|
||||||
}, [deferredText, mermaidToExcalidrawLib]);
|
}, [deferredText, mermaidToExcalidrawLib, arrowType]);
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => () => {
|
() => () => {
|
||||||
@@ -123,6 +127,29 @@ const MermaidToExcalidraw = ({
|
|||||||
icon: ArrowRightIcon,
|
icon: ArrowRightIcon,
|
||||||
}}
|
}}
|
||||||
renderSubmitShortcut={() => <TTDDialogSubmitShortcut />}
|
renderSubmitShortcut={() => <TTDDialogSubmitShortcut />}
|
||||||
|
renderBottomRight={() => (
|
||||||
|
<div className="dialog-mermaid-arrow-type">
|
||||||
|
<RadioGroup
|
||||||
|
name={"mermaid arrow config"}
|
||||||
|
value={arrowType}
|
||||||
|
onChange={(value: "arrow" | "elbow") => {
|
||||||
|
setArrowType(value);
|
||||||
|
}}
|
||||||
|
choices={[
|
||||||
|
{
|
||||||
|
value: "arrow",
|
||||||
|
label: roundArrowIcon,
|
||||||
|
ariaLabel: `${t("labels.arrowtype_round")}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "elbow",
|
||||||
|
label: elbowArrowIcon,
|
||||||
|
ariaLabel: `${t("labels.arrowtype_elbowed")}`,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<TTDDialogOutput
|
<TTDDialogOutput
|
||||||
canvasRef={canvasRef}
|
canvasRef={canvasRef}
|
||||||
|
|||||||
@@ -234,6 +234,11 @@ $verticalBreakpoint: 861px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ttd-dialog-panel-button-container-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.ttd-dialog-panel-button {
|
.ttd-dialog-panel-button {
|
||||||
&.excalidraw-button {
|
&.excalidraw-button {
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
|
|||||||
@@ -42,8 +42,13 @@ export const TTDDialogPanel = ({
|
|||||||
className={clsx("ttd-dialog-panel-button-container", {
|
className={clsx("ttd-dialog-panel-button-container", {
|
||||||
invisible: !panelAction,
|
invisible: !panelAction,
|
||||||
})}
|
})}
|
||||||
style={{ display: "flex", alignItems: "center" }}
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
|
<div className="ttd-dialog-panel-button-container-left">
|
||||||
<Button
|
<Button
|
||||||
className="ttd-dialog-panel-button"
|
className="ttd-dialog-panel-button"
|
||||||
onSelect={panelAction ? panelAction.action : () => {}}
|
onSelect={panelAction ? panelAction.action : () => {}}
|
||||||
@@ -58,6 +63,7 @@ export const TTDDialogPanel = ({
|
|||||||
{!panelActionDisabled &&
|
{!panelActionDisabled &&
|
||||||
!onTextSubmitInProgess &&
|
!onTextSubmitInProgess &&
|
||||||
renderSubmitShortcut?.()}
|
renderSubmitShortcut?.()}
|
||||||
|
</div>
|
||||||
{renderBottomRight?.()}
|
{renderBottomRight?.()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ interface ConvertMermaidToExcalidrawFormatProps {
|
|||||||
elements: readonly NonDeletedExcalidrawElement[];
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
files: BinaryFiles | null;
|
files: BinaryFiles | null;
|
||||||
}>;
|
}>;
|
||||||
|
useElbow?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const convertMermaidToExcalidraw = async ({
|
export const convertMermaidToExcalidraw = async ({
|
||||||
@@ -60,6 +61,7 @@ export const convertMermaidToExcalidraw = async ({
|
|||||||
mermaidDefinition,
|
mermaidDefinition,
|
||||||
setError,
|
setError,
|
||||||
data,
|
data,
|
||||||
|
useElbow = false,
|
||||||
}: ConvertMermaidToExcalidrawFormatProps) => {
|
}: ConvertMermaidToExcalidrawFormatProps) => {
|
||||||
const canvasNode = canvasRef.current;
|
const canvasNode = canvasRef.current;
|
||||||
const parent = canvasNode?.parentElement;
|
const parent = canvasNode?.parentElement;
|
||||||
@@ -90,6 +92,7 @@ export const convertMermaidToExcalidraw = async ({
|
|||||||
data.current = {
|
data.current = {
|
||||||
elements: convertToExcalidrawElements(elements, {
|
elements: convertToExcalidrawElements(elements, {
|
||||||
regenerateIds: true,
|
regenerateIds: true,
|
||||||
|
useElbow,
|
||||||
}),
|
}),
|
||||||
files,
|
files,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ class ElementStore {
|
|||||||
|
|
||||||
export const convertToExcalidrawElements = (
|
export const convertToExcalidrawElements = (
|
||||||
elementsSkeleton: ExcalidrawElementSkeleton[] | null,
|
elementsSkeleton: ExcalidrawElementSkeleton[] | null,
|
||||||
opts?: { regenerateIds: boolean },
|
opts?: { regenerateIds: boolean; useElbow?: boolean },
|
||||||
) => {
|
) => {
|
||||||
if (!elementsSkeleton) {
|
if (!elementsSkeleton) {
|
||||||
return [];
|
return [];
|
||||||
@@ -567,6 +567,7 @@ export const convertToExcalidrawElements = (
|
|||||||
points: [pointFrom(0, 0), pointFrom(width, height)],
|
points: [pointFrom(0, 0), pointFrom(width, height)],
|
||||||
...element,
|
...element,
|
||||||
type: "arrow",
|
type: "arrow",
|
||||||
|
elbowed: opts?.useElbow,
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.assign(
|
Object.assign(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ exports[`Test <MermaidToExcalidraw/> > should open mermaid popup when active too
|
|||||||
B --> C{Let me think}
|
B --> C{Let me think}
|
||||||
C -->|One| D[Laptop]
|
C -->|One| D[Laptop]
|
||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[Car]</textarea><div class="ttd-dialog-panel-button-container invisible" style="display: flex; align-items: center;"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class=""></div></button></div></div><div class="ttd-dialog-panel"><div class="ttd-dialog-panel__header"><label>Preview</label></div><div class="ttd-dialog-output-wrapper"><div style="opacity: 1;" class="ttd-dialog-output-canvas-container"><canvas width="89" height="158" dir="ltr"></canvas></div></div><div class="ttd-dialog-panel-button-container" style="display: flex; align-items: center;"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class="">Insert<span><svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 20 20" class="" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><g stroke-width="1.25"><path d="M4.16602 10H15.8327"></path><path d="M12.5 13.3333L15.8333 10"></path><path d="M12.5 6.66666L15.8333 9.99999"></path></g></svg></span></div></button><div class="ttd-dialog-submit-shortcut"><div class="ttd-dialog-submit-shortcut__key">Ctrl</div><div class="ttd-dialog-submit-shortcut__key">Enter</div></div></div></div></div></div></div></div></div></div></div>"
|
C -->|Three| F[Car]</textarea><div class="ttd-dialog-panel-button-container invisible" style="display: flex; align-items: center; justify-content: space-between;"><div class="ttd-dialog-panel-button-container-left"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class=""></div></button></div></div></div><div class="ttd-dialog-panel"><div class="ttd-dialog-panel__header"><label>Preview</label></div><div class="ttd-dialog-output-wrapper"><div style="opacity: 1;" class="ttd-dialog-output-canvas-container"><canvas width="89" height="158" dir="ltr"></canvas></div></div><div class="ttd-dialog-panel-button-container" style="display: flex; align-items: center; justify-content: space-between;"><div class="ttd-dialog-panel-button-container-left"><button type="button" class="excalidraw-button ttd-dialog-panel-button"><div class="">Insert<span><svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 20 20" class="" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><g stroke-width="1.25"><path d="M4.16602 10H15.8327"></path><path d="M12.5 13.3333L15.8333 10"></path><path d="M12.5 6.66666L15.8333 9.99999"></path></g></svg></span></div></button><div class="ttd-dialog-submit-shortcut"><div class="ttd-dialog-submit-shortcut__key">Ctrl</div><div class="ttd-dialog-submit-shortcut__key">Enter</div></div></div><div class="dialog-mermaid-arrow-type"><div class="RadioGroup"><div class="RadioGroup__choice active" title="Curved arrow"><input aria-label="Curved arrow" type="radio" checked="" name="mermaid arrow config"><svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 24 24" class="" fill="none" stroke-width="2" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><g><path d="M16,12L20,9L16,6"></path><path d="M6 20c0 -6.075 4.925 -11 11 -11h3"></path></g></svg></div><div class="RadioGroup__choice" title="Elbow arrow"><input aria-label="Elbow arrow" type="radio" name="mermaid arrow config"><svg aria-hidden="true" focusable="false" role="img" viewBox="0 0 24 24" class="" fill="none" stroke-width="2" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><g><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4,19L10,19C11.097,19 12,18.097 12,17L12,9C12,7.903 12.903,7 14,7L21,7"></path><path d="M18 4l3 3l-3 3"></path></g></svg></div></div></div></div></div></div></div></div></div></div></div></div>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Test <MermaidToExcalidraw/> > should show error in preview when mermaid library throws error 1`] = `
|
exports[`Test <MermaidToExcalidraw/> > should show error in preview when mermaid library throws error 1`] = `
|
||||||
|
|||||||
Reference in New Issue
Block a user