diff --git a/dev-docs/docs/codebase/frames.mdx b/dev-docs/docs/codebase/frames.mdx index 45a551f23..67c84b792 100644 --- a/dev-docs/docs/codebase/frames.mdx +++ b/dev-docs/docs/codebase/frames.mdx @@ -19,4 +19,4 @@ Frames should be ordered where frame children come first, followed by the frame ] ``` -If not oredered correctly, the editor will still function, but the elements may not be rendered and clipped correctly. Further, the renderer relies on this ordering for performance optimizations. +If not ordered correctly, the editor will still function, but the elements may not be rendered and clipped correctly. Further, the renderer relies on this ordering for performance optimizations. diff --git a/excalidraw-app/index.tsx b/excalidraw-app/index.tsx index 5b2e29818..7708fc190 100644 --- a/excalidraw-app/index.tsx +++ b/excalidraw-app/index.tsx @@ -691,7 +691,7 @@ const ExcalidrawWrapper = () => { })} > event.key === KEYS.H, + keyTest: (event) => + !event.altKey && !event[KEYS.CTRL_OR_CMD] && event.key === KEYS.H, }); diff --git a/src/actions/actionGroup.tsx b/src/actions/actionGroup.tsx index 5a2d38c2c..219f1444c 100644 --- a/src/actions/actionGroup.tsx +++ b/src/actions/actionGroup.tsx @@ -17,15 +17,12 @@ import { import { getNonDeletedElements } from "../element"; import { randomId } from "../random"; import { ToolButton } from "../components/ToolButton"; -import { - ExcalidrawElement, - ExcalidrawFrameElement, - ExcalidrawTextElement, -} from "../element/types"; +import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types"; import { AppClassProperties, AppState } from "../types"; import { isBoundToContainer } from "../element/typeChecks"; import { getElementsInResizingFrame, + getFrameElements, groupByFrames, removeElementsFromFrame, replaceAllElementsInFrame, @@ -190,19 +187,6 @@ export const actionUngroup = register({ let nextElements = [...elements]; - const frameIds: { - [id: string]: true; - } = {}; - const selectedElements = app.scene.getSelectedElements(appState); - for (const element of selectedElements) { - if (element.frameId) { - frameIds[element.frameId] = true; - } - } - const frames = Object.keys(frameIds) - .map((eid) => app.scene.getElement(eid)) - .filter((element) => element != null) as ExcalidrawFrameElement[]; - const boundTextElementIds: ExcalidrawTextElement["id"][] = []; nextElements = nextElements.map((element) => { if (isBoundToContainer(element)) { @@ -227,7 +211,19 @@ export const actionUngroup = register({ null, ); - frames.forEach((frame) => { + const selectedElements = app.scene.getSelectedElements(appState); + + const selectedElementFrameIds = new Set( + selectedElements + .filter((element) => element.frameId) + .map((element) => element.frameId!), + ); + + const targetFrames = getFrameElements(elements).filter((frame) => + selectedElementFrameIds.has(frame.id), + ); + + targetFrames.forEach((frame) => { if (frame) { nextElements = replaceAllElementsInFrame( nextElements, diff --git a/src/actions/actionMenu.tsx b/src/actions/actionMenu.tsx index 80a5c2b1f..b259d7267 100644 --- a/src/actions/actionMenu.tsx +++ b/src/actions/actionMenu.tsx @@ -3,7 +3,6 @@ import { ToolButton } from "../components/ToolButton"; import { t } from "../i18n"; import { showSelectedShapeActions, getNonDeletedElements } from "../element"; import { register } from "./register"; -import { allowFullScreen, exitFullScreen, isFullScreen } from "../utils"; import { KEYS } from "../keys"; export const actionToggleCanvasMenu = register({ @@ -52,23 +51,6 @@ export const actionToggleEditMenu = register({ ), }); -export const actionFullScreen = register({ - name: "toggleFullScreen", - viewMode: true, - trackEvent: { category: "canvas", predicate: (appState) => !isFullScreen() }, - perform: () => { - if (!isFullScreen()) { - allowFullScreen(); - } - if (isFullScreen()) { - exitFullScreen(); - } - return { - commitToHistory: false, - }; - }, -}); - export const actionShortcuts = register({ name: "toggleShortcuts", viewMode: true, diff --git a/src/actions/index.ts b/src/actions/index.ts index 1e72aa48a..b4551acf5 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -44,7 +44,6 @@ export { actionCopyStyles, actionPasteStyles } from "./actionStyles"; export { actionToggleCanvasMenu, actionToggleEditMenu, - actionFullScreen, actionShortcuts, } from "./actionMenu"; diff --git a/src/components/App.tsx b/src/components/App.tsx index 493877c2c..8e4ab6355 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -240,7 +240,6 @@ import { isInputLike, isToolIcon, isWritableElement, - resolvablePromise, sceneCoordsToViewportCoords, tupleToCoors, viewportCoordsToSceneCoords, @@ -540,7 +539,7 @@ class App extends React.Component { super(props); const defaultAppState = getDefaultAppState(); const { - excalidrawRef, + excalidrawAPI, viewModeEnabled = false, zenModeEnabled = false, gridModeEnabled = false, @@ -571,14 +570,8 @@ class App extends React.Component { this.rc = rough.canvas(this.canvas); this.renderer = new Renderer(this.scene); - if (excalidrawRef) { - const readyPromise = - ("current" in excalidrawRef && excalidrawRef.current?.readyPromise) || - resolvablePromise(); - + if (excalidrawAPI) { const api: ExcalidrawImperativeAPI = { - ready: true, - readyPromise, updateScene: this.updateScene, updateLibrary: this.library.updateLibrary, addFiles: this.addFiles, @@ -603,12 +596,11 @@ class App extends React.Component { onPointerDown: (cb) => this.onPointerDownEmitter.on(cb), onPointerUp: (cb) => this.onPointerUpEmitter.on(cb), } as const; - if (typeof excalidrawRef === "function") { - excalidrawRef(api); + if (typeof excalidrawAPI === "function") { + excalidrawAPI(api); } else { - excalidrawRef.current = api; + console.error("excalidrawAPI should be a function!"); } - readyPromise.resolve(api); } this.excalidrawContainerValue = { @@ -1181,6 +1173,19 @@ class App extends React.Component { pendingImageElementId: this.state.pendingImageElementId, }); + const shouldBlockPointerEvents = + !( + this.state.editingElement && isLinearElement(this.state.editingElement) + ) && + (this.state.selectionElement || + this.state.draggingElement || + this.state.resizingElement || + (this.state.activeTool.type === "laser" && + // technically we can just test on this once we make it more safe + this.state.cursorButton === "down") || + (this.state.editingElement && + !isTextElement(this.state.editingElement))); + return (
{ "excalidraw--mobile": this.device.editor.isMobile, })} style={{ - ["--ui-pointerEvents" as any]: - this.state.selectionElement || - this.state.draggingElement || - this.state.resizingElement || - (this.state.activeTool.type === "laser" && - // technically we can just test on this once we make it more safe - this.state.cursorButton === "down") || - (this.state.editingElement && - !isTextElement(this.state.editingElement)) - ? POINTER_EVENTS.disabled - : POINTER_EVENTS.enabled, + ["--ui-pointerEvents" as any]: shouldBlockPointerEvents + ? POINTER_EVENTS.disabled + : POINTER_EVENTS.enabled, }} ref={this.excalidrawContainerRef} onDrop={this.handleAppOnDrop} @@ -2719,7 +2716,7 @@ class App extends React.Component { }); }; - togglePenMode = (force?: boolean) => { + togglePenMode = (force: boolean | null) => { this.setState((prevState) => { return { penMode: force ?? !prevState.penMode, diff --git a/src/components/HelpDialog.tsx b/src/components/HelpDialog.tsx index b27823fc5..961158c0c 100644 --- a/src/components/HelpDialog.tsx +++ b/src/components/HelpDialog.tsx @@ -254,7 +254,6 @@ export const HelpDialog = ({ onClose }: { onClose?: () => void }) => { label={t("helpDialog.movePageLeftRight")} shortcuts={["Shift+PgUp/PgDn"]} /> - void; onHandToolToggle: () => void; - onPenModeToggle: () => void; + onPenModeToggle: AppClassProperties["togglePenMode"]; showExitZenModeBtn: boolean; langCode: Language["code"]; renderTopRightUI?: ExcalidrawProps["renderTopRightUI"]; @@ -258,7 +258,7 @@ const LayerUI = ({ onPenModeToggle(null)} title={t("toolBar.penMode")} penDetected={appState.penDetected} /> diff --git a/src/components/MobileMenu.tsx b/src/components/MobileMenu.tsx index bb26fe713..4299bf844 100644 --- a/src/components/MobileMenu.tsx +++ b/src/components/MobileMenu.tsx @@ -35,7 +35,7 @@ type MobileMenuProps = { elements: readonly NonDeletedExcalidrawElement[]; onLockToggle: () => void; onHandToolToggle: () => void; - onPenModeToggle: () => void; + onPenModeToggle: AppClassProperties["togglePenMode"]; renderTopRightUI?: ( isMobile: boolean, @@ -94,7 +94,7 @@ export const MobileMenu = ({ )} onPenModeToggle(null)} title={t("toolBar.penMode")} isMobile penDetected={appState.penDetected} diff --git a/src/element/embeddable.ts b/src/element/embeddable.ts index c0ade4fe2..e03ea7a61 100644 --- a/src/element/embeddable.ts +++ b/src/element/embeddable.ts @@ -64,6 +64,7 @@ const ALLOWED_DOMAINS = new Set([ "stackblitz.com", "val.town", "giphy.com", + "dddice.com", ]); const createSrcDoc = (body: string) => { diff --git a/src/packages/excalidraw/CHANGELOG.md b/src/packages/excalidraw/CHANGELOG.md index 7f21b9cc3..a001e2426 100644 --- a/src/packages/excalidraw/CHANGELOG.md +++ b/src/packages/excalidraw/CHANGELOG.md @@ -15,6 +15,14 @@ Please add the latest change on the top under the correct section. ### Features +- Support `excalidrawAPI` prop for accessing the Excalidraw API [#7251](https://github.com/excalidraw/excalidraw/pull/7251). + +#### BREAKING CHANGE + +- The `Ref` support has been removed in v0.17.0 so if you are using refs, please update the integration to use the [`excalidrawAPI`](http://localhost:3003/docs/@excalidraw/excalidraw/api/props/excalidraw-api) + +- Additionally `ready` and `readyPromise` from the API have been discontinued. These APIs were found to be superfluous, and as part of the effort to streamline the APIs and maintain simplicity, they were removed in version v0.17.0. + - Export [`getCommonBounds`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/utils#getcommonbounds) helper from the package [#7247](https://github.com/excalidraw/excalidraw/pull/7247). - Support frames via programmatic API [#7205](https://github.com/excalidraw/excalidraw/pull/7205). diff --git a/src/packages/excalidraw/example/App.tsx b/src/packages/excalidraw/example/App.tsx index 157444271..974bbb7ef 100644 --- a/src/packages/excalidraw/example/App.tsx +++ b/src/packages/excalidraw/example/App.tsx @@ -665,7 +665,9 @@ export default function App({ appTitle, useCustom, customArgs }: AppProps) {
setExcalidrawAPI(api)} + excalidrawAPI={(api: ExcalidrawImperativeAPI) => + setExcalidrawAPI(api) + } initialData={initialStatePromiseRef.current.promise} onChange={(elements, state) => { console.info("Elements :", elements, "State : ", state); diff --git a/src/packages/excalidraw/index.tsx b/src/packages/excalidraw/index.tsx index ac12c65af..2458c112d 100644 --- a/src/packages/excalidraw/index.tsx +++ b/src/packages/excalidraw/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, forwardRef } from "react"; +import React, { useEffect } from "react"; import { InitializeApp } from "../../components/InitializeApp"; import App from "../../components/App"; import { isShallowEqual } from "../../utils"; @@ -6,7 +6,7 @@ import { isShallowEqual } from "../../utils"; import "../../css/app.scss"; import "../../css/styles.scss"; -import { AppProps, ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types"; +import { AppProps, ExcalidrawProps } from "../../types"; import { defaultLang } from "../../i18n"; import { DEFAULT_UI_OPTIONS } from "../../constants"; import { Provider } from "jotai"; @@ -20,7 +20,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => { const { onChange, initialData, - excalidrawRef, + excalidrawAPI, isCollaborating = false, onPointerUpdate, renderTopRightUI, @@ -95,7 +95,7 @@ const ExcalidrawBase = (props: ExcalidrawProps) => { { ); }; -type PublicExcalidrawProps = Omit; - -const areEqual = ( - prevProps: PublicExcalidrawProps, - nextProps: PublicExcalidrawProps, -) => { +const areEqual = (prevProps: ExcalidrawProps, nextProps: ExcalidrawProps) => { // short-circuit early if (prevProps.children !== nextProps.children) { return false; @@ -189,12 +184,7 @@ const areEqual = ( return isUIOptionsSame && isShallowEqual(prev, next); }; -const forwardedRefComp = forwardRef< - ExcalidrawAPIRefValue, - PublicExcalidrawProps ->((props, ref) => ); - -export const Excalidraw = React.memo(forwardedRefComp, areEqual); +export const Excalidraw = React.memo(ExcalidrawBase, areEqual); Excalidraw.displayName = "Excalidraw"; export { diff --git a/src/scene/Shape.ts b/src/scene/Shape.ts index 16b6518f8..cf4681542 100644 --- a/src/scene/Shape.ts +++ b/src/scene/Shape.ts @@ -14,18 +14,34 @@ import { generateFreeDrawShape } from "../renderer/renderElement"; import { isTransparent, assertNever } from "../utils"; import { simplify } from "points-on-curve"; import { ROUGHNESS } from "../constants"; +import { isLinearElement } from "../element/typeChecks"; +import { canChangeRoundness } from "./comparisons"; const getDashArrayDashed = (strokeWidth: number) => [8, 8 + strokeWidth]; const getDashArrayDotted = (strokeWidth: number) => [1.5, 6 + strokeWidth]; -function adjustRoughness(size: number, roughness: number): number { - if (size >= 50) { +function adjustRoughness(element: ExcalidrawElement): number { + const roughness = element.roughness; + + const maxSize = Math.max(element.width, element.height); + const minSize = Math.min(element.width, element.height); + + // don't reduce roughness if + if ( + // both sides relatively big + (minSize >= 20 && maxSize >= 50) || + // is round & both sides above 15px + (minSize >= 15 && + !!element.roundness && + canChangeRoundness(element.type)) || + // relatively long linear element + (isLinearElement(element) && maxSize >= 50) + ) { return roughness; } - const factor = 2 + (50 - size) / 10; - return roughness / factor; + return Math.min(roughness / (maxSize < 10 ? 3 : 2), 2.5); } export const generateRoughOptions = ( @@ -54,10 +70,7 @@ export const generateRoughOptions = ( // calculate them (and we don't want the fills to be modified) fillWeight: element.strokeWidth / 2, hachureGap: element.strokeWidth * 4, - roughness: adjustRoughness( - Math.min(element.width, element.height), - element.roughness, - ), + roughness: adjustRoughness(element), stroke: element.strokeColor, preserveVertices: continuousPath || element.roughness < ROUGHNESS.cartoonist, diff --git a/src/scene/export.ts b/src/scene/export.ts index 694c162da..26fe7ff43 100644 --- a/src/scene/export.ts +++ b/src/scene/export.ts @@ -11,10 +11,11 @@ import { getElementAbsoluteCoords, } from "../element/bounds"; import { renderSceneToSvg, renderStaticScene } from "../renderer/renderScene"; -import { distance, getFontString } from "../utils"; +import { cloneJSON, distance, getFontString } from "../utils"; import { AppState, BinaryFiles } from "../types"; import { DEFAULT_EXPORT_PADDING, + FONT_FAMILY, FRAME_STYLE, SVG_NS, THEME_FILTER, @@ -51,8 +52,9 @@ const __createSceneForElementsHack__ = ( // we can't duplicate elements to regenerate ids because we need the // orig ids when embedding. So we do another hack of not mapping element // ids to Scene instances so that we don't override the editor elements - // mapping - scene.replaceAllElements(elements, false); + // mapping. + // We still need to clone the objects themselves to regen references. + scene.replaceAllElements(cloneJSON(elements), false); return scene; }; @@ -105,7 +107,7 @@ const addFrameLabelsAsTextElements = ( let textElement: Mutable = newTextElement({ x: element.x, y: element.y - FRAME_STYLE.nameOffsetY, - fontFamily: 4, + fontFamily: FONT_FAMILY.Assistant, fontSize: FRAME_STYLE.nameFontSize, lineHeight: FRAME_STYLE.nameLineHeight as ExcalidrawTextElement["lineHeight"], @@ -139,6 +141,36 @@ const getFrameRenderingConfig = ( }; }; +const prepareElementsForRender = ({ + elements, + exportingFrame, + frameRendering, + exportWithDarkMode, +}: { + elements: readonly ExcalidrawElement[]; + exportingFrame: ExcalidrawFrameElement | null | undefined; + frameRendering: AppState["frameRendering"]; + exportWithDarkMode: AppState["exportWithDarkMode"]; +}) => { + let nextElements: readonly ExcalidrawElement[]; + + if (exportingFrame) { + nextElements = elementsOverlappingBBox({ + elements, + bounds: exportingFrame, + type: "overlap", + }); + } else if (frameRendering.enabled && frameRendering.name) { + nextElements = addFrameLabelsAsTextElements(elements, { + exportWithDarkMode, + }); + } else { + nextElements = elements; + } + + return nextElements; +}; + export const exportToCanvas = async ( elements: readonly NonDeletedExcalidrawElement[], appState: AppState, @@ -167,21 +199,24 @@ export const exportToCanvas = async ( const tempScene = __createSceneForElementsHack__(elements); elements = tempScene.getNonDeletedElements(); - let nextElements: ExcalidrawElement[]; + const frameRendering = getFrameRenderingConfig( + exportingFrame ?? null, + appState.frameRendering ?? null, + ); + + const elementsForRender = prepareElementsForRender({ + elements, + exportingFrame, + exportWithDarkMode: appState.exportWithDarkMode, + frameRendering, + }); if (exportingFrame) { exportPadding = 0; - nextElements = elementsOverlappingBBox({ - elements, - bounds: exportingFrame, - type: "overlap", - }); - } else { - nextElements = addFrameLabelsAsTextElements(elements, appState); } const [minX, minY, width, height] = getCanvasSize( - exportingFrame ? [exportingFrame] : getRootElements(nextElements), + exportingFrame ? [exportingFrame] : getRootElements(elementsForRender), exportPadding, ); @@ -191,7 +226,7 @@ export const exportToCanvas = async ( const { imageCache } = await updateImageCache({ imageCache: new Map(), - fileIds: getInitializedImageElements(nextElements).map( + fileIds: getInitializedImageElements(elementsForRender).map( (element) => element.fileId, ), files, @@ -200,15 +235,12 @@ export const exportToCanvas = async ( renderStaticScene({ canvas, rc: rough.canvas(canvas), - elements: nextElements, - visibleElements: nextElements, + elements: elementsForRender, + visibleElements: elementsForRender, scale, appState: { ...appState, - frameRendering: getFrameRenderingConfig( - exportingFrame ?? null, - appState.frameRendering ?? null, - ), + frameRendering, viewBackgroundColor: exportBackground ? viewBackgroundColor : null, scrollX: -minX + exportPadding, scrollY: -minY + exportPadding, @@ -248,8 +280,14 @@ export const exportToSvg = async ( const tempScene = __createSceneForElementsHack__(elements); elements = tempScene.getNonDeletedElements(); + const frameRendering = getFrameRenderingConfig( + opts?.exportingFrame ?? null, + appState.frameRendering ?? null, + ); + let { exportPadding = DEFAULT_EXPORT_PADDING, + exportWithDarkMode = false, viewBackgroundColor, exportScale = 1, exportEmbedScene, @@ -257,19 +295,15 @@ export const exportToSvg = async ( const { exportingFrame = null } = opts || {}; - let nextElements: ExcalidrawElement[] = []; + const elementsForRender = prepareElementsForRender({ + elements, + exportingFrame, + exportWithDarkMode, + frameRendering, + }); if (exportingFrame) { exportPadding = 0; - nextElements = elementsOverlappingBBox({ - elements, - bounds: exportingFrame, - type: "overlap", - }); - } else { - nextElements = addFrameLabelsAsTextElements(elements, { - exportWithDarkMode: appState.exportWithDarkMode ?? false, - }); } let metadata = ""; @@ -293,7 +327,7 @@ export const exportToSvg = async ( } const [minX, minY, width, height] = getCanvasSize( - exportingFrame ? [exportingFrame] : getRootElements(nextElements), + exportingFrame ? [exportingFrame] : getRootElements(elementsForRender), exportPadding, ); @@ -304,7 +338,7 @@ export const exportToSvg = async ( svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`); svgRoot.setAttribute("width", `${width * exportScale}`); svgRoot.setAttribute("height", `${height * exportScale}`); - if (appState.exportWithDarkMode) { + if (exportWithDarkMode) { svgRoot.setAttribute("filter", THEME_FILTER); } @@ -379,15 +413,12 @@ export const exportToSvg = async ( } const rsvg = rough.svg(svgRoot); - renderSceneToSvg(nextElements, rsvg, svgRoot, files || {}, { + renderSceneToSvg(elementsForRender, rsvg, svgRoot, files || {}, { offsetX, offsetY, - exportWithDarkMode: appState.exportWithDarkMode ?? false, + exportWithDarkMode, renderEmbeddables: opts?.renderEmbeddables ?? false, - frameRendering: getFrameRenderingConfig( - exportingFrame ?? null, - appState.frameRendering ?? null, - ), + frameRendering, }); tempScene.destroy(); diff --git a/src/tests/packages/events.test.tsx b/src/tests/packages/events.test.tsx index 231af5799..907dc7a8e 100644 --- a/src/tests/packages/events.test.tsx +++ b/src/tests/packages/events.test.tsx @@ -15,7 +15,9 @@ describe("event callbacks", () => { beforeEach(async () => { const excalidrawAPIPromise = resolvablePromise(); await render( - excalidrawAPIPromise.resolve(api as any)} />, + excalidrawAPIPromise.resolve(api as any)} + />, ); excalidrawAPI = await excalidrawAPIPromise; }); diff --git a/src/tests/tool.test.tsx b/src/tests/tool.test.tsx index 84a43c6b5..41ffbbf8e 100644 --- a/src/tests/tool.test.tsx +++ b/src/tests/tool.test.tsx @@ -14,7 +14,9 @@ describe("setActiveTool()", () => { beforeEach(async () => { const excalidrawAPIPromise = resolvablePromise(); await render( - excalidrawAPIPromise.resolve(api as any)} />, + excalidrawAPIPromise.resolve(api as any)} + />, ); excalidrawAPI = await excalidrawAPIPromise; }); diff --git a/src/types.ts b/src/types.ts index 3fe0f2d72..c1290c8f1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -23,7 +23,7 @@ import { LinearElementEditor } from "./element/linearElementEditor"; import { SuggestedBinding } from "./element/binding"; import { ImportedDataState } from "./data/types"; import type App from "./components/App"; -import type { ResolvablePromise, throttleRAF } from "./utils"; +import type { throttleRAF } from "./utils"; import { Spreadsheet } from "./charts"; import { Language } from "./i18n"; import { ClipboardData } from "./clipboard"; @@ -34,7 +34,7 @@ import type { FileSystemHandle } from "./data/filesystem"; import type { IMAGE_MIME_TYPES, MIME_TYPES } from "./constants"; import { ContextMenuItems } from "./components/ContextMenu"; import { SnapLine } from "./snapping"; -import { Merge, ForwardRef, ValueOf } from "./utility-types"; +import { Merge, ValueOf } from "./utility-types"; export type Point = Readonly; @@ -362,15 +362,6 @@ export type LibraryItemsSource = | Promise; // ----------------------------------------------------------------------------- -// NOTE ready/readyPromise props are optional for host apps' sake (our own -// implem guarantees existence) -export type ExcalidrawAPIRefValue = - | ExcalidrawImperativeAPI - | { - readyPromise?: ResolvablePromise; - ready?: false; - }; - export type ExcalidrawInitialDataState = Merge< ImportedDataState, { @@ -390,7 +381,7 @@ export interface ExcalidrawProps { | ExcalidrawInitialDataState | null | Promise; - excalidrawRef?: ForwardRef; + excalidrawAPI?: (api: ExcalidrawImperativeAPI) => void; isCollaborating?: boolean; onPointerUpdate?: (payload: { pointer: { x: number; y: number; tool: "pointer" | "laser" }; @@ -630,8 +621,6 @@ export type ExcalidrawImperativeAPI = { refresh: InstanceType["refresh"]; setToast: InstanceType["setToast"]; addFiles: (data: BinaryFileData[]) => void; - readyPromise: ResolvablePromise; - ready: true; id: string; setActiveTool: InstanceType["setActiveTool"]; setCursor: InstanceType["setCursor"]; diff --git a/yarn.lock b/yarn.lock index eacc147c7..82691f7b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1602,10 +1602,10 @@ resolved "https://registry.yarnpkg.com/@excalidraw/prettier-config/-/prettier-config-1.0.2.tgz#b7c061c99cee2f78b9ca470ea1fbd602683bba65" integrity sha512-rFIq8+A8WvkEzBsF++Rw6gzxE+hU3ZNkdg8foI+Upz2y/rOC/gUpWJaggPbCkoH3nlREVU59axQjZ1+F6ePRGg== -"@excalidraw/random-username@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@excalidraw/random-username/-/random-username-1.0.0.tgz#6d5293148aee6cd08dcdfcadc0c91276572f4499" - integrity sha512-pd4VapWahQ7PIyThGq32+C+JUS73mf3RSdC7BmQiXzhQsCTU4RHc8y9jBi+pb1CFV0iJXvjJRXnVdLCbTj3+HA== +"@excalidraw/random-username@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@excalidraw/random-username/-/random-username-1.1.0.tgz#6f388d6a9708cf655b8c9c6aa3fa569ee71ecf0f" + integrity sha512-nULYsQxkWHnbmHvcs+efMkJ4/9TtvNyFeLyHdeGxW0zHs6P+jYVqcRff9A6Vq9w9JXeDRnRh2VKvTtS19GW2qA== "@firebase/analytics-types@0.4.0": version "0.4.0"