Skip to content

Commit 4c08a06

Browse files
committed
mq_stuff
1 parent 4302ce7 commit 4c08a06

File tree

7 files changed

+74
-36
lines changed

7 files changed

+74
-36
lines changed

packages/common/src/utils.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ import {
2424
isAndroid,
2525
isIOS,
2626
WINDOWS_EMOJI_FALLBACK_FONT,
27+
MQ_MAX_HEIGHT_LANDSCAPE,
28+
MQ_MAX_MOBILE,
29+
MQ_MAX_TABLET,
30+
MQ_MAX_WIDTH_LANDSCAPE,
31+
MQ_MIN_TABLET,
2732
} from "./constants";
2833

2934
import type { MaybePromise, ResolutionType } from "./utility-types";
@@ -1338,3 +1343,34 @@ export const isMobileOrTablet = (): boolean => {
13381343
}
13391344
return false;
13401345
};
1346+
1347+
export const getUIMode = ({
1348+
width,
1349+
height,
1350+
}: {
1351+
width: number;
1352+
height: number;
1353+
}) => {
1354+
return isTabletBreakpoint(width, height) && isMobileOrTablet()
1355+
? "compact"
1356+
: isMobileBreakpoint(width, height)
1357+
? "mobile"
1358+
: "full";
1359+
};
1360+
1361+
export const isMobileBreakpoint = (width: number, height: number) => {
1362+
return (
1363+
width <= MQ_MAX_MOBILE ||
1364+
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE)
1365+
);
1366+
};
1367+
1368+
export const isTabletBreakpoint = (
1369+
editorWidth: number,
1370+
editorHeight: number,
1371+
) => {
1372+
const minSide = Math.min(editorWidth, editorHeight);
1373+
const maxSide = Math.max(editorWidth, editorHeight);
1374+
1375+
return minSide >= MQ_MIN_TABLET && maxSide <= MQ_MAX_TABLET;
1376+
};

packages/excalidraw/components/App.tsx

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,10 @@ import {
100100
MINIMUM_ARROW_SIZE,
101101
DOUBLE_TAP_POSITION_THRESHOLD,
102102
isMobileOrTablet,
103-
MQ_MAX_MOBILE,
104-
MQ_MIN_TABLET,
105-
MQ_MAX_TABLET,
106-
MQ_MAX_HEIGHT_LANDSCAPE,
107-
MQ_MAX_WIDTH_LANDSCAPE,
108103
isProdEnv,
104+
isMobileBreakpoint,
105+
isTabletBreakpoint,
106+
getUIMode,
109107
} from "@excalidraw/common";
110108

111109
import {
@@ -2451,20 +2449,6 @@ class App extends React.Component<AppProps, AppState> {
24512449
}
24522450
};
24532451

