diff --git a/excalidraw-app/App.tsx b/excalidraw-app/App.tsx index 4e46bb4d06..7f3ad974ac 100644 --- a/excalidraw-app/App.tsx +++ b/excalidraw-app/App.tsx @@ -852,7 +852,7 @@ const ExcalidrawWrapper = () => { return null; } return ( -
+
{collabError.message && } appState.zenModeEnabled, - predicate: (elements, appState, appProps) => { - return typeof appProps.zenModeEnabled === "undefined"; + predicate: (elements, appState, appProps, app) => { + return ( + app.editorInterface.formFactor !== "phone" && + typeof appProps.zenModeEnabled === "undefined" + ); }, keyTest: (event) => !event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === CODES.Z, diff --git a/packages/excalidraw/components/Actions.tsx b/packages/excalidraw/components/Actions.tsx index c5b8d6ae5f..9967ee2c99 100644 --- a/packages/excalidraw/components/Actions.tsx +++ b/packages/excalidraw/components/Actions.tsx @@ -49,6 +49,8 @@ import { getFormValue } from "../actions/actionProperties"; import { useTextEditorFocus } from "../hooks/useTextEditorFocus"; +import { actionToggleViewMode } from "../actions/actionToggleViewMode"; + import { getToolbarTools } from "./shapes"; import "./Actions.scss"; @@ -79,6 +81,7 @@ import { adjustmentsIcon, DotsHorizontalIcon, SelectionIcon, + pencilIcon, } from "./icons"; import { Island } from "./Island"; @@ -1304,7 +1307,7 @@ export const UndoRedoActions = ({
); -export const ExitZenModeAction = ({ +export const ExitZenModeButton = ({ actionManager, showExitZenModeBtn, }: { @@ -1321,3 +1324,17 @@ export const ExitZenModeAction = ({ {t("buttons.exitZenMode")} ); + +export const ExitViewModeButton = ({ + actionManager, +}: { + actionManager: ActionManager; +}) => ( + +); diff --git a/packages/excalidraw/components/LayerUI.scss b/packages/excalidraw/components/LayerUI.scss index 5c202a0679..7ee1469e23 100644 --- a/packages/excalidraw/components/LayerUI.scss +++ b/packages/excalidraw/components/LayerUI.scss @@ -120,4 +120,53 @@ margin-bottom: auto; } } + + .disable-view-mode { + display: flex; + justify-content: center; + cursor: pointer; + align-items: center; + border: 1px solid var(--color-primary); + padding: 0.5rem; + border-radius: var(--border-radius-lg); + background-color: var(--island-bg-color); + text-decoration: none !important; + + font-family: var(--ui-font); + font-size: 0.8333rem; + box-sizing: border-box; + + width: var(--mobile-action-button-size, var(--default-button-size)); + height: var(--mobile-action-button-size, var(--default-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; + } + &:active { + background-color: var(--color-primary-darker); + } + + svg { + width: 20px; + height: 20px; + } + } + + .theme--dark { + .plus-banner { + &:hover { + color: black !important; + } + } + } } diff --git a/packages/excalidraw/components/MobileMenu.tsx b/packages/excalidraw/components/MobileMenu.tsx index 8da02b30b3..ac52fb6bcc 100644 --- a/packages/excalidraw/components/MobileMenu.tsx +++ b/packages/excalidraw/components/MobileMenu.tsx @@ -7,7 +7,7 @@ import { t } from "../i18n"; import { calculateScrollCenter } from "../scene"; import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars"; -import { MobileShapeActions } from "./Actions"; +import { ExitViewModeButton, MobileShapeActions } from "./Actions"; import { MobileToolBar } from "./MobileToolBar"; import { FixedSideContainer } from "./FixedSideContainer"; @@ -65,8 +65,18 @@ export const MobileMenu = ({ DefaultSidebarTriggerTunnel, } = useTunnels(); const renderAppTopBar = () => { - const topRightUI = renderTopRightUI?.(true, appState) ?? ( - + if (appState.openDialog?.name === "elementLinkSelector") { + return null; + } + + const topRightUI = ( +
+ {renderTopRightUI?.(true, appState) ?? + (!appState.viewModeEnabled && )} + {appState.viewModeEnabled && ( + + )} +
); const topLeftUI = ( @@ -76,13 +86,6 @@ export const MobileMenu = ({
); - if ( - appState.viewModeEnabled || - appState.openDialog?.name === "elementLinkSelector" - ) { - return
{topLeftUI}
; - } - return (
}
-
- + {!appState.viewModeEnabled && ( +
+ - - {!appState.viewModeEnabled && - appState.openDialog?.name !== "elementLinkSelector" && - renderToolbar()} - {appState.scrolledOutside && - !appState.openMenu && - !appState.openSidebar && ( - - )} - -
+ + {!appState.viewModeEnabled && + appState.openDialog?.name !== "elementLinkSelector" && + renderToolbar()} + {appState.scrolledOutside && + !appState.openMenu && + !appState.openSidebar && ( + + )} + +
+ )} {renderAppTopBar()} diff --git a/packages/excalidraw/components/MobileToolBar.tsx b/packages/excalidraw/components/MobileToolBar.tsx index bc52c01b71..9cd351d2ee 100644 --- a/packages/excalidraw/components/MobileToolBar.tsx +++ b/packages/excalidraw/components/MobileToolBar.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef } from "react"; +import { useState, useEffect } from "react"; import clsx from "clsx"; import { KEYS, capitalizeString } from "@excalidraw/common"; @@ -101,8 +101,6 @@ export const MobileToolBar = ({ "arrow" | "line" >("arrow"); - const toolbarRef = useRef(null); - // keep lastActiveGenericShape in sync with active tool if user switches via other UI useEffect(() => { if ( @@ -143,8 +141,8 @@ export const MobileToolBar = ({ } }; - const toolbarWidth = - toolbarRef.current?.getBoundingClientRect()?.width ?? 0 - 8; + const [toolbarWidth, setToolbarWidth] = useState(0); + const WIDTH = 36; const GAP = 4; @@ -164,6 +162,9 @@ export const MobileToolBar = ({ "laser", "magicframe", ].filter((tool) => { + if (showTextToolOutside && tool === "text") { + return false; + } if (showImageToolOutside && tool === "image") { return false; } @@ -174,21 +175,30 @@ export const MobileToolBar = ({ }); const extraToolSelected = extraTools.includes(activeTool.type); const extraIcon = extraToolSelected - ? activeTool.type === "frame" + ? activeTool.type === "text" + ? TextIcon + : activeTool.type === "image" + ? ImageIcon + : activeTool.type === "frame" ? frameToolIcon : activeTool.type === "embeddable" ? EmbedIcon : activeTool.type === "laser" ? laserPointerToolIcon - : activeTool.type === "text" - ? TextIcon : activeTool.type === "magicframe" ? MagicIcon : extraToolsIcon : extraToolsIcon; return ( -
+
{ + if (div) { + setToolbarWidth(div.getBoundingClientRect().width); + } + }} + > {/* Hand Tool */}
- diff --git a/packages/excalidraw/components/icons.tsx b/packages/excalidraw/components/icons.tsx index 3f6c4d1bb1..fcc5785598 100644 --- a/packages/excalidraw/components/icons.tsx +++ b/packages/excalidraw/components/icons.tsx @@ -2326,3 +2326,12 @@ export const strokeIcon = createIcon( , tablerIconProps, ); + +export const pencilIcon = createIcon( + + + + + , + tablerIconProps, +); diff --git a/packages/excalidraw/css/styles.scss b/packages/excalidraw/css/styles.scss index c5b2e12550..e1c34b2a12 100644 --- a/packages/excalidraw/css/styles.scss +++ b/packages/excalidraw/css/styles.scss @@ -293,7 +293,8 @@ body.excalidraw-cursor-resize * { } } - .excalidraw-ui-top-left { + .excalidraw-ui-top-left, + .excalidraw-ui-top-right { display: flex; align-items: center; gap: 0.5rem;