chore: upgrade to react@19 (#9182)
This commit is contained in:
parent
9ee0b8ffcb
commit
31e8476c78
@ -23,8 +23,8 @@
|
|||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"docusaurus-plugin-sass": "0.2.3",
|
"docusaurus-plugin-sass": "0.2.3",
|
||||||
"prism-react-renderer": "^1.3.5",
|
"prism-react-renderer": "^1.3.5",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"sass": "1.57.1"
|
"sass": "1.57.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"@excalidraw/excalidraw": "*"
|
"@excalidraw/excalidraw": "*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@excalidraw/excalidraw": "*",
|
"@excalidraw/excalidraw": "*",
|
||||||
"next": "14.1",
|
"next": "14.1",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "18.2.0",
|
"@types/react": "19.0.10",
|
||||||
"@types/react-dom": "18.2.0",
|
"@types/react-dom": "19.0.4",
|
||||||
"path2d-polyfill": "2.0.1",
|
"path2d-polyfill": "2.0.1",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"@excalidraw/excalidraw": "*"
|
"@excalidraw/excalidraw": "*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -19,16 +19,16 @@ export const collabErrorIndicatorAtom = atom<ErrorIndicator>({
|
|||||||
|
|
||||||
const CollabError = ({ collabError }: { collabError: ErrorIndicator }) => {
|
const CollabError = ({ collabError }: { collabError: ErrorIndicator }) => {
|
||||||
const [isAnimating, setIsAnimating] = useState(false);
|
const [isAnimating, setIsAnimating] = useState(false);
|
||||||
const clearAnimationRef = useRef<string | number | NodeJS.Timeout>();
|
const clearAnimationRef = useRef<string | number>(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsAnimating(true);
|
setIsAnimating(true);
|
||||||
clearAnimationRef.current = setTimeout(() => {
|
clearAnimationRef.current = window.setTimeout(() => {
|
||||||
setIsAnimating(false);
|
setIsAnimating(false);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(clearAnimationRef.current);
|
window.clearTimeout(clearAnimationRef.current);
|
||||||
};
|
};
|
||||||
}, [collabError.message, collabError.nonce]);
|
}, [collabError.message, collabError.nonce]);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { forwardRef, useCallback, useImperativeHandle, useRef } from "react";
|
import { useCallback, useImperativeHandle, useRef } from "react";
|
||||||
import { type AppState } from "../../packages/excalidraw/types";
|
import { type AppState } from "../../packages/excalidraw/types";
|
||||||
import { throttleRAF } from "../../packages/excalidraw/utils";
|
import { throttleRAF } from "../../packages/excalidraw/utils";
|
||||||
import {
|
import {
|
||||||
@ -276,36 +276,35 @@ export const DebugFooter = ({ onChange }: { onChange: () => void }) => {
|
|||||||
interface DebugCanvasProps {
|
interface DebugCanvasProps {
|
||||||
appState: AppState;
|
appState: AppState;
|
||||||
scale: number;
|
scale: number;
|
||||||
|
ref?: React.Ref<HTMLCanvasElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DebugCanvas = forwardRef<HTMLCanvasElement, DebugCanvasProps>(
|
const DebugCanvas = ({ appState, scale, ref }: DebugCanvasProps) => {
|
||||||
({ appState, scale }, ref) => {
|
const { width, height } = appState;
|
||||||
const { width, height } = appState;
|
|
||||||
|
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
useImperativeHandle<HTMLCanvasElement | null, HTMLCanvasElement | null>(
|
useImperativeHandle<HTMLCanvasElement | null, HTMLCanvasElement | null>(
|
||||||
ref,
|
ref,
|
||||||
() => canvasRef.current,
|
() => canvasRef.current,
|
||||||
[canvasRef],
|
[canvasRef],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<canvas
|
<canvas
|
||||||
style={{
|
style={{
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
zIndex: 2,
|
zIndex: 2,
|
||||||
pointerEvents: "none",
|
pointerEvents: "none",
|
||||||
}}
|
}}
|
||||||
width={width * scale}
|
width={width * scale}
|
||||||
height={height * scale}
|
height={height * scale}
|
||||||
ref={canvasRef}
|
ref={canvasRef}
|
||||||
>
|
>
|
||||||
Debug Canvas
|
Debug Canvas
|
||||||
</canvas>
|
</canvas>
|
||||||
);
|
);
|
||||||
},
|
};
|
||||||
);
|
|
||||||
|
|
||||||
export default DebugCanvas;
|
export default DebugCanvas;
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
"i18next-browser-languagedetector": "6.1.4",
|
"i18next-browser-languagedetector": "6.1.4",
|
||||||
"idb-keyval": "6.0.3",
|
"idb-keyval": "6.0.3",
|
||||||
"jotai": "2.11.0",
|
"jotai": "2.11.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"socket.io-client": "4.7.2",
|
"socket.io-client": "4.7.2",
|
||||||
"vite-plugin-html": "3.2.2"
|
"vite-plugin-html": "3.2.2"
|
||||||
},
|
},
|
||||||
|
11
package.json
11
package.json
@ -17,11 +17,11 @@
|
|||||||
"@types/chai": "4.3.0",
|
"@types/chai": "4.3.0",
|
||||||
"@types/jest": "27.4.0",
|
"@types/jest": "27.4.0",
|
||||||
"@types/lodash.throttle": "4.1.7",
|
"@types/lodash.throttle": "4.1.7",
|
||||||
"@types/react": "18.2.0",
|
"@types/react": "19.0.10",
|
||||||
"@types/react-dom": "18.2.0",
|
"@types/react-dom": "19.0.4",
|
||||||
"@types/socket.io-client": "3.0.0",
|
"@types/socket.io-client": "3.0.0",
|
||||||
"@vitejs/plugin-react": "3.1.0",
|
"@vitejs/plugin-react": "3.1.0",
|
||||||
"@vitest/coverage-v8": "2.0.5",
|
"@vitest/coverage-v8": "3.0.7",
|
||||||
"@vitest/ui": "2.0.5",
|
"@vitest/ui": "2.0.5",
|
||||||
"chai": "4.3.6",
|
"chai": "4.3.6",
|
||||||
"dotenv": "16.0.1",
|
"dotenv": "16.0.1",
|
||||||
@ -39,9 +39,9 @@
|
|||||||
"vite": "5.0.12",
|
"vite": "5.0.12",
|
||||||
"vite-plugin-checker": "0.7.2",
|
"vite-plugin-checker": "0.7.2",
|
||||||
"vite-plugin-ejs": "1.7.0",
|
"vite-plugin-ejs": "1.7.0",
|
||||||
"vite-plugin-pwa": "0.17.4",
|
"vite-plugin-pwa": "0.21.1",
|
||||||
"vite-plugin-svgr": "4.2.0",
|
"vite-plugin-svgr": "4.2.0",
|
||||||
"vitest": "2.0.5",
|
"vitest": "3.0.6",
|
||||||
"vitest-canvas-mock": "0.3.3"
|
"vitest-canvas-mock": "0.3.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -83,7 +83,6 @@
|
|||||||
"clean-install": "yarn rm:node_modules && yarn install"
|
"clean-install": "yarn rm:node_modules && yarn install"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@types/react": "18.2.0",
|
|
||||||
"strip-ansi": "6.0.1"
|
"strip-ansi": "6.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
|
import type { JSX } from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
import "./ButtonIcon.scss";
|
import "./ButtonIcon.scss";
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
export const ButtonIconCycle = <T extends any>({
|
export const ButtonIconCycle = <T extends any>({
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { ButtonIcon } from "./ButtonIcon";
|
import { ButtonIcon } from "./ButtonIcon";
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import React, {
|
import React, {
|
||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
|
@ -4,7 +4,7 @@ import { type FontDescriptor } from "./FontPickerList";
|
|||||||
|
|
||||||
interface FontPickerKeyNavHandlerProps {
|
interface FontPickerKeyNavHandlerProps {
|
||||||
event: React.KeyboardEvent<HTMLDivElement>;
|
event: React.KeyboardEvent<HTMLDivElement>;
|
||||||
inputRef: React.RefObject<HTMLInputElement>;
|
inputRef: React.RefObject<HTMLInputElement | null>;
|
||||||
hoveredFont: Node<FontDescriptor> | undefined;
|
hoveredFont: Node<FontDescriptor> | undefined;
|
||||||
filteredFonts: Node<FontDescriptor>[];
|
filteredFonts: Node<FontDescriptor>[];
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import * as Popover from "@radix-ui/react-popover";
|
import * as Popover from "@radix-ui/react-popover";
|
||||||
import { isArrowKey, KEYS } from "../keys";
|
import { isArrowKey, KEYS } from "../keys";
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import "./ToolIcon.scss";
|
import type { JSX } from "react";
|
||||||
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import type { ToolButtonSize } from "./ToolButton";
|
import type { ToolButtonSize } from "./ToolButton";
|
||||||
|
|
||||||
|
import "./ToolIcon.scss";
|
||||||
|
|
||||||
const DEFAULT_SIZE: ToolButtonSize = "small";
|
const DEFAULT_SIZE: ToolButtonSize = "small";
|
||||||
|
|
||||||
export const ElementCanvasButton = (props: {
|
export const ElementCanvasButton = (props: {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import type {
|
import type {
|
||||||
AppClassProperties,
|
AppClassProperties,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import type { AppState, SidebarName, SidebarTabName } from "../../types";
|
import type { AppState, SidebarName, SidebarTabName } from "../../types";
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ type StackProps = {
|
|||||||
justifyContent?: "center" | "space-around" | "space-between";
|
justifyContent?: "center" | "space-around" | "space-between";
|
||||||
className?: string | boolean;
|
className?: string | boolean;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
ref: React.RefObject<HTMLDivElement>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const RowStack = forwardRef(
|
const RowStack = forwardRef(
|
||||||
|
@ -13,7 +13,7 @@ const ErrorComp = ({ error }: { error: string }) => {
|
|||||||
|
|
||||||
interface TTDDialogOutputProps {
|
interface TTDDialogOutputProps {
|
||||||
error: Error | null;
|
error: Error | null;
|
||||||
canvasRef: React.RefObject<HTMLDivElement>;
|
canvasRef: React.RefObject<HTMLDivElement | null>;
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { useTunnels } from "../../context/tunnels";
|
import { useTunnels } from "../../context/tunnels";
|
||||||
import DropdownMenu from "../dropdownMenu/DropdownMenu";
|
import DropdownMenu from "../dropdownMenu/DropdownMenu";
|
||||||
|
@ -12,7 +12,7 @@ const resetPreview = ({
|
|||||||
canvasRef,
|
canvasRef,
|
||||||
setError,
|
setError,
|
||||||
}: {
|
}: {
|
||||||
canvasRef: React.RefObject<HTMLDivElement>;
|
canvasRef: React.RefObject<HTMLDivElement | null>;
|
||||||
setError: (error: Error | null) => void;
|
setError: (error: Error | null) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const canvasNode = canvasRef.current;
|
const canvasNode = canvasRef.current;
|
||||||
@ -40,7 +40,7 @@ export interface MermaidToExcalidrawLibProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ConvertMermaidToExcalidrawFormatProps {
|
interface ConvertMermaidToExcalidrawFormatProps {
|
||||||
canvasRef: React.RefObject<HTMLDivElement>;
|
canvasRef: React.RefObject<HTMLDivElement | null>;
|
||||||
mermaidToExcalidrawLib: MermaidToExcalidrawLibProps;
|
mermaidToExcalidrawLib: MermaidToExcalidrawLibProps;
|
||||||
mermaidDefinition: string;
|
mermaidDefinition: string;
|
||||||
setError: (error: Error | null) => void;
|
setError: (error: Error | null) => void;
|
||||||
|
@ -17,7 +17,7 @@ import { isRenderThrottlingEnabled } from "../../reactUtils";
|
|||||||
import { renderInteractiveScene } from "../../renderer/interactiveScene";
|
import { renderInteractiveScene } from "../../renderer/interactiveScene";
|
||||||
|
|
||||||
type InteractiveCanvasProps = {
|
type InteractiveCanvasProps = {
|
||||||
containerRef: React.RefObject<HTMLDivElement>;
|
containerRef: React.RefObject<HTMLDivElement | null>;
|
||||||
canvas: HTMLCanvasElement | null;
|
canvas: HTMLCanvasElement | null;
|
||||||
elementsMap: RenderableElementsMap;
|
elementsMap: RenderableElementsMap;
|
||||||
visibleElements: readonly NonDeletedExcalidrawElement[];
|
visibleElements: readonly NonDeletedExcalidrawElement[];
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import React, { useEffect, useRef } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
import {
|
import {
|
||||||
getDropdownMenuItemClassName,
|
getDropdownMenuItemClassName,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import { useDevice } from "../App";
|
import { useDevice } from "../App";
|
||||||
|
|
||||||
const MenuItemContent = ({
|
const MenuItemContent = ({
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import MenuItemContent from "./DropdownMenuItemContent";
|
import MenuItemContent from "./DropdownMenuItemContent";
|
||||||
|
import type { JSX } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
getDropdownMenuItemClassName,
|
getDropdownMenuItemClassName,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import { actionLoadScene, actionShortcuts } from "../../actions";
|
import { actionLoadScene, actionShortcuts } from "../../actions";
|
||||||
import { getShortcutFromShortcutName } from "../../actions/shortcuts";
|
import { getShortcutFromShortcutName } from "../../actions/shortcuts";
|
||||||
import { t, useI18n } from "../../i18n";
|
import { t, useI18n } from "../../i18n";
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import ReactDOM from "react-dom";
|
import { render, unmountComponent } from "../tests/test-utils";
|
||||||
import { render } from "../tests/test-utils";
|
|
||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
import { UI, Keyboard, Pointer } from "../tests/helpers/ui";
|
import { UI, Keyboard, Pointer } from "../tests/helpers/ui";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { API } from "../tests/helpers/api";
|
import { API } from "../tests/helpers/api";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
|
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
unmountComponent();
|
||||||
|
|
||||||
const { h } = window;
|
const { h } = window;
|
||||||
const mouse = new Pointer("mouse");
|
const mouse = new Pointer("mouse");
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { GlobalTestState, render, screen } from "../tests/test-utils";
|
import {
|
||||||
|
GlobalTestState,
|
||||||
|
render,
|
||||||
|
screen,
|
||||||
|
unmountComponent,
|
||||||
|
} from "../tests/test-utils";
|
||||||
import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
|
import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
|
||||||
import { CODES, KEYS } from "../keys";
|
import { CODES, KEYS } from "../keys";
|
||||||
import {
|
import {
|
||||||
@ -21,8 +25,7 @@ import { getOriginalContainerHeightFromCache } from "./containerCache";
|
|||||||
import { getTextEditor, updateTextEditor } from "../tests/queries/dom";
|
import { getTextEditor, updateTextEditor } from "../tests/queries/dom";
|
||||||
import { pointFrom } from "../../math";
|
import { pointFrom } from "../../math";
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
const tab = " ";
|
const tab = " ";
|
||||||
const mouse = new Pointer("mouse");
|
const mouse = new Pointer("mouse");
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import {
|
import {
|
||||||
FreedrawIcon,
|
FreedrawIcon,
|
||||||
FontFamilyNormalIcon,
|
FontFamilyNormalIcon,
|
||||||
|
12
packages/excalidraw/global.d.ts
vendored
12
packages/excalidraw/global.d.ts
vendored
@ -99,8 +99,12 @@ declare module "image-blob-reduce" {
|
|||||||
export = reduce;
|
export = reduce;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare namespace jest {
|
interface CustomMatchers {
|
||||||
interface Expect {
|
toBeNonNaNNumber(): void;
|
||||||
toBeNonNaNNumber(): void;
|
toCloselyEqualPoints(points: readonly [number, number][]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare namespace jest {
|
||||||
|
interface Expect extends CustomMatchers {}
|
||||||
|
interface Matchers extends CustomMatchers {}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { useEffect } from "react";
|
|||||||
import { EVENT } from "../constants";
|
import { EVENT } from "../constants";
|
||||||
|
|
||||||
export function useOutsideClick<T extends HTMLElement>(
|
export function useOutsideClick<T extends HTMLElement>(
|
||||||
ref: React.RefObject<T>,
|
ref: React.RefObject<T | null>,
|
||||||
/** if performance is of concern, memoize the callback */
|
/** if performance is of concern, memoize the callback */
|
||||||
callback: (event: Event) => void,
|
callback: (event: Event) => void,
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,7 @@ import throttle from "lodash.throttle";
|
|||||||
const scrollPositionAtom = atom<number>(0);
|
const scrollPositionAtom = atom<number>(0);
|
||||||
|
|
||||||
export const useScrollPosition = <T extends HTMLElement>(
|
export const useScrollPosition = <T extends HTMLElement>(
|
||||||
elementRef: React.RefObject<T>,
|
elementRef: React.RefObject<T | null>,
|
||||||
) => {
|
) => {
|
||||||
const [scrollPosition, setScrollPosition] = useAtom(scrollPositionAtom);
|
const [scrollPosition, setScrollPosition] = useAtom(scrollPositionAtom);
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^17.0.2 || ^18.2.0",
|
"react": "^17.0.2 || ^18.2.0 || ^19.0.0",
|
||||||
"react-dom": "^17.0.2 || ^18.2.0"
|
"react-dom": "^17.0.2 || ^18.2.0 || ^19.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@braintree/sanitize-url": "6.0.2",
|
"@braintree/sanitize-url": "6.0.2",
|
||||||
@ -98,8 +98,8 @@
|
|||||||
"@babel/preset-typescript": "7.24.1",
|
"@babel/preset-typescript": "7.24.1",
|
||||||
"@size-limit/preset-big-lib": "9.0.0",
|
"@size-limit/preset-big-lib": "9.0.0",
|
||||||
"@testing-library/dom": "10.4.0",
|
"@testing-library/dom": "10.4.0",
|
||||||
"@testing-library/jest-dom": "5.16.2",
|
"@testing-library/jest-dom": "6.6.3",
|
||||||
"@testing-library/react": "16.0.0",
|
"@testing-library/react": "16.2.0",
|
||||||
"@types/pako": "1.0.3",
|
"@types/pako": "1.0.3",
|
||||||
"@types/pica": "5.1.3",
|
"@types/pica": "5.1.3",
|
||||||
"@types/resize-observer-browser": "0.1.7",
|
"@types/resize-observer-browser": "0.1.7",
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import * as StaticScene from "../renderer/staticScene";
|
import * as StaticScene from "../renderer/staticScene";
|
||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
import { render, queryByTestId } from "../tests/test-utils";
|
import { render, queryByTestId, unmountComponent } from "../tests/test-utils";
|
||||||
|
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
@ -11,8 +10,7 @@ const renderStaticScene = vi.spyOn(StaticScene, "renderStaticScene");
|
|||||||
|
|
||||||
describe("Test <App/>", () => {
|
describe("Test <App/>", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
renderStaticScene.mockClear();
|
renderStaticScene.mockClear();
|
||||||
reseed(7);
|
reseed(7);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import { act, unmountComponent, render } from "./test-utils";
|
||||||
import { act, render } from "./test-utils";
|
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { defaultLang, setLanguage } from "../i18n";
|
import { defaultLang, setLanguage } from "../i18n";
|
||||||
import { UI, Pointer, Keyboard } from "./helpers/ui";
|
import { UI, Pointer, Keyboard } from "./helpers/ui";
|
||||||
@ -54,8 +53,7 @@ const createAndSelectTwoRectanglesWithDifferentSizes = () => {
|
|||||||
|
|
||||||
describe("aligning", () => {
|
describe("aligning", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
mouse.reset();
|
mouse.reset();
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
import ReactDOM from "react-dom";
|
import {
|
||||||
import { render, waitFor, GlobalTestState } from "./test-utils";
|
render,
|
||||||
|
waitFor,
|
||||||
|
GlobalTestState,
|
||||||
|
unmountComponent,
|
||||||
|
} from "./test-utils";
|
||||||
import { Pointer, Keyboard } from "./helpers/ui";
|
import { Pointer, Keyboard } from "./helpers/ui";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
@ -63,7 +67,7 @@ const sleep = (ms: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
unmountComponent();
|
||||||
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import {
|
import {
|
||||||
render,
|
render,
|
||||||
fireEvent,
|
fireEvent,
|
||||||
@ -11,6 +10,7 @@ import {
|
|||||||
queryAllByText,
|
queryAllByText,
|
||||||
waitFor,
|
waitFor,
|
||||||
togglePopover,
|
togglePopover,
|
||||||
|
unmountComponent,
|
||||||
} from "./test-utils";
|
} from "./test-utils";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import * as StaticScene from "../renderer/staticScene";
|
import * as StaticScene from "../renderer/staticScene";
|
||||||
@ -38,8 +38,7 @@ const checkpoint = (name: string) => {
|
|||||||
|
|
||||||
const mouse = new Pointer("mouse");
|
const mouse = new Pointer("mouse");
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
const renderStaticScene = vi.spyOn(StaticScene, "renderStaticScene");
|
const renderStaticScene = vi.spyOn(StaticScene, "renderStaticScene");
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
import { Keyboard, Pointer, UI } from "./helpers/ui";
|
import { Keyboard, Pointer, UI } from "./helpers/ui";
|
||||||
import type { ExcalidrawImageElement, ImageCrop } from "../element/types";
|
import type { ExcalidrawImageElement, ImageCrop } from "../element/types";
|
||||||
import { act, GlobalTestState, render } from "./test-utils";
|
import { act, GlobalTestState, render, unmountComponent } from "./test-utils";
|
||||||
import { Excalidraw, exportToCanvas, exportToSvg } from "..";
|
import { Excalidraw, exportToCanvas, exportToSvg } from "..";
|
||||||
import { API } from "./helpers/api";
|
import { API } from "./helpers/api";
|
||||||
import type { NormalizedZoomValue } from "../types";
|
import type { NormalizedZoomValue } from "../types";
|
||||||
@ -16,8 +15,7 @@ const { h } = window;
|
|||||||
const mouse = new Pointer("mouse");
|
const mouse = new Pointer("mouse");
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
mouse.reset();
|
mouse.reset();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
@ -173,7 +173,7 @@ exports[`restoreElements > should restore freedraw element correctly 1`] = `
|
|||||||
"fillStyle": "solid",
|
"fillStyle": "solid",
|
||||||
"frameId": null,
|
"frameId": null,
|
||||||
"groupIds": [],
|
"groupIds": [],
|
||||||
"height": 0,
|
"height": 100,
|
||||||
"id": "id-freedraw01",
|
"id": "id-freedraw01",
|
||||||
"index": "a0",
|
"index": "a0",
|
||||||
"isDeleted": false,
|
"isDeleted": false,
|
||||||
@ -181,7 +181,16 @@ exports[`restoreElements > should restore freedraw element correctly 1`] = `
|
|||||||
"link": null,
|
"link": null,
|
||||||
"locked": false,
|
"locked": false,
|
||||||
"opacity": 100,
|
"opacity": 100,
|
||||||
"points": [],
|
"points": [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
10,
|
||||||
|
10,
|
||||||
|
],
|
||||||
|
],
|
||||||
"pressures": [],
|
"pressures": [],
|
||||||
"roughness": 1,
|
"roughness": 1,
|
||||||
"roundness": {
|
"roundness": {
|
||||||
@ -196,7 +205,7 @@ exports[`restoreElements > should restore freedraw element correctly 1`] = `
|
|||||||
"updated": 1,
|
"updated": 1,
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"versionNonce": Any<Number>,
|
"versionNonce": Any<Number>,
|
||||||
"width": 0,
|
"width": 100,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 0,
|
"y": 0,
|
||||||
}
|
}
|
||||||
|
@ -80,9 +80,12 @@ const test = <U extends `${string}:${"L" | "R"}`>(
|
|||||||
const reconciledIds = reconciled.map((x) => x.id);
|
const reconciledIds = reconciled.map((x) => x.id);
|
||||||
const reconciledIndices = reconciled.map((x) => x.index);
|
const reconciledIndices = reconciled.map((x) => x.index);
|
||||||
|
|
||||||
expect(target.length).equal(reconciled.length);
|
expect(target.length).toEqual(reconciled.length);
|
||||||
expect(reconciledIndices.length).equal(new Set([...reconciledIndices]).size); // expect no duplicated indices
|
expect(reconciledIndices.length).toEqual(
|
||||||
expect(reconciledIds).deep.equal(
|
new Set([...reconciledIndices]).size,
|
||||||
|
); // expect no duplicated indices
|
||||||
|
assert.deepEqual(
|
||||||
|
reconciledIds,
|
||||||
target.map((uid) => {
|
target.map((uid) => {
|
||||||
const [, id, source] = uid.match(/^(\w+):([LR])$/)!;
|
const [, id, source] = uid.match(/^(\w+):([LR])$/)!;
|
||||||
const element = (source === "L" ? _local : _remote).find(
|
const element = (source === "L" ? _local : _remote).find(
|
||||||
@ -96,13 +99,15 @@ const test = <U extends `${string}:${"L" | "R"}`>(
|
|||||||
|
|
||||||
// convergent reconciliation on the remote client
|
// convergent reconciliation on the remote client
|
||||||
try {
|
try {
|
||||||
expect(
|
assert.deepEqual(
|
||||||
reconcileElements(
|
reconcileElements(
|
||||||
cloneJSON(_remote),
|
cloneJSON(_remote),
|
||||||
cloneJSON(_local as RemoteExcalidrawElement[]),
|
cloneJSON(_local as RemoteExcalidrawElement[]),
|
||||||
{} as AppState,
|
{} as AppState,
|
||||||
).map((x) => x.id),
|
).map((x) => x.id),
|
||||||
).deep.equal(reconciledIds, "convergent reconciliation");
|
reconciledIds,
|
||||||
|
"convergent reconciliation",
|
||||||
|
);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error("local original", _remote);
|
console.error("local original", _remote);
|
||||||
console.error("remote original", _local);
|
console.error("remote original", _local);
|
||||||
@ -111,13 +116,15 @@ const test = <U extends `${string}:${"L" | "R"}`>(
|
|||||||
|
|
||||||
// bidirectional re-reconciliation on remote client
|
// bidirectional re-reconciliation on remote client
|
||||||
try {
|
try {
|
||||||
expect(
|
assert.deepEqual(
|
||||||
reconcileElements(
|
reconcileElements(
|
||||||
cloneJSON(_remote),
|
cloneJSON(_remote),
|
||||||
cloneJSON(reconciled as unknown as RemoteExcalidrawElement[]),
|
cloneJSON(reconciled as unknown as RemoteExcalidrawElement[]),
|
||||||
{} as AppState,
|
{} as AppState,
|
||||||
).map((x) => x.id),
|
).map((x) => x.id),
|
||||||
).deep.equal(reconciledIds, "local re-reconciliation");
|
reconciledIds,
|
||||||
|
"local re-reconciliation",
|
||||||
|
);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error("local original", _remote);
|
console.error("local original", _remote);
|
||||||
console.error("remote reconciled", reconciled);
|
console.error("remote reconciled", reconciled);
|
||||||
@ -309,7 +316,10 @@ describe("elements reconciliation", () => {
|
|||||||
throw new Error("reconcileElements: duplicate elements found");
|
throw new Error("reconcileElements: duplicate elements found");
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(ret.map((x) => x.id)).to.deep.equal(expected);
|
assert.deepEqual(
|
||||||
|
ret.map((x) => x.id),
|
||||||
|
expected,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// identical id/version/versionNonce/index
|
// identical id/version/versionNonce/index
|
||||||
|
@ -13,6 +13,7 @@ import type { NormalizedZoomValue } from "../../types";
|
|||||||
import { DEFAULT_SIDEBAR, FONT_FAMILY, ROUNDNESS } from "../../constants";
|
import { DEFAULT_SIDEBAR, FONT_FAMILY, ROUNDNESS } from "../../constants";
|
||||||
import { newElementWith } from "../../element/mutateElement";
|
import { newElementWith } from "../../element/mutateElement";
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
|
import { pointFrom } from "../../../math";
|
||||||
|
|
||||||
describe("restoreElements", () => {
|
describe("restoreElements", () => {
|
||||||
const mockSizeHelper = vi.spyOn(sizeHelpers, "isInvisiblySmallElement");
|
const mockSizeHelper = vi.spyOn(sizeHelpers, "isInvisiblySmallElement");
|
||||||
@ -103,6 +104,7 @@ describe("restoreElements", () => {
|
|||||||
const freedrawElement = API.createElement({
|
const freedrawElement = API.createElement({
|
||||||
type: "freedraw",
|
type: "freedraw",
|
||||||
id: "id-freedraw01",
|
id: "id-freedraw01",
|
||||||
|
points: [pointFrom(0, 0), pointFrom(10, 10)],
|
||||||
});
|
});
|
||||||
|
|
||||||
const restoredFreedraw = restore.restoreElements(
|
const restoredFreedraw = restore.restoreElements(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import * as StaticScene from "../renderer/staticScene";
|
import * as StaticScene from "../renderer/staticScene";
|
||||||
import * as InteractiveScene from "../renderer/interactiveScene";
|
import * as InteractiveScene from "../renderer/interactiveScene";
|
||||||
@ -9,13 +8,13 @@ import {
|
|||||||
fireEvent,
|
fireEvent,
|
||||||
mockBoundingClientRect,
|
mockBoundingClientRect,
|
||||||
restoreOriginalGetBoundingClientRect,
|
restoreOriginalGetBoundingClientRect,
|
||||||
|
unmountComponent,
|
||||||
} from "./test-utils";
|
} from "./test-utils";
|
||||||
import type { ExcalidrawLinearElement } from "../element/types";
|
import type { ExcalidrawLinearElement } from "../element/types";
|
||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
const renderInteractiveScene = vi.spyOn(
|
const renderInteractiveScene = vi.spyOn(
|
||||||
InteractiveScene,
|
InteractiveScene,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { render } from "../tests/test-utils";
|
import { render, unmountComponent } from "../tests/test-utils";
|
||||||
import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
|
import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
import { API } from "../tests/helpers/api";
|
import { API } from "../tests/helpers/api";
|
||||||
@ -9,7 +8,7 @@ import { actionSelectAll } from "../actions";
|
|||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
import { mutateElement } from "../element/mutateElement";
|
import { mutateElement } from "../element/mutateElement";
|
||||||
|
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
unmountComponent();
|
||||||
|
|
||||||
const mouse = new Pointer("mouse");
|
const mouse = new Pointer("mouse");
|
||||||
const h = window.h;
|
const h = window.h;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import {
|
import {
|
||||||
fireEvent,
|
fireEvent,
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
render,
|
render,
|
||||||
screen,
|
screen,
|
||||||
|
unmountComponent,
|
||||||
waitFor,
|
waitFor,
|
||||||
} from "./test-utils";
|
} from "./test-utils";
|
||||||
import { UI, Pointer, Keyboard } from "./helpers/ui";
|
import { UI, Pointer, Keyboard } from "./helpers/ui";
|
||||||
@ -43,8 +43,7 @@ vi.mock("../data/blob", async (actual) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
mouse.reset();
|
mouse.reset();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
@ -189,7 +189,7 @@ export class API {
|
|||||||
containerId?: T extends "text"
|
containerId?: T extends "text"
|
||||||
? ExcalidrawTextElement["containerId"]
|
? ExcalidrawTextElement["containerId"]
|
||||||
: never;
|
: never;
|
||||||
points?: T extends "arrow" | "line" ? readonly LocalPoint[] : never;
|
points?: T extends "arrow" | "line" | "freedraw" ? readonly LocalPoint[] : never;
|
||||||
locked?: boolean;
|
locked?: boolean;
|
||||||
fileId?: T extends "image" ? string : never;
|
fileId?: T extends "image" ? string : never;
|
||||||
scale?: T extends "image" ? ExcalidrawImageElement["scale"] : never;
|
scale?: T extends "image" ? ExcalidrawImageElement["scale"] : never;
|
||||||
@ -228,8 +228,6 @@ export class API {
|
|||||||
const base: Omit<
|
const base: Omit<
|
||||||
ExcalidrawGenericElement,
|
ExcalidrawGenericElement,
|
||||||
| "id"
|
| "id"
|
||||||
| "width"
|
|
||||||
| "height"
|
|
||||||
| "type"
|
| "type"
|
||||||
| "version"
|
| "version"
|
||||||
| "versionNonce"
|
| "versionNonce"
|
||||||
@ -241,6 +239,8 @@ export class API {
|
|||||||
seed: 1,
|
seed: 1,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
frameId: rest.frameId ?? null,
|
frameId: rest.frameId ?? null,
|
||||||
index: rest.index ?? null,
|
index: rest.index ?? null,
|
||||||
angle: (rest.angle ?? 0) as Radians,
|
angle: (rest.angle ?? 0) as Radians,
|
||||||
@ -272,8 +272,6 @@ export class API {
|
|||||||
case "ellipse":
|
case "ellipse":
|
||||||
element = newElement({
|
element = newElement({
|
||||||
type: type as "rectangle" | "diamond" | "ellipse",
|
type: type as "rectangle" | "diamond" | "ellipse",
|
||||||
width,
|
|
||||||
height,
|
|
||||||
...base,
|
...base,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -308,6 +306,7 @@ export class API {
|
|||||||
element = newFreeDrawElement({
|
element = newFreeDrawElement({
|
||||||
type: type as "freedraw",
|
type: type as "freedraw",
|
||||||
simulatePressure: true,
|
simulatePressure: true,
|
||||||
|
points: rest.points,
|
||||||
...base,
|
...base,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import type {
|
import type {
|
||||||
ExcalidrawElement,
|
ExcalidrawElement,
|
||||||
ExcalidrawLinearElement,
|
ExcalidrawLinearElement,
|
||||||
@ -12,7 +11,13 @@ import * as StaticScene from "../renderer/staticScene";
|
|||||||
import * as InteractiveCanvas from "../renderer/interactiveScene";
|
import * as InteractiveCanvas from "../renderer/interactiveScene";
|
||||||
|
|
||||||
import { Keyboard, Pointer, UI } from "./helpers/ui";
|
import { Keyboard, Pointer, UI } from "./helpers/ui";
|
||||||
import { screen, render, fireEvent, GlobalTestState } from "./test-utils";
|
import {
|
||||||
|
screen,
|
||||||
|
render,
|
||||||
|
fireEvent,
|
||||||
|
GlobalTestState,
|
||||||
|
unmountComponent,
|
||||||
|
} from "./test-utils";
|
||||||
import { API } from "../tests/helpers/api";
|
import { API } from "../tests/helpers/api";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
import { LinearElementEditor } from "../element/linearElementEditor";
|
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||||
@ -43,8 +48,7 @@ describe("Test Linear Elements", () => {
|
|||||||
let interactiveCanvas: HTMLCanvasElement;
|
let interactiveCanvas: HTMLCanvasElement;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
renderInteractiveScene.mockClear();
|
renderInteractiveScene.mockClear();
|
||||||
renderStaticScene.mockClear();
|
renderStaticScene.mockClear();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import { render, fireEvent, act, unmountComponent } from "./test-utils";
|
||||||
import { render, fireEvent, act } from "./test-utils";
|
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import * as StaticScene from "../renderer/staticScene";
|
import * as StaticScene from "../renderer/staticScene";
|
||||||
import * as InteractiveCanvas from "../renderer/interactiveScene";
|
import * as InteractiveCanvas from "../renderer/interactiveScene";
|
||||||
@ -16,8 +15,7 @@ import { KEYS } from "../keys";
|
|||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
import type Scene from "../scene/Scene";
|
import type Scene from "../scene/Scene";
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
const renderInteractiveScene = vi.spyOn(
|
const renderInteractiveScene = vi.spyOn(
|
||||||
InteractiveCanvas,
|
InteractiveCanvas,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import {
|
import {
|
||||||
render,
|
render,
|
||||||
fireEvent,
|
fireEvent,
|
||||||
mockBoundingClientRect,
|
mockBoundingClientRect,
|
||||||
restoreOriginalGetBoundingClientRect,
|
restoreOriginalGetBoundingClientRect,
|
||||||
|
unmountComponent,
|
||||||
} from "./test-utils";
|
} from "./test-utils";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import * as StaticScene from "../renderer/staticScene";
|
import * as StaticScene from "../renderer/staticScene";
|
||||||
@ -14,8 +14,7 @@ import type { ExcalidrawLinearElement } from "../element/types";
|
|||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
const renderInteractiveScene = vi.spyOn(
|
const renderInteractiveScene = vi.spyOn(
|
||||||
InteractiveCanvas,
|
InteractiveCanvas,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import type { ExcalidrawElement } from "../element/types";
|
import type { ExcalidrawElement } from "../element/types";
|
||||||
import { CODES, KEYS } from "../keys";
|
import { CODES, KEYS } from "../keys";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
@ -14,6 +13,7 @@ import {
|
|||||||
render,
|
render,
|
||||||
screen,
|
screen,
|
||||||
togglePopover,
|
togglePopover,
|
||||||
|
unmountComponent,
|
||||||
} from "./test-utils";
|
} from "./test-utils";
|
||||||
import { FONT_FAMILY } from "../constants";
|
import { FONT_FAMILY } from "../constants";
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
@ -43,8 +43,7 @@ const checkpoint = (name: string) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
renderStaticScene.mockClear();
|
renderStaticScene.mockClear();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import { render, unmountComponent } from "./test-utils";
|
||||||
import { render } from "./test-utils";
|
|
||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
import { UI, Keyboard, Pointer } from "./helpers/ui";
|
import { UI, Keyboard, Pointer } from "./helpers/ui";
|
||||||
import type {
|
import type {
|
||||||
@ -21,7 +20,7 @@ import { pointFrom } from "../../math";
|
|||||||
import { resizeSingleElement } from "../element/resizeElements";
|
import { resizeSingleElement } from "../element/resizeElements";
|
||||||
import { getSizeFromPoints } from "../points";
|
import { getSizeFromPoints } from "../points";
|
||||||
|
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
unmountComponent();
|
||||||
|
|
||||||
const { h } = window;
|
const { h } = window;
|
||||||
const mouse = new Pointer("mouse");
|
const mouse = new Pointer("mouse");
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import { render, unmountComponent } from "./test-utils";
|
||||||
import { render } from "./test-utils";
|
|
||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
import { UI } from "./helpers/ui";
|
import { UI } from "./helpers/ui";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { expect } from "vitest";
|
import { expect } from "vitest";
|
||||||
|
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
unmountComponent();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
|
||||||
import {
|
import {
|
||||||
render,
|
render,
|
||||||
fireEvent,
|
fireEvent,
|
||||||
mockBoundingClientRect,
|
mockBoundingClientRect,
|
||||||
restoreOriginalGetBoundingClientRect,
|
restoreOriginalGetBoundingClientRect,
|
||||||
assertSelectedElements,
|
assertSelectedElements,
|
||||||
|
unmountComponent,
|
||||||
} from "./test-utils";
|
} from "./test-utils";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import * as StaticScene from "../renderer/staticScene";
|
import * as StaticScene from "../renderer/staticScene";
|
||||||
@ -17,8 +17,7 @@ import { Keyboard, Pointer, UI } from "./helpers/ui";
|
|||||||
import { SHAPES } from "../shapes";
|
import { SHAPES } from "../shapes";
|
||||||
import { vi } from "vitest";
|
import { vi } from "vitest";
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
const renderInteractiveScene = vi.spyOn(
|
const renderInteractiveScene = vi.spyOn(
|
||||||
InteractiveCanvas,
|
InteractiveCanvas,
|
||||||
|
@ -2,7 +2,13 @@ import "pepjs";
|
|||||||
|
|
||||||
import type { RenderResult, RenderOptions } from "@testing-library/react";
|
import type { RenderResult, RenderOptions } from "@testing-library/react";
|
||||||
import { act } from "@testing-library/react";
|
import { act } from "@testing-library/react";
|
||||||
import { render, queries, waitFor, fireEvent } from "@testing-library/react";
|
import {
|
||||||
|
render,
|
||||||
|
queries,
|
||||||
|
waitFor,
|
||||||
|
fireEvent,
|
||||||
|
cleanup,
|
||||||
|
} from "@testing-library/react";
|
||||||
|
|
||||||
import * as toolQueries from "./queries/toolQueries";
|
import * as toolQueries from "./queries/toolQueries";
|
||||||
import type { ImportedDataState } from "../data/types";
|
import type { ImportedDataState } from "../data/types";
|
||||||
@ -16,6 +22,8 @@ import { ORIG_ID } from "../constants";
|
|||||||
import { arrayToMap } from "../utils";
|
import { arrayToMap } from "../utils";
|
||||||
import type { AllPossibleKeys } from "../utility-types";
|
import type { AllPossibleKeys } from "../utility-types";
|
||||||
|
|
||||||
|
export { cleanup as unmountComponent };
|
||||||
|
|
||||||
const customQueries = {
|
const customQueries = {
|
||||||
...queries,
|
...queries,
|
||||||
...toolQueries,
|
...toolQueries,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import { act, getCloneByOrigId, render, unmountComponent } from "./test-utils";
|
||||||
import { act, getCloneByOrigId, render } from "./test-utils";
|
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import { reseed } from "../random";
|
import { reseed } from "../random";
|
||||||
import {
|
import {
|
||||||
@ -19,8 +18,7 @@ import type {
|
|||||||
ExcalidrawSelectionElement,
|
ExcalidrawSelectionElement,
|
||||||
} from "../element/types";
|
} from "../element/types";
|
||||||
|
|
||||||
// Unmount ReactDOM from root
|
unmountComponent();
|
||||||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { JSX } from "react";
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import type {
|
import type {
|
||||||
PointerType,
|
PointerType,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"types": ["vitest/globals", "@testing-library/jest-dom"],
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user