2454-
private isMobileBreakpoint = (width: number, height: number) => {
2455-
return (
2456-
width <= MQ_MAX_MOBILE ||
2457-
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE)
2458-
);
2459-
};
2460-
2461-
private isTabletBreakpoint = (editorWidth: number, editorHeight: number) => {
2462-
const minSide = Math.min(editorWidth, editorHeight);
2463-
const maxSide = Math.max(editorWidth, editorHeight);
2464-
2465-
return minSide >= MQ_MIN_TABLET && maxSide <= MQ_MAX_TABLET;
2466-
};
2467-
24682452
private refreshViewportBreakpoints = () => {
24692453
const container = this.excalidrawContainerRef.current;
24702454
if (!container) {
@@ -2478,7 +2462,7 @@ class App extends React.Component<AppProps, AppState> {
24782462

24792463
const nextViewportState = updateObject(prevViewportState, {
24802464
isLandscape: editorWidth > editorHeight,
2481-
isMobile: this.isMobileBreakpoint(editorWidth, editorHeight),
2465+
isMobile: isMobileBreakpoint(editorWidth, editorHeight),
24822466
});
24832467

24842468
if (prevViewportState !== nextViewportState) {
@@ -2504,28 +2488,22 @@ class App extends React.Component<AppProps, AppState> {
25042488

25052489
const prevEditorState = this.device.editor;
25062490

2491+
const uiMode =
2492+
this.props.getUIMode?.({ width: editorWidth, height: editorHeight }) ??
2493+
getUIMode({ width: editorWidth, height: editorHeight });
2494+
25072495
const nextEditorState = updateObject(prevEditorState, {
2508-
isMobile: this.isMobileBreakpoint(editorWidth, editorHeight),
2496+
isMobile: uiMode === "mobile",
25092497
canFitSidebar: editorWidth > sidebarBreakpoint,
25102498
});
25112499

2512-
const stylesPanelMode =
2513-
// NOTE: we could also remove the isMobileOrTablet check here and
2514-
// always switch to compact mode when the editor is narrow (e.g. < MQ_MIN_WIDTH_DESKTOP)
2515-
// but not too narrow (> MQ_MAX_WIDTH_MOBILE)
2516-
this.isTabletBreakpoint(editorWidth, editorHeight) && isMobileOrTablet()
2517-
? "compact"
2518-
: this.isMobileBreakpoint(editorWidth, editorHeight)
2519-
? "mobile"
2520-
: "full";
2521-
25222500
// also check if we need to update the app state
25232501
this.setState((prevState) => ({
2524-
stylesPanelMode,
2502+
stylesPanelMode: uiMode,
25252503
// reset to box selection mode if the UI changes to full
25262504
// where you'd not be able to change the mode yourself currently
25272505
preferredSelectionTool:
2528-
stylesPanelMode === "full"
2506+
uiMode === "full"
25292507
? {
25302508
type: "selection",
25312509
initialized: true,

packages/excalidraw/components/LayerUI.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,10 @@ const LayerUI = ({
232232
<div style={{ position: "relative" }}>
233233
{/* wrapping to Fragment stops React from occasionally complaining
234234
about identical Keys */}
235-
<tunnels.MainMenuTunnel.Out />
235+
<div className="excalidraw-ui-top-left">
236+
{renderTopLeftUI?.(false, appState)}
237+
<tunnels.MainMenuTunnel.Out />
238+
</div>
236239
{renderWelcomeScreen && <tunnels.WelcomeScreenMenuHintTunnel.Out />}
237240
</div>
238241
);

packages/excalidraw/components/MobileMenu.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,11 @@ export const MobileMenu = ({
6565
DefaultSidebarTriggerTunnel,
6666
} = useTunnels();
6767
const renderAppTopBar = () => {
68-
const topRightUI = renderTopRightUI?.(true, appState) ?? (
69-
<DefaultSidebarTriggerTunnel.Out />
68+
const topRightUI = (
69+
<div className="excalidraw-ui-top-right">
70+
{renderTopRightUI?.(true, appState)}
71+
<DefaultSidebarTriggerTunnel.Out />
72+
</div>
7073
);
7174

7275
const topLeftUI = (

packages/excalidraw/css/styles.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ body.excalidraw-cursor-resize * {
315315
gap: 0.5rem;
316316
}
317317

318+
.excalidraw-ui-top-right {
319+
display: flex;
320+
align-items: center;
321+
gap: 0.5rem;
322+
}
323+
318324
.App-toolbar-content {
319325
display: flex;
320326
flex-direction: column;

packages/excalidraw/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => {
6161
ui,
6262
interactive,
6363
activeTool,
64+
getUIMode,
6465
} = props;
6566

6667
const canvasActions = props.UIOptions?.canvasActions;
@@ -159,6 +160,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => {
159160
ui={ui}
160161
interactive={interactive}
161162
activeTool={activeTool}
163+
getUIMode={getUIMode}
162164
>
163165
{children}
164166
</App>
@@ -336,3 +338,9 @@ export { duplicateElements, duplicateElement } from "../element/src/duplicate";
336338
export { parseMermaidToExcalidraw } from "@excalidraw/mermaid-to-excalidraw";
337339

338340
export { CommandPalette } from "./components/CommandPalette/CommandPalette";
341+
342+
export {
343+
getUIMode,
344+
isMobileBreakpoint,
345+
isTabletBreakpoint,
346+
} from "@excalidraw/common";

packages/excalidraw/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,10 @@ export interface ExcalidrawProps {
648648
type: "custom";
649649
customType: string;
650650
};
651+
getUIMode?: (editorDimensions: {
652+
width: number;
653+
height: number;
654+
}) => "mobile" | "compact" | "full";
651655
}
652656

653657
export type SceneData = {

0 commit comments

Comments
 (0)