diff --git a/excalidraw-app/App.tsx b/excalidraw-app/App.tsx index a5d01769cc..ab91d8cc36 100644 --- a/excalidraw-app/App.tsx +++ b/excalidraw-app/App.tsx @@ -137,6 +137,9 @@ import { ExcalidrawPlusIframeExport } from "./ExcalidrawPlusIframeExport"; import "./index.scss"; +import { ExcalidrawPlusAppLink } from "./components/ExcalidrawPlusAppLink"; +import { AppSidebar } from "./components/AppSidebar"; + import type { CollabAPI } from "./collab/Collab"; polyfill(); @@ -850,6 +853,7 @@ const ExcalidrawWrapper = () => { } return (
+ {collabError.message && } { }} /> + + {errorMessage && ( setErrorMessage("")}> {errorMessage} diff --git a/excalidraw-app/components/AppFooter.tsx b/excalidraw-app/components/AppFooter.tsx index 7d42d46bf8..5e2cb27cb3 100644 --- a/excalidraw-app/components/AppFooter.tsx +++ b/excalidraw-app/components/AppFooter.tsx @@ -5,7 +5,6 @@ import { isExcalidrawPlusSignedUser } from "../app_constants"; import { DebugFooter, isVisualDebuggerEnabled } from "./DebugCanvas"; import { EncryptedIcon } from "./EncryptedIcon"; -import { ExcalidrawPlusAppLink } from "./ExcalidrawPlusAppLink"; export const AppFooter = React.memo( ({ onChange }: { onChange: () => void }) => { @@ -19,11 +18,7 @@ export const AppFooter = React.memo( }} > {isVisualDebuggerEnabled() && } - {isExcalidrawPlusSignedUser ? ( - - ) : ( - - )} + {!isExcalidrawPlusSignedUser && }
); diff --git a/excalidraw-app/components/AppSidebar.scss b/excalidraw-app/components/AppSidebar.scss new file mode 100644 index 0000000000..ab3156c2d5 --- /dev/null +++ b/excalidraw-app/components/AppSidebar.scss @@ -0,0 +1,36 @@ +.excalidraw { + .app-sidebar-promo-container { + padding: 0.75rem; + display: flex; + flex-direction: column; + text-align: center; + gap: 1rem; + flex: 1 1 auto; + } + + .app-sidebar-promo-image { + margin: 1rem 0; + + height: 16.25rem; + background-size: contain; + background-position: center; + background-repeat: no-repeat; + + background-image: radial-gradient( + circle, + transparent 60%, + var(--sidebar-bg-color) 100% + ), + var(--image-source); + + display: flex; + } + + .app-sidebar-promo-text { + padding: 0 2rem; + } + + .link-button { + margin: 0 auto; + } +} diff --git a/excalidraw-app/components/AppSidebar.tsx b/excalidraw-app/components/AppSidebar.tsx new file mode 100644 index 0000000000..a722a406ba --- /dev/null +++ b/excalidraw-app/components/AppSidebar.tsx @@ -0,0 +1,73 @@ +import { DefaultSidebar, Sidebar, THEME } from "@excalidraw/excalidraw"; +import { + messageCircleIcon, + presentationIcon, +} from "@excalidraw/excalidraw/components/icons"; +import { LinkButton } from "@excalidraw/excalidraw/components/LinkButton"; +import { useUIAppState } from "@excalidraw/excalidraw/context/ui-appState"; + +import "./AppSidebar.scss"; + +export const AppSidebar = () => { + const { theme } = useUIAppState(); + + return ( + + + + {messageCircleIcon} + + + {presentationIcon} + + + +
+
+
+ Make comments with Excalidraw+ +
+ + Sign up now + +
+ + +
+
+
+ Create presentations with Excalidraw+ +
+ + Sign up now + +
+ + + ); +}; diff --git a/excalidraw-app/components/ExcalidrawPlusAppLink.tsx b/excalidraw-app/components/ExcalidrawPlusAppLink.tsx index 04cd963022..51d856dbfc 100644 --- a/excalidraw-app/components/ExcalidrawPlusAppLink.tsx +++ b/excalidraw-app/components/ExcalidrawPlusAppLink.tsx @@ -1,19 +1,22 @@ -import { isExcalidrawPlusSignedUser } from "../app_constants"; - -export const ExcalidrawPlusAppLink = () => { - if (!isExcalidrawPlusSignedUser) { - return null; - } +export const ExcalidrawPlusAppLink = ({ + isSignedIn, +}: { + isSignedIn: boolean; +}) => { return ( - Go to Excalidraw+ + Excalidraw+ ); }; diff --git a/excalidraw-app/index.scss b/excalidraw-app/index.scss index 9f320775be..aa58d88c05 100644 --- a/excalidraw-app/index.scss +++ b/excalidraw-app/index.scss @@ -1,3 +1,5 @@ +@import "../packages/excalidraw/css/variables.module.scss"; + .excalidraw { --color-primary-contrast-offset: #625ee0; // to offset Chubb illusion @@ -9,6 +11,7 @@ display: flex; justify-content: center; align-items: flex-start; + gap: 0.75rem; } .footer-center { @@ -90,22 +93,31 @@ } } -.plus-button { +.plus-banner { display: flex; justify-content: center; cursor: pointer; align-items: center; border: 1px solid var(--color-primary); - padding: 0.5rem 0.75rem; + padding: 0.5rem 0.875rem; border-radius: var(--border-radius-lg); background-color: var(--island-bg-color); - color: var(--color-primary) !important; text-decoration: none !important; - font-size: 0.75rem; + font-family: var(--ui-font); + font-size: 0.8333rem; box-sizing: border-box; height: var(--lg-button-size); + border: none; + box-shadow: 0 0 0 1px var(--color-surface-lowest); + background-color: var(--color-surface-low); + color: var(--button-color, var(--color-on-surface)) !important; + + &:active { + box-shadow: 0 0 0 1px var(--color-brand-active); + } + &:hover { background-color: var(--color-primary); color: white !important; @@ -117,7 +129,7 @@ } .theme--dark { - .plus-button { + .plus-banner { &:hover { color: black !important; } diff --git a/packages/excalidraw/components/FilledButton.tsx b/packages/excalidraw/components/FilledButton.tsx index 53b30a0469..7d5c4ccfd1 100644 --- a/packages/excalidraw/components/FilledButton.tsx +++ b/packages/excalidraw/components/FilledButton.tsx @@ -20,7 +20,7 @@ export type ButtonColor = export type ButtonSize = "medium" | "large"; export type FilledButtonProps = { - label: string; + label?: string; children?: React.ReactNode; onClick?: (event: React.MouseEvent) => void; diff --git a/packages/excalidraw/components/LayerUI.tsx b/packages/excalidraw/components/LayerUI.tsx index 4fd6f6d269..f7f5a98e6d 100644 --- a/packages/excalidraw/components/LayerUI.tsx +++ b/packages/excalidraw/components/LayerUI.tsx @@ -4,7 +4,6 @@ import React from "react"; import { CLASSES, DEFAULT_SIDEBAR, - MQ_MIN_WIDTH_DESKTOP, TOOL_TYPE, arrayToMap, capitalizeString, @@ -48,7 +47,7 @@ import MainMenu from "./main-menu/MainMenu"; import { ActiveConfirmDialog } from "./ActiveConfirmDialog"; import { useDevice } from "./App"; import { OverwriteConfirmDialog } from "./OverwriteConfirm/OverwriteConfirm"; -import { LibraryIcon } from "./icons"; +import { sidebarRightIcon } from "./icons"; import { DefaultSidebar } from "./DefaultSidebar"; import { TTDDialog } from "./TTDDialog/TTDDialog"; import { Stats } from "./Stats"; @@ -469,7 +468,7 @@ const LayerUI = ({ { if (open) { @@ -481,11 +480,7 @@ const LayerUI = ({ } }} tab={DEFAULT_SIDEBAR.defaultTab} - > - {appState.stylesPanelMode === "full" && - appState.width >= MQ_MIN_WIDTH_DESKTOP && - t("toolBar.library")} - + /> {appState.openDialog?.name === "ttd" && } {/* ------------------------------------------------------------------ */} diff --git a/packages/excalidraw/components/LinkButton.tsx b/packages/excalidraw/components/LinkButton.tsx new file mode 100644 index 0000000000..6c53e2da0a --- /dev/null +++ b/packages/excalidraw/components/LinkButton.tsx @@ -0,0 +1,15 @@ +import { FilledButton } from "./FilledButton"; + +export const LinkButton = ({ + children, + href, +}: { + href: string; + children: React.ReactNode; +}) => { + return ( + + {children} + + ); +}; diff --git a/packages/excalidraw/components/icons.tsx b/packages/excalidraw/components/icons.tsx index 3f6c4d1bb1..be84f087a6 100644 --- a/packages/excalidraw/components/icons.tsx +++ b/packages/excalidraw/components/icons.tsx @@ -2326,3 +2326,41 @@ export const strokeIcon = createIcon( , tablerIconProps, ); + +export const chevronLeftIcon = createIcon( + + + + + , + tablerIconProps, +); + +export const sidebarRightIcon = createIcon( + + + + + , + tablerIconProps, +); + +export const messageCircleIcon = createIcon( + + + + , + tablerIconProps, +); + +export const presentationIcon = createIcon( + + + + + + + + , + tablerIconProps, +); diff --git a/packages/excalidraw/css/styles.scss b/packages/excalidraw/css/styles.scss index c5b2e12550..8ff2d081dd 100644 --- a/packages/excalidraw/css/styles.scss +++ b/packages/excalidraw/css/styles.scss @@ -50,6 +50,11 @@ body.excalidraw-cursor-resize * { height: 100%; width: 100%; + button { + // browser default. Looks kinda good on low-dpi. + font-size: 0.8333rem; + } + button, label { @include buttonNoHighlight; @@ -707,6 +712,11 @@ body.excalidraw-cursor-resize * { margin-top: 0rem; } } + + .link-button { + display: flex; + text-decoration: none !important; + } } .ErrorSplash.excalidraw { diff --git a/public/oss_promo_comments_dark.jpg b/public/oss_promo_comments_dark.jpg new file mode 100644 index 0000000000..e015f8a6b9 Binary files /dev/null and b/public/oss_promo_comments_dark.jpg differ diff --git a/public/oss_promo_comments_light.jpg b/public/oss_promo_comments_light.jpg new file mode 100644 index 0000000000..c8c4507b8e Binary files /dev/null and b/public/oss_promo_comments_light.jpg differ diff --git a/public/oss_promo_presentations_dark.svg b/public/oss_promo_presentations_dark.svg new file mode 100644 index 0000000000..31a0eac6e6 --- /dev/null +++ b/public/oss_promo_presentations_dark.svg @@ -0,0 +1 @@ + diff --git a/public/oss_promo_presentations_light.svg b/public/oss_promo_presentations_light.svg new file mode 100644 index 0000000000..d9e7c93572 --- /dev/null +++ b/public/oss_promo_presentations_light.svg @@ -0,0 +1 @@ +