WelcomeScreen.Center.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import { actionLoadScene, actionShortcuts } from "../../actions";
  2. import { getShortcutFromShortcutName } from "../../actions/shortcuts";
  3. import { t } from "../../i18n";
  4. import {
  5. useDevice,
  6. useExcalidrawActionManager,
  7. useExcalidrawAppState,
  8. } from "../App";
  9. import { ExcalLogo, HelpIcon, LoadIcon, usersIcon } from "../icons";
  10. import { welcomeScreenCenterTunnel } from "../tunnels";
  11. const WelcomeScreenMenuItemContent = ({
  12. icon,
  13. shortcut,
  14. children,
  15. }: {
  16. icon?: JSX.Element;
  17. shortcut?: string | null;
  18. children: React.ReactNode;
  19. }) => {
  20. const device = useDevice();
  21. return (
  22. <>
  23. <div className="welcome-screen-menu-item__icon">{icon}</div>
  24. <div className="welcome-screen-menu-item__text">{children}</div>
  25. {shortcut && !device.isMobile && (
  26. <div className="welcome-screen-menu-item__shortcut">{shortcut}</div>
  27. )}
  28. </>
  29. );
  30. };
  31. WelcomeScreenMenuItemContent.displayName = "WelcomeScreenMenuItemContent";
  32. const WelcomeScreenMenuItem = ({
  33. onSelect,
  34. children,
  35. icon,
  36. shortcut,
  37. className = "",
  38. ...props
  39. }: {
  40. onSelect: () => void;
  41. children: React.ReactNode;
  42. icon?: JSX.Element;
  43. shortcut?: string | null;
  44. } & React.ButtonHTMLAttributes<HTMLButtonElement>) => {
  45. return (
  46. <button
  47. {...props}
  48. type="button"
  49. className={`welcome-screen-menu-item ${className}`}
  50. onClick={onSelect}
  51. >
  52. <WelcomeScreenMenuItemContent icon={icon} shortcut={shortcut}>
  53. {children}
  54. </WelcomeScreenMenuItemContent>
  55. </button>
  56. );
  57. };
  58. WelcomeScreenMenuItem.displayName = "WelcomeScreenMenuItem";
  59. const WelcomeScreenMenuItemLink = ({
  60. children,
  61. href,
  62. icon,
  63. shortcut,
  64. className = "",
  65. ...props
  66. }: {
  67. children: React.ReactNode;
  68. href: string;
  69. icon?: JSX.Element;
  70. shortcut?: string | null;
  71. } & React.AnchorHTMLAttributes<HTMLAnchorElement>) => {
  72. return (
  73. <a
  74. {...props}
  75. className={`welcome-screen-menu-item ${className}`}
  76. href={href}
  77. target="_blank"
  78. rel="noreferrer"
  79. >
  80. <WelcomeScreenMenuItemContent icon={icon} shortcut={shortcut}>
  81. {children}
  82. </WelcomeScreenMenuItemContent>
  83. </a>
  84. );
  85. };
  86. WelcomeScreenMenuItemLink.displayName = "WelcomeScreenMenuItemLink";
  87. const Center = ({ children }: { children?: React.ReactNode }) => {
  88. return (
  89. <welcomeScreenCenterTunnel.In>
  90. <div className="welcome-screen-center">
  91. {children || (
  92. <>
  93. <Logo />
  94. <Heading>{t("welcomeScreen.defaults.center_heading")}</Heading>
  95. <Menu>
  96. <MenuItemLoadScene />
  97. <MenuItemHelp />
  98. </Menu>
  99. </>
  100. )}
  101. </div>
  102. </welcomeScreenCenterTunnel.In>
  103. );
  104. };
  105. Center.displayName = "Center";
  106. const Logo = ({ children }: { children?: React.ReactNode }) => {
  107. return (
  108. <div className="welcome-screen-center__logo virgil welcome-screen-decor">
  109. {children || <>{ExcalLogo} Excalidraw</>}
  110. </div>
  111. );
  112. };
  113. Logo.displayName = "Logo";
  114. const Heading = ({ children }: { children: React.ReactNode }) => {
  115. return (
  116. <div className="welcome-screen-center__heading welcome-screen-decor virgil">
  117. {children}
  118. </div>
  119. );
  120. };
  121. Heading.displayName = "Heading";
  122. const Menu = ({ children }: { children?: React.ReactNode }) => {
  123. return <div className="welcome-screen-menu">{children}</div>;
  124. };
  125. Menu.displayName = "Menu";
  126. const MenuItemHelp = () => {
  127. const actionManager = useExcalidrawActionManager();
  128. return (
  129. <WelcomeScreenMenuItem
  130. onSelect={() => actionManager.executeAction(actionShortcuts)}
  131. shortcut="?"
  132. icon={HelpIcon}
  133. >
  134. {t("helpDialog.title")}
  135. </WelcomeScreenMenuItem>
  136. );
  137. };
  138. MenuItemHelp.displayName = "MenuItemHelp";
  139. const MenuItemLoadScene = () => {
  140. const appState = useExcalidrawAppState();
  141. const actionManager = useExcalidrawActionManager();
  142. if (appState.viewModeEnabled) {
  143. return null;
  144. }
  145. return (
  146. <WelcomeScreenMenuItem
  147. onSelect={() => actionManager.executeAction(actionLoadScene)}
  148. shortcut={getShortcutFromShortcutName("loadScene")}
  149. icon={LoadIcon}
  150. >
  151. {t("buttons.load")}
  152. </WelcomeScreenMenuItem>
  153. );
  154. };
  155. MenuItemLoadScene.displayName = "MenuItemLoadScene";
  156. const MenuItemLiveCollaborationTrigger = ({
  157. onSelect,
  158. }: {
  159. onSelect: () => any;
  160. }) => {
  161. // FIXME when we tie t() to lang state
  162. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  163. const appState = useExcalidrawAppState();
  164. return (
  165. <WelcomeScreenMenuItem shortcut={null} onSelect={onSelect} icon={usersIcon}>
  166. {t("labels.liveCollaboration")}
  167. </WelcomeScreenMenuItem>
  168. );
  169. };
  170. MenuItemLiveCollaborationTrigger.displayName =
  171. "MenuItemLiveCollaborationTrigger";
  172. // -----------------------------------------------------------------------------
  173. Center.Logo = Logo;
  174. Center.Heading = Heading;
  175. Center.Menu = Menu;
  176. Center.MenuItem = WelcomeScreenMenuItem;
  177. Center.MenuItemLink = WelcomeScreenMenuItemLink;
  178. Center.MenuItemHelp = MenuItemHelp;
  179. Center.MenuItemLoadScene = MenuItemLoadScene;
  180. Center.MenuItemLiveCollaborationTrigger = MenuItemLiveCollaborationTrigger;
  181. export { Center };