baf9651d34
Co-authored-by: dwelle <luzar.david@gmail.com> Co-authored-by: Antonio Della Fortuna <a.dellafortuna00@gmail.com>
416 lines
13 KiB
TypeScript
416 lines
13 KiB
TypeScript
import React from "react";
|
|
import { t } from "../i18n";
|
|
import { isDarwin, isWindows, KEYS } from "../keys";
|
|
import { Dialog } from "./Dialog";
|
|
import { getShortcutKey } from "../utils";
|
|
import "./HelpDialog.scss";
|
|
import { ExternalLinkIcon } from "./icons";
|
|
|
|
const Header = () => (
|
|
<div className="HelpDialog__header">
|
|
<a
|
|
className="HelpDialog__btn"
|
|
href="https://github.com/excalidraw/excalidraw#documentation"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
{t("helpDialog.documentation")}
|
|
<div className="HelpDialog__link-icon">{ExternalLinkIcon}</div>
|
|
</a>
|
|
<a
|
|
className="HelpDialog__btn"
|
|
href="https://blog.excalidraw.com"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
{t("helpDialog.blog")}
|
|
<div className="HelpDialog__link-icon">{ExternalLinkIcon}</div>
|
|
</a>
|
|
<a
|
|
className="HelpDialog__btn"
|
|
href="https://github.com/excalidraw/excalidraw/issues"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
{t("helpDialog.github")}
|
|
<div className="HelpDialog__link-icon">{ExternalLinkIcon}</div>
|
|
</a>
|
|
</div>
|
|
);
|
|
|
|
const Section = (props: { title: string; children: React.ReactNode }) => (
|
|
<>
|
|
<h3>{props.title}</h3>
|
|
<div className="HelpDialog__islands-container">{props.children}</div>
|
|
</>
|
|
);
|
|
|
|
const ShortcutIsland = (props: {
|
|
caption: string;
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}) => (
|
|
<div className={`HelpDialog__island ${props.className}`}>
|
|
<h4 className="HelpDialog__island-title">{props.caption}</h4>
|
|
<div className="HelpDialog__island-content">{props.children}</div>
|
|
</div>
|
|
);
|
|
|
|
function* intersperse(as: JSX.Element[][], delim: string | null) {
|
|
let first = true;
|
|
for (const x of as) {
|
|
if (!first) {
|
|
yield delim;
|
|
}
|
|
first = false;
|
|
yield x;
|
|
}
|
|
}
|
|
|
|
const Shortcut = ({
|
|
label,
|
|
shortcuts,
|
|
isOr = true,
|
|
}: {
|
|
label: string;
|
|
shortcuts: string[];
|
|
isOr?: boolean;
|
|
}) => {
|
|
const splitShortcutKeys = shortcuts.map((shortcut) => {
|
|
const keys = shortcut.endsWith("++")
|
|
? [...shortcut.slice(0, -2).split("+"), "+"]
|
|
: shortcut.split("+");
|
|
|
|
return keys.map((key) => <ShortcutKey key={key}>{key}</ShortcutKey>);
|
|
});
|
|
|
|
return (
|
|
<div className="HelpDialog__shortcut">
|
|
<div>{label}</div>
|
|
<div className="HelpDialog__key-container">
|
|
{[...intersperse(splitShortcutKeys, isOr ? t("helpDialog.or") : null)]}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const ShortcutKey = (props: { children: React.ReactNode }) => (
|
|
<kbd className="HelpDialog__key" {...props} />
|
|
);
|
|
|
|
export const HelpDialog = ({ onClose }: { onClose?: () => void }) => {
|
|
const handleClose = React.useCallback(() => {
|
|
if (onClose) {
|
|
onClose();
|
|
}
|
|
}, [onClose]);
|
|
|
|
return (
|
|
<>
|
|
<Dialog
|
|
onCloseRequest={handleClose}
|
|
title={t("helpDialog.title")}
|
|
className={"HelpDialog"}
|
|
>
|
|
<Header />
|
|
<Section title={t("helpDialog.shortcuts")}>
|
|
<ShortcutIsland
|
|
className="HelpDialog__island--tools"
|
|
caption={t("helpDialog.tools")}
|
|
>
|
|
<Shortcut
|
|
label={t("toolBar.selection")}
|
|
shortcuts={[KEYS.V, KEYS["1"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.rectangle")}
|
|
shortcuts={[KEYS.R, KEYS["2"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.diamond")}
|
|
shortcuts={[KEYS.D, KEYS["3"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.ellipse")}
|
|
shortcuts={[KEYS.O, KEYS["4"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.arrow")}
|
|
shortcuts={[KEYS.A, KEYS["5"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.line")}
|
|
shortcuts={[KEYS.P, KEYS["6"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.freedraw")}
|
|
shortcuts={["Shift + P", KEYS["7"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.text")}
|
|
shortcuts={[KEYS.T, KEYS["8"]]}
|
|
/>
|
|
<Shortcut label={t("toolBar.image")} shortcuts={[KEYS["9"]]} />
|
|
<Shortcut
|
|
label={t("toolBar.eraser")}
|
|
shortcuts={[KEYS.E, KEYS["0"]]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.editSelectedShape")}
|
|
shortcuts={[getShortcutKey("Enter"), t("helpDialog.doubleClick")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.textNewLine")}
|
|
shortcuts={[
|
|
getShortcutKey("Enter"),
|
|
getShortcutKey("Shift+Enter"),
|
|
]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.textFinish")}
|
|
shortcuts={[
|
|
getShortcutKey("Esc"),
|
|
getShortcutKey("CtrlOrCmd+Enter"),
|
|
]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.curvedArrow")}
|
|
shortcuts={[
|
|
"A",
|
|
t("helpDialog.click"),
|
|
t("helpDialog.click"),
|
|
t("helpDialog.click"),
|
|
]}
|
|
isOr={false}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.curvedLine")}
|
|
shortcuts={[
|
|
"L",
|
|
t("helpDialog.click"),
|
|
t("helpDialog.click"),
|
|
t("helpDialog.click"),
|
|
]}
|
|
isOr={false}
|
|
/>
|
|
<Shortcut label={t("toolBar.lock")} shortcuts={[KEYS.Q]} />
|
|
<Shortcut
|
|
label={t("helpDialog.preventBinding")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("toolBar.link")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+K")]}
|
|
/>
|
|
</ShortcutIsland>
|
|
<ShortcutIsland
|
|
className="HelpDialog__island--view"
|
|
caption={t("helpDialog.view")}
|
|
>
|
|
<Shortcut
|
|
label={t("buttons.zoomIn")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd++")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("buttons.zoomOut")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+-")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("buttons.resetZoom")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+0")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.zoomToFit")}
|
|
shortcuts={["Shift+1"]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.zoomToSelection")}
|
|
shortcuts={["Shift+2"]}
|
|
/>
|
|
<Shortcut label={t("buttons.fullScreen")} shortcuts={["F"]} />
|
|
<Shortcut
|
|
label={t("buttons.zenMode")}
|
|
shortcuts={[getShortcutKey("Alt+Z")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.showGrid")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+'")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.viewMode")}
|
|
shortcuts={[getShortcutKey("Alt+R")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.toggleTheme")}
|
|
shortcuts={[getShortcutKey("Alt+Shift+D")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("stats.title")}
|
|
shortcuts={[getShortcutKey("Alt+/")]}
|
|
/>
|
|
</ShortcutIsland>
|
|
<ShortcutIsland
|
|
className="HelpDialog__island--editor"
|
|
caption={t("helpDialog.editor")}
|
|
>
|
|
<Shortcut
|
|
label={t("labels.selectAll")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+A")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.multiSelect")}
|
|
shortcuts={[getShortcutKey(`Shift+${t("helpDialog.click")}`)]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.deepSelect")}
|
|
shortcuts={[getShortcutKey(`CtrlOrCmd+${t("helpDialog.click")}`)]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.deepBoxSelect")}
|
|
shortcuts={[getShortcutKey(`CtrlOrCmd+${t("helpDialog.drag")}`)]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.moveCanvas")}
|
|
shortcuts={[
|
|
getShortcutKey(`Space+${t("helpDialog.drag")}`),
|
|
getShortcutKey(`Wheel+${t("helpDialog.drag")}`),
|
|
]}
|
|
isOr={true}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.cut")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+X")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.copy")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+C")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.paste")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+V")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.pasteAsPlaintext")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+V")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.copyAsPng")}
|
|
shortcuts={[getShortcutKey("Shift+Alt+C")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.copyStyles")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Alt+C")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.pasteStyles")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Alt+V")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.delete")}
|
|
shortcuts={[getShortcutKey("Delete")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.sendToBack")}
|
|
shortcuts={[
|
|
isDarwin
|
|
? getShortcutKey("CtrlOrCmd+Alt+[")
|
|
: getShortcutKey("CtrlOrCmd+Shift+["),
|
|
]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.bringToFront")}
|
|
shortcuts={[
|
|
isDarwin
|
|
? getShortcutKey("CtrlOrCmd+Alt+]")
|
|
: getShortcutKey("CtrlOrCmd+Shift+]"),
|
|
]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.sendBackward")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+[")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.bringForward")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+]")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.alignTop")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Up")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.alignBottom")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Down")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.alignLeft")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Left")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.alignRight")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Right")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.duplicateSelection")}
|
|
shortcuts={[
|
|
getShortcutKey("CtrlOrCmd+D"),
|
|
getShortcutKey(`Alt+${t("helpDialog.drag")}`),
|
|
]}
|
|
/>
|
|
<Shortcut
|
|
label={t("helpDialog.toggleElementLock")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+L")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("buttons.undo")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Z")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("buttons.redo")}
|
|
shortcuts={
|
|
isWindows
|
|
? [
|
|
getShortcutKey("CtrlOrCmd+Y"),
|
|
getShortcutKey("CtrlOrCmd+Shift+Z"),
|
|
]
|
|
: [getShortcutKey("CtrlOrCmd+Shift+Z")]
|
|
}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.group")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+G")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.ungroup")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+G")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.flipHorizontal")}
|
|
shortcuts={[getShortcutKey("Shift+H")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.flipVertical")}
|
|
shortcuts={[getShortcutKey("Shift+V")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.showStroke")}
|
|
shortcuts={[getShortcutKey("S")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.showBackground")}
|
|
shortcuts={[getShortcutKey("G")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.decreaseFontSize")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+<")]}
|
|
/>
|
|
<Shortcut
|
|
label={t("labels.increaseFontSize")}
|
|
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+>")]}
|
|
/>
|
|
</ShortcutIsland>
|
|
</Section>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
};
|