* feat: new Menu Component API * allow valid children types * introduce menu group to group items * Add lang footer * use display name * displayName * define types inside * fix default menu * add json export to menu * fix * simplify expression * put open menu into own compo to optimize perf So that we don't rerun `useOutsideClickHook` (and rebind event listeners all the time) * naming tweaks * rename MenuComponents->MenuDefaultItems and export default items from Menu.Items * import Menu.scss in Menu.tsx * move menu scss to excal app * Don't filter children inside menu group * move E+ out of socials * support style prop for MenuItem and MenuGroup * Support header in menu group and add Excalidraw links header for default items in social section * rename header to title * fix padding for lang * render menu in mobile * review fixes * tweaks * Export collaborators and show in mobile menu * revert .env * lint :p * again lint * show correct actions in view mode for mobile * Whitelist Collaborators Comp * mobile styling * padding * don't show nerds when menu open in mobile * lint :( * hide shortcuts * refactor userlist to support mobile and keep a wrapper comp for excal app * use only UserList * render only on mobile for default items * remove unused hooks * Show collab button in menu when onCollabButtonClick present and hide export when UIOptions.canvasActions.export is false * fix tests * lint * inject userlist inside menu on mobile * revert userlist * move menu socials to default menu * fix collab * use meny in library * Make Menu generic and create hamburgemenu for public excal menu and use menu in library as well * use appState.openMenu for mobile * fix tests * styling fixes and support style and class name in menu content * fix test * rename MenuDefaultItems->DefaultItems * move footer css to its own comp * rename HamburgerMenu -> MainMenu * rename menu -> dropdownMenu and update classes, onClick->onToggle * close main menu when dialog closes * by bye filtering * update docs * fix lint * update example, docs for useDevice and footer in mobile, rename menu ->DropDownMenu everywhere * spec * remove isMenuOpenAtom and set openMenu as canvas for main menu, render decreases in specs :) * [temp] remove cyclic depenedency to fix build * hack- update appstate to sync lang change * Add more specs * wip: rewrite MainMenu footer * fix margin * fix snaps * not needed as lang list no more imported * simplify custom footer rendering * Add DropdownMenuItemLink and DropdownMenuItemCustom and update API, docs * fix `MainMenu.ItemCustom` * naming * use onSelect and base class for custom items * fix lint * fix snap * use custom item for lang * update docs * fix * properly use `MainMenu.ItemCustom` for `LanguageList` * add margin top to custom items * flex Co-authored-by: dwelle <luzar.david@gmail.com>
175 lines
4.7 KiB
TypeScript
175 lines
4.7 KiB
TypeScript
import clsx from "clsx";
|
|
import { getShortcutFromShortcutName } from "../../actions/shortcuts";
|
|
import { t } from "../../i18n";
|
|
import {
|
|
useExcalidrawAppState,
|
|
useExcalidrawSetAppState,
|
|
useExcalidrawActionManager,
|
|
} from "../App";
|
|
import { ExportIcon, ExportImageIcon, UsersIcon } from "../icons";
|
|
import { GithubIcon, DiscordIcon, TwitterIcon } from "../icons";
|
|
import DropdownMenuItem from "../dropdownMenu/DropdownMenuItem";
|
|
import DropdownMenuItemLink from "../dropdownMenu/DropdownMenuItemLink";
|
|
|
|
export const LoadScene = () => {
|
|
const appState = useExcalidrawAppState();
|
|
const actionManager = useExcalidrawActionManager();
|
|
if (appState.viewModeEnabled) {
|
|
return null;
|
|
}
|
|
return actionManager.renderAction("loadScene");
|
|
};
|
|
LoadScene.displayName = "LoadScene";
|
|
|
|
export const SaveToActiveFile = () => {
|
|
const appState = useExcalidrawAppState();
|
|
const actionManager = useExcalidrawActionManager();
|
|
if (!appState.fileHandle) {
|
|
return null;
|
|
}
|
|
return actionManager.renderAction("saveToActiveFile");
|
|
};
|
|
SaveToActiveFile.displayName = "SaveToActiveFile";
|
|
|
|
export const SaveAsImage = () => {
|
|
const setAppState = useExcalidrawSetAppState();
|
|
// Hack until we tie "t" to lang state
|
|
// eslint-disable-next-line
|
|
const appState = useExcalidrawAppState();
|
|
return (
|
|
<DropdownMenuItem
|
|
icon={ExportImageIcon}
|
|
dataTestId="image-export-button"
|
|
onSelect={() => setAppState({ openDialog: "imageExport" })}
|
|
shortcut={getShortcutFromShortcutName("imageExport")}
|
|
ariaLabel={t("buttons.exportImage")}
|
|
>
|
|
{t("buttons.exportImage")}
|
|
</DropdownMenuItem>
|
|
);
|
|
};
|
|
SaveAsImage.displayName = "SaveAsImage";
|
|
|
|
export const Help = () => {
|
|
// Hack until we tie "t" to lang state
|
|
// eslint-disable-next-line
|
|
const appState = useExcalidrawAppState();
|
|
|
|
const actionManager = useExcalidrawActionManager();
|
|
return actionManager.renderAction("toggleShortcuts", undefined, true);
|
|
};
|
|
Help.displayName = "Help";
|
|
|
|
export const ClearCanvas = () => {
|
|
const appState = useExcalidrawAppState();
|
|
const actionManager = useExcalidrawActionManager();
|
|
|
|
if (appState.viewModeEnabled) {
|
|
return null;
|
|
}
|
|
return actionManager.renderAction("clearCanvas");
|
|
};
|
|
ClearCanvas.displayName = "ClearCanvas";
|
|
|
|
export const ToggleTheme = () => {
|
|
// Hack until we tie "t" to lang state
|
|
// eslint-disable-next-line
|
|
const appState = useExcalidrawAppState();
|
|
const actionManager = useExcalidrawActionManager();
|
|
return actionManager.renderAction("toggleTheme");
|
|
};
|
|
ToggleTheme.displayName = "ToggleTheme";
|
|
|
|
export const ChangeCanvasBackground = () => {
|
|
const appState = useExcalidrawAppState();
|
|
const actionManager = useExcalidrawActionManager();
|
|
|
|
if (appState.viewModeEnabled) {
|
|
return null;
|
|
}
|
|
return (
|
|
<div style={{ marginTop: "0.5rem" }}>
|
|
<div style={{ fontSize: ".75rem", marginBottom: ".5rem" }}>
|
|
{t("labels.canvasBackground")}
|
|
</div>
|
|
<div style={{ padding: "0 0.625rem" }}>
|
|
{actionManager.renderAction("changeViewBackgroundColor")}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
ChangeCanvasBackground.displayName = "ChangeCanvasBackground";
|
|
|
|
export const Export = () => {
|
|
// Hack until we tie "t" to lang state
|
|
// eslint-disable-next-line
|
|
const appState = useExcalidrawAppState();
|
|
const setAppState = useExcalidrawSetAppState();
|
|
return (
|
|
<DropdownMenuItem
|
|
icon={ExportIcon}
|
|
onSelect={() => {
|
|
setAppState({ openDialog: "jsonExport" });
|
|
}}
|
|
dataTestId="json-export-button"
|
|
ariaLabel={t("buttons.export")}
|
|
>
|
|
{t("buttons.export")}
|
|
</DropdownMenuItem>
|
|
);
|
|
};
|
|
Export.displayName = "Export";
|
|
|
|
export const Socials = () => (
|
|
<>
|
|
<DropdownMenuItemLink
|
|
icon={GithubIcon}
|
|
href="https://github.com/excalidraw/excalidraw"
|
|
ariaLabel="GitHub"
|
|
>
|
|
GitHub
|
|
</DropdownMenuItemLink>
|
|
<DropdownMenuItemLink
|
|
icon={DiscordIcon}
|
|
href="https://discord.gg/UexuTaE"
|
|
ariaLabel="Discord"
|
|
>
|
|
Discord
|
|
</DropdownMenuItemLink>
|
|
<DropdownMenuItemLink
|
|
icon={TwitterIcon}
|
|
href="https://twitter.com/excalidraw"
|
|
ariaLabel="Twitter"
|
|
>
|
|
Twitter
|
|
</DropdownMenuItemLink>
|
|
</>
|
|
);
|
|
Socials.displayName = "Socials";
|
|
|
|
export const LiveCollaboration = ({
|
|
onSelect,
|
|
isCollaborating,
|
|
}: {
|
|
onSelect: () => void;
|
|
isCollaborating: boolean;
|
|
}) => {
|
|
// Hack until we tie "t" to lang state
|
|
// eslint-disable-next-line
|
|
const appState = useExcalidrawAppState();
|
|
return (
|
|
<DropdownMenuItem
|
|
dataTestId="collab-button"
|
|
icon={UsersIcon}
|
|
className={clsx({
|
|
"active-collab": isCollaborating,
|
|
})}
|
|
onSelect={onSelect}
|
|
>
|
|
{t("labels.liveCollaboration")}
|
|
</DropdownMenuItem>
|
|
);
|
|
};
|
|
|
|
LiveCollaboration.displayName = "LiveCollaboration";
|