Skip to content

Commit e5c79f1

Browse files
authored
ENG-741 Allow Canvas to be opened in Sidebar (#346)
* Refactor Tldraw component to enhance canvas rendering in both main and sidebar contexts. Update utility functions to support sidebar canvas rendering. * Refactor Tldraw canvas rendering logic to utilize heading context for improved element selection.
1 parent 8ac1ce1 commit e5c79f1

File tree

4 files changed

+109
-29
lines changed

4 files changed

+109
-29
lines changed

apps/roam/src/components/canvas/Tldraw.tsx

Lines changed: 82 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ import ConvertToDialog from "./ConvertToDialog";
8181
import { createArrowShapeMigrations } from "./DiscourseRelationShape/discourseRelationMigrations";
8282
import ToastListener, { dispatchToastEvent } from "./ToastListener";
8383
import sendErrorEmail from "~/utils/sendErrorEmail";
84+
import { TLDRAW_DATA_ATTRIBUTE } from "./tldrawStyles";
8485

8586
declare global {
8687
interface Window {
@@ -467,8 +468,7 @@ const TldrawCanvas = ({ title }: { title: string }) => {
467468

468469
return (
469470
<div
470-
className={`z-10 h-full w-full overflow-hidden rounded-md border border-gray-300 bg-white ${maximized ? "absolute inset-0" : "relative"}`}
471-
id={`roamjs-tldraw-canvas-container`}
471+
className={`roamjs-tldraw-canvas-container z-10 h-full w-full overflow-hidden rounded-md border border-gray-300 bg-white ${maximized ? "absolute inset-0" : "relative"}`}
472472
ref={containerRef}
473473
tabIndex={-1}
474474
>
@@ -845,31 +845,91 @@ const InsideEditorAndUiContext = ({
845845
return <CustomContextMenu extensionAPI={extensionAPI} allNodes={allNodes} />;
846846
};
847847

848-
export const renderTldrawCanvas = ({
848+
const renderTldrawCanvasHelper = ({
849849
title,
850850
onloadArgs,
851+
h1,
852+
rootSelector,
853+
minHeight,
854+
height,
851855
}: {
852856
title: string;
853857
onloadArgs: OnloadArgs;
858+
h1: HTMLHeadingElement;
859+
rootSelector: string;
860+
minHeight: string;
861+
height: string;
854862
}) => {
855-
const children = document.querySelector<HTMLDivElement>(
856-
".roam-article .rm-block-children",
863+
// Find the root element using the H1 context to avoid scope issues
864+
const rootElement = h1.closest(rootSelector) as HTMLDivElement;
865+
if (!rootElement) return () => {};
866+
867+
if (rootElement.hasAttribute(TLDRAW_DATA_ATTRIBUTE)) return () => {};
868+
869+
const blockChildrenContainer =
870+
rootElement.querySelector<HTMLDivElement>(".rm-block-children");
871+
if (!blockChildrenContainer) return () => {};
872+
873+
rootElement.setAttribute(TLDRAW_DATA_ATTRIBUTE, "true");
874+
875+
const canvasWrapperEl = document.createElement("div");
876+
canvasWrapperEl.style.minHeight = minHeight;
877+
canvasWrapperEl.style.height = height;
878+
879+
blockChildrenContainer.parentElement?.insertBefore(
880+
canvasWrapperEl,
881+
blockChildrenContainer.nextSibling,
857882
);
858-
if (
859-
children &&
860-
children.parentElement &&
861-
!children.hasAttribute("data-roamjs-discourse-playground")
862-
) {
863-
children.setAttribute("data-roamjs-discourse-playground", "true");
864-
const parent = document.createElement("div");
865-
children.parentElement.appendChild(parent);
866-
parent.style.minHeight = "500px";
867-
parent.style.height = "70vh";
868-
renderWithUnmount(
869-
<ExtensionApiContextProvider {...onloadArgs}>
870-
<TldrawCanvas title={title} />
871-
</ExtensionApiContextProvider>,
872-
parent,
873-
);
874-
}
883+
884+
const unmount = renderWithUnmount(
885+
<ExtensionApiContextProvider {...onloadArgs}>
886+
<TldrawCanvas title={title} />
887+
</ExtensionApiContextProvider>,
888+
canvasWrapperEl,
889+
);
890+
891+
const originalUnmount = unmount;
892+
return () => {
893+
originalUnmount();
894+
rootElement.removeAttribute(TLDRAW_DATA_ATTRIBUTE);
895+
canvasWrapperEl.remove();
896+
};
897+
};
898+
899+
export const renderTldrawCanvas = ({
900+
title,
901+
onloadArgs,
902+
h1,
903+
}: {
904+
title: string;
905+
onloadArgs: OnloadArgs;
906+
h1: HTMLHeadingElement;
907+
}) => {
908+
return renderTldrawCanvasHelper({
909+
title,
910+
onloadArgs,
911+
h1,
912+
rootSelector: ".roam-article",
913+
minHeight: "500px",
914+
height: "70vh",
915+
});
916+
};
917+
918+
export const renderTldrawCanvasInSidebar = ({
919+
title,
920+
onloadArgs,
921+
h1,
922+
}: {
923+
title: string;
924+
onloadArgs: OnloadArgs;
925+
h1: HTMLHeadingElement;
926+
}) => {
927+
return renderTldrawCanvasHelper({
928+
title,
929+
onloadArgs,
930+
h1,
931+
rootSelector: ".rm-sidebar-outline",
932+
minHeight: "400px",
933+
height: "60vh",
934+
});
875935
};

apps/roam/src/components/canvas/tldrawStyles.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
// tldrawStyles.ts because some of these styles need to be inlined
2+
export const TLDRAW_DATA_ATTRIBUTE = "dg-tldraw-canvas-wrapper";
23
export default `
3-
/* Hide Roam Blocks */
4-
.roam-article .rm-block-children {
4+
/* Hide Roam Blocks only when canvas is present */
5+
.roam-article[${TLDRAW_DATA_ATTRIBUTE}="true"] .rm-block-children {
6+
display: none;
7+
}
8+
9+
/* Hide Roam Blocks in sidebar when canvas is present */
10+
.rm-sidebar-outline[${TLDRAW_DATA_ATTRIBUTE}="true"] .rm-block-children {
511
display: none;
612
}
713
@@ -13,7 +19,7 @@ export default `
1319
/* CANVAS */
1420
/* fixes drawing arrows in north-west direction */
1521
/* and selection context not being shown */
16-
#roamjs-tldraw-canvas-container svg {
22+
.roamjs-tldraw-canvas-container svg {
1723
overflow: visible;
1824
}
1925
@@ -43,7 +49,7 @@ export default `
4349
padding: initial;
4450
}
4551
46-
/* #roamjs-tldraw-canvas-container
52+
/* .roamjs-tldraw-canvas-container
4753
.tl-shape
4854
.roamjs-tldraw-node
4955
.rm-block-main

apps/roam/src/utils/initializeObserversAndListeners.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ import {
66
import { createBlock } from "roamjs-components/writes";
77
import { renderLinkedReferenceAdditions } from "~/utils/renderLinkedReferenceAdditions";
88
import { createConfigObserver } from "roamjs-components/components/ConfigPage";
9-
import { renderTldrawCanvas } from "~/components/canvas/Tldraw";
9+
import {
10+
renderTldrawCanvas,
11+
renderTldrawCanvasInSidebar,
12+
} from "~/components/canvas/Tldraw";
1013
import { renderQueryPage, renderQueryBlock } from "~/components/QueryBuilder";
1114
import {
1215
DISCOURSE_CONFIG_PAGE_TITLE,
1316
renderNodeConfigPage,
1417
} from "~/utils/renderNodeConfigPage";
15-
import { isCurrentPageCanvas as isCanvasPage } from "~/utils/isCanvasPage";
18+
import { isCurrentPageCanvas, isSidebarCanvas } from "~/utils/isCanvasPage";
1619
import { isDiscourseNodeConfigPage as isNodeConfigPage } from "~/utils/isDiscourseNodeConfigPage";
1720
import { isQueryPage } from "~/utils/isQueryPage";
1821
import {
@@ -74,7 +77,8 @@ export const initObservers = async ({
7477

7578
if (isNodeConfigPage(title)) renderNodeConfigPage(props);
7679
else if (isQueryPage(props)) renderQueryPage(props);
77-
else if (isCanvasPage(props)) renderTldrawCanvas(props);
80+
else if (isCurrentPageCanvas(props)) renderTldrawCanvas(props);
81+
else if (isSidebarCanvas(props)) renderTldrawCanvasInSidebar(props);
7882
},
7983
});
8084

apps/roam/src/utils/isCanvasPage.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,13 @@ export const isCurrentPageCanvas = ({
1717
}) => {
1818
return isCanvasPage({ title }) && !!h1.closest(".roam-article");
1919
};
20+
21+
export const isSidebarCanvas = ({
22+
title,
23+
h1,
24+
}: {
25+
title: string;
26+
h1: HTMLHeadingElement;
27+
}) => {
28+
return isCanvasPage({ title }) && !!h1.closest(".rm-sidebar-outline");
29+
};

0 commit comments

Comments
 (0)