feat: use component dimensions to break to mobile (#3414)

Co-authored-by: Jed Fox <git@jedfox.com>
This commit is contained in:
David Luzar 2021-04-08 19:54:50 +02:00 committed by GitHub
parent 016e69b9f2
commit 09dfd16b17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 162 additions and 144 deletions

View File

@ -8,7 +8,7 @@ import { getCommonBounds, getNonDeletedElements } from "../element";
import { newElementWith } from "../element/mutateElement"; import { newElementWith } from "../element/mutateElement";
import { ExcalidrawElement } from "../element/types"; import { ExcalidrawElement } from "../element/types";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { CODES, KEYS } from "../keys"; import { CODES, KEYS } from "../keys";
import { getNormalizedZoom, getSelectedElements } from "../scene"; import { getNormalizedZoom, getSelectedElements } from "../scene";
import { centerScrollOn } from "../scene/scroll"; import { centerScrollOn } from "../scene/scroll";

View File

@ -8,7 +8,7 @@ import { Tooltip } from "../components/Tooltip";
import { DarkModeToggle, Appearence } from "../components/DarkModeToggle"; import { DarkModeToggle, Appearence } from "../components/DarkModeToggle";
import { loadFromJSON, saveAsJSON } from "../data"; import { loadFromJSON, saveAsJSON } from "../data";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { KEYS } from "../keys"; import { KEYS } from "../keys";
import { register } from "./register"; import { register } from "./register";
import { supported } from "browser-fs-access"; import { supported } from "browser-fs-access";

View File

@ -3,7 +3,7 @@ import { ActionManager } from "../actions/manager";
import { getNonDeletedElements } from "../element"; import { getNonDeletedElements } from "../element";
import { ExcalidrawElement } from "../element/types"; import { ExcalidrawElement } from "../element/types";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { import {
canChangeSharpness, canChangeSharpness,
canHaveArrowheads, canHaveArrowheads,

View File

@ -1,5 +1,5 @@
import { Point, simplify } from "points-on-curve"; import { Point, simplify } from "points-on-curve";
import React from "react"; import React, { useContext } from "react";
import { RoughCanvas } from "roughjs/bin/canvas"; import { RoughCanvas } from "roughjs/bin/canvas";
import rough from "roughjs/bin/rough"; import rough from "roughjs/bin/rough";
import clsx from "clsx"; import clsx from "clsx";
@ -54,6 +54,9 @@ import {
GRID_SIZE, GRID_SIZE,
LINE_CONFIRM_THRESHOLD, LINE_CONFIRM_THRESHOLD,
MIME_TYPES, MIME_TYPES,
MQ_MAX_HEIGHT_LANDSCAPE,
MQ_MAX_WIDTH_LANDSCAPE,
MQ_MAX_WIDTH_PORTRAIT,
POINTER_BUTTON, POINTER_BUTTON,
SCROLL_TIMEOUT, SCROLL_TIMEOUT,
TAP_TWICE_TIMEOUT, TAP_TWICE_TIMEOUT,
@ -178,13 +181,15 @@ import {
viewportCoordsToSceneCoords, viewportCoordsToSceneCoords,
withBatchedUpdates, withBatchedUpdates,
} from "../utils"; } from "../utils";
import { isMobile } from "../is-mobile";
import ContextMenu, { ContextMenuOption } from "./ContextMenu"; import ContextMenu, { ContextMenuOption } from "./ContextMenu";
import LayerUI from "./LayerUI"; import LayerUI from "./LayerUI";
import { Stats } from "./Stats"; import { Stats } from "./Stats";
import { Toast } from "./Toast"; import { Toast } from "./Toast";
import { actionToggleViewMode } from "../actions/actionToggleViewMode"; import { actionToggleViewMode } from "../actions/actionToggleViewMode";
export const IsMobileContext = React.createContext(false);
export const useIsMobile = () => useContext(IsMobileContext);
const { history } = createHistory(); const { history } = createHistory();
let didTapTwice: boolean = false; let didTapTwice: boolean = false;
@ -286,6 +291,9 @@ class App extends React.Component<AppProps, AppState> {
rc: RoughCanvas | null = null; rc: RoughCanvas | null = null;
unmounted: boolean = false; unmounted: boolean = false;
actionManager: ActionManager; actionManager: ActionManager;
isMobile = false;
detachIsMobileMqHandler?: () => void;
private excalidrawContainerRef = React.createRef<HTMLDivElement>(); private excalidrawContainerRef = React.createRef<HTMLDivElement>();
public static defaultProps: Partial<AppProps> = { public static defaultProps: Partial<AppProps> = {
@ -437,60 +445,64 @@ class App extends React.Component<AppProps, AppState> {
<div <div
className={clsx("excalidraw", { className={clsx("excalidraw", {
"excalidraw--view-mode": viewModeEnabled, "excalidraw--view-mode": viewModeEnabled,
"excalidraw--mobile": this.isMobile,
})} })}
ref={this.excalidrawContainerRef} ref={this.excalidrawContainerRef}
onDrop={this.handleAppOnDrop} onDrop={this.handleAppOnDrop}
> >
<LayerUI <IsMobileContext.Provider value={this.isMobile}>
canvas={this.canvas} <LayerUI
appState={this.state} canvas={this.canvas}
setAppState={this.setAppState}
actionManager={this.actionManager}
elements={this.scene.getElements()}
onCollabButtonClick={onCollabButtonClick}
onLockToggle={this.toggleLock}
onInsertElements={(elements) =>
this.addElementsFromPasteOrLibrary(
elements,
DEFAULT_PASTE_X,
DEFAULT_PASTE_Y,
)
}
zenModeEnabled={zenModeEnabled}
toggleZenMode={this.toggleZenMode}
langCode={getLanguage().code}
isCollaborating={this.props.isCollaborating || false}
onExportToBackend={onExportToBackend}
renderCustomFooter={renderFooter}
viewModeEnabled={viewModeEnabled}
showExitZenModeBtn={
typeof this.props?.zenModeEnabled === "undefined" && zenModeEnabled
}
showThemeBtn={
typeof this.props?.theme === "undefined" &&
this.props.UIOptions.canvasActions.theme
}
libraryReturnUrl={this.props.libraryReturnUrl}
UIOptions={this.props.UIOptions}
/>
<div className="excalidraw-textEditorContainer" />
<div className="excalidraw-contextMenuContainer" />
{this.state.showStats && (
<Stats
appState={this.state} appState={this.state}
setAppState={this.setAppState} setAppState={this.setAppState}
actionManager={this.actionManager}
elements={this.scene.getElements()} elements={this.scene.getElements()}
onClose={this.toggleStats} onCollabButtonClick={onCollabButtonClick}
renderCustomStats={renderCustomStats} onLockToggle={this.toggleLock}
onInsertElements={(elements) =>
this.addElementsFromPasteOrLibrary(
elements,
DEFAULT_PASTE_X,
DEFAULT_PASTE_Y,
)
}
zenModeEnabled={zenModeEnabled}
toggleZenMode={this.toggleZenMode}
langCode={getLanguage().code}
isCollaborating={this.props.isCollaborating || false}
onExportToBackend={onExportToBackend}
renderCustomFooter={renderFooter}
viewModeEnabled={viewModeEnabled}
showExitZenModeBtn={
typeof this.props?.zenModeEnabled === "undefined" &&
zenModeEnabled
}
showThemeBtn={
typeof this.props?.theme === "undefined" &&
this.props.UIOptions.canvasActions.theme
}
libraryReturnUrl={this.props.libraryReturnUrl}
UIOptions={this.props.UIOptions}
/> />
)} <div className="excalidraw-textEditorContainer" />
{this.state.toastMessage !== null && ( <div className="excalidraw-contextMenuContainer" />
<Toast {this.state.showStats && (
message={this.state.toastMessage} <Stats
clearToast={this.clearToast} appState={this.state}
/> setAppState={this.setAppState}
)} elements={this.scene.getElements()}
<main>{this.renderCanvas()}</main> onClose={this.toggleStats}
renderCustomStats={renderCustomStats}
/>
)}
{this.state.toastMessage !== null && (
<Toast
message={this.state.toastMessage}
clearToast={this.clearToast}
/>
)}
<main>{this.renderCanvas()}</main>
</IsMobileContext.Provider>
</div> </div>
); );
} }
@ -776,10 +788,29 @@ class App extends React.Component<AppProps, AppState> {
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) { if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
this.resizeObserver = new ResizeObserver(() => { this.resizeObserver = new ResizeObserver(() => {
// compute isMobile state
// ---------------------------------------------------------------------
const {
width,
height,
} = this.excalidrawContainerRef.current!.getBoundingClientRect();
this.isMobile =
width < MQ_MAX_WIDTH_PORTRAIT ||
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE);
// refresh offsets
// ---------------------------------------------------------------------
this.updateDOMRect(); this.updateDOMRect();
}); });
this.resizeObserver?.observe(this.excalidrawContainerRef.current); this.resizeObserver?.observe(this.excalidrawContainerRef.current);
} else if (window.matchMedia) {
const mediaQuery = window.matchMedia(
`(max-width: ${MQ_MAX_WIDTH_PORTRAIT}px), (max-height: ${MQ_MAX_HEIGHT_LANDSCAPE}px) and (max-width: ${MQ_MAX_WIDTH_LANDSCAPE}px)`,
);
const handler = () => (this.isMobile = mediaQuery.matches);
mediaQuery.addListener(handler);
this.detachIsMobileMqHandler = () => mediaQuery.removeListener(handler);
} }
const searchParams = new URLSearchParams(window.location.search.slice(1)); const searchParams = new URLSearchParams(window.location.search.slice(1));
if (searchParams.has("web-share-target")) { if (searchParams.has("web-share-target")) {
@ -839,6 +870,8 @@ class App extends React.Component<AppProps, AppState> {
this.onGestureEnd as any, this.onGestureEnd as any,
false, false,
); );
this.detachIsMobileMqHandler?.();
} }
private addEventListeners() { private addEventListeners() {
@ -1016,7 +1049,7 @@ class App extends React.Component<AppProps, AppState> {
}, },
{ {
renderOptimizations: true, renderOptimizations: true,
renderScrollbars: !isMobile(), renderScrollbars: !this.isMobile,
}, },
); );
if (scrollBars) { if (scrollBars) {
@ -3811,8 +3844,6 @@ class App extends React.Component<AppProps, AppState> {
const separator = "separator"; const separator = "separator";
const _isMobile = isMobile();
const elements = this.scene.getElements(); const elements = this.scene.getElements();
const options: ContextMenuOption[] = []; const options: ContextMenuOption[] = [];
@ -3849,7 +3880,7 @@ class App extends React.Component<AppProps, AppState> {
ContextMenu.push({ ContextMenu.push({
options: [ options: [
_isMobile && this.isMobile &&
navigator.clipboard && { navigator.clipboard && {
name: "paste", name: "paste",
perform: (elements, appStates) => { perform: (elements, appStates) => {
@ -3860,7 +3891,7 @@ class App extends React.Component<AppProps, AppState> {
}, },
contextItemLabel: "labels.paste", contextItemLabel: "labels.paste",
}, },
_isMobile && navigator.clipboard && separator, this.isMobile && navigator.clipboard && separator,
probablySupportsClipboardBlob && probablySupportsClipboardBlob &&
elements.length > 0 && elements.length > 0 &&
actionCopyAsPng, actionCopyAsPng,
@ -3903,9 +3934,9 @@ class App extends React.Component<AppProps, AppState> {
ContextMenu.push({ ContextMenu.push({
options: [ options: [
_isMobile && actionCut, this.isMobile && actionCut,
_isMobile && navigator.clipboard && actionCopy, this.isMobile && navigator.clipboard && actionCopy,
_isMobile && this.isMobile &&
navigator.clipboard && { navigator.clipboard && {
name: "paste", name: "paste",
perform: (elements, appStates) => { perform: (elements, appStates) => {
@ -3916,7 +3947,7 @@ class App extends React.Component<AppProps, AppState> {
}, },
contextItemLabel: "labels.paste", contextItemLabel: "labels.paste",
}, },
_isMobile && separator, this.isMobile && separator,
...options, ...options,
separator, separator,
actionCopyStyles, actionCopyStyles,

View File

@ -2,7 +2,7 @@ import React from "react";
import clsx from "clsx"; import clsx from "clsx";
import { ToolButton } from "./ToolButton"; import { ToolButton } from "./ToolButton";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { users } from "./icons"; import { users } from "./icons";
import "./CollabButton.scss"; import "./CollabButton.scss";

View File

@ -218,7 +218,7 @@
left: 2px; left: 2px;
} }
@media #{$is-mobile-query} { @include isMobile {
display: none; display: none;
} }
} }

View File

@ -76,7 +76,7 @@
z-index: 1; z-index: 1;
} }
@media #{$is-mobile-query} { @include isMobile {
.context-menu-option { .context-menu-option {
display: block; display: block;

View File

@ -31,7 +31,7 @@
padding: 0 16px 16px; padding: 0 16px 16px;
} }
@media #{$is-mobile-query} { @include isMobile {
.Dialog { .Dialog {
--metric: calc(var(--space-factor) * 4); --metric: calc(var(--space-factor) * 4);
--inset-left: #{"max(var(--metric), var(--sal))"}; --inset-left: #{"max(var(--metric), var(--sal))"};

View File

@ -2,7 +2,7 @@ import clsx from "clsx";
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useCallbackRefState } from "../hooks/useCallbackRefState"; import { useCallbackRefState } from "../hooks/useCallbackRefState";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { KEYS } from "../keys"; import { KEYS } from "../keys";
import "./Dialog.scss"; import "./Dialog.scss";
import { back, close } from "./icons"; import { back, close } from "./icons";

View File

@ -55,7 +55,7 @@
} }
} }
@media #{$is-mobile-query} { @include isMobile {
.ExportDialog { .ExportDialog {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -6,7 +6,7 @@ import { canvasToBlob } from "../data/blob";
import { NonDeletedExcalidrawElement } from "../element/types"; import { NonDeletedExcalidrawElement } from "../element/types";
import { CanvasError } from "../errors"; import { CanvasError } from "../errors";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { getSelectedElements, isSomeElementSelected } from "../scene"; import { getSelectedElements, isSomeElementSelected } from "../scene";
import { exportToCanvas, getExportSize } from "../scene/export"; import { exportToCanvas, getExportSize } from "../scene/export";
import { AppState } from "../types"; import { AppState } from "../types";

View File

@ -19,7 +19,7 @@ $wide-viewport-width: 1000px;
color: $oc-gray-6; color: $oc-gray-6;
font-size: 0.8rem; font-size: 0.8rem;
@media #{$is-mobile-query} { @include isMobile {
position: static; position: static;
padding-right: 2em; padding-right: 2em;
} }

View File

@ -111,7 +111,7 @@
:root[dir="rtl"] & { :root[dir="rtl"] & {
left: 2px; left: 2px;
} }
@media #{$is-mobile-query} { @include isMobile {
display: none; display: none;
} }
} }

View File

@ -14,7 +14,7 @@ import { Library } from "../data/library";
import { isTextElement, showSelectedShapeActions } from "../element"; import { isTextElement, showSelectedShapeActions } from "../element";
import { NonDeletedExcalidrawElement } from "../element/types"; import { NonDeletedExcalidrawElement } from "../element/types";
import { Language, t } from "../i18n"; import { Language, t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { calculateScrollCenter, getSelectedElements } from "../scene"; import { calculateScrollCenter, getSelectedElements } from "../scene";
import { ExportType } from "../scene/types"; import { ExportType } from "../scene/types";
import { import {

View File

@ -4,7 +4,7 @@ import React, { useEffect, useRef, useState } from "react";
import { close } from "../components/icons"; import { close } from "../components/icons";
import { MIME_TYPES } from "../constants"; import { MIME_TYPES } from "../constants";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { exportToSvg } from "../scene/export"; import { exportToSvg } from "../scene/export";
import { LibraryItem } from "../types"; import { LibraryItem } from "../types";
import "./LibraryUnit.scss"; import "./LibraryUnit.scss";

View File

@ -52,7 +52,7 @@
border-radius: 6px; border-radius: 6px;
box-sizing: border-box; box-sizing: border-box;
@media #{$is-mobile-query} { @include isMobile {
max-width: 100%; max-width: 100%;
border: 0; border: 0;
border-radius: 0; border-radius: 0;
@ -82,7 +82,7 @@
} }
} }
@media #{$is-mobile-query} { @include isMobile {
.Modal { .Modal {
padding: 0; padding: 0;
} }

View File

@ -1,9 +1,10 @@
import "./Modal.scss"; import "./Modal.scss";
import React, { useState, useLayoutEffect } from "react"; import React, { useState, useLayoutEffect, useRef } from "react";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import clsx from "clsx"; import clsx from "clsx";
import { KEYS } from "../keys"; import { KEYS } from "../keys";
import { useIsMobile } from "../components/App";
export const Modal = (props: { export const Modal = (props: {
className?: string; className?: string;
@ -48,6 +49,16 @@ export const Modal = (props: {
const useBodyRoot = () => { const useBodyRoot = () => {
const [div, setDiv] = useState<HTMLDivElement | null>(null); const [div, setDiv] = useState<HTMLDivElement | null>(null);
const isMobile = useIsMobile();
const isMobileRef = useRef(isMobile);
isMobileRef.current = isMobile;
useLayoutEffect(() => {
if (div) {
div.classList.toggle("excalidraw--mobile", isMobile);
}
}, [div, isMobile]);
useLayoutEffect(() => { useLayoutEffect(() => {
const isDarkTheme = !!document const isDarkTheme = !!document
.querySelector(".excalidraw") .querySelector(".excalidraw")
@ -55,6 +66,7 @@ const useBodyRoot = () => {
const div = document.createElement("div"); const div = document.createElement("div");
div.classList.add("excalidraw", "excalidraw-modal-container"); div.classList.add("excalidraw", "excalidraw-modal-container");
div.classList.toggle("excalidraw--mobile", isMobileRef.current);
if (isDarkTheme) { if (isDarkTheme) {
div.classList.add("theme--dark"); div.classList.add("theme--dark");

View File

@ -2,7 +2,7 @@
.excalidraw { .excalidraw {
.PasteChartDialog { .PasteChartDialog {
@media #{$is-mobile-query} { @include isMobile {
.Island { .Island {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -13,7 +13,7 @@
align-items: center; align-items: center;
justify-content: space-around; justify-content: space-around;
flex-wrap: wrap; flex-wrap: wrap;
@media #{$is-mobile-query} { @include isMobile {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
} }

View File

@ -2,7 +2,7 @@ import React from "react";
import { getCommonBounds } from "../element/bounds"; import { getCommonBounds } from "../element/bounds";
import { NonDeletedExcalidrawElement } from "../element/types"; import { NonDeletedExcalidrawElement } from "../element/types";
import { t } from "../i18n"; import { t } from "../i18n";
import { useIsMobile } from "../is-mobile"; import { useIsMobile } from "../components/App";
import { getTargetElements } from "../scene"; import { getTargetElements } from "../scene";
import { AppState, ExcalidrawProps } from "../types"; import { AppState, ExcalidrawProps } from "../types";
import { close } from "./icons"; import { close } from "./icons";

View File

@ -193,7 +193,7 @@
margin-left: 5px; margin-left: 5px;
margin-top: 1px; margin-top: 1px;
@media #{$is-mobile-query} { @include isMobile {
display: none; display: none;
} }
} }

View File

@ -137,3 +137,7 @@ export const DEFAULT_UI_OPTIONS: AppProps["UIOptions"] = {
theme: true, theme: true,
}, },
}; };
export const MQ_MAX_WIDTH_PORTRAIT = 730;
export const MQ_MAX_WIDTH_LANDSCAPE = 1000;
export const MQ_MAX_HEIGHT_LANDSCAPE = 500;

View File

@ -480,7 +480,7 @@
} }
} }
@media #{$is-mobile-query} { @include isMobile {
aside { aside {
display: none; display: none;
} }

View File

@ -1,10 +1,13 @@
@import "open-color/open-color.scss"; @import "open-color/open-color.scss";
// keep up to date with is-mobile.tsx @mixin isMobile() {
$is-mobile-query: "(max-width: 600px), (max-height: 500px) and (max-width: 1000px)"; @at-root .excalidraw--mobile#{&} {
@content;
}
}
$theme-filter: "invert(93%) hue-rotate(180deg)"; $theme-filter: "invert(93%) hue-rotate(180deg)";
:export { :export {
isMobileQuery: unquote($is-mobile-query);
themeFilter: unquote($theme-filter); themeFilter: unquote($theme-filter);
} }

View File

@ -32,13 +32,13 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@media #{$is-mobile-query} { @include isMobile {
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
} }
} }
@media #{$is-mobile-query} { @include isMobile {
.RoomDialog-usernameLabel { .RoomDialog-usernameLabel {
font-weight: bold; font-weight: bold;
} }
@ -51,7 +51,7 @@
min-width: 0; min-width: 0;
flex: 1 1 auto; flex: 1 1 auto;
margin-inline-start: 1em; margin-inline-start: 1em;
@media #{$is-mobile-query} { @include isMobile {
margin-top: 0.5em; margin-top: 0.5em;
margin-inline-start: 0; margin-inline-start: 0;
} }

View File

@ -1,37 +0,0 @@
import React, { useState, useEffect, useRef, useContext } from "react";
import variables from "./css/variables.module.scss";
const context = React.createContext(false);
const getIsMobileMatcher = () => {
return window.matchMedia
? window.matchMedia(variables.isMobileQuery)
: (({
matches: false,
addListener: () => {},
removeListener: () => {},
} as any) as MediaQueryList);
};
export const IsMobileProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const query = useRef<MediaQueryList>();
if (!query.current) {
query.current = getIsMobileMatcher();
}
const [isMobile, setMobile] = useState(query.current.matches);
useEffect(() => {
const handler = () => setMobile(query.current!.matches);
query.current!.addListener(handler);
return () => query.current!.removeListener(handler);
}, []);
return <context.Provider value={isMobile}>{children}</context.Provider>;
};
export const isMobile = () => getIsMobileMatcher().matches;
export const useIsMobile = () => useContext(context);

View File

@ -11,6 +11,14 @@ The change should be grouped under one of the below section and must contain PR
Please add the latest change on the top under the correct section. Please add the latest change on the top under the correct section.
--> -->
## Unreleased
## Excalidraw Library
### Features
- App now breaks into mobile view using the component dimensions, not viewport dimensions. This fixes a case where the app would break sooner than necessary when the component's size is smaller than viewport [#3414](https://github.com/excalidraw/excalidraw/pull/3414).
## 0.6.0 (2021-04-04) ## 0.6.0 (2021-04-04)
## Excalidraw API ## Excalidraw API

View File

@ -8,7 +8,6 @@ import "../../css/app.scss";
import "../../css/styles.scss"; import "../../css/styles.scss";
import { ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types"; import { ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types";
import { IsMobileProvider } from "../../is-mobile";
import { defaultLang } from "../../i18n"; import { defaultLang } from "../../i18n";
import { DEFAULT_UI_OPTIONS } from "../../constants"; import { DEFAULT_UI_OPTIONS } from "../../constants";
@ -61,27 +60,25 @@ const Excalidraw = (props: ExcalidrawProps) => {
return ( return (
<InitializeApp langCode={langCode}> <InitializeApp langCode={langCode}>
<IsMobileProvider> <App
<App onChange={onChange}
onChange={onChange} initialData={initialData}
initialData={initialData} excalidrawRef={excalidrawRef}
excalidrawRef={excalidrawRef} onCollabButtonClick={onCollabButtonClick}
onCollabButtonClick={onCollabButtonClick} isCollaborating={isCollaborating}
isCollaborating={isCollaborating} onPointerUpdate={onPointerUpdate}
onPointerUpdate={onPointerUpdate} onExportToBackend={onExportToBackend}
onExportToBackend={onExportToBackend} renderFooter={renderFooter}
renderFooter={renderFooter} langCode={langCode}
langCode={langCode} viewModeEnabled={viewModeEnabled}
viewModeEnabled={viewModeEnabled} zenModeEnabled={zenModeEnabled}
zenModeEnabled={zenModeEnabled} gridModeEnabled={gridModeEnabled}
gridModeEnabled={gridModeEnabled} libraryReturnUrl={libraryReturnUrl}
libraryReturnUrl={libraryReturnUrl} theme={theme}
theme={theme} name={name}
name={name} renderCustomStats={renderCustomStats}
renderCustomStats={renderCustomStats} UIOptions={UIOptions}
UIOptions={UIOptions} />
/>
</IsMobileProvider>
</InitializeApp> </InitializeApp>
); );
}; };