mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
build: decouple package deps and introduce yarn workspaces (#7415)
* feat: decouple package deps and introduce yarn workspaces * update root directory * fix * fix scripts * fix lint * update path in scripts * remove yarn.lock files from packages * ignore workspace * dummy * dummy * remove comment check * revert workflow changes * ignore ws when installing gh actions * remove log * update path * fix * fix typo
This commit is contained in:
parent
b7d7ccc929
commit
d6cd8b78f1
567 changed files with 5066 additions and 8648 deletions
453
packages/excalidraw/components/HelpDialog.tsx
Normal file
453
packages/excalidraw/components/HelpDialog.tsx
Normal file
|
@ -0,0 +1,453 @@
|
|||
import React from "react";
|
||||
import { t } from "../i18n";
|
||||
import { KEYS } from "../keys";
|
||||
import { Dialog } from "./Dialog";
|
||||
import { getShortcutKey } from "../utils";
|
||||
import "./HelpDialog.scss";
|
||||
import { ExternalLinkIcon } from "./icons";
|
||||
import { probablySupportsClipboardBlob } from "../clipboard";
|
||||
import { isDarwin, isFirefox, isWindows } from "../constants";
|
||||
|
||||
const Header = () => (
|
||||
<div className="HelpDialog__header">
|
||||
<a
|
||||
className="HelpDialog__btn"
|
||||
href="https://docs.excalidraw.com"
|
||||
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 upperCaseSingleChars = (str: string) => {
|
||||
return str.replace(/\b[a-z]\b/, (c) => c.toUpperCase());
|
||||
};
|
||||
|
||||
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}>{upperCaseSingleChars(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.hand")} shortcuts={[KEYS.H]} />
|
||||
<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.L, KEYS["6"]]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("toolBar.freedraw")}
|
||||
shortcuts={[KEYS.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("toolBar.frame")} shortcuts={[KEYS.F]} />
|
||||
<Shortcut label={t("toolBar.laser")} shortcuts={[KEYS.K]} />
|
||||
<Shortcut
|
||||
label={t("labels.eyeDropper")}
|
||||
shortcuts={[KEYS.I, "Shift+S", "Shift+G"]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("helpDialog.editLineArrowPoints")}
|
||||
shortcuts={[getShortcutKey("CtrlOrCmd+Enter")]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("helpDialog.editText")}
|
||||
shortcuts={[getShortcutKey("Enter")]}
|
||||
/>
|
||||
<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("helpDialog.movePageUpDown")}
|
||||
shortcuts={["PgUp/PgDn"]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("helpDialog.movePageLeftRight")}
|
||||
shortcuts={["Shift+PgUp/PgDn"]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("buttons.zenMode")}
|
||||
shortcuts={[getShortcutKey("Alt+Z")]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("buttons.objectsSnapMode")}
|
||||
shortcuts={[getShortcutKey("Alt+S")]}
|
||||
/>
|
||||
<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.moveCanvas")}
|
||||
shortcuts={[
|
||||
getShortcutKey(`Space+${t("helpDialog.drag")}`),
|
||||
getShortcutKey(`Wheel+${t("helpDialog.drag")}`),
|
||||
]}
|
||||
isOr={true}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("buttons.clearReset")}
|
||||
shortcuts={[getShortcutKey("CtrlOrCmd+Delete")]}
|
||||
/>
|
||||
<Shortcut
|
||||
label={t("labels.delete")}
|
||||
shortcuts={[getShortcutKey("Delete")]}
|
||||
/>
|
||||
<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.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")}`)]}
|
||||
/>
|
||||
{/* firefox supports clipboard API under a flag, so we'll
|
||||
show users what they can do in the error message */}
|
||||
{(probablySupportsClipboardBlob || isFirefox) && (
|
||||
<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.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>
|
||||
</>
|
||||
);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue