diff --git a/src/appState.ts b/src/appState.ts index 0cd2fca0..f0448159 100644 --- a/src/appState.ts +++ b/src/appState.ts @@ -46,6 +46,7 @@ export function getDefaultAppState(): AppState { collaborators: new Map(), shouldCacheIgnoreZoom: false, showShortcutsDialog: false, + zenModeEnabled: false, }; } diff --git a/src/components/App.tsx b/src/components/App.tsx index 0aafef4f..2dbcb800 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -192,6 +192,7 @@ class App extends React.Component { } public render() { + const { zenModeEnabled } = this.state; const canvasDOMWidth = window.innerWidth; const canvasDOMHeight = window.innerHeight; @@ -217,6 +218,8 @@ class App extends React.Component { }); }} onLockToggle={this.toggleLock} + zenModeEnabled={zenModeEnabled} + toggleZenMode={this.toggleZenMode} />
{ })); }; + toggleZenMode = () => { + this.setState({ + zenModeEnabled: !this.state.zenModeEnabled, + }); + }; + private destroySocketClient = () => { this.setState({ isCollaborating: false, @@ -1072,6 +1081,14 @@ class App extends React.Component { }); } + if ( + !event[KEYS.CTRL_OR_CMD] && + event.altKey && + event.keyCode === KEYS.Z_KEY_CODE + ) { + this.toggleZenMode(); + } + if (event.code === "KeyC" && event.altKey && event.shiftKey) { this.copyToClipboardAsPng(); event.preventDefault(); diff --git a/src/components/FixedSideContainer.css b/src/components/FixedSideContainer.css index 3a5fcafb..1e1ab69e 100644 --- a/src/components/FixedSideContainer.css +++ b/src/components/FixedSideContainer.css @@ -15,6 +15,10 @@ z-index: 2; } +.FixedSideContainer_side_top.zen-mode { + right: 42px; +} + /* TODO: if these are used, make sure to implement RTL support .FixedSideContainer_side_left { left: var(--margin); diff --git a/src/components/FixedSideContainer.tsx b/src/components/FixedSideContainer.tsx index cc37144a..ba9b81db 100644 --- a/src/components/FixedSideContainer.tsx +++ b/src/components/FixedSideContainer.tsx @@ -5,14 +5,18 @@ import React from "react"; type FixedSideContainerProps = { children: React.ReactNode; side: "top" | "left" | "right"; + className?: string; }; export function FixedSideContainer({ children, side, + className, }: FixedSideContainerProps) { return ( -
+
{children}
); diff --git a/src/components/Island.css b/src/components/Island.scss similarity index 76% rename from src/components/Island.css rename to src/components/Island.scss index bca91f08..4e246a43 100644 --- a/src/components/Island.css +++ b/src/components/Island.scss @@ -6,4 +6,9 @@ border-radius: var(--border-radius-m); padding: calc(var(--padding) * var(--space-factor)); position: relative; + transition: box-shadow 0.5s ease-in-out; + + &.zen-mode { + box-shadow: none; + } } diff --git a/src/components/Island.tsx b/src/components/Island.tsx index 08ae1c89..60c292b7 100644 --- a/src/components/Island.tsx +++ b/src/components/Island.tsx @@ -1,11 +1,11 @@ -import "./Island.css"; +import "./Island.scss"; import React from "react"; type IslandProps = { children: React.ReactNode; padding?: number; - className?: string; + className?: string | boolean; style?: object; }; diff --git a/src/components/LayerUI.scss b/src/components/LayerUI.scss index 1ffda3c7..790aaf9b 100644 --- a/src/components/LayerUI.scss +++ b/src/components/LayerUI.scss @@ -66,4 +66,48 @@ visibility: visible; } } + + &__github-corner { + top: 0; + right: 0; + position: absolute; + width: 40px; + } + + &__footer { + position: absolute; + bottom: 0px; + right: 0; + width: 190px; + } + + .zen-mode-transition { + transition: transform 0.5s ease-in-out; + &.transition-left { + transform: translate(-999px, 0); + } + &.transition-right { + transform: translate(999px, 0px); + } + } + + .disable-zen-mode { + height: 30px; + position: absolute; + bottom: 10px; + right: 15px; + font-size: 10px; + padding: 10px; + font-weight: 500; + opacity: 0; + visibility: hidden; + transition: visibility 0s linear 0s, opacity 0.5s; + + &--visible { + opacity: 1; + visibility: visible; + transition: visibility 0s linear 300ms, opacity 0.5s; + transition-delay: 0.8s; + } + } } diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx index befac6c2..3af1130b 100644 --- a/src/components/LayerUI.tsx +++ b/src/components/LayerUI.tsx @@ -41,6 +41,8 @@ interface LayerUIProps { onUsernameChange: (username: string) => void; onRoomDestroy: () => void; onLockToggle: () => void; + zenModeEnabled: boolean; + toggleZenMode: () => void; } const LayerUI = ({ @@ -53,6 +55,8 @@ const LayerUI = ({ onUsernameChange, onRoomDestroy, onLockToggle, + zenModeEnabled, + toggleZenMode, }: LayerUIProps) => { const isMobile = useIsMobile(); @@ -112,7 +116,10 @@ const LayerUI = ({ }; const renderCanvasActions = () => ( -
+
{/* the zIndex ensures this menu has higher stacking order, see https://github.com/excalidraw/excalidraw/pull/1445 */} @@ -138,7 +145,10 @@ const LayerUI = ({ ); const renderSelectedShapeActions = () => ( -
+
( - + {heading}
-
- -
- - - - {renderEncryptedIcon()} -
-
-
+ { +
+ +
+ + + + {renderEncryptedIcon()} +
+
+
+ } ); }; const renderFooter = () => ( -
- { - setLanguage(lng); - setAppState({}); - }} - languages={languages} - floating - /> - {actionManager.renderAction("toggleShortcuts")} +
+
+ { + setLanguage(lng); + setAppState({}); + }} + languages={languages} + floating + /> + {actionManager.renderAction("toggleShortcuts")} +
+ {appState.scrolledOutside && (
); diff --git a/src/components/LockIcon.tsx b/src/components/LockIcon.tsx index fcd330fd..3d657ab0 100644 --- a/src/components/LockIcon.tsx +++ b/src/components/LockIcon.tsx @@ -11,6 +11,7 @@ type LockIconProps = { checked: boolean; onChange?(): void; size?: LockIconSize; + zenModeEnabled?: boolean; }; const DEFAULT_SIZE: LockIconSize = "m"; @@ -44,7 +45,9 @@ export function LockIcon(props: LockIconProps) { return (