Skip to content

Commit

Permalink
custom
Browse files Browse the repository at this point in the history
  • Loading branch information
dwelle committed Jun 15, 2022
1 parent 5feacd9 commit 3bc9664
Show file tree
Hide file tree
Showing 27 changed files with 346 additions and 260 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"prettier": "@excalidraw/prettier-config",
"private": true,
"scripts": {
"setup": "yarn && cd src/packages/excalidraw && yarn",
"build-node": "node ./scripts/build-node.js",
"build:app:docker": "REACT_APP_DISABLE_SENTRY=true react-scripts build",
"build:app": "REACT_APP_GIT_SHA=$VERCEL_GIT_COMMIT_SHA react-scripts build",
Expand All @@ -112,6 +113,8 @@
"test:typecheck": "tsc",
"test:update": "yarn test:app --updateSnapshot --watchAll=false",
"test": "yarn test:app",
"autorelease": "node scripts/autorelease.js"
"autorelease": "node scripts/autorelease.js",
"pull": "git pull upstream master --rebase",
"publish": "cd src/packages/excalidraw && npm run build:umd && yarn publish"
}
}
4 changes: 2 additions & 2 deletions src/actions/manager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export class ActionManager {
.sort((a, b) => (b.keyPriority || 0) - (a.keyPriority || 0))
.filter(
(action) =>
(action.name in canvasActions
(canvasActions && action.name in canvasActions
? canvasActions[action.name as keyof typeof canvasActions]
: true) &&
action.keyTest &&
Expand Down Expand Up @@ -141,7 +141,7 @@ export class ActionManager {
if (
this.actions[name] &&
"PanelComponent" in this.actions[name] &&
(name in canvasActions
(canvasActions && name in canvasActions
? canvasActions[name as keyof typeof canvasActions]
: true)
) {
Expand Down
48 changes: 46 additions & 2 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,10 @@ import {
} from "../keys";
import { distance2d, getGridPoint, isPathALoop } from "../math";
import { renderScene } from "../renderer";
import { invalidateShapeForElement } from "../renderer/renderElement";
import {
clearRenderCache,
invalidateShapeForElement,
} from "../renderer/renderElement";
import {
calculateScrollCenter,
getTextBindableContainerAtPosition,
Expand Down Expand Up @@ -267,7 +270,7 @@ const DeviceTypeContext = React.createContext(defaultDeviceTypeContext);
export const useDeviceType = () => useContext(DeviceTypeContext);
const ExcalidrawContainerContext = React.createContext<{
container: HTMLDivElement | null;
id: string | null;
id?: string | null;
}>({ container: null, id: null });
export const useExcalidrawContainer = () =>
useContext(ExcalidrawContainerContext);
Expand Down Expand Up @@ -385,6 +388,7 @@ class App extends React.Component<AppProps, AppState> {
setActiveTool: this.setActiveTool,
setCursor: this.setCursor,
resetCursor: this.resetCursor,
app: this,
} as const;
if (typeof excalidrawRef === "function") {
excalidrawRef(api);
Expand Down Expand Up @@ -484,6 +488,7 @@ class App extends React.Component<AppProps, AppState> {
return (
<div
className={clsx("excalidraw excalidraw-container", {
"excalidraw--zen-mode": zenModeEnabled,
"excalidraw--view-mode": viewModeEnabled,
"excalidraw--mobile": this.deviceType.isMobile,
})}
Expand All @@ -499,6 +504,7 @@ class App extends React.Component<AppProps, AppState> {
>
<DeviceTypeContext.Provider value={this.deviceType}>
<LayerUI
onHomeButtonClick={this.props.onHomeButtonClick}
canvas={this.canvas}
appState={this.state}
files={this.files}
Expand Down Expand Up @@ -528,6 +534,7 @@ class App extends React.Component<AppProps, AppState> {
}
showThemeBtn={
typeof this.props?.theme === "undefined" &&
this.props.UIOptions.canvasActions &&
this.props.UIOptions.canvasActions.theme
}
libraryReturnUrl={this.props.libraryReturnUrl}
Expand Down Expand Up @@ -787,6 +794,13 @@ class App extends React.Component<AppProps, AppState> {
};
}

if (initialData?.scrollX != null) {
scene.appState.scrollX = initialData.scrollX;
}
if (initialData?.scrollY != null) {
scene.appState.scrollY = initialData.scrollY;
}

this.resetHistory();
this.syncActionResult({
...scene,
Expand Down Expand Up @@ -882,6 +896,25 @@ class App extends React.Component<AppProps, AppState> {
this.unmounted = true;
this.removeEventListeners();
this.scene.destroy();
clearRenderCache();

this.scene = new Scene();
this.history = new History();
this.actionManager = new ActionManager(
this.syncActionResult,
() => this.state,
() => this.scene.getElementsIncludingDeleted(),
this,
);
this.library = new Library(this);
this.canvas = null;
this.rc = null;

// @ts-ignore
this.excalidrawContainerRef.current = undefined;
this.nearestScrollableContainer = undefined;
this.excalidrawContainerValue = { container: null, id: "unmounted" };

clearTimeout(touchTimeout);
touchTimeout = 0;
}
Expand Down Expand Up @@ -922,6 +955,7 @@ class App extends React.Component<AppProps, AppState> {
this.disableEvent,
false,
);
document.fonts?.removeEventListener?.("loadingdone", this.onFontLoaded);

document.removeEventListener(
EVENT.GESTURE_START,
Expand Down Expand Up @@ -1059,6 +1093,15 @@ class App extends React.Component<AppProps, AppState> {
});
}

if (
!this.props.UIOptions.canvasActions &&
this.state.openMenu === "canvas"
) {
this.setState({
openMenu: null,
});
}

if (this.props.name && prevProps.name !== this.props.name) {
this.setState({
name: this.props.name,
Expand Down Expand Up @@ -1205,6 +1248,7 @@ class App extends React.Component<AppProps, AppState> {
this.scene.getElementsIncludingDeleted(),
this.state,
this.files,
this.props.id,
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Avatar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.Avatar {
width: 2.5rem;
height: 2.5rem;
border-radius: 1.25rem;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
Expand Down
41 changes: 40 additions & 1 deletion src/components/Island.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,49 @@
border-radius: var(--border-radius-lg);
padding: calc(var(--padding) * var(--space-factor));
position: relative;
transition: box-shadow 0.5s ease-in-out;

&.zen-mode {
box-shadow: none;
}

&::-webkit-scrollbar {
width: 10px;
}

&::-webkit-scrollbar-track {
background-color: transparent;
}

&::-webkit-scrollbar-thumb {
background-color: var(--color-scrollbar-thumb);
}
&::-webkit-scrollbar-thumb:hover {
background-color: var(--color-scrollbar-thumb-hover);
}

&::-webkit-scrollbar-thumb:active {
background-color: var(--color-scrollbar-thumb-active);
}
}

.App-menu_top {
.Stack_vertical {
.Island {
min-width: 216px;
}
.Stack_horizontal {
justify-content: center !important;
}
}
}

&.excalidraw--view-mode {
.App-menu_top {
.Stack_vertical {
.Island {
min-width: auto;
}
}
}
}
}
16 changes: 10 additions & 6 deletions src/components/JSONExportDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React, { useState } from "react";
import { NonDeletedExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import { useDeviceType } from "./App";
import { AppState, ExportOpts, BinaryFiles } from "../types";
import { AppState, CanvasActions, ExportOpts, BinaryFiles } from "../types";
import { Dialog } from "./Dialog";
import { exportFile, exportToFileIcon, link } from "./icons";
import { exportToFileIcon, link } from "./icons";
import { ToolButton } from "./ToolButton";
import { actionSaveFileToDisk } from "../actions/actionExport";
import { Card } from "./Card";
Expand Down Expand Up @@ -98,7 +98,7 @@ export const JSONExportDialog = ({
appState: AppState;
files: BinaryFiles;
actionManager: ActionManager;
exportOpts: ExportOpts;
exportOpts: CanvasActions["export"];
canvas: HTMLCanvasElement | null;
}) => {
const [modalIsShown, setModalIsShown] = useState(false);
Expand All @@ -111,16 +111,20 @@ export const JSONExportDialog = ({
<>
<ToolButton
onClick={() => {
setModalIsShown(true);
if (typeof exportOpts === "function") {
actionManager.executeAction(actionSaveFileToDisk);
} else {
setModalIsShown(true);
}
}}
data-testid="json-export-button"
icon={exportFile}
icon={exportToFileIcon}
type="button"
aria-label={t("buttons.export")}
showAriaLabel={useDeviceType().isMobile}
title={t("buttons.export")}
/>
{modalIsShown && (
{modalIsShown && exportOpts && typeof exportOpts !== "function" && (
<Dialog onCloseRequest={handleClose} title={t("buttons.export")}>
<JSONExportModal
elements={elements}
Expand Down
31 changes: 18 additions & 13 deletions src/components/LayerUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { trackEvent } from "../analytics";
import { useDeviceType } from "../components/App";

interface LayerUIProps {
onHomeButtonClick?: () => void;
actionManager: ActionManager;
appState: AppState;
files: BinaryFiles;
Expand All @@ -58,6 +59,7 @@ interface LayerUIProps {
renderTopRightUI?: (
isMobile: boolean,
appState: AppState,
canvas: HTMLCanvasElement | null,
) => JSX.Element | null;
renderCustomFooter?: (
isMobile: boolean,
Expand All @@ -73,6 +75,7 @@ interface LayerUIProps {
}

const LayerUI = ({
onHomeButtonClick,
actionManager,
appState,
files,
Expand Down Expand Up @@ -101,7 +104,7 @@ const LayerUI = ({
const deviceType = useDeviceType();

const renderJSONExportDialog = () => {
if (!UIOptions.canvasActions.export) {
if (!UIOptions.canvasActions || !UIOptions.canvasActions.export) {
return null;
}

Expand All @@ -118,7 +121,7 @@ const LayerUI = ({
};

const renderImageExportDialog = () => {
if (!UIOptions.canvasActions.saveAsImage) {
if (!UIOptions.canvasActions || !UIOptions.canvasActions.saveAsImage) {
return null;
}

Expand Down Expand Up @@ -165,10 +168,6 @@ const LayerUI = ({
);
};

const Separator = () => {
return <div style={{ width: ".625em" }} />;
};

const renderViewModeCanvasActions = () => {
return (
<Section
Expand Down Expand Up @@ -202,13 +201,11 @@ const LayerUI = ({
see https://github.com/excalidraw/excalidraw/pull/1445 */}
<Island padding={2} style={{ zIndex: 1 }}>
<Stack.Col gap={4}>
<Stack.Row gap={1} justifyContent="space-between">
<Stack.Row gap={3} justifyContent="space-between">
{actionManager.renderAction("clearCanvas")}
<Separator />
{actionManager.renderAction("loadScene")}
{renderJSONExportDialog()}
{renderImageExportDialog()}
<Separator />
{onCollabButtonClick && (
<CollabButton
isCollaborating={isCollaborating}
Expand Down Expand Up @@ -307,9 +304,10 @@ const LayerUI = ({
gap={4}
className={clsx({ "disable-pointerEvents": zenModeEnabled })}
>
{viewModeEnabled
? renderViewModeCanvasActions()
: renderCanvasActions()}
{UIOptions.canvasActions &&
(viewModeEnabled
? renderViewModeCanvasActions()
: renderCanvasActions())}
{shouldRenderSelectedShapeActions && renderSelectedShapeActions()}
</Stack.Col>
{!viewModeEnabled && (
Expand Down Expand Up @@ -382,8 +380,12 @@ const LayerUI = ({
<UserList
collaborators={appState.collaborators}
actionManager={actionManager}
className={clsx("zen-mode-transition", {
"transition-right": zenModeEnabled,
})}
layout="vertical"
/>
{renderTopRightUI?.(deviceType.isMobile, appState)}
{renderTopRightUI?.(deviceType.isMobile, appState, canvas)}
</div>
</div>
</FixedSideContainer>
Expand Down Expand Up @@ -517,6 +519,7 @@ const LayerUI = ({
<>
{dialogs}
<MobileMenu
onHomeButtonClick={onHomeButtonClick}
appState={appState}
elements={elements}
actionManager={actionManager}
Expand All @@ -534,6 +537,7 @@ const LayerUI = ({
showThemeBtn={showThemeBtn}
onImageAction={onImageAction}
renderTopRightUI={renderTopRightUI}
UIOptions={UIOptions}
/>
</>
) : (
Expand Down Expand Up @@ -578,6 +582,7 @@ const areEqual = (prev: LayerUIProps, next: LayerUIProps) => {

const keys = Object.keys(prevAppState) as (keyof Partial<AppState>)[];
return (
prev.renderTopRightUI === next.renderTopRightUI &&
prev.renderCustomFooter === next.renderCustomFooter &&
prev.langCode === next.langCode &&
prev.elements === next.elements &&
Expand Down
Loading

0 comments on commit 3bc9664

Please sign in to comment